@uns-kit/core 2.0.25 → 2.0.27
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/LICENSE +21 -21
- package/README.md +137 -137
- package/dist/app-config.d.ts.map +1 -0
- package/dist/app-config.js.map +1 -0
- package/dist/base-path.js.map +1 -1
- package/dist/config/app-config.d.ts +1 -0
- package/dist/config/app-config.d.ts.map +1 -1
- package/dist/config/app-config.js.map +1 -1
- package/dist/config/project.config.extension.js.map +1 -1
- package/dist/config-file.js.map +1 -1
- package/dist/graphql/schema.js.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/logger.d.ts.map +1 -1
- package/dist/logger.js +10 -15
- package/dist/logger.js.map +1 -1
- package/dist/tools/auth/auth-client.js.map +1 -1
- package/dist/tools/auth/index.js.map +1 -1
- package/dist/tools/auth/secure-store.js.map +1 -1
- package/dist/tools/base-path.js.map +1 -1
- package/dist/tools/file-utils.js.map +1 -1
- package/dist/tools/generate-config-schema.js.map +1 -1
- package/dist/tools/generate-uns-dictionary.js +7 -7
- package/dist/tools/generate-uns-dictionary.js.map +1 -1
- package/dist/tools/generate-uns-measurements.js +7 -7
- package/dist/tools/generate-uns-measurements.js.map +1 -1
- package/dist/tools/generate-uns-reference.js +9 -9
- package/dist/tools/generate-uns-reference.js.map +1 -1
- package/dist/tools/pull-request.js.map +1 -1
- package/dist/tools/refresh-uns.js +50 -50
- package/dist/tools/refresh-uns.js.map +1 -1
- package/dist/tools/schema.js.map +1 -1
- package/dist/tools/sync-uns-schema.js +17 -17
- package/dist/tools/sync-uns-schema.js.map +1 -1
- package/dist/uns/handover-manager-event-emitter.js.map +1 -1
- package/dist/uns/handover-manager.js.map +1 -1
- package/dist/uns/process-config.js.map +1 -1
- package/dist/uns/process-name-service.js.map +1 -1
- package/dist/uns/status-monitor.js.map +1 -1
- package/dist/uns/uns-asset.js.map +1 -1
- package/dist/uns/uns-attributes.js.map +1 -1
- package/dist/uns/uns-dictionary-registry.js.map +1 -1
- package/dist/uns/uns-dictionary.generated.js.map +1 -1
- package/dist/uns/uns-event-emitter.js.map +1 -1
- package/dist/uns/uns-interfaces.js.map +1 -1
- package/dist/uns/uns-measurements.generated.js.map +1 -1
- package/dist/uns/uns-measurements.js.map +1 -1
- package/dist/uns/uns-object.js.map +1 -1
- package/dist/uns/uns-packet.js.map +1 -1
- package/dist/uns/uns-path.js.map +1 -1
- package/dist/uns/uns-proxy-process.js.map +1 -1
- package/dist/uns/uns-proxy.js.map +1 -1
- package/dist/uns/uns-tags.js.map +1 -1
- package/dist/uns/uns-topic-matcher.js.map +1 -1
- package/dist/uns/uns-topics.js.map +1 -1
- package/dist/uns-config/config-schema.js.map +1 -1
- package/dist/uns-config/host-placeholders.js.map +1 -1
- package/dist/uns-config/schema-tolls.js.map +1 -1
- package/dist/uns-config/schema-tools.js.map +1 -1
- package/dist/uns-config/secret-placeholders.js.map +1 -1
- package/dist/uns-config/secret-resolver.js.map +1 -1
- package/dist/uns-config/uns-core-schema.d.ts +405 -400
- package/dist/uns-config/uns-core-schema.d.ts.map +1 -1
- package/dist/uns-config/uns-core-schema.js +10 -0
- package/dist/uns-config/uns-core-schema.js.map +1 -1
- package/dist/uns-grpc/uns-gateway-cli.js.map +1 -1
- package/dist/uns-grpc/uns-gateway-server.js.map +1 -1
- package/dist/uns-grpc/uns-gateway.proto +104 -104
- package/dist/uns-mqtt/mqtt-interfaces.js.map +1 -1
- package/dist/uns-mqtt/mqtt-proxy.js.map +1 -1
- package/dist/uns-mqtt/mqtt-topic-builder.js.map +1 -1
- package/dist/uns-mqtt/mqtt-worker-init.js.map +1 -1
- package/dist/uns-mqtt/mqtt-worker.js.map +1 -1
- package/dist/uns-mqtt/throttled-queue.js.map +1 -1
- package/dist/uns-mqtt/uns-mqtt-proxy.js.map +1 -1
- package/dist/uns-mqtt/ws-proxy.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAOxE,cAAc,yBAAyB,CAAC;AACxC,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,OAAO,IAAI,MAAM,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,sBAAsB,EAAE,MAAM,iCAAiC,CAAC","sourcesContent":["export { default as UnsProxyProcess } from \"./uns/uns-proxy-process.js\";\nexport type {\n UnsProxyProcessPlugin,\n UnsProxyProcessPluginApi,\n UnsProxyProcessPluginMethod,\n UnsProxyProcessPluginMethods,\n} from \"./uns/uns-proxy-process.js\";\nexport * from \"./uns/uns-interfaces.js\";\nexport { ConfigFile } from \"./config-file.js\";\nexport { default as logger } from \"./logger.js\";\nexport { getLogger } from \"./logger.js\";\nexport { resolveInfisicalConfig } from \"./uns-config/secret-resolver.js\";\n"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAOxE,cAAc,yBAAyB,CAAC;AACxC,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,OAAO,IAAI,MAAM,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,sBAAsB,EAAE,MAAM,iCAAiC,CAAC","sourcesContent":["export { default as UnsProxyProcess } from \"./uns/uns-proxy-process.js\";\r\nexport type {\r\n UnsProxyProcessPlugin,\r\n UnsProxyProcessPluginApi,\r\n UnsProxyProcessPluginMethod,\r\n UnsProxyProcessPluginMethods,\r\n} from \"./uns/uns-proxy-process.js\";\r\nexport * from \"./uns/uns-interfaces.js\";\r\nexport { ConfigFile } from \"./config-file.js\";\r\nexport { default as logger } from \"./logger.js\";\r\nexport { getLogger } from \"./logger.js\";\r\nexport { resolveInfisicalConfig } from \"./uns-config/secret-resolver.js\";\r\n"]}
|
package/dist/logger.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":"AAuEA,QAAA,MAAM,MAAM,0BAiBV,CAAC;AAEH,wBAAgB,SAAS,CAAC,UAAU,EAAE,MAAM,4BAY3C;AAED,eAAe,MAAM,CAAA"}
|
package/dist/logger.js
CHANGED
|
@@ -6,22 +6,17 @@ import fs from 'fs';
|
|
|
6
6
|
import { fileURLToPath } from 'url';
|
|
7
7
|
import { ConfigFile } from './config-file.js';
|
|
8
8
|
function loadPackageMeta() {
|
|
9
|
-
const
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
const raw = fs.readFileSync(packageJsonPath, 'utf8');
|
|
16
|
-
const packageMeta = JSON.parse(raw);
|
|
17
|
-
if (packageMeta.name || packageMeta.version) {
|
|
18
|
-
return packageMeta;
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
catch {
|
|
22
|
-
// Try the next candidate.
|
|
9
|
+
const packageJsonPath = path.join(process.cwd(), 'package.json');
|
|
10
|
+
try {
|
|
11
|
+
const raw = fs.readFileSync(packageJsonPath, 'utf8');
|
|
12
|
+
const packageMeta = JSON.parse(raw);
|
|
13
|
+
if (packageMeta.name || packageMeta.version) {
|
|
14
|
+
return packageMeta;
|
|
23
15
|
}
|
|
24
16
|
}
|
|
17
|
+
catch {
|
|
18
|
+
// Use unknown values when the application package metadata is unavailable.
|
|
19
|
+
}
|
|
25
20
|
return {};
|
|
26
21
|
}
|
|
27
22
|
function loadLoggingConfig() {
|
|
@@ -62,7 +57,7 @@ if (loggingConfig) {
|
|
|
62
57
|
}));
|
|
63
58
|
}
|
|
64
59
|
const logger = createLogger({
|
|
65
|
-
level: 'info',
|
|
60
|
+
level: loggingConfig?.level ?? 'info',
|
|
66
61
|
format: format.combine(format.timestamp({ format: 'YYYY-MM-DD HH:mm:ss' }), format.errors({ stack: true }), // Include stack trace
|
|
67
62
|
format.splat(), format.json()),
|
|
68
63
|
transports: loggerTransports,
|
package/dist/logger.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"logger.js","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAC3D,OAAO,aAAa,MAAM,cAAc,CAAA;AACxC,OAAO,EAAE,MAAM,IAAI,CAAA;AACnB,OAAO,IAAI,MAAM,MAAM,CAAA;AACvB,OAAO,EAAE,MAAM,IAAI,CAAA;AACnB,OAAO,EAAE,aAAa,EAAE,MAAM,KAAK,CAAC;AACpC,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAE7C,SAAS,eAAe;IACtB,MAAM,
|
|
1
|
+
{"version":3,"file":"logger.js","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":"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","sourcesContent":["import { createLogger, format, transports } from 'winston';\r\nimport GelfTransport from 'winston-gelf'\r\nimport os from 'os'\r\nimport path from 'path'\r\nimport fs from 'fs'\r\nimport { fileURLToPath } from 'url';\r\nimport { ConfigFile } from './config-file.js'\r\n\r\nfunction loadPackageMeta(): { name?: string; version?: string } {\r\n const packageJsonPath = path.join(process.cwd(), 'package.json')\r\n\r\n try {\r\n const raw = fs.readFileSync(packageJsonPath, 'utf8')\r\n const packageMeta = JSON.parse(raw) as { name?: string; version?: string }\r\n if (packageMeta.name || packageMeta.version) {\r\n return packageMeta\r\n }\r\n } catch {\r\n // Use unknown values when the application package metadata is unavailable.\r\n }\r\n\r\n return {}\r\n}\r\n\r\nfunction loadLoggingConfig() {\r\n try {\r\n return ConfigFile.loadRawConfig().logging\r\n } catch {\r\n return undefined\r\n }\r\n}\r\n\r\nconst packageMeta = loadPackageMeta()\r\nconst loggingConfig = loadLoggingConfig()\r\nconst gelfMeta = {\r\n service: packageMeta.name ?? 'unknown-service',\r\n version: packageMeta.version ?? 'unknown',\r\n environment: process.env.NODE_ENV || 'unknown',\r\n hostname: os.hostname()\r\n}\r\nconst consoleFormat = format.combine(\r\n format.timestamp({ format: 'YYYY-MM-DD HH:mm:ss' }),\r\n format.errors({ stack: true }),\r\n format.splat(),\r\n format.json()\r\n)\r\n\r\nconst loggerTransports = [\r\n new transports.Console({\r\n format: consoleFormat\r\n })\r\n]\r\n\r\nif (loggingConfig) {\r\n loggerTransports.push(\r\n new GelfTransport({\r\n format: format((info) => ({\r\n ...info,\r\n ...gelfMeta\r\n }))(),\r\n gelfPro: {\r\n adapterName: loggingConfig.adapter,\r\n adapterOptions: {\r\n host: loggingConfig.host,\r\n port: loggingConfig.port\r\n }\r\n }\r\n })\r\n )\r\n}\r\n\r\nconst logger = createLogger({\r\n level: loggingConfig?.level ?? 'info',\r\n\r\n format: format.combine(\r\n format.timestamp({ format: 'YYYY-MM-DD HH:mm:ss' }),\r\n format.errors({ stack: true }), // Include stack trace\r\n format.splat(),\r\n format.json()\r\n ),\r\n transports: loggerTransports,\r\n exceptionHandlers: [\r\n new transports.Console({\r\n format: consoleFormat\r\n }), // Log exceptions to console\r\n // Remove exception logging to file\r\n // new transports.File({ filename: 'logs/exceptions.log' })\r\n ]\r\n});\r\n\r\nexport function getLogger(modulePath: string) {\r\n const normalizedModulePath = modulePath.startsWith('file:')\r\n ? fileURLToPath(modulePath)\r\n : modulePath\r\n\r\n const relativePath = path.relative(process.cwd(), normalizedModulePath)\r\n const withoutExt = relativePath.replace(/\\.[^/.]+$/, '')\r\n const dotted = withoutExt.split(path.sep).join('.')\r\n\r\n return logger.child({\r\n facility: dotted\r\n })\r\n}\r\n\r\nexport default logger\r\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth-client.js","sourceRoot":"","sources":["../../../src/tools/auth/auth-client.ts"],"names":[],"mappings":"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","sourcesContent":["import { ConfigFile } from \"../../config-file.js\";\nimport { SecureStoreFactory, ISecureStore } from \"./secure-store.js\";\nimport jwt from \"jsonwebtoken\";\nimport readline from \"readline\";\n\nconst cfg = await ConfigFile.loadConfig();\n\ntype LoginResponse = {\n accessToken: string;\n};\n\n/**\n * AuthClient handles acquiring and refreshing JWT access tokens\n * using the configured REST base URL.\n */\nexport class AuthClient {\n private readonly restBase: string;\n private readonly namespace: string;\n private store!: ISecureStore;\n\n private constructor(restBase: string) {\n this.restBase = restBase.replace(/\\/$/, \"\");\n // namespace store by rest base to allow multiple environments\n this.namespace = `uns-auth:${this.restBase}`;\n }\n\n static async create(): Promise<AuthClient> {\n const restBase: string = cfg?.uns?.rest;\n if (!restBase) throw new Error(\"config.uns.rest is not set\");\n const client = new AuthClient(restBase);\n client.store = await SecureStoreFactory.create(client.namespace);\n return client;\n }\n\n async getAccessToken(): Promise<string> {\n const accessToken = await this.store.get(\"accessToken\");\n const refreshToken = await this.store.get(\"refreshToken\");\n\n if (accessToken && !AuthClient.isExpired(accessToken)) {\n return accessToken;\n }\n\n // Try refresh if we have refresh token\n if (refreshToken) {\n try {\n const refreshed = await this.refresh(refreshToken);\n await this.persistTokens(refreshed.accessToken, refreshed.refreshToken);\n return refreshed.accessToken;\n } catch {\n // ignore, fallback to login\n }\n }\n\n // First try to get email and password from config\n const configEmail = cfg?.uns?.email;\n const configPassword = cfg?.uns?.password;\n if (typeof configEmail === \"string\" && typeof configPassword === \"string\") {\n try {\n const loggedIn = await this.login(configEmail, configPassword);\n await this.persistTokens(loggedIn.accessToken, loggedIn.refreshToken);\n return loggedIn.accessToken;\n } catch {\n // ignore, fallback to interactive login\n }\n }\n\n // Interactive login\n const { email, password } = await AuthClient.promptCredentials();\n const loggedIn = await this.login(email, password);\n await this.persistTokens(loggedIn.accessToken, loggedIn.refreshToken);\n return loggedIn.accessToken;\n }\n\n private static isExpired(token: string, skewSeconds = 30): boolean {\n try {\n const decoded: any = jwt.decode(token);\n if (!decoded || typeof decoded !== \"object\" || !decoded.exp) return true;\n const now = Math.floor(Date.now() / 1000);\n return decoded.exp <= now + skewSeconds;\n } catch {\n return true;\n }\n }\n\n private static endpoint(base: string, tail: string): string {\n // base ends without trailing slash; tail must not start with slash\n const b = base.replace(/\\/$/, \"\");\n const t = tail.replace(/^\\//, \"\");\n return `${b}/${t}`;\n }\n\n private static async fetchWithTimeout(url: string, init: RequestInit = {}, timeoutMs = 10_000): Promise<Response> {\n const controller = new AbortController();\n const id = setTimeout(() => controller.abort(), timeoutMs);\n try {\n const resp = await fetch(url, { ...init, signal: controller.signal });\n return resp;\n } finally {\n clearTimeout(id);\n }\n }\n\n private static extractRefreshCookie(resp: Response): string | null {\n const anyHeaders: any = resp.headers as any;\n const getSetCookie = typeof anyHeaders.getSetCookie === \"function\" ? anyHeaders.getSetCookie.bind(anyHeaders) : null;\n const candidates: string[] = getSetCookie ? getSetCookie() : (resp.headers.get(\"set-cookie\") ? [resp.headers.get(\"set-cookie\") as string] : []);\n for (const header of candidates) {\n const match = header.match(/(?:^|;\\s*)RefreshToken=([^;]+)/i);\n if (match) return match[1];\n }\n return null;\n }\n\n private async login(email: string, password: string): Promise<{ accessToken: string; refreshToken: string; }> {\n const url = AuthClient.endpoint(this.restBase, \"auth/login\");\n const resp = await AuthClient.fetchWithTimeout(url, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ email, password }),\n }, 12_000);\n\n if (!resp.ok) {\n throw new Error(`Login failed: ${resp.status} ${resp.statusText}`);\n }\n const data = (await resp.json()) as LoginResponse;\n const refreshToken = AuthClient.extractRefreshCookie(resp);\n if (!data?.accessToken || !refreshToken) {\n throw new Error(\"Login response missing tokens\");\n }\n return { accessToken: data.accessToken, refreshToken };\n }\n\n private async refresh(refreshToken: string): Promise<{ accessToken: string; refreshToken: string; }> {\n const url = AuthClient.endpoint(this.restBase, \"auth/refresh\");\n const resp = await AuthClient.fetchWithTimeout(url, {\n method: \"POST\",\n headers: {\n // server expects cookie RefreshToken\n \"Cookie\": `RefreshToken=${refreshToken}`,\n },\n }, 8_000);\n\n if (!resp.ok) {\n throw new Error(`Refresh failed: ${resp.status} ${resp.statusText}`);\n }\n const data = (await resp.json()) as LoginResponse;\n const newRefreshToken = AuthClient.extractRefreshCookie(resp) || refreshToken;\n if (!data?.accessToken) throw new Error(\"Refresh response missing accessToken\");\n return { accessToken: data.accessToken, refreshToken: newRefreshToken };\n }\n\n private async persistTokens(accessToken: string, refreshToken: string): Promise<void> {\n await this.store.set(\"accessToken\", accessToken);\n await this.store.set(\"refreshToken\", refreshToken);\n }\n\n static async promptCredentials(): Promise<{ email: string; password: string }> {\n const rl = readline.createInterface({ input: process.stdin, output: process.stdout, terminal: true });\n\n const ask = (q: string) => new Promise<string>((resolve) => rl.question(q, (ans) => resolve(ans.trim())));\n\n const askMasked = (q: string) => new Promise<string>((resolve) => {\n const anyRl = rl as any;\n const out: any = anyRl.output || process.stdout;\n const origWrite = (anyRl._writeToOutput as ((str: string) => void))?.bind(rl) || ((s: string) => out.write(s));\n anyRl.stdoutMuted = true;\n anyRl._writeToOutput = function (stringToWrite: string) {\n // Keep prompt text intact; mask user input\n if (anyRl.stdoutMuted) {\n if (stringToWrite.startsWith(q)) {\n out.write(stringToWrite);\n } else if (stringToWrite.endsWith(\"\\n\")) {\n out.write(\"\\n\");\n } else {\n out.write(\"*\");\n }\n } else {\n origWrite(stringToWrite);\n }\n };\n rl.question(q, (value) => {\n anyRl.stdoutMuted = false;\n anyRl._writeToOutput = origWrite;\n out.write(\"\\n\");\n resolve(value.trim());\n });\n });\n\n try {\n const email = await ask(\"Email: \");\n const password = await askMasked(\"Password: \");\n rl.close();\n return { email, password };\n } catch (e) {\n rl.close();\n throw e;\n }\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"auth-client.js","sourceRoot":"","sources":["../../../src/tools/auth/auth-client.ts"],"names":[],"mappings":"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","sourcesContent":["import { ConfigFile } from \"../../config-file.js\";\r\nimport { SecureStoreFactory, ISecureStore } from \"./secure-store.js\";\r\nimport jwt from \"jsonwebtoken\";\r\nimport readline from \"readline\";\r\n\r\nconst cfg = await ConfigFile.loadConfig();\r\n\r\ntype LoginResponse = {\r\n accessToken: string;\r\n};\r\n\r\n/**\r\n * AuthClient handles acquiring and refreshing JWT access tokens\r\n * using the configured REST base URL.\r\n */\r\nexport class AuthClient {\r\n private readonly restBase: string;\r\n private readonly namespace: string;\r\n private store!: ISecureStore;\r\n\r\n private constructor(restBase: string) {\r\n this.restBase = restBase.replace(/\\/$/, \"\");\r\n // namespace store by rest base to allow multiple environments\r\n this.namespace = `uns-auth:${this.restBase}`;\r\n }\r\n\r\n static async create(): Promise<AuthClient> {\r\n const restBase: string = cfg?.uns?.rest;\r\n if (!restBase) throw new Error(\"config.uns.rest is not set\");\r\n const client = new AuthClient(restBase);\r\n client.store = await SecureStoreFactory.create(client.namespace);\r\n return client;\r\n }\r\n\r\n async getAccessToken(): Promise<string> {\r\n const accessToken = await this.store.get(\"accessToken\");\r\n const refreshToken = await this.store.get(\"refreshToken\");\r\n\r\n if (accessToken && !AuthClient.isExpired(accessToken)) {\r\n return accessToken;\r\n }\r\n\r\n // Try refresh if we have refresh token\r\n if (refreshToken) {\r\n try {\r\n const refreshed = await this.refresh(refreshToken);\r\n await this.persistTokens(refreshed.accessToken, refreshed.refreshToken);\r\n return refreshed.accessToken;\r\n } catch {\r\n // ignore, fallback to login\r\n }\r\n }\r\n\r\n // First try to get email and password from config\r\n const configEmail = cfg?.uns?.email;\r\n const configPassword = cfg?.uns?.password;\r\n if (typeof configEmail === \"string\" && typeof configPassword === \"string\") {\r\n try {\r\n const loggedIn = await this.login(configEmail, configPassword);\r\n await this.persistTokens(loggedIn.accessToken, loggedIn.refreshToken);\r\n return loggedIn.accessToken;\r\n } catch {\r\n // ignore, fallback to interactive login\r\n }\r\n }\r\n\r\n // Interactive login\r\n const { email, password } = await AuthClient.promptCredentials();\r\n const loggedIn = await this.login(email, password);\r\n await this.persistTokens(loggedIn.accessToken, loggedIn.refreshToken);\r\n return loggedIn.accessToken;\r\n }\r\n\r\n private static isExpired(token: string, skewSeconds = 30): boolean {\r\n try {\r\n const decoded: any = jwt.decode(token);\r\n if (!decoded || typeof decoded !== \"object\" || !decoded.exp) return true;\r\n const now = Math.floor(Date.now() / 1000);\r\n return decoded.exp <= now + skewSeconds;\r\n } catch {\r\n return true;\r\n }\r\n }\r\n\r\n private static endpoint(base: string, tail: string): string {\r\n // base ends without trailing slash; tail must not start with slash\r\n const b = base.replace(/\\/$/, \"\");\r\n const t = tail.replace(/^\\//, \"\");\r\n return `${b}/${t}`;\r\n }\r\n\r\n private static async fetchWithTimeout(url: string, init: RequestInit = {}, timeoutMs = 10_000): Promise<Response> {\r\n const controller = new AbortController();\r\n const id = setTimeout(() => controller.abort(), timeoutMs);\r\n try {\r\n const resp = await fetch(url, { ...init, signal: controller.signal });\r\n return resp;\r\n } finally {\r\n clearTimeout(id);\r\n }\r\n }\r\n\r\n private static extractRefreshCookie(resp: Response): string | null {\r\n const anyHeaders: any = resp.headers as any;\r\n const getSetCookie = typeof anyHeaders.getSetCookie === \"function\" ? anyHeaders.getSetCookie.bind(anyHeaders) : null;\r\n const candidates: string[] = getSetCookie ? getSetCookie() : (resp.headers.get(\"set-cookie\") ? [resp.headers.get(\"set-cookie\") as string] : []);\r\n for (const header of candidates) {\r\n const match = header.match(/(?:^|;\\s*)RefreshToken=([^;]+)/i);\r\n if (match) return match[1];\r\n }\r\n return null;\r\n }\r\n\r\n private async login(email: string, password: string): Promise<{ accessToken: string; refreshToken: string; }> {\r\n const url = AuthClient.endpoint(this.restBase, \"auth/login\");\r\n const resp = await AuthClient.fetchWithTimeout(url, {\r\n method: \"POST\",\r\n headers: { \"Content-Type\": \"application/json\" },\r\n body: JSON.stringify({ email, password }),\r\n }, 12_000);\r\n\r\n if (!resp.ok) {\r\n throw new Error(`Login failed: ${resp.status} ${resp.statusText}`);\r\n }\r\n const data = (await resp.json()) as LoginResponse;\r\n const refreshToken = AuthClient.extractRefreshCookie(resp);\r\n if (!data?.accessToken || !refreshToken) {\r\n throw new Error(\"Login response missing tokens\");\r\n }\r\n return { accessToken: data.accessToken, refreshToken };\r\n }\r\n\r\n private async refresh(refreshToken: string): Promise<{ accessToken: string; refreshToken: string; }> {\r\n const url = AuthClient.endpoint(this.restBase, \"auth/refresh\");\r\n const resp = await AuthClient.fetchWithTimeout(url, {\r\n method: \"POST\",\r\n headers: {\r\n // server expects cookie RefreshToken\r\n \"Cookie\": `RefreshToken=${refreshToken}`,\r\n },\r\n }, 8_000);\r\n\r\n if (!resp.ok) {\r\n throw new Error(`Refresh failed: ${resp.status} ${resp.statusText}`);\r\n }\r\n const data = (await resp.json()) as LoginResponse;\r\n const newRefreshToken = AuthClient.extractRefreshCookie(resp) || refreshToken;\r\n if (!data?.accessToken) throw new Error(\"Refresh response missing accessToken\");\r\n return { accessToken: data.accessToken, refreshToken: newRefreshToken };\r\n }\r\n\r\n private async persistTokens(accessToken: string, refreshToken: string): Promise<void> {\r\n await this.store.set(\"accessToken\", accessToken);\r\n await this.store.set(\"refreshToken\", refreshToken);\r\n }\r\n\r\n static async promptCredentials(): Promise<{ email: string; password: string }> {\r\n const rl = readline.createInterface({ input: process.stdin, output: process.stdout, terminal: true });\r\n\r\n const ask = (q: string) => new Promise<string>((resolve) => rl.question(q, (ans) => resolve(ans.trim())));\r\n\r\n const askMasked = (q: string) => new Promise<string>((resolve) => {\r\n const anyRl = rl as any;\r\n const out: any = anyRl.output || process.stdout;\r\n const origWrite = (anyRl._writeToOutput as ((str: string) => void))?.bind(rl) || ((s: string) => out.write(s));\r\n anyRl.stdoutMuted = true;\r\n anyRl._writeToOutput = function (stringToWrite: string) {\r\n // Keep prompt text intact; mask user input\r\n if (anyRl.stdoutMuted) {\r\n if (stringToWrite.startsWith(q)) {\r\n out.write(stringToWrite);\r\n } else if (stringToWrite.endsWith(\"\\n\")) {\r\n out.write(\"\\n\");\r\n } else {\r\n out.write(\"*\");\r\n }\r\n } else {\r\n origWrite(stringToWrite);\r\n }\r\n };\r\n rl.question(q, (value) => {\r\n anyRl.stdoutMuted = false;\r\n anyRl._writeToOutput = origWrite;\r\n out.write(\"\\n\");\r\n resolve(value.trim());\r\n });\r\n });\r\n\r\n try {\r\n const email = await ask(\"Email: \");\r\n const password = await askMasked(\"Password: \");\r\n rl.close();\r\n return { email, password };\r\n } catch (e) {\r\n rl.close();\r\n throw e;\r\n }\r\n }\r\n}\r\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/tools/auth/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC","sourcesContent":["export { AuthClient } from \"./auth-client.js\";\n"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/tools/auth/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC","sourcesContent":["export { AuthClient } from \"./auth-client.js\";\r\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"secure-store.js","sourceRoot":"","sources":["../../../src/tools/auth/secure-store.ts"],"names":[],"mappings":"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","sourcesContent":["import os from \"os\";\nimport path from \"path\";\nimport fs from \"fs\";\n\n/**\n * Abstraction over secure storage for tokens.\n *\n * Prefers OS keychain via `keytar` if available at runtime.\n * Falls back to a local file store with restricted permissions.\n */\nexport interface ISecureStore {\n get(key: string): Promise<string | null>;\n set(key: string, value: string): Promise<void>;\n del(key: string): Promise<void>;\n}\n\n/**\n * Try to lazily import keytar without making it a hard dependency.\n */\nasync function tryLoadKeytar(): Promise<any | null> {\n try {\n // Avoid static import to prevent type resolution errors when not installed\n const dynamicImport = new Function(\"m\", \"return import(m)\") as (m: string) => Promise<any>;\n const mod = await dynamicImport(\"keytar\");\n return (mod && (mod.default || mod)) ?? null;\n } catch {\n return null;\n }\n}\n\nclass KeytarStore implements ISecureStore {\n private service: string;\n private keytar: any;\n constructor(service: string, keytar: any) {\n this.service = service;\n this.keytar = keytar;\n }\n async get(key: string): Promise<string | null> {\n return (await this.keytar.getPassword(this.service, key)) ?? null;\n }\n async set(key: string, value: string): Promise<void> {\n await this.keytar.setPassword(this.service, key, value);\n }\n async del(key: string): Promise<void> {\n await this.keytar.deletePassword(this.service, key);\n }\n}\n\nclass FileStore implements ISecureStore {\n private filePath: string;\n\n constructor(namespace: string) {\n const baseDir = FileStore.resolveBaseDir();\n const folder = path.join(baseDir, \"uns-auth\");\n if (!fs.existsSync(folder)) {\n fs.mkdirSync(folder, { recursive: true, mode: 0o700 });\n }\n this.filePath = path.join(folder, `${FileStore.sanitize(namespace)}.json`);\n if (!fs.existsSync(this.filePath)) {\n fs.writeFileSync(this.filePath, \"{}\", { mode: 0o600 });\n }\n try {\n // tighten permissions if possible (no-op on Windows)\n fs.chmodSync(this.filePath, 0o600);\n } catch {\n // ignore\n }\n }\n\n private static resolveBaseDir(): string {\n if (process.platform === \"win32\") {\n return process.env.APPDATA || path.join(os.homedir(), \"AppData\", \"Roaming\");\n }\n // Linux and macOS default to XDG_CONFIG_HOME or ~/.config\n return process.env.XDG_CONFIG_HOME || path.join(os.homedir(), \".config\");\n }\n\n private static sanitize(name: string): string {\n return name.replace(/[^a-zA-Z0-9_.-]/g, \"_\");\n }\n\n private async load(): Promise<Record<string, string>> {\n try {\n const raw = await fs.promises.readFile(this.filePath, \"utf-8\");\n return JSON.parse(raw || \"{}\");\n } catch {\n return {};\n }\n }\n\n private async save(data: Record<string, string>): Promise<void> {\n const json = JSON.stringify(data, null, 2);\n await fs.promises.writeFile(this.filePath, json, { mode: 0o600 });\n try {\n fs.chmodSync(this.filePath, 0o600);\n } catch {\n // ignore\n }\n }\n\n async get(key: string): Promise<string | null> {\n const data = await this.load();\n return data[key] ?? null;\n }\n\n async set(key: string, value: string): Promise<void> {\n const data = await this.load();\n data[key] = value;\n await this.save(data);\n }\n\n async del(key: string): Promise<void> {\n const data = await this.load();\n delete data[key];\n await this.save(data);\n }\n}\n\nexport class SecureStoreFactory {\n /**\n * Creates a secure store for a namespace. Tries keytar first; falls back to file store.\n */\n static async create(namespace: string): Promise<ISecureStore> {\n const keytar = await tryLoadKeytar();\n if (keytar) {\n return new KeytarStore(namespace, keytar);\n }\n return new FileStore(namespace);\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"secure-store.js","sourceRoot":"","sources":["../../../src/tools/auth/secure-store.ts"],"names":[],"mappings":"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","sourcesContent":["import os from \"os\";\r\nimport path from \"path\";\r\nimport fs from \"fs\";\r\n\r\n/**\r\n * Abstraction over secure storage for tokens.\r\n *\r\n * Prefers OS keychain via `keytar` if available at runtime.\r\n * Falls back to a local file store with restricted permissions.\r\n */\r\nexport interface ISecureStore {\r\n get(key: string): Promise<string | null>;\r\n set(key: string, value: string): Promise<void>;\r\n del(key: string): Promise<void>;\r\n}\r\n\r\n/**\r\n * Try to lazily import keytar without making it a hard dependency.\r\n */\r\nasync function tryLoadKeytar(): Promise<any | null> {\r\n try {\r\n // Avoid static import to prevent type resolution errors when not installed\r\n const dynamicImport = new Function(\"m\", \"return import(m)\") as (m: string) => Promise<any>;\r\n const mod = await dynamicImport(\"keytar\");\r\n return (mod && (mod.default || mod)) ?? null;\r\n } catch {\r\n return null;\r\n }\r\n}\r\n\r\nclass KeytarStore implements ISecureStore {\r\n private service: string;\r\n private keytar: any;\r\n constructor(service: string, keytar: any) {\r\n this.service = service;\r\n this.keytar = keytar;\r\n }\r\n async get(key: string): Promise<string | null> {\r\n return (await this.keytar.getPassword(this.service, key)) ?? null;\r\n }\r\n async set(key: string, value: string): Promise<void> {\r\n await this.keytar.setPassword(this.service, key, value);\r\n }\r\n async del(key: string): Promise<void> {\r\n await this.keytar.deletePassword(this.service, key);\r\n }\r\n}\r\n\r\nclass FileStore implements ISecureStore {\r\n private filePath: string;\r\n\r\n constructor(namespace: string) {\r\n const baseDir = FileStore.resolveBaseDir();\r\n const folder = path.join(baseDir, \"uns-auth\");\r\n if (!fs.existsSync(folder)) {\r\n fs.mkdirSync(folder, { recursive: true, mode: 0o700 });\r\n }\r\n this.filePath = path.join(folder, `${FileStore.sanitize(namespace)}.json`);\r\n if (!fs.existsSync(this.filePath)) {\r\n fs.writeFileSync(this.filePath, \"{}\", { mode: 0o600 });\r\n }\r\n try {\r\n // tighten permissions if possible (no-op on Windows)\r\n fs.chmodSync(this.filePath, 0o600);\r\n } catch {\r\n // ignore\r\n }\r\n }\r\n\r\n private static resolveBaseDir(): string {\r\n if (process.platform === \"win32\") {\r\n return process.env.APPDATA || path.join(os.homedir(), \"AppData\", \"Roaming\");\r\n }\r\n // Linux and macOS default to XDG_CONFIG_HOME or ~/.config\r\n return process.env.XDG_CONFIG_HOME || path.join(os.homedir(), \".config\");\r\n }\r\n\r\n private static sanitize(name: string): string {\r\n return name.replace(/[^a-zA-Z0-9_.-]/g, \"_\");\r\n }\r\n\r\n private async load(): Promise<Record<string, string>> {\r\n try {\r\n const raw = await fs.promises.readFile(this.filePath, \"utf-8\");\r\n return JSON.parse(raw || \"{}\");\r\n } catch {\r\n return {};\r\n }\r\n }\r\n\r\n private async save(data: Record<string, string>): Promise<void> {\r\n const json = JSON.stringify(data, null, 2);\r\n await fs.promises.writeFile(this.filePath, json, { mode: 0o600 });\r\n try {\r\n fs.chmodSync(this.filePath, 0o600);\r\n } catch {\r\n // ignore\r\n }\r\n }\r\n\r\n async get(key: string): Promise<string | null> {\r\n const data = await this.load();\r\n return data[key] ?? null;\r\n }\r\n\r\n async set(key: string, value: string): Promise<void> {\r\n const data = await this.load();\r\n data[key] = value;\r\n await this.save(data);\r\n }\r\n\r\n async del(key: string): Promise<void> {\r\n const data = await this.load();\r\n delete data[key];\r\n await this.save(data);\r\n }\r\n}\r\n\r\nexport class SecureStoreFactory {\r\n /**\r\n * Creates a secure store for a namespace. Tries keytar first; falls back to file store.\r\n */\r\n static async create(namespace: string): Promise<ISecureStore> {\r\n const keytar = await tryLoadKeytar();\r\n if (keytar) {\r\n return new KeytarStore(namespace, keytar);\r\n }\r\n return new FileStore(namespace);\r\n }\r\n}\r\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"base-path.js","sourceRoot":"","sources":["../../src/tools/base-path.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAElD,MAAM,CAAC,MAAM,QAAQ,GAAG,eAAe,EAAE,CAAC","sourcesContent":["import { resolveBasePath } from \"../base-path.js\";\n\nexport const basePath = resolveBasePath();\n"]}
|
|
1
|
+
{"version":3,"file":"base-path.js","sourceRoot":"","sources":["../../src/tools/base-path.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAElD,MAAM,CAAC,MAAM,QAAQ,GAAG,eAAe,EAAE,CAAC","sourcesContent":["import { resolveBasePath } from \"../base-path.js\";\r\n\r\nexport const basePath = resolveBasePath();\r\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"file-utils.js","sourceRoot":"","sources":["../../src/tools/file-utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC9D,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,MAAM,CAAC,KAAK,UAAU,oBAAoB,CAAC,QAAgB;IACzD,MAAM,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,QAAQ,CAAC,CAAC;IAE3D,IAAI,CAAC;QACH,OAAO,MAAM,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC;IAC9C,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAK,KAA+B,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YACvD,OAAO,SAAS,CAAC;QACnB,CAAC;QACD,MAAM,KAAK,CAAC;IACd,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAAC,QAAgB,EAAE,OAAe;IAC5E,MAAM,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,QAAQ,CAAC,CAAC;IAC3D,MAAM,OAAO,GAAG,MAAM,oBAAoB,CAAC,YAAY,CAAC,CAAC;IAEzD,IAAI,OAAO,KAAK,OAAO,EAAE,CAAC;QACxB,OAAO,KAAK,CAAC;IACf,CAAC;IAED,MAAM,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC7D,MAAM,SAAS,CAAC,YAAY,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;IAC/C,OAAO,IAAI,CAAC;AACd,CAAC","sourcesContent":["import { mkdir, readFile, writeFile } from \"node:fs/promises\";\nimport path from \"node:path\";\n\nexport async function readTextFileIfExists(filePath: string): Promise<string | undefined> {\n const absolutePath = path.resolve(process.cwd(), filePath);\n\n try {\n return await readFile(absolutePath, \"utf8\");\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\") {\n return undefined;\n }\n throw error;\n }\n}\n\nexport async function writeTextFileIfChanged(filePath: string, content: string): Promise<boolean> {\n const absolutePath = path.resolve(process.cwd(), filePath);\n const current = await readTextFileIfExists(absolutePath);\n\n if (current === content) {\n return false;\n }\n\n await mkdir(path.dirname(absolutePath), { recursive: true });\n await writeFile(absolutePath, content, \"utf8\");\n return true;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"file-utils.js","sourceRoot":"","sources":["../../src/tools/file-utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC9D,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,MAAM,CAAC,KAAK,UAAU,oBAAoB,CAAC,QAAgB;IACzD,MAAM,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,QAAQ,CAAC,CAAC;IAE3D,IAAI,CAAC;QACH,OAAO,MAAM,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC;IAC9C,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAK,KAA+B,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YACvD,OAAO,SAAS,CAAC;QACnB,CAAC;QACD,MAAM,KAAK,CAAC;IACd,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAAC,QAAgB,EAAE,OAAe;IAC5E,MAAM,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,QAAQ,CAAC,CAAC;IAC3D,MAAM,OAAO,GAAG,MAAM,oBAAoB,CAAC,YAAY,CAAC,CAAC;IAEzD,IAAI,OAAO,KAAK,OAAO,EAAE,CAAC;QACxB,OAAO,KAAK,CAAC;IACf,CAAC;IAED,MAAM,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC7D,MAAM,SAAS,CAAC,YAAY,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;IAC/C,OAAO,IAAI,CAAC;AACd,CAAC","sourcesContent":["import { mkdir, readFile, writeFile } from \"node:fs/promises\";\r\nimport path from \"node:path\";\r\n\r\nexport async function readTextFileIfExists(filePath: string): Promise<string | undefined> {\r\n const absolutePath = path.resolve(process.cwd(), filePath);\r\n\r\n try {\r\n return await readFile(absolutePath, \"utf8\");\r\n } catch (error) {\r\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\") {\r\n return undefined;\r\n }\r\n throw error;\r\n }\r\n}\r\n\r\nexport async function writeTextFileIfChanged(filePath: string, content: string): Promise<boolean> {\r\n const absolutePath = path.resolve(process.cwd(), filePath);\r\n const current = await readTextFileIfExists(absolutePath);\r\n\r\n if (current === content) {\r\n return false;\r\n }\r\n\r\n await mkdir(path.dirname(absolutePath), { recursive: true });\r\n await writeFile(absolutePath, content, \"utf8\");\r\n return true;\r\n}\r\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generate-config-schema.js","sourceRoot":"","sources":["../../src/tools/generate-config-schema.ts"],"names":[],"mappings":"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","sourcesContent":["import fs from \"node:fs\";\nimport path from \"node:path\";\nimport { pathToFileURL } from \"node:url\";\nimport { zodToJsonSchema } from \"zod-to-json-schema\";\nimport { zodToTs, printNode, withGetType } from \"zod-to-ts\";\nimport { z } from \"zod\";\n\nimport { hostValueSchema } from \"../uns-config/host-placeholders.js\";\nimport { secretValueSchema } from \"../uns-config/secret-placeholders.js\";\nimport { composeConfigSchema } from \"../uns-config/schema-tools.js\";\n\nfunction write(filePath: string, data: string) {\n fs.mkdirSync(path.dirname(filePath), { recursive: true });\n fs.writeFileSync(filePath, data);\n}\n\nlet tsLoaderReady = false;\n\nasync function ensureTsLoader(): Promise<void> {\n if (tsLoaderReady) {\n return;\n }\n tsLoaderReady = true;\n try {\n await import(\"tsx/esm\");\n } catch (error) {\n throw new Error(\n \"Unable to load TypeScript project.config.extension. Install 'tsx' (e.g. pnpm add -D tsx) or provide a compiled JavaScript file.\",\n );\n }\n}\n\nasync function loadProjectExtrasSchema(): Promise<z.AnyZodObject> {\n const base = path.resolve(process.cwd(), \"src/config/project.config.extension\");\n const extensions = [\"\", \".ts\", \".mts\", \".tsx\", \".js\", \".mjs\", \".cjs\"];\n\n for (const ext of extensions) {\n const candidate = ext ? `${base}${ext}` : base;\n if (!fs.existsSync(candidate)) {\n continue;\n }\n\n const lowerExt = path.extname(candidate).toLowerCase();\n try {\n if (lowerExt === \".ts\" || lowerExt === \".mts\" || lowerExt === \".tsx\") {\n await ensureTsLoader();\n }\n\n const module = await import(pathToFileURL(candidate).href);\n if (module?.projectExtrasSchema) {\n return module.projectExtrasSchema as z.AnyZodObject;\n }\n\n throw new Error(`Module '${candidate}' does not export projectExtrasSchema.`);\n } catch (error) {\n const reason = error instanceof Error ? error.message : String(error);\n throw new Error(`Failed to load project config extension at '${candidate}': ${reason}`);\n }\n }\n\n const coreModule = await import(\"../config/project.config.extension.js\");\n return coreModule.projectExtrasSchema as z.AnyZodObject;\n}\n\n// Keep placeholder-backed values as plain strings in the generated TypeScript typings so\n// consuming code reflects the resolved shapes while the JSON schema still exposes full unions.\nconst renderAsString = (typescript: any) =>\n typescript.factory.createKeywordTypeNode(typescript.SyntaxKind.StringKeyword);\n\nfor (const schema of [hostValueSchema, secretValueSchema]) {\n withGetType(schema, renderAsString);\n}\n\nconst { unsCoreSchema } = await import(\"../uns-config/uns-core-schema.js\");\nconst projectExtrasSchema = await loadProjectExtrasSchema();\nconst baseSchema = composeConfigSchema(unsCoreSchema, projectExtrasSchema).strict();\n\n// 1) JSON Schema for VS Code $schema\nconst jsonSchema = zodToJsonSchema(baseSchema, \"AppConfig\");\nwrite(path.resolve(\"config.schema.json\"), JSON.stringify(jsonSchema, null, 2));\n\n// 2) TypeScript `export type AppConfig = {...}`\nconst { node } = zodToTs(baseSchema, \"AppConfig\");\nconst interfaceBody = printNode(node);\n\nlet shouldAugment = true;\ntry {\n const pkgJsonPath = path.resolve(process.cwd(), \"package.json\");\n if (fs.existsSync(pkgJsonPath)) {\n const pkg = JSON.parse(fs.readFileSync(pkgJsonPath, \"utf8\"));\n if (pkg?.name === \"@uns-kit/core\") {\n shouldAugment = false;\n }\n }\n} catch {\n shouldAugment = true;\n}\n\nconst augmentationBlock = shouldAugment\n ? `\\n\\ntype GeneratedProjectAppConfig = ProjectAppConfig;\\ntype GeneratedAppConfig = AppConfig;\\n\\ndeclare module \"@uns-kit/core/config/app-config.js\" {\\n interface ProjectAppConfig extends GeneratedProjectAppConfig {}\\n interface AppConfig extends GeneratedAppConfig {}\\n}\\n`\n : \"\\n\";\n\nconst tsContent = `/* Auto-generated. Do not edit by hand. */\\nexport interface ProjectAppConfig ${interfaceBody}\\n\\nexport interface AppConfig extends ProjectAppConfig {}${augmentationBlock}`;\n\nwrite(path.resolve(\"./src/config/app-config.ts\"), tsContent);\n\nconsole.log(\"Generated config.schema.json and updated src/config/app-config.ts\");\n"]}
|
|
1
|
+
{"version":3,"file":"generate-config-schema.js","sourceRoot":"","sources":["../../src/tools/generate-config-schema.ts"],"names":[],"mappings":"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","sourcesContent":["import fs from \"node:fs\";\r\nimport path from \"node:path\";\r\nimport { pathToFileURL } from \"node:url\";\r\nimport { zodToJsonSchema } from \"zod-to-json-schema\";\r\nimport { zodToTs, printNode, withGetType } from \"zod-to-ts\";\r\nimport { z } from \"zod\";\r\n\r\nimport { hostValueSchema } from \"../uns-config/host-placeholders.js\";\r\nimport { secretValueSchema } from \"../uns-config/secret-placeholders.js\";\r\nimport { composeConfigSchema } from \"../uns-config/schema-tools.js\";\r\n\r\nfunction write(filePath: string, data: string) {\r\n fs.mkdirSync(path.dirname(filePath), { recursive: true });\r\n fs.writeFileSync(filePath, data);\r\n}\r\n\r\nlet tsLoaderReady = false;\r\n\r\nasync function ensureTsLoader(): Promise<void> {\r\n if (tsLoaderReady) {\r\n return;\r\n }\r\n tsLoaderReady = true;\r\n try {\r\n await import(\"tsx/esm\");\r\n } catch (error) {\r\n throw new Error(\r\n \"Unable to load TypeScript project.config.extension. Install 'tsx' (e.g. pnpm add -D tsx) or provide a compiled JavaScript file.\",\r\n );\r\n }\r\n}\r\n\r\nasync function loadProjectExtrasSchema(): Promise<z.AnyZodObject> {\r\n const base = path.resolve(process.cwd(), \"src/config/project.config.extension\");\r\n const extensions = [\"\", \".ts\", \".mts\", \".tsx\", \".js\", \".mjs\", \".cjs\"];\r\n\r\n for (const ext of extensions) {\r\n const candidate = ext ? `${base}${ext}` : base;\r\n if (!fs.existsSync(candidate)) {\r\n continue;\r\n }\r\n\r\n const lowerExt = path.extname(candidate).toLowerCase();\r\n try {\r\n if (lowerExt === \".ts\" || lowerExt === \".mts\" || lowerExt === \".tsx\") {\r\n await ensureTsLoader();\r\n }\r\n\r\n const module = await import(pathToFileURL(candidate).href);\r\n if (module?.projectExtrasSchema) {\r\n return module.projectExtrasSchema as z.AnyZodObject;\r\n }\r\n\r\n throw new Error(`Module '${candidate}' does not export projectExtrasSchema.`);\r\n } catch (error) {\r\n const reason = error instanceof Error ? error.message : String(error);\r\n throw new Error(`Failed to load project config extension at '${candidate}': ${reason}`);\r\n }\r\n }\r\n\r\n const coreModule = await import(\"../config/project.config.extension.js\");\r\n return coreModule.projectExtrasSchema as z.AnyZodObject;\r\n}\r\n\r\n// Keep placeholder-backed values as plain strings in the generated TypeScript typings so\r\n// consuming code reflects the resolved shapes while the JSON schema still exposes full unions.\r\nconst renderAsString = (typescript: any) =>\r\n typescript.factory.createKeywordTypeNode(typescript.SyntaxKind.StringKeyword);\r\n\r\nfor (const schema of [hostValueSchema, secretValueSchema]) {\r\n withGetType(schema, renderAsString);\r\n}\r\n\r\nconst { unsCoreSchema } = await import(\"../uns-config/uns-core-schema.js\");\r\nconst projectExtrasSchema = await loadProjectExtrasSchema();\r\nconst baseSchema = composeConfigSchema(unsCoreSchema, projectExtrasSchema).strict();\r\n\r\n// 1) JSON Schema for VS Code $schema\r\nconst jsonSchema = zodToJsonSchema(baseSchema, \"AppConfig\");\r\nwrite(path.resolve(\"config.schema.json\"), JSON.stringify(jsonSchema, null, 2));\r\n\r\n// 2) TypeScript `export type AppConfig = {...}`\r\nconst { node } = zodToTs(baseSchema, \"AppConfig\");\r\nconst interfaceBody = printNode(node);\r\n\r\nlet shouldAugment = true;\r\ntry {\r\n const pkgJsonPath = path.resolve(process.cwd(), \"package.json\");\r\n if (fs.existsSync(pkgJsonPath)) {\r\n const pkg = JSON.parse(fs.readFileSync(pkgJsonPath, \"utf8\"));\r\n if (pkg?.name === \"@uns-kit/core\") {\r\n shouldAugment = false;\r\n }\r\n }\r\n} catch {\r\n shouldAugment = true;\r\n}\r\n\r\nconst augmentationBlock = shouldAugment\r\n ? `\\n\\ntype GeneratedProjectAppConfig = ProjectAppConfig;\\ntype GeneratedAppConfig = AppConfig;\\n\\ndeclare module \"@uns-kit/core/config/app-config.js\" {\\n interface ProjectAppConfig extends GeneratedProjectAppConfig {}\\n interface AppConfig extends GeneratedAppConfig {}\\n}\\n`\r\n : \"\\n\";\r\n\r\nconst tsContent = `/* Auto-generated. Do not edit by hand. */\\nexport interface ProjectAppConfig ${interfaceBody}\\n\\nexport interface AppConfig extends ProjectAppConfig {}${augmentationBlock}`;\r\n\r\nwrite(path.resolve(\"./src/config/app-config.ts\"), tsContent);\r\n\r\nconsole.log(\"Generated config.schema.json and updated src/config/app-config.ts\");\r\n"]}
|
|
@@ -53,13 +53,13 @@ function parseArgs(argv) {
|
|
|
53
53
|
return { input, output, lang };
|
|
54
54
|
}
|
|
55
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
|
|
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
63
|
`);
|
|
64
64
|
}
|
|
65
65
|
async function readDictionaryFromJson(filePath) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generate-uns-dictionary.js","sourceRoot":"","sources":["../../src/tools/generate-uns-dictionary.ts"],"names":[],"mappings":"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","sourcesContent":["#!/usr/bin/env node\n/**\n * Generate a TypeScript dictionary of object types and attributes (with descriptions)\n * from a JSON file. The output is meant for IntelliSense and metadata enrichment\n * (e.g., emitting descriptions alongside topics). No GraphQL calls are performed.\n *\n * JSON shape (example):\n * {\n * \"objectTypes\": {\n * \"energy-resource\": { \"description\": \"Energy carriers (electricity/steam/gas)\" },\n * \"custom-type\": { \"description\": \"Tenant-specific thing\" }\n * },\n * \"attributes\": {\n * \"cumulative-active-energy-delivered\": { \"description\": \"kWh total\" },\n * \"status\": { \"description\": \"Generic status\" }\n * }\n * }\n */\nimport { readFile } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { pathToFileURL } from \"node:url\";\nimport { writeTextFileIfChanged } from \"./file-utils.js\";\n\ntype DictionaryEntry = {\n description?: string | null;\n descriptions?: Record<string, string | null | undefined>;\n [key: string]: unknown;\n};\ntype ObjectTypeEntry = DictionaryEntry & {\n attributes?: string[] | null;\n};\ntype UnsDictionary = {\n schemaVersion?: unknown;\n objectTypes?: Record<string, ObjectTypeEntry>;\n attributes?: Record<string, DictionaryEntry>;\n [key: string]: unknown;\n};\n\ntype CliArgs = {\n input: string;\n output: string;\n lang: string;\n};\n\nconst DEFAULT_INPUT = \"uns-dictionary.json\";\nconst DEFAULT_OUTPUT = path.resolve(process.cwd(), \"src/uns/uns-dictionary.generated.ts\");\n\nasync function main(): Promise<void> {\n const args = parseArgs(process.argv.slice(2));\n await generateUnsDictionary(args);\n}\n\nfunction parseArgs(argv: string[]): CliArgs {\n let input = DEFAULT_INPUT;\n let output = DEFAULT_OUTPUT;\n let lang = \"sl\";\n\n for (let i = 0; i < argv.length; i++) {\n const arg = argv[i];\n if (arg === \"--input\" && argv[i + 1]) {\n input = argv[++i];\n continue;\n }\n if (arg === \"--output\" && argv[i + 1]) {\n output = argv[++i];\n continue;\n }\n if (arg === \"--lang\" && argv[i + 1]) {\n lang = argv[++i];\n continue;\n }\n if (arg === \"--help\" || arg === \"-h\") {\n printHelp();\n process.exit(0);\n }\n throw new Error(`Unknown argument: ${arg}`);\n }\n\n return { input, output, lang };\n}\n\nfunction printHelp(): void {\n console.log(`Usage: tsx packages/uns-core/src/tools/generate-uns-dictionary.ts [options]\n\nOptions:\n --input <file> Path to uns-dictionary.json (default: ${DEFAULT_INPUT})\n --output <file> Path to generated TS file (default: src/uns/uns-dictionary.generated.ts)\n --lang <code> Preferred description language code (default: \"sl\")\n --help, -h Show this help\n`);\n}\n\nasync function readDictionaryFromJson(filePath: string): Promise<UnsDictionary> {\n const absolute = path.resolve(process.cwd(), filePath);\n const raw = await readFile(absolute, \"utf8\");\n return JSON.parse(raw) as UnsDictionary;\n}\n\nexport async function generateUnsDictionary(args: Partial<CliArgs>): Promise<void> {\n const effective: CliArgs = {\n input: args.input ?? DEFAULT_INPUT,\n output: args.output ?? DEFAULT_OUTPUT,\n lang: args.lang ?? \"sl\",\n };\n\n const dictionary = await readDictionaryFromJson(effective.input);\n const changed = await writeDictionaryTs(dictionary, effective.output, effective.lang);\n console.log(`Generated dictionary -> ${effective.output}${changed ? \"\" : \" (unchanged)\"}`);\n}\n\nconst resolveDescription = (entry: DictionaryEntry | undefined, lang: string): string | undefined => {\n if (!entry) return undefined;\n const byLang = entry.descriptions?.[lang];\n if (byLang && byLang.length > 0) return byLang;\n if (entry.description && entry.description.length > 0) return entry.description;\n return undefined;\n};\n\nfunction renderDoc(description: string | undefined, indent: string): string {\n if (!description) return \"\";\n const normalized = description\n .replaceAll(\"*/\", \"*\\\\/\")\n .split(/\\r?\\n/)\n .map((line) => `${indent} * ${line}`)\n .join(\"\\n\");\n return `${indent}/**\\n${normalized}\\n${indent} */\\n`;\n}\n\nexport function renderDictionaryTs(dictionary: UnsDictionary, lang: string): string {\n const objectTypeEntries = Object.entries(dictionary.objectTypes ?? {}).sort(([left], [right]) => left.localeCompare(right));\n const attributeEntries = Object.entries(dictionary.attributes ?? {}).sort(([left], [right]) => left.localeCompare(right));\n const attributesByType: Record<string, string[]> = {};\n for (const [name, entry] of objectTypeEntries) {\n if (Array.isArray(entry.attributes) && entry.attributes.length > 0) {\n attributesByType[name] = entry.attributes.filter(\n (attribute): attribute is string => typeof attribute === \"string\" && attribute.length > 0,\n );\n }\n }\n\n const renderRecord = (entries: [string, DictionaryEntry][]) =>\n entries\n .map(([name, entry]) => {\n const desc = resolveDescription(entry, lang);\n const doc = renderDoc(desc, \" \");\n return `${doc} \"${name}\": \"${name}\",`;\n })\n .join(\"\\n\");\n\n const renderDescriptions = (entries: [string, DictionaryEntry][]) =>\n entries\n .map(([name, value]) => ` \"${name}\": ${JSON.stringify(resolveDescription(value, lang) ?? \"\")},`)\n .join(\"\\n\");\n\n const objectTypeConst = `export const GeneratedObjectTypes = {\\n${renderRecord(objectTypeEntries)}\\n} as const;`;\n const objectTypeDescConst = `export const GeneratedObjectTypeDescriptions: Record<keyof typeof GeneratedObjectTypes, string> = {\\n${renderDescriptions(objectTypeEntries)}\\n};`;\n\n const attributeConst = `export const GeneratedAttributes = {\\n${renderRecord(attributeEntries)}\\n} as const;`;\n const attributeDescConst = `export const GeneratedAttributeDescriptions: Record<keyof typeof GeneratedAttributes, string> = {\\n${renderDescriptions(attributeEntries)}\\n};`;\n\n const renderAttributesByType = () => {\n const blocks: string[] = [];\n for (const [objectType, attrs] of Object.entries(attributesByType)) {\n if (!attrs.length) continue;\n const lines = attrs\n .map((attr) => {\n const desc = resolveDescription(dictionary.attributes?.[attr], lang);\n const doc = renderDoc(desc, \" \");\n return `${doc} \"${attr}\": \"${attr}\",`;\n })\n .join(\"\\n\");\n blocks.push(` \"${objectType}\": {\\n${lines}\\n },`);\n }\n return blocks.join(\"\\n\");\n };\n\n const attributesByTypeConst = `const GeneratedAttributesByTypeBase = {\\n${renderAttributesByType()}\\n} as const;\\n\\nexport const GeneratedAttributesByType = GeneratedAttributesByTypeBase;`;\n\n 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`;\n}\n\nasync function writeDictionaryTs(dictionary: UnsDictionary, filePath: string, lang: string): Promise<boolean> {\n const content = renderDictionaryTs(dictionary, lang);\n return writeTextFileIfChanged(filePath, content);\n}\n\nconst isDirectExecution = process.argv[1]\n ? import.meta.url === pathToFileURL(path.resolve(process.argv[1])).href\n : false;\n\nif (isDirectExecution) {\n main().catch((error) => {\n console.error(\"Failed to generate UNS dictionary:\", error);\n process.exitCode = 1;\n });\n}\n"]}
|
|
1
|
+
{"version":3,"file":"generate-uns-dictionary.js","sourceRoot":"","sources":["../../src/tools/generate-uns-dictionary.ts"],"names":[],"mappings":"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","sourcesContent":["#!/usr/bin/env node\r\n/**\r\n * Generate a TypeScript dictionary of object types and attributes (with descriptions)\r\n * from a JSON file. The output is meant for IntelliSense and metadata enrichment\r\n * (e.g., emitting descriptions alongside topics). No GraphQL calls are performed.\r\n *\r\n * JSON shape (example):\r\n * {\r\n * \"objectTypes\": {\r\n * \"energy-resource\": { \"description\": \"Energy carriers (electricity/steam/gas)\" },\r\n * \"custom-type\": { \"description\": \"Tenant-specific thing\" }\r\n * },\r\n * \"attributes\": {\r\n * \"cumulative-active-energy-delivered\": { \"description\": \"kWh total\" },\r\n * \"status\": { \"description\": \"Generic status\" }\r\n * }\r\n * }\r\n */\r\nimport { readFile } from \"node:fs/promises\";\r\nimport path from \"node:path\";\r\nimport { pathToFileURL } from \"node:url\";\r\nimport { writeTextFileIfChanged } from \"./file-utils.js\";\r\n\r\ntype DictionaryEntry = {\r\n description?: string | null;\r\n descriptions?: Record<string, string | null | undefined>;\r\n [key: string]: unknown;\r\n};\r\ntype ObjectTypeEntry = DictionaryEntry & {\r\n attributes?: string[] | null;\r\n};\r\ntype UnsDictionary = {\r\n schemaVersion?: unknown;\r\n objectTypes?: Record<string, ObjectTypeEntry>;\r\n attributes?: Record<string, DictionaryEntry>;\r\n [key: string]: unknown;\r\n};\r\n\r\ntype CliArgs = {\r\n input: string;\r\n output: string;\r\n lang: string;\r\n};\r\n\r\nconst DEFAULT_INPUT = \"uns-dictionary.json\";\r\nconst DEFAULT_OUTPUT = path.resolve(process.cwd(), \"src/uns/uns-dictionary.generated.ts\");\r\n\r\nasync function main(): Promise<void> {\r\n const args = parseArgs(process.argv.slice(2));\r\n await generateUnsDictionary(args);\r\n}\r\n\r\nfunction parseArgs(argv: string[]): CliArgs {\r\n let input = DEFAULT_INPUT;\r\n let output = DEFAULT_OUTPUT;\r\n let lang = \"sl\";\r\n\r\n for (let i = 0; i < argv.length; i++) {\r\n const arg = argv[i];\r\n if (arg === \"--input\" && argv[i + 1]) {\r\n input = argv[++i];\r\n continue;\r\n }\r\n if (arg === \"--output\" && argv[i + 1]) {\r\n output = argv[++i];\r\n continue;\r\n }\r\n if (arg === \"--lang\" && argv[i + 1]) {\r\n lang = argv[++i];\r\n continue;\r\n }\r\n if (arg === \"--help\" || arg === \"-h\") {\r\n printHelp();\r\n process.exit(0);\r\n }\r\n throw new Error(`Unknown argument: ${arg}`);\r\n }\r\n\r\n return { input, output, lang };\r\n}\r\n\r\nfunction printHelp(): void {\r\n console.log(`Usage: tsx packages/uns-core/src/tools/generate-uns-dictionary.ts [options]\r\n\r\nOptions:\r\n --input <file> Path to uns-dictionary.json (default: ${DEFAULT_INPUT})\r\n --output <file> Path to generated TS file (default: src/uns/uns-dictionary.generated.ts)\r\n --lang <code> Preferred description language code (default: \"sl\")\r\n --help, -h Show this help\r\n`);\r\n}\r\n\r\nasync function readDictionaryFromJson(filePath: string): Promise<UnsDictionary> {\r\n const absolute = path.resolve(process.cwd(), filePath);\r\n const raw = await readFile(absolute, \"utf8\");\r\n return JSON.parse(raw) as UnsDictionary;\r\n}\r\n\r\nexport async function generateUnsDictionary(args: Partial<CliArgs>): Promise<void> {\r\n const effective: CliArgs = {\r\n input: args.input ?? DEFAULT_INPUT,\r\n output: args.output ?? DEFAULT_OUTPUT,\r\n lang: args.lang ?? \"sl\",\r\n };\r\n\r\n const dictionary = await readDictionaryFromJson(effective.input);\r\n const changed = await writeDictionaryTs(dictionary, effective.output, effective.lang);\r\n console.log(`Generated dictionary -> ${effective.output}${changed ? \"\" : \" (unchanged)\"}`);\r\n}\r\n\r\nconst resolveDescription = (entry: DictionaryEntry | undefined, lang: string): string | undefined => {\r\n if (!entry) return undefined;\r\n const byLang = entry.descriptions?.[lang];\r\n if (byLang && byLang.length > 0) return byLang;\r\n if (entry.description && entry.description.length > 0) return entry.description;\r\n return undefined;\r\n};\r\n\r\nfunction renderDoc(description: string | undefined, indent: string): string {\r\n if (!description) return \"\";\r\n const normalized = description\r\n .replaceAll(\"*/\", \"*\\\\/\")\r\n .split(/\\r?\\n/)\r\n .map((line) => `${indent} * ${line}`)\r\n .join(\"\\n\");\r\n return `${indent}/**\\n${normalized}\\n${indent} */\\n`;\r\n}\r\n\r\nexport function renderDictionaryTs(dictionary: UnsDictionary, lang: string): string {\r\n const objectTypeEntries = Object.entries(dictionary.objectTypes ?? {}).sort(([left], [right]) => left.localeCompare(right));\r\n const attributeEntries = Object.entries(dictionary.attributes ?? {}).sort(([left], [right]) => left.localeCompare(right));\r\n const attributesByType: Record<string, string[]> = {};\r\n for (const [name, entry] of objectTypeEntries) {\r\n if (Array.isArray(entry.attributes) && entry.attributes.length > 0) {\r\n attributesByType[name] = entry.attributes.filter(\r\n (attribute): attribute is string => typeof attribute === \"string\" && attribute.length > 0,\r\n );\r\n }\r\n }\r\n\r\n const renderRecord = (entries: [string, DictionaryEntry][]) =>\r\n entries\r\n .map(([name, entry]) => {\r\n const desc = resolveDescription(entry, lang);\r\n const doc = renderDoc(desc, \" \");\r\n return `${doc} \"${name}\": \"${name}\",`;\r\n })\r\n .join(\"\\n\");\r\n\r\n const renderDescriptions = (entries: [string, DictionaryEntry][]) =>\r\n entries\r\n .map(([name, value]) => ` \"${name}\": ${JSON.stringify(resolveDescription(value, lang) ?? \"\")},`)\r\n .join(\"\\n\");\r\n\r\n const objectTypeConst = `export const GeneratedObjectTypes = {\\n${renderRecord(objectTypeEntries)}\\n} as const;`;\r\n const objectTypeDescConst = `export const GeneratedObjectTypeDescriptions: Record<keyof typeof GeneratedObjectTypes, string> = {\\n${renderDescriptions(objectTypeEntries)}\\n};`;\r\n\r\n const attributeConst = `export const GeneratedAttributes = {\\n${renderRecord(attributeEntries)}\\n} as const;`;\r\n const attributeDescConst = `export const GeneratedAttributeDescriptions: Record<keyof typeof GeneratedAttributes, string> = {\\n${renderDescriptions(attributeEntries)}\\n};`;\r\n\r\n const renderAttributesByType = () => {\r\n const blocks: string[] = [];\r\n for (const [objectType, attrs] of Object.entries(attributesByType)) {\r\n if (!attrs.length) continue;\r\n const lines = attrs\r\n .map((attr) => {\r\n const desc = resolveDescription(dictionary.attributes?.[attr], lang);\r\n const doc = renderDoc(desc, \" \");\r\n return `${doc} \"${attr}\": \"${attr}\",`;\r\n })\r\n .join(\"\\n\");\r\n blocks.push(` \"${objectType}\": {\\n${lines}\\n },`);\r\n }\r\n return blocks.join(\"\\n\");\r\n };\r\n\r\n const attributesByTypeConst = `const GeneratedAttributesByTypeBase = {\\n${renderAttributesByType()}\\n} as const;\\n\\nexport const GeneratedAttributesByType = GeneratedAttributesByTypeBase;`;\r\n\r\n 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`;\r\n}\r\n\r\nasync function writeDictionaryTs(dictionary: UnsDictionary, filePath: string, lang: string): Promise<boolean> {\r\n const content = renderDictionaryTs(dictionary, lang);\r\n return writeTextFileIfChanged(filePath, content);\r\n}\r\n\r\nconst isDirectExecution = process.argv[1]\r\n ? import.meta.url === pathToFileURL(path.resolve(process.argv[1])).href\r\n : false;\r\n\r\nif (isDirectExecution) {\r\n main().catch((error) => {\r\n console.error(\"Failed to generate UNS dictionary:\", error);\r\n process.exitCode = 1;\r\n });\r\n}\r\n"]}
|
|
@@ -53,13 +53,13 @@ function parseArgs(argv) {
|
|
|
53
53
|
return { input, output, lang };
|
|
54
54
|
}
|
|
55
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
|
|
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
63
|
`);
|
|
64
64
|
}
|
|
65
65
|
async function loadJson(filePath) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generate-uns-measurements.js","sourceRoot":"","sources":["../../src/tools/generate-uns-measurements.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;;;;;;GAgBG;AACH,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,sBAAsB,EAAE,MAAM,iBAAiB,CAAC;AAgBzD,MAAM,aAAa,GAAG,uBAAuB,CAAC;AAC9C,MAAM,cAAc,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,uCAAuC,CAAC,CAAC;AAE5F,KAAK,UAAU,IAAI;IACjB,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IACjE,MAAM,uBAAuB,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;AACzD,CAAC;AAED,SAAS,SAAS,CAAC,IAAc;IAC/B,IAAI,KAAK,GAAG,aAAa,CAAC;IAC1B,IAAI,MAAM,GAAG,cAAc,CAAC;IAC5B,IAAI,IAAI,GAAG,IAAI,CAAC;IAEhB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACrC,MAAM,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QACpB,IAAI,GAAG,KAAK,SAAS,IAAI,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC;YACrC,KAAK,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;YAClB,SAAS;QACX,CAAC;QACD,IAAI,GAAG,KAAK,UAAU,IAAI,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC;YACtC,MAAM,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;YACnB,SAAS;QACX,CAAC;QACD,IAAI,GAAG,KAAK,QAAQ,IAAI,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC;YACpC,IAAI,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;YACjB,SAAS;QACX,CAAC;QACD,IAAI,GAAG,KAAK,QAAQ,IAAI,GAAG,KAAK,IAAI,EAAE,CAAC;YACrC,SAAS,EAAE,CAAC;YACZ,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QACD,MAAM,IAAI,KAAK,CAAC,qBAAqB,GAAG,EAAE,CAAC,CAAC;IAC9C,CAAC;IAED,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;AACjC,CAAC;AAED,SAAS,SAAS;IAChB,OAAO,CAAC,GAAG,CAAC;;;6DAG+C,aAAa;;;;CAIzE,CAAC,CAAC;AACH,CAAC;AAED,KAAK,UAAU,QAAQ,CAAC,QAAgB;IACtC,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,QAAQ,CAAC,CAAC;IAClD,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;IACxC,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAqB,CAAC;AAC7C,CAAC;AAED,MAAM,WAAW,GAAG,CAAC,KAAwB,EAAE,IAAY,EAAsB,EAAE;IACjF,IAAI,CAAC,KAAK;QAAE,OAAO,SAAS,CAAC;IAC7B,MAAM,MAAM,GAAG,KAAK,CAAC,YAAY,EAAE,CAAC,IAAI,CAAC,CAAC;IAC1C,IAAI,MAAM,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC;QAAE,OAAO,MAAM,CAAC;IAC/C,IAAI,KAAK,CAAC,WAAW,IAAI,KAAK,CAAC,WAAW,CAAC,MAAM,GAAG,CAAC;QAAE,OAAO,KAAK,CAAC,WAAW,CAAC;IAChF,OAAO,SAAS,CAAC;AACnB,CAAC,CAAC;AAEF,SAAS,aAAa,CAAC,IAAY,EAAE,OAA0C,EAAE,IAAY;IAC3F,IAAI,CAAC,OAAO;QAAE,OAAO,gBAAgB,IAAI,iBAAiB,CAAC;IAC3D,MAAM,KAAK,GAAG,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC;SAClC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;SACpD,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,EAAE;QACpB,MAAM,IAAI,GAAG,WAAW,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;QACtC,MAAM,GAAG,GAAG,SAAS,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;QAClC,OAAO,GAAG,GAAG,MAAM,GAAG,OAAO,KAAK,CAAC,KAAK,IAAI,CAAC;IAC/C,CAAC,CAAC;SACD,IAAI,CAAC,IAAI,CAAC,CAAC;IACd,OAAO,gBAAgB,IAAI,SAAS,KAAK,eAAe,CAAC;AAC3D,CAAC;AAED,SAAS,SAAS,CAAC,WAA+B,EAAE,MAAc;IAChE,IAAI,CAAC,WAAW;QAAE,OAAO,EAAE,CAAC;IAC5B,MAAM,UAAU,GAAG,WAAW;SAC3B,UAAU,CAAC,IAAI,EAAE,MAAM,CAAC;SACxB,KAAK,CAAC,OAAO,CAAC;SACd,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,GAAG,MAAM,MAAM,IAAI,EAAE,CAAC;SACpC,IAAI,CAAC,IAAI,CAAC,CAAC;IACd,OAAO,GAAG,MAAM,QAAQ,UAAU,KAAK,MAAM,OAAO,CAAC;AACvD,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,IAAsB,EAAE,IAAY;IACvE,MAAM,QAAQ,GAAG,aAAa,CAAC,+BAA+B,EAAE,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;IACrF,MAAM,QAAQ,GAAG,aAAa,CAAC,+BAA+B,EAAE,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;IACrF,MAAM,OAAO,GAAG,aAAa,CAAC,8BAA8B,EAAE,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;IAElF,OAAO,+EAA+E,QAAQ,OAAO,QAAQ,OAAO,OAAO,ghBAAghB,CAAC;AAC9oB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAC3C,IAA8D;IAE9D,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,IAAI,aAAa,CAAC;IAC1C,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,IAAI,cAAc,CAAC;IAC7C,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC;IAE/B,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,KAAK,CAAC,CAAC;IACnC,MAAM,OAAO,GAAG,oBAAoB,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IACjD,MAAM,OAAO,GAAG,MAAM,sBAAsB,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC9D,OAAO,CAAC,GAAG,CAAC,6BAA6B,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,cAAc,EAAE,CAAC,CAAC;AACrF,CAAC;AAED,MAAM,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;IACvC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,KAAK,aAAa,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI;IACvE,CAAC,CAAC,KAAK,CAAC;AAEV,IAAI,iBAAiB,EAAE,CAAC;IACtB,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;QACnB,OAAO,CAAC,KAAK,CAAC,kCAAkC,EAAE,GAAG,CAAC,CAAC;QACvD,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;IACvB,CAAC,CAAC,CAAC;AACL,CAAC","sourcesContent":["#!/usr/bin/env node\n/**\n * Generate a TypeScript helper for measurements from a JSON file.\n *\n * JSON shape (example):\n * {\n * \"physical\": {\n * \"None\": { \"value\": \"\", \"description\": \"Brez enote\" },\n * \"Celsius\": { \"value\": \"°C\", \"description\": \"Stopinje Celzija\" }\n * },\n * \"dataSize\": {\n * \"Bit\": { \"value\": \"bit\", \"description\": \"Bit\" }\n * },\n * \"counter\": {\n * \"Kilo\": { \"value\": \"k\", \"description\": \"Kilo\" }\n * }\n * }\n */\nimport { readFile } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { pathToFileURL } from \"node:url\";\nimport { writeTextFileIfChanged } from \"./file-utils.js\";\n\ntype Entry = {\n value: string;\n description?: string | null;\n descriptions?: Record<string, string | null | undefined>;\n [key: string]: unknown;\n};\ntype MeasurementsJson = {\n schemaVersion?: unknown;\n physical?: Record<string, Entry>;\n dataSize?: Record<string, Entry>;\n counter?: Record<string, Entry>;\n [category: string]: unknown;\n};\n\nconst DEFAULT_INPUT = \"uns-measurements.json\";\nconst DEFAULT_OUTPUT = path.resolve(process.cwd(), \"src/uns/uns-measurements.generated.ts\");\n\nasync function main() {\n const { input, output, lang } = parseArgs(process.argv.slice(2));\n await generateUnsMeasurements({ input, output, lang });\n}\n\nfunction parseArgs(argv: string[]) {\n let input = DEFAULT_INPUT;\n let output = DEFAULT_OUTPUT;\n let lang = \"sl\";\n\n for (let i = 0; i < argv.length; i++) {\n const arg = argv[i];\n if (arg === \"--input\" && argv[i + 1]) {\n input = argv[++i];\n continue;\n }\n if (arg === \"--output\" && argv[i + 1]) {\n output = argv[++i];\n continue;\n }\n if (arg === \"--lang\" && argv[i + 1]) {\n lang = argv[++i];\n continue;\n }\n if (arg === \"--help\" || arg === \"-h\") {\n printHelp();\n process.exit(0);\n }\n throw new Error(`Unknown argument: ${arg}`);\n }\n\n return { input, output, lang };\n}\n\nfunction printHelp(): void {\n console.log(`Usage: tsx packages/uns-core/src/tools/generate-uns-measurements.ts [options]\n\nOptions:\n --input <file> Path to uns-measurements.json (default: ${DEFAULT_INPUT})\n --output <file> Path to generated TS file (default: src/uns/uns-measurements.generated.ts)\n --lang <code> Preferred description language (default: \"sl\")\n --help, -h Show this help\n`);\n}\n\nasync function loadJson(filePath: string): Promise<MeasurementsJson> {\n const abs = path.resolve(process.cwd(), filePath);\n const raw = await readFile(abs, \"utf8\");\n return JSON.parse(raw) as MeasurementsJson;\n}\n\nconst resolveDesc = (entry: Entry | undefined, lang: string): string | undefined => {\n if (!entry) return undefined;\n const byLang = entry.descriptions?.[lang];\n if (byLang && byLang.length > 0) return byLang;\n if (entry.description && entry.description.length > 0) return entry.description;\n return undefined;\n};\n\nfunction renderSection(name: string, entries: Record<string, Entry> | undefined, lang: string): string {\n if (!entries) return `export const ${name} = {} as const;`;\n const lines = Object.entries(entries)\n .sort(([left], [right]) => left.localeCompare(right))\n .map(([key, entry]) => {\n const desc = resolveDesc(entry, lang);\n const doc = renderDoc(desc, \" \");\n return `${doc} \"${key}\": \"${entry.value}\",`;\n })\n .join(\"\\n\");\n return `export const ${name} = {\\n${lines}\\n} as const;`;\n}\n\nfunction renderDoc(description: string | undefined, indent: string): string {\n if (!description) return \"\";\n const normalized = description\n .replaceAll(\"*/\", \"*\\\\/\")\n .split(/\\r?\\n/)\n .map((line) => `${indent} * ${line}`)\n .join(\"\\n\");\n return `${indent}/**\\n${normalized}\\n${indent} */\\n`;\n}\n\nexport function renderMeasurementsTs(json: MeasurementsJson, lang: string): string {\n const physical = renderSection(\"GeneratedPhysicalMeasurements\", json.physical, lang);\n const dataSize = renderSection(\"GeneratedDataSizeMeasurements\", json.dataSize, lang);\n const counter = renderSection(\"GeneratedCounterMeasurements\", json.counter, lang);\n\n 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`;\n}\n\nexport async function generateUnsMeasurements(\n args: Partial<{ input: string; output: string; lang: string }>,\n): Promise<void> {\n const input = args.input ?? DEFAULT_INPUT;\n const output = args.output ?? DEFAULT_OUTPUT;\n const lang = args.lang ?? \"sl\";\n\n const json = await loadJson(input);\n const content = renderMeasurementsTs(json, lang);\n const changed = await writeTextFileIfChanged(output, content);\n console.log(`Generated measurements -> ${output}${changed ? \"\" : \" (unchanged)\"}`);\n}\n\nconst isDirectExecution = process.argv[1]\n ? import.meta.url === pathToFileURL(path.resolve(process.argv[1])).href\n : false;\n\nif (isDirectExecution) {\n main().catch((err) => {\n console.error(\"Failed to generate measurements:\", err);\n process.exitCode = 1;\n });\n}\n"]}
|
|
1
|
+
{"version":3,"file":"generate-uns-measurements.js","sourceRoot":"","sources":["../../src/tools/generate-uns-measurements.ts"],"names":[],"mappings":"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","sourcesContent":["#!/usr/bin/env node\r\n/**\r\n * Generate a TypeScript helper for measurements from a JSON file.\r\n *\r\n * JSON shape (example):\r\n * {\r\n * \"physical\": {\r\n * \"None\": { \"value\": \"\", \"description\": \"Brez enote\" },\r\n * \"Celsius\": { \"value\": \"°C\", \"description\": \"Stopinje Celzija\" }\r\n * },\r\n * \"dataSize\": {\r\n * \"Bit\": { \"value\": \"bit\", \"description\": \"Bit\" }\r\n * },\r\n * \"counter\": {\r\n * \"Kilo\": { \"value\": \"k\", \"description\": \"Kilo\" }\r\n * }\r\n * }\r\n */\r\nimport { readFile } from \"node:fs/promises\";\r\nimport path from \"node:path\";\r\nimport { pathToFileURL } from \"node:url\";\r\nimport { writeTextFileIfChanged } from \"./file-utils.js\";\r\n\r\ntype Entry = {\r\n value: string;\r\n description?: string | null;\r\n descriptions?: Record<string, string | null | undefined>;\r\n [key: string]: unknown;\r\n};\r\ntype MeasurementsJson = {\r\n schemaVersion?: unknown;\r\n physical?: Record<string, Entry>;\r\n dataSize?: Record<string, Entry>;\r\n counter?: Record<string, Entry>;\r\n [category: string]: unknown;\r\n};\r\n\r\nconst DEFAULT_INPUT = \"uns-measurements.json\";\r\nconst DEFAULT_OUTPUT = path.resolve(process.cwd(), \"src/uns/uns-measurements.generated.ts\");\r\n\r\nasync function main() {\r\n const { input, output, lang } = parseArgs(process.argv.slice(2));\r\n await generateUnsMeasurements({ input, output, lang });\r\n}\r\n\r\nfunction parseArgs(argv: string[]) {\r\n let input = DEFAULT_INPUT;\r\n let output = DEFAULT_OUTPUT;\r\n let lang = \"sl\";\r\n\r\n for (let i = 0; i < argv.length; i++) {\r\n const arg = argv[i];\r\n if (arg === \"--input\" && argv[i + 1]) {\r\n input = argv[++i];\r\n continue;\r\n }\r\n if (arg === \"--output\" && argv[i + 1]) {\r\n output = argv[++i];\r\n continue;\r\n }\r\n if (arg === \"--lang\" && argv[i + 1]) {\r\n lang = argv[++i];\r\n continue;\r\n }\r\n if (arg === \"--help\" || arg === \"-h\") {\r\n printHelp();\r\n process.exit(0);\r\n }\r\n throw new Error(`Unknown argument: ${arg}`);\r\n }\r\n\r\n return { input, output, lang };\r\n}\r\n\r\nfunction printHelp(): void {\r\n console.log(`Usage: tsx packages/uns-core/src/tools/generate-uns-measurements.ts [options]\r\n\r\nOptions:\r\n --input <file> Path to uns-measurements.json (default: ${DEFAULT_INPUT})\r\n --output <file> Path to generated TS file (default: src/uns/uns-measurements.generated.ts)\r\n --lang <code> Preferred description language (default: \"sl\")\r\n --help, -h Show this help\r\n`);\r\n}\r\n\r\nasync function loadJson(filePath: string): Promise<MeasurementsJson> {\r\n const abs = path.resolve(process.cwd(), filePath);\r\n const raw = await readFile(abs, \"utf8\");\r\n return JSON.parse(raw) as MeasurementsJson;\r\n}\r\n\r\nconst resolveDesc = (entry: Entry | undefined, lang: string): string | undefined => {\r\n if (!entry) return undefined;\r\n const byLang = entry.descriptions?.[lang];\r\n if (byLang && byLang.length > 0) return byLang;\r\n if (entry.description && entry.description.length > 0) return entry.description;\r\n return undefined;\r\n};\r\n\r\nfunction renderSection(name: string, entries: Record<string, Entry> | undefined, lang: string): string {\r\n if (!entries) return `export const ${name} = {} as const;`;\r\n const lines = Object.entries(entries)\r\n .sort(([left], [right]) => left.localeCompare(right))\r\n .map(([key, entry]) => {\r\n const desc = resolveDesc(entry, lang);\r\n const doc = renderDoc(desc, \" \");\r\n return `${doc} \"${key}\": \"${entry.value}\",`;\r\n })\r\n .join(\"\\n\");\r\n return `export const ${name} = {\\n${lines}\\n} as const;`;\r\n}\r\n\r\nfunction renderDoc(description: string | undefined, indent: string): string {\r\n if (!description) return \"\";\r\n const normalized = description\r\n .replaceAll(\"*/\", \"*\\\\/\")\r\n .split(/\\r?\\n/)\r\n .map((line) => `${indent} * ${line}`)\r\n .join(\"\\n\");\r\n return `${indent}/**\\n${normalized}\\n${indent} */\\n`;\r\n}\r\n\r\nexport function renderMeasurementsTs(json: MeasurementsJson, lang: string): string {\r\n const physical = renderSection(\"GeneratedPhysicalMeasurements\", json.physical, lang);\r\n const dataSize = renderSection(\"GeneratedDataSizeMeasurements\", json.dataSize, lang);\r\n const counter = renderSection(\"GeneratedCounterMeasurements\", json.counter, lang);\r\n\r\n 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`;\r\n}\r\n\r\nexport async function generateUnsMeasurements(\r\n args: Partial<{ input: string; output: string; lang: string }>,\r\n): Promise<void> {\r\n const input = args.input ?? DEFAULT_INPUT;\r\n const output = args.output ?? DEFAULT_OUTPUT;\r\n const lang = args.lang ?? \"sl\";\r\n\r\n const json = await loadJson(input);\r\n const content = renderMeasurementsTs(json, lang);\r\n const changed = await writeTextFileIfChanged(output, content);\r\n console.log(`Generated measurements -> ${output}${changed ? \"\" : \" (unchanged)\"}`);\r\n}\r\n\r\nconst isDirectExecution = process.argv[1]\r\n ? import.meta.url === pathToFileURL(path.resolve(process.argv[1])).href\r\n : false;\r\n\r\nif (isDirectExecution) {\r\n main().catch((err) => {\r\n console.error(\"Failed to generate measurements:\", err);\r\n process.exitCode = 1;\r\n });\r\n}\r\n"]}
|
|
@@ -63,15 +63,15 @@ function parseArgs(argv) {
|
|
|
63
63
|
return { dictionary, dictionaryOutput, measurements, measurementsOutput, lang };
|
|
64
64
|
}
|
|
65
65
|
function printHelp() {
|
|
66
|
-
console.log(`Usage: tsx packages/uns-core/src/tools/generate-uns-reference.ts [options]
|
|
67
|
-
|
|
68
|
-
Options:
|
|
69
|
-
--dictionary <file> Path to uns-dictionary.json (default: ${DEFAULT_DICT_INPUT})
|
|
70
|
-
--dictionary-output <file> Path to generated dictionary TS (default: ${DEFAULT_DICT_OUTPUT})
|
|
71
|
-
--measurements <file> Path to uns-measurements.json (default: ${DEFAULT_MEAS_INPUT})
|
|
72
|
-
--measurements-output <file> Path to generated measurements TS (default: ${DEFAULT_MEAS_OUTPUT})
|
|
73
|
-
--lang <code> Preferred description language (default: "sl")
|
|
74
|
-
--help, -h Show this help
|
|
66
|
+
console.log(`Usage: tsx packages/uns-core/src/tools/generate-uns-reference.ts [options]
|
|
67
|
+
|
|
68
|
+
Options:
|
|
69
|
+
--dictionary <file> Path to uns-dictionary.json (default: ${DEFAULT_DICT_INPUT})
|
|
70
|
+
--dictionary-output <file> Path to generated dictionary TS (default: ${DEFAULT_DICT_OUTPUT})
|
|
71
|
+
--measurements <file> Path to uns-measurements.json (default: ${DEFAULT_MEAS_INPUT})
|
|
72
|
+
--measurements-output <file> Path to generated measurements TS (default: ${DEFAULT_MEAS_OUTPUT})
|
|
73
|
+
--lang <code> Preferred description language (default: "sl")
|
|
74
|
+
--help, -h Show this help
|
|
75
75
|
`);
|
|
76
76
|
}
|
|
77
77
|
const isDirectExecution = process.argv[1]
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generate-uns-reference.js","sourceRoot":"","sources":["../../src/tools/generate-uns-reference.ts"],"names":[],"mappings":"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","sourcesContent":["#!/usr/bin/env node\n/**\n * Generate both UNS dictionary and measurements in one go.\n * This is a small wrapper over generate-uns-dictionary.ts and\n * generate-uns-measurements.ts to make project setup simpler.\n */\nimport path from \"node:path\";\nimport { pathToFileURL } from \"node:url\";\nimport { generateUnsDictionary } from \"./generate-uns-dictionary.js\";\nimport { generateUnsMeasurements } from \"./generate-uns-measurements.js\";\n\ntype CliArgs = {\n dictionary: string;\n dictionaryOutput: string;\n measurements: string;\n measurementsOutput: string;\n lang: string;\n};\n\nconst DEFAULT_DICT_INPUT = \"uns-dictionary.json\";\nconst DEFAULT_DICT_OUTPUT = path.resolve(process.cwd(), \"src/uns/uns-dictionary.generated.ts\");\nconst DEFAULT_MEAS_INPUT = \"uns-measurements.json\";\nconst DEFAULT_MEAS_OUTPUT = path.resolve(process.cwd(), \"src/uns/uns-measurements.generated.ts\");\n\nasync function main(): Promise<void> {\n const args = parseArgs(process.argv.slice(2));\n\n await generateUnsDictionary({\n input: args.dictionary,\n output: args.dictionaryOutput,\n lang: args.lang,\n });\n\n await generateUnsMeasurements({\n input: args.measurements,\n output: args.measurementsOutput,\n lang: args.lang,\n });\n\n console.log(\n `Generated reference -> dictionary: ${args.dictionaryOutput}, measurements: ${args.measurementsOutput}`,\n );\n}\n\nfunction parseArgs(argv: string[]): CliArgs {\n let dictionary = DEFAULT_DICT_INPUT;\n let dictionaryOutput = DEFAULT_DICT_OUTPUT;\n let measurements = DEFAULT_MEAS_INPUT;\n let measurementsOutput = DEFAULT_MEAS_OUTPUT;\n let lang = \"sl\";\n\n for (let i = 0; i < argv.length; i++) {\n const arg = argv[i];\n if (arg === \"--dictionary\" && argv[i + 1]) {\n dictionary = argv[++i];\n continue;\n }\n if (arg === \"--dictionary-output\" && argv[i + 1]) {\n dictionaryOutput = argv[++i];\n continue;\n }\n if (arg === \"--measurements\" && argv[i + 1]) {\n measurements = argv[++i];\n continue;\n }\n if (arg === \"--measurements-output\" && argv[i + 1]) {\n measurementsOutput = argv[++i];\n continue;\n }\n if (arg === \"--lang\" && argv[i + 1]) {\n lang = argv[++i];\n continue;\n }\n if (arg === \"--help\" || arg === \"-h\") {\n printHelp();\n process.exit(0);\n }\n throw new Error(`Unknown argument: ${arg}`);\n }\n\n return { dictionary, dictionaryOutput, measurements, measurementsOutput, lang };\n}\n\nfunction printHelp(): void {\n console.log(`Usage: tsx packages/uns-core/src/tools/generate-uns-reference.ts [options]\n\nOptions:\n --dictionary <file> Path to uns-dictionary.json (default: ${DEFAULT_DICT_INPUT})\n --dictionary-output <file> Path to generated dictionary TS (default: ${DEFAULT_DICT_OUTPUT})\n --measurements <file> Path to uns-measurements.json (default: ${DEFAULT_MEAS_INPUT})\n --measurements-output <file> Path to generated measurements TS (default: ${DEFAULT_MEAS_OUTPUT})\n --lang <code> Preferred description language (default: \"sl\")\n --help, -h Show this help\n`);\n}\n\nconst isDirectExecution = process.argv[1]\n ? import.meta.url === pathToFileURL(path.resolve(process.argv[1])).href\n : false;\n\nif (isDirectExecution) {\n main().catch((err) => {\n console.error(\"Failed to generate UNS reference:\", err);\n process.exitCode = 1;\n });\n}\n"]}
|
|
1
|
+
{"version":3,"file":"generate-uns-reference.js","sourceRoot":"","sources":["../../src/tools/generate-uns-reference.ts"],"names":[],"mappings":"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","sourcesContent":["#!/usr/bin/env node\r\n/**\r\n * Generate both UNS dictionary and measurements in one go.\r\n * This is a small wrapper over generate-uns-dictionary.ts and\r\n * generate-uns-measurements.ts to make project setup simpler.\r\n */\r\nimport path from \"node:path\";\r\nimport { pathToFileURL } from \"node:url\";\r\nimport { generateUnsDictionary } from \"./generate-uns-dictionary.js\";\r\nimport { generateUnsMeasurements } from \"./generate-uns-measurements.js\";\r\n\r\ntype CliArgs = {\r\n dictionary: string;\r\n dictionaryOutput: string;\r\n measurements: string;\r\n measurementsOutput: string;\r\n lang: string;\r\n};\r\n\r\nconst DEFAULT_DICT_INPUT = \"uns-dictionary.json\";\r\nconst DEFAULT_DICT_OUTPUT = path.resolve(process.cwd(), \"src/uns/uns-dictionary.generated.ts\");\r\nconst DEFAULT_MEAS_INPUT = \"uns-measurements.json\";\r\nconst DEFAULT_MEAS_OUTPUT = path.resolve(process.cwd(), \"src/uns/uns-measurements.generated.ts\");\r\n\r\nasync function main(): Promise<void> {\r\n const args = parseArgs(process.argv.slice(2));\r\n\r\n await generateUnsDictionary({\r\n input: args.dictionary,\r\n output: args.dictionaryOutput,\r\n lang: args.lang,\r\n });\r\n\r\n await generateUnsMeasurements({\r\n input: args.measurements,\r\n output: args.measurementsOutput,\r\n lang: args.lang,\r\n });\r\n\r\n console.log(\r\n `Generated reference -> dictionary: ${args.dictionaryOutput}, measurements: ${args.measurementsOutput}`,\r\n );\r\n}\r\n\r\nfunction parseArgs(argv: string[]): CliArgs {\r\n let dictionary = DEFAULT_DICT_INPUT;\r\n let dictionaryOutput = DEFAULT_DICT_OUTPUT;\r\n let measurements = DEFAULT_MEAS_INPUT;\r\n let measurementsOutput = DEFAULT_MEAS_OUTPUT;\r\n let lang = \"sl\";\r\n\r\n for (let i = 0; i < argv.length; i++) {\r\n const arg = argv[i];\r\n if (arg === \"--dictionary\" && argv[i + 1]) {\r\n dictionary = argv[++i];\r\n continue;\r\n }\r\n if (arg === \"--dictionary-output\" && argv[i + 1]) {\r\n dictionaryOutput = argv[++i];\r\n continue;\r\n }\r\n if (arg === \"--measurements\" && argv[i + 1]) {\r\n measurements = argv[++i];\r\n continue;\r\n }\r\n if (arg === \"--measurements-output\" && argv[i + 1]) {\r\n measurementsOutput = argv[++i];\r\n continue;\r\n }\r\n if (arg === \"--lang\" && argv[i + 1]) {\r\n lang = argv[++i];\r\n continue;\r\n }\r\n if (arg === \"--help\" || arg === \"-h\") {\r\n printHelp();\r\n process.exit(0);\r\n }\r\n throw new Error(`Unknown argument: ${arg}`);\r\n }\r\n\r\n return { dictionary, dictionaryOutput, measurements, measurementsOutput, lang };\r\n}\r\n\r\nfunction printHelp(): void {\r\n console.log(`Usage: tsx packages/uns-core/src/tools/generate-uns-reference.ts [options]\r\n\r\nOptions:\r\n --dictionary <file> Path to uns-dictionary.json (default: ${DEFAULT_DICT_INPUT})\r\n --dictionary-output <file> Path to generated dictionary TS (default: ${DEFAULT_DICT_OUTPUT})\r\n --measurements <file> Path to uns-measurements.json (default: ${DEFAULT_MEAS_INPUT})\r\n --measurements-output <file> Path to generated measurements TS (default: ${DEFAULT_MEAS_OUTPUT})\r\n --lang <code> Preferred description language (default: \"sl\")\r\n --help, -h Show this help\r\n`);\r\n}\r\n\r\nconst isDirectExecution = process.argv[1]\r\n ? import.meta.url === pathToFileURL(path.resolve(process.argv[1])).href\r\n : false;\r\n\r\nif (isDirectExecution) {\r\n main().catch((err) => {\r\n console.error(\"Failed to generate UNS reference:\", err);\r\n process.exitCode = 1;\r\n });\r\n}\r\n"]}
|