ironflock 1.0.2 → 1.1.1
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 +258 -24
- package/dist/index.cjs +3 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.ts +146 -2
- package/dist/index.mjs +669 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +42 -11
- package/dist/crossbar/index.d.ts +0 -38
- package/dist/crossbar/index.js +0 -153
- package/dist/crossbar/serializer.d.ts +0 -8
- package/dist/crossbar/serializer.js +0 -55
- package/dist/index.js +0 -3
- package/dist/ironflock.d.ts +0 -19
- package/dist/ironflock.js +0 -166
- package/dist/test/index.d.ts +0 -1
- package/dist/test/index.js +0 -69
- package/dist/utils/index.d.ts +0 -1
- package/dist/utils/index.js +0 -26
- package/src/crossbar/index.ts +0 -125
- package/src/crossbar/serializer.ts +0 -31
- package/src/index.ts +0 -3
- package/src/ironflock.ts +0 -109
- package/src/test/index.ts +0 -28
- package/src/utils/index.ts +0 -25
- package/tsconfig.json +0 -21
package/README.md
CHANGED
|
@@ -8,59 +8,293 @@ of the device's fleet and the data is collected in the respective fleet database
|
|
|
8
8
|
|
|
9
9
|
So if you use the library in your app, the data collection will always be private to the app user's fleet.
|
|
10
10
|
|
|
11
|
-
For more information on the IronFlock IoT Devops Platform for engineers and developers visit our [
|
|
11
|
+
For more information on the IronFlock IoT Devops Platform for engineers and developers visit our [IronFlock](https://www.ironflock.com) home page.
|
|
12
12
|
|
|
13
|
-
##
|
|
13
|
+
## Requirements
|
|
14
|
+
|
|
15
|
+
- Node.js 18 or higher
|
|
14
16
|
|
|
15
|
-
|
|
17
|
+
## Installation
|
|
16
18
|
|
|
17
19
|
```shell
|
|
18
|
-
npm install
|
|
20
|
+
npm install ironflock
|
|
19
21
|
```
|
|
20
22
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
```js
|
|
24
|
-
const IronFlock = require("ironflock")
|
|
25
|
-
const ironflock = new IronFlock()
|
|
23
|
+
## Usage
|
|
26
24
|
|
|
27
|
-
|
|
28
|
-
|
|
25
|
+
```ts
|
|
26
|
+
import { IronFlock } from "ironflock";
|
|
29
27
|
|
|
30
|
-
|
|
28
|
+
// Create an IronFlock instance to connect to the IronFlock platform data infrastructure.
|
|
29
|
+
// The IronFlock instance handles authentication when run on a device registered in IronFlock.
|
|
30
|
+
const ironflock = new IronFlock();
|
|
31
31
|
|
|
32
|
-
|
|
32
|
+
// Start the connection to the platform
|
|
33
|
+
await ironflock.start();
|
|
33
34
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
const ironflock = new IronFlock()
|
|
35
|
+
// Publish an event
|
|
36
|
+
await ironflock.publish("test.publish.example", [{ temperature: 20 }]);
|
|
37
37
|
|
|
38
|
-
|
|
38
|
+
// Stop the connection when done
|
|
39
|
+
await ironflock.stop();
|
|
39
40
|
```
|
|
40
41
|
|
|
41
|
-
|
|
42
|
+
## Options
|
|
42
43
|
|
|
43
44
|
The `IronFlock` constructor can be configured with the following options:
|
|
44
45
|
|
|
45
46
|
```ts
|
|
46
47
|
{
|
|
47
|
-
|
|
48
|
-
serialNumber?: string;
|
|
48
|
+
serialNumber?: string;
|
|
49
49
|
}
|
|
50
50
|
```
|
|
51
51
|
|
|
52
|
-
**
|
|
52
|
+
**serialNumber**: Used to set the serial number of the device if the `DEVICE_SERIAL_NUMBER` environment variable does not exist. It can also be used if the user wishes to authenticate as another device.
|
|
53
|
+
|
|
54
|
+
## API Reference
|
|
55
|
+
|
|
56
|
+
### `publish(topic, args?, kwargs?)`
|
|
57
|
+
|
|
58
|
+
Publishes an event to a topic on the IronFlock message router.
|
|
59
|
+
|
|
60
|
+
```ts
|
|
61
|
+
const publication = await ironflock.publish("com.myapp.mytopic", [{ temperature: 20 }]);
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
| Parameter | Type | Description |
|
|
65
|
+
|-----------|------|-------------|
|
|
66
|
+
| `topic` | `string` | The URI of the topic to publish to |
|
|
67
|
+
| `args` | `unknown[]`, optional | Payload arguments |
|
|
68
|
+
| `kwargs` | `Record<string, unknown>`, optional | Payload keyword arguments |
|
|
69
|
+
|
|
70
|
+
**Returns:** `Promise<unknown>` — The publication object (an acknowledged publish receipt).
|
|
71
|
+
|
|
72
|
+
---
|
|
73
|
+
|
|
74
|
+
### `publishToTable(tablename, args?, kwargs?)`
|
|
75
|
+
|
|
76
|
+
Convenience function to publish data to a fleet table in the IronFlock platform. Automatically constructs the correct topic using the `SWARM_KEY` and `APP_KEY` environment variables.
|
|
77
|
+
|
|
78
|
+
```ts
|
|
79
|
+
await ironflock.publishToTable("sensordata", [{ temperature: 22.5, humidity: 60 }]);
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
| Parameter | Type | Description |
|
|
83
|
+
|-----------|------|-------------|
|
|
84
|
+
| `tablename` | `string` | The name of the table, e.g. `"sensordata"` |
|
|
85
|
+
| `args` | `unknown[]`, optional | Row data to publish |
|
|
86
|
+
| `kwargs` | `Record<string, unknown>`, optional | Row data as keyword arguments |
|
|
87
|
+
|
|
88
|
+
**Returns:** `Promise<unknown>` — The publication object (an acknowledged publish receipt).
|
|
89
|
+
|
|
90
|
+
---
|
|
91
|
+
|
|
92
|
+
### `subscribe(topic, handler)`
|
|
93
|
+
|
|
94
|
+
Subscribes to a topic on the IronFlock message router.
|
|
95
|
+
|
|
96
|
+
```ts
|
|
97
|
+
function onMessage(...args: any[]) {
|
|
98
|
+
console.log("Received:", args);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
const subscription = await ironflock.subscribe("com.myapp.mytopic", onMessage);
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
| Parameter | Type | Description |
|
|
105
|
+
|-----------|------|-------------|
|
|
106
|
+
| `topic` | `string` | The URI of the topic to subscribe to |
|
|
107
|
+
| `handler` | `(...args: any[]) => void` | Function called when a message is received |
|
|
108
|
+
|
|
109
|
+
**Returns:** `Promise<Subscription | undefined>` — The subscription object.
|
|
110
|
+
|
|
111
|
+
---
|
|
112
|
+
|
|
113
|
+
### `subscribeToTable(tablename, handler)`
|
|
114
|
+
|
|
115
|
+
Convenience function to subscribe to a fleet table. Automatically constructs the correct topic using the `SWARM_KEY` and `APP_KEY` environment variables.
|
|
116
|
+
|
|
117
|
+
```ts
|
|
118
|
+
function onTableData(...args: any[]) {
|
|
119
|
+
console.log("New row:", args);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
await ironflock.subscribeToTable("sensordata", onTableData);
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
| Parameter | Type | Description |
|
|
126
|
+
|-----------|------|-------------|
|
|
127
|
+
| `tablename` | `string` | The name of the table to subscribe to |
|
|
128
|
+
| `handler` | `(...args: any[]) => void` | Function called when new data arrives |
|
|
129
|
+
|
|
130
|
+
**Returns:** `Promise<Subscription | undefined>` — The subscription object.
|
|
131
|
+
|
|
132
|
+
---
|
|
133
|
+
|
|
134
|
+
### `getHistory(tablename, queryParams?)`
|
|
135
|
+
|
|
136
|
+
Retrieves historical data from a fleet table.
|
|
137
|
+
|
|
138
|
+
```ts
|
|
139
|
+
// Simple query with limit
|
|
140
|
+
const data = await ironflock.getHistory("sensordata", { limit: 100 });
|
|
141
|
+
|
|
142
|
+
// Query with time range and filters
|
|
143
|
+
const data = await ironflock.getHistory("sensordata", {
|
|
144
|
+
limit: 500,
|
|
145
|
+
offset: 0,
|
|
146
|
+
timeRange: {
|
|
147
|
+
start: "2026-01-01T00:00:00Z",
|
|
148
|
+
end: "2026-03-01T00:00:00Z",
|
|
149
|
+
},
|
|
150
|
+
filterAnd: [
|
|
151
|
+
{ column: "temperature", operator: ">", value: 20 },
|
|
152
|
+
{ column: "humidity", operator: "<=", value: 80 },
|
|
153
|
+
],
|
|
154
|
+
});
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
| Parameter | Type | Description |
|
|
158
|
+
|-----------|------|-------------|
|
|
159
|
+
| `tablename` | `string` | The name of the table to query |
|
|
160
|
+
| `queryParams` | `TableQueryParams` | Query parameters (see below) |
|
|
161
|
+
|
|
162
|
+
**queryParams fields:**
|
|
163
|
+
|
|
164
|
+
| Field | Type | Description |
|
|
165
|
+
|-------|------|-------------|
|
|
166
|
+
| `limit` | `number` | Maximum number of rows to return (1–10000, required) |
|
|
167
|
+
| `offset` | `number`, optional | Offset for pagination |
|
|
168
|
+
| `timeRange` | `ISOTimeRange`, optional | `{ start: "<ISO datetime>", end: "<ISO datetime>" }` |
|
|
169
|
+
| `filterAnd` | `SQLFilterAnd[]`, optional | List of AND filter conditions: `{ column: string, operator: string, value: ... }` |
|
|
170
|
+
|
|
171
|
+
Supported filter operators: `=`, `!=`, `>`, `<`, `>=`, `<=`, `LIKE`, `ILIKE`, `IN`, `NOT IN`, `IS`, `IS NOT`.
|
|
172
|
+
|
|
173
|
+
**Returns:** `Promise<unknown | null>` — The query result data (typically an array of row objects), or `null` if the call failed.
|
|
174
|
+
|
|
175
|
+
---
|
|
53
176
|
|
|
54
|
-
|
|
177
|
+
### `call(deviceKey, topic, args?, kwargs?)`
|
|
55
178
|
|
|
179
|
+
Calls a remote procedure registered by another IronFlock device.
|
|
180
|
+
|
|
181
|
+
```ts
|
|
182
|
+
const result = await ironflock.call("other-device-key", "com.myapp.myprocedure", [42]);
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
| Parameter | Type | Description |
|
|
186
|
+
|-----------|------|-------------|
|
|
187
|
+
| `deviceKey` | `string` | The device key of the target device |
|
|
188
|
+
| `topic` | `string` | The URI of the procedure to call |
|
|
189
|
+
| `args` | `unknown[]`, optional | Positional arguments |
|
|
190
|
+
| `kwargs` | `Record<string, unknown>`, optional | Keyword arguments |
|
|
191
|
+
|
|
192
|
+
**Returns:** `Promise<unknown>` — The result of the remote procedure call.
|
|
193
|
+
|
|
194
|
+
---
|
|
195
|
+
|
|
196
|
+
### `registerFunction(topic, endpoint)`
|
|
197
|
+
|
|
198
|
+
Registers a procedure that can be called by other devices in the fleet.
|
|
199
|
+
|
|
200
|
+
```ts
|
|
201
|
+
function add(args: any[]) {
|
|
202
|
+
return args[0] + args[1];
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
await ironflock.registerFunction("com.myapp.add", add);
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
| Parameter | Type | Description |
|
|
209
|
+
|-----------|------|-------------|
|
|
210
|
+
| `topic` | `string` | The URI of the procedure to register |
|
|
211
|
+
| `endpoint` | `(...args: any[]) => any` | The function to register |
|
|
212
|
+
|
|
213
|
+
**Returns:** `Promise<Registration | undefined>` — The registration object.
|
|
214
|
+
|
|
215
|
+
> `register()` is an alias for `registerFunction()`.
|
|
216
|
+
|
|
217
|
+
---
|
|
218
|
+
|
|
219
|
+
### `setDeviceLocation(long, lat)`
|
|
220
|
+
|
|
221
|
+
Updates the device's location in the platform master data. The maps in device or group overviews will reflect the new location in realtime.
|
|
222
|
+
|
|
223
|
+
```ts
|
|
224
|
+
await ironflock.setDeviceLocation(8.6821, 50.1109);
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
| Parameter | Type | Description |
|
|
228
|
+
|-----------|------|-------------|
|
|
229
|
+
| `long` | `number` | Longitude (-180 to 180) |
|
|
230
|
+
| `lat` | `number` | Latitude (-90 to 90) |
|
|
231
|
+
|
|
232
|
+
**Returns:** `Promise<unknown | null>` — The result of the location update call, or `null` if the call failed.
|
|
233
|
+
|
|
234
|
+
> **Note:** Location history is not stored. If you need location history, create a dedicated table and use `publishToTable`.
|
|
235
|
+
|
|
236
|
+
---
|
|
237
|
+
|
|
238
|
+
### `getRemoteAccessUrlForPort(port)`
|
|
239
|
+
|
|
240
|
+
Returns the remote access URL for a given port on the device.
|
|
241
|
+
|
|
242
|
+
```ts
|
|
243
|
+
const url = ironflock.getRemoteAccessUrlForPort(8080);
|
|
244
|
+
// e.g. "https://<device_key>-<app_name>-8080.app.ironflock.com"
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
| Parameter | Type | Description |
|
|
248
|
+
|-----------|------|-------------|
|
|
249
|
+
| `port` | `number` | The port number |
|
|
250
|
+
|
|
251
|
+
**Returns:** `string | null` — The remote access URL string, or `null` if the device key or app name is not available.
|
|
252
|
+
|
|
253
|
+
---
|
|
254
|
+
|
|
255
|
+
### Properties
|
|
256
|
+
|
|
257
|
+
| Property | Type | Description |
|
|
258
|
+
|----------|------|-------------|
|
|
259
|
+
| `isConnected` | `boolean` | `true` if the connection to the platform is established |
|
|
260
|
+
| `connection` | `CrossbarConnection` | The underlying connection instance (for advanced use) |
|
|
261
|
+
|
|
262
|
+
### Lifecycle Methods
|
|
263
|
+
|
|
264
|
+
| Method | Description |
|
|
265
|
+
|--------|-------------|
|
|
266
|
+
| `await start(cburl?)` | Configures and starts the connection to the platform |
|
|
267
|
+
| `await stop()` | Stops the connection |
|
|
56
268
|
|
|
57
269
|
## Development
|
|
58
270
|
|
|
59
|
-
|
|
271
|
+
Install dependencies:
|
|
272
|
+
|
|
273
|
+
```shell
|
|
274
|
+
npm install
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
Run tests:
|
|
278
|
+
|
|
279
|
+
```shell
|
|
280
|
+
npm test
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
Type check:
|
|
284
|
+
|
|
285
|
+
```shell
|
|
286
|
+
npm run typecheck
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
Build:
|
|
60
290
|
|
|
61
291
|
```shell
|
|
62
292
|
npm run build
|
|
293
|
+
```
|
|
294
|
+
|
|
295
|
+
Publish a new release:
|
|
296
|
+
|
|
297
|
+
```shell
|
|
63
298
|
npm run release
|
|
64
|
-
npm run publish
|
|
65
299
|
```
|
|
66
300
|
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const R=require("autobahn"),K=require("events"),T="wss://cbw.datapods.io/ws-ua-usr",k="wss://cbw.ironflock.com/ws-ua-usr",$="wss://cbw.ironflock.dev/ws-ua-usr",P="wss://cbw.record-evolution.com/ws-ua-usr",E="ws://localhost:8080/ws-ua-usr",C={"https://studio.datapods.io":T,"https://studio.ironflock.dev":$,"https://studio.ironflock.com":k,"https://studio.record-evolution.com":P,"http://localhost:8085":E,"http://localhost:8086":E,"http://host.docker.internal:8086":E},N=6e3;class A extends K.EventEmitter{constructor(){super(),this.subscriptions=[],this.registrations=[],this.firstResolver=()=>{},this.firstRejecter=()=>{}}static getWebSocketURI(){const t=process.env.RESWARM_URL;return t?C[t]??k:k}configure(t,s,a,c,n){this.realm=`realm-${t}-${s}-${a}`,this.serial_number=c,this.socketURI=n??A.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.firstConnection=new Promise((t,s)=>{this.firstResolver=t,this.firstRejecter=s}),this.connection=new R.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)=>R.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.resubscribeAll(),this.emit("connected",this.serial_number),this.firstResolver(),this.firstResolver=()=>{}}onClose(t,s){return 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}),!1}async sessionWait(){const t=Date.now();for(;!this.session;){if(Date.now()-t>N)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;(t=this.connection)==null||t.close("wamp.close.normal","Connection closed by client")}async subscribe(t,s){var c;await this.sessionWait();const a=await((c=this.session)==null?void 0:c.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 register(t,s){var c;await this.sessionWait();const a=await((c=this.session)==null?void 0:c.register(t,s));return a&&this.registrations.push(a),a}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,c){var n;return await this.sessionWait(),(n=this.session)==null?void 0:n.call(t,s,a,c)}async publish(t,s,a,c){var n;return await this.sessionWait(),(n=this.session)==null?void 0:n.publish(t,s,a,c)}}const w=d=>Math.floor(d)===d&&j<=d&&d<=x,j=0,x=2**32-1,b=d=>O.test(d),O=/^[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,m=d=>{const t=s=>{if(d.length===0)return!0;const a=d[d.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
|
+
`))),d.push(a)),!1)},y=d=>Object.assign(d,{"~standard":{version:1,vendor:"typia",validate:t=>{const s=d(t);return s.success?{value:s.data}:{issues:s.errors.map(a=>({message:`expected ${a.expected}, got ${a.value}`,path:L(a.path)}))}}}});var v;(function(d){d[d.Start=0]="Start",d[d.Property=1]="Property",d[d.StringKey=2]="StringKey",d[d.NumberKey=3]="NumberKey"})(v||(v={}));const L=d=>{if(!d.startsWith("$input"))throw new Error(`Invalid path: ${JSON.stringify(d)}`);const t=[];let s="",a=v.Start,c=5;for(;c<d.length-1;){c++;const n=d[c];if(a===v.Property?n==="."||n==="["?(t.push({key:s}),a=v.Start):c===d.length-1?(s+=n,t.push({key:s}),c++,a=v.Start):s+=n:a===v.StringKey?n==='"'?(t.push({key:JSON.parse(s+n)}),c+=2,a=v.Start):n==="\\"?(s+=d[c],c++,s+=d[c]):s+=n:a===v.NumberKey&&(n==="]"?(t.push({key:Number.parseInt(s)}),c++,a=v.Start):s+=n),a===v.Start&&c<d.length-1){const l=d[c];if(s="",l==="[")d[c+1]==='"'?(a=v.StringKey,c++,s='"'):a=v.NumberKey;else if(l===".")a=v.Property;else throw new Error("Unreachable: pointer points invalid character")}}if(a!==v.Start)throw new Error(`Failed to parse path: ${JSON.stringify(d)}`);return t};var f=(d=>(d.DEVELOPMENT="dev",d.PRODUCTION="prod",d))(f||{});const M=(()=>{const d=r=>typeof r.limit=="number"&&w(r.limit)&&1<=r.limit&&r.limit<=1e4&&(r.offset===void 0||typeof r.offset=="number"&&w(r.offset)&&0<=r.offset)&&(r.timeRange===void 0||typeof r.timeRange=="object"&&r.timeRange!==null&&t(r.timeRange))&&(r.filterAnd===void 0||Array.isArray(r.filterAnd)&&r.filterAnd.every(i=>typeof i=="object"&&i!==null&&s(i))),t=r=>typeof r.start=="string"&&b(r.start)&&typeof r.end=="string"&&b(r.end),s=r=>typeof r.column=="string"&&1<=r.column.length&&typeof r.operator=="string"&&1<=r.operator.length&&r.value!==null&&r.value!==void 0&&(typeof r.value=="string"||typeof r.value=="number"||typeof r.value=="boolean"||Array.isArray(r.value)&&r.value.every(i=>typeof i=="string"||typeof i=="number")),a=(r,i,u=!0)=>[typeof r.limit=="number"&&(w(r.limit)||o(u,{path:i+".limit",expected:'number & Type<"uint32">',value:r.limit}))&&(1<=r.limit||o(u,{path:i+".limit",expected:"number & Minimum<1>",value:r.limit}))&&(r.limit<=1e4||o(u,{path:i+".limit",expected:"number & Maximum<10000>",value:r.limit}))||o(u,{path:i+".limit",expected:'(number & Type<"uint32"> & Minimum<1> & Maximum<10000>)',value:r.limit}),r.offset===void 0||typeof r.offset=="number"&&(w(r.offset)||o(u,{path:i+".offset",expected:'number & Type<"uint32">',value:r.offset}))&&(0<=r.offset||o(u,{path:i+".offset",expected:"number & Minimum<0>",value:r.offset}))||o(u,{path:i+".offset",expected:'((number & Type<"uint32"> & Minimum<0>) | undefined)',value:r.offset}),r.timeRange===void 0||(typeof r.timeRange=="object"&&r.timeRange!==null||o(u,{path:i+".timeRange",expected:"(ISOTimeRange | undefined)",value:r.timeRange}))&&c(r.timeRange,i+".timeRange",u)||o(u,{path:i+".timeRange",expected:"(ISOTimeRange | undefined)",value:r.timeRange}),r.filterAnd===void 0||(Array.isArray(r.filterAnd)||o(u,{path:i+".filterAnd",expected:"(Array<SQLFilterAnd> | undefined)",value:r.filterAnd}))&&r.filterAnd.map((h,g)=>(typeof h=="object"&&h!==null||o(u,{path:i+".filterAnd["+g+"]",expected:"SQLFilterAnd",value:h}))&&n(h,i+".filterAnd["+g+"]",u)||o(u,{path:i+".filterAnd["+g+"]",expected:"SQLFilterAnd",value:h})).every(h=>h)||o(u,{path:i+".filterAnd",expected:"(Array<SQLFilterAnd> | undefined)",value:r.filterAnd})].every(h=>h),c=(r,i,u=!0)=>[typeof r.start=="string"&&(b(r.start)||o(u,{path:i+".start",expected:'string & Format<"date-time">',value:r.start}))||o(u,{path:i+".start",expected:'(string & Format<"date-time">)',value:r.start}),typeof r.end=="string"&&(b(r.end)||o(u,{path:i+".end",expected:'string & Format<"date-time">',value:r.end}))||o(u,{path:i+".end",expected:'(string & Format<"date-time">)',value:r.end})].every(h=>h),n=(r,i,u=!0)=>[typeof r.column=="string"&&(1<=r.column.length||o(u,{path:i+".column",expected:"string & MinLength<1>",value:r.column}))||o(u,{path:i+".column",expected:"(string & MinLength<1>)",value:r.column}),typeof r.operator=="string"&&(1<=r.operator.length||o(u,{path:i+".operator",expected:"string & MinLength<1>",value:r.operator}))||o(u,{path:i+".operator",expected:"(string & MinLength<1>)",value:r.operator}),(r.value!==null||o(u,{path:i+".value",expected:"(Array<string | number> | boolean | number | string)",value:r.value}))&&(r.value!==void 0||o(u,{path:i+".value",expected:"(Array<string | number> | boolean | number | string)",value:r.value}))&&(typeof r.value=="string"||typeof r.value=="number"||typeof r.value=="boolean"||(Array.isArray(r.value)||o(u,{path:i+".value",expected:"(Array<string | number> | boolean | number | string)",value:r.value}))&&r.value.map((h,g)=>typeof h=="string"||typeof h=="number"||o(u,{path:i+".value["+g+"]",expected:"(number | string)",value:h})).every(h=>h)||o(u,{path:i+".value",expected:"(Array<string | number> | boolean | number | string)",value:r.value}))].every(h=>h),l=r=>typeof r=="object"&&r!==null&&d(r);let e,o;return y(r=>{if(l(r)===!1){e=[],o=m(e),((u,h,g=!0)=>(typeof u=="object"&&u!==null||o(!0,{path:h+"",expected:"TableQueryParams",value:u}))&&a(u,h+"",!0)||o(!0,{path:h+"",expected:"TableQueryParams",value:u}))(r,"$input",!0);const i=e.length===0;return i?{success:i,data:r}:{success:i,errors:e,data:r}}return{success:!0,data:r}})})(),_=(()=>{const d=n=>typeof n.longitude=="number"&&-180<=n.longitude&&n.longitude<=180&&typeof n.latitude=="number"&&-90<=n.latitude&&n.latitude<=90,t=(n,l,e=!0)=>[typeof n.longitude=="number"&&(-180<=n.longitude||c(e,{path:l+".longitude",expected:"number & Minimum<-180>",value:n.longitude}))&&(n.longitude<=180||c(e,{path:l+".longitude",expected:"number & Maximum<180>",value:n.longitude}))||c(e,{path:l+".longitude",expected:"(number & Minimum<-180> & Maximum<180>)",value:n.longitude}),typeof n.latitude=="number"&&(-90<=n.latitude||c(e,{path:l+".latitude",expected:"number & Minimum<-90>",value:n.latitude}))&&(n.latitude<=90||c(e,{path:l+".latitude",expected:"number & Maximum<90>",value:n.latitude}))||c(e,{path:l+".latitude",expected:"(number & Minimum<-90> & Maximum<90>)",value:n.latitude})].every(o=>o),s=n=>typeof n=="object"&&n!==null&&d(n);let a,c;return y(n=>{if(s(n)===!1){a=[],c=m(a),((e,o,r=!0)=>(typeof e=="object"&&e!==null||c(!0,{path:o+"",expected:"LocationParams",value:e}))&&t(e,o+"",!0)||c(!0,{path:o+"",expected:"LocationParams",value:e}))(n,"$input",!0);const l=a.length===0;return l?{success:l,data:n}:{success:l,errors:a,data:n}}return{success:!0,data:n}})})(),S=(()=>{const d=e=>typeof e.topic=="string"&&1<=e.topic.length&&(e.args===void 0||Array.isArray(e.args))&&(e.kwargs===void 0||typeof e.kwargs=="object"&&e.kwargs!==null&&Array.isArray(e.kwargs)===!1&&t(e.kwargs)),t=e=>Object.keys(e).every(o=>(e[o]===void 0,!0)),s=(e,o,r=!0)=>[typeof e.topic=="string"&&(1<=e.topic.length||l(r,{path:o+".topic",expected:"string & MinLength<1>",value:e.topic}))||l(r,{path:o+".topic",expected:"(string & MinLength<1>)",value:e.topic}),e.args===void 0||Array.isArray(e.args)||l(r,{path:o+".args",expected:"(Array<unknown> | undefined)",value:e.args}),e.kwargs===void 0||(typeof e.kwargs=="object"&&e.kwargs!==null&&Array.isArray(e.kwargs)===!1||l(r,{path:o+".kwargs",expected:"(Record<string, unknown> | undefined)",value:e.kwargs}))&&a(e.kwargs,o+".kwargs",r)||l(r,{path:o+".kwargs",expected:"(Record<string, unknown> | undefined)",value:e.kwargs})].every(i=>i),a=(e,o,r=!0)=>[r===!1||Object.keys(e).map(i=>(e[i]===void 0,!0)).every(i=>i)].every(i=>i),c=e=>typeof e=="object"&&e!==null&&d(e);let n,l;return y(e=>{if(c(e)===!1){n=[],l=m(n),((r,i,u=!0)=>(typeof r=="object"&&r!==null||l(!0,{path:i+"",expected:"PublishParams",value:r}))&&s(r,i+"",!0)||l(!0,{path:i+"",expected:"PublishParams",value:r}))(e,"$input",!0);const o=n.length===0;return o?{success:o,data:e}:{success:o,errors:n,data:e}}return{success:!0,data:e}})})(),p=(()=>{const d=e=>typeof e.deviceKey=="string"&&1<=e.deviceKey.length&&typeof e.topic=="string"&&1<=e.topic.length&&(e.args===void 0||Array.isArray(e.args))&&(e.kwargs===void 0||typeof e.kwargs=="object"&&e.kwargs!==null&&Array.isArray(e.kwargs)===!1&&t(e.kwargs)),t=e=>Object.keys(e).every(o=>(e[o]===void 0,!0)),s=(e,o,r=!0)=>[typeof e.deviceKey=="string"&&(1<=e.deviceKey.length||l(r,{path:o+".deviceKey",expected:"string & MinLength<1>",value:e.deviceKey}))||l(r,{path:o+".deviceKey",expected:"(string & MinLength<1>)",value:e.deviceKey}),typeof e.topic=="string"&&(1<=e.topic.length||l(r,{path:o+".topic",expected:"string & MinLength<1>",value:e.topic}))||l(r,{path:o+".topic",expected:"(string & MinLength<1>)",value:e.topic}),e.args===void 0||Array.isArray(e.args)||l(r,{path:o+".args",expected:"(Array<unknown> | undefined)",value:e.args}),e.kwargs===void 0||(typeof e.kwargs=="object"&&e.kwargs!==null&&Array.isArray(e.kwargs)===!1||l(r,{path:o+".kwargs",expected:"(Record<string, unknown> | undefined)",value:e.kwargs}))&&a(e.kwargs,o+".kwargs",r)||l(r,{path:o+".kwargs",expected:"(Record<string, unknown> | undefined)",value:e.kwargs})].every(i=>i),a=(e,o,r=!0)=>[r===!1||Object.keys(e).map(i=>(e[i]===void 0,!0)).every(i=>i)].every(i=>i),c=e=>typeof e=="object"&&e!==null&&d(e);let n,l;return y(e=>{if(c(e)===!1){n=[],l=m(n),((r,i,u=!0)=>(typeof r=="object"&&r!==null||l(!0,{path:i+"",expected:"CallParams",value:r}))&&s(r,i+"",!0)||l(!0,{path:i+"",expected:"CallParams",value:r}))(e,"$input",!0);const o=n.length===0;return o?{success:o,data:e}:{success:o,errors:n,data:e}}return{success:!0,data:e}})})(),I=(()=>{const d=e=>typeof e.tablename=="string"&&1<=e.tablename.length&&(e.args===void 0||Array.isArray(e.args))&&(e.kwargs===void 0||typeof e.kwargs=="object"&&e.kwargs!==null&&Array.isArray(e.kwargs)===!1&&t(e.kwargs)),t=e=>Object.keys(e).every(o=>(e[o]===void 0,!0)),s=(e,o,r=!0)=>[typeof e.tablename=="string"&&(1<=e.tablename.length||l(r,{path:o+".tablename",expected:"string & MinLength<1>",value:e.tablename}))||l(r,{path:o+".tablename",expected:"(string & MinLength<1>)",value:e.tablename}),e.args===void 0||Array.isArray(e.args)||l(r,{path:o+".args",expected:"(Array<unknown> | undefined)",value:e.args}),e.kwargs===void 0||(typeof e.kwargs=="object"&&e.kwargs!==null&&Array.isArray(e.kwargs)===!1||l(r,{path:o+".kwargs",expected:"(Record<string, unknown> | undefined)",value:e.kwargs}))&&a(e.kwargs,o+".kwargs",r)||l(r,{path:o+".kwargs",expected:"(Record<string, unknown> | undefined)",value:e.kwargs})].every(i=>i),a=(e,o,r=!0)=>[r===!1||Object.keys(e).map(i=>(e[i]===void 0,!0)).every(i=>i)].every(i=>i),c=e=>typeof e=="object"&&e!==null&&d(e);let n,l;return y(e=>{if(c(e)===!1){n=[],l=m(n),((r,i,u=!0)=>(typeof r=="object"&&r!==null||l(!0,{path:i+"",expected:"TableParams",value:r}))&&s(r,i+"",!0)||l(!0,{path:i+"",expected:"TableParams",value:r}))(e,"$input",!0);const o=n.length===0;return o?{success:o,data:e}:{success:o,errors:n,data:e}}return{success:!0,data:e}})})();function D(d){const t=d??process.env.DEVICE_SERIAL_NUMBER;if(!t)throw new Error("DEVICE_SERIAL_NUMBER environment variable is not set and no serialNumber was provided");return t}class U{constructor(t){this._isConfigured=!1,this._serialNumber=D(t==null?void 0:t.serialNumber),this._deviceName=process.env.DEVICE_NAME,this._deviceKey=process.env.DEVICE_KEY,this._appName=process.env.APP_NAME,this._swarmKey=parseInt(process.env.SWARM_KEY??"0",10),this._appKey=parseInt(process.env.APP_KEY??"0",10),this._env=process.env.ENV,this._connection=new A;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(),c={DEV:f.DEVELOPMENT,PROD:f.PRODUCTION}[s]??f.DEVELOPMENT;this._connection.configure(this._swarmKey,this._appKey,c,this._serialNumber,t),this._isConfigured=!0}async start(t){this.configureConnection(t),await this._connection.start()}async stop(){this._connection.stop()}async publish(t,s,a){const c=S({topic:t,args:s,kwargs:a});if(!c.success)throw new Error(`Invalid publish parameters: ${c.errors.map(e=>e.path+": "+e.expected).join(", ")}`);const l={...{DEVICE_SERIAL_NUMBER:this._serialNumber,DEVICE_KEY:this._deviceKey,DEVICE_NAME:this._deviceName},...a??{}};return this._connection.publish(t,s,l,{acknowledge:!0})}async publishToTable(t,s,a){const c=I({tablename:t,args:s,kwargs:a});if(!c.success)throw new Error(`Invalid table parameters: ${c.errors.map(l=>l.path+": "+l.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 n=`${this._swarmKey}.${this._appKey}.${t}`;return this.publish(n,s,a)}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 c=`${this._swarmKey}.${this._appKey}.${t}`;return this.subscribe(c,s,a)}async call(t,s,a,c,n){const l=p({deviceKey:t,topic:s,args:a,kwargs:c});if(!l.success)throw new Error(`Invalid call parameters: ${l.errors.map(o=>o.path+": "+o.expected).join(", ")}`);const e=`${t}.${s}`;return this._connection.call(e,a,c,n)}async registerFunction(t,s,a){const c=`${this._swarmKey}.${this._deviceKey}.${this._appKey}.${this._env}.${t}`,n=await this._connection.register(c,s);return console.log(`Function registered for IronFlock topic '${t}'. (Full WAMP topic: '${c}')`),n}async register(t,s,a){return this.registerFunction(t,s,a)}async getHistory(t,s={limit:10}){if(!t)throw new Error("Tablename must not be empty!");const a=M(s);if(!a.success)throw new Error(`Invalid query parameters: ${a.errors.map(n=>n.path+": "+n.expected).join(", ")}`);const c=`history.transformed.app.${this._appKey}.${t}`;try{return await this._connection.call(c,[s])}catch(n){const l=String(n);return l.includes("no_such_procedure")||l.includes("no callee registered")?(console.error(`Get history failed: History service procedure '${c}' not registered`),null):(console.error(`Get history failed: ${n}`),null)}}async setDeviceLocation(t,s){const a=_({longitude:t,latitude:s});if(!a.success)throw new Error(`Invalid location parameters: ${a.errors.map(l=>l.path+": "+l.expected).join(", ")}`);const c={long:t,lat:s},n={DEVICE_SERIAL_NUMBER:this._serialNumber,DEVICE_KEY:this._deviceKey,DEVICE_NAME:this._deviceName};try{return await this._connection.call("ironflock.location_service.update",[c],n)}catch(l){return console.error(`Set location failed: ${l}`),null}}getRemoteAccessUrlForPort(t){return this._deviceKey&&this._appName?`https://${this._deviceKey}-${this._appName.toLowerCase()}-${t}.app.ironflock.com`:null}}exports.CrossbarConnection=A;exports.IronFlock=U;exports.Stage=f;exports.validateCallParams=p;exports.validateLocationParams=_;exports.validatePublishParams=S;exports.validateTableParams=I;exports.validateTableQueryParams=M;
|
|
3
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.cjs","sources":["../src/crossbar/index.ts","../node_modules/typia/lib/internal/_isTypeUint32.mjs","../node_modules/typia/lib/internal/_isFormatDateTime.mjs","../node_modules/typia/lib/internal/_validateReport.mjs","../node_modules/typia/lib/internal/_createStandardSchema.mjs","../src/types.ts","../src/ironflock.ts"],"sourcesContent":["import autobahn from \"autobahn\";\nimport { EventEmitter } from \"events\";\nimport { Stage } from \"../types\";\n\nexport type Details = { caller_authid: string; caller_authrole: string };\n\nexport type AuthPayload = {\n success: boolean;\n role: string;\n realm: string;\n authid: string;\n extra: {\n username: string;\n };\n};\n\nconst DATAPODS_WS_URI = \"wss://cbw.datapods.io/ws-ua-usr\";\nconst STUDIO_WS_URI = \"wss://cbw.ironflock.com/ws-ua-usr\";\nconst STUDIO_DEV_WS_URI = \"wss://cbw.ironflock.dev/ws-ua-usr\";\nconst STUDIO_WS_URI_OLD = \"wss://cbw.record-evolution.com/ws-ua-usr\";\nconst LOCALHOST_WS_URI = \"ws://localhost:8080/ws-ua-usr\";\n\nconst socketURIMap: Record<string, string> = {\n \"https://studio.datapods.io\": DATAPODS_WS_URI,\n \"https://studio.ironflock.dev\": STUDIO_DEV_WS_URI,\n \"https://studio.ironflock.com\": STUDIO_WS_URI,\n \"https://studio.record-evolution.com\": STUDIO_WS_URI_OLD,\n \"http://localhost:8085\": LOCALHOST_WS_URI,\n \"http://localhost:8086\": LOCALHOST_WS_URI,\n \"http://host.docker.internal:8086\": LOCALHOST_WS_URI,\n};\n\nconst SESSION_WAIT_TIMEOUT = 6000;\n\nexport class CrossbarConnection extends EventEmitter {\n session?: autobahn.Session;\n connection?: autobahn.Connection;\n serial_number?: string;\n socketURI?: string;\n realm?: string;\n\n private subscriptions: autobahn.Subscription[] = [];\n private registrations: autobahn.Registration[] = [];\n private firstConnection?: Promise<void>;\n private firstResolver: () => void = () => undefined;\n private firstRejecter: (reason?: any) => void = () => undefined;\n\n constructor() {\n super();\n }\n\n static getWebSocketURI(): string {\n const reswarmUrl = process.env.RESWARM_URL;\n if (!reswarmUrl) return STUDIO_WS_URI;\n return socketURIMap[reswarmUrl] ?? STUDIO_WS_URI;\n }\n\n configure(\n swarmKey: number,\n appKey: number,\n stage: Stage,\n serialNumber: string,\n cburl?: string\n ) {\n this.realm = `realm-${swarmKey}-${appKey}-${stage}`;\n this.serial_number = serialNumber;\n this.socketURI = cburl ?? CrossbarConnection.getWebSocketURI();\n }\n\n async start(): Promise<void> {\n if (!this.realm || !this.serial_number || !this.socketURI) {\n throw new Error(\"CrossbarConnection must be configured before starting. Call configure() first.\");\n }\n\n this.firstConnection = new Promise((resolve, reject) => {\n this.firstResolver = resolve;\n this.firstRejecter = reject;\n });\n\n this.connection = new autobahn.Connection({\n realm: this.realm,\n url: this.socketURI,\n authmethods: [\"wampcra\"],\n authid: this.serial_number,\n max_retries: -1,\n max_retry_delay: 2,\n initial_retry_delay: 1,\n // @ts-ignore\n autoping_interval: 2,\n autoping_timeout: 4,\n onchallenge: (_session, _method, extra) => {\n return autobahn.auth_cra.sign(this.serial_number!, extra.challenge);\n },\n });\n\n this.connection.onopen = this.onOpen.bind(this);\n this.connection.onclose = this.onClose.bind(this);\n this.connection.open();\n\n return this.firstConnection;\n }\n\n private onOpen(session: autobahn.Session) {\n this.session = session;\n this.session.caller_disclose_me = true;\n\n this.resubscribeAll();\n this.emit(\"connected\", this.serial_number);\n\n this.firstResolver();\n this.firstResolver = () => undefined;\n }\n\n private onClose(reason: string, details: any): boolean {\n this.session = undefined;\n this.emit(\"disconnected\");\n\n this.firstRejecter(\n new Error(\n `Connection failed: ${reason} - ${JSON.stringify(details, null, 2)}`\n )\n );\n this.firstRejecter = () => undefined;\n\n console.warn(\"Connection closed:\", {\n reason,\n details,\n realm: this.realm,\n url: this.socketURI,\n authid: this.serial_number,\n });\n\n // return false to let autobahn handle auto-reconnect\n return false;\n }\n\n private async sessionWait() {\n const startTime = Date.now();\n while (!this.session) {\n if (Date.now() - startTime > SESSION_WAIT_TIMEOUT) {\n throw new Error(\"Timeout waiting for session\");\n }\n await new Promise((resolve) => setTimeout(resolve, 200));\n }\n }\n\n async waitForConnection() {\n return this.firstConnection;\n }\n\n getSession() {\n return this.session;\n }\n\n get is_open(): boolean {\n return !!this.session?.isOpen;\n }\n\n isConnected() {\n return this.is_open;\n }\n\n stop() {\n this.connection?.close(\"wamp.close.normal\", \"Connection closed by client\");\n }\n\n async subscribe(\n topic: string,\n handler: autobahn.SubscribeHandler\n ): Promise<autobahn.Subscription | undefined> {\n await this.sessionWait();\n const sub = await this.session?.subscribe(topic, handler);\n if (sub) {\n this.subscriptions.push(sub);\n }\n return sub;\n }\n\n async unsubscribe(sub: autobahn.Subscription) {\n await this.sessionWait();\n const idx = this.subscriptions.indexOf(sub);\n if (idx !== -1) {\n this.subscriptions.splice(idx, 1);\n await this.session?.unsubscribe(sub);\n }\n }\n\n async unsubscribeTopic(topic: string) {\n const matching = this.subscriptions.filter((sub) => sub.topic === topic);\n for (const sub of matching) {\n await this.unsubscribe(sub);\n }\n }\n\n private async resubscribeAll() {\n const previous = [...this.subscriptions];\n this.subscriptions = [];\n await Promise.all(\n previous.map((sub) => this.subscribe(sub.topic, sub.handler))\n );\n }\n\n async register(\n topic: string,\n endpoint: autobahn.RegisterEndpoint\n ): Promise<autobahn.IRegistration | undefined> {\n await this.sessionWait();\n const registration = await this.session?.register(topic, endpoint);\n if (registration) {\n this.registrations.push(registration);\n }\n return registration;\n }\n\n async unregister(registration: autobahn.Registration) {\n await this.sessionWait();\n await this.session?.unregister(registration);\n const idx = this.registrations.indexOf(registration);\n if (idx !== -1) {\n this.registrations.splice(idx, 1);\n }\n }\n\n async call<T>(\n procedure: string,\n args?: any[],\n kwargs?: object,\n options?: any\n ) {\n await this.sessionWait();\n return this.session?.call<T>(procedure, args, kwargs, options);\n }\n\n async publish(\n topic: string,\n args?: any[],\n kwargs?: object,\n options?: any\n ) {\n await this.sessionWait();\n return this.session?.publish(topic, args, kwargs, options);\n }\n}\n","const _isTypeUint32 = (value) => Math.floor(value) === value && MINIMUM <= value && value <= MAXIMUM;\nconst MINIMUM = 0;\nconst MAXIMUM = 2 ** 32 - 1;\n\nexport { _isTypeUint32 };\n//# sourceMappingURL=_isTypeUint32.mjs.map\n","const _isFormatDateTime = (str) => PATTERN.test(str);\nconst PATTERN = /^[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;\n\nexport { _isFormatDateTime };\n//# sourceMappingURL=_isFormatDateTime.mjs.map\n","const _validateReport = (array) => {\n const reportable = (path) => {\n if (array.length === 0)\n return true;\n const last = array[array.length - 1].path;\n return path.length > last.length || last.substring(0, path.length) !== path;\n };\n return (exceptable, error) => {\n if (exceptable && reportable(error.path)) {\n if (error.value === undefined)\n error.description ??= [\n \"The value at this path is `undefined`.\",\n \"\",\n `Please fill the \\`${error.expected}\\` typed value next time.`,\n ].join(\"\\n\");\n array.push(error);\n }\n return false;\n };\n};\n\nexport { _validateReport };\n//# sourceMappingURL=_validateReport.mjs.map\n","const _createStandardSchema = (fn) => Object.assign(fn, {\n \"~standard\": {\n version: 1,\n vendor: \"typia\",\n validate: (input) => {\n const result = fn(input);\n if (result.success) {\n return {\n value: result.data,\n };\n }\n else {\n return {\n issues: result.errors.map((error) => ({\n message: `expected ${error.expected}, got ${error.value}`,\n path: typiaPathToStandardSchemaPath(error.path),\n })),\n };\n }\n },\n },\n});\nvar PathParserState;\n(function (PathParserState) {\n // Start of a new segment\n // When the parser is in this state,\n // the pointer must point `.` or `[` or equal to length of the path\n PathParserState[PathParserState[\"Start\"] = 0] = \"Start\";\n // Parsing a property key (`.hoge`)\n PathParserState[PathParserState[\"Property\"] = 1] = \"Property\";\n // Parsing a string key (`[\"fuga\"]`)\n PathParserState[PathParserState[\"StringKey\"] = 2] = \"StringKey\";\n // Parsing a number key (`[42]`)\n PathParserState[PathParserState[\"NumberKey\"] = 3] = \"NumberKey\";\n})(PathParserState || (PathParserState = {}));\nconst typiaPathToStandardSchemaPath = (path) => {\n if (!path.startsWith(\"$input\")) {\n throw new Error(`Invalid path: ${JSON.stringify(path)}`);\n }\n const segments = [];\n let currentSegment = \"\";\n let state = PathParserState.Start;\n let index = \"$input\".length - 1;\n while (index < path.length - 1) {\n index++;\n const char = path[index];\n if (state === PathParserState.Property) {\n if (char === \".\" || char === \"[\") {\n // End of property\n segments.push({\n key: currentSegment,\n });\n state = PathParserState.Start;\n }\n else if (index === path.length - 1) {\n // End of path\n currentSegment += char;\n segments.push({\n key: currentSegment,\n });\n index++;\n state = PathParserState.Start;\n }\n else {\n currentSegment += char;\n }\n }\n else if (state === PathParserState.StringKey) {\n if (char === '\"') {\n // End of string key\n segments.push({\n key: JSON.parse(currentSegment + char),\n });\n // Skip `\"` and `]`\n index += 2;\n state = PathParserState.Start;\n }\n else if (char === \"\\\\\") {\n // Skip the next character from parsing\n currentSegment += path[index];\n index++;\n currentSegment += path[index];\n }\n else {\n currentSegment += char;\n }\n }\n else if (state === PathParserState.NumberKey) {\n if (char === \"]\") {\n // End of number key\n segments.push({\n key: Number.parseInt(currentSegment),\n });\n index++;\n state = PathParserState.Start;\n }\n else {\n currentSegment += char;\n }\n }\n if (state === PathParserState.Start && index < path.length - 1) {\n const newChar = path[index];\n currentSegment = \"\";\n if (newChar === \"[\") {\n if (path[index + 1] === '\"') {\n // Start of string key\n // NOTE: Typia uses JSON.stringify for this kind of keys, so `'` will not used as a string delimiter\n state = PathParserState.StringKey;\n index++;\n currentSegment = '\"';\n }\n else {\n // Start of number key\n state = PathParserState.NumberKey;\n }\n }\n else if (newChar === \".\") {\n // Start of property\n state = PathParserState.Property;\n }\n else {\n throw new Error(\"Unreachable: pointer points invalid character\");\n }\n }\n }\n if (state !== PathParserState.Start) {\n throw new Error(`Failed to parse path: ${JSON.stringify(path)}`);\n }\n return segments;\n};\n\nexport { _createStandardSchema };\n//# sourceMappingURL=_createStandardSchema.mjs.map\n","import typia, { tags } from \"typia\";\n\nexport enum Stage {\n DEVELOPMENT = \"dev\",\n PRODUCTION = \"prod\",\n}\n\nexport interface ISOTimeRange {\n start: string & tags.Format<\"date-time\">;\n end: string & tags.Format<\"date-time\">;\n}\n\nexport interface SQLFilterAnd {\n column: string & tags.MinLength<1>;\n operator: string & tags.MinLength<1>;\n value: string | number | boolean | Array<string | number>;\n}\n\nexport interface TableQueryParams {\n limit: number & tags.Type<\"uint32\"> & tags.Minimum<1> & tags.Maximum<10000>;\n offset?: number & tags.Type<\"uint32\"> & tags.Minimum<0>;\n timeRange?: ISOTimeRange;\n filterAnd?: SQLFilterAnd[];\n}\n\nexport interface LocationParams {\n longitude: number & tags.Minimum<-180> & tags.Maximum<180>;\n latitude: number & tags.Minimum<-90> & tags.Maximum<90>;\n}\n\nexport interface PublishParams {\n topic: string & tags.MinLength<1>;\n args?: unknown[];\n kwargs?: Record<string, unknown>;\n}\n\nexport interface CallParams {\n deviceKey: string & tags.MinLength<1>;\n topic: string & tags.MinLength<1>;\n args?: unknown[];\n kwargs?: Record<string, unknown>;\n}\n\nexport interface TableParams {\n tablename: string & tags.MinLength<1>;\n args?: unknown[];\n kwargs?: Record<string, unknown>;\n}\n\nexport const validateTableQueryParams = typia.createValidate<TableQueryParams>();\nexport const validateLocationParams = typia.createValidate<LocationParams>();\nexport const validatePublishParams = typia.createValidate<PublishParams>();\nexport const validateCallParams = typia.createValidate<CallParams>();\nexport const validateTableParams = typia.createValidate<TableParams>();\n","import { CrossbarConnection } from \"./crossbar\";\nimport {\n Stage,\n validatePublishParams,\n validateCallParams,\n validateTableParams,\n validateLocationParams,\n validateTableQueryParams,\n type TableQueryParams,\n} from \"./types\";\n\nfunction getSerialNumber(serialNumber?: string): string {\n const sn = serialNumber ?? process.env.DEVICE_SERIAL_NUMBER;\n if (!sn) {\n throw new Error(\"DEVICE_SERIAL_NUMBER environment variable is not set and no serialNumber was provided\");\n }\n return sn;\n}\n\nexport interface IronFlockOptions {\n serialNumber?: string;\n}\n\nexport class IronFlock {\n private _connection: CrossbarConnection;\n private _serialNumber: string;\n private _deviceName?: string;\n private _deviceKey?: string;\n private _appName?: string;\n private _swarmKey: number;\n private _appKey: number;\n private _env?: string;\n private _isConfigured = false;\n\n constructor(options?: IronFlockOptions) {\n this._serialNumber = getSerialNumber(options?.serialNumber);\n this._deviceName = process.env.DEVICE_NAME;\n this._deviceKey = process.env.DEVICE_KEY;\n this._appName = process.env.APP_NAME;\n this._swarmKey = parseInt(process.env.SWARM_KEY ?? \"0\", 10);\n this._appKey = parseInt(process.env.APP_KEY ?? \"0\", 10);\n this._env = process.env.ENV;\n this._connection = new CrossbarConnection();\n\n const missing: string[] = [];\n if (!this._deviceKey) missing.push(\"DEVICE_KEY\");\n if (!this._appName) missing.push(\"APP_NAME\");\n if (!this._swarmKey) missing.push(\"SWARM_KEY\");\n if (!this._appKey) missing.push(\"APP_KEY\");\n if (missing.length > 0) {\n console.warn(\n `Warning: The following environment variables must be present: ${missing.join(\", \")}`\n );\n }\n }\n\n get connection(): CrossbarConnection {\n return this._connection;\n }\n\n get isConnected(): boolean {\n return this._connection.is_open;\n }\n\n private configureConnection(cburl?: string) {\n if (this._isConfigured) return;\n\n const envValue = (this._env ?? \"DEV\").toUpperCase();\n const stageMap: Record<string, Stage> = {\n DEV: Stage.DEVELOPMENT,\n PROD: Stage.PRODUCTION,\n };\n const stage = stageMap[envValue] ?? Stage.DEVELOPMENT;\n\n this._connection.configure(\n this._swarmKey,\n this._appKey,\n stage,\n this._serialNumber,\n cburl\n );\n this._isConfigured = true;\n }\n\n async start(cburl?: string): Promise<void> {\n this.configureConnection(cburl);\n await this._connection.start();\n }\n\n async stop(): Promise<void> {\n this._connection.stop();\n }\n\n async publish(\n topic: string,\n args?: unknown[],\n kwargs?: Record<string, unknown>\n ): Promise<unknown> {\n const validation = validatePublishParams({ topic, args, kwargs });\n if (!validation.success) {\n throw new Error(`Invalid publish parameters: ${validation.errors.map(e => e.path + \": \" + e.expected).join(\", \")}`);\n }\n\n const deviceMetadata: Record<string, unknown> = {\n DEVICE_SERIAL_NUMBER: this._serialNumber,\n DEVICE_KEY: this._deviceKey,\n DEVICE_NAME: this._deviceName,\n };\n const combinedKwargs = { ...deviceMetadata, ...(kwargs ?? {}) };\n\n return this._connection.publish(topic, args, combinedKwargs, {\n acknowledge: true,\n });\n }\n\n async publishToTable(\n tablename: string,\n args?: unknown[],\n kwargs?: Record<string, unknown>\n ): Promise<unknown> {\n const validation = validateTableParams({ tablename, args, kwargs });\n if (!validation.success) {\n throw new Error(`Invalid table parameters: ${validation.errors.map(e => e.path + \": \" + e.expected).join(\", \")}`);\n }\n\n if (!this._swarmKey) throw new Error(\"SWARM_KEY not set in environment variables!\");\n if (!this._appKey) throw new Error(\"APP_KEY not set in environment variables!\");\n\n const topic = `${this._swarmKey}.${this._appKey}.${tablename}`;\n return this.publish(topic, args, kwargs);\n }\n\n async subscribe(\n topic: string,\n handler: (...args: any[]) => void,\n options?: object\n ) {\n return this._connection.subscribe(topic, handler);\n }\n\n async subscribeToTable(\n tablename: string,\n handler: (...args: any[]) => void,\n options?: object\n ) {\n if (!this._swarmKey) throw new Error(\"SWARM_KEY not set in environment variables!\");\n if (!this._appKey) throw new Error(\"APP_KEY not set in environment variables!\");\n\n const topic = `${this._swarmKey}.${this._appKey}.${tablename}`;\n return this.subscribe(topic, handler, options);\n }\n\n async call(\n deviceKey: string,\n topic: string,\n args?: unknown[],\n kwargs?: Record<string, unknown>,\n options?: object\n ) {\n const validation = validateCallParams({ deviceKey, topic, args, kwargs });\n if (!validation.success) {\n throw new Error(`Invalid call parameters: ${validation.errors.map(e => e.path + \": \" + e.expected).join(\", \")}`);\n }\n\n const callTopic = `${deviceKey}.${topic}`;\n return this._connection.call(callTopic, args as any[], kwargs, options);\n }\n\n async registerFunction(\n topic: string,\n endpoint: (...args: any[]) => any,\n options?: object\n ) {\n const fullTopic = `${this._swarmKey}.${this._deviceKey}.${this._appKey}.${this._env}.${topic}`;\n\n const reg = await this._connection.register(fullTopic, endpoint);\n console.log(`Function registered for IronFlock topic '${topic}'. (Full WAMP topic: '${fullTopic}')`);\n return reg;\n }\n\n async register(\n topic: string,\n endpoint: (...args: any[]) => any,\n options?: object\n ) {\n return this.registerFunction(topic, endpoint, options);\n }\n\n async getHistory(\n tablename: string,\n queryParams: TableQueryParams = { limit: 10 }\n ) {\n if (!tablename) throw new Error(\"Tablename must not be empty!\");\n\n const validation = validateTableQueryParams(queryParams);\n if (!validation.success) {\n throw new Error(`Invalid query parameters: ${validation.errors.map(e => e.path + \": \" + e.expected).join(\", \")}`);\n }\n\n const topic = `history.transformed.app.${this._appKey}.${tablename}`;\n try {\n return await this._connection.call(topic, [queryParams]);\n } catch (e: any) {\n const errorStr = String(e);\n if (\n errorStr.includes(\"no_such_procedure\") ||\n errorStr.includes(\"no callee registered\")\n ) {\n console.error(`Get history failed: History service procedure '${topic}' not registered`);\n return null;\n }\n console.error(`Get history failed: ${e}`);\n return null;\n }\n }\n\n async setDeviceLocation(long: number, lat: number) {\n const validation = validateLocationParams({ longitude: long, latitude: lat });\n if (!validation.success) {\n throw new Error(`Invalid location parameters: ${validation.errors.map(e => e.path + \": \" + e.expected).join(\", \")}`);\n }\n\n const payload = { long, lat };\n const extra: Record<string, unknown> = {\n DEVICE_SERIAL_NUMBER: this._serialNumber,\n DEVICE_KEY: this._deviceKey,\n DEVICE_NAME: this._deviceName,\n };\n\n try {\n return await this._connection.call(\n \"ironflock.location_service.update\",\n [payload],\n extra\n );\n } catch (e) {\n console.error(`Set location failed: ${e}`);\n return null;\n }\n }\n\n getRemoteAccessUrlForPort(port: number): string | null {\n if (this._deviceKey && this._appName) {\n return `https://${this._deviceKey}-${this._appName.toLowerCase()}-${port}.app.ironflock.com`;\n }\n return null;\n }\n}\n"],"names":["DATAPODS_WS_URI","STUDIO_WS_URI","STUDIO_DEV_WS_URI","STUDIO_WS_URI_OLD","LOCALHOST_WS_URI","socketURIMap","SESSION_WAIT_TIMEOUT","CrossbarConnection","EventEmitter","reswarmUrl","swarmKey","appKey","stage","serialNumber","cburl","resolve","reject","autobahn","_session","_method","extra","session","reason","details","startTime","_a","topic","handler","sub","idx","matching","previous","endpoint","registration","procedure","args","kwargs","options","_isTypeUint32","value","MINIMUM","MAXIMUM","_isFormatDateTime","str","PATTERN","_validateReport","array","reportable","path","last","exceptable","error","_createStandardSchema","fn","input","result","typiaPathToStandardSchemaPath","PathParserState","segments","currentSegment","state","index","char","newChar","Stage","validateTableQueryParams","_io0","__typia_transform__isTypeUint32._isTypeUint32","_io1","elem","_io2","__typia_transform__isFormatDateTime._isFormatDateTime","_vo0","_path","_exceptionable","_report","_vo1","_index3","_vo2","flag","_index4","__is","errors","__typia_transform__createStandardSchema._createStandardSchema","__typia_transform__validateReport._validateReport","success","validateLocationParams","validatePublishParams","key","validateCallParams","validateTableParams","getSerialNumber","sn","IronFlock","missing","envValue","validation","combinedKwargs","tablename","e","deviceKey","callTopic","fullTopic","reg","queryParams","errorStr","long","lat","payload","port"],"mappings":"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","x_google_ignoreList":[1,2,3,4]}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,2 +1,146 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
1
|
+
import { default as default_2 } from 'autobahn';
|
|
2
|
+
import { default as default_3 } from 'typia';
|
|
3
|
+
import { EventEmitter } from 'events';
|
|
4
|
+
import { IRegistration } from 'autobahn';
|
|
5
|
+
import { StandardSchemaV1 } from '@standard-schema/spec';
|
|
6
|
+
import { Subscription } from 'autobahn';
|
|
7
|
+
import { tags } from 'typia';
|
|
8
|
+
|
|
9
|
+
export declare type AuthPayload = {
|
|
10
|
+
success: boolean;
|
|
11
|
+
role: string;
|
|
12
|
+
realm: string;
|
|
13
|
+
authid: string;
|
|
14
|
+
extra: {
|
|
15
|
+
username: string;
|
|
16
|
+
};
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
export declare interface CallParams {
|
|
20
|
+
deviceKey: string & tags.MinLength<1>;
|
|
21
|
+
topic: string & tags.MinLength<1>;
|
|
22
|
+
args?: unknown[];
|
|
23
|
+
kwargs?: Record<string, unknown>;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export declare class CrossbarConnection extends EventEmitter {
|
|
27
|
+
session?: default_2.Session;
|
|
28
|
+
connection?: default_2.Connection;
|
|
29
|
+
serial_number?: string;
|
|
30
|
+
socketURI?: string;
|
|
31
|
+
realm?: string;
|
|
32
|
+
private subscriptions;
|
|
33
|
+
private registrations;
|
|
34
|
+
private firstConnection?;
|
|
35
|
+
private firstResolver;
|
|
36
|
+
private firstRejecter;
|
|
37
|
+
constructor();
|
|
38
|
+
static getWebSocketURI(): string;
|
|
39
|
+
configure(swarmKey: number, appKey: number, stage: Stage, serialNumber: string, cburl?: string): void;
|
|
40
|
+
start(): Promise<void>;
|
|
41
|
+
private onOpen;
|
|
42
|
+
private onClose;
|
|
43
|
+
private sessionWait;
|
|
44
|
+
waitForConnection(): Promise<void | undefined>;
|
|
45
|
+
getSession(): default_2.Session | undefined;
|
|
46
|
+
get is_open(): boolean;
|
|
47
|
+
isConnected(): boolean;
|
|
48
|
+
stop(): void;
|
|
49
|
+
subscribe(topic: string, handler: default_2.SubscribeHandler): Promise<default_2.Subscription | undefined>;
|
|
50
|
+
unsubscribe(sub: default_2.Subscription): Promise<void>;
|
|
51
|
+
unsubscribeTopic(topic: string): Promise<void>;
|
|
52
|
+
private resubscribeAll;
|
|
53
|
+
register(topic: string, endpoint: default_2.RegisterEndpoint): Promise<default_2.IRegistration | undefined>;
|
|
54
|
+
unregister(registration: default_2.Registration): Promise<void>;
|
|
55
|
+
call<T>(procedure: string, args?: any[], kwargs?: object, options?: any): Promise<T | undefined>;
|
|
56
|
+
publish(topic: string, args?: any[], kwargs?: object, options?: any): Promise<default_2.IPublication | undefined>;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export declare type Details = {
|
|
60
|
+
caller_authid: string;
|
|
61
|
+
caller_authrole: string;
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
export declare class IronFlock {
|
|
65
|
+
private _connection;
|
|
66
|
+
private _serialNumber;
|
|
67
|
+
private _deviceName?;
|
|
68
|
+
private _deviceKey?;
|
|
69
|
+
private _appName?;
|
|
70
|
+
private _swarmKey;
|
|
71
|
+
private _appKey;
|
|
72
|
+
private _env?;
|
|
73
|
+
private _isConfigured;
|
|
74
|
+
constructor(options?: IronFlockOptions);
|
|
75
|
+
get connection(): CrossbarConnection;
|
|
76
|
+
get isConnected(): boolean;
|
|
77
|
+
private configureConnection;
|
|
78
|
+
start(cburl?: string): Promise<void>;
|
|
79
|
+
stop(): Promise<void>;
|
|
80
|
+
publish(topic: string, args?: unknown[], kwargs?: Record<string, unknown>): Promise<unknown>;
|
|
81
|
+
publishToTable(tablename: string, args?: unknown[], kwargs?: Record<string, unknown>): Promise<unknown>;
|
|
82
|
+
subscribe(topic: string, handler: (...args: any[]) => void, options?: object): Promise<Subscription<any[], any, string> | undefined>;
|
|
83
|
+
subscribeToTable(tablename: string, handler: (...args: any[]) => void, options?: object): Promise<Subscription<any[], any, string> | undefined>;
|
|
84
|
+
call(deviceKey: string, topic: string, args?: unknown[], kwargs?: Record<string, unknown>, options?: object): Promise<unknown>;
|
|
85
|
+
registerFunction(topic: string, endpoint: (...args: any[]) => any, options?: object): Promise<IRegistration<any, any[], any, string> | undefined>;
|
|
86
|
+
register(topic: string, endpoint: (...args: any[]) => any, options?: object): Promise<IRegistration<any, any[], any, string> | undefined>;
|
|
87
|
+
getHistory(tablename: string, queryParams?: TableQueryParams): Promise<unknown>;
|
|
88
|
+
setDeviceLocation(long: number, lat: number): Promise<unknown>;
|
|
89
|
+
getRemoteAccessUrlForPort(port: number): string | null;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
export declare interface IronFlockOptions {
|
|
93
|
+
serialNumber?: string;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
export declare interface ISOTimeRange {
|
|
97
|
+
start: string & tags.Format<"date-time">;
|
|
98
|
+
end: string & tags.Format<"date-time">;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
export declare interface LocationParams {
|
|
102
|
+
longitude: number & tags.Minimum<-180> & tags.Maximum<180>;
|
|
103
|
+
latitude: number & tags.Minimum<-90> & tags.Maximum<90>;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
export declare interface PublishParams {
|
|
107
|
+
topic: string & tags.MinLength<1>;
|
|
108
|
+
args?: unknown[];
|
|
109
|
+
kwargs?: Record<string, unknown>;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
export declare interface SQLFilterAnd {
|
|
113
|
+
column: string & tags.MinLength<1>;
|
|
114
|
+
operator: string & tags.MinLength<1>;
|
|
115
|
+
value: string | number | boolean | Array<string | number>;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
export declare enum Stage {
|
|
119
|
+
DEVELOPMENT = "dev",
|
|
120
|
+
PRODUCTION = "prod"
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
export declare interface TableParams {
|
|
124
|
+
tablename: string & tags.MinLength<1>;
|
|
125
|
+
args?: unknown[];
|
|
126
|
+
kwargs?: Record<string, unknown>;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
export declare interface TableQueryParams {
|
|
130
|
+
limit: number & tags.Type<"uint32"> & tags.Minimum<1> & tags.Maximum<10000>;
|
|
131
|
+
offset?: number & tags.Type<"uint32"> & tags.Minimum<0>;
|
|
132
|
+
timeRange?: ISOTimeRange;
|
|
133
|
+
filterAnd?: SQLFilterAnd[];
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
export declare const validateCallParams: ((input: unknown) => default_3.IValidation<CallParams>) & StandardSchemaV1<CallParams, CallParams>;
|
|
137
|
+
|
|
138
|
+
export declare const validateLocationParams: ((input: unknown) => default_3.IValidation<LocationParams>) & StandardSchemaV1<LocationParams, LocationParams>;
|
|
139
|
+
|
|
140
|
+
export declare const validatePublishParams: ((input: unknown) => default_3.IValidation<PublishParams>) & StandardSchemaV1<PublishParams, PublishParams>;
|
|
141
|
+
|
|
142
|
+
export declare const validateTableParams: ((input: unknown) => default_3.IValidation<TableParams>) & StandardSchemaV1<TableParams, TableParams>;
|
|
143
|
+
|
|
144
|
+
export declare const validateTableQueryParams: ((input: unknown) => default_3.IValidation<TableQueryParams>) & StandardSchemaV1<TableQueryParams, TableQueryParams>;
|
|
145
|
+
|
|
146
|
+
export { }
|