signalk-questdb 2.0.1 → 2.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.
Files changed (91) hide show
  1. package/.coderabbit.yaml +4 -3
  2. package/README.md +151 -5
  3. package/dist/api-contract.d.ts +62 -0
  4. package/dist/config/schema.d.ts +1 -0
  5. package/dist/config/schema.js +5 -0
  6. package/dist/config/schema.js.map +1 -1
  7. package/dist/configpanel/responses.d.ts +33 -1
  8. package/dist/configpanel/responses.js +89 -0
  9. package/dist/configpanel/responses.js.map +1 -1
  10. package/dist/history-v1.js +12 -9
  11. package/dist/history-v1.js.map +1 -1
  12. package/dist/history-v2.d.ts +18 -6
  13. package/dist/history-v2.js +275 -41
  14. package/dist/history-v2.js.map +1 -1
  15. package/dist/ilp-writer.d.ts +22 -0
  16. package/dist/ilp-writer.js +76 -4
  17. package/dist/ilp-writer.js.map +1 -1
  18. package/dist/index.d.ts +1 -0
  19. package/dist/index.js +326 -58
  20. package/dist/index.js.map +1 -1
  21. package/dist/influx-detect.d.ts +19 -0
  22. package/dist/influx-detect.js +165 -0
  23. package/dist/influx-detect.js.map +1 -0
  24. package/dist/migration.d.ts +147 -0
  25. package/dist/migration.js +819 -0
  26. package/dist/migration.js.map +1 -0
  27. package/dist/query-client.d.ts +9 -0
  28. package/dist/query-client.js +11 -0
  29. package/dist/query-client.js.map +1 -1
  30. package/dist/restore.js +9 -0
  31. package/dist/restore.js.map +1 -1
  32. package/dist/schema-errors.d.ts +15 -0
  33. package/dist/schema-errors.js +38 -0
  34. package/dist/schema-errors.js.map +1 -0
  35. package/package.json +5 -4
  36. package/public/assets/PluginConfigurationPanel-CR4mD9IH.js +9 -0
  37. package/public/assets/{index-Z7eUk0W6.js → index-CyI4zKUm.js} +1 -1
  38. package/public/assets/{virtualExposes-CyrNon4j.js → virtualExposes-BBIkbTtD.js} +1 -1
  39. package/public/remoteEntry.js +1 -1
  40. package/dist/test/config.test.d.ts +0 -1
  41. package/dist/test/config.test.js +0 -161
  42. package/dist/test/config.test.js.map +0 -1
  43. package/dist/test/configpanel-responses.test.d.ts +0 -1
  44. package/dist/test/configpanel-responses.test.js +0 -108
  45. package/dist/test/configpanel-responses.test.js.map +0 -1
  46. package/dist/test/console-proxy.test.d.ts +0 -1
  47. package/dist/test/console-proxy.test.js +0 -664
  48. package/dist/test/console-proxy.test.js.map +0 -1
  49. package/dist/test/container-env.test.d.ts +0 -1
  50. package/dist/test/container-env.test.js +0 -70
  51. package/dist/test/container-env.test.js.map +0 -1
  52. package/dist/test/delta-routing.test.d.ts +0 -1
  53. package/dist/test/delta-routing.test.js +0 -258
  54. package/dist/test/delta-routing.test.js.map +0 -1
  55. package/dist/test/full-export-range.test.d.ts +0 -1
  56. package/dist/test/full-export-range.test.js +0 -78
  57. package/dist/test/full-export-range.test.js.map +0 -1
  58. package/dist/test/history-v1.test.d.ts +0 -1
  59. package/dist/test/history-v1.test.js +0 -676
  60. package/dist/test/history-v1.test.js.map +0 -1
  61. package/dist/test/history-v2.test.d.ts +0 -1
  62. package/dist/test/history-v2.test.js +0 -563
  63. package/dist/test/history-v2.test.js.map +0 -1
  64. package/dist/test/host-limits.test.d.ts +0 -1
  65. package/dist/test/host-limits.test.js +0 -81
  66. package/dist/test/host-limits.test.js.map +0 -1
  67. package/dist/test/ilp-writer.test.d.ts +0 -1
  68. package/dist/test/ilp-writer.test.js +0 -391
  69. package/dist/test/ilp-writer.test.js.map +0 -1
  70. package/dist/test/package-e2e.test.d.ts +0 -1
  71. package/dist/test/package-e2e.test.js +0 -306
  72. package/dist/test/package-e2e.test.js.map +0 -1
  73. package/dist/test/path-matcher.test.d.ts +0 -1
  74. package/dist/test/path-matcher.test.js +0 -224
  75. package/dist/test/path-matcher.test.js.map +0 -1
  76. package/dist/test/query-client.test.d.ts +0 -1
  77. package/dist/test/query-client.test.js +0 -299
  78. package/dist/test/query-client.test.js.map +0 -1
  79. package/dist/test/questdb-endpoint.test.d.ts +0 -1
  80. package/dist/test/questdb-endpoint.test.js +0 -297
  81. package/dist/test/questdb-endpoint.test.js.map +0 -1
  82. package/dist/test/restore.test.d.ts +0 -1
  83. package/dist/test/restore.test.js +0 -496
  84. package/dist/test/restore.test.js.map +0 -1
  85. package/dist/test/time-range.test.d.ts +0 -1
  86. package/dist/test/time-range.test.js +0 -53
  87. package/dist/test/time-range.test.js.map +0 -1
  88. package/dist/test/wal-monitor.test.d.ts +0 -1
  89. package/dist/test/wal-monitor.test.js +0 -405
  90. package/dist/test/wal-monitor.test.js.map +0 -1
  91. package/public/assets/PluginConfigurationPanel-CyS3A7gD.js +0 -9
@@ -1,299 +0,0 @@
1
- import { describe, it } from "node:test";
2
- import assert from "node:assert/strict";
3
- import { validateIdentifier, validateTimestamp, isReadOnlySQL, QueryClient, } from "../query-client.js";
4
- // Build a QueryClient whose exec() is stubbed: every call records the SQL and
5
- // returns the next canned result (a single-column `column` dataset for the
6
- // designated-timestamp introspection, or an empty dataset for DDL). Lets us
7
- // test the schema-heal logic without a live QuestDB.
8
- function stubClient(responder) {
9
- const client = new QueryClient("127.0.0.1", 9000);
10
- const sql = [];
11
- client.exec =
12
- (q) => {
13
- sql.push(q);
14
- return Promise.resolve(responder(q));
15
- };
16
- return { client, sql };
17
- }
18
- const tsRow = (column) => ({
19
- columns: [{ name: "column", type: "STRING" }],
20
- dataset: [[column]],
21
- count: 1,
22
- timestamp: -1,
23
- });
24
- const emptyResult = {
25
- columns: [{ name: "column", type: "STRING" }],
26
- dataset: [],
27
- count: 0,
28
- timestamp: -1,
29
- };
30
- describe("validateIdentifier", () => {
31
- it("accepts valid Signal K paths", () => {
32
- assert.equal(validateIdentifier("navigation.speedOverGround"), "navigation.speedOverGround");
33
- assert.equal(validateIdentifier("self"), "self");
34
- assert.equal(validateIdentifier("vessels.urn:mrn:imo:mmsi:123456789"), "vessels.urn:mrn:imo:mmsi:123456789");
35
- });
36
- it("accepts paths containing underscores", () => {
37
- assert.equal(validateIdentifier("electrical.batteries.house_bank.voltage"), "electrical.batteries.house_bank.voltage");
38
- assert.equal(validateIdentifier("tanks.fuel.starboard_main.currentLevel"), "tanks.fuel.starboard_main.currentLevel");
39
- });
40
- it("rejects SQL injection attempts", () => {
41
- assert.throws(() => validateIdentifier("'; DROP TABLE signalk;--"));
42
- assert.throws(() => validateIdentifier("path OR 1=1"));
43
- assert.throws(() => validateIdentifier("path\nSELECT"));
44
- });
45
- });
46
- describe("validateTimestamp", () => {
47
- it("accepts valid ISO timestamps", () => {
48
- const result = validateTimestamp("2024-06-15T12:00:00.000Z");
49
- assert.equal(result, "2024-06-15T12:00:00.000Z");
50
- });
51
- it("normalizes various timestamp formats to ISO", () => {
52
- const result = validateTimestamp("2024-06-15");
53
- assert.ok(result.startsWith("2024-06-15"), `Got: ${result}`);
54
- });
55
- it("rejects invalid timestamps", () => {
56
- assert.throws(() => validateTimestamp("not-a-date"));
57
- assert.throws(() => validateTimestamp(""));
58
- });
59
- });
60
- describe("isReadOnlySQL", () => {
61
- it("allows SELECT queries", () => {
62
- assert.ok(isReadOnlySQL("SELECT count() FROM signalk"));
63
- assert.ok(isReadOnlySQL(" SELECT ts, value FROM signalk WHERE path = 'nav'"));
64
- assert.ok(isReadOnlySQL("WITH cte AS (SELECT 1) SELECT * FROM cte"));
65
- });
66
- it("allows SHOW queries", () => {
67
- assert.ok(isReadOnlySQL("SHOW TABLES"));
68
- assert.ok(isReadOnlySQL("SHOW COLUMNS FROM signalk"));
69
- });
70
- it("blocks DDL and DML", () => {
71
- assert.ok(!isReadOnlySQL("DROP TABLE signalk"));
72
- assert.ok(!isReadOnlySQL("ALTER TABLE signalk ADD COLUMN x INT"));
73
- assert.ok(!isReadOnlySQL("INSERT INTO signalk VALUES (1)"));
74
- assert.ok(!isReadOnlySQL("DELETE FROM signalk WHERE ts < now()"));
75
- assert.ok(!isReadOnlySQL("CREATE TABLE evil (x INT)"));
76
- assert.ok(!isReadOnlySQL("TRUNCATE TABLE signalk"));
77
- });
78
- it("blocks DDL hidden in SELECT", () => {
79
- assert.ok(!isReadOnlySQL("SELECT 1; DROP TABLE signalk"), "Should block DROP even after SELECT");
80
- });
81
- });
82
- describe("QueryClient schema heal", () => {
83
- it("reports the designated timestamp column", async () => {
84
- const { client } = stubClient(() => tsRow("ts"));
85
- assert.equal(await client.designatedTimestamp("signalk"), "ts");
86
- });
87
- it("double-quotes the `column` keyword in the introspection query", async () => {
88
- // `column` is a SQL keyword in QuestDB; an unquoted `SELECT column` is
89
- // rejected at parse time. The stub matches blind, so guard the exact SQL.
90
- const { client, sql } = stubClient(() => tsRow("ts"));
91
- await client.designatedTimestamp("signalk");
92
- assert.match(sql[0], /SELECT "column" FROM table_columns\(/);
93
- assert.doesNotMatch(sql[0], /SELECT column\b/);
94
- });
95
- it("returns null when the table has no designated timestamp / is missing", async () => {
96
- const { client } = stubClient(() => emptyResult);
97
- assert.equal(await client.designatedTimestamp("signalk"), null);
98
- });
99
- it("treats a `ts` designated timestamp as no mismatch", async () => {
100
- const { client } = stubClient(() => tsRow("ts"));
101
- assert.equal(await client.hasSchemaMismatch("signalk"), false);
102
- });
103
- it("flags a `timestamp` (ILP auto-created) designated timestamp as a mismatch", async () => {
104
- const { client } = stubClient(() => tsRow("timestamp"));
105
- assert.equal(await client.hasSchemaMismatch("signalk"), true);
106
- });
107
- it("treats a missing table as no mismatch", async () => {
108
- const { client } = stubClient(() => emptyResult);
109
- assert.equal(await client.hasSchemaMismatch("signalk"), false);
110
- });
111
- it("treats introspection failure as no mismatch (swallowed)", async () => {
112
- const { client } = stubClient(() => {
113
- throw new Error("table does not exist");
114
- });
115
- assert.equal(await client.hasSchemaMismatch("signalk"), false);
116
- });
117
- it("healSchema is a no-op on a correct table", async () => {
118
- const { client, sql } = stubClient(() => tsRow("ts"));
119
- assert.equal(await client.healSchema("signalk"), false);
120
- // Only the introspection query ran — no DROP, no CREATE.
121
- assert.ok(sql.every((q) => !/DROP TABLE|CREATE TABLE/i.test(q)));
122
- });
123
- it("healSchema drops and recreates a wrong-schema table", async () => {
124
- // First introspection says `timestamp` (mismatch); after the rebuild the
125
- // CREATE TABLE statements just return empty.
126
- let firstIntrospection = true;
127
- const { client, sql } = stubClient((q) => {
128
- if (/table_columns/.test(q)) {
129
- if (firstIntrospection) {
130
- firstIntrospection = false;
131
- return tsRow("timestamp");
132
- }
133
- return tsRow("ts");
134
- }
135
- return emptyResult;
136
- });
137
- assert.equal(await client.healSchema("signalk"), true);
138
- assert.ok(sql.some((q) => /DROP TABLE IF EXISTS signalk/i.test(q)), "should drop the wrong-schema table");
139
- assert.ok(sql.some((q) => /CREATE TABLE IF NOT EXISTS signalk\b/i.test(q)), "should recreate via ensureTables");
140
- });
141
- it("rejects an invalid table identifier", async () => {
142
- const { client } = stubClient(() => emptyResult);
143
- await assert.rejects(() => client.designatedTimestamp("signalk; DROP TABLE x"));
144
- });
145
- it("hasSchemaMismatch rejects an invalid identifier instead of swallowing it", async () => {
146
- const { client } = stubClient(() => emptyResult);
147
- await assert.rejects(() => client.hasSchemaMismatch("signalk; DROP TABLE x"));
148
- });
149
- });
150
- describe("QueryClient.toObjects", () => {
151
- const client = new QueryClient("127.0.0.1", 9000);
152
- it("maps a populated dataset to named objects", () => {
153
- const objs = client.toObjects({
154
- columns: [
155
- { name: "name", type: "STRING" },
156
- { name: "suspended", type: "BOOLEAN" },
157
- { name: "errorMessage", type: "STRING" },
158
- ],
159
- dataset: [["signalk", true, "OUT_OF_MEMORY: mmap failed"]],
160
- count: 1,
161
- timestamp: -1,
162
- });
163
- assert.deepEqual(objs, [
164
- {
165
- name: "signalk",
166
- suspended: true,
167
- errorMessage: "OUT_OF_MEMORY: mmap failed",
168
- },
169
- ]);
170
- });
171
- it("returns [] when the result carries rows but no column metadata", () => {
172
- // QuestDB omits `columns` when queried with nm=true. A non-empty dataset
173
- // in that shape previously threw; it must degrade to [] instead.
174
- const result = {
175
- dataset: [["signalk", true]],
176
- count: 1,
177
- };
178
- assert.deepEqual(client.toObjects(result), []);
179
- });
180
- });
181
- describe("QueryClient statement timeout header", () => {
182
- // A real (loopback) HTTP server instead of a fetch stub: the point is to
183
- // assert what actually goes on the wire, since Statement-Timeout is only
184
- // honored when QuestDB receives it as a request header.
185
- async function captureHeaders(run) {
186
- const http = await import("node:http");
187
- let headers = {};
188
- const server = http.createServer((req, res) => {
189
- headers = req.headers;
190
- res.setHeader("content-type", "application/json");
191
- res.end(JSON.stringify({ columns: [], dataset: [], count: 0, timestamp: -1 }));
192
- });
193
- await new Promise((resolve) => server.listen(0, "127.0.0.1", resolve));
194
- const port = server.address().port;
195
- try {
196
- await run(new QueryClient("127.0.0.1", port));
197
- }
198
- finally {
199
- server.close();
200
- }
201
- return headers;
202
- }
203
- it("mirrors the exec() deadline into Statement-Timeout (ms)", async () => {
204
- const headers = await captureHeaders((client) => client.exec("SELECT 1", 12345));
205
- assert.equal(headers["statement-timeout"], "12345");
206
- });
207
- it("sends the default deadline when none is given", async () => {
208
- const headers = await captureHeaders((client) => client.exec("SELECT 1"));
209
- assert.equal(headers["statement-timeout"], "30000");
210
- });
211
- it("bounds CSV exports the same way", async () => {
212
- const headers = await captureHeaders((client) => client.execCsv("SELECT 1"));
213
- assert.equal(headers["statement-timeout"], "60000");
214
- });
215
- it("mirrors an explicit CSV deadline into Statement-Timeout", async () => {
216
- const headers = await captureHeaders((client) => client.execCsv("SELECT 1", 12345));
217
- assert.equal(headers["statement-timeout"], "12345");
218
- });
219
- });
220
- describe("QueryClient.ensureTables schema migration", () => {
221
- it("creates signalk_str with value_kind and migrates existing tables", async () => {
222
- // CREATE TABLE IF NOT EXISTS leaves a pre-existing table untouched, so
223
- // installs that predate value_kind need the explicit ALTER. It must run
224
- // unconditionally (it is idempotent) or those installs never gain the
225
- // column and every replayed boolean silently degrades to text.
226
- const { client, sql } = stubClient(() => emptyResult);
227
- await client.ensureTables();
228
- const created = sql.find((q) => q.includes("CREATE TABLE IF NOT EXISTS signalk_str"));
229
- assert.ok(created, "expected signalk_str to be created");
230
- assert.ok(created.includes("value_kind"), `new tables must include value_kind, got: ${created}`);
231
- const altered = sql.find((q) => q.includes("ALTER TABLE signalk_str"));
232
- assert.ok(altered, "expected the migration ALTER for existing tables");
233
- assert.ok(altered.includes("ADD COLUMN IF NOT EXISTS value_kind"), `migration must be idempotent, got: ${altered}`);
234
- });
235
- it("adds the source column and grows the dedup keys on every table", async () => {
236
- // Same shape as the value_kind migration: CREATE TABLE IF NOT EXISTS
237
- // leaves pre-existing tables untouched, so each table needs the explicit
238
- // idempotent ALTER. The dedup keys must grow with the column too — a
239
- // replayed ILP batch keeps its original stamps, so two sources stamped
240
- // identically would otherwise upsert over each other and replay would
241
- // silently drop one source's row.
242
- const { client, sql } = stubClient(() => emptyResult);
243
- await client.ensureTables();
244
- for (const table of ["signalk", "signalk_str", "signalk_position"]) {
245
- const created = sql.find((q) => q.includes(`CREATE TABLE IF NOT EXISTS ${table} (`));
246
- assert.ok(created, `expected ${table} to be created`);
247
- assert.match(created, /source\s+SYMBOL/, `new ${table} must include the source column`);
248
- assert.match(created, /DEDUP UPSERT KEYS\([^)]*\bsource\)/, `new ${table} must dedup on source, got: ${created}`);
249
- assert.ok(sql.some((q) => q.includes(`ALTER TABLE ${table} ADD COLUMN IF NOT EXISTS source`)), `expected the source ADD COLUMN migration for ${table}`);
250
- const dedup = sql.find((q) => q.includes(`ALTER TABLE ${table} DEDUP ENABLE UPSERT KEYS(`));
251
- assert.ok(dedup, `expected the dedup-key migration for ${table}`);
252
- assert.ok(dedup.includes("source"), `migrated dedup keys must include source, got: ${dedup}`);
253
- }
254
- });
255
- it("skips the dedup migration quietly on a wrong-schema table", async () => {
256
- // An ILP auto-created table (designated timestamp `timestamp`) rejects
257
- // UPSERT KEYS naming `ts`. Throwing would abort startup BEFORE
258
- // healSchema() runs — and the heal is what fixes this exact table — so
259
- // the mismatch case must neither throw nor warn, and the remaining
260
- // tables must still get their migration.
261
- const warnings = [];
262
- const { client, sql } = stubClient((q) => {
263
- if (q.includes("ALTER TABLE signalk DEDUP ENABLE")) {
264
- throw new Error("Invalid column: ts");
265
- }
266
- if (q.includes("table_columns('signalk')"))
267
- return tsRow("timestamp");
268
- return emptyResult;
269
- });
270
- await client.ensureTables((msg) => warnings.push(msg));
271
- assert.deepEqual(warnings, []);
272
- for (const table of ["signalk_str", "signalk_position"]) {
273
- assert.ok(sql.some((q) => q.includes(`ALTER TABLE ${table} DEDUP ENABLE`)), `${table} must still be migrated after signalk's failure`);
274
- }
275
- });
276
- it("warns instead of throwing when dedup fails on a well-shaped table", async () => {
277
- // A non-WAL external table also rejects DEDUP ENABLE, but looks healthy
278
- // to the mismatch probe (its designated timestamp IS `ts`). healSchema
279
- // will never rebuild it, so the degradation has to be reported — while
280
- // still not failing a startup that worked before this migration existed.
281
- const warnings = [];
282
- const { client } = stubClient((q) => {
283
- if (q.includes("ALTER TABLE signalk_str DEDUP ENABLE")) {
284
- throw new Error("table is not WAL enabled");
285
- }
286
- if (q.includes("table_columns('signalk_str')"))
287
- return tsRow("ts");
288
- return emptyResult;
289
- });
290
- await client.ensureTables((msg) => warnings.push(msg));
291
- assert.equal(warnings.length, 1);
292
- assert.match(warnings[0], /signalk_str/);
293
- // The message must state the condition (keys not updated), not a
294
- // resulting mode: depending on prior state dedup may be fully off
295
- // (non-WAL) or still on with the stale keys (timed-out ALTER).
296
- assert.match(warnings[0], /deduplication keys were not updated/);
297
- });
298
- });
299
- //# sourceMappingURL=query-client.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"query-client.test.js","sourceRoot":"","sources":["../../src/test/query-client.test.ts"],"names":[],"mappings":"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"}
@@ -1 +0,0 @@
1
- export {};
@@ -1,297 +0,0 @@
1
- import { describe, it } from "node:test";
2
- import assert from "node:assert/strict";
3
- import http from "node:http";
4
- import { splitHostPort, resolveManagedEndpoints, resolveLanExposureHost, lanExposureEndpoints, probeQuestdbPing, HOST_GATEWAY, QUESTDB_INTERNAL_HTTP_PORT, QUESTDB_INTERNAL_ILP_PORT, } from "../questdb-endpoint.js";
5
- describe("splitHostPort", () => {
6
- it("parses host:port", () => {
7
- assert.deepEqual(splitHostPort("127.0.0.1:9000", 1), {
8
- host: "127.0.0.1",
9
- port: 9000,
10
- });
11
- assert.deepEqual(splitHostPort("sk-signalk-questdb:9009", 1), {
12
- host: "sk-signalk-questdb",
13
- port: 9009,
14
- });
15
- });
16
- it("falls back to fallbackPort for a bare host", () => {
17
- assert.deepEqual(splitHostPort("questdb.local", 8812), {
18
- host: "questdb.local",
19
- port: 8812,
20
- });
21
- });
22
- it("parses bracketed IPv6 with and without a port", () => {
23
- assert.deepEqual(splitHostPort("[::1]:9000", 1), {
24
- host: "::1",
25
- port: 9000,
26
- });
27
- assert.deepEqual(splitHostPort("[fe80::1]", 9000), {
28
- host: "fe80::1",
29
- port: 9000,
30
- });
31
- });
32
- it("treats a bare unbracketed IPv6 literal as a host", () => {
33
- // Multiple colons, no brackets — ambiguous, so the whole string is the
34
- // host and the fallback port applies.
35
- assert.deepEqual(splitHostPort("fe80::1", 9000), {
36
- host: "fe80::1",
37
- port: 9000,
38
- });
39
- });
40
- it("returns null for empty/whitespace/malformed input", () => {
41
- assert.equal(splitHostPort("", 9000), null);
42
- assert.equal(splitHostPort(" ", 9000), null);
43
- assert.equal(splitHostPort(null, 9000), null);
44
- assert.equal(splitHostPort(undefined, 9000), null);
45
- assert.equal(splitHostPort("host:notaport", 9000), null);
46
- assert.equal(splitHostPort("host:0", 9000), null);
47
- assert.equal(splitHostPort(":9000", 9000), null);
48
- assert.equal(splitHostPort("[]:9000", 9000), null);
49
- });
50
- });
51
- describe("resolveManagedEndpoints", () => {
52
- it("uses resolveContainerAddress for each internal port", async () => {
53
- const calls = [];
54
- const containers = {
55
- resolveContainerAddress: async (name, port) => {
56
- calls.push([name, port]);
57
- return port === QUESTDB_INTERNAL_HTTP_PORT
58
- ? "sk-signalk-questdb:9000"
59
- : "sk-signalk-questdb:9009";
60
- },
61
- };
62
- const ep = await resolveManagedEndpoints(containers, "signalk-questdb", "127.0.0.1");
63
- assert.deepEqual(ep.http, { host: "sk-signalk-questdb", port: 9000 });
64
- assert.deepEqual(ep.ilp, { host: "sk-signalk-questdb", port: 9009 });
65
- assert.deepEqual(calls, [
66
- ["signalk-questdb", QUESTDB_INTERNAL_HTTP_PORT],
67
- ["signalk-questdb", QUESTDB_INTERNAL_ILP_PORT],
68
- ]);
69
- });
70
- it("honors a remapped host port from bare-metal allocation", async () => {
71
- const containers = {
72
- resolveContainerAddress: async (_name, port) => port === QUESTDB_INTERNAL_HTTP_PORT
73
- ? "127.0.0.1:9100" // declared 9000 was taken, allocated 9100
74
- : "127.0.0.1:9009",
75
- };
76
- const ep = await resolveManagedEndpoints(containers, "signalk-questdb", "127.0.0.1");
77
- assert.deepEqual(ep.http, { host: "127.0.0.1", port: 9100 });
78
- });
79
- it("falls back when resolveContainerAddress is absent (old container plugin)", async () => {
80
- const ep = await resolveManagedEndpoints({}, "signalk-questdb", "10.0.0.5");
81
- assert.deepEqual(ep.http, { host: "10.0.0.5", port: 9000 });
82
- assert.deepEqual(ep.ilp, { host: "10.0.0.5", port: 9009 });
83
- });
84
- it("falls back when resolveContainerAddress returns null", async () => {
85
- const containers = {
86
- resolveContainerAddress: async () => null,
87
- };
88
- const ep = await resolveManagedEndpoints(containers, "signalk-questdb", "127.0.0.1");
89
- assert.deepEqual(ep.http, { host: "127.0.0.1", port: 9000 });
90
- assert.deepEqual(ep.ilp, { host: "127.0.0.1", port: 9009 });
91
- });
92
- it("falls back when resolveContainerAddress throws", async () => {
93
- const containers = {
94
- resolveContainerAddress: async () => {
95
- throw new Error("not yet available");
96
- },
97
- };
98
- const ep = await resolveManagedEndpoints(containers, "signalk-questdb", "127.0.0.1");
99
- assert.deepEqual(ep.http, { host: "127.0.0.1", port: 9000 });
100
- });
101
- });
102
- describe("probeQuestdbPing", () => {
103
- // A real local HTTP server exercises the URL construction, status check,
104
- // and timeout path without mocking fetch.
105
- function serve(handler) {
106
- const server = http.createServer(handler);
107
- return new Promise((resolve) => server.listen(0, "127.0.0.1", () => resolve({
108
- port: server.address().port,
109
- close: () => new Promise((r) => {
110
- server.closeAllConnections();
111
- server.close(() => r(undefined));
112
- }),
113
- })));
114
- }
115
- it("accepts the documented 204 on /ping", async () => {
116
- const { port, close } = await serve((req, res) => {
117
- assert.equal(req.url, "/ping");
118
- res.writeHead(204).end();
119
- });
120
- try {
121
- assert.equal(await probeQuestdbPing("127.0.0.1", port), true);
122
- }
123
- finally {
124
- await close();
125
- }
126
- });
127
- it("rejects any other status (an unrelated service must not win)", async () => {
128
- const { port, close } = await serve((_req, res) => {
129
- res.writeHead(200).end("not questdb");
130
- });
131
- try {
132
- assert.equal(await probeQuestdbPing("127.0.0.1", port), false);
133
- }
134
- finally {
135
- await close();
136
- }
137
- });
138
- it("returns false on a refused connection", async () => {
139
- const { port, close } = await serve((_req, res) => res.end());
140
- await close();
141
- assert.equal(await probeQuestdbPing("127.0.0.1", port), false);
142
- });
143
- it("returns false when the server never answers within the timeout", async () => {
144
- const { port, close } = await serve(() => {
145
- /* hold the request open */
146
- });
147
- try {
148
- assert.equal(await probeQuestdbPing("127.0.0.1", port, 200), false);
149
- }
150
- finally {
151
- await close();
152
- }
153
- });
154
- });
155
- describe("resolveLanExposureHost", () => {
156
- // Probes never involve the network in these tests: a stub records the
157
- // candidates and scripts which host answers.
158
- function recordingProbe(answers) {
159
- const calls = [];
160
- return {
161
- calls,
162
- probe: async (host, port) => {
163
- calls.push(`${host}:${port}`);
164
- return answers.includes(host);
165
- },
166
- };
167
- }
168
- const containerized = {
169
- doctor: { selfDeployment: async () => ({ isContainerized: true }) },
170
- };
171
- const noRetry = { deadlineMs: 0, intervalMs: 0 };
172
- it("returns loopback for bare-metal Signal K without probing", async () => {
173
- const { calls, probe } = recordingProbe([]);
174
- const host = await resolveLanExposureHost({
175
- doctor: { selfDeployment: async () => ({ isContainerized: false }) },
176
- }, 9000, undefined, { probe, ...noRetry });
177
- assert.equal(host, "127.0.0.1");
178
- assert.deepEqual(calls, []);
179
- });
180
- it("containerized + loopback answers: host-networked SK gets 127.0.0.1 (issue #67)", async () => {
181
- const { calls, probe } = recordingProbe(["127.0.0.1", HOST_GATEWAY]);
182
- const host = await resolveLanExposureHost(containerized, 9000, undefined, {
183
- probe,
184
- ...noRetry,
185
- });
186
- assert.equal(host, "127.0.0.1");
187
- assert.deepEqual(calls, ["127.0.0.1:9000"]);
188
- });
189
- it("containerized + only the gateway answers: bridge-networked SK gets the gateway", async () => {
190
- const { calls, probe } = recordingProbe([HOST_GATEWAY]);
191
- const host = await resolveLanExposureHost(containerized, 9500, undefined, {
192
- probe,
193
- ...noRetry,
194
- });
195
- assert.equal(host, HOST_GATEWAY);
196
- assert.deepEqual(calls, ["127.0.0.1:9500", `${HOST_GATEWAY}:9500`]);
197
- });
198
- // A fake clock that only advances inside sleep() makes the retry cadence
199
- // fully deterministic — wall-clock scheduling never decides how many
200
- // rounds fit before the deadline.
201
- function fakeClock() {
202
- let t = 0;
203
- return {
204
- now: () => t,
205
- sleep: async (ms) => {
206
- t += ms;
207
- },
208
- };
209
- }
210
- it("retries the candidate pair until the deadline, then falls back to the gateway", async () => {
211
- const { calls, probe } = recordingProbe([]);
212
- const host = await resolveLanExposureHost(containerized, 9000, undefined, {
213
- probe,
214
- deadlineMs: 2500,
215
- intervalMs: 1000,
216
- ...fakeClock(),
217
- });
218
- assert.equal(host, HOST_GATEWAY);
219
- // Rounds at t=0, 1000, 2000; the sleep ending at t=3000 crosses the
220
- // deadline, so no fourth round starts.
221
- assert.equal(calls.length, 6);
222
- });
223
- it("a late success on a retry round wins over the fallback", async () => {
224
- let round = 0;
225
- const host = await resolveLanExposureHost(containerized, 9000, undefined, {
226
- probe: async (candidate) => {
227
- if (candidate === "127.0.0.1")
228
- round++;
229
- return candidate === "127.0.0.1" && round >= 3;
230
- },
231
- deadlineMs: 60_000,
232
- intervalMs: 1000,
233
- ...fakeClock(),
234
- });
235
- assert.equal(host, "127.0.0.1");
236
- assert.equal(round, 3);
237
- });
238
- it("clamps each probe's budget to the remaining deadline, with a floor", async () => {
239
- const budgets = [];
240
- const clock = fakeClock();
241
- await resolveLanExposureHost(containerized, 9000, undefined, {
242
- probe: async (_host, _port, timeoutMs) => {
243
- budgets.push(timeoutMs);
244
- return false;
245
- },
246
- deadlineMs: 2000,
247
- intervalMs: 1500,
248
- ...clock,
249
- });
250
- // Round 1 (t=0): full 2000ms remain, capped at the 3000ms default → 2000.
251
- // Round 2 (t=1500): 500ms remain → floored at 1000.
252
- assert.deepEqual(budgets, [2000, 2000, 1000, 1000]);
253
- });
254
- it("falls back to loopback when the doctor API is absent", async () => {
255
- assert.equal(await resolveLanExposureHost({}, 9000), "127.0.0.1");
256
- });
257
- it("falls back to loopback when doctor.selfDeployment is absent", async () => {
258
- assert.equal(await resolveLanExposureHost({ doctor: {} }, 9000), "127.0.0.1");
259
- });
260
- it("falls back to loopback when doctor.selfDeployment throws", async () => {
261
- const { calls, probe } = recordingProbe(["127.0.0.1"]);
262
- const host = await resolveLanExposureHost({
263
- doctor: {
264
- selfDeployment: async () => {
265
- throw new Error("probe failed");
266
- },
267
- },
268
- }, 9000, undefined, { probe, ...noRetry });
269
- assert.equal(host, "127.0.0.1");
270
- assert.deepEqual(calls, []);
271
- });
272
- it("does NOT consult a top-level selfDeployment (wrong API shape)", async () => {
273
- let called = false;
274
- const host = await resolveLanExposureHost({
275
- // Deliberately the wrong nesting — must be ignored.
276
- selfDeployment: async () => {
277
- called = true;
278
- return { isContainerized: true };
279
- },
280
- }, 9000);
281
- assert.equal(called, false);
282
- assert.equal(host, "127.0.0.1");
283
- });
284
- });
285
- describe("lanExposureEndpoints", () => {
286
- it("uses the supplied host and the configured host ports", () => {
287
- assert.deepEqual(lanExposureEndpoints("127.0.0.1", 9000, 9009), {
288
- http: { host: "127.0.0.1", port: 9000 },
289
- ilp: { host: "127.0.0.1", port: 9009 },
290
- });
291
- assert.deepEqual(lanExposureEndpoints(HOST_GATEWAY, 9500, 9509), {
292
- http: { host: HOST_GATEWAY, port: 9500 },
293
- ilp: { host: HOST_GATEWAY, port: 9509 },
294
- });
295
- });
296
- });
297
- //# sourceMappingURL=questdb-endpoint.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"questdb-endpoint.test.js","sourceRoot":"","sources":["../../src/test/questdb-endpoint.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,MAAM,MAAM,oBAAoB,CAAC;AACxC,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,OAAO,EACL,aAAa,EACb,uBAAuB,EACvB,sBAAsB,EACtB,oBAAoB,EACpB,gBAAgB,EAChB,YAAY,EACZ,0BAA0B,EAC1B,yBAAyB,GAC1B,MAAM,wBAAwB,CAAC;AAEhC,QAAQ,CAAC,eAAe,EAAE,GAAG,EAAE;IAC7B,EAAE,CAAC,kBAAkB,EAAE,GAAG,EAAE;QAC1B,MAAM,CAAC,SAAS,CAAC,aAAa,CAAC,gBAAgB,EAAE,CAAC,CAAC,EAAE;YACnD,IAAI,EAAE,WAAW;YACjB,IAAI,EAAE,IAAI;SACX,CAAC,CAAC;QACH,MAAM,CAAC,SAAS,CAAC,aAAa,CAAC,yBAAyB,EAAE,CAAC,CAAC,EAAE;YAC5D,IAAI,EAAE,oBAAoB;YAC1B,IAAI,EAAE,IAAI;SACX,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,4CAA4C,EAAE,GAAG,EAAE;QACpD,MAAM,CAAC,SAAS,CAAC,aAAa,CAAC,eAAe,EAAE,IAAI,CAAC,EAAE;YACrD,IAAI,EAAE,eAAe;YACrB,IAAI,EAAE,IAAI;SACX,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,+CAA+C,EAAE,GAAG,EAAE;QACvD,MAAM,CAAC,SAAS,CAAC,aAAa,CAAC,YAAY,EAAE,CAAC,CAAC,EAAE;YAC/C,IAAI,EAAE,KAAK;YACX,IAAI,EAAE,IAAI;SACX,CAAC,CAAC;QACH,MAAM,CAAC,SAAS,CAAC,aAAa,CAAC,WAAW,EAAE,IAAI,CAAC,EAAE;YACjD,IAAI,EAAE,SAAS;YACf,IAAI,EAAE,IAAI;SACX,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,kDAAkD,EAAE,GAAG,EAAE;QAC1D,uEAAuE;QACvE,sCAAsC;QACtC,MAAM,CAAC,SAAS,CAAC,aAAa,CAAC,SAAS,EAAE,IAAI,CAAC,EAAE;YAC/C,IAAI,EAAE,SAAS;YACf,IAAI,EAAE,IAAI;SACX,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,mDAAmD,EAAE,GAAG,EAAE;QAC3D,MAAM,CAAC,KAAK,CAAC,aAAa,CAAC,EAAE,EAAE,IAAI,CAAC,EAAE,IAAI,CAAC,CAAC;QAC5C,MAAM,CAAC,KAAK,CAAC,aAAa,CAAC,KAAK,EAAE,IAAI,CAAC,EAAE,IAAI,CAAC,CAAC;QAC/C,MAAM,CAAC,KAAK,CAAC,aAAa,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,IAAI,CAAC,CAAC;QAC9C,MAAM,CAAC,KAAK,CAAC,aAAa,CAAC,SAAS,EAAE,IAAI,CAAC,EAAE,IAAI,CAAC,CAAC;QACnD,MAAM,CAAC,KAAK,CAAC,aAAa,CAAC,eAAe,EAAE,IAAI,CAAC,EAAE,IAAI,CAAC,CAAC;QACzD,MAAM,CAAC,KAAK,CAAC,aAAa,CAAC,QAAQ,EAAE,IAAI,CAAC,EAAE,IAAI,CAAC,CAAC;QAClD,MAAM,CAAC,KAAK,CAAC,aAAa,CAAC,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,CAAC,CAAC;QACjD,MAAM,CAAC,KAAK,CAAC,aAAa,CAAC,SAAS,EAAE,IAAI,CAAC,EAAE,IAAI,CAAC,CAAC;IACrD,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,yBAAyB,EAAE,GAAG,EAAE;IACvC,EAAE,CAAC,qDAAqD,EAAE,KAAK,IAAI,EAAE;QACnE,MAAM,KAAK,GAA4B,EAAE,CAAC;QAC1C,MAAM,UAAU,GAAG;YACjB,uBAAuB,EAAE,KAAK,EAAE,IAAY,EAAE,IAAY,EAAE,EAAE;gBAC5D,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC;gBACzB,OAAO,IAAI,KAAK,0BAA0B;oBACxC,CAAC,CAAC,yBAAyB;oBAC3B,CAAC,CAAC,yBAAyB,CAAC;YAChC,CAAC;SACF,CAAC;QACF,MAAM,EAAE,GAAG,MAAM,uBAAuB,CACtC,UAAU,EACV,iBAAiB,EACjB,WAAW,CACZ,CAAC;QACF,MAAM,CAAC,SAAS,CAAC,EAAE,CAAC,IAAI,EAAE,EAAE,IAAI,EAAE,oBAAoB,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;QACtE,MAAM,CAAC,SAAS,CAAC,EAAE,CAAC,GAAG,EAAE,EAAE,IAAI,EAAE,oBAAoB,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;QACrE,MAAM,CAAC,SAAS,CAAC,KAAK,EAAE;YACtB,CAAC,iBAAiB,EAAE,0BAA0B,CAAC;YAC/C,CAAC,iBAAiB,EAAE,yBAAyB,CAAC;SAC/C,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,wDAAwD,EAAE,KAAK,IAAI,EAAE;QACtE,MAAM,UAAU,GAAG;YACjB,uBAAuB,EAAE,KAAK,EAAE,KAAa,EAAE,IAAY,EAAE,EAAE,CAC7D,IAAI,KAAK,0BAA0B;gBACjC,CAAC,CAAC,gBAAgB,CAAC,0CAA0C;gBAC7D,CAAC,CAAC,gBAAgB;SACvB,CAAC;QACF,MAAM,EAAE,GAAG,MAAM,uBAAuB,CACtC,UAAU,EACV,iBAAiB,EACjB,WAAW,CACZ,CAAC;QACF,MAAM,CAAC,SAAS,CAAC,EAAE,CAAC,IAAI,EAAE,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;IAC/D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,0EAA0E,EAAE,KAAK,IAAI,EAAE;QACxF,MAAM,EAAE,GAAG,MAAM,uBAAuB,CAAC,EAAE,EAAE,iBAAiB,EAAE,UAAU,CAAC,CAAC;QAC5E,MAAM,CAAC,SAAS,CAAC,EAAE,CAAC,IAAI,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;QAC5D,MAAM,CAAC,SAAS,CAAC,EAAE,CAAC,GAAG,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;IAC7D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sDAAsD,EAAE,KAAK,IAAI,EAAE;QACpE,MAAM,UAAU,GAAG;YACjB,uBAAuB,EAAE,KAAK,IAAI,EAAE,CAAC,IAAI;SAC1C,CAAC;QACF,MAAM,EAAE,GAAG,MAAM,uBAAuB,CACtC,UAAU,EACV,iBAAiB,EACjB,WAAW,CACZ,CAAC;QACF,MAAM,CAAC,SAAS,CAAC,EAAE,CAAC,IAAI,EAAE,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;QAC7D,MAAM,CAAC,SAAS,CAAC,EAAE,CAAC,GAAG,EAAE,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;IAC9D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,gDAAgD,EAAE,KAAK,IAAI,EAAE;QAC9D,MAAM,UAAU,GAAG;YACjB,uBAAuB,EAAE,KAAK,IAAI,EAAE;gBAClC,MAAM,IAAI,KAAK,CAAC,mBAAmB,CAAC,CAAC;YACvC,CAAC;SACF,CAAC;QACF,MAAM,EAAE,GAAG,MAAM,uBAAuB,CACtC,UAAU,EACV,iBAAiB,EACjB,WAAW,CACZ,CAAC;QACF,MAAM,CAAC,SAAS,CAAC,EAAE,CAAC,IAAI,EAAE,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;IAC/D,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,kBAAkB,EAAE,GAAG,EAAE;IAChC,yEAAyE;IACzE,0CAA0C;IAC1C,SAAS,KAAK,CACZ,OAAsE;QAEtE,MAAM,MAAM,GAAG,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC;QAC1C,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAC7B,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,WAAW,EAAE,GAAG,EAAE,CACjC,OAAO,CAAC;YACN,IAAI,EAAG,MAAM,CAAC,OAAO,EAAkB,CAAC,IAAI;YAC5C,KAAK,EAAE,GAAG,EAAE,CACV,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE;gBAChB,MAAM,CAAC,mBAAmB,EAAE,CAAC;gBAC7B,MAAM,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC;YACnC,CAAC,CAAC;SACL,CAAC,CACH,CACF,CAAC;IACJ,CAAC;IAED,EAAE,CAAC,qCAAqC,EAAE,KAAK,IAAI,EAAE;QACnD,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,MAAM,KAAK,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE;YAC/C,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;YAC/B,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC;QAC3B,CAAC,CAAC,CAAC;QACH,IAAI,CAAC;YACH,MAAM,CAAC,KAAK,CAAC,MAAM,gBAAgB,CAAC,WAAW,EAAE,IAAI,CAAC,EAAE,IAAI,CAAC,CAAC;QAChE,CAAC;gBAAS,CAAC;YACT,MAAM,KAAK,EAAE,CAAC;QAChB,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,8DAA8D,EAAE,KAAK,IAAI,EAAE;QAC5E,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,MAAM,KAAK,CAAC,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE;YAChD,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;QACxC,CAAC,CAAC,CAAC;QACH,IAAI,CAAC;YACH,MAAM,CAAC,KAAK,CAAC,MAAM,gBAAgB,CAAC,WAAW,EAAE,IAAI,CAAC,EAAE,KAAK,CAAC,CAAC;QACjE,CAAC;gBAAS,CAAC;YACT,MAAM,KAAK,EAAE,CAAC;QAChB,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uCAAuC,EAAE,KAAK,IAAI,EAAE;QACrD,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,MAAM,KAAK,CAAC,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC;QAC9D,MAAM,KAAK,EAAE,CAAC;QACd,MAAM,CAAC,KAAK,CAAC,MAAM,gBAAgB,CAAC,WAAW,EAAE,IAAI,CAAC,EAAE,KAAK,CAAC,CAAC;IACjE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,gEAAgE,EAAE,KAAK,IAAI,EAAE;QAC9E,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;YACvC,2BAA2B;QAC7B,CAAC,CAAC,CAAC;QACH,IAAI,CAAC;YACH,MAAM,CAAC,KAAK,CAAC,MAAM,gBAAgB,CAAC,WAAW,EAAE,IAAI,EAAE,GAAG,CAAC,EAAE,KAAK,CAAC,CAAC;QACtE,CAAC;gBAAS,CAAC;YACT,MAAM,KAAK,EAAE,CAAC;QAChB,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,wBAAwB,EAAE,GAAG,EAAE;IACtC,sEAAsE;IACtE,6CAA6C;IAC7C,SAAS,cAAc,CAAC,OAAiB;QACvC,MAAM,KAAK,GAAa,EAAE,CAAC;QAC3B,OAAO;YACL,KAAK;YACL,KAAK,EAAE,KAAK,EAAE,IAAY,EAAE,IAAY,EAAE,EAAE;gBAC1C,KAAK,CAAC,IAAI,CAAC,GAAG,IAAI,IAAI,IAAI,EAAE,CAAC,CAAC;gBAC9B,OAAO,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;YAChC,CAAC;SACF,CAAC;IACJ,CAAC;IACD,MAAM,aAAa,GAAG;QACpB,MAAM,EAAE,EAAE,cAAc,EAAE,KAAK,IAAI,EAAE,CAAC,CAAC,EAAE,eAAe,EAAE,IAAI,EAAE,CAAC,EAAE;KACpE,CAAC;IACF,MAAM,OAAO,GAAG,EAAE,UAAU,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,CAAC;IAEjD,EAAE,CAAC,0DAA0D,EAAE,KAAK,IAAI,EAAE;QACxE,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,cAAc,CAAC,EAAE,CAAC,CAAC;QAC5C,MAAM,IAAI,GAAG,MAAM,sBAAsB,CACvC;YACE,MAAM,EAAE,EAAE,cAAc,EAAE,KAAK,IAAI,EAAE,CAAC,CAAC,EAAE,eAAe,EAAE,KAAK,EAAE,CAAC,EAAE;SACrE,EACD,IAAI,EACJ,SAAS,EACT,EAAE,KAAK,EAAE,GAAG,OAAO,EAAE,CACtB,CAAC;QACF,MAAM,CAAC,KAAK,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;QAChC,MAAM,CAAC,SAAS,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;IAC9B,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,gFAAgF,EAAE,KAAK,IAAI,EAAE;QAC9F,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,cAAc,CAAC,CAAC,WAAW,EAAE,YAAY,CAAC,CAAC,CAAC;QACrE,MAAM,IAAI,GAAG,MAAM,sBAAsB,CAAC,aAAa,EAAE,IAAI,EAAE,SAAS,EAAE;YACxE,KAAK;YACL,GAAG,OAAO;SACX,CAAC,CAAC;QACH,MAAM,CAAC,KAAK,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;QAChC,MAAM,CAAC,SAAS,CAAC,KAAK,EAAE,CAAC,gBAAgB,CAAC,CAAC,CAAC;IAC9C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,gFAAgF,EAAE,KAAK,IAAI,EAAE;QAC9F,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,cAAc,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC;QACxD,MAAM,IAAI,GAAG,MAAM,sBAAsB,CAAC,aAAa,EAAE,IAAI,EAAE,SAAS,EAAE;YACxE,KAAK;YACL,GAAG,OAAO;SACX,CAAC,CAAC;QACH,MAAM,CAAC,KAAK,CAAC,IAAI,EAAE,YAAY,CAAC,CAAC;QACjC,MAAM,CAAC,SAAS,CAAC,KAAK,EAAE,CAAC,gBAAgB,EAAE,GAAG,YAAY,OAAO,CAAC,CAAC,CAAC;IACtE,CAAC,CAAC,CAAC;IAEH,yEAAyE;IACzE,qEAAqE;IACrE,kCAAkC;IAClC,SAAS,SAAS;QAChB,IAAI,CAAC,GAAG,CAAC,CAAC;QACV,OAAO;YACL,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC;YACZ,KAAK,EAAE,KAAK,EAAE,EAAU,EAAE,EAAE;gBAC1B,CAAC,IAAI,EAAE,CAAC;YACV,CAAC;SACF,CAAC;IACJ,CAAC;IAED,EAAE,CAAC,+EAA+E,EAAE,KAAK,IAAI,EAAE;QAC7F,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,cAAc,CAAC,EAAE,CAAC,CAAC;QAC5C,MAAM,IAAI,GAAG,MAAM,sBAAsB,CAAC,aAAa,EAAE,IAAI,EAAE,SAAS,EAAE;YACxE,KAAK;YACL,UAAU,EAAE,IAAI;YAChB,UAAU,EAAE,IAAI;YAChB,GAAG,SAAS,EAAE;SACf,CAAC,CAAC;QACH,MAAM,CAAC,KAAK,CAAC,IAAI,EAAE,YAAY,CAAC,CAAC;QACjC,oEAAoE;QACpE,uCAAuC;QACvC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;IAChC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,wDAAwD,EAAE,KAAK,IAAI,EAAE;QACtE,IAAI,KAAK,GAAG,CAAC,CAAC;QACd,MAAM,IAAI,GAAG,MAAM,sBAAsB,CAAC,aAAa,EAAE,IAAI,EAAE,SAAS,EAAE;YACxE,KAAK,EAAE,KAAK,EAAE,SAAiB,EAAE,EAAE;gBACjC,IAAI,SAAS,KAAK,WAAW;oBAAE,KAAK,EAAE,CAAC;gBACvC,OAAO,SAAS,KAAK,WAAW,IAAI,KAAK,IAAI,CAAC,CAAC;YACjD,CAAC;YACD,UAAU,EAAE,MAAM;YAClB,UAAU,EAAE,IAAI;YAChB,GAAG,SAAS,EAAE;SACf,CAAC,CAAC;QACH,MAAM,CAAC,KAAK,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;QAChC,MAAM,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;IACzB,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,oEAAoE,EAAE,KAAK,IAAI,EAAE;QAClF,MAAM,OAAO,GAA2B,EAAE,CAAC;QAC3C,MAAM,KAAK,GAAG,SAAS,EAAE,CAAC;QAC1B,MAAM,sBAAsB,CAAC,aAAa,EAAE,IAAI,EAAE,SAAS,EAAE;YAC3D,KAAK,EAAE,KAAK,EAAE,KAAa,EAAE,KAAa,EAAE,SAAkB,EAAE,EAAE;gBAChE,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;gBACxB,OAAO,KAAK,CAAC;YACf,CAAC;YACD,UAAU,EAAE,IAAI;YAChB,UAAU,EAAE,IAAI;YAChB,GAAG,KAAK;SACT,CAAC,CAAC;QACH,0EAA0E;QAC1E,oDAAoD;QACpD,MAAM,CAAC,SAAS,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC;IACtD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sDAAsD,EAAE,KAAK,IAAI,EAAE;QACpE,MAAM,CAAC,KAAK,CAAC,MAAM,sBAAsB,CAAC,EAAE,EAAE,IAAI,CAAC,EAAE,WAAW,CAAC,CAAC;IACpE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,6DAA6D,EAAE,KAAK,IAAI,EAAE;QAC3E,MAAM,CAAC,KAAK,CACV,MAAM,sBAAsB,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,IAAI,CAAC,EAClD,WAAW,CACZ,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,0DAA0D,EAAE,KAAK,IAAI,EAAE;QACxE,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,cAAc,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC;QACvD,MAAM,IAAI,GAAG,MAAM,sBAAsB,CACvC;YACE,MAAM,EAAE;gBACN,cAAc,EAAE,KAAK,IAAI,EAAE;oBACzB,MAAM,IAAI,KAAK,CAAC,cAAc,CAAC,CAAC;gBAClC,CAAC;aACF;SACF,EACD,IAAI,EACJ,SAAS,EACT,EAAE,KAAK,EAAE,GAAG,OAAO,EAAE,CACtB,CAAC;QACF,MAAM,CAAC,KAAK,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;QAChC,MAAM,CAAC,SAAS,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;IAC9B,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,+DAA+D,EAAE,KAAK,IAAI,EAAE;QAC7E,IAAI,MAAM,GAAG,KAAK,CAAC;QACnB,MAAM,IAAI,GAAG,MAAM,sBAAsB,CACvC;YACE,oDAAoD;YACpD,cAAc,EAAE,KAAK,IAAI,EAAE;gBACzB,MAAM,GAAG,IAAI,CAAC;gBACd,OAAO,EAAE,eAAe,EAAE,IAAI,EAAE,CAAC;YACnC,CAAC;SACO,EACV,IAAI,CACL,CAAC;QACF,MAAM,CAAC,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;QAC5B,MAAM,CAAC,KAAK,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;IAClC,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,sBAAsB,EAAE,GAAG,EAAE;IACpC,EAAE,CAAC,sDAAsD,EAAE,GAAG,EAAE;QAC9D,MAAM,CAAC,SAAS,CAAC,oBAAoB,CAAC,WAAW,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE;YAC9D,IAAI,EAAE,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,IAAI,EAAE;YACvC,GAAG,EAAE,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,IAAI,EAAE;SACvC,CAAC,CAAC;QACH,MAAM,CAAC,SAAS,CAAC,oBAAoB,CAAC,YAAY,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE;YAC/D,IAAI,EAAE,EAAE,IAAI,EAAE,YAAY,EAAE,IAAI,EAAE,IAAI,EAAE;YACxC,GAAG,EAAE,EAAE,IAAI,EAAE,YAAY,EAAE,IAAI,EAAE,IAAI,EAAE;SACxC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -1 +0,0 @@
1
- export {};