@uns-kit/core 2.0.40 → 2.0.42

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 (102) hide show
  1. package/README.md +38 -15
  2. package/dist/base-path.js.map +1 -1
  3. package/dist/config/project.config.extension.js.map +1 -1
  4. package/dist/config-file.js.map +1 -1
  5. package/dist/graphql/schema.js.map +1 -1
  6. package/dist/index.d.ts +9 -8
  7. package/dist/index.d.ts.map +1 -1
  8. package/dist/index.js +8 -7
  9. package/dist/index.js.map +1 -1
  10. package/dist/logger.js.map +1 -1
  11. package/dist/tools/auth/auth-client.js.map +1 -1
  12. package/dist/tools/auth/index.js.map +1 -1
  13. package/dist/tools/auth/secure-store.js.map +1 -1
  14. package/dist/tools/base-path.js.map +1 -1
  15. package/dist/tools/datahub/datahub-client.js.map +1 -1
  16. package/dist/tools/file-utils.d.ts +2 -2
  17. package/dist/tools/file-utils.js +24 -24
  18. package/dist/tools/file-utils.js.map +1 -1
  19. package/dist/tools/generate-config-schema.js.map +1 -1
  20. package/dist/tools/generate-uns-dictionary.d.ts +23 -23
  21. package/dist/tools/generate-uns-dictionary.js +147 -147
  22. package/dist/tools/generate-uns-dictionary.js.map +1 -1
  23. package/dist/tools/generate-uns-measurements.d.ts +21 -21
  24. package/dist/tools/generate-uns-measurements.js +119 -119
  25. package/dist/tools/generate-uns-measurements.js.map +1 -1
  26. package/dist/tools/generate-uns-reference.d.ts +2 -2
  27. package/dist/tools/generate-uns-reference.js +76 -76
  28. package/dist/tools/generate-uns-reference.js.map +1 -1
  29. package/dist/tools/pull-request.js.map +1 -1
  30. package/dist/tools/refresh-uns.js.map +1 -1
  31. package/dist/tools/schema.js.map +1 -1
  32. package/dist/tools/sync-uns-schema.d.ts +2 -2
  33. package/dist/tools/sync-uns-schema.js +472 -472
  34. package/dist/tools/sync-uns-schema.js.map +1 -1
  35. package/dist/uns/handover-manager-event-emitter.js.map +1 -1
  36. package/dist/uns/handover-manager.js.map +1 -1
  37. package/dist/uns/process-config.js.map +1 -1
  38. package/dist/uns/service-metadata.d.ts +53 -0
  39. package/dist/uns/service-metadata.d.ts.map +1 -0
  40. package/dist/uns/service-metadata.js +56 -0
  41. package/dist/uns/service-metadata.js.map +1 -0
  42. package/dist/uns/status-monitor.js.map +1 -1
  43. package/dist/uns/uns-asset.d.ts +1 -1
  44. package/dist/uns/uns-asset.js +1 -1
  45. package/dist/uns/uns-asset.js.map +1 -1
  46. package/dist/uns/uns-attributes.d.ts +6 -6
  47. package/dist/uns/uns-attributes.js +9 -9
  48. package/dist/uns/uns-attributes.js.map +1 -1
  49. package/dist/uns/uns-dictionary-registry.d.ts +4 -4
  50. package/dist/uns/uns-dictionary-registry.js +20 -20
  51. package/dist/uns/uns-dictionary-registry.js.map +1 -1
  52. package/dist/uns/uns-dictionary.generated.d.ts +663 -663
  53. package/dist/uns/uns-dictionary.generated.js +745 -745
  54. package/dist/uns/uns-dictionary.generated.js.map +1 -1
  55. package/dist/uns/uns-event-emitter.js.map +1 -1
  56. package/dist/uns/uns-interfaces.d.ts +365 -365
  57. package/dist/uns/uns-interfaces.js.map +1 -1
  58. package/dist/uns/uns-measurements.generated.d.ts +362 -362
  59. package/dist/uns/uns-measurements.generated.js +359 -359
  60. package/dist/uns/uns-measurements.generated.js.map +1 -1
  61. package/dist/uns/uns-measurements.js.map +1 -1
  62. package/dist/uns/uns-object.d.ts +20 -20
  63. package/dist/uns/uns-object.js +9 -9
  64. package/dist/uns/uns-object.js.map +1 -1
  65. package/dist/uns/uns-packet.js +263 -263
  66. package/dist/uns/uns-packet.js.map +1 -1
  67. package/dist/uns/uns-path.d.ts +2 -2
  68. package/dist/uns/uns-path.js +10 -10
  69. package/dist/uns/uns-path.js.map +1 -1
  70. package/dist/uns/uns-proxy-process.d.ts +11 -0
  71. package/dist/uns/uns-proxy-process.d.ts.map +1 -1
  72. package/dist/uns/uns-proxy-process.js +224 -203
  73. package/dist/uns/uns-proxy-process.js.map +1 -1
  74. package/dist/uns/uns-proxy.d.ts +51 -51
  75. package/dist/uns/uns-proxy.js +190 -190
  76. package/dist/uns/uns-proxy.js.map +1 -1
  77. package/dist/uns/uns-tags.js.map +1 -1
  78. package/dist/uns/uns-topic-matcher.js.map +1 -1
  79. package/dist/uns/uns-topics.js.map +1 -1
  80. package/dist/uns-config/config-schema.js.map +1 -1
  81. package/dist/uns-config/host-placeholders.js.map +1 -1
  82. package/dist/uns-config/schema-tolls.js.map +1 -1
  83. package/dist/uns-config/schema-tools.js.map +1 -1
  84. package/dist/uns-config/secret-placeholders.js.map +1 -1
  85. package/dist/uns-config/secret-resolver.js.map +1 -1
  86. package/dist/uns-config/uns-core-schema.d.ts +3276 -3276
  87. package/dist/uns-config/uns-core-schema.js.map +1 -1
  88. package/dist/uns-grpc/uns-gateway-cli.js.map +1 -1
  89. package/dist/uns-grpc/uns-gateway-server.js.map +1 -1
  90. package/dist/uns-mqtt/mqtt-interfaces.js.map +1 -1
  91. package/dist/uns-mqtt/mqtt-proxy.js.map +1 -1
  92. package/dist/uns-mqtt/mqtt-topic-builder.d.ts +6 -0
  93. package/dist/uns-mqtt/mqtt-topic-builder.d.ts.map +1 -1
  94. package/dist/uns-mqtt/mqtt-topic-builder.js +8 -0
  95. package/dist/uns-mqtt/mqtt-topic-builder.js.map +1 -1
  96. package/dist/uns-mqtt/mqtt-worker-init.js.map +1 -1
  97. package/dist/uns-mqtt/mqtt-worker.js.map +1 -1
  98. package/dist/uns-mqtt/throttled-queue.js.map +1 -1
  99. package/dist/uns-mqtt/uns-mqtt-proxy.js +477 -477
  100. package/dist/uns-mqtt/uns-mqtt-proxy.js.map +1 -1
  101. package/dist/uns-mqtt/ws-proxy.js.map +1 -1
  102. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"uns-interfaces.js","sourceRoot":"","sources":["../../src/uns/uns-interfaces.ts"],"names":[],"mappings":"AAUA,MAAM,UAAU,aAAa,CAAC,KAAa;IACzC,MAAM,YAAY,GAAG,+CAA+C,CAAC;IACrE,OAAO,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AAClC,CAAC;AAID,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,QAAQ,EAAE,QAAQ,CAAU,CAAC;AAIxD,MAAM,CAAC,MAAM,qBAAqB,GAAG;IACnC,SAAS;IACT,MAAM;IACN,MAAM;IACN,OAAO;IACP,MAAM;IACN,KAAK;IACL,OAAO;IACP,QAAQ;IACR,SAAS;IACT,QAAQ;IACR,MAAM;IACN,MAAM;IACN,WAAW;IACX,cAAc;IACd,QAAQ;IACR,MAAM;IACN,QAAQ;IACR,SAAS;CACD,CAAC;AAEX,MAAM,uBAAuB,GAAG,IAAI,GAAG,CAAS,qBAAqB,CAAC,CAAC;AACvE,MAAM,mBAAmB,GAAG,sBAAsB,CAAC;AACnD,MAAM,mBAAmB,GAAG,sBAAsB,CAAC;AACnD,MAAM,iBAAiB,GAAG,gBAAgB,CAAC;AAW3C,MAAM,UAAU,aAAa,CAAC,KAAc;IAC1C,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,OAAO,KAAK,CAAC;IACf,CAAC;IACD,IAAI,uBAAuB,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;QACvC,OAAO,IAAI,CAAC;IACd,CAAC;IACD,OAAO,CACL,mBAAmB,CAAC,IAAI,CAAC,KAAK,CAAC;QAC/B,mBAAmB,CAAC,IAAI,CAAC,KAAK,CAAC;QAC/B,iBAAiB,CAAC,IAAI,CAAC,KAAK,CAAC,CAC9B,CAAC;AACJ,CAAC","sourcesContent":["import { UnsAttributeType } from \"../graphql/schema.js\";\nimport { MeasurementUnit } from \"./uns-measurements.js\";\nimport { UnsTags } from \"./uns-tags.js\";\nimport type { UnsObjectId, UnsObjectType } from \"./uns-object.js\";\nimport type { UnsAsset } from \"./uns-asset.js\";\nimport type { IMqttConnectProperties, IMqttPublishOptions, IMqttServerConfig, MqttProtocol } from \"../uns-mqtt/mqtt-interfaces.js\";\nimport { UnsTopics } from \"./uns-topics.js\";\nimport { knownUnsAttributes, type KnownUnsAttributeName } from \"./uns-attributes.js\";\n\nexport type ISO8601 = `${number}-${string}-${string}T${string}:${string}:${string}.${string}Z`;\nexport function isIOS8601Type(value: string): value is ISO8601 {\n const iso8601Regex = /^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z$/;\n return iso8601Regex.test(value);\n}\n// Known attribute names (with IntelliSense) while still allowing arbitrary strings.\nexport type UnsAttribute = KnownUnsAttributeName | (string & {});\n\nexport const valueTypes = [\"string\", \"number\"] as const;\nexport type ValueTypeString = (typeof valueTypes)[number];\nexport type ValueType = string | number;\n\nexport const questDbPrimitiveTypes = [\n \"boolean\",\n \"ipv4\",\n \"byte\",\n \"short\",\n \"char\",\n \"int\",\n \"float\",\n \"symbol\",\n \"varchar\",\n \"string\",\n \"long\",\n \"date\",\n \"timestamp\",\n \"timestamp_ns\",\n \"double\",\n \"uuid\",\n \"binary\",\n \"long256\",\n] as const;\n\nconst questDbPrimitiveTypeSet = new Set<string>(questDbPrimitiveTypes);\nconst questDbGeohashRegex = /^geohash\\(\\d+[bc]\\)$/;\nconst questDbDecimalRegex = /^decimal\\(\\d+,\\d+\\)$/;\nconst questDbArrayRegex = /^array<[^>]+>$/;\n\nexport type QuestDbPrimitiveType = (typeof questDbPrimitiveTypes)[number];\n\n// Supported QuestDB column types for UNS tables.\nexport type QuestDbType =\n | QuestDbPrimitiveType\n | `geohash(${number}${\"b\" | \"c\"})`\n | `decimal(${number},${number})`\n | `array<${string}>`;\n\nexport function isQuestDbType(value: unknown): value is QuestDbType {\n if (typeof value !== \"string\") {\n return false;\n }\n if (questDbPrimitiveTypeSet.has(value)) {\n return true;\n }\n return (\n questDbGeohashRegex.test(value) ||\n questDbDecimalRegex.test(value) ||\n questDbArrayRegex.test(value)\n );\n}\n\nexport interface IUnsParameters {\n mqttSubToTopics?: string | string[];\n username?: string;\n password?: string;\n mqttSSL?: boolean;\n publishThrottlingDelay?: number; // Delay in milliseconds; default is 1ms\n subscribeThrottlingDelay?: number; // Delay in milliseconds; default is 1ms\n rejectUnauthorized?: boolean;\n clientId?: string;\n hosts?: string[];\n servers?: IMqttServerConfig[];\n port?: number;\n protocol?: MqttProtocol;\n keepalive?: number;\n clean?: boolean;\n connectTimeout?: number;\n reconnectPeriod?: number;\n reconnectOnConnackError?: boolean;\n resubscribe?: boolean;\n queueQoSZero?: boolean;\n properties?: IMqttConnectProperties;\n ca?: string;\n cert?: string;\n key?: string;\n servername?: string;\n /**\n * Default MQTT publish options applied to all outgoing messages\n * (e.g., qos, retain, messageExpiryInterval).\n */\n defaultPublishOptions?: IMqttPublishOptions;\n}\n\nexport interface IUnsProcessParameters {\n processName: string;\n mqttSubToTopics?: string | string[];\n username?: string;\n password?: string;\n mqttSSL?: boolean;\n clientId?: string;\n hosts?: string[];\n servers?: IMqttServerConfig[];\n port?: number;\n protocol?: MqttProtocol;\n keepalive?: number;\n clean?: boolean;\n connectTimeout?: number;\n reconnectPeriod?: number;\n reconnectOnConnackError?: boolean;\n resubscribe?: boolean;\n queueQoSZero?: boolean;\n rejectUnauthorized?: boolean;\n properties?: IMqttConnectProperties;\n ca?: string;\n cert?: string;\n key?: string;\n servername?: string;\n}\n\nexport interface UnsEvents {\n // Emitters in MqttProxy, UnsMqttProxy\n input: { topic: string; message: string, packet: any };\n mqttProxyStatus: { event: string, value: number, uom: MeasurementUnit, statusTopic: string };\n \n // Emitters in MqttProxy\n error: { code: number; message: string };\n \n // Emitters in UnsMqttProxy\n mqttWorker: { command: string, instanceName: string; batchSize: number, referenceHash: string };\n\n // Emitter in UnsCronProxy\n cronEvent: { event?: string; cronExpression?: string };\n\n // Emitters in UnsApiProxy\n apiGetEvent: {req: any, res: any};\n apiPostEvent: {req: any, res: any};\n\n // Emitters in UnsProxy\n unsProxyProducedTopics: { producedTopics: ITopicObject[], statusTopic: string };\n\n // Emitters in UnsProxy\n unsProxyProducedApiEndpoints: { producedApiEndpoints: IApiObject[], statusTopic: string };\n\n // Emitters in UnsProxy\n unsProxyProducedApiCatchAll: { producedCatchall: IApiCatchallMapping[], statusTopic: string };\n}\n\nexport interface IUnsExtendedData extends IUnsData {\n valueType: ValueTypeString;\n}\n\nexport interface IUnsData {\n time: ISO8601;\n value: ValueType;\n dataGroup?: string;\n uom?: MeasurementUnit;\n foreignEventKey?: string;\n intervalStart?: ISO8601 | number;\n intervalEnd?: ISO8601 | number;\n windowStart?: ISO8601 | number;\n windowEnd?: ISO8601 | number;\n eventId?: string;\n deleted?: boolean;\n deletedAt?: ISO8601 | number;\n lastSeen?: ISO8601 | number;\n}\n\nexport interface IUnsTableColumn {\n name: string;\n type: QuestDbType;\n value: string | number | boolean | null;\n uom?: MeasurementUnit;\n}\n\nexport interface IUnsTable {\n time: ISO8601;\n dataGroup?: string;\n columns: IUnsTableColumn[];\n intervalStart?: ISO8601 | number;\n intervalEnd?: ISO8601 | number;\n windowStart?: ISO8601 | number;\n windowEnd?: ISO8601 | number;\n eventId?: string;\n deleted?: boolean;\n deletedAt?: ISO8601 | number;\n lastSeen?: ISO8601 | number;\n}\n\nexport interface IMqttAttributeMessage {\n attribute: UnsAttribute;\n description?: string;\n tags?: UnsTags[];\n attributeNeedsPersistence?: boolean | null;\n /**\n * How the controller determines if this attribute is live or stale.\n * Defaults to `\"interval\"` with the controller's default interval (~120s) when omitted.\n *\n * @example\n * // Sensor publishing every 2 seconds:\n * { validityMode: \"interval\", expectedIntervalMs: 2000 }\n *\n * // Status attribute publishing every 2 seconds (string values like \"HEATING\"):\n * { validityMode: \"interval\", expectedIntervalMs: 2000 }\n *\n * // Material location with ENTERED/EXITED lifecycle:\n * { validityMode: \"lifecycle\", lifecycleEndValue: \"EXITED\" }\n *\n * // Static configuration value:\n * { validityMode: \"static\" }\n */\n validityMode?: ValidityMode;\n /**\n * Expected publish interval in milliseconds. Only meaningful for `validityMode: \"interval\"`.\n * The controller marks the attribute as stale after ~2× this value without a heartbeat update.\n * Ignored for `\"lifecycle\"` and `\"static\"` modes.\n */\n expectedIntervalMs?: number;\n /**\n * The string value that marks a lifecycle as completed. Only meaningful for `validityMode: \"lifecycle\"`.\n * When the attribute's current value matches this, the controller considers the lifecycle done.\n * Example: `\"EXITED\"` for a location attribute with ENTERED/EXITED events.\n */\n lifecycleEndValue?: string;\n}\n\ntype AttributePayload =\n | { message: IUnsMessage; data?: never; table?: never; createdAt?: never; expiresAt?: never }\n | { message?: never; data: IUnsData; table?: never; createdAt?: ISO8601; expiresAt?: ISO8601 }\n | { message?: never; data?: never; table: IUnsTable; createdAt?: ISO8601; expiresAt?: ISO8601 };\n\nexport type IMqttAttributeEntry = IMqttAttributeMessage & AttributePayload;\n\nexport interface IMqttPublishRequest {\n topic: UnsTopics;\n asset: UnsAsset;\n assetDescription?: string;\n objectType: UnsObjectType;\n objectTypeDescription?: string;\n objectId: UnsObjectId;\n attributes: IMqttAttributeEntry | IMqttAttributeEntry[];\n}\n\n// This interface represents a packet for a UNS system\nexport interface IUnsPacket {\n // The message object of the packet\n message: IUnsExtendedMessage;\n \n // The HMAC signature of the message\n messageSignature?: string;\n\n // Automatically calculated interval between two packets in ms\n interval?: number;\n\n // Current library version\n readonly version: string;\n\n // Autogenerated sequence number\n sequenceId?: number;\n}\n\nexport interface IUnsPackatParameters {\n\n}\n\nexport interface IUnsMessage {\n data?: IUnsData;\n table?: IUnsTable;\n expiresAt?: ISO8601;\n createdAt?: ISO8601;\n}\n\nexport interface IUnsExtendedMessage extends IUnsMessage {\n data?: IUnsExtendedData;\n}\n\n/**\n * Controls how the controller determines whether an attribute is live or stale.\n *\n * - `\"interval\"` — Attribute publishes periodically. Stale if no heartbeat within ~2× the expected interval.\n * Use with `expectedIntervalMs`. Works for both numeric sensors (temperature every 2s)\n * and string status attributes (status every 2s). Example:\n * `{ validityMode: \"interval\", expectedIntervalMs: 2000 }`\n *\n * - `\"lifecycle\"` — Attribute represents a lifecycle with a start and end event.\n * Use with `lifecycleEndValue` to mark the end state. Example: material location with \"ENTERED\" / \"EXITED\".\n *\n * - `\"static\"` — Attribute is set once and never changes (configuration, metadata). Always live.\n *\n * When omitted, defaults to `\"interval\"` with the controller's default interval (~120s).\n */\nexport type ValidityMode = \"interval\" | \"lifecycle\" | \"static\";\n\nexport interface ITopicObject {\n timestamp: string;\n attribute:string;\n attributeType: UnsAttributeType;\n topic:string;\n description:string;\n dataGroup:string;\n tags:string[] | null;\n attributeNeedsPersistence: boolean | null;\n asset: UnsAsset;\n assetDescription?: string;\n objectType: UnsObjectType;\n objectTypeDescription?: string;\n objectId: UnsObjectId;\n /** Liveliness validity mode — how the controller determines if this attribute is live/stale. */\n validityMode?: ValidityMode;\n /** For interval mode: expected publish interval in milliseconds (stale after ~2x this value). */\n expectedIntervalMs?: number;\n /** For lifecycle mode: the string value that marks the lifecycle as completed (e.g. \"EXITED\"). */\n lifecycleEndValue?: string;\n}\n\n// API Interfaces below\nexport interface IApiObject {\n timestamp: string;\n attribute:string;\n topic:string;\n attributeType: UnsAttributeType;\n apiDescription?: string; // Optional description for the API endpoint\n apiHost: string; // Hostname of the service\n apiEndpoint: string; // API endpoint for virtual topics\n apiSwaggerEndpoint: string; // Swagger endpoint for API documentation\n apiMethod: \"GET\" | \"POST\" | \"PUT\" | \"DELETE\"; // HTTP method for API endpoint\n apiQueryParams: QueryParamDef[]; // query parameters for the API endpoint\n asset: UnsAsset;\n objectType: UnsObjectType;\n objectId: UnsObjectId;\n controllerName?: string;\n controllerHost?: string;\n controllerPort?: string;\n controllerPublicBase?: string;\n}\n\nexport interface IApiCatchallMapping {\n topic: string;\n apiBase: string;\n apiBasePath: string;\n swaggerPath: string;\n}\n\nexport interface QueryParamDef {\n name: string;\n type: \"string\" | \"number\" | \"boolean\";\n required?: boolean;\n description?: string;\n /**\n * Optional canonical chat alias used by assistant tooling.\n * Typical values: from, to, limit, topic, timezone, summaryOnly.\n */\n chatCanonical?: string;\n /**\n * Optional default query value. Included in generated OpenAPI metadata.\n */\n defaultValue?: string | number | boolean;\n}\n\nexport interface ApiChatDefaults {\n from?: string;\n to?: string;\n limit?: number;\n topic?: string;\n timezone?: string;\n summaryOnly?: boolean;\n [key: string]: string | number | boolean | undefined;\n}\n\nexport interface IApiProxyOptions {\n jwtSecret?: string;\n jwks?: {\n wellKnownJwksUrl: string;\n activeKidUrl?: string;\n cacheTtlMs?: number;\n algorithms?: (\"RS256\" | \"RS384\" | \"RS512\")[];\n };\n /**\n * Optional base prefixes to mount the API and swagger JSON under (e.g. \"/archiver-3\").\n * Defaults to \"/api\" when not provided.\n */\n apiBasePath?: string;\n swaggerBasePath?: string;\n /**\n * Skip mounting the default \"/api\" route. Useful when rebasing entirely under a custom prefix.\n */\n disableDefaultApiMount?: boolean;\n}\n\nexport interface IGetEndpointOptions {\n apiDescription?: string;\n tags?: string[];\n queryParams?: QueryParamDef[];\n /**\n * Optional defaults consumed by chat tooling (published as OpenAPI vendor extension x-uns-chat.defaults).\n */\n chatDefaults?: ApiChatDefaults;\n}\n\nexport interface IPostEndpointOptions {\n apiDescription?: string;\n tags?: string[];\n requestBody?: {\n description?: string;\n required?: boolean;\n schema?: Record<string, unknown>;\n };\n}\n"]}
1
+ {"version":3,"file":"uns-interfaces.js","sourceRoot":"","sources":["../../src/uns/uns-interfaces.ts"],"names":[],"mappings":"AAUA,MAAM,UAAU,aAAa,CAAC,KAAa;IACzC,MAAM,YAAY,GAAG,+CAA+C,CAAC;IACrE,OAAO,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AAClC,CAAC;AAID,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,QAAQ,EAAE,QAAQ,CAAU,CAAC;AAIxD,MAAM,CAAC,MAAM,qBAAqB,GAAG;IACnC,SAAS;IACT,MAAM;IACN,MAAM;IACN,OAAO;IACP,MAAM;IACN,KAAK;IACL,OAAO;IACP,QAAQ;IACR,SAAS;IACT,QAAQ;IACR,MAAM;IACN,MAAM;IACN,WAAW;IACX,cAAc;IACd,QAAQ;IACR,MAAM;IACN,QAAQ;IACR,SAAS;CACD,CAAC;AAEX,MAAM,uBAAuB,GAAG,IAAI,GAAG,CAAS,qBAAqB,CAAC,CAAC;AACvE,MAAM,mBAAmB,GAAG,sBAAsB,CAAC;AACnD,MAAM,mBAAmB,GAAG,sBAAsB,CAAC;AACnD,MAAM,iBAAiB,GAAG,gBAAgB,CAAC;AAW3C,MAAM,UAAU,aAAa,CAAC,KAAc;IAC1C,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,OAAO,KAAK,CAAC;IACf,CAAC;IACD,IAAI,uBAAuB,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;QACvC,OAAO,IAAI,CAAC;IACd,CAAC;IACD,OAAO,CACL,mBAAmB,CAAC,IAAI,CAAC,KAAK,CAAC;QAC/B,mBAAmB,CAAC,IAAI,CAAC,KAAK,CAAC;QAC/B,iBAAiB,CAAC,IAAI,CAAC,KAAK,CAAC,CAC9B,CAAC;AACJ,CAAC","sourcesContent":["import { UnsAttributeType } from \"../graphql/schema.js\";\r\nimport { MeasurementUnit } from \"./uns-measurements.js\";\r\nimport { UnsTags } from \"./uns-tags.js\";\r\nimport type { UnsObjectId, UnsObjectType } from \"./uns-object.js\";\r\nimport type { UnsAsset } from \"./uns-asset.js\";\r\nimport type { IMqttConnectProperties, IMqttPublishOptions, IMqttServerConfig, MqttProtocol } from \"../uns-mqtt/mqtt-interfaces.js\";\r\nimport { UnsTopics } from \"./uns-topics.js\";\r\nimport { knownUnsAttributes, type KnownUnsAttributeName } from \"./uns-attributes.js\";\r\n\r\nexport type ISO8601 = `${number}-${string}-${string}T${string}:${string}:${string}.${string}Z`;\r\nexport function isIOS8601Type(value: string): value is ISO8601 {\r\n const iso8601Regex = /^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z$/;\r\n return iso8601Regex.test(value);\r\n}\r\n// Known attribute names (with IntelliSense) while still allowing arbitrary strings.\r\nexport type UnsAttribute = KnownUnsAttributeName | (string & {});\r\n\r\nexport const valueTypes = [\"string\", \"number\"] as const;\r\nexport type ValueTypeString = (typeof valueTypes)[number];\r\nexport type ValueType = string | number;\r\n\r\nexport const questDbPrimitiveTypes = [\r\n \"boolean\",\r\n \"ipv4\",\r\n \"byte\",\r\n \"short\",\r\n \"char\",\r\n \"int\",\r\n \"float\",\r\n \"symbol\",\r\n \"varchar\",\r\n \"string\",\r\n \"long\",\r\n \"date\",\r\n \"timestamp\",\r\n \"timestamp_ns\",\r\n \"double\",\r\n \"uuid\",\r\n \"binary\",\r\n \"long256\",\r\n] as const;\r\n\r\nconst questDbPrimitiveTypeSet = new Set<string>(questDbPrimitiveTypes);\r\nconst questDbGeohashRegex = /^geohash\\(\\d+[bc]\\)$/;\r\nconst questDbDecimalRegex = /^decimal\\(\\d+,\\d+\\)$/;\r\nconst questDbArrayRegex = /^array<[^>]+>$/;\r\n\r\nexport type QuestDbPrimitiveType = (typeof questDbPrimitiveTypes)[number];\r\n\r\n// Supported QuestDB column types for UNS tables.\r\nexport type QuestDbType =\r\n | QuestDbPrimitiveType\r\n | `geohash(${number}${\"b\" | \"c\"})`\r\n | `decimal(${number},${number})`\r\n | `array<${string}>`;\r\n\r\nexport function isQuestDbType(value: unknown): value is QuestDbType {\r\n if (typeof value !== \"string\") {\r\n return false;\r\n }\r\n if (questDbPrimitiveTypeSet.has(value)) {\r\n return true;\r\n }\r\n return (\r\n questDbGeohashRegex.test(value) ||\r\n questDbDecimalRegex.test(value) ||\r\n questDbArrayRegex.test(value)\r\n );\r\n}\r\n\r\nexport interface IUnsParameters {\r\n mqttSubToTopics?: string | string[];\r\n username?: string;\r\n password?: string;\r\n mqttSSL?: boolean;\r\n publishThrottlingDelay?: number; // Delay in milliseconds; default is 1ms\r\n subscribeThrottlingDelay?: number; // Delay in milliseconds; default is 1ms\r\n rejectUnauthorized?: boolean;\r\n clientId?: string;\r\n hosts?: string[];\r\n servers?: IMqttServerConfig[];\r\n port?: number;\r\n protocol?: MqttProtocol;\r\n keepalive?: number;\r\n clean?: boolean;\r\n connectTimeout?: number;\r\n reconnectPeriod?: number;\r\n reconnectOnConnackError?: boolean;\r\n resubscribe?: boolean;\r\n queueQoSZero?: boolean;\r\n properties?: IMqttConnectProperties;\r\n ca?: string;\r\n cert?: string;\r\n key?: string;\r\n servername?: string;\r\n /**\r\n * Default MQTT publish options applied to all outgoing messages\r\n * (e.g., qos, retain, messageExpiryInterval).\r\n */\r\n defaultPublishOptions?: IMqttPublishOptions;\r\n}\r\n\r\nexport interface IUnsProcessParameters {\r\n processName: string;\r\n mqttSubToTopics?: string | string[];\r\n username?: string;\r\n password?: string;\r\n mqttSSL?: boolean;\r\n clientId?: string;\r\n hosts?: string[];\r\n servers?: IMqttServerConfig[];\r\n port?: number;\r\n protocol?: MqttProtocol;\r\n keepalive?: number;\r\n clean?: boolean;\r\n connectTimeout?: number;\r\n reconnectPeriod?: number;\r\n reconnectOnConnackError?: boolean;\r\n resubscribe?: boolean;\r\n queueQoSZero?: boolean;\r\n rejectUnauthorized?: boolean;\r\n properties?: IMqttConnectProperties;\r\n ca?: string;\r\n cert?: string;\r\n key?: string;\r\n servername?: string;\r\n}\r\n\r\nexport interface UnsEvents {\r\n // Emitters in MqttProxy, UnsMqttProxy\r\n input: { topic: string; message: string, packet: any };\r\n mqttProxyStatus: { event: string, value: number, uom: MeasurementUnit, statusTopic: string };\r\n \r\n // Emitters in MqttProxy\r\n error: { code: number; message: string };\r\n \r\n // Emitters in UnsMqttProxy\r\n mqttWorker: { command: string, instanceName: string; batchSize: number, referenceHash: string };\r\n\r\n // Emitter in UnsCronProxy\r\n cronEvent: { event?: string; cronExpression?: string };\r\n\r\n // Emitters in UnsApiProxy\r\n apiGetEvent: {req: any, res: any};\r\n apiPostEvent: {req: any, res: any};\r\n\r\n // Emitters in UnsProxy\r\n unsProxyProducedTopics: { producedTopics: ITopicObject[], statusTopic: string };\r\n\r\n // Emitters in UnsProxy\r\n unsProxyProducedApiEndpoints: { producedApiEndpoints: IApiObject[], statusTopic: string };\r\n\r\n // Emitters in UnsProxy\r\n unsProxyProducedApiCatchAll: { producedCatchall: IApiCatchallMapping[], statusTopic: string };\r\n}\r\n\r\nexport interface IUnsExtendedData extends IUnsData {\r\n valueType: ValueTypeString;\r\n}\r\n\r\nexport interface IUnsData {\r\n time: ISO8601;\r\n value: ValueType;\r\n dataGroup?: string;\r\n uom?: MeasurementUnit;\r\n foreignEventKey?: string;\r\n intervalStart?: ISO8601 | number;\r\n intervalEnd?: ISO8601 | number;\r\n windowStart?: ISO8601 | number;\r\n windowEnd?: ISO8601 | number;\r\n eventId?: string;\r\n deleted?: boolean;\r\n deletedAt?: ISO8601 | number;\r\n lastSeen?: ISO8601 | number;\r\n}\r\n\r\nexport interface IUnsTableColumn {\r\n name: string;\r\n type: QuestDbType;\r\n value: string | number | boolean | null;\r\n uom?: MeasurementUnit;\r\n}\r\n\r\nexport interface IUnsTable {\r\n time: ISO8601;\r\n dataGroup?: string;\r\n columns: IUnsTableColumn[];\r\n intervalStart?: ISO8601 | number;\r\n intervalEnd?: ISO8601 | number;\r\n windowStart?: ISO8601 | number;\r\n windowEnd?: ISO8601 | number;\r\n eventId?: string;\r\n deleted?: boolean;\r\n deletedAt?: ISO8601 | number;\r\n lastSeen?: ISO8601 | number;\r\n}\r\n\r\nexport interface IMqttAttributeMessage {\r\n attribute: UnsAttribute;\r\n description?: string;\r\n tags?: UnsTags[];\r\n attributeNeedsPersistence?: boolean | null;\r\n /**\r\n * How the controller determines if this attribute is live or stale.\r\n * Defaults to `\"interval\"` with the controller's default interval (~120s) when omitted.\r\n *\r\n * @example\r\n * // Sensor publishing every 2 seconds:\r\n * { validityMode: \"interval\", expectedIntervalMs: 2000 }\r\n *\r\n * // Status attribute publishing every 2 seconds (string values like \"HEATING\"):\r\n * { validityMode: \"interval\", expectedIntervalMs: 2000 }\r\n *\r\n * // Material location with ENTERED/EXITED lifecycle:\r\n * { validityMode: \"lifecycle\", lifecycleEndValue: \"EXITED\" }\r\n *\r\n * // Static configuration value:\r\n * { validityMode: \"static\" }\r\n */\r\n validityMode?: ValidityMode;\r\n /**\r\n * Expected publish interval in milliseconds. Only meaningful for `validityMode: \"interval\"`.\r\n * The controller marks the attribute as stale after ~2× this value without a heartbeat update.\r\n * Ignored for `\"lifecycle\"` and `\"static\"` modes.\r\n */\r\n expectedIntervalMs?: number;\r\n /**\r\n * The string value that marks a lifecycle as completed. Only meaningful for `validityMode: \"lifecycle\"`.\r\n * When the attribute's current value matches this, the controller considers the lifecycle done.\r\n * Example: `\"EXITED\"` for a location attribute with ENTERED/EXITED events.\r\n */\r\n lifecycleEndValue?: string;\r\n}\r\n\r\ntype AttributePayload =\r\n | { message: IUnsMessage; data?: never; table?: never; createdAt?: never; expiresAt?: never }\r\n | { message?: never; data: IUnsData; table?: never; createdAt?: ISO8601; expiresAt?: ISO8601 }\r\n | { message?: never; data?: never; table: IUnsTable; createdAt?: ISO8601; expiresAt?: ISO8601 };\r\n\r\nexport type IMqttAttributeEntry = IMqttAttributeMessage & AttributePayload;\r\n\r\nexport interface IMqttPublishRequest {\r\n topic: UnsTopics;\r\n asset: UnsAsset;\r\n assetDescription?: string;\r\n objectType: UnsObjectType;\r\n objectTypeDescription?: string;\r\n objectId: UnsObjectId;\r\n attributes: IMqttAttributeEntry | IMqttAttributeEntry[];\r\n}\r\n\r\n// This interface represents a packet for a UNS system\r\nexport interface IUnsPacket {\r\n // The message object of the packet\r\n message: IUnsExtendedMessage;\r\n \r\n // The HMAC signature of the message\r\n messageSignature?: string;\r\n\r\n // Automatically calculated interval between two packets in ms\r\n interval?: number;\r\n\r\n // Current library version\r\n readonly version: string;\r\n\r\n // Autogenerated sequence number\r\n sequenceId?: number;\r\n}\r\n\r\nexport interface IUnsPackatParameters {\r\n\r\n}\r\n\r\nexport interface IUnsMessage {\r\n data?: IUnsData;\r\n table?: IUnsTable;\r\n expiresAt?: ISO8601;\r\n createdAt?: ISO8601;\r\n}\r\n\r\nexport interface IUnsExtendedMessage extends IUnsMessage {\r\n data?: IUnsExtendedData;\r\n}\r\n\r\n/**\r\n * Controls how the controller determines whether an attribute is live or stale.\r\n *\r\n * - `\"interval\"` — Attribute publishes periodically. Stale if no heartbeat within ~2× the expected interval.\r\n * Use with `expectedIntervalMs`. Works for both numeric sensors (temperature every 2s)\r\n * and string status attributes (status every 2s). Example:\r\n * `{ validityMode: \"interval\", expectedIntervalMs: 2000 }`\r\n *\r\n * - `\"lifecycle\"` — Attribute represents a lifecycle with a start and end event.\r\n * Use with `lifecycleEndValue` to mark the end state. Example: material location with \"ENTERED\" / \"EXITED\".\r\n *\r\n * - `\"static\"` — Attribute is set once and never changes (configuration, metadata). Always live.\r\n *\r\n * When omitted, defaults to `\"interval\"` with the controller's default interval (~120s).\r\n */\r\nexport type ValidityMode = \"interval\" | \"lifecycle\" | \"static\";\r\n\r\nexport interface ITopicObject {\r\n timestamp: string;\r\n attribute:string;\r\n attributeType: UnsAttributeType;\r\n topic:string;\r\n description:string;\r\n dataGroup:string;\r\n tags:string[] | null;\r\n attributeNeedsPersistence: boolean | null;\r\n asset: UnsAsset;\r\n assetDescription?: string;\r\n objectType: UnsObjectType;\r\n objectTypeDescription?: string;\r\n objectId: UnsObjectId;\r\n /** Liveliness validity mode — how the controller determines if this attribute is live/stale. */\r\n validityMode?: ValidityMode;\r\n /** For interval mode: expected publish interval in milliseconds (stale after ~2x this value). */\r\n expectedIntervalMs?: number;\r\n /** For lifecycle mode: the string value that marks the lifecycle as completed (e.g. \"EXITED\"). */\r\n lifecycleEndValue?: string;\r\n}\r\n\r\n// API Interfaces below\r\nexport interface IApiObject {\r\n timestamp: string;\r\n attribute:string;\r\n topic:string;\r\n attributeType: UnsAttributeType;\r\n apiDescription?: string; // Optional description for the API endpoint\r\n apiHost: string; // Hostname of the service\r\n apiEndpoint: string; // API endpoint for virtual topics\r\n apiSwaggerEndpoint: string; // Swagger endpoint for API documentation\r\n apiMethod: \"GET\" | \"POST\" | \"PUT\" | \"DELETE\"; // HTTP method for API endpoint\r\n apiQueryParams: QueryParamDef[]; // query parameters for the API endpoint\r\n asset: UnsAsset;\r\n objectType: UnsObjectType;\r\n objectId: UnsObjectId;\r\n controllerName?: string;\r\n controllerHost?: string;\r\n controllerPort?: string;\r\n controllerPublicBase?: string;\r\n}\r\n\r\nexport interface IApiCatchallMapping {\r\n topic: string;\r\n apiBase: string;\r\n apiBasePath: string;\r\n swaggerPath: string;\r\n}\r\n\r\nexport interface QueryParamDef {\r\n name: string;\r\n type: \"string\" | \"number\" | \"boolean\";\r\n required?: boolean;\r\n description?: string;\r\n /**\r\n * Optional canonical chat alias used by assistant tooling.\r\n * Typical values: from, to, limit, topic, timezone, summaryOnly.\r\n */\r\n chatCanonical?: string;\r\n /**\r\n * Optional default query value. Included in generated OpenAPI metadata.\r\n */\r\n defaultValue?: string | number | boolean;\r\n}\r\n\r\nexport interface ApiChatDefaults {\r\n from?: string;\r\n to?: string;\r\n limit?: number;\r\n topic?: string;\r\n timezone?: string;\r\n summaryOnly?: boolean;\r\n [key: string]: string | number | boolean | undefined;\r\n}\r\n\r\nexport interface IApiProxyOptions {\r\n jwtSecret?: string;\r\n jwks?: {\r\n wellKnownJwksUrl: string;\r\n activeKidUrl?: string;\r\n cacheTtlMs?: number;\r\n algorithms?: (\"RS256\" | \"RS384\" | \"RS512\")[];\r\n };\r\n /**\r\n * Optional base prefixes to mount the API and swagger JSON under (e.g. \"/archiver-3\").\r\n * Defaults to \"/api\" when not provided.\r\n */\r\n apiBasePath?: string;\r\n swaggerBasePath?: string;\r\n /**\r\n * Skip mounting the default \"/api\" route. Useful when rebasing entirely under a custom prefix.\r\n */\r\n disableDefaultApiMount?: boolean;\r\n}\r\n\r\nexport interface IGetEndpointOptions {\r\n apiDescription?: string;\r\n tags?: string[];\r\n queryParams?: QueryParamDef[];\r\n /**\r\n * Optional defaults consumed by chat tooling (published as OpenAPI vendor extension x-uns-chat.defaults).\r\n */\r\n chatDefaults?: ApiChatDefaults;\r\n}\r\n\r\nexport interface IPostEndpointOptions {\r\n apiDescription?: string;\r\n tags?: string[];\r\n requestBody?: {\r\n description?: string;\r\n required?: boolean;\r\n schema?: Record<string, unknown>;\r\n };\r\n}\r\n"]}