@butlr/butlr-mcp-server 0.1.1 → 0.2.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/LICENSE +1 -1
- package/README.md +28 -2
- package/dist/cache/occupancy-cache.d.ts.map +1 -1
- package/dist/cache/occupancy-cache.js +9 -20
- package/dist/cache/occupancy-cache.js.map +1 -1
- package/dist/cache/topology-cache.d.ts.map +1 -1
- package/dist/cache/topology-cache.js +7 -10
- package/dist/cache/topology-cache.js.map +1 -1
- package/dist/clients/auth-client.d.ts.map +1 -1
- package/dist/clients/auth-client.js +5 -9
- package/dist/clients/auth-client.js.map +1 -1
- package/dist/clients/graphql-client.d.ts.map +1 -1
- package/dist/clients/graphql-client.js +5 -4
- package/dist/clients/graphql-client.js.map +1 -1
- package/dist/clients/queries/tags.d.ts +39 -0
- package/dist/clients/queries/tags.d.ts.map +1 -0
- package/dist/clients/queries/tags.js +42 -0
- package/dist/clients/queries/tags.js.map +1 -0
- package/dist/clients/queries/topology.d.ts +0 -1
- package/dist/clients/queries/topology.d.ts.map +1 -1
- package/dist/clients/queries/topology.js +0 -1
- package/dist/clients/queries/topology.js.map +1 -1
- package/dist/clients/reporting-client.d.ts +1 -1
- package/dist/clients/reporting-client.d.ts.map +1 -1
- package/dist/clients/reporting-client.js +10 -14
- package/dist/clients/reporting-client.js.map +1 -1
- package/dist/clients/stats-client.d.ts +1 -2
- package/dist/clients/stats-client.d.ts.map +1 -1
- package/dist/clients/stats-client.js +7 -11
- package/dist/clients/stats-client.js.map +1 -1
- package/dist/clients/types.d.ts +2 -3
- package/dist/clients/types.d.ts.map +1 -1
- package/dist/clients/types.js +0 -1
- package/dist/clients/types.js.map +1 -1
- package/dist/errors/mcp-errors.d.ts +6 -0
- package/dist/errors/mcp-errors.d.ts.map +1 -1
- package/dist/errors/mcp-errors.js +21 -1
- package/dist/errors/mcp-errors.js.map +1 -1
- package/dist/index.js +8 -5
- package/dist/index.js.map +1 -1
- package/dist/tools/butlr-available-rooms.d.ts +25 -1
- package/dist/tools/butlr-available-rooms.d.ts.map +1 -1
- package/dist/tools/butlr-available-rooms.js +130 -57
- package/dist/tools/butlr-available-rooms.js.map +1 -1
- package/dist/tools/butlr-fetch-entity-details.d.ts.map +1 -1
- package/dist/tools/butlr-fetch-entity-details.js +14 -14
- package/dist/tools/butlr-fetch-entity-details.js.map +1 -1
- package/dist/tools/butlr-get-asset-details.d.ts.map +1 -1
- package/dist/tools/butlr-get-asset-details.js +10 -15
- package/dist/tools/butlr-get-asset-details.js.map +1 -1
- package/dist/tools/butlr-get-current-occupancy.d.ts.map +1 -1
- package/dist/tools/butlr-get-current-occupancy.js +27 -12
- package/dist/tools/butlr-get-current-occupancy.js.map +1 -1
- package/dist/tools/butlr-get-occupancy-timeseries.d.ts.map +1 -1
- package/dist/tools/butlr-get-occupancy-timeseries.js +36 -28
- package/dist/tools/butlr-get-occupancy-timeseries.js.map +1 -1
- package/dist/tools/butlr-hardware-snapshot.d.ts.map +1 -1
- package/dist/tools/butlr-hardware-snapshot.js +7 -9
- package/dist/tools/butlr-hardware-snapshot.js.map +1 -1
- package/dist/tools/butlr-list-tags.d.ts +32 -0
- package/dist/tools/butlr-list-tags.d.ts.map +1 -0
- package/dist/tools/butlr-list-tags.js +108 -0
- package/dist/tools/butlr-list-tags.js.map +1 -0
- package/dist/tools/butlr-list-topology.d.ts.map +1 -1
- package/dist/tools/butlr-list-topology.js +20 -26
- package/dist/tools/butlr-list-topology.js.map +1 -1
- package/dist/tools/butlr-search-assets.d.ts.map +1 -1
- package/dist/tools/butlr-search-assets.js +19 -31
- package/dist/tools/butlr-search-assets.js.map +1 -1
- package/dist/tools/butlr-space-busyness.d.ts.map +1 -1
- package/dist/tools/butlr-space-busyness.js +27 -22
- package/dist/tools/butlr-space-busyness.js.map +1 -1
- package/dist/tools/butlr-traffic-flow.d.ts.map +1 -1
- package/dist/tools/butlr-traffic-flow.js +17 -31
- package/dist/tools/butlr-traffic-flow.js.map +1 -1
- package/dist/types/responses.d.ts +4 -0
- package/dist/types/responses.d.ts.map +1 -1
- package/dist/utils/asset-flattener.js +2 -2
- package/dist/utils/asset-flattener.js.map +1 -1
- package/dist/utils/debug.d.ts +6 -0
- package/dist/utils/debug.d.ts.map +1 -0
- package/dist/utils/debug.js +10 -0
- package/dist/utils/debug.js.map +1 -0
- package/dist/utils/graphql-helpers.d.ts +13 -0
- package/dist/utils/graphql-helpers.d.ts.map +1 -1
- package/dist/utils/graphql-helpers.js +25 -0
- package/dist/utils/graphql-helpers.js.map +1 -1
- package/dist/utils/occupancy-helpers.d.ts +2 -0
- package/dist/utils/occupancy-helpers.d.ts.map +1 -1
- package/dist/utils/occupancy-helpers.js +8 -5
- package/dist/utils/occupancy-helpers.js.map +1 -1
- package/dist/utils/timezone-helpers.d.ts +8 -3
- package/dist/utils/timezone-helpers.d.ts.map +1 -1
- package/dist/utils/timezone-helpers.js +27 -24
- package/dist/utils/timezone-helpers.js.map +1 -1
- package/llms.txt +125 -0
- package/package.json +3 -3
package/LICENSE
CHANGED
package/README.md
CHANGED
|
@@ -18,7 +18,7 @@ A [Model Context Protocol](https://modelcontextprotocol.io) (MCP) server that co
|
|
|
18
18
|
## Prerequisites
|
|
19
19
|
|
|
20
20
|
- [Node.js](https://nodejs.org/) 18 or higher
|
|
21
|
-
- An MCP-compatible client ([Claude Desktop](https://claude.ai/download), [Claude Code](https://docs.anthropic.com/en/docs/claude-code), [VS Code](https://code.visualstudio.com/), [Cursor](https://cursor.com/), etc.)
|
|
21
|
+
- An MCP-compatible client ([Claude Desktop](https://claude.ai/download), [Claude Code](https://docs.anthropic.com/en/docs/claude-code), [Codex CLI](https://developers.openai.com/codex/cli), [VS Code](https://code.visualstudio.com/), [Cursor](https://cursor.com/), etc.)
|
|
22
22
|
- Butlr API token — see [Getting API Credentials](#getting-api-credentials)
|
|
23
23
|
|
|
24
24
|
## Quick Start
|
|
@@ -57,6 +57,32 @@ claude mcp add butlr \
|
|
|
57
57
|
|
|
58
58
|
</details>
|
|
59
59
|
|
|
60
|
+
<details>
|
|
61
|
+
<summary><strong>Codex CLI</strong></summary>
|
|
62
|
+
|
|
63
|
+
Add with the `codex mcp` command:
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
codex mcp add butlr \
|
|
67
|
+
--env BUTLR_CLIENT_ID=your_client_id \
|
|
68
|
+
--env BUTLR_CLIENT_SECRET=your_client_secret \
|
|
69
|
+
-- npx -y @butlr/butlr-mcp-server@latest
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
Or edit `~/.codex/config.toml` directly:
|
|
73
|
+
|
|
74
|
+
```toml
|
|
75
|
+
[mcp_servers.butlr]
|
|
76
|
+
command = "npx"
|
|
77
|
+
args = ["-y", "@butlr/butlr-mcp-server@latest"]
|
|
78
|
+
|
|
79
|
+
[mcp_servers.butlr.env]
|
|
80
|
+
BUTLR_CLIENT_ID = "your_client_id"
|
|
81
|
+
BUTLR_CLIENT_SECRET = "your_client_secret"
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
</details>
|
|
85
|
+
|
|
60
86
|
<details>
|
|
61
87
|
<summary><strong>VS Code (Copilot)</strong></summary>
|
|
62
88
|
|
|
@@ -169,7 +195,7 @@ See [CONTRIBUTING.md](CONTRIBUTING.md) for full development workflow and standar
|
|
|
169
195
|
```bash
|
|
170
196
|
npm install # Install dependencies
|
|
171
197
|
npm run build # Build TypeScript
|
|
172
|
-
npm test # Run tests
|
|
198
|
+
npm test # Run tests
|
|
173
199
|
npm run typecheck # Type checking
|
|
174
200
|
npm run lint # ESLint
|
|
175
201
|
npm run dev # Dev with hot-reload
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"occupancy-cache.d.ts","sourceRoot":"","sources":["../../src/cache/occupancy-cache.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"occupancy-cache.d.ts","sourceRoot":"","sources":["../../src/cache/occupancy-cache.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAUrC,UAAU,mBAAmB;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;;;;;GAMG;AACH,eAAO,MAAM,cAAc,gDAKzB,CAAC;AAEH;;;GAGG;AACH,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,IAAI,GAAG,MAAM,CAanF;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,MAAM,EACf,SAAS,CAAC,EAAE,IAAI,GACf,mBAAmB,GAAG,SAAS,CAcjC;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,CACpC,QAAQ,EAAE,MAAM,EAAE,EAClB,SAAS,CAAC,EAAE,IAAI,GACf;IACD,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,mBAAmB,CAAC,CAAC;IAC1C,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB,CAgBA;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EACjB,SAAS,CAAC,EAAE,IAAI,GACf,IAAI,CAiBN;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,KAAK,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,IAAI,CAAC;CAClB,CAAC,GACD,IAAI,CAMN;AAED;;GAEG;AACH,wBAAgB,mBAAmB,IAAI,IAAI,CAI1C;AAED;;GAEG;AACH,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAa9D;AAED;;GAEG;AACH,wBAAgB,sBAAsB;;;;;EAOrC;AASD,wBAAgB,cAAc,IAAI,IAAI,CAErC;AAED,wBAAgB,eAAe,IAAI,IAAI,CAEtC;AAED,wBAAgB,eAAe,IAAI;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;CACjB,CAOA;AAED,wBAAgB,iBAAiB,IAAI,IAAI,CAGxC"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { LRUCache } from "lru-cache";
|
|
2
|
+
import { debug } from "../utils/debug.js";
|
|
2
3
|
/**
|
|
3
4
|
* Occupancy cache configuration
|
|
4
5
|
* TTL: 60 seconds (fast-changing data)
|
|
@@ -42,15 +43,11 @@ export function getCachedOccupancy(assetId, timestamp) {
|
|
|
42
43
|
// Track cache hit/miss metrics
|
|
43
44
|
if (cached) {
|
|
44
45
|
recordCacheHit();
|
|
45
|
-
|
|
46
|
-
console.error(`[occupancy-cache] Cache HIT for ${assetId}`);
|
|
47
|
-
}
|
|
46
|
+
debug("occupancy-cache", `Cache HIT for ${assetId}`);
|
|
48
47
|
}
|
|
49
48
|
else {
|
|
50
49
|
recordCacheMiss();
|
|
51
|
-
|
|
52
|
-
console.error(`[occupancy-cache] Cache MISS for ${assetId}`);
|
|
53
|
-
}
|
|
50
|
+
debug("occupancy-cache", `Cache MISS for ${assetId}`);
|
|
54
51
|
}
|
|
55
52
|
return cached;
|
|
56
53
|
}
|
|
@@ -70,9 +67,7 @@ export function getBulkCachedOccupancy(assetIds, timestamp) {
|
|
|
70
67
|
misses.push(assetId);
|
|
71
68
|
}
|
|
72
69
|
}
|
|
73
|
-
|
|
74
|
-
console.error(`[occupancy-cache] Bulk query: ${Object.keys(hits).length} hits, ${misses.length} misses`);
|
|
75
|
-
}
|
|
70
|
+
debug("occupancy-cache", `Bulk query: ${Object.keys(hits).length} hits, ${misses.length} misses`);
|
|
76
71
|
return { hits, misses };
|
|
77
72
|
}
|
|
78
73
|
/**
|
|
@@ -88,9 +83,7 @@ export function setCachedOccupancy(assetId, occupancy, assetType, timestamp) {
|
|
|
88
83
|
asset_type: assetType,
|
|
89
84
|
};
|
|
90
85
|
occupancyCache.set(key, entry);
|
|
91
|
-
|
|
92
|
-
console.error(`[occupancy-cache] Cached occupancy for ${assetId}: ${occupancy} (TTL: ${CACHE_TTL_SECONDS / 1000}s)`);
|
|
93
|
-
}
|
|
86
|
+
debug("occupancy-cache", `Cached occupancy for ${assetId}: ${occupancy} (TTL: ${CACHE_TTL_SECONDS / 1000}s)`);
|
|
94
87
|
}
|
|
95
88
|
/**
|
|
96
89
|
* Store multiple occupancy values
|
|
@@ -99,18 +92,14 @@ export function setBulkCachedOccupancy(entries) {
|
|
|
99
92
|
for (const entry of entries) {
|
|
100
93
|
setCachedOccupancy(entry.assetId, entry.occupancy, entry.assetType, entry.timestamp);
|
|
101
94
|
}
|
|
102
|
-
|
|
103
|
-
console.error(`[occupancy-cache] Bulk cached ${entries.length} occupancy values`);
|
|
104
|
-
}
|
|
95
|
+
debug("occupancy-cache", `Bulk cached ${entries.length} occupancy values`);
|
|
105
96
|
}
|
|
106
97
|
/**
|
|
107
98
|
* Clear all cached occupancy data
|
|
108
99
|
*/
|
|
109
100
|
export function clearOccupancyCache() {
|
|
110
101
|
occupancyCache.clear();
|
|
111
|
-
|
|
112
|
-
console.error("[occupancy-cache] Cache cleared");
|
|
113
|
-
}
|
|
102
|
+
debug("occupancy-cache", "Cache cleared");
|
|
114
103
|
}
|
|
115
104
|
/**
|
|
116
105
|
* Invalidate cache for specific asset
|
|
@@ -124,8 +113,8 @@ export function invalidateAssetOccupancy(assetId) {
|
|
|
124
113
|
deleted++;
|
|
125
114
|
}
|
|
126
115
|
}
|
|
127
|
-
if (
|
|
128
|
-
|
|
116
|
+
if (deleted > 0) {
|
|
117
|
+
debug("occupancy-cache", `Invalidated ${deleted} cache entries for ${assetId}`);
|
|
129
118
|
}
|
|
130
119
|
}
|
|
131
120
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"occupancy-cache.js","sourceRoot":"","sources":["../../src/cache/occupancy-cache.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"occupancy-cache.js","sourceRoot":"","sources":["../../src/cache/occupancy-cache.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AACrC,OAAO,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAE1C;;;GAGG;AACH,MAAM,iBAAiB,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,uBAAuB,IAAI,IAAI,EAAE,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC,0BAA0B;AACtH,MAAM,iBAAiB,GAAG,GAAG,CAAC,CAAC,0CAA0C;AASzE;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,IAAI,QAAQ,CAA8B;IACtE,GAAG,EAAE,iBAAiB;IACtB,GAAG,EAAE,iBAAiB;IACtB,cAAc,EAAE,IAAI,EAAE,yBAAyB;IAC/C,cAAc,EAAE,KAAK;CACtB,CAAC,CAAC;AAEH;;;GAGG;AACH,MAAM,UAAU,yBAAyB,CAAC,OAAe,EAAE,SAAgB;IACzE,MAAM,GAAG,GAAG,SAAS,IAAI,IAAI,IAAI,EAAE,CAAC;IAEpC,sCAAsC;IACtC,MAAM,YAAY,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC;IACnC,YAAY,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAE9B,MAAM,SAAS,GAAG,YAAY;SAC3B,WAAW,EAAE;SACb,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC,+BAA+B;SACrD,SAAS,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,eAAe;IAEpC,OAAO,aAAa,OAAO,IAAI,SAAS,EAAE,CAAC;AAC7C,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,kBAAkB,CAChC,OAAe,EACf,SAAgB;IAEhB,MAAM,GAAG,GAAG,yBAAyB,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;IAC1D,MAAM,MAAM,GAAG,cAAc,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAEvC,+BAA+B;IAC/B,IAAI,MAAM,EAAE,CAAC;QACX,cAAc,EAAE,CAAC;QACjB,KAAK,CAAC,iBAAiB,EAAE,iBAAiB,OAAO,EAAE,CAAC,CAAC;IACvD,CAAC;SAAM,CAAC;QACN,eAAe,EAAE,CAAC;QAClB,KAAK,CAAC,iBAAiB,EAAE,kBAAkB,OAAO,EAAE,CAAC,CAAC;IACxD,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,sBAAsB,CACpC,QAAkB,EAClB,SAAgB;IAKhB,MAAM,IAAI,GAAwC,EAAE,CAAC;IACrD,MAAM,MAAM,GAAa,EAAE,CAAC;IAE5B,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;QAC/B,MAAM,MAAM,GAAG,kBAAkB,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;QACtD,IAAI,MAAM,EAAE,CAAC;YACX,IAAI,CAAC,OAAO,CAAC,GAAG,MAAM,CAAC;QACzB,CAAC;aAAM,CAAC;YACN,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACvB,CAAC;IACH,CAAC;IAED,KAAK,CAAC,iBAAiB,EAAE,eAAe,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,MAAM,UAAU,MAAM,CAAC,MAAM,SAAS,CAAC,CAAC;IAElG,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;AAC1B,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,kBAAkB,CAChC,OAAe,EACf,SAAiB,EACjB,SAAiB,EACjB,SAAgB;IAEhB,MAAM,GAAG,GAAG,SAAS,IAAI,IAAI,IAAI,EAAE,CAAC;IACpC,MAAM,GAAG,GAAG,yBAAyB,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;IAEpD,MAAM,KAAK,GAAwB;QACjC,SAAS;QACT,SAAS,EAAE,GAAG,CAAC,WAAW,EAAE;QAC5B,QAAQ,EAAE,OAAO;QACjB,UAAU,EAAE,SAAS;KACtB,CAAC;IAEF,cAAc,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;IAE/B,KAAK,CACH,iBAAiB,EACjB,wBAAwB,OAAO,KAAK,SAAS,UAAU,iBAAiB,GAAG,IAAI,IAAI,CACpF,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,sBAAsB,CACpC,OAKE;IAEF,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC5B,kBAAkB,CAAC,KAAK,CAAC,OAAO,EAAE,KAAK,CAAC,SAAS,EAAE,KAAK,CAAC,SAAS,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC;IACvF,CAAC;IAED,KAAK,CAAC,iBAAiB,EAAE,eAAe,OAAO,CAAC,MAAM,mBAAmB,CAAC,CAAC;AAC7E,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,mBAAmB;IACjC,cAAc,CAAC,KAAK,EAAE,CAAC;IAEvB,KAAK,CAAC,iBAAiB,EAAE,eAAe,CAAC,CAAC;AAC5C,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,wBAAwB,CAAC,OAAe;IACtD,oDAAoD;IACpD,IAAI,OAAO,GAAG,CAAC,CAAC;IAChB,KAAK,MAAM,GAAG,IAAI,cAAc,CAAC,IAAI,EAAE,EAAE,CAAC;QACxC,IAAI,GAAG,CAAC,UAAU,CAAC,aAAa,OAAO,GAAG,CAAC,EAAE,CAAC;YAC5C,cAAc,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YAC3B,OAAO,EAAE,CAAC;QACZ,CAAC;IACH,CAAC;IAED,IAAI,OAAO,GAAG,CAAC,EAAE,CAAC;QAChB,KAAK,CAAC,iBAAiB,EAAE,eAAe,OAAO,sBAAsB,OAAO,EAAE,CAAC,CAAC;IAClF,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,sBAAsB;IACpC,OAAO;QACL,IAAI,EAAE,cAAc,CAAC,IAAI;QACzB,OAAO,EAAE,iBAAiB;QAC1B,GAAG,EAAE,iBAAiB,GAAG,IAAI,EAAE,sCAAsC;QACrE,kBAAkB,EAAE,CAAC,cAAc,CAAC,IAAI,GAAG,iBAAiB,CAAC,GAAG,GAAG;KACpE,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,IAAI,SAAS,GAAG,CAAC,CAAC;AAClB,IAAI,WAAW,GAAG,CAAC,CAAC;AAEpB,MAAM,UAAU,cAAc;IAC5B,SAAS,EAAE,CAAC;AACd,CAAC;AAED,MAAM,UAAU,eAAe;IAC7B,WAAW,EAAE,CAAC;AAChB,CAAC;AAED,MAAM,UAAU,eAAe;IAK7B,MAAM,KAAK,GAAG,SAAS,GAAG,WAAW,CAAC;IACtC,OAAO;QACL,IAAI,EAAE,SAAS;QACf,MAAM,EAAE,WAAW;QACnB,OAAO,EAAE,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,GAAG,KAAK,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC;KACnD,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,iBAAiB;IAC/B,SAAS,GAAG,CAAC,CAAC;IACd,WAAW,GAAG,CAAC,CAAC;AAClB,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"topology-cache.d.ts","sourceRoot":"","sources":["../../src/cache/topology-cache.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"topology-cache.d.ts","sourceRoot":"","sources":["../../src/cache/topology-cache.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AASrC,UAAU,UAAU;IAClB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC9B,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;;GAGG;AACH,eAAO,MAAM,aAAa,uCAKxB,CAAC;AAEH;;GAEG;AACH,wBAAgB,wBAAwB,CACtC,KAAK,EAAE,MAAM,EACb,cAAc,EAAE,OAAO,EACvB,YAAY,EAAE,OAAO,EACrB,OAAO,CAAC,EAAE,MAAM,EAAE,GACjB,MAAM,CAWR;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS,CAUrE;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CASlF;AAED;;GAEG;AACH,wBAAgB,kBAAkB,IAAI,IAAI,CAIzC;AAED;;GAEG;AACH,wBAAgB,aAAa;;;;EAM5B"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { LRUCache } from "lru-cache";
|
|
2
|
+
import { debug } from "../utils/debug.js";
|
|
2
3
|
/**
|
|
3
4
|
* Topology cache configuration
|
|
4
5
|
*/
|
|
@@ -31,11 +32,11 @@ export function generateTopologyCacheKey(orgId, includeDevices, includeZones, si
|
|
|
31
32
|
*/
|
|
32
33
|
export function getCachedTopology(key) {
|
|
33
34
|
const cached = topologyCache.get(key);
|
|
34
|
-
if (cached
|
|
35
|
-
|
|
35
|
+
if (cached) {
|
|
36
|
+
debug("topology-cache", `Cache HIT for key: ${key}`);
|
|
36
37
|
}
|
|
37
|
-
else
|
|
38
|
-
|
|
38
|
+
else {
|
|
39
|
+
debug("topology-cache", `Cache MISS for key: ${key}`);
|
|
39
40
|
}
|
|
40
41
|
return cached;
|
|
41
42
|
}
|
|
@@ -48,18 +49,14 @@ export function setCachedTopology(key, data) {
|
|
|
48
49
|
timestamp: new Date().toISOString(),
|
|
49
50
|
};
|
|
50
51
|
topologyCache.set(key, entry);
|
|
51
|
-
|
|
52
|
-
console.error(`[topology-cache] Cached data for key: ${key} (TTL: ${CACHE_TTL_SECONDS / 1000}s)`);
|
|
53
|
-
}
|
|
52
|
+
debug("topology-cache", `Cached data for key: ${key} (TTL: ${CACHE_TTL_SECONDS / 1000}s)`);
|
|
54
53
|
}
|
|
55
54
|
/**
|
|
56
55
|
* Clear all cached topology data
|
|
57
56
|
*/
|
|
58
57
|
export function clearTopologyCache() {
|
|
59
58
|
topologyCache.clear();
|
|
60
|
-
|
|
61
|
-
console.error("[topology-cache] Cache cleared");
|
|
62
|
-
}
|
|
59
|
+
debug("topology-cache", "Cache cleared");
|
|
63
60
|
}
|
|
64
61
|
/**
|
|
65
62
|
* Get cache statistics
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"topology-cache.js","sourceRoot":"","sources":["../../src/cache/topology-cache.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"topology-cache.js","sourceRoot":"","sources":["../../src/cache/topology-cache.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AACrC,OAAO,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAE1C;;GAEG;AACH,MAAM,iBAAiB,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,kBAAkB,IAAI,KAAK,EAAE,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC,0BAA0B;AAClH,MAAM,iBAAiB,GAAG,GAAG,CAAC;AAO9B;;;GAGG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,IAAI,QAAQ,CAAqB;IAC5D,GAAG,EAAE,iBAAiB;IACtB,GAAG,EAAE,iBAAiB;IACtB,cAAc,EAAE,IAAI,EAAE,yBAAyB;IAC/C,cAAc,EAAE,KAAK;CACtB,CAAC,CAAC;AAEH;;GAEG;AACH,MAAM,UAAU,wBAAwB,CACtC,KAAa,EACb,cAAuB,EACvB,YAAqB,EACrB,OAAkB;IAElB,MAAM,KAAK,GAAG,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;IAE9B,IAAI,OAAO,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAClC,KAAK,CAAC,IAAI,CAAC,SAAS,OAAO,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAClD,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,WAAW,cAAc,EAAE,CAAC,CAAC;IACxC,KAAK,CAAC,IAAI,CAAC,SAAS,YAAY,EAAE,CAAC,CAAC;IAEpC,OAAO,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AACzB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,iBAAiB,CAAC,GAAW;IAC3C,MAAM,MAAM,GAAG,aAAa,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAEtC,IAAI,MAAM,EAAE,CAAC;QACX,KAAK,CAAC,gBAAgB,EAAE,sBAAsB,GAAG,EAAE,CAAC,CAAC;IACvD,CAAC;SAAM,CAAC;QACN,KAAK,CAAC,gBAAgB,EAAE,uBAAuB,GAAG,EAAE,CAAC,CAAC;IACxD,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,iBAAiB,CAAC,GAAW,EAAE,IAA6B;IAC1E,MAAM,KAAK,GAAe;QACxB,IAAI;QACJ,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;KACpC,CAAC;IAEF,aAAa,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;IAE9B,KAAK,CAAC,gBAAgB,EAAE,wBAAwB,GAAG,UAAU,iBAAiB,GAAG,IAAI,IAAI,CAAC,CAAC;AAC7F,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,kBAAkB;IAChC,aAAa,CAAC,KAAK,EAAE,CAAC;IAEtB,KAAK,CAAC,gBAAgB,EAAE,eAAe,CAAC,CAAC;AAC3C,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,aAAa;IAC3B,OAAO;QACL,IAAI,EAAE,aAAa,CAAC,IAAI;QACxB,OAAO,EAAE,iBAAiB;QAC1B,GAAG,EAAE,iBAAiB,GAAG,IAAI,EAAE,sCAAsC;KACtE,CAAC;AACJ,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth-client.d.ts","sourceRoot":"","sources":["../../src/clients/auth-client.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"auth-client.d.ts","sourceRoot":"","sources":["../../src/clients/auth-client.ts"],"names":[],"mappings":"AAcA;;;GAGG;AACH,cAAM,eAAe;IACnB,OAAO,CAAC,KAAK,CAAuB;IACpC,OAAO,CAAC,WAAW,CAAqB;IACxC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAS;;IAOtC;;OAEG;IACG,QAAQ,IAAI,OAAO,CAAC,MAAM,CAAC;IA2DjC;;OAEG;IACH,UAAU,IAAI,IAAI;CAInB;AAGD,eAAO,MAAM,UAAU,iBAAwB,CAAC"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import dotenv from "dotenv";
|
|
2
|
+
import { debug } from "../utils/debug.js";
|
|
2
3
|
dotenv.config();
|
|
3
4
|
const BASE_URL = process.env.BUTLR_BASE_URL || "https://api.butlr.io";
|
|
4
5
|
const AUTH_ENDPOINT = `${BASE_URL}/api/v2/clients/login`;
|
|
@@ -26,14 +27,10 @@ class ButlrAuthClient {
|
|
|
26
27
|
}
|
|
27
28
|
// Return cached token if still valid (with 5 minute buffer)
|
|
28
29
|
if (this.token && this.tokenExpiry && Date.now() < this.tokenExpiry.getTime() - 5 * 60 * 1000) {
|
|
29
|
-
|
|
30
|
-
console.error("[auth-client] Using cached token");
|
|
31
|
-
}
|
|
30
|
+
debug("auth-client", "Using cached token");
|
|
32
31
|
return this.token;
|
|
33
32
|
}
|
|
34
|
-
|
|
35
|
-
console.error("[auth-client] Fetching new token...");
|
|
36
|
-
}
|
|
33
|
+
debug("auth-client", "Fetching new token...");
|
|
37
34
|
// Fetch new token
|
|
38
35
|
try {
|
|
39
36
|
const response = await fetch(AUTH_ENDPOINT, {
|
|
@@ -47,6 +44,7 @@ class ButlrAuthClient {
|
|
|
47
44
|
audience: "https://butlrauth/",
|
|
48
45
|
grant_type: "client_credentials",
|
|
49
46
|
}),
|
|
47
|
+
signal: AbortSignal.timeout(30_000),
|
|
50
48
|
});
|
|
51
49
|
if (!response.ok) {
|
|
52
50
|
const errorText = await response.text();
|
|
@@ -59,9 +57,7 @@ class ButlrAuthClient {
|
|
|
59
57
|
// Cache the token
|
|
60
58
|
this.token = data.access_token;
|
|
61
59
|
this.tokenExpiry = new Date(Date.now() + data.expires_in * 1000);
|
|
62
|
-
|
|
63
|
-
console.error(`[auth-client] Token acquired, expires at ${this.tokenExpiry.toISOString()}`);
|
|
64
|
-
}
|
|
60
|
+
debug("auth-client", `Token acquired, expires at ${this.tokenExpiry.toISOString()}`);
|
|
65
61
|
return this.token;
|
|
66
62
|
}
|
|
67
63
|
catch (error) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth-client.js","sourceRoot":"","sources":["../../src/clients/auth-client.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,QAAQ,CAAC;
|
|
1
|
+
{"version":3,"file":"auth-client.js","sourceRoot":"","sources":["../../src/clients/auth-client.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"graphql-client.d.ts","sourceRoot":"","sources":["../../src/clients/graphql-client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAuC,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"graphql-client.d.ts","sourceRoot":"","sources":["../../src/clients/graphql-client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAuC,MAAM,gBAAgB,CAAC;AA+EnF;;GAEG;AACH,eAAO,MAAM,YAAY,cAkCvB,CAAC"}
|
|
@@ -2,6 +2,7 @@ import { ApolloClient, InMemoryCache, createHttpLink, from } from "@apollo/clien
|
|
|
2
2
|
import { setContext } from "@apollo/client/link/context";
|
|
3
3
|
import { onError } from "@apollo/client/link/error";
|
|
4
4
|
import { authClient } from "./auth-client.js";
|
|
5
|
+
import { debug } from "../utils/debug.js";
|
|
5
6
|
const BASE_URL = process.env.BUTLR_BASE_URL || "https://api.butlr.io";
|
|
6
7
|
const GRAPHQL_ENDPOINT = `${BASE_URL}/api/v3/graphql`;
|
|
7
8
|
/**
|
|
@@ -25,7 +26,7 @@ const authLink = setContext(async (_, { headers }) => {
|
|
|
25
26
|
};
|
|
26
27
|
}
|
|
27
28
|
catch (error) {
|
|
28
|
-
|
|
29
|
+
debug("graphql-client", "Failed to get auth token:", error);
|
|
29
30
|
throw error;
|
|
30
31
|
}
|
|
31
32
|
});
|
|
@@ -43,21 +44,21 @@ const errorLink = onError((errorResponse) => {
|
|
|
43
44
|
const topError = resp.error;
|
|
44
45
|
if (graphQLErrors) {
|
|
45
46
|
for (const err of graphQLErrors) {
|
|
46
|
-
|
|
47
|
+
debug("graphql-client", `GraphQL error in ${operation.operationName}:`, err.message);
|
|
47
48
|
if (err.extensions?.code === "UNAUTHENTICATED") {
|
|
48
49
|
authClient.clearToken();
|
|
49
50
|
}
|
|
50
51
|
}
|
|
51
52
|
}
|
|
52
53
|
if (networkError) {
|
|
53
|
-
|
|
54
|
+
debug("graphql-client", `Network error in ${operation.operationName}:`, networkError.message);
|
|
54
55
|
if (networkError.statusCode === 401 || networkError.statusCode === 403) {
|
|
55
56
|
authClient.clearToken();
|
|
56
57
|
}
|
|
57
58
|
}
|
|
58
59
|
// Fallback for Apollo 4.x single error field
|
|
59
60
|
if (!graphQLErrors && !networkError && topError) {
|
|
60
|
-
|
|
61
|
+
debug("graphql-client", `Error in ${operation.operationName}:`, topError.message);
|
|
61
62
|
if (topError.message?.includes("UNAUTHENTICATED") ||
|
|
62
63
|
topError.message?.includes("401") ||
|
|
63
64
|
topError.message?.includes("403")) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"graphql-client.js","sourceRoot":"","sources":["../../src/clients/graphql-client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,cAAc,EAAE,IAAI,EAAE,MAAM,gBAAgB,CAAC;AACnF,OAAO,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAC;AACzD,OAAO,EAAE,OAAO,EAAE,MAAM,2BAA2B,CAAC;AACpD,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"graphql-client.js","sourceRoot":"","sources":["../../src/clients/graphql-client.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GraphQL queries for tag retrieval and lookups.
|
|
3
|
+
*
|
|
4
|
+
* Tags are org-scoped: a single tag (id, name, organization_id) can be
|
|
5
|
+
* applied to any combination of rooms, zones, and floors via separate
|
|
6
|
+
* association tables. There is no per-level tag namespace.
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* Branded string types for tag identifiers.
|
|
10
|
+
*
|
|
11
|
+
* The Butlr API filter `roomsByTag` accepts tag *IDs*, not tag *names*.
|
|
12
|
+
* These two are both `string` at runtime, which previously led to silent
|
|
13
|
+
* filter failures when names were sent in the IDs slot. Branding them keeps
|
|
14
|
+
* the distinction visible at the type level so the wrong one cannot be
|
|
15
|
+
* passed by accident.
|
|
16
|
+
*/
|
|
17
|
+
export type TagId = string & {
|
|
18
|
+
readonly __brand: "TagId";
|
|
19
|
+
};
|
|
20
|
+
export type TagName = string & {
|
|
21
|
+
readonly __brand: "TagName";
|
|
22
|
+
};
|
|
23
|
+
export declare const asTagId: (value: string) => TagId;
|
|
24
|
+
export declare const asTagName: (value: string) => TagName;
|
|
25
|
+
/**
|
|
26
|
+
* List every tag in the org along with its application footprint.
|
|
27
|
+
*
|
|
28
|
+
* Each tag's `rooms`, `zones`, and `floors` arrays are returned with
|
|
29
|
+
* id-only payloads so the response stays bounded by tag count.
|
|
30
|
+
*/
|
|
31
|
+
export declare const GET_TAGS_WITH_USAGE: import("@apollo/client").DocumentNode;
|
|
32
|
+
/**
|
|
33
|
+
* Minimal tag listing — id and name only.
|
|
34
|
+
*
|
|
35
|
+
* Used to resolve user-supplied tag names to tag IDs before invoking
|
|
36
|
+
* tag-filtered queries (e.g. `roomsByTag(tagIDs:..)`).
|
|
37
|
+
*/
|
|
38
|
+
export declare const GET_TAGS_MINIMAL: import("@apollo/client").DocumentNode;
|
|
39
|
+
//# sourceMappingURL=tags.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tags.d.ts","sourceRoot":"","sources":["../../../src/clients/queries/tags.ts"],"names":[],"mappings":"AAEA;;;;;;GAMG;AAEH;;;;;;;;GAQG;AACH,MAAM,MAAM,KAAK,GAAG,MAAM,GAAG;IAAE,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAA;CAAE,CAAC;AAC3D,MAAM,MAAM,OAAO,GAAG,MAAM,GAAG;IAAE,QAAQ,CAAC,OAAO,EAAE,SAAS,CAAA;CAAE,CAAC;AAE/D,eAAO,MAAM,OAAO,GAAI,OAAO,MAAM,KAAG,KAAuB,CAAC;AAChE,eAAO,MAAM,SAAS,GAAI,OAAO,MAAM,KAAG,OAA2B,CAAC;AAEtE;;;;;GAKG;AACH,eAAO,MAAM,mBAAmB,uCAiB/B,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,gBAAgB,uCAO5B,CAAC"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { gql } from "@apollo/client";
|
|
2
|
+
export const asTagId = (value) => value;
|
|
3
|
+
export const asTagName = (value) => value;
|
|
4
|
+
/**
|
|
5
|
+
* List every tag in the org along with its application footprint.
|
|
6
|
+
*
|
|
7
|
+
* Each tag's `rooms`, `zones`, and `floors` arrays are returned with
|
|
8
|
+
* id-only payloads so the response stays bounded by tag count.
|
|
9
|
+
*/
|
|
10
|
+
export const GET_TAGS_WITH_USAGE = gql `
|
|
11
|
+
query GetTagsWithUsage {
|
|
12
|
+
tags {
|
|
13
|
+
id
|
|
14
|
+
name
|
|
15
|
+
organization_id
|
|
16
|
+
rooms {
|
|
17
|
+
id
|
|
18
|
+
}
|
|
19
|
+
zones {
|
|
20
|
+
id
|
|
21
|
+
}
|
|
22
|
+
floors {
|
|
23
|
+
id
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
`;
|
|
28
|
+
/**
|
|
29
|
+
* Minimal tag listing — id and name only.
|
|
30
|
+
*
|
|
31
|
+
* Used to resolve user-supplied tag names to tag IDs before invoking
|
|
32
|
+
* tag-filtered queries (e.g. `roomsByTag(tagIDs:..)`).
|
|
33
|
+
*/
|
|
34
|
+
export const GET_TAGS_MINIMAL = gql `
|
|
35
|
+
query GetTagsMinimal {
|
|
36
|
+
tags {
|
|
37
|
+
id
|
|
38
|
+
name
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
`;
|
|
42
|
+
//# sourceMappingURL=tags.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tags.js","sourceRoot":"","sources":["../../../src/clients/queries/tags.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,gBAAgB,CAAC;AAsBrC,MAAM,CAAC,MAAM,OAAO,GAAG,CAAC,KAAa,EAAS,EAAE,CAAC,KAAc,CAAC;AAChE,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,KAAa,EAAW,EAAE,CAAC,KAAgB,CAAC;AAEtE;;;;;GAKG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,GAAG,CAAA;;;;;;;;;;;;;;;;;CAiBrC,CAAC;AAEF;;;;;GAKG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,GAAG,CAAA;;;;;;;CAOlC,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"topology.d.ts","sourceRoot":"","sources":["../../../src/clients/queries/topology.ts"],"names":[],"mappings":"AAEA
|
|
1
|
+
{"version":3,"file":"topology.d.ts","sourceRoot":"","sources":["../../../src/clients/queries/topology.ts"],"names":[],"mappings":"AAEA;;GAEG;AAEH;;GAEG;AACH,eAAO,MAAM,cAAc,uCAY1B,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,kBAAkB,uCA6B9B,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,iBAAiB,uCAiE7B,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,eAAe,uCAwB3B,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,aAAa,uCAqBzB,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,uBAAuB,uCAgEnC,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"topology.js","sourceRoot":"","sources":["../../../src/clients/queries/topology.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,gBAAgB,CAAC;AAErC
|
|
1
|
+
{"version":3,"file":"topology.js","sourceRoot":"","sources":["../../../src/clients/queries/topology.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,gBAAgB,CAAC;AAErC;;GAEG;AAEH;;GAEG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,GAAG,CAAA;;;;;;;;;;;;CAYhC,CAAC;AAEF;;;GAGG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA6BpC,CAAC;AAEF;;;;GAIG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAiEnC,CAAC;AAEF;;;;GAIG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;CAwBjC,CAAC;AAEF;;;GAGG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;CAqB/B,CAAC;AAEF;;;GAGG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAG,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAgEzC,CAAC"}
|
|
@@ -7,7 +7,7 @@ export declare class ApiError extends Error {
|
|
|
7
7
|
}
|
|
8
8
|
/**
|
|
9
9
|
* v3 Reporting API Request Structure
|
|
10
|
-
* Based on
|
|
10
|
+
* Based on Butlr's internal reporting API schema
|
|
11
11
|
*/
|
|
12
12
|
export interface ReportingRequest {
|
|
13
13
|
group_by?: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reporting-client.d.ts","sourceRoot":"","sources":["../../src/clients/reporting-client.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"reporting-client.d.ts","sourceRoot":"","sources":["../../src/clients/reporting-client.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { authClient } from "./auth-client.js";
|
|
2
|
+
import { debug } from "../utils/debug.js";
|
|
2
3
|
/**
|
|
3
4
|
* Structured API error with status code for proper error translation
|
|
4
5
|
*/
|
|
@@ -59,19 +60,19 @@ export function getMeasurement(assetType) {
|
|
|
59
60
|
*/
|
|
60
61
|
export function normalizeTimestamp(rfc3339) {
|
|
61
62
|
if (!rfc3339) {
|
|
62
|
-
|
|
63
|
+
debug("reporting-client", `Invalid timestamp received: ${rfc3339}`);
|
|
63
64
|
return "";
|
|
64
65
|
}
|
|
65
66
|
try {
|
|
66
67
|
const date = new Date(rfc3339);
|
|
67
68
|
if (isNaN(date.getTime())) {
|
|
68
|
-
|
|
69
|
+
debug("reporting-client", `Invalid timestamp received: ${rfc3339}`);
|
|
69
70
|
return "";
|
|
70
71
|
}
|
|
71
72
|
return date.toISOString();
|
|
72
73
|
}
|
|
73
74
|
catch (error) {
|
|
74
|
-
|
|
75
|
+
debug("reporting-client", `Failed to normalize timestamp ${rfc3339}:`, error);
|
|
75
76
|
return "";
|
|
76
77
|
}
|
|
77
78
|
}
|
|
@@ -79,9 +80,7 @@ export function normalizeTimestamp(rfc3339) {
|
|
|
79
80
|
* Query v3 Reporting API
|
|
80
81
|
*/
|
|
81
82
|
export async function queryReporting(requestBody) {
|
|
82
|
-
|
|
83
|
-
console.error(`[reporting-client] POST ${REPORTING_ENDPOINT}`, JSON.stringify(requestBody, null, 2));
|
|
84
|
-
}
|
|
83
|
+
debug("reporting-client", `POST ${REPORTING_ENDPOINT}`, JSON.stringify(requestBody, null, 2));
|
|
85
84
|
try {
|
|
86
85
|
// Get auth token
|
|
87
86
|
const token = await authClient.getToken();
|
|
@@ -93,22 +92,19 @@ export async function queryReporting(requestBody) {
|
|
|
93
92
|
Authorization: `Bearer ${token}`,
|
|
94
93
|
},
|
|
95
94
|
body: JSON.stringify(requestBody),
|
|
95
|
+
signal: AbortSignal.timeout(30_000),
|
|
96
96
|
});
|
|
97
97
|
if (!response.ok) {
|
|
98
98
|
const errorBody = await response.text();
|
|
99
|
-
|
|
100
|
-
console.error(`[reporting-client] API error body: ${errorBody}`);
|
|
101
|
-
}
|
|
99
|
+
debug("reporting-client", `API error body: ${errorBody}`);
|
|
102
100
|
throw new ApiError(response.status, `Butlr API error (${response.status}). Enable DEBUG=butlr-mcp for details.`);
|
|
103
101
|
}
|
|
104
102
|
const data = (await response.json());
|
|
105
|
-
|
|
106
|
-
console.error(`[reporting-client] Response: ${data.data?.length || 0} data points`);
|
|
107
|
-
}
|
|
103
|
+
debug("reporting-client", `Response: ${data.data?.length || 0} data points`);
|
|
108
104
|
return data;
|
|
109
105
|
}
|
|
110
106
|
catch (error) {
|
|
111
|
-
|
|
107
|
+
debug("reporting-client", "Request failed:", error);
|
|
112
108
|
// Translate common errors using structured ApiError
|
|
113
109
|
if (error instanceof ApiError) {
|
|
114
110
|
if (error.statusCode === 401 || error.statusCode === 403) {
|
|
@@ -271,7 +267,7 @@ export async function getCurrentOccupancy(assetType, assetIds) {
|
|
|
271
267
|
const presenceResponse = presenceResult.status === "fulfilled" ? presenceResult.value : { data: [] };
|
|
272
268
|
const trafficResponse = trafficResult.status === "fulfilled" ? trafficResult.value : { data: [] };
|
|
273
269
|
if (trafficResult.status === "rejected") {
|
|
274
|
-
|
|
270
|
+
debug("reporting-client", "Traffic query failed (may not have traffic sensors):", trafficResult.reason);
|
|
275
271
|
}
|
|
276
272
|
// Normalize presence data
|
|
277
273
|
// Response structure: { "room_123": { "2025-10-10T00:00:00Z": { "max": 5 } } }
|