ironflock 1.5.2 → 1.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +43 -7
- package/dist/index.cjs +2 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +123 -7
- package/dist/index.mjs +1024 -839
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -309,6 +309,14 @@ const data = await ironflock.getHistory("sensordata", {
|
|
|
309
309
|
{ column: "humidity", operator: "<=", value: 80 },
|
|
310
310
|
],
|
|
311
311
|
});
|
|
312
|
+
|
|
313
|
+
// Current value(s) only: add the `latest` marker. The data backend derives
|
|
314
|
+
// the latest row per entity in SQL (entity = the table's maintainLatestFlagFor
|
|
315
|
+
// columns from the data-template; without one, the single most recent row).
|
|
316
|
+
const current = await ironflock.getHistory("sensordata", {
|
|
317
|
+
limit: 100,
|
|
318
|
+
filterAnd: [{ latest: true }],
|
|
319
|
+
});
|
|
312
320
|
```
|
|
313
321
|
|
|
314
322
|
| Parameter | Type | Description |
|
|
@@ -323,11 +331,16 @@ const data = await ironflock.getHistory("sensordata", {
|
|
|
323
331
|
| `limit` | `number` | Maximum number of rows to return (1–10000, required) |
|
|
324
332
|
| `offset` | `number`, optional | Offset for pagination |
|
|
325
333
|
| `timeRange` | `ISOTimeRange`, optional | `{ start: "<ISO datetime>", end: "<ISO datetime>" }` |
|
|
326
|
-
| `filterAnd` | `
|
|
334
|
+
| `filterAnd` | `TableFilter[]`, optional | List of AND filter conditions `{ column: string, operator: string, value: ... }`, and/or the `{ latest: true }` mode marker (see below) |
|
|
335
|
+
| `columns` | `string[]`, optional | Columns to return (`tsp`, `device_key` and `authid` are always included). Omit for all columns |
|
|
327
336
|
|
|
328
337
|
Supported filter operators: `=`, `!=`, `>`, `<`, `>=`, `<=`, `LIKE`, `ILIKE`, `IN`, `NOT IN`, `IS`, `IS NOT`.
|
|
329
338
|
|
|
330
|
-
**
|
|
339
|
+
**Latest values:** a `{ latest: true }` entry in `filterAnd` is not a WHERE predicate but a mode switch: the data backend returns only the latest row per entity, derived on the fly in SQL (`DISTINCT ON` over the entity key declared as `maintainLatestFlagFor` in the table's data-template; a table without an entity key yields the single most recent row). The former physical `latest_flag` column no longer exists — a legacy `{ column: "latest_flag", operator: "=", value: true }` filter is still accepted and treated as the marker, but new code should use `{ latest: true }`. Other predicates combine with the marker as expected: entity-key predicates narrow which entities are returned, all other predicates and `timeRange` filter the resulting latest rows.
|
|
340
|
+
|
|
341
|
+
**Returns:** `Promise<unknown>` — The query result data (typically an array of row objects).
|
|
342
|
+
|
|
343
|
+
**Throws:** `Error` with a descriptive message on invalid parameters, when the history procedure is not registered (table not declared / data backend not running), or when the router rejects the call.
|
|
331
344
|
|
|
332
345
|
---
|
|
333
346
|
|
|
@@ -359,9 +372,11 @@ const series = await ironflock.getSeriesHistory("sensordata", {
|
|
|
359
372
|
| `limit` | `number` | Maximum number of buckets (1–10000) |
|
|
360
373
|
| `timeRange` | `SeriesTimeRange` | `[start, end]` — ISO strings or epoch-ms numbers; `null` = open end (required) |
|
|
361
374
|
| `groupBy` | `string[]`, optional | Columns to group the series by |
|
|
362
|
-
| `filterAnd` | `SQLFilterAnd[]`, optional | AND filter conditions |
|
|
375
|
+
| `filterAnd` | `SQLFilterAnd[]`, optional | AND filter conditions (WHERE predicates only — the `{ latest: true }` marker is not supported in series queries; use `getHistory` for latest values) |
|
|
363
376
|
|
|
364
|
-
**Returns:** `Promise<unknown
|
|
377
|
+
**Returns:** `Promise<unknown>` — The down-sampled series rows.
|
|
378
|
+
|
|
379
|
+
**Throws:** `Error` with a descriptive message on invalid parameters, when the series procedure is not registered, or when the router rejects the call.
|
|
365
380
|
|
|
366
381
|
---
|
|
367
382
|
|
|
@@ -457,7 +472,9 @@ await ironflock.setDeviceLocation(8.6821, 50.1109);
|
|
|
457
472
|
| `long` | `number` | Longitude (-180 to 180) |
|
|
458
473
|
| `lat` | `number` | Latitude (-90 to 90) |
|
|
459
474
|
|
|
460
|
-
**Returns:** `Promise<unknown
|
|
475
|
+
**Returns:** `Promise<unknown>` — The result of the location update call.
|
|
476
|
+
|
|
477
|
+
**Throws:** `Error` with a descriptive message on invalid coordinates or when the location service call fails.
|
|
461
478
|
|
|
462
479
|
> **Note:** Location history is not stored. If you need location history, create a dedicated table and use `publishToTable`.
|
|
463
480
|
|
|
@@ -639,10 +656,14 @@ Returned by `connectToApp`. A read-only view of a provider app's shared tables a
|
|
|
639
656
|
|
|
640
657
|
#### `consumedApp.getHistory(tablename, queryParams?)`
|
|
641
658
|
|
|
642
|
-
Queries history rows of a shared table or transform. Takes the same query parameters as [`getHistory`](#gethistorytablename-queryparams) (`limit`, `offset`, `timeRange`, `filterAnd`).
|
|
659
|
+
Queries history rows of a shared table or transform. Takes the same query parameters as [`getHistory`](#gethistorytablename-queryparams) (`limit`, `offset`, `timeRange`, `filterAnd`, `columns`) — including the `{ latest: true }` marker in `filterAnd` for reading the provider's current values.
|
|
643
660
|
|
|
644
661
|
```ts
|
|
645
662
|
const rows = await weather.getHistory("forecasts", { limit: 100 });
|
|
663
|
+
const current = await weather.getHistory("forecasts", {
|
|
664
|
+
limit: 100,
|
|
665
|
+
filterAnd: [{ latest: true }],
|
|
666
|
+
});
|
|
646
667
|
```
|
|
647
668
|
|
|
648
669
|
**Returns:** `Promise<unknown>` — The query result rows.
|
|
@@ -679,7 +700,7 @@ const series = await weather.getSeriesHistory("forecasts", {
|
|
|
679
700
|
| `limit` | `number` | Maximum number of rows (1–10000) |
|
|
680
701
|
| `timeRange` | `SeriesTimeRange` | `[start, end]` — ISO strings or epoch-ms numbers; `null` = open end (required) |
|
|
681
702
|
| `groupBy` | `string[]`, optional | Columns to group the series by |
|
|
682
|
-
| `filterAnd` | `SQLFilterAnd[]`, optional | AND filter conditions |
|
|
703
|
+
| `filterAnd` | `SQLFilterAnd[]`, optional | AND filter conditions (WHERE predicates only — no `{ latest: true }` marker) |
|
|
683
704
|
|
|
684
705
|
**Returns:** `Promise<unknown>` — The down-sampled series rows.
|
|
685
706
|
|
|
@@ -703,6 +724,21 @@ Thrown by `connectToApp` and the `ConsumedApp` methods when cross-app access is
|
|
|
703
724
|
| `PRIVATE_TABLE` | The requested table/transform is not in the provider's shared catalog |
|
|
704
725
|
| `NOT_AUTHORIZED` | The router/provider denied access (e.g. the grant was revoked) |
|
|
705
726
|
|
|
727
|
+
---
|
|
728
|
+
|
|
729
|
+
### `WampError`
|
|
730
|
+
|
|
731
|
+
All SDK methods fail with a descriptive `Error` — nothing is silently swallowed. When the failure originates from the WAMP router or a remote handler, the error is a `WampError` (a native `Error` subclass) whose message names the operation, the topic and the reason, and which preserves the raw WAMP payload:
|
|
732
|
+
|
|
733
|
+
| Property | Type | Description |
|
|
734
|
+
|----------|------|-------------|
|
|
735
|
+
| `message` | `string` | e.g. `Call of procedure 'history.transformed.foo' failed with WAMP error 'wamp.error.no_such_procedure'` |
|
|
736
|
+
| `error` | `string` | The WAMP error URI |
|
|
737
|
+
| `args` | `unknown[]` | The WAMP error's positional payload |
|
|
738
|
+
| `kwargs` | `Record<string, unknown>` | The WAMP error's keyword payload |
|
|
739
|
+
|
|
740
|
+
Operations attempted while not connected fail with a plain `Error` explaining that no session is available and pointing to `start()`.
|
|
741
|
+
|
|
706
742
|
## Development
|
|
707
743
|
|
|
708
744
|
Install dependencies:
|
package/dist/index.cjs
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const D=require("autobahn");function H(h){return h&&h.__esModule&&Object.prototype.hasOwnProperty.call(h,"default")?h.default:h}var O={exports:{}},U;function G(){return U||(U=1,(function(h){var t=Object.prototype.hasOwnProperty,s="~";function a(){}Object.create&&(a.prototype=Object.create(null),new a().__proto__||(s=!1));function l(o,e,n){this.fn=o,this.context=e,this.once=n||!1}function i(o,e,n,c,d){if(typeof n!="function")throw new TypeError("The listener must be a function");var v=new l(n,c||o,d),f=s?s+e:e;return o._events[f]?o._events[f].fn?o._events[f]=[o._events[f],v]:o._events[f].push(v):(o._events[f]=v,o._eventsCount++),o}function u(o,e){--o._eventsCount===0?o._events=new a:delete o._events[e]}function r(){this._events=new a,this._eventsCount=0}r.prototype.eventNames=function(){var e=[],n,c;if(this._eventsCount===0)return e;for(c in n=this._events)t.call(n,c)&&e.push(s?c.slice(1):c);return Object.getOwnPropertySymbols?e.concat(Object.getOwnPropertySymbols(n)):e},r.prototype.listeners=function(e){var n=s?s+e:e,c=this._events[n];if(!c)return[];if(c.fn)return[c.fn];for(var d=0,v=c.length,f=new Array(v);d<v;d++)f[d]=c[d].fn;return f},r.prototype.listenerCount=function(e){var n=s?s+e:e,c=this._events[n];return c?c.fn?1:c.length:0},r.prototype.emit=function(e,n,c,d,v,f){var g=s?s+e:e;if(!this._events[g])return!1;var y=this._events[g],A=arguments.length,p,m;if(y.fn){switch(y.once&&this.removeListener(e,y.fn,void 0,!0),A){case 1:return y.fn.call(y.context),!0;case 2:return y.fn.call(y.context,n),!0;case 3:return y.fn.call(y.context,n,c),!0;case 4:return y.fn.call(y.context,n,c,d),!0;case 5:return y.fn.call(y.context,n,c,d,v),!0;case 6:return y.fn.call(y.context,n,c,d,v,f),!0}for(m=1,p=new Array(A-1);m<A;m++)p[m-1]=arguments[m];y.fn.apply(y.context,p)}else{var Q=y.length,S;for(m=0;m<Q;m++)switch(y[m].once&&this.removeListener(e,y[m].fn,void 0,!0),A){case 1:y[m].fn.call(y[m].context);break;case 2:y[m].fn.call(y[m].context,n);break;case 3:y[m].fn.call(y[m].context,n,c);break;case 4:y[m].fn.call(y[m].context,n,c,d);break;default:if(!p)for(S=1,p=new Array(A-1);S<A;S++)p[S-1]=arguments[S];y[m].fn.apply(y[m].context,p)}}return!0},r.prototype.on=function(e,n,c){return i(this,e,n,c,!1)},r.prototype.once=function(e,n,c){return i(this,e,n,c,!0)},r.prototype.removeListener=function(e,n,c,d){var v=s?s+e:e;if(!this._events[v])return this;if(!n)return u(this,v),this;var f=this._events[v];if(f.fn)f.fn===n&&(!d||f.once)&&(!c||f.context===c)&&u(this,v);else{for(var g=0,y=[],A=f.length;g<A;g++)(f[g].fn!==n||d&&!f[g].once||c&&f[g].context!==c)&&y.push(f[g]);y.length?this._events[v]=y.length===1?y[0]:y:u(this,v)}return this},r.prototype.removeAllListeners=function(e){var n;return e?(n=s?s+e:e,this._events[n]&&u(this,n)):(this._events=new a,this._eventsCount=0),this},r.prototype.off=r.prototype.removeListener,r.prototype.addListener=r.prototype.on,r.prefixed=s,r.EventEmitter=r,h.exports=r})(O)),O.exports}var J=G();const Z=H(J),z="wss://cbw.datapods.io/ws-ua-usr",V="wss://cbw.ironflock.com/ws-ua-usr",X="wss://cbw.ironflock.dev/ws-ua-usr",q="wss://cbw.record-evolution.com/ws-ua-usr",C="ws://localhost:8080/ws-ua-usr",F={"https://studio.datapods.io":z,"https://studio.ironflock.dev":X,"https://studio.ironflock.com":V,"https://studio.record-evolution.com":q,"http://localhost:8085":C,"http://localhost:8086":C,"http://host.docker.internal:8086":C},ee=6e3,re=["wamp.error.not_authorized","wamp.error.authorization_failed","wamp.error.authentication_failed","wamp.error.no_auth_method"];class k extends Z{constructor(){super(),this.failOnAuthError=!1,this.subscriptions=[],this.registrations=[],this.firstResolver=()=>{},this.firstRejecter=()=>{},this.shouldReconnect=!1,this.isReconnecting=!1,this.hasOpenedOnce=!1}static getWebSocketURI(t){var l;const s=typeof process<"u"?(l=process.env)==null?void 0:l.DEVICE_ENDPOINT_URL:void 0;if(s)try{const i=new URL(s);return i.pathname="/ws-ua-usr",i.toString().replace(/\/$/,"")}catch{}if(!t)return V;const a=F[t];if(a===void 0)throw new Error(`Cannot resolve WebSocket URI for reswarmUrl=${JSON.stringify(t)}. Set DEVICE_ENDPOINT_URL to the deployment's WAMP router URL (e.g. ws://<host>:18080/ws-re-dev) or pass ironFlockUrl=… to IronFlock(). Known cloud URLs: ${JSON.stringify(Object.keys(F))}`);return a}configure(t,s,a,l,i){this.realm=`realm-${t}-${s}-${a}`,this.serial_number=l,this.socketURI=i??k.getWebSocketURI()}async start(){if(!this.realm||!this.serial_number||!this.socketURI)throw new Error("CrossbarConnection must be configured before starting. Call configure() first.");return this.shouldReconnect=!0,this.firstConnection=new Promise((t,s)=>{this.firstResolver=t,this.firstRejecter=s}),this.connection=new D.Connection({realm:this.realm,url:this.socketURI,authmethods:["wampcra"],authid:this.serial_number,max_retries:-1,max_retry_delay:2,initial_retry_delay:1,autoping_interval:2,autoping_timeout:4,onchallenge:(t,s,a)=>D.auth_cra.sign(this.serial_number,a.challenge)}),this.connection.onopen=this.onOpen.bind(this),this.connection.onclose=this.onClose.bind(this),this.connection.open(),this.firstConnection}onOpen(t){this.session=t,this.session.caller_disclose_me=!0,this.hasOpenedOnce=!0,this.resubscribeAll(),this.reregisterAll(),this.emit("connected",this.serial_number),this.firstResolver(),this.firstResolver=()=>{}}onClose(t,s){this.session=void 0,this.emit("disconnected"),this.firstRejecter(new Error(`Connection failed: ${t} - ${JSON.stringify(s,null,2)}`)),this.firstRejecter=()=>{},console.warn("Connection closed:",{reason:t,details:s,realm:this.realm,url:this.socketURI,authid:this.serial_number});const a=(s==null?void 0:s.reason)??t;return this.failOnAuthError&&typeof a=="string"&&re.includes(a)?(this.shouldReconnect=!1,this.emit("auth_failure",a,s),!0):(this.shouldReconnect&&this.hasOpenedOnce&&(s==null?void 0:s.will_retry)===!1&&this.handleManualReconnect((s==null?void 0:s.reason)??t),!1)}async handleManualReconnect(t){if(!(this.isReconnecting||!this.shouldReconnect)){for(this.isReconnecting=!0;this.shouldReconnect&&!this.session;)if(await new Promise(s=>setTimeout(s,1e3)),this.shouldReconnect&&this.connection&&!this.session){console.log(`Manually retrying connection after ${t}...`);try{this.connection.open(),await new Promise(s=>setTimeout(s,500))}catch(s){console.error("Error during manual reconnection attempt:",s)}}this.isReconnecting=!1}}async sessionWait(){const t=Date.now();for(;!this.session;){if(Date.now()-t>ee)throw new Error("Timeout waiting for session");await new Promise(s=>setTimeout(s,200))}}async waitForConnection(){return this.firstConnection}getSession(){return this.session}get is_open(){var t;return!!((t=this.session)!=null&&t.isOpen)}isConnected(){return this.is_open}stop(){var t;this.shouldReconnect=!1,(t=this.connection)==null||t.close("wamp.close.normal","Connection closed by client")}async subscribe(t,s){var l;await this.sessionWait();const a=await((l=this.session)==null?void 0:l.subscribe(t,s));return a&&this.subscriptions.push(a),a}async unsubscribe(t){var a;await this.sessionWait();const s=this.subscriptions.indexOf(t);s!==-1&&(this.subscriptions.splice(s,1),await((a=this.session)==null?void 0:a.unsubscribe(t)))}async unsubscribeTopic(t){const s=this.subscriptions.filter(a=>a.topic===t);for(const a of s)await this.unsubscribe(a)}async resubscribeAll(){const t=[...this.subscriptions];this.subscriptions=[],await Promise.all(t.map(s=>this.subscribe(s.topic,s.handler)))}async reregisterAll(){const t=[...this.registrations];this.registrations=[],await Promise.all(t.map(s=>this.register(s.procedure,s.endpoint,s.options)))}async register(t,s,a){var u;await this.sessionWait();const l={force_reregister:!0,...a??{}},i=await((u=this.session)==null?void 0:u.register(t,s,l));return i&&this.registrations.push(i),i}async unregister(t){var a;await this.sessionWait(),await((a=this.session)==null?void 0:a.unregister(t));const s=this.registrations.indexOf(t);s!==-1&&this.registrations.splice(s,1)}async call(t,s,a,l){var i;return await this.sessionWait(),(i=this.session)==null?void 0:i.call(t,s,a,l)}async publish(t,s,a,l){var i;return await this.sessionWait(),(i=this.session)==null?void 0:i.publish(t,s,a,l)}}const I=h=>Math.floor(h)===h&&te<=h&&h<=se,te=0,se=2**32-1,$=h=>ne.test(h),ne=/^[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])(T|\s)([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9](?:\.[0-9]{1,9})?(Z|[+-]([01][0-9]|2[0-3]):[0-5][0-9])$/i,_=h=>{const t=s=>{if(h.length===0)return!0;const a=h[h.length-1].path;return s.length>a.length||a.substring(0,s.length)!==s};return(s,a)=>(s&&t(a.path)&&(a.value===void 0&&(a.description??(a.description=["The value at this path is `undefined`.","",`Please fill the \`${a.expected}\` typed value next time.`].join(`
|
|
2
|
-
`))),h.push(a)),!1)},T=h=>Object.assign(h,{"~standard":{version:1,vendor:"typia",validate:t=>{const s=h(t);return s.success?{value:s.data}:{issues:s.errors.map(a=>({message:`expected ${a.expected}, got ${a.value}`,path:oe(a.path)}))}}}});var w;(function(h){h[h.Start=0]="Start",h[h.Property=1]="Property",h[h.StringKey=2]="StringKey",h[h.NumberKey=3]="NumberKey"})(w||(w={}));const oe=h=>{if(!h.startsWith("$input"))throw new Error(`Invalid path: ${JSON.stringify(h)}`);const t=[];let s="",a=w.Start,l=5;for(;l<h.length-1;){l++;const i=h[l];if(a===w.Property?i==="."||i==="["?(t.push({key:s}),a=w.Start):l===h.length-1?(s+=i,t.push({key:s}),l++,a=w.Start):s+=i:a===w.StringKey?i==='"'?(t.push({key:JSON.parse(s+i)}),l+=2,a=w.Start):i==="\\"?(s+=h[l],l++,s+=h[l]):s+=i:a===w.NumberKey&&(i==="]"?(t.push({key:Number.parseInt(s)}),l++,a=w.Start):s+=i),a===w.Start&&l<h.length-1){const u=h[l];if(s="",u==="[")h[l+1]==='"'?(a=w.StringKey,l++,s='"'):a=w.NumberKey;else if(u===".")a=w.Property;else throw new Error("Unreachable: pointer points invalid character")}}if(a!==w.Start)throw new Error(`Failed to parse path: ${JSON.stringify(h)}`);return t};var R=(h=>(h.DEVELOPMENT="dev",h.PRODUCTION="prod",h))(R||{});const P=(()=>{const h=e=>typeof e.limit=="number"&&I(e.limit)&&1<=e.limit&&e.limit<=1e4&&(e.offset===void 0||typeof e.offset=="number"&&I(e.offset)&&0<=e.offset)&&(e.timeRange===void 0||typeof e.timeRange=="object"&&e.timeRange!==null&&t(e.timeRange))&&(e.filterAnd===void 0||Array.isArray(e.filterAnd)&&e.filterAnd.every(n=>typeof n=="object"&&n!==null&&s(n))),t=e=>typeof e.start=="string"&&$(e.start)&&typeof e.end=="string"&&$(e.end),s=e=>typeof e.column=="string"&&1<=e.column.length&&typeof e.operator=="string"&&1<=e.operator.length&&e.value!==null&&e.value!==void 0&&(typeof e.value=="string"||typeof e.value=="number"||typeof e.value=="boolean"||Array.isArray(e.value)&&e.value.every(n=>typeof n=="string"||typeof n=="number")),a=(e,n,c=!0)=>[typeof e.limit=="number"&&(I(e.limit)||o(c,{path:n+".limit",expected:'number & Type<"uint32">',value:e.limit}))&&(1<=e.limit||o(c,{path:n+".limit",expected:"number & Minimum<1>",value:e.limit}))&&(e.limit<=1e4||o(c,{path:n+".limit",expected:"number & Maximum<10000>",value:e.limit}))||o(c,{path:n+".limit",expected:'(number & Type<"uint32"> & Minimum<1> & Maximum<10000>)',value:e.limit}),e.offset===void 0||typeof e.offset=="number"&&(I(e.offset)||o(c,{path:n+".offset",expected:'number & Type<"uint32">',value:e.offset}))&&(0<=e.offset||o(c,{path:n+".offset",expected:"number & Minimum<0>",value:e.offset}))||o(c,{path:n+".offset",expected:'((number & Type<"uint32"> & Minimum<0>) | undefined)',value:e.offset}),e.timeRange===void 0||(typeof e.timeRange=="object"&&e.timeRange!==null||o(c,{path:n+".timeRange",expected:"(ISOTimeRange | undefined)",value:e.timeRange}))&&l(e.timeRange,n+".timeRange",c)||o(c,{path:n+".timeRange",expected:"(ISOTimeRange | undefined)",value:e.timeRange}),e.filterAnd===void 0||(Array.isArray(e.filterAnd)||o(c,{path:n+".filterAnd",expected:"(Array<SQLFilterAnd> | undefined)",value:e.filterAnd}))&&e.filterAnd.map((d,v)=>(typeof d=="object"&&d!==null||o(c,{path:n+".filterAnd["+v+"]",expected:"SQLFilterAnd",value:d}))&&i(d,n+".filterAnd["+v+"]",c)||o(c,{path:n+".filterAnd["+v+"]",expected:"SQLFilterAnd",value:d})).every(d=>d)||o(c,{path:n+".filterAnd",expected:"(Array<SQLFilterAnd> | undefined)",value:e.filterAnd})].every(d=>d),l=(e,n,c=!0)=>[typeof e.start=="string"&&($(e.start)||o(c,{path:n+".start",expected:'string & Format<"date-time">',value:e.start}))||o(c,{path:n+".start",expected:'(string & Format<"date-time">)',value:e.start}),typeof e.end=="string"&&($(e.end)||o(c,{path:n+".end",expected:'string & Format<"date-time">',value:e.end}))||o(c,{path:n+".end",expected:'(string & Format<"date-time">)',value:e.end})].every(d=>d),i=(e,n,c=!0)=>[typeof e.column=="string"&&(1<=e.column.length||o(c,{path:n+".column",expected:"string & MinLength<1>",value:e.column}))||o(c,{path:n+".column",expected:"(string & MinLength<1>)",value:e.column}),typeof e.operator=="string"&&(1<=e.operator.length||o(c,{path:n+".operator",expected:"string & MinLength<1>",value:e.operator}))||o(c,{path:n+".operator",expected:"(string & MinLength<1>)",value:e.operator}),(e.value!==null||o(c,{path:n+".value",expected:"(Array<string | number> | boolean | number | string)",value:e.value}))&&(e.value!==void 0||o(c,{path:n+".value",expected:"(Array<string | number> | boolean | number | string)",value:e.value}))&&(typeof e.value=="string"||typeof e.value=="number"||typeof e.value=="boolean"||(Array.isArray(e.value)||o(c,{path:n+".value",expected:"(Array<string | number> | boolean | number | string)",value:e.value}))&&e.value.map((d,v)=>typeof d=="string"||typeof d=="number"||o(c,{path:n+".value["+v+"]",expected:"(number | string)",value:d})).every(d=>d)||o(c,{path:n+".value",expected:"(Array<string | number> | boolean | number | string)",value:e.value}))].every(d=>d),u=e=>typeof e=="object"&&e!==null&&h(e);let r,o;return T(e=>{if(u(e)===!1){r=[],o=_(r),((c,d,v=!0)=>(typeof c=="object"&&c!==null||o(!0,{path:d+"",expected:"TableQueryParams",value:c}))&&a(c,d+"",!0)||o(!0,{path:d+"",expected:"TableQueryParams",value:c}))(e,"$input",!0);const n=r.length===0;return n?{success:n,data:e}:{success:n,errors:r,data:e}}return{success:!0,data:e}})})(),j=(()=>{const h=e=>{const n=e,c=[[d=>d.length===2&&(d[0]===null||typeof d[0]=="number")&&(d[1]===null||typeof d[1]=="number"),d=>d.length===2&&(d[0]===null||typeof d[0]=="number")&&(d[1]===null||typeof d[1]=="number")],[d=>d.length===2&&(d[0]===null||typeof d[0]=="string")&&(d[1]===null||typeof d[1]=="string"),d=>d.length===2&&(d[0]===null||typeof d[0]=="string")&&(d[1]===null||typeof d[1]=="string")]];for(const d of c)if(d[0](n))return d[1](n);return!1},t=(e,n,c=!0)=>{const d=e,v=[[f=>f.length===2&&[f[0]===null||typeof f[0]=="number",f[1]===null||typeof f[1]=="number"].every(g=>g),f=>(f.length===2||o(c,{path:n,expected:"[(null | number), (null | number)]",value:f}))&&[f[0]===null||typeof f[0]=="number"||o(c,{path:n+"[0]",expected:"(null | number)",value:f[0]}),f[1]===null||typeof f[1]=="number"||o(c,{path:n+"[1]",expected:"(null | number)",value:f[1]})].every(g=>g)],[f=>f.length===2&&[f[0]===null||typeof f[0]=="string",f[1]===null||typeof f[1]=="string"].every(g=>g),f=>(f.length===2||o(c,{path:n,expected:"[(null | string), (null | string)]",value:f}))&&[f[0]===null||typeof f[0]=="string"||o(c,{path:n+"[0]",expected:"(null | string)",value:f[0]}),f[1]===null||typeof f[1]=="string"||o(c,{path:n+"[1]",expected:"(null | string)",value:f[1]})].every(g=>g)]];for(const f of v)if(f[0](d))return f[1](d);return o(c,{path:n,expected:"([number | null, number | null] | [string | null, string | null])",value:e})},s=e=>Array.isArray(e.metrics)&&e.metrics.every(n=>typeof n=="string")&&(e.method==="AVG"||e.method==="SUM"||e.method==="COUNT"||e.method==="MIN"||e.method==="MAX"||e.method==="FIRST"||e.method==="LAST")&&typeof e.limit=="number"&&I(e.limit)&&1<=e.limit&&e.limit<=1e4&&Array.isArray(e.timeRange)&&(h(e.timeRange)||!1)&&(e.groupBy===null||e.groupBy===void 0||Array.isArray(e.groupBy)&&e.groupBy.every(n=>typeof n=="string"))&&(e.filterAnd===null||e.filterAnd===void 0||Array.isArray(e.filterAnd)&&e.filterAnd.every(n=>typeof n=="object"&&n!==null&&a(n))),a=e=>typeof e.column=="string"&&1<=e.column.length&&typeof e.operator=="string"&&1<=e.operator.length&&e.value!==null&&e.value!==void 0&&(typeof e.value=="string"||typeof e.value=="number"||typeof e.value=="boolean"||Array.isArray(e.value)&&e.value.every(n=>typeof n=="string"||typeof n=="number")),l=(e,n,c=!0)=>[(Array.isArray(e.metrics)||o(c,{path:n+".metrics",expected:"Array<string>",value:e.metrics}))&&e.metrics.map((d,v)=>typeof d=="string"||o(c,{path:n+".metrics["+v+"]",expected:"string",value:d})).every(d=>d)||o(c,{path:n+".metrics",expected:"Array<string>",value:e.metrics}),e.method==="AVG"||e.method==="SUM"||e.method==="COUNT"||e.method==="MIN"||e.method==="MAX"||e.method==="FIRST"||e.method==="LAST"||o(c,{path:n+".method",expected:'("AVG" | "COUNT" | "FIRST" | "LAST" | "MAX" | "MIN" | "SUM")',value:e.method}),typeof e.limit=="number"&&(I(e.limit)||o(c,{path:n+".limit",expected:'number & Type<"uint32">',value:e.limit}))&&(1<=e.limit||o(c,{path:n+".limit",expected:"number & Minimum<1>",value:e.limit}))&&(e.limit<=1e4||o(c,{path:n+".limit",expected:"number & Maximum<10000>",value:e.limit}))||o(c,{path:n+".limit",expected:'(number & Type<"uint32"> & Minimum<1> & Maximum<10000>)',value:e.limit}),(Array.isArray(e.timeRange)||o(c,{path:n+".timeRange",expected:"([number | null, number | null] | [string | null, string | null])",value:e.timeRange}))&&(t(e.timeRange,n+".timeRange",c)||o(c,{path:n+".timeRange",expected:"[number | null, number | null] | [string | null, string | null]",value:e.timeRange}))||o(c,{path:n+".timeRange",expected:"([number | null, number | null] | [string | null, string | null])",value:e.timeRange}),e.groupBy===null||e.groupBy===void 0||(Array.isArray(e.groupBy)||o(c,{path:n+".groupBy",expected:"(Array<string> | null | undefined)",value:e.groupBy}))&&e.groupBy.map((d,v)=>typeof d=="string"||o(c,{path:n+".groupBy["+v+"]",expected:"string",value:d})).every(d=>d)||o(c,{path:n+".groupBy",expected:"(Array<string> | null | undefined)",value:e.groupBy}),e.filterAnd===null||e.filterAnd===void 0||(Array.isArray(e.filterAnd)||o(c,{path:n+".filterAnd",expected:"(Array<SQLFilterAnd> | null | undefined)",value:e.filterAnd}))&&e.filterAnd.map((d,v)=>(typeof d=="object"&&d!==null||o(c,{path:n+".filterAnd["+v+"]",expected:"SQLFilterAnd",value:d}))&&i(d,n+".filterAnd["+v+"]",c)||o(c,{path:n+".filterAnd["+v+"]",expected:"SQLFilterAnd",value:d})).every(d=>d)||o(c,{path:n+".filterAnd",expected:"(Array<SQLFilterAnd> | null | undefined)",value:e.filterAnd})].every(d=>d),i=(e,n,c=!0)=>[typeof e.column=="string"&&(1<=e.column.length||o(c,{path:n+".column",expected:"string & MinLength<1>",value:e.column}))||o(c,{path:n+".column",expected:"(string & MinLength<1>)",value:e.column}),typeof e.operator=="string"&&(1<=e.operator.length||o(c,{path:n+".operator",expected:"string & MinLength<1>",value:e.operator}))||o(c,{path:n+".operator",expected:"(string & MinLength<1>)",value:e.operator}),(e.value!==null||o(c,{path:n+".value",expected:"(Array<string | number> | boolean | number | string)",value:e.value}))&&(e.value!==void 0||o(c,{path:n+".value",expected:"(Array<string | number> | boolean | number | string)",value:e.value}))&&(typeof e.value=="string"||typeof e.value=="number"||typeof e.value=="boolean"||(Array.isArray(e.value)||o(c,{path:n+".value",expected:"(Array<string | number> | boolean | number | string)",value:e.value}))&&e.value.map((d,v)=>typeof d=="string"||typeof d=="number"||o(c,{path:n+".value["+v+"]",expected:"(number | string)",value:d})).every(d=>d)||o(c,{path:n+".value",expected:"(Array<string | number> | boolean | number | string)",value:e.value}))].every(d=>d),u=e=>typeof e=="object"&&e!==null&&s(e);let r,o;return T(e=>{if(u(e)===!1){r=[],o=_(r),((c,d,v=!0)=>(typeof c=="object"&&c!==null||o(!0,{path:d+"",expected:"SeriesQueryParams",value:c}))&&l(c,d+"",!0)||o(!0,{path:d+"",expected:"SeriesQueryParams",value:c}))(e,"$input",!0);const n=r.length===0;return n?{success:n,data:e}:{success:n,errors:r,data:e}}return{success:!0,data:e}})})(),W=(()=>{const h=i=>typeof i.longitude=="number"&&-180<=i.longitude&&i.longitude<=180&&typeof i.latitude=="number"&&-90<=i.latitude&&i.latitude<=90,t=(i,u,r=!0)=>[typeof i.longitude=="number"&&(-180<=i.longitude||l(r,{path:u+".longitude",expected:"number & Minimum<-180>",value:i.longitude}))&&(i.longitude<=180||l(r,{path:u+".longitude",expected:"number & Maximum<180>",value:i.longitude}))||l(r,{path:u+".longitude",expected:"(number & Minimum<-180> & Maximum<180>)",value:i.longitude}),typeof i.latitude=="number"&&(-90<=i.latitude||l(r,{path:u+".latitude",expected:"number & Minimum<-90>",value:i.latitude}))&&(i.latitude<=90||l(r,{path:u+".latitude",expected:"number & Maximum<90>",value:i.latitude}))||l(r,{path:u+".latitude",expected:"(number & Minimum<-90> & Maximum<90>)",value:i.latitude})].every(o=>o),s=i=>typeof i=="object"&&i!==null&&h(i);let a,l;return T(i=>{if(s(i)===!1){a=[],l=_(a),((r,o,e=!0)=>(typeof r=="object"&&r!==null||l(!0,{path:o+"",expected:"LocationParams",value:r}))&&t(r,o+"",!0)||l(!0,{path:o+"",expected:"LocationParams",value:r}))(i,"$input",!0);const u=a.length===0;return u?{success:u,data:i}:{success:u,errors:a,data:i}}return{success:!0,data:i}})})(),B=(()=>{const h=r=>typeof r.topic=="string"&&1<=r.topic.length&&(r.args===void 0||Array.isArray(r.args))&&(r.kwargs===void 0||typeof r.kwargs=="object"&&r.kwargs!==null&&Array.isArray(r.kwargs)===!1&&t(r.kwargs)),t=r=>Object.keys(r).every(o=>(r[o]===void 0,!0)),s=(r,o,e=!0)=>[typeof r.topic=="string"&&(1<=r.topic.length||u(e,{path:o+".topic",expected:"string & MinLength<1>",value:r.topic}))||u(e,{path:o+".topic",expected:"(string & MinLength<1>)",value:r.topic}),r.args===void 0||Array.isArray(r.args)||u(e,{path:o+".args",expected:"(Array<unknown> | undefined)",value:r.args}),r.kwargs===void 0||(typeof r.kwargs=="object"&&r.kwargs!==null&&Array.isArray(r.kwargs)===!1||u(e,{path:o+".kwargs",expected:"(Record<string, unknown> | undefined)",value:r.kwargs}))&&a(r.kwargs,o+".kwargs",e)||u(e,{path:o+".kwargs",expected:"(Record<string, unknown> | undefined)",value:r.kwargs})].every(n=>n),a=(r,o,e=!0)=>[e===!1||Object.keys(r).map(n=>(r[n]===void 0,!0)).every(n=>n)].every(n=>n),l=r=>typeof r=="object"&&r!==null&&h(r);let i,u;return T(r=>{if(l(r)===!1){i=[],u=_(i),((e,n,c=!0)=>(typeof e=="object"&&e!==null||u(!0,{path:n+"",expected:"PublishParams",value:e}))&&s(e,n+"",!0)||u(!0,{path:n+"",expected:"PublishParams",value:e}))(r,"$input",!0);const o=i.length===0;return o?{success:o,data:r}:{success:o,errors:i,data:r}}return{success:!0,data:r}})})(),ae=(()=>{const h=r=>typeof r.deviceKey=="string"&&1<=r.deviceKey.length&&typeof r.topic=="string"&&1<=r.topic.length&&(r.args===void 0||Array.isArray(r.args))&&(r.kwargs===void 0||typeof r.kwargs=="object"&&r.kwargs!==null&&Array.isArray(r.kwargs)===!1&&t(r.kwargs)),t=r=>Object.keys(r).every(o=>(r[o]===void 0,!0)),s=(r,o,e=!0)=>[typeof r.deviceKey=="string"&&(1<=r.deviceKey.length||u(e,{path:o+".deviceKey",expected:"string & MinLength<1>",value:r.deviceKey}))||u(e,{path:o+".deviceKey",expected:"(string & MinLength<1>)",value:r.deviceKey}),typeof r.topic=="string"&&(1<=r.topic.length||u(e,{path:o+".topic",expected:"string & MinLength<1>",value:r.topic}))||u(e,{path:o+".topic",expected:"(string & MinLength<1>)",value:r.topic}),r.args===void 0||Array.isArray(r.args)||u(e,{path:o+".args",expected:"(Array<unknown> | undefined)",value:r.args}),r.kwargs===void 0||(typeof r.kwargs=="object"&&r.kwargs!==null&&Array.isArray(r.kwargs)===!1||u(e,{path:o+".kwargs",expected:"(Record<string, unknown> | undefined)",value:r.kwargs}))&&a(r.kwargs,o+".kwargs",e)||u(e,{path:o+".kwargs",expected:"(Record<string, unknown> | undefined)",value:r.kwargs})].every(n=>n),a=(r,o,e=!0)=>[e===!1||Object.keys(r).map(n=>(r[n]===void 0,!0)).every(n=>n)].every(n=>n),l=r=>typeof r=="object"&&r!==null&&h(r);let i,u;return T(r=>{if(l(r)===!1){i=[],u=_(i),((e,n,c=!0)=>(typeof e=="object"&&e!==null||u(!0,{path:n+"",expected:"CallParams",value:e}))&&s(e,n+"",!0)||u(!0,{path:n+"",expected:"CallParams",value:e}))(r,"$input",!0);const o=i.length===0;return o?{success:o,data:r}:{success:o,errors:i,data:r}}return{success:!0,data:r}})})(),N=(()=>{const h=r=>typeof r.tablename=="string"&&1<=r.tablename.length&&(r.args===void 0||Array.isArray(r.args))&&(r.kwargs===void 0||typeof r.kwargs=="object"&&r.kwargs!==null&&Array.isArray(r.kwargs)===!1&&t(r.kwargs)),t=r=>Object.keys(r).every(o=>(r[o]===void 0,!0)),s=(r,o,e=!0)=>[typeof r.tablename=="string"&&(1<=r.tablename.length||u(e,{path:o+".tablename",expected:"string & MinLength<1>",value:r.tablename}))||u(e,{path:o+".tablename",expected:"(string & MinLength<1>)",value:r.tablename}),r.args===void 0||Array.isArray(r.args)||u(e,{path:o+".args",expected:"(Array<unknown> | undefined)",value:r.args}),r.kwargs===void 0||(typeof r.kwargs=="object"&&r.kwargs!==null&&Array.isArray(r.kwargs)===!1||u(e,{path:o+".kwargs",expected:"(Record<string, unknown> | undefined)",value:r.kwargs}))&&a(r.kwargs,o+".kwargs",e)||u(e,{path:o+".kwargs",expected:"(Record<string, unknown> | undefined)",value:r.kwargs})].every(n=>n),a=(r,o,e=!0)=>[e===!1||Object.keys(r).map(n=>(r[n]===void 0,!0)).every(n=>n)].every(n=>n),l=r=>typeof r=="object"&&r!==null&&h(r);let i,u;return T(r=>{if(l(r)===!1){i=[],u=_(i),((e,n,c=!0)=>(typeof e=="object"&&e!==null||u(!0,{path:n+"",expected:"TableParams",value:e}))&&s(e,n+"",!0)||u(!0,{path:n+"",expected:"TableParams",value:e}))(r,"$input",!0);const o=i.length===0;return o?{success:o,data:r}:{success:o,errors:i,data:r}}return{success:!0,data:r}})})(),K=(()=>{const h=r=>typeof r.tablename=="string"&&1<=r.tablename.length&&Array.isArray(r.rows)&&1<=r.rows.length&&r.rows.every(o=>typeof o=="object"&&o!==null&&Array.isArray(o)===!1&&t(o))&&(r.kwargs===void 0||typeof r.kwargs=="object"&&r.kwargs!==null&&Array.isArray(r.kwargs)===!1&&t(r.kwargs)),t=r=>Object.keys(r).every(o=>(r[o]===void 0,!0)),s=(r,o,e=!0)=>[typeof r.tablename=="string"&&(1<=r.tablename.length||u(e,{path:o+".tablename",expected:"string & MinLength<1>",value:r.tablename}))||u(e,{path:o+".tablename",expected:"(string & MinLength<1>)",value:r.tablename}),(Array.isArray(r.rows)||u(e,{path:o+".rows",expected:"(Array<Record<string, unknown>> & MinItems<1>)",value:r.rows}))&&(1<=r.rows.length||u(e,{path:o+".rows",expected:"Array<> & MinItems<1>",value:r.rows}))&&r.rows.map((n,c)=>(typeof n=="object"&&n!==null&&Array.isArray(n)===!1||u(e,{path:o+".rows["+c+"]",expected:"Record<string, unknown>",value:n}))&&a(n,o+".rows["+c+"]",e)||u(e,{path:o+".rows["+c+"]",expected:"Record<string, unknown>",value:n})).every(n=>n)||u(e,{path:o+".rows",expected:"(Array<Record<string, unknown>> & MinItems<1>)",value:r.rows}),r.kwargs===void 0||(typeof r.kwargs=="object"&&r.kwargs!==null&&Array.isArray(r.kwargs)===!1||u(e,{path:o+".kwargs",expected:"(Record<string, unknown> | undefined)",value:r.kwargs}))&&a(r.kwargs,o+".kwargs",e)||u(e,{path:o+".kwargs",expected:"(Record<string, unknown> | undefined)",value:r.kwargs})].every(n=>n),a=(r,o,e=!0)=>[e===!1||Object.keys(r).map(n=>(r[n]===void 0,!0)).every(n=>n)].every(n=>n),l=r=>typeof r=="object"&&r!==null&&h(r);let i,u;return T(r=>{if(l(r)===!1){i=[],u=_(i),((e,n,c=!0)=>(typeof e=="object"&&e!==null||u(!0,{path:n+"",expected:"BulkTableParams",value:e}))&&s(e,n+"",!0)||u(!0,{path:n+"",expected:"BulkTableParams",value:e}))(r,"$input",!0);const o=i.length===0;return o?{success:o,data:r}:{success:o,errors:i,data:r}}return{success:!0,data:r}})})(),ie={"sys.appaccess.error.no_grant":"NO_GRANT","sys.appaccess.error.provider_not_installed":"PROVIDER_NOT_INSTALLED","sys.appaccess.error.unknown_app":"UNKNOWN_APP","wamp.error.not_authorized":"NOT_AUTHORIZED","wamp.error.authorization_failed":"NOT_AUTHORIZED","wamp.error.authentication_failed":"NOT_AUTHORIZED"};class E extends Error{constructor(t,s){super(s??t),this.name="CrossAppAccessError",this.code=t}}function M(h){const t=h==null?void 0:h.error;if(typeof t!="string")return null;const s=ie[t];if(!s)return null;const a=h.args,l=Array.isArray(a)&&a.length>0?`: ${JSON.stringify(a[0])}`:"";return new E(s,`${t}${l}`)}class Y{constructor(t,s,a,l,i){this.app=t,this.stage=s,this.tables=a.tables??[],this.transforms=a.transforms??[],this._connection=l,this._onClosed=i}get connection(){return this._connection}get isConnected(){return this._connection.is_open}assertInCatalog(t){if(!t)throw new Error("Tablename must not be empty!");const s=[...this.tables,...this.transforms].map(a=>a.tablename);if(!s.includes(t))throw new E("PRIVATE_TABLE",`'${t}' is not shared by app '${this.app}' (${this.stage}). Available tables/transforms: ${s.length>0?s.join(", "):"none"}`)}async subscribeToTable(t,s,a){this.assertInCatalog(t);const l=await this._connection.subscribe(`transformed.${t}`,s),i=(u,r,o)=>{const e=Array.isArray(u)?u[0]:u,n=Array.isArray(e)?e:e==null?[]:[e];for(const c of n)s([c],r,o)};return await this._connection.subscribe(`transformed.bulk.${t}`,i),l}async getHistory(t,s={limit:10}){this.assertInCatalog(t),s.offset==null&&(s.offset=0);const a=P(s);if(!a.success)throw new Error(`Invalid query parameters: ${a.errors.map(l=>l.path+": "+l.expected).join(", ")}`);try{return await this._connection.call(`history.transformed.${t}`,[s])}catch(l){throw M(l)??l}}async getSeriesHistory(t,s){if(!t)throw new Error("Tablename must not be empty!");const a=this.tables.map(i=>i.tablename);if(!a.includes(t))throw this.transforms.some(i=>i.tablename===t)?new E("PRIVATE_TABLE",`'${t}' is a transform of app '${this.app}' (${this.stage}); series history is available for tables only — use getHistory() instead.`):new E("PRIVATE_TABLE",`'${t}' is not a shared table of app '${this.app}' (${this.stage}). Available tables: ${a.length>0?a.join(", "):"none"}`);const l=j(s);if(!l.success)throw new Error(`Invalid series query parameters: ${l.errors.map(i=>i.path+": "+i.expected).join(", ")}`);try{return await this._connection.call(`history.transformed.series.${t}`,[s])}catch(i){throw M(i)??i}}async close(){var t;this._connection.stop(),(t=this._onClosed)==null||t.call(this),this._onClosed=void 0}}const L="error-logs";function b(h){var t;return typeof process<"u"?(t=process.env)==null?void 0:t[h]:void 0}function ce(h){const t=h??b("DEVICE_SERIAL_NUMBER");if(!t)throw new Error("serialNumber option is required (or set DEVICE_SERIAL_NUMBER env var in Node.js)");return t}class x{constructor(t){this._isConfigured=!1,this._consumedApps=new Map,this._serialNumber=ce(t==null?void 0:t.serialNumber),this._deviceName=(t==null?void 0:t.deviceName)??b("DEVICE_NAME"),this._deviceKey=(t==null?void 0:t.deviceKey)??b("DEVICE_KEY"),this._appName=(t==null?void 0:t.appName)??b("APP_NAME"),this._swarmKey=(t==null?void 0:t.swarmKey)??parseInt(b("SWARM_KEY")??"0",10),this._appKey=(t==null?void 0:t.appKey)??parseInt(b("APP_KEY")??"0",10),this._env=(t==null?void 0:t.env)??b("ENV"),this._reswarmUrl=(t==null?void 0:t.reswarmUrl)??b("RESWARM_URL"),this._cburl=(t==null?void 0:t.ironFlockUrl)??(t==null?void 0:t.cburl),this._connection=new k;const s=[];this._deviceKey||s.push("DEVICE_KEY"),this._appName||s.push("APP_NAME"),this._swarmKey||s.push("SWARM_KEY"),this._appKey||s.push("APP_KEY"),s.length>0&&console.warn(`Warning: The following environment variables must be present: ${s.join(", ")}`)}get connection(){return this._connection}get isConnected(){return this._connection.is_open}configureConnection(t){if(this._isConfigured)return;const s=(this._env??"DEV").toUpperCase(),l={DEV:R.DEVELOPMENT,PROD:R.PRODUCTION}[s]??R.DEVELOPMENT,i=t??this._cburl??k.getWebSocketURI(this._reswarmUrl);this._connection.configure(this._swarmKey,this._appKey,l,this._serialNumber,i),this._isConfigured=!0}async start(t){this.configureConnection(t),await this._connection.start()}async stop(){const t=[...this._consumedApps.values()];this._consumedApps.clear(),await Promise.all(t.map(s=>s.then(a=>a.close()).catch(()=>{}))),this._connection.stop()}async connectToApp(t,s){if(!t)throw new Error("appName must not be empty!");const a=(this._env??"DEV").toUpperCase()==="PROD"?"prod":"dev",l=(s==null?void 0:s.stage)??a,i=`${t.toLowerCase()}:${l}`,u=this._consumedApps.get(i);if(u)return u;let r;const o=()=>{this._consumedApps.get(i)===r&&this._consumedApps.delete(i)};return r=this.openConsumedApp(t,l,o,s==null?void 0:s.onError),this._consumedApps.set(i,r),r.catch(o),r}async listConsumableApps(){try{return await this._connection.call("sys.appaccess.list",[])??[]}catch(t){throw M(t)??t}}async connectToAllApps(t){var e,n;const s=(this._env??"DEV").toUpperCase()==="PROD"?"prod":"dev",a=(t==null?void 0:t.stage)??s,l=(t==null?void 0:t.continueOnError)??!0,i=await this.listConsumableApps(),u=[];for(const c of i)(e=c.stages)!=null&&e[a]&&u.push(this.openCachedFromInfo(c,a,t==null?void 0:t.onError));const r=await Promise.allSettled(u),o=[];for(const c of r)if(c.status==="fulfilled")o.push(c.value);else if(l)(n=t==null?void 0:t.onError)==null||n.call(t,c.reason);else throw c.reason;return o}async openConsumedApp(t,s,a,l){let i;try{i=await this._connection.call("sys.appaccess.resolve",[{app:t}])}catch(u){throw M(u)??u}if(!i)throw new E("PROVIDER_NOT_INSTALLED",`App '${t}' has no ${s} data backend in this project`);return this.openFromInfo(i,s,a,l)}openCachedFromInfo(t,s,a){const l=`${t.app}:${s}`,i=this._consumedApps.get(l);if(i)return i;let u;const r=()=>{this._consumedApps.get(l)===u&&this._consumedApps.delete(l)};return u=this.openFromInfo(t,s,r,a),this._consumedApps.set(l,u),u.catch(r),u}async openFromInfo(t,s,a,l){var n;const i=t.app,u=(n=t.stages)==null?void 0:n[s];if(!u)throw new E("PROVIDER_NOT_INSTALLED",`App '${i}' has no ${s} data backend in this project`);const r=new k;r.failOnAuthError=!0,r.configure(this._swarmKey,t.provider_app_key,s==="prod"?R.PRODUCTION:R.DEVELOPMENT,this._serialNumber,this._connection.socketURI??this._cburl??k.getWebSocketURI(this._reswarmUrl));let o=!1,e;r.on("auth_failure",c=>{e=new E("NOT_AUTHORIZED",`Access to app '${i}' (${s}) denied: ${c}. The grant may have been revoked.`),a(),o&&(l==null||l(e))});try{await r.start()}catch(c){throw e??c}return o=!0,new Y(i,s,u,r,a)}async publish(t,s,a){const l=B({topic:t,args:s,kwargs:a});if(!l.success)throw new Error(`Invalid publish parameters: ${l.errors.map(r=>r.path+": "+r.expected).join(", ")}`);const u={...{DEVICE_SERIAL_NUMBER:this._serialNumber,DEVICE_KEY:this._deviceKey,DEVICE_NAME:this._deviceName},...a??{}};return this._connection.publish(t,s,u,{acknowledge:!0})}async publishToTable(t,s,a){const l=N({tablename:t,args:s,kwargs:a});if(!l.success)throw new Error(`Invalid table parameters: ${l.errors.map(u=>u.path+": "+u.expected).join(", ")}`);if(!this._swarmKey)throw new Error("SWARM_KEY not set in environment variables!");if(!this._appKey)throw new Error("APP_KEY not set in environment variables!");const i=`${this._swarmKey}.${this._appKey}.${t}`;return this.publish(i,s,a)}async reportError(t,s){const a=t instanceof Error?t.stack??t.message:t,l={tsp:(s==null?void 0:s.tsp)??new Date().toISOString(),msg:a,source:"app",level:(s==null?void 0:s.level)??"error"};return s!=null&&s.append?this.appendToTable(L,[l]):this.publishToTable(L,[l])}async appendToTable(t,s,a){const l=N({tablename:t,args:s,kwargs:a});if(!l.success)throw new Error(`Invalid table parameters: ${l.errors.map(o=>o.path+": "+o.expected).join(", ")}`);if(!this._swarmKey)throw new Error("SWARM_KEY not set in environment variables!");if(!this._appKey)throw new Error("APP_KEY not set in environment variables!");const i=`append.${this._swarmKey}.${this._appKey}.${t}`,r={...{DEVICE_SERIAL_NUMBER:this._serialNumber,DEVICE_KEY:this._deviceKey,DEVICE_NAME:this._deviceName},...a??{}};return this._connection.call(i,s,r)}async publishRowsToTable(t,s,a){const l=K({tablename:t,rows:s,kwargs:a});if(!l.success)throw new Error(`Invalid bulk table parameters: ${l.errors.map(u=>u.path+": "+u.expected).join(", ")}`);if(!this._swarmKey)throw new Error("SWARM_KEY not set in environment variables!");if(!this._appKey)throw new Error("APP_KEY not set in environment variables!");const i=`bulk.${this._swarmKey}.${this._appKey}.${t}`;return this.publish(i,[s],a)}async appendRowsToTable(t,s,a){const l=K({tablename:t,rows:s,kwargs:a});if(!l.success)throw new Error(`Invalid bulk table parameters: ${l.errors.map(o=>o.path+": "+o.expected).join(", ")}`);if(!this._swarmKey)throw new Error("SWARM_KEY not set in environment variables!");if(!this._appKey)throw new Error("APP_KEY not set in environment variables!");const i=`appendBulk.${this._swarmKey}.${this._appKey}.${t}`,r={...{DEVICE_SERIAL_NUMBER:this._serialNumber,DEVICE_KEY:this._deviceKey,DEVICE_NAME:this._deviceName},...a??{}};return this._connection.call(i,[s],r)}async subscribe(t,s,a){return this._connection.subscribe(t,s)}async subscribeToTable(t,s,a){if(!this._swarmKey)throw new Error("SWARM_KEY not set in environment variables!");if(!this._appKey)throw new Error("APP_KEY not set in environment variables!");const l=`transformed.${t}`,i=await this.subscribe(l,s,a),u=(r,o,e)=>{const n=Array.isArray(r)?r[0]:r,c=Array.isArray(n)?n:n==null?[]:[n];for(const d of c)s([d],o,e)};return await this.subscribe(`transformed.bulk.${t}`,u,a),i}async call(t,s,a,l){return this._connection.call(t,s,a,l)}async callDeviceFunction(t,s,a,l,i){const u=`${this._swarmKey}.${t}.${this._appKey}.${this._env}.${s}`;return this._connection.call(u,a,l,i)}async callFunction(t,s,a,l,i){return console.warn("callFunction() is deprecated and will be removed in a future version. Use callDeviceFunction() instead."),this.callDeviceFunction(t,s,a,l,i)}async registerDeviceFunction(t,s,a){const l=`${this._swarmKey}.${this._deviceKey}.${this._appKey}.${this._env}.${t}`,i=await this._connection.register(l,s,a);return console.log(`Function registered for IronFlock topic '${t}'. (Full WAMP topic: '${l}')`),i}async registerFunction(t,s,a){return console.warn("registerFunction() is deprecated and will be removed in a future version. Use registerDeviceFunction() instead."),this.registerDeviceFunction(t,s,a)}async register(t,s,a){return this.registerDeviceFunction(t,s,a)}async getHistory(t,s={limit:10}){if(!t)throw new Error("Tablename must not be empty!");s.offset==null&&(s.offset=0);const a=P(s);if(!a.success)throw new Error(`Invalid query parameters: ${a.errors.map(i=>i.path+": "+i.expected).join(", ")}`);const l=`history.transformed.${t}`;try{return await this._connection.call(l,[s])}catch(i){const u=String(i);return u.includes("no_such_procedure")||u.includes("no callee registered")?(console.error(`Get history failed: History service procedure '${l}' not registered`),null):(console.error(`Get history failed: ${i}`),null)}}async getSeriesHistory(t,s){if(!t)throw new Error("Tablename must not be empty!");const a=j(s);if(!a.success)throw new Error(`Invalid series query parameters: ${a.errors.map(i=>i.path+": "+i.expected).join(", ")}`);const l=`history.transformed.series.${t}`;try{return await this._connection.call(l,[s])}catch(i){const u=String(i);return u.includes("no_such_procedure")||u.includes("no callee registered")?(console.error(`Get series history failed: History service procedure '${l}' not registered`),null):(console.error(`Get series history failed: ${i}`),null)}}async setDeviceLocation(t,s){const a=W({longitude:t,latitude:s});if(!a.success)throw new Error(`Invalid location parameters: ${a.errors.map(u=>u.path+": "+u.expected).join(", ")}`);const l={long:t,lat:s},i={DEVICE_SERIAL_NUMBER:this._serialNumber,DEVICE_KEY:this._deviceKey,DEVICE_NAME:this._deviceName};try{return await this._connection.call("ironflock.location_service.update",[l],i)}catch(u){return console.error(`Set location failed: ${u}`),null}}getRemoteAccessUrlForPort(t){return this._deviceKey&&this._appName?`https://${this._deviceKey}-${this._appName.toLowerCase()}-${t}.app.ironflock.com`:null}static async fromServer(t){const s=await fetch(t);if(!s.ok)throw new Error(`Failed to fetch IronFlock config from ${t}: ${s.status} ${s.statusText}`);const a=await s.json();return new x(a)}}exports.ConsumedApp=Y;exports.CrossAppAccessError=E;exports.CrossbarConnection=k;exports.ERROR_LOGS_TABLE=L;exports.IronFlock=x;exports.Stage=R;exports.validateBulkTableParams=K;exports.validateCallParams=ae;exports.validateLocationParams=W;exports.validatePublishParams=B;exports.validateSeriesQueryParams=j;exports.validateTableParams=N;exports.validateTableQueryParams=P;
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const x=require("autobahn");function ee(y){return y&&y.__esModule&&Object.prototype.hasOwnProperty.call(y,"default")?y.default:y}var N={exports:{}},F;function re(){return F||(F=1,(function(y){var r=Object.prototype.hasOwnProperty,e="~";function n(){}Object.create&&(n.prototype=Object.create(null),new n().__proto__||(e=!1));function l(a,s,o){this.fn=a,this.context=s,this.once=o||!1}function i(a,s,o,f,d){if(typeof o!="function")throw new TypeError("The listener must be a function");var c=new l(o,f||a,d),h=e?e+s:s;return a._events[h]?a._events[h].fn?a._events[h]=[a._events[h],c]:a._events[h].push(c):(a._events[h]=c,a._eventsCount++),a}function u(a,s){--a._eventsCount===0?a._events=new n:delete a._events[s]}function t(){this._events=new n,this._eventsCount=0}t.prototype.eventNames=function(){var s=[],o,f;if(this._eventsCount===0)return s;for(f in o=this._events)r.call(o,f)&&s.push(e?f.slice(1):f);return Object.getOwnPropertySymbols?s.concat(Object.getOwnPropertySymbols(o)):s},t.prototype.listeners=function(s){var o=e?e+s:s,f=this._events[o];if(!f)return[];if(f.fn)return[f.fn];for(var d=0,c=f.length,h=new Array(c);d<c;d++)h[d]=f[d].fn;return h},t.prototype.listenerCount=function(s){var o=e?e+s:s,f=this._events[o];return f?f.fn?1:f.length:0},t.prototype.emit=function(s,o,f,d,c,h){var m=e?e+s:s;if(!this._events[m])return!1;var v=this._events[m],w=arguments.length,p,g;if(v.fn){switch(v.once&&this.removeListener(s,v.fn,void 0,!0),w){case 1:return v.fn.call(v.context),!0;case 2:return v.fn.call(v.context,o),!0;case 3:return v.fn.call(v.context,o,f),!0;case 4:return v.fn.call(v.context,o,f,d),!0;case 5:return v.fn.call(v.context,o,f,d,c),!0;case 6:return v.fn.call(v.context,o,f,d,c,h),!0}for(g=1,p=new Array(w-1);g<w;g++)p[g-1]=arguments[g];v.fn.apply(v.context,p)}else{var q=v.length,I;for(g=0;g<q;g++)switch(v[g].once&&this.removeListener(s,v[g].fn,void 0,!0),w){case 1:v[g].fn.call(v[g].context);break;case 2:v[g].fn.call(v[g].context,o);break;case 3:v[g].fn.call(v[g].context,o,f);break;case 4:v[g].fn.call(v[g].context,o,f,d);break;default:if(!p)for(I=1,p=new Array(w-1);I<w;I++)p[I-1]=arguments[I];v[g].fn.apply(v[g].context,p)}}return!0},t.prototype.on=function(s,o,f){return i(this,s,o,f,!1)},t.prototype.once=function(s,o,f){return i(this,s,o,f,!0)},t.prototype.removeListener=function(s,o,f,d){var c=e?e+s:s;if(!this._events[c])return this;if(!o)return u(this,c),this;var h=this._events[c];if(h.fn)h.fn===o&&(!d||h.once)&&(!f||h.context===f)&&u(this,c);else{for(var m=0,v=[],w=h.length;m<w;m++)(h[m].fn!==o||d&&!h[m].once||f&&h[m].context!==f)&&v.push(h[m]);v.length?this._events[c]=v.length===1?v[0]:v:u(this,c)}return this},t.prototype.removeAllListeners=function(s){var o;return s?(o=e?e+s:s,this._events[o]&&u(this,o)):(this._events=new n,this._eventsCount=0),this},t.prototype.off=t.prototype.removeListener,t.prototype.addListener=t.prototype.on,t.prefixed=e,t.EventEmitter=t,y.exports=t})(N)),N.exports}var te=re();const se=ee(te),ne="wss://cbw.datapods.io/ws-ua-usr",J="wss://cbw.ironflock.com/ws-ua-usr",oe="wss://cbw.ironflock.dev/ws-ua-usr",ae="wss://cbw.record-evolution.com/ws-ua-usr",V="ws://localhost:8080/ws-ua-usr",ie="ws://host.docker.internal:8080/ws-ua-usr",W={"https://studio.datapods.io":ne,"https://studio.ironflock.dev":oe,"https://studio.ironflock.com":J,"https://studio.record-evolution.com":ae,"http://localhost:8085":V,"http://localhost:8086":V,"http://host.docker.internal:8086":ie},B=6e3;class G extends Error{constructor(r,e,n=[],l={}){super(r),this.name="WampError",this.error=e,this.args=n,this.kwargs=l}}function Y(y){try{return JSON.stringify(y)??String(y)}catch{return String(y)}}function O(y,r,e){if(e instanceof Error)return e;const n=e==null?void 0:e.error;if(typeof n=="string"){const l=Array.isArray(e.args)?e.args:[],i=e.kwargs??{},u=l.length>0?` — ${Y(l)}`:"";return new G(`${y} '${r}' failed with WAMP error '${n}'${u}`,n,l,i)}return new Error(`${y} '${r}' failed: ${Y(e)}`)}const ce=["wamp.error.not_authorized","wamp.error.authorization_failed","wamp.error.authentication_failed","wamp.error.no_auth_method"];class k extends se{constructor(){super(),this.failOnAuthError=!1,this.subscriptions=[],this.registrations=[],this.firstResolver=()=>{},this.firstRejecter=()=>{},this.shouldReconnect=!1,this.isReconnecting=!1,this.hasOpenedOnce=!1}static getWebSocketURI(r){var l;const e=typeof process<"u"?(l=process.env)==null?void 0:l.DEVICE_ENDPOINT_URL:void 0;if(e)try{const i=new URL(e);return i.pathname="/ws-ua-usr",i.toString().replace(/\/$/,"")}catch{}if(!r)return J;const n=W[r];if(n===void 0)throw new Error(`Cannot resolve WebSocket URI for reswarmUrl=${JSON.stringify(r)}. Set DEVICE_ENDPOINT_URL to the deployment's WAMP router URL (e.g. ws://<host>:18080/ws-re-dev) or pass ironFlockUrl=… to IronFlock(). Known cloud URLs: ${JSON.stringify(Object.keys(W))}`);return n}configure(r,e,n,l,i){this.realm=`realm-${r}-${e}-${n}`,this.serial_number=l,this.socketURI=i??k.getWebSocketURI()}async start(){if(!this.realm||!this.serial_number||!this.socketURI)throw new Error("CrossbarConnection must be configured before starting. Call configure() first.");return this.shouldReconnect=!0,this.firstConnection=new Promise((r,e)=>{this.firstResolver=r,this.firstRejecter=e}),this.connection=new x.Connection({realm:this.realm,url:this.socketURI,authmethods:["wampcra"],authid:this.serial_number,max_retries:-1,max_retry_delay:2,initial_retry_delay:1,autoping_interval:2,autoping_timeout:4,onchallenge:(r,e,n)=>x.auth_cra.sign(this.serial_number,n.challenge)}),this.connection.onopen=this.onOpen.bind(this),this.connection.onclose=this.onClose.bind(this),this.connection.open(),this.firstConnection}onOpen(r){this.session=r,this.session.caller_disclose_me=!0,this.hasOpenedOnce=!0,this.resubscribeAll().catch(e=>console.error("Failed to restore subscriptions after (re)connect:",e)),this.reregisterAll().catch(e=>console.error("Failed to restore registrations after (re)connect:",e)),this.emit("connected",this.serial_number),this.firstResolver(),this.firstResolver=()=>{}}onClose(r,e){this.session=void 0,this.emit("disconnected"),console.warn("Connection closed:",{reason:r,details:e,realm:this.realm,url:this.socketURI,authid:this.serial_number});const n=(e==null?void 0:e.reason)??r;return this.failOnAuthError&&typeof n=="string"&&ce.includes(n)?(this.shouldReconnect=!1,this.firstRejecter(new Error(`Connection failed (auth denied): ${n}`)),this.firstRejecter=()=>{},this.emit("auth_failure",n,e),!0):this.failOnAuthError&&!this.hasOpenedOnce?(this.firstRejecter(new Error(`Connection failed: ${r} - ${JSON.stringify(e,null,2)}`)),this.firstRejecter=()=>{},!1):(this.shouldReconnect&&(e==null?void 0:e.will_retry)===!1&&this.handleManualReconnect(n),!1)}async handleManualReconnect(r){if(!(this.isReconnecting||!this.shouldReconnect)){for(this.isReconnecting=!0;this.shouldReconnect&&!this.session;)if(await new Promise(e=>setTimeout(e,1e3)),this.shouldReconnect&&this.connection&&!this.session){console.log(`Manually retrying connection after ${r}...`);try{this.connection.open(),await new Promise(e=>setTimeout(e,500))}catch(e){console.error("Error during manual reconnection attempt:",e)}}this.isReconnecting=!1}}async sessionWait(r){const e=Date.now();for(;!this.session;){if(Date.now()-e>B)throw new Error(`Cannot ${r}: not connected to the IronFlock router (no session after ${B/1e3}s, realm '${this.realm??"unconfigured"}'). Ensure start() was called and the connection is established.`);await new Promise(n=>setTimeout(n,200))}return this.session}async waitForConnection(){return this.firstConnection}getSession(){return this.session}get is_open(){var r;return!!((r=this.session)!=null&&r.isOpen)}isConnected(){return this.is_open}stop(){var r;this.shouldReconnect=!1,this.firstRejecter(new Error("Connection stopped before it opened")),this.firstRejecter=()=>{},(r=this.connection)==null||r.close("wamp.close.normal","Connection closed by client")}async subscribe(r,e){const n=await this.sessionWait(`subscribe to topic '${r}'`);let l;try{l=await n.subscribe(r,e)}catch(i){throw O("Subscribe to topic",r,i)}return l&&this.subscriptions.push(l),l}async unsubscribe(r){var n;await this.sessionWait(`unsubscribe from topic '${r.topic}'`);const e=this.subscriptions.indexOf(r);e!==-1&&(this.subscriptions.splice(e,1),await((n=this.session)==null?void 0:n.unsubscribe(r)))}async unsubscribeTopic(r){const e=this.subscriptions.filter(n=>n.topic===r);for(const n of e)await this.unsubscribe(n)}async resubscribeAll(){const r=[...this.subscriptions];this.subscriptions=[],await Promise.all(r.map(e=>this.subscribe(e.topic,e.handler)))}async reregisterAll(){const r=[...this.registrations];this.registrations=[],await Promise.all(r.map(e=>this.register(e.procedure,e.endpoint,e.options)))}async register(r,e,n){const l=await this.sessionWait(`register procedure '${r}'`),i={force_reregister:!0,...n??{}};let u;try{u=await l.register(r,e,i)}catch(t){throw O("Register of procedure",r,t)}return u&&this.registrations.push(u),u}async unregister(r){var n;await this.sessionWait(`unregister procedure '${r.procedure}'`),await((n=this.session)==null?void 0:n.unregister(r));const e=this.registrations.indexOf(r);e!==-1&&this.registrations.splice(e,1)}async call(r,e,n,l){const i=await this.sessionWait(`call procedure '${r}'`);try{return await i.call(r,e,n,l)}catch(u){throw O("Call of procedure",r,u)}}async publish(r,e,n,l){const i=await this.sessionWait(`publish to topic '${r}'`);try{return await i.publish(r,e,n,l)}catch(u){throw O("Publish to topic",r,u)}}}const T=y=>Math.floor(y)===y&&le<=y&&y<=ue,le=0,ue=2**32-1,M=y=>de.test(y),de=/^[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])(T|\s)([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9](?:\.[0-9]{1,9})?(Z|[+-]([01][0-9]|2[0-3]):[0-5][0-9])$/i,_=y=>{const r=e=>{if(y.length===0)return!0;const n=y[y.length-1].path;return e.length>n.length||n.substring(0,e.length)!==e};return(e,n)=>(e&&r(n.path)&&(n.value===void 0&&(n.description??(n.description=["The value at this path is `undefined`.","",`Please fill the \`${n.expected}\` typed value next time.`].join(`
|
|
2
|
+
`))),y.push(n)),!1)},$=y=>Object.assign(y,{"~standard":{version:1,vendor:"typia",validate:r=>{const e=y(r);return e.success?{value:e.data}:{issues:e.errors.map(n=>({message:`expected ${n.expected}, got ${n.value}`,path:fe(n.path)}))}}}});var A;(function(y){y[y.Start=0]="Start",y[y.Property=1]="Property",y[y.StringKey=2]="StringKey",y[y.NumberKey=3]="NumberKey"})(A||(A={}));const fe=y=>{if(!y.startsWith("$input"))throw new Error(`Invalid path: ${JSON.stringify(y)}`);const r=[];let e="",n=A.Start,l=5;for(;l<y.length-1;){l++;const i=y[l];if(n===A.Property?i==="."||i==="["?(r.push({key:e}),n=A.Start):l===y.length-1?(e+=i,r.push({key:e}),l++,n=A.Start):e+=i:n===A.StringKey?i==='"'?(r.push({key:JSON.parse(e+i)}),l+=2,n=A.Start):i==="\\"?(e+=y[l],l++,e+=y[l]):e+=i:n===A.NumberKey&&(i==="]"?(r.push({key:Number.parseInt(e)}),l++,n=A.Start):e+=i),n===A.Start&&l<y.length-1){const u=y[l];if(e="",u==="[")y[l+1]==='"'?(n=A.StringKey,l++,e='"'):n=A.NumberKey;else if(u===".")n=A.Property;else throw new Error("Unreachable: pointer points invalid character")}}if(n!==A.Start)throw new Error(`Failed to parse path: ${JSON.stringify(y)}`);return r};var R=(y=>(y.DEVELOPMENT="dev",y.PRODUCTION="prod",y))(R||{});function P(y){const r=(y==null?void 0:y.filterAnd)??[];for(const e of r)if(e&&(e.latest===!0||e.column==="latest_flag"))throw new Error("The 'latest' marker (and the legacy latest_flag filter) is not supported in series queries — use getHistory() with filterAnd: [{ latest: true }] to read current values.")}const D=(()=>{const y=c=>typeof c.limit=="number"&&T(c.limit)&&1<=c.limit&&c.limit<=1e4&&(c.offset===void 0||typeof c.offset=="number"&&T(c.offset)&&0<=c.offset)&&(c.timeRange===void 0||typeof c.timeRange=="object"&&c.timeRange!==null&&r(c.timeRange))&&(c.filterAnd===void 0||Array.isArray(c.filterAnd)&&c.filterAnd.every(h=>typeof h=="object"&&h!==null&&l(h)))&&(c.columns===void 0||Array.isArray(c.columns)&&c.columns.every(h=>typeof h=="string")),r=c=>typeof c.start=="string"&&M(c.start)&&typeof c.end=="string"&&M(c.end),e=c=>typeof c.column=="string"&&1<=c.column.length&&typeof c.operator=="string"&&1<=c.operator.length&&c.value!==null&&c.value!==void 0&&(typeof c.value=="string"||typeof c.value=="number"||typeof c.value=="boolean"||Array.isArray(c.value)&&c.value.every(h=>typeof h=="string"||typeof h=="number")),n=c=>c.latest===!0,l=c=>c.column!==void 0?e(c):c.latest!==void 0?n(c):!1,i=(c,h,m=!0)=>[typeof c.limit=="number"&&(T(c.limit)||d(m,{path:h+".limit",expected:'number & Type<"uint32">',value:c.limit}))&&(1<=c.limit||d(m,{path:h+".limit",expected:"number & Minimum<1>",value:c.limit}))&&(c.limit<=1e4||d(m,{path:h+".limit",expected:"number & Maximum<10000>",value:c.limit}))||d(m,{path:h+".limit",expected:'(number & Type<"uint32"> & Minimum<1> & Maximum<10000>)',value:c.limit}),c.offset===void 0||typeof c.offset=="number"&&(T(c.offset)||d(m,{path:h+".offset",expected:'number & Type<"uint32">',value:c.offset}))&&(0<=c.offset||d(m,{path:h+".offset",expected:"number & Minimum<0>",value:c.offset}))||d(m,{path:h+".offset",expected:'((number & Type<"uint32"> & Minimum<0>) | undefined)',value:c.offset}),c.timeRange===void 0||(typeof c.timeRange=="object"&&c.timeRange!==null||d(m,{path:h+".timeRange",expected:"(ISOTimeRange | undefined)",value:c.timeRange}))&&u(c.timeRange,h+".timeRange",m)||d(m,{path:h+".timeRange",expected:"(ISOTimeRange | undefined)",value:c.timeRange}),c.filterAnd===void 0||(Array.isArray(c.filterAnd)||d(m,{path:h+".filterAnd",expected:"(Array<TableFilter> | undefined)",value:c.filterAnd}))&&c.filterAnd.map((v,w)=>(typeof v=="object"&&v!==null||d(m,{path:h+".filterAnd["+w+"]",expected:"(LatestMarker | SQLFilterAnd)",value:v}))&&s(v,h+".filterAnd["+w+"]",m)||d(m,{path:h+".filterAnd["+w+"]",expected:"(LatestMarker | SQLFilterAnd)",value:v})).every(v=>v)||d(m,{path:h+".filterAnd",expected:"(Array<TableFilter> | undefined)",value:c.filterAnd}),c.columns===void 0||(Array.isArray(c.columns)||d(m,{path:h+".columns",expected:"(Array<string> | undefined)",value:c.columns}))&&c.columns.map((v,w)=>typeof v=="string"||d(m,{path:h+".columns["+w+"]",expected:"string",value:v})).every(v=>v)||d(m,{path:h+".columns",expected:"(Array<string> | undefined)",value:c.columns})].every(v=>v),u=(c,h,m=!0)=>[typeof c.start=="string"&&(M(c.start)||d(m,{path:h+".start",expected:'string & Format<"date-time">',value:c.start}))||d(m,{path:h+".start",expected:'(string & Format<"date-time">)',value:c.start}),typeof c.end=="string"&&(M(c.end)||d(m,{path:h+".end",expected:'string & Format<"date-time">',value:c.end}))||d(m,{path:h+".end",expected:'(string & Format<"date-time">)',value:c.end})].every(v=>v),t=(c,h,m=!0)=>[typeof c.column=="string"&&(1<=c.column.length||d(m,{path:h+".column",expected:"string & MinLength<1>",value:c.column}))||d(m,{path:h+".column",expected:"(string & MinLength<1>)",value:c.column}),typeof c.operator=="string"&&(1<=c.operator.length||d(m,{path:h+".operator",expected:"string & MinLength<1>",value:c.operator}))||d(m,{path:h+".operator",expected:"(string & MinLength<1>)",value:c.operator}),(c.value!==null||d(m,{path:h+".value",expected:"(Array<string | number> | boolean | number | string)",value:c.value}))&&(c.value!==void 0||d(m,{path:h+".value",expected:"(Array<string | number> | boolean | number | string)",value:c.value}))&&(typeof c.value=="string"||typeof c.value=="number"||typeof c.value=="boolean"||(Array.isArray(c.value)||d(m,{path:h+".value",expected:"(Array<string | number> | boolean | number | string)",value:c.value}))&&c.value.map((v,w)=>typeof v=="string"||typeof v=="number"||d(m,{path:h+".value["+w+"]",expected:"(number | string)",value:v})).every(v=>v)||d(m,{path:h+".value",expected:"(Array<string | number> | boolean | number | string)",value:c.value}))].every(v=>v),a=(c,h,m=!0)=>[c.latest===!0||d(m,{path:h+".latest",expected:"true",value:c.latest})].every(v=>v),s=(c,h,m=!0)=>c.column!==void 0?t(c,h,m):c.latest!==void 0?a(c,h,m):d(m,{path:h,expected:"(SQLFilterAnd | LatestMarker)",value:c}),o=c=>typeof c=="object"&&c!==null&&y(c);let f,d;return $(c=>{if(o(c)===!1){f=[],d=_(f),((m,v,w=!0)=>(typeof m=="object"&&m!==null||d(!0,{path:v+"",expected:"TableQueryParams",value:m}))&&i(m,v+"",!0)||d(!0,{path:v+"",expected:"TableQueryParams",value:m}))(c,"$input",!0);const h=f.length===0;return h?{success:h,data:c}:{success:h,errors:f,data:c}}return{success:!0,data:c}})})(),j=(()=>{const y=s=>{const o=s,f=[[d=>d.length===2&&(d[0]===null||typeof d[0]=="number")&&(d[1]===null||typeof d[1]=="number"),d=>d.length===2&&(d[0]===null||typeof d[0]=="number")&&(d[1]===null||typeof d[1]=="number")],[d=>d.length===2&&(d[0]===null||typeof d[0]=="string")&&(d[1]===null||typeof d[1]=="string"),d=>d.length===2&&(d[0]===null||typeof d[0]=="string")&&(d[1]===null||typeof d[1]=="string")]];for(const d of f)if(d[0](o))return d[1](o);return!1},r=(s,o,f=!0)=>{const d=s,c=[[h=>h.length===2&&[h[0]===null||typeof h[0]=="number",h[1]===null||typeof h[1]=="number"].every(m=>m),h=>(h.length===2||a(f,{path:o,expected:"[(null | number), (null | number)]",value:h}))&&[h[0]===null||typeof h[0]=="number"||a(f,{path:o+"[0]",expected:"(null | number)",value:h[0]}),h[1]===null||typeof h[1]=="number"||a(f,{path:o+"[1]",expected:"(null | number)",value:h[1]})].every(m=>m)],[h=>h.length===2&&[h[0]===null||typeof h[0]=="string",h[1]===null||typeof h[1]=="string"].every(m=>m),h=>(h.length===2||a(f,{path:o,expected:"[(null | string), (null | string)]",value:h}))&&[h[0]===null||typeof h[0]=="string"||a(f,{path:o+"[0]",expected:"(null | string)",value:h[0]}),h[1]===null||typeof h[1]=="string"||a(f,{path:o+"[1]",expected:"(null | string)",value:h[1]})].every(m=>m)]];for(const h of c)if(h[0](d))return h[1](d);return a(f,{path:o,expected:"([number | null, number | null] | [string | null, string | null])",value:s})},e=s=>Array.isArray(s.metrics)&&s.metrics.every(o=>typeof o=="string")&&(s.method==="AVG"||s.method==="SUM"||s.method==="COUNT"||s.method==="MIN"||s.method==="MAX"||s.method==="FIRST"||s.method==="LAST")&&typeof s.limit=="number"&&T(s.limit)&&1<=s.limit&&s.limit<=1e4&&Array.isArray(s.timeRange)&&(y(s.timeRange)||!1)&&(s.groupBy===null||s.groupBy===void 0||Array.isArray(s.groupBy)&&s.groupBy.every(o=>typeof o=="string"))&&(s.filterAnd===null||s.filterAnd===void 0||Array.isArray(s.filterAnd)&&s.filterAnd.every(o=>typeof o=="object"&&o!==null&&n(o))),n=s=>typeof s.column=="string"&&1<=s.column.length&&typeof s.operator=="string"&&1<=s.operator.length&&s.value!==null&&s.value!==void 0&&(typeof s.value=="string"||typeof s.value=="number"||typeof s.value=="boolean"||Array.isArray(s.value)&&s.value.every(o=>typeof o=="string"||typeof o=="number")),l=(s,o,f=!0)=>[(Array.isArray(s.metrics)||a(f,{path:o+".metrics",expected:"Array<string>",value:s.metrics}))&&s.metrics.map((d,c)=>typeof d=="string"||a(f,{path:o+".metrics["+c+"]",expected:"string",value:d})).every(d=>d)||a(f,{path:o+".metrics",expected:"Array<string>",value:s.metrics}),s.method==="AVG"||s.method==="SUM"||s.method==="COUNT"||s.method==="MIN"||s.method==="MAX"||s.method==="FIRST"||s.method==="LAST"||a(f,{path:o+".method",expected:'("AVG" | "COUNT" | "FIRST" | "LAST" | "MAX" | "MIN" | "SUM")',value:s.method}),typeof s.limit=="number"&&(T(s.limit)||a(f,{path:o+".limit",expected:'number & Type<"uint32">',value:s.limit}))&&(1<=s.limit||a(f,{path:o+".limit",expected:"number & Minimum<1>",value:s.limit}))&&(s.limit<=1e4||a(f,{path:o+".limit",expected:"number & Maximum<10000>",value:s.limit}))||a(f,{path:o+".limit",expected:'(number & Type<"uint32"> & Minimum<1> & Maximum<10000>)',value:s.limit}),(Array.isArray(s.timeRange)||a(f,{path:o+".timeRange",expected:"([number | null, number | null] | [string | null, string | null])",value:s.timeRange}))&&(r(s.timeRange,o+".timeRange",f)||a(f,{path:o+".timeRange",expected:"[number | null, number | null] | [string | null, string | null]",value:s.timeRange}))||a(f,{path:o+".timeRange",expected:"([number | null, number | null] | [string | null, string | null])",value:s.timeRange}),s.groupBy===null||s.groupBy===void 0||(Array.isArray(s.groupBy)||a(f,{path:o+".groupBy",expected:"(Array<string> | null | undefined)",value:s.groupBy}))&&s.groupBy.map((d,c)=>typeof d=="string"||a(f,{path:o+".groupBy["+c+"]",expected:"string",value:d})).every(d=>d)||a(f,{path:o+".groupBy",expected:"(Array<string> | null | undefined)",value:s.groupBy}),s.filterAnd===null||s.filterAnd===void 0||(Array.isArray(s.filterAnd)||a(f,{path:o+".filterAnd",expected:"(Array<SQLFilterAnd> | null | undefined)",value:s.filterAnd}))&&s.filterAnd.map((d,c)=>(typeof d=="object"&&d!==null||a(f,{path:o+".filterAnd["+c+"]",expected:"SQLFilterAnd",value:d}))&&i(d,o+".filterAnd["+c+"]",f)||a(f,{path:o+".filterAnd["+c+"]",expected:"SQLFilterAnd",value:d})).every(d=>d)||a(f,{path:o+".filterAnd",expected:"(Array<SQLFilterAnd> | null | undefined)",value:s.filterAnd})].every(d=>d),i=(s,o,f=!0)=>[typeof s.column=="string"&&(1<=s.column.length||a(f,{path:o+".column",expected:"string & MinLength<1>",value:s.column}))||a(f,{path:o+".column",expected:"(string & MinLength<1>)",value:s.column}),typeof s.operator=="string"&&(1<=s.operator.length||a(f,{path:o+".operator",expected:"string & MinLength<1>",value:s.operator}))||a(f,{path:o+".operator",expected:"(string & MinLength<1>)",value:s.operator}),(s.value!==null||a(f,{path:o+".value",expected:"(Array<string | number> | boolean | number | string)",value:s.value}))&&(s.value!==void 0||a(f,{path:o+".value",expected:"(Array<string | number> | boolean | number | string)",value:s.value}))&&(typeof s.value=="string"||typeof s.value=="number"||typeof s.value=="boolean"||(Array.isArray(s.value)||a(f,{path:o+".value",expected:"(Array<string | number> | boolean | number | string)",value:s.value}))&&s.value.map((d,c)=>typeof d=="string"||typeof d=="number"||a(f,{path:o+".value["+c+"]",expected:"(number | string)",value:d})).every(d=>d)||a(f,{path:o+".value",expected:"(Array<string | number> | boolean | number | string)",value:s.value}))].every(d=>d),u=s=>typeof s=="object"&&s!==null&&e(s);let t,a;return $(s=>{if(u(s)===!1){t=[],a=_(t),((f,d,c=!0)=>(typeof f=="object"&&f!==null||a(!0,{path:d+"",expected:"SeriesQueryParams",value:f}))&&l(f,d+"",!0)||a(!0,{path:d+"",expected:"SeriesQueryParams",value:f}))(s,"$input",!0);const o=t.length===0;return o?{success:o,data:s}:{success:o,errors:t,data:s}}return{success:!0,data:s}})})(),Z=(()=>{const y=i=>typeof i.longitude=="number"&&-180<=i.longitude&&i.longitude<=180&&typeof i.latitude=="number"&&-90<=i.latitude&&i.latitude<=90,r=(i,u,t=!0)=>[typeof i.longitude=="number"&&(-180<=i.longitude||l(t,{path:u+".longitude",expected:"number & Minimum<-180>",value:i.longitude}))&&(i.longitude<=180||l(t,{path:u+".longitude",expected:"number & Maximum<180>",value:i.longitude}))||l(t,{path:u+".longitude",expected:"(number & Minimum<-180> & Maximum<180>)",value:i.longitude}),typeof i.latitude=="number"&&(-90<=i.latitude||l(t,{path:u+".latitude",expected:"number & Minimum<-90>",value:i.latitude}))&&(i.latitude<=90||l(t,{path:u+".latitude",expected:"number & Maximum<90>",value:i.latitude}))||l(t,{path:u+".latitude",expected:"(number & Minimum<-90> & Maximum<90>)",value:i.latitude})].every(a=>a),e=i=>typeof i=="object"&&i!==null&&y(i);let n,l;return $(i=>{if(e(i)===!1){n=[],l=_(n),((t,a,s=!0)=>(typeof t=="object"&&t!==null||l(!0,{path:a+"",expected:"LocationParams",value:t}))&&r(t,a+"",!0)||l(!0,{path:a+"",expected:"LocationParams",value:t}))(i,"$input",!0);const u=n.length===0;return u?{success:u,data:i}:{success:u,errors:n,data:i}}return{success:!0,data:i}})})(),z=(()=>{const y=t=>typeof t.topic=="string"&&1<=t.topic.length&&(t.args===void 0||Array.isArray(t.args))&&(t.kwargs===void 0||typeof t.kwargs=="object"&&t.kwargs!==null&&Array.isArray(t.kwargs)===!1&&r(t.kwargs)),r=t=>Object.keys(t).every(a=>(t[a]===void 0,!0)),e=(t,a,s=!0)=>[typeof t.topic=="string"&&(1<=t.topic.length||u(s,{path:a+".topic",expected:"string & MinLength<1>",value:t.topic}))||u(s,{path:a+".topic",expected:"(string & MinLength<1>)",value:t.topic}),t.args===void 0||Array.isArray(t.args)||u(s,{path:a+".args",expected:"(Array<unknown> | undefined)",value:t.args}),t.kwargs===void 0||(typeof t.kwargs=="object"&&t.kwargs!==null&&Array.isArray(t.kwargs)===!1||u(s,{path:a+".kwargs",expected:"(Record<string, unknown> | undefined)",value:t.kwargs}))&&n(t.kwargs,a+".kwargs",s)||u(s,{path:a+".kwargs",expected:"(Record<string, unknown> | undefined)",value:t.kwargs})].every(o=>o),n=(t,a,s=!0)=>[s===!1||Object.keys(t).map(o=>(t[o]===void 0,!0)).every(o=>o)].every(o=>o),l=t=>typeof t=="object"&&t!==null&&y(t);let i,u;return $(t=>{if(l(t)===!1){i=[],u=_(i),((s,o,f=!0)=>(typeof s=="object"&&s!==null||u(!0,{path:o+"",expected:"PublishParams",value:s}))&&e(s,o+"",!0)||u(!0,{path:o+"",expected:"PublishParams",value:s}))(t,"$input",!0);const a=i.length===0;return a?{success:a,data:t}:{success:a,errors:i,data:t}}return{success:!0,data:t}})})(),he=(()=>{const y=t=>typeof t.deviceKey=="string"&&1<=t.deviceKey.length&&typeof t.topic=="string"&&1<=t.topic.length&&(t.args===void 0||Array.isArray(t.args))&&(t.kwargs===void 0||typeof t.kwargs=="object"&&t.kwargs!==null&&Array.isArray(t.kwargs)===!1&&r(t.kwargs)),r=t=>Object.keys(t).every(a=>(t[a]===void 0,!0)),e=(t,a,s=!0)=>[typeof t.deviceKey=="string"&&(1<=t.deviceKey.length||u(s,{path:a+".deviceKey",expected:"string & MinLength<1>",value:t.deviceKey}))||u(s,{path:a+".deviceKey",expected:"(string & MinLength<1>)",value:t.deviceKey}),typeof t.topic=="string"&&(1<=t.topic.length||u(s,{path:a+".topic",expected:"string & MinLength<1>",value:t.topic}))||u(s,{path:a+".topic",expected:"(string & MinLength<1>)",value:t.topic}),t.args===void 0||Array.isArray(t.args)||u(s,{path:a+".args",expected:"(Array<unknown> | undefined)",value:t.args}),t.kwargs===void 0||(typeof t.kwargs=="object"&&t.kwargs!==null&&Array.isArray(t.kwargs)===!1||u(s,{path:a+".kwargs",expected:"(Record<string, unknown> | undefined)",value:t.kwargs}))&&n(t.kwargs,a+".kwargs",s)||u(s,{path:a+".kwargs",expected:"(Record<string, unknown> | undefined)",value:t.kwargs})].every(o=>o),n=(t,a,s=!0)=>[s===!1||Object.keys(t).map(o=>(t[o]===void 0,!0)).every(o=>o)].every(o=>o),l=t=>typeof t=="object"&&t!==null&&y(t);let i,u;return $(t=>{if(l(t)===!1){i=[],u=_(i),((s,o,f=!0)=>(typeof s=="object"&&s!==null||u(!0,{path:o+"",expected:"CallParams",value:s}))&&e(s,o+"",!0)||u(!0,{path:o+"",expected:"CallParams",value:s}))(t,"$input",!0);const a=i.length===0;return a?{success:a,data:t}:{success:a,errors:i,data:t}}return{success:!0,data:t}})})(),C=(()=>{const y=t=>typeof t.tablename=="string"&&1<=t.tablename.length&&(t.args===void 0||Array.isArray(t.args))&&(t.kwargs===void 0||typeof t.kwargs=="object"&&t.kwargs!==null&&Array.isArray(t.kwargs)===!1&&r(t.kwargs)),r=t=>Object.keys(t).every(a=>(t[a]===void 0,!0)),e=(t,a,s=!0)=>[typeof t.tablename=="string"&&(1<=t.tablename.length||u(s,{path:a+".tablename",expected:"string & MinLength<1>",value:t.tablename}))||u(s,{path:a+".tablename",expected:"(string & MinLength<1>)",value:t.tablename}),t.args===void 0||Array.isArray(t.args)||u(s,{path:a+".args",expected:"(Array<unknown> | undefined)",value:t.args}),t.kwargs===void 0||(typeof t.kwargs=="object"&&t.kwargs!==null&&Array.isArray(t.kwargs)===!1||u(s,{path:a+".kwargs",expected:"(Record<string, unknown> | undefined)",value:t.kwargs}))&&n(t.kwargs,a+".kwargs",s)||u(s,{path:a+".kwargs",expected:"(Record<string, unknown> | undefined)",value:t.kwargs})].every(o=>o),n=(t,a,s=!0)=>[s===!1||Object.keys(t).map(o=>(t[o]===void 0,!0)).every(o=>o)].every(o=>o),l=t=>typeof t=="object"&&t!==null&&y(t);let i,u;return $(t=>{if(l(t)===!1){i=[],u=_(i),((s,o,f=!0)=>(typeof s=="object"&&s!==null||u(!0,{path:o+"",expected:"TableParams",value:s}))&&e(s,o+"",!0)||u(!0,{path:o+"",expected:"TableParams",value:s}))(t,"$input",!0);const a=i.length===0;return a?{success:a,data:t}:{success:a,errors:i,data:t}}return{success:!0,data:t}})})(),L=(()=>{const y=t=>typeof t.tablename=="string"&&1<=t.tablename.length&&Array.isArray(t.rows)&&1<=t.rows.length&&t.rows.every(a=>typeof a=="object"&&a!==null&&Array.isArray(a)===!1&&r(a))&&(t.kwargs===void 0||typeof t.kwargs=="object"&&t.kwargs!==null&&Array.isArray(t.kwargs)===!1&&r(t.kwargs)),r=t=>Object.keys(t).every(a=>(t[a]===void 0,!0)),e=(t,a,s=!0)=>[typeof t.tablename=="string"&&(1<=t.tablename.length||u(s,{path:a+".tablename",expected:"string & MinLength<1>",value:t.tablename}))||u(s,{path:a+".tablename",expected:"(string & MinLength<1>)",value:t.tablename}),(Array.isArray(t.rows)||u(s,{path:a+".rows",expected:"(Array<Record<string, unknown>> & MinItems<1>)",value:t.rows}))&&(1<=t.rows.length||u(s,{path:a+".rows",expected:"Array<> & MinItems<1>",value:t.rows}))&&t.rows.map((o,f)=>(typeof o=="object"&&o!==null&&Array.isArray(o)===!1||u(s,{path:a+".rows["+f+"]",expected:"Record<string, unknown>",value:o}))&&n(o,a+".rows["+f+"]",s)||u(s,{path:a+".rows["+f+"]",expected:"Record<string, unknown>",value:o})).every(o=>o)||u(s,{path:a+".rows",expected:"(Array<Record<string, unknown>> & MinItems<1>)",value:t.rows}),t.kwargs===void 0||(typeof t.kwargs=="object"&&t.kwargs!==null&&Array.isArray(t.kwargs)===!1||u(s,{path:a+".kwargs",expected:"(Record<string, unknown> | undefined)",value:t.kwargs}))&&n(t.kwargs,a+".kwargs",s)||u(s,{path:a+".kwargs",expected:"(Record<string, unknown> | undefined)",value:t.kwargs})].every(o=>o),n=(t,a,s=!0)=>[s===!1||Object.keys(t).map(o=>(t[o]===void 0,!0)).every(o=>o)].every(o=>o),l=t=>typeof t=="object"&&t!==null&&y(t);let i,u;return $(t=>{if(l(t)===!1){i=[],u=_(i),((s,o,f=!0)=>(typeof s=="object"&&s!==null||u(!0,{path:o+"",expected:"BulkTableParams",value:s}))&&e(s,o+"",!0)||u(!0,{path:o+"",expected:"BulkTableParams",value:s}))(t,"$input",!0);const a=i.length===0;return a?{success:a,data:t}:{success:a,errors:i,data:t}}return{success:!0,data:t}})})(),ye={"sys.appaccess.error.no_grant":"NO_GRANT","sys.appaccess.error.provider_not_installed":"PROVIDER_NOT_INSTALLED","sys.appaccess.error.unknown_app":"UNKNOWN_APP","wamp.error.not_authorized":"NOT_AUTHORIZED","wamp.error.authorization_failed":"NOT_AUTHORIZED","wamp.error.authentication_failed":"NOT_AUTHORIZED"};class E extends Error{constructor(r,e){super(e??r),this.name="CrossAppAccessError",this.code=r}}function S(y){const r=y==null?void 0:y.error;if(typeof r!="string")return null;const e=ye[r];if(!e)return null;const n=y.args,l=Array.isArray(n)&&n.length>0?`: ${JSON.stringify(n[0])}`:"";return new E(e,`${r}${l}`)}class X{constructor(r,e,n,l,i){this.app=r,this.stage=e,this.tables=n.tables??[],this.transforms=n.transforms??[],this._connection=l,this._onClosed=i}get connection(){return this._connection}get isConnected(){return this._connection.is_open}assertInCatalog(r){if(!r)throw new Error("Tablename must not be empty!");const e=[...this.tables,...this.transforms].map(n=>n.tablename);if(!e.includes(r))throw new E("PRIVATE_TABLE",`'${r}' is not shared by app '${this.app}' (${this.stage}). Available tables/transforms: ${e.length>0?e.join(", "):"none"}`)}async subscribeToTable(r,e,n){this.assertInCatalog(r);const l=await this._connection.subscribe(`transformed.${r}`,e),i=(u,t,a)=>{const s=Array.isArray(u)?u[0]:u,o=Array.isArray(s)?s:s==null?[]:[s];for(const f of o)e([f],t,a)};return await this._connection.subscribe(`transformed.bulk.${r}`,i),l}async getHistory(r,e={limit:10}){this.assertInCatalog(r),e.offset==null&&(e.offset=0);const n=D(e);if(!n.success)throw new Error(`Invalid query parameters: ${n.errors.map(l=>l.path+": "+l.expected).join(", ")}`);try{return await this._connection.call(`history.transformed.${r}`,[e])}catch(l){throw S(l)??l}}async getSeriesHistory(r,e){if(!r)throw new Error("Tablename must not be empty!");P(e);const n=this.tables.map(i=>i.tablename);if(!n.includes(r))throw this.transforms.some(i=>i.tablename===r)?new E("PRIVATE_TABLE",`'${r}' is a transform of app '${this.app}' (${this.stage}); series history is available for tables only — use getHistory() instead.`):new E("PRIVATE_TABLE",`'${r}' is not a shared table of app '${this.app}' (${this.stage}). Available tables: ${n.length>0?n.join(", "):"none"}`);const l=j(e);if(!l.success)throw new Error(`Invalid series query parameters: ${l.errors.map(i=>i.path+": "+i.expected).join(", ")}`);try{return await this._connection.call(`history.transformed.series.${r}`,[e])}catch(i){throw S(i)??i}}async close(){var r;this._connection.stop(),(r=this._onClosed)==null||r.call(this),this._onClosed=void 0}}const K="error-logs";function b(y){var r;return typeof process<"u"?(r=process.env)==null?void 0:r[y]:void 0}function H(y){var r;if(typeof process<"u")try{const e=(r=process.getBuiltinModule)==null?void 0:r.call(process,"node:fs");if(e){const n=b("IRONFLOCK_ENV_DIR")??"/data/env",l=e.readFileSync(`${n}/${y}.txt`,"utf8").trim();if(l)return l}}catch{}return b(y)}function ve(y){const r=y??b("DEVICE_SERIAL_NUMBER");if(!r)throw new Error("serialNumber option is required (or set DEVICE_SERIAL_NUMBER env var in Node.js)");return r}function Q(y,r,e){const n=e==null?void 0:e.error,l=e instanceof Error?e.message:String(e);return typeof n=="string"&&n.includes("no_such_procedure")||l.includes("no_such_procedure")||l.includes("no callee registered")?new Error(`${y} failed: history procedure '${r}' is not registered. Check that the table is declared in the app's data-template and that the app's data backend is running.`):e instanceof Error?e:new Error(`${y} failed: ${l}`)}class U{constructor(r){this._isConfigured=!1,this._consumedApps=new Map,this._serialNumber=ve(r==null?void 0:r.serialNumber),this._deviceName=(r==null?void 0:r.deviceName)??b("DEVICE_NAME"),this._deviceKey=(r==null?void 0:r.deviceKey)??b("DEVICE_KEY"),this._appName=(r==null?void 0:r.appName)??b("APP_NAME"),this._swarmKey=(r==null?void 0:r.swarmKey)??parseInt(b("SWARM_KEY")??"0",10),this._appKey=(r==null?void 0:r.appKey)??parseInt(b("APP_KEY")??"0",10),this._env=(r==null?void 0:r.env)??b("ENV"),this._reswarmUrl=(r==null?void 0:r.reswarmUrl)??b("RESWARM_URL"),this._cburl=(r==null?void 0:r.ironFlockUrl)??(r==null?void 0:r.cburl),this._connection=new k;const e=[];this._deviceKey||e.push("DEVICE_KEY"),this._appName||e.push("APP_NAME"),this._swarmKey||e.push("SWARM_KEY"),this._appKey||e.push("APP_KEY"),e.length>0&&console.warn(`Warning: The following environment variables must be present: ${e.join(", ")}`)}get connection(){return this._connection}get isConnected(){return this._connection.is_open}configureConnection(r){if(this._isConfigured)return;const e=(this._env??"DEV").toUpperCase(),l={DEV:R.DEVELOPMENT,PROD:R.PRODUCTION}[e]??R.DEVELOPMENT,i=r??this._cburl??k.getWebSocketURI(this._reswarmUrl);this._connection.configure(this._swarmKey,this._appKey,l,this._serialNumber,i),this._isConfigured=!0}async start(r){this.configureConnection(r),await this._connection.start()}async stop(){const r=[...this._consumedApps.values()];this._consumedApps.clear(),await Promise.all(r.map(e=>e.then(n=>n.close()).catch(()=>{}))),this._connection.stop()}async connectToApp(r,e){if(!r)throw new Error("appName must not be empty!");const n=(this._env??"DEV").toUpperCase()==="PROD"?"prod":"dev",l=(e==null?void 0:e.stage)??n,i=`${r.toLowerCase()}:${l}`,u=this._consumedApps.get(i);if(u)return u;let t;const a=()=>{this._consumedApps.get(i)===t&&this._consumedApps.delete(i)};return t=this.openConsumedApp(r,l,a,e==null?void 0:e.onError),this._consumedApps.set(i,t),t.catch(a),t}async listConsumableApps(){try{return await this._connection.call("sys.appaccess.list",[])??[]}catch(r){throw S(r)??r}}async connectToAllApps(r){var s,o;const e=(this._env??"DEV").toUpperCase()==="PROD"?"prod":"dev",n=(r==null?void 0:r.stage)??e,l=(r==null?void 0:r.continueOnError)??!0,i=await this.listConsumableApps(),u=[];for(const f of i)(s=f.stages)!=null&&s[n]&&u.push(this.openCachedFromInfo(f,n,r==null?void 0:r.onError));const t=await Promise.allSettled(u),a=[];for(const f of t)if(f.status==="fulfilled")a.push(f.value);else if(l)(o=r==null?void 0:r.onError)==null||o.call(r,f.reason);else throw f.reason;return a}async openConsumedApp(r,e,n,l){let i;try{i=await this._connection.call("sys.appaccess.resolve",[{app:r}])}catch(u){throw S(u)??u}if(!i)throw new E("PROVIDER_NOT_INSTALLED",`App '${r}' has no ${e} data backend in this project`);return this.openFromInfo(i,e,n,l)}openCachedFromInfo(r,e,n){const l=`${r.app}:${e}`,i=this._consumedApps.get(l);if(i)return i;let u;const t=()=>{this._consumedApps.get(l)===u&&this._consumedApps.delete(l)};return u=this.openFromInfo(r,e,t,n),this._consumedApps.set(l,u),u.catch(t),u}async openFromInfo(r,e,n,l){var o;const i=r.app,u=(o=r.stages)==null?void 0:o[e];if(!u)throw new E("PROVIDER_NOT_INSTALLED",`App '${i}' has no ${e} data backend in this project`);const t=new k;t.failOnAuthError=!0,t.configure(this._swarmKey,r.provider_app_key,e==="prod"?R.PRODUCTION:R.DEVELOPMENT,this._serialNumber,this._connection.socketURI??this._cburl??k.getWebSocketURI(this._reswarmUrl));let a=!1,s;t.on("auth_failure",f=>{s=new E("NOT_AUTHORIZED",`Access to app '${i}' (${e}) denied: ${f}. The grant may have been revoked.`),n(),a&&(l==null||l(s))});try{await t.start()}catch(f){throw s??f}return a=!0,new X(i,e,u,t,n)}async publish(r,e,n){const l=z({topic:r,args:e,kwargs:n});if(!l.success)throw new Error(`Invalid publish parameters: ${l.errors.map(t=>t.path+": "+t.expected).join(", ")}`);const u={...{DEVICE_SERIAL_NUMBER:this._serialNumber,DEVICE_KEY:this._deviceKey,DEVICE_NAME:this._deviceName},...n??{}};return this._connection.publish(r,e,u,{acknowledge:!0})}async publishToTable(r,e,n){const l=C({tablename:r,args:e,kwargs:n});if(!l.success)throw new Error(`Invalid table parameters: ${l.errors.map(u=>u.path+": "+u.expected).join(", ")}`);if(!this._swarmKey)throw new Error("SWARM_KEY not set in environment variables!");if(!this._appKey)throw new Error("APP_KEY not set in environment variables!");const i=`${this._swarmKey}.${this._appKey}.${r}`;return this.publish(i,e,n)}async reportError(r,e){const n=r instanceof Error?r.stack??r.message:r,l={tsp:(e==null?void 0:e.tsp)??new Date().toISOString(),msg:n,source:"app",level:(e==null?void 0:e.level)??"error"};return e!=null&&e.append?this.appendToTable(K,[l]):this.publishToTable(K,[l])}async appendToTable(r,e,n){const l=C({tablename:r,args:e,kwargs:n});if(!l.success)throw new Error(`Invalid table parameters: ${l.errors.map(a=>a.path+": "+a.expected).join(", ")}`);if(!this._swarmKey)throw new Error("SWARM_KEY not set in environment variables!");if(!this._appKey)throw new Error("APP_KEY not set in environment variables!");const i=`append.${this._swarmKey}.${this._appKey}.${r}`,t={...{DEVICE_SERIAL_NUMBER:this._serialNumber,DEVICE_KEY:this._deviceKey,DEVICE_NAME:this._deviceName},...n??{}};return this._connection.call(i,e,t)}async publishRowsToTable(r,e,n){const l=L({tablename:r,rows:e,kwargs:n});if(!l.success)throw new Error(`Invalid bulk table parameters: ${l.errors.map(u=>u.path+": "+u.expected).join(", ")}`);if(!this._swarmKey)throw new Error("SWARM_KEY not set in environment variables!");if(!this._appKey)throw new Error("APP_KEY not set in environment variables!");const i=`bulk.${this._swarmKey}.${this._appKey}.${r}`;return this.publish(i,[e],n)}async appendRowsToTable(r,e,n){const l=L({tablename:r,rows:e,kwargs:n});if(!l.success)throw new Error(`Invalid bulk table parameters: ${l.errors.map(a=>a.path+": "+a.expected).join(", ")}`);if(!this._swarmKey)throw new Error("SWARM_KEY not set in environment variables!");if(!this._appKey)throw new Error("APP_KEY not set in environment variables!");const i=`appendBulk.${this._swarmKey}.${this._appKey}.${r}`,t={...{DEVICE_SERIAL_NUMBER:this._serialNumber,DEVICE_KEY:this._deviceKey,DEVICE_NAME:this._deviceName},...n??{}};return this._connection.call(i,[e],t)}async subscribe(r,e,n){return this._connection.subscribe(r,e)}async subscribeToTable(r,e,n){if(!this._swarmKey)throw new Error("SWARM_KEY not set in environment variables!");if(!this._appKey)throw new Error("APP_KEY not set in environment variables!");const l=`transformed.${r}`,i=await this.subscribe(l,e,n),u=(t,a,s)=>{const o=Array.isArray(t)?t[0]:t,f=Array.isArray(o)?o:o==null?[]:[o];for(const d of f)e([d],a,s)};return await this.subscribe(`transformed.bulk.${r}`,u,n),i}async call(r,e,n,l){return this._connection.call(r,e,n,l)}async callDeviceFunction(r,e,n,l,i){const u=`${this._swarmKey}.${r}.${this._appKey}.${this._env}.${e}`;return this._connection.call(u,n,l,i)}async callFunction(r,e,n,l,i){return console.warn("callFunction() is deprecated and will be removed in a future version. Use callDeviceFunction() instead."),this.callDeviceFunction(r,e,n,l,i)}async registerDeviceFunction(r,e,n){const l=`${this._swarmKey}.${this._deviceKey}.${this._appKey}.${this._env}.${r}`,i=await this._connection.register(l,e,n);return console.log(`Function registered for IronFlock topic '${r}'. (Full WAMP topic: '${l}')`),i}async registerFunction(r,e,n){return console.warn("registerFunction() is deprecated and will be removed in a future version. Use registerDeviceFunction() instead."),this.registerDeviceFunction(r,e,n)}async register(r,e,n){return this.registerDeviceFunction(r,e,n)}async getHistory(r,e={limit:10}){if(!r)throw new Error("Tablename must not be empty!");e.offset==null&&(e.offset=0);const n=D(e);if(!n.success)throw new Error(`Invalid query parameters: ${n.errors.map(i=>i.path+": "+i.expected).join(", ")}`);const l=`history.transformed.${r}`;try{return await this._connection.call(l,[e])}catch(i){throw Q(`getHistory('${r}')`,l,i)}}async getSeriesHistory(r,e){if(!r)throw new Error("Tablename must not be empty!");P(e);const n=j(e);if(!n.success)throw new Error(`Invalid series query parameters: ${n.errors.map(i=>i.path+": "+i.expected).join(", ")}`);const l=`history.transformed.series.${r}`;try{return await this._connection.call(l,[e])}catch(i){throw Q(`getSeriesHistory('${r}')`,l,i)}}async setDeviceLocation(r,e){const n=Z({longitude:r,latitude:e});if(!n.success)throw new Error(`Invalid location parameters: ${n.errors.map(u=>u.path+": "+u.expected).join(", ")}`);const l={long:r,lat:e},i={DEVICE_SERIAL_NUMBER:this._serialNumber,DEVICE_KEY:this._deviceKey,DEVICE_NAME:this._deviceName};return this._connection.call("ironflock.location_service.update",[l],i)}getRemoteAccessUrlForPort(r,e="http",n){const l=b("INSTANCE_KEY");if(e==="tcp"||e==="udp"){if(!n)return null;if(l){const s=H(`${n}_CLOUD`);if(s){const o=b("CLOUD_TUNNEL_DOMAIN")??"app.ironflock.com";return`${e}://${o}:${s}`}}const t=H(n);if(!t)return null;const a=b("TUNNEL_DOMAIN")??"app.ironflock.com";return`${e}://${a}:${t}`}if(e!=="http"&&e!=="https"||!this._deviceKey||!this._appName)return null;let i=`${this._deviceKey}-${this._appName.toLowerCase()}-${r}`;e==="https"&&(i=`secure-${i}`);let u;return l?(i=`i${l}-${i}`,u=b("CLOUD_TUNNEL_DOMAIN")??"app.ironflock.com"):u=b("TUNNEL_DOMAIN")??"app.ironflock.com",i.length>63||i.includes(".")?null:`https://${i}.${u}`}static async fromServer(r){const e=await fetch(r);if(!e.ok)throw new Error(`Failed to fetch IronFlock config from ${r}: ${e.status} ${e.statusText}`);const n=await e.json();return new U(n)}}exports.ConsumedApp=X;exports.CrossAppAccessError=E;exports.CrossbarConnection=k;exports.ERROR_LOGS_TABLE=K;exports.IronFlock=U;exports.Stage=R;exports.WampError=G;exports.assertNoLatestMarker=P;exports.validateBulkTableParams=L;exports.validateCallParams=he;exports.validateLocationParams=Z;exports.validatePublishParams=z;exports.validateSeriesQueryParams=j;exports.validateTableParams=C;exports.validateTableQueryParams=D;
|
|
3
3
|
//# sourceMappingURL=index.cjs.map
|