@rawdash/core 0.14.0 → 0.16.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +11 -8
- package/dist/index.d.ts +214 -18
- package/dist/index.js +549 -86
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -291,8 +291,79 @@ function computeDelay(attempt, initialDelayMs, maxDelayMs) {
|
|
|
291
291
|
const jitter = base * 0.25 * Math.random();
|
|
292
292
|
return Math.min(base + jitter, maxDelayMs);
|
|
293
293
|
}
|
|
294
|
+
var MAX_VALUE_LEN = 120;
|
|
295
|
+
function truncate(s, max = MAX_VALUE_LEN) {
|
|
296
|
+
if (s.length <= max) {
|
|
297
|
+
return s;
|
|
298
|
+
}
|
|
299
|
+
return `${s.slice(0, max - 1)}\u2026`;
|
|
300
|
+
}
|
|
301
|
+
function formatValue(value) {
|
|
302
|
+
if (value === null) {
|
|
303
|
+
return "null";
|
|
304
|
+
}
|
|
305
|
+
if (value === void 0) {
|
|
306
|
+
return "";
|
|
307
|
+
}
|
|
308
|
+
if (typeof value === "number" || typeof value === "boolean") {
|
|
309
|
+
return String(value);
|
|
310
|
+
}
|
|
311
|
+
if (typeof value === "string") {
|
|
312
|
+
const t = truncate(value);
|
|
313
|
+
if (/[\s"=]/.test(t)) {
|
|
314
|
+
return JSON.stringify(t);
|
|
315
|
+
}
|
|
316
|
+
return t;
|
|
317
|
+
}
|
|
318
|
+
if (typeof value === "bigint") {
|
|
319
|
+
return value.toString();
|
|
320
|
+
}
|
|
321
|
+
let json;
|
|
322
|
+
try {
|
|
323
|
+
json = JSON.stringify(value);
|
|
324
|
+
} catch {
|
|
325
|
+
json = void 0;
|
|
326
|
+
}
|
|
327
|
+
return truncate(json ?? String(value));
|
|
328
|
+
}
|
|
329
|
+
function formatLogFields(fields) {
|
|
330
|
+
if (!fields) {
|
|
331
|
+
return "";
|
|
332
|
+
}
|
|
333
|
+
const parts = [];
|
|
334
|
+
for (const [k, v] of Object.entries(fields)) {
|
|
335
|
+
if (v === void 0) {
|
|
336
|
+
continue;
|
|
337
|
+
}
|
|
338
|
+
parts.push(`${k}=${formatValue(v)}`);
|
|
339
|
+
}
|
|
340
|
+
return parts.length > 0 ? ` ${parts.join(" ")}` : "";
|
|
341
|
+
}
|
|
342
|
+
function formatLogLine(scope, event, fields) {
|
|
343
|
+
return `[${scope}] ${event}${formatLogFields(fields)}`;
|
|
344
|
+
}
|
|
345
|
+
function createDefaultConnectorLogger(opts) {
|
|
346
|
+
return {
|
|
347
|
+
info(event, fields) {
|
|
348
|
+
console.info(formatLogLine(opts.scope, event, fields));
|
|
349
|
+
},
|
|
350
|
+
warn(event, fields) {
|
|
351
|
+
console.warn(formatLogLine(opts.scope, event, fields));
|
|
352
|
+
}
|
|
353
|
+
};
|
|
354
|
+
}
|
|
355
|
+
var NOOP_LOGGER = {
|
|
356
|
+
info() {
|
|
357
|
+
},
|
|
358
|
+
warn() {
|
|
359
|
+
}
|
|
360
|
+
};
|
|
361
|
+
function noopConnectorLogger() {
|
|
362
|
+
return NOOP_LOGGER;
|
|
363
|
+
}
|
|
294
364
|
|
|
295
365
|
// src/secrets.ts
|
|
366
|
+
import { z } from "zod";
|
|
296
367
|
function secret(name) {
|
|
297
368
|
if (!/^[A-Z][A-Z0-9_]*$/.test(name)) {
|
|
298
369
|
throw new Error(
|
|
@@ -304,10 +375,31 @@ function secret(name) {
|
|
|
304
375
|
function isSecret(value) {
|
|
305
376
|
return typeof value === "object" && value !== null && "$secret" in value && typeof value.$secret === "string";
|
|
306
377
|
}
|
|
378
|
+
var secretRefSchema = z.strictObject({
|
|
379
|
+
$secret: z.string()
|
|
380
|
+
});
|
|
381
|
+
function withSecretRef(schema) {
|
|
382
|
+
return z.union([schema, secretRefSchema]);
|
|
383
|
+
}
|
|
307
384
|
var EnvSecretsResolver = class {
|
|
308
385
|
resolve(name) {
|
|
309
386
|
const env = globalThis.process?.env;
|
|
310
|
-
|
|
387
|
+
const raw = env?.[name];
|
|
388
|
+
if (raw === void 0) {
|
|
389
|
+
return void 0;
|
|
390
|
+
}
|
|
391
|
+
if (raw.length === 0) {
|
|
392
|
+
return raw;
|
|
393
|
+
}
|
|
394
|
+
const first = raw.charCodeAt(0);
|
|
395
|
+
if (first !== 123 && first !== 91) {
|
|
396
|
+
return raw;
|
|
397
|
+
}
|
|
398
|
+
try {
|
|
399
|
+
return JSON.parse(raw);
|
|
400
|
+
} catch {
|
|
401
|
+
return raw;
|
|
402
|
+
}
|
|
311
403
|
}
|
|
312
404
|
};
|
|
313
405
|
function extractSecretNames(value) {
|
|
@@ -364,6 +456,7 @@ var BaseConnector = class {
|
|
|
364
456
|
creds;
|
|
365
457
|
rawCredInput;
|
|
366
458
|
ctx;
|
|
459
|
+
cachedLogger;
|
|
367
460
|
constructor(settings, creds, ctx) {
|
|
368
461
|
this.settings = settings;
|
|
369
462
|
this.rawCredInput = creds;
|
|
@@ -373,6 +466,12 @@ var BaseConnector = class {
|
|
|
373
466
|
this.ctx.secretsResolver ?? new EnvSecretsResolver()
|
|
374
467
|
) : {};
|
|
375
468
|
}
|
|
469
|
+
get logger() {
|
|
470
|
+
if (!this.cachedLogger) {
|
|
471
|
+
this.cachedLogger = this.ctx.logger ?? createDefaultConnectorLogger({ scope: this.id });
|
|
472
|
+
}
|
|
473
|
+
return this.cachedLogger;
|
|
474
|
+
}
|
|
376
475
|
request(req, opts) {
|
|
377
476
|
return request(req, {
|
|
378
477
|
resource: opts.resource,
|
|
@@ -405,6 +504,13 @@ var BaseConnector = class {
|
|
|
405
504
|
{ resource: opts.resource, requestId: opts.requestId }
|
|
406
505
|
);
|
|
407
506
|
}
|
|
507
|
+
isResourceEnabled(resource) {
|
|
508
|
+
const enabled = this.settings?.resources;
|
|
509
|
+
if (!enabled || enabled.length === 0) {
|
|
510
|
+
return true;
|
|
511
|
+
}
|
|
512
|
+
return enabled.includes(resource);
|
|
513
|
+
}
|
|
408
514
|
serializeConfig() {
|
|
409
515
|
const config = {
|
|
410
516
|
...this.settings
|
|
@@ -478,8 +584,44 @@ function defineConnector() {
|
|
|
478
584
|
}
|
|
479
585
|
|
|
480
586
|
// src/paginate-chunked.ts
|
|
587
|
+
function selectActivePhases(resourceToPhase, order, enabled) {
|
|
588
|
+
if (!enabled || enabled.length === 0) {
|
|
589
|
+
return [...order];
|
|
590
|
+
}
|
|
591
|
+
const want = /* @__PURE__ */ new Set();
|
|
592
|
+
for (const r of enabled) {
|
|
593
|
+
want.add(resourceToPhase(r));
|
|
594
|
+
}
|
|
595
|
+
return order.filter((p) => want.has(p));
|
|
596
|
+
}
|
|
597
|
+
function makeChunkedCursorGuard(phases) {
|
|
598
|
+
const phaseSet = new Set(phases);
|
|
599
|
+
return (value) => {
|
|
600
|
+
if (typeof value !== "object" || value === null) {
|
|
601
|
+
return false;
|
|
602
|
+
}
|
|
603
|
+
const v = value;
|
|
604
|
+
if (typeof v.phase !== "string" || !phaseSet.has(v.phase)) {
|
|
605
|
+
return false;
|
|
606
|
+
}
|
|
607
|
+
if (v.page !== null && typeof v.page !== "string") {
|
|
608
|
+
return false;
|
|
609
|
+
}
|
|
610
|
+
return true;
|
|
611
|
+
};
|
|
612
|
+
}
|
|
613
|
+
function truncateCursor(page) {
|
|
614
|
+
if (page === null || page === void 0) {
|
|
615
|
+
return void 0;
|
|
616
|
+
}
|
|
617
|
+
const s = typeof page === "string" ? page : JSON.stringify(page);
|
|
618
|
+
if (s.length <= 80) {
|
|
619
|
+
return s;
|
|
620
|
+
}
|
|
621
|
+
return `${s.slice(0, 79)}\u2026`;
|
|
622
|
+
}
|
|
481
623
|
async function paginateChunked(opts) {
|
|
482
|
-
const { phases, cursor, signal, fetchPage, writeBatch } = opts;
|
|
624
|
+
const { phases, cursor, signal, fetchPage, writeBatch, logger } = opts;
|
|
483
625
|
if (phases.length === 0) {
|
|
484
626
|
return { done: true };
|
|
485
627
|
}
|
|
@@ -489,6 +631,9 @@ async function paginateChunked(opts) {
|
|
|
489
631
|
for (let i = startIdx; i < phases.length; i++) {
|
|
490
632
|
const phase = phases[i];
|
|
491
633
|
let page = i === startIdx && hasKnownResumePhase ? cursor.page : null;
|
|
634
|
+
let pageCount = 0;
|
|
635
|
+
let itemCount = 0;
|
|
636
|
+
const phaseStart = Date.now();
|
|
492
637
|
while (true) {
|
|
493
638
|
if (signal?.aborted) {
|
|
494
639
|
return {
|
|
@@ -496,6 +641,7 @@ async function paginateChunked(opts) {
|
|
|
496
641
|
cursor: { phase, page }
|
|
497
642
|
};
|
|
498
643
|
}
|
|
644
|
+
pageCount += 1;
|
|
499
645
|
let items;
|
|
500
646
|
let next;
|
|
501
647
|
try {
|
|
@@ -507,12 +653,26 @@ async function paginateChunked(opts) {
|
|
|
507
653
|
cursor: { phase, page }
|
|
508
654
|
};
|
|
509
655
|
}
|
|
656
|
+
logger?.warn("fetch page failed", {
|
|
657
|
+
resource: phase,
|
|
658
|
+
page: pageCount,
|
|
659
|
+
cursor: truncateCursor(page),
|
|
660
|
+
error: err instanceof Error ? err.message : String(err)
|
|
661
|
+
});
|
|
510
662
|
return {
|
|
511
663
|
done: false,
|
|
512
664
|
cursor: { phase, page },
|
|
513
665
|
transientError: err
|
|
514
666
|
};
|
|
515
667
|
}
|
|
668
|
+
itemCount += items.length;
|
|
669
|
+
logger?.info("fetched page", {
|
|
670
|
+
resource: phase,
|
|
671
|
+
page: pageCount,
|
|
672
|
+
items: items.length,
|
|
673
|
+
cursor: truncateCursor(page),
|
|
674
|
+
next: truncateCursor(next)
|
|
675
|
+
});
|
|
516
676
|
try {
|
|
517
677
|
await writeBatch(phase, items, page);
|
|
518
678
|
} catch (err) {
|
|
@@ -522,6 +682,12 @@ async function paginateChunked(opts) {
|
|
|
522
682
|
cursor: { phase, page }
|
|
523
683
|
};
|
|
524
684
|
}
|
|
685
|
+
logger?.warn("write batch failed", {
|
|
686
|
+
resource: phase,
|
|
687
|
+
page: pageCount,
|
|
688
|
+
cursor: truncateCursor(page),
|
|
689
|
+
error: err instanceof Error ? err.message : String(err)
|
|
690
|
+
});
|
|
525
691
|
return {
|
|
526
692
|
done: false,
|
|
527
693
|
cursor: { phase, page },
|
|
@@ -533,20 +699,26 @@ async function paginateChunked(opts) {
|
|
|
533
699
|
}
|
|
534
700
|
page = next;
|
|
535
701
|
}
|
|
702
|
+
logger?.info("resource done", {
|
|
703
|
+
resource: phase,
|
|
704
|
+
pages: pageCount,
|
|
705
|
+
items: itemCount,
|
|
706
|
+
duration_ms: Date.now() - phaseStart
|
|
707
|
+
});
|
|
536
708
|
}
|
|
537
709
|
return { done: true };
|
|
538
710
|
}
|
|
539
711
|
|
|
540
712
|
// src/widget-schemas.ts
|
|
541
|
-
import { z } from "zod";
|
|
542
|
-
var shapeSchema =
|
|
713
|
+
import { z as z2 } from "zod";
|
|
714
|
+
var shapeSchema = z2.enum([
|
|
543
715
|
"event",
|
|
544
716
|
"entity",
|
|
545
717
|
"metric",
|
|
546
718
|
"edge",
|
|
547
719
|
"distribution"
|
|
548
720
|
]);
|
|
549
|
-
var aggFnSchema =
|
|
721
|
+
var aggFnSchema = z2.enum([
|
|
550
722
|
"count",
|
|
551
723
|
"sum",
|
|
552
724
|
"avg",
|
|
@@ -555,7 +727,7 @@ var aggFnSchema = z.enum([
|
|
|
555
727
|
"latest",
|
|
556
728
|
"first"
|
|
557
729
|
]);
|
|
558
|
-
var filterOperatorSchema =
|
|
730
|
+
var filterOperatorSchema = z2.enum([
|
|
559
731
|
"eq",
|
|
560
732
|
"neq",
|
|
561
733
|
"gt",
|
|
@@ -564,70 +736,70 @@ var filterOperatorSchema = z.enum([
|
|
|
564
736
|
"lte",
|
|
565
737
|
"contains"
|
|
566
738
|
]);
|
|
567
|
-
var filterConditionSchema =
|
|
568
|
-
field:
|
|
739
|
+
var filterConditionSchema = z2.object({
|
|
740
|
+
field: z2.string(),
|
|
569
741
|
op: filterOperatorSchema,
|
|
570
|
-
value:
|
|
742
|
+
value: z2.union([z2.string(), z2.number(), z2.boolean()])
|
|
571
743
|
});
|
|
572
|
-
var filterClauseSchema =
|
|
744
|
+
var filterClauseSchema = z2.union([
|
|
573
745
|
filterConditionSchema,
|
|
574
|
-
|
|
746
|
+
z2.object({ or: z2.array(filterConditionSchema) })
|
|
575
747
|
]);
|
|
576
|
-
var groupBySchema =
|
|
577
|
-
field:
|
|
578
|
-
granularity:
|
|
748
|
+
var groupBySchema = z2.object({
|
|
749
|
+
field: z2.string(),
|
|
750
|
+
granularity: z2.enum(["hour", "day", "week", "month"])
|
|
579
751
|
});
|
|
580
|
-
var computedMetricSchema =
|
|
581
|
-
connectorId:
|
|
752
|
+
var computedMetricSchema = z2.object({
|
|
753
|
+
connectorId: z2.string(),
|
|
582
754
|
shape: shapeSchema,
|
|
583
|
-
name:
|
|
584
|
-
entityType:
|
|
585
|
-
field:
|
|
755
|
+
name: z2.string().optional(),
|
|
756
|
+
entityType: z2.string().optional(),
|
|
757
|
+
field: z2.string().optional(),
|
|
586
758
|
fn: aggFnSchema,
|
|
587
|
-
window:
|
|
588
|
-
filter:
|
|
759
|
+
window: z2.string().optional(),
|
|
760
|
+
filter: z2.array(filterClauseSchema).optional(),
|
|
589
761
|
groupBy: groupBySchema.optional()
|
|
590
762
|
}).refine((m) => m.fn === "count" || m.field !== void 0, {
|
|
591
763
|
message: 'field is required unless fn is "count"',
|
|
592
764
|
path: ["field"]
|
|
593
765
|
});
|
|
594
|
-
var titleField =
|
|
595
|
-
var statWidgetSchema =
|
|
596
|
-
kind:
|
|
766
|
+
var titleField = z2.string().meta({ label: "Title", description: "Widget title." });
|
|
767
|
+
var statWidgetSchema = z2.object({
|
|
768
|
+
kind: z2.literal("stat"),
|
|
597
769
|
title: titleField,
|
|
598
770
|
metric: computedMetricSchema.meta({
|
|
599
771
|
label: "Metric",
|
|
600
772
|
description: "Computed metric definition."
|
|
601
773
|
}),
|
|
602
|
-
window:
|
|
603
|
-
compare:
|
|
774
|
+
window: z2.string().optional().meta({ label: "Window", description: "Time window, e.g. '7d'." }),
|
|
775
|
+
compare: z2.enum(["none", "previous-period"]).default("none").meta({ label: "Compare", description: "Comparison mode." })
|
|
604
776
|
});
|
|
605
|
-
var statusWidgetSchema =
|
|
606
|
-
kind:
|
|
777
|
+
var statusWidgetSchema = z2.object({
|
|
778
|
+
kind: z2.literal("status"),
|
|
607
779
|
title: titleField,
|
|
608
|
-
source:
|
|
780
|
+
source: z2.string().meta({
|
|
609
781
|
label: "Source",
|
|
610
782
|
description: "Connector or data source reference."
|
|
611
783
|
})
|
|
612
784
|
});
|
|
613
|
-
var timeseriesWidgetSchema =
|
|
614
|
-
kind:
|
|
785
|
+
var timeseriesWidgetSchema = z2.object({
|
|
786
|
+
kind: z2.literal("timeseries"),
|
|
615
787
|
title: titleField,
|
|
616
788
|
metric: computedMetricSchema.meta({
|
|
617
789
|
label: "Metric",
|
|
618
790
|
description: "Computed metric definition."
|
|
619
791
|
}),
|
|
620
|
-
window:
|
|
621
|
-
granularity:
|
|
792
|
+
window: z2.string().meta({ label: "Window", description: "Time window, e.g. '30d'." }),
|
|
793
|
+
granularity: z2.enum(["hour", "day", "week"]).default("day").meta({ label: "Granularity", description: "Time bucket size." })
|
|
622
794
|
});
|
|
623
|
-
var distributionWidgetSchema =
|
|
624
|
-
kind:
|
|
795
|
+
var distributionWidgetSchema = z2.object({
|
|
796
|
+
kind: z2.literal("distribution"),
|
|
625
797
|
title: titleField,
|
|
626
798
|
metric: computedMetricSchema.meta({
|
|
627
799
|
label: "Metric",
|
|
628
800
|
description: "Computed metric definition."
|
|
629
801
|
}),
|
|
630
|
-
window:
|
|
802
|
+
window: z2.string().meta({ label: "Window", description: "Time window, e.g. '7d'." })
|
|
631
803
|
});
|
|
632
804
|
var widgetSchemas = {
|
|
633
805
|
stat: statWidgetSchema,
|
|
@@ -635,7 +807,7 @@ var widgetSchemas = {
|
|
|
635
807
|
timeseries: timeseriesWidgetSchema,
|
|
636
808
|
distribution: distributionWidgetSchema
|
|
637
809
|
};
|
|
638
|
-
var widgetSchema =
|
|
810
|
+
var widgetSchema = z2.discriminatedUnion("kind", [
|
|
639
811
|
statWidgetSchema,
|
|
640
812
|
statusWidgetSchema,
|
|
641
813
|
timeseriesWidgetSchema,
|
|
@@ -666,7 +838,7 @@ function defineDashboard(options) {
|
|
|
666
838
|
}
|
|
667
839
|
function defineMetric(options) {
|
|
668
840
|
return {
|
|
669
|
-
connectorId: options.connector.
|
|
841
|
+
connectorId: options.connector.name,
|
|
670
842
|
shape: options.shape,
|
|
671
843
|
name: options.name,
|
|
672
844
|
entityType: options.entityType,
|
|
@@ -715,7 +887,36 @@ function validateConfig(config) {
|
|
|
715
887
|
'defineConfig: config must include a "dashboards" record \u2014 did you mean to migrate from the old flat "widgets" shape?'
|
|
716
888
|
);
|
|
717
889
|
}
|
|
718
|
-
|
|
890
|
+
if (!Array.isArray(config.connectors)) {
|
|
891
|
+
throw new Error('defineConfig: "connectors" must be an array');
|
|
892
|
+
}
|
|
893
|
+
const connectorNames = /* @__PURE__ */ new Set();
|
|
894
|
+
for (const entry of config.connectors) {
|
|
895
|
+
if (!entry || typeof entry !== "object") {
|
|
896
|
+
throw new Error(
|
|
897
|
+
'defineConfig: every connector entry must be an object with "name", "connectorId", and "config"'
|
|
898
|
+
);
|
|
899
|
+
}
|
|
900
|
+
if (!entry.name) {
|
|
901
|
+
throw new Error('defineConfig: every connector entry must have a "name"');
|
|
902
|
+
}
|
|
903
|
+
if (!entry.connectorId) {
|
|
904
|
+
throw new Error(
|
|
905
|
+
`defineConfig: connector "${entry.name}" must have a "connectorId" (the connector type id)`
|
|
906
|
+
);
|
|
907
|
+
}
|
|
908
|
+
if (entry.config === null || typeof entry.config !== "object" || Array.isArray(entry.config)) {
|
|
909
|
+
throw new Error(
|
|
910
|
+
`defineConfig: connector "${entry.name}" must have a "config" object`
|
|
911
|
+
);
|
|
912
|
+
}
|
|
913
|
+
if (connectorNames.has(entry.name)) {
|
|
914
|
+
throw new Error(
|
|
915
|
+
`defineConfig: duplicate connector name "${entry.name}". Each instance must have a unique name.`
|
|
916
|
+
);
|
|
917
|
+
}
|
|
918
|
+
connectorNames.add(entry.name);
|
|
919
|
+
}
|
|
719
920
|
for (const [dashboardKey, dashboard] of Object.entries(config.dashboards)) {
|
|
720
921
|
if (!dashboard.widgets || typeof dashboard.widgets !== "object" || Array.isArray(dashboard.widgets)) {
|
|
721
922
|
throw new Error(
|
|
@@ -738,7 +939,7 @@ function validateConfig(config) {
|
|
|
738
939
|
continue;
|
|
739
940
|
}
|
|
740
941
|
const { connectorId, shape, fn } = widget.metric;
|
|
741
|
-
if (!
|
|
942
|
+
if (!connectorNames.has(connectorId)) {
|
|
742
943
|
throw new Error(
|
|
743
944
|
`${ref}: connector "${connectorId}" is not listed in connectors`
|
|
744
945
|
);
|
|
@@ -808,9 +1009,9 @@ async function computeRetention(handle, config, nowMs = Date.now()) {
|
|
|
808
1009
|
}
|
|
809
1010
|
|
|
810
1011
|
// src/config-fields.ts
|
|
811
|
-
import { z as
|
|
1012
|
+
import { z as z3 } from "zod";
|
|
812
1013
|
function defineConfigFields(schema) {
|
|
813
|
-
if (!(schema instanceof
|
|
1014
|
+
if (!(schema instanceof z3.ZodObject)) {
|
|
814
1015
|
throw new Error(
|
|
815
1016
|
`configFields must be a Zod object schema (z.object({...})). Received: ${Object.prototype.toString.call(schema)}`
|
|
816
1017
|
);
|
|
@@ -818,6 +1019,88 @@ function defineConfigFields(schema) {
|
|
|
818
1019
|
return schema;
|
|
819
1020
|
}
|
|
820
1021
|
|
|
1022
|
+
// src/connector-doc.ts
|
|
1023
|
+
import { z as z4 } from "zod";
|
|
1024
|
+
var connectorCategorySchema = z4.enum([
|
|
1025
|
+
"engineering",
|
|
1026
|
+
"product",
|
|
1027
|
+
"analytics",
|
|
1028
|
+
"marketing",
|
|
1029
|
+
"sales",
|
|
1030
|
+
"support",
|
|
1031
|
+
"finance",
|
|
1032
|
+
"infrastructure",
|
|
1033
|
+
"security"
|
|
1034
|
+
]);
|
|
1035
|
+
var connectorDocSchema = z4.object({
|
|
1036
|
+
displayName: z4.string().min(1),
|
|
1037
|
+
category: connectorCategorySchema,
|
|
1038
|
+
tagline: z4.string().min(1),
|
|
1039
|
+
// Brand accent color (hex) for the connector's docs/landing card. The icon
|
|
1040
|
+
// itself is a committed `icon.svg` co-located in the connector package.
|
|
1041
|
+
brandColor: z4.string().regex(/^#[0-9A-Fa-f]{6}$/).optional(),
|
|
1042
|
+
vendor: z4.object({
|
|
1043
|
+
name: z4.string().min(1),
|
|
1044
|
+
apiDocs: z4.url().optional(),
|
|
1045
|
+
website: z4.url().optional()
|
|
1046
|
+
}),
|
|
1047
|
+
auth: z4.object({
|
|
1048
|
+
summary: z4.string().min(1),
|
|
1049
|
+
setup: z4.array(z4.string().min(1))
|
|
1050
|
+
}),
|
|
1051
|
+
// Upstream API rate-limit / quota notes worth surfacing (e.g. "GA4 Data API:
|
|
1052
|
+
// 200k tokens/day per property"). Free text, rendered in docs.
|
|
1053
|
+
rateLimit: z4.string().min(1).optional(),
|
|
1054
|
+
// Operational caveats / out-of-scope notes (API ceilings, sampling, Cloud-only,
|
|
1055
|
+
// data revision windows, etc.).
|
|
1056
|
+
limitations: z4.array(z4.string().min(1)).optional()
|
|
1057
|
+
});
|
|
1058
|
+
function defineConnectorDoc(doc) {
|
|
1059
|
+
return connectorDocSchema.parse(doc);
|
|
1060
|
+
}
|
|
1061
|
+
|
|
1062
|
+
// src/resource.ts
|
|
1063
|
+
var SHAPES = /* @__PURE__ */ new Set([
|
|
1064
|
+
"entity",
|
|
1065
|
+
"event",
|
|
1066
|
+
"metric",
|
|
1067
|
+
"edge",
|
|
1068
|
+
"distribution"
|
|
1069
|
+
]);
|
|
1070
|
+
function defineResources(defs) {
|
|
1071
|
+
for (const [name, def] of Object.entries(defs)) {
|
|
1072
|
+
if (!name) {
|
|
1073
|
+
throw new Error("Resource name must be a non-empty string.");
|
|
1074
|
+
}
|
|
1075
|
+
if (!SHAPES.has(def.shape)) {
|
|
1076
|
+
throw new Error(
|
|
1077
|
+
`Resource "${name}" has invalid shape "${def.shape}". Expected one of: ${[...SHAPES].join(", ")}.`
|
|
1078
|
+
);
|
|
1079
|
+
}
|
|
1080
|
+
if (!def.description || def.description.trim().length === 0) {
|
|
1081
|
+
throw new Error(`Resource "${name}" must have a non-empty description.`);
|
|
1082
|
+
}
|
|
1083
|
+
}
|
|
1084
|
+
return defs;
|
|
1085
|
+
}
|
|
1086
|
+
function schemasFromResources(defs) {
|
|
1087
|
+
const out = {};
|
|
1088
|
+
for (const [name, def] of Object.entries(defs)) {
|
|
1089
|
+
if (!def.responses) {
|
|
1090
|
+
continue;
|
|
1091
|
+
}
|
|
1092
|
+
for (const [tag, schema] of Object.entries(def.responses)) {
|
|
1093
|
+
if (out[tag]) {
|
|
1094
|
+
throw new Error(
|
|
1095
|
+
`Duplicate response schema tag "${tag}" (declared again on resource "${name}").`
|
|
1096
|
+
);
|
|
1097
|
+
}
|
|
1098
|
+
out[tag] = schema;
|
|
1099
|
+
}
|
|
1100
|
+
}
|
|
1101
|
+
return out;
|
|
1102
|
+
}
|
|
1103
|
+
|
|
821
1104
|
// src/compute.ts
|
|
822
1105
|
function matchesCondition(record, cond) {
|
|
823
1106
|
const val = record[cond.field];
|
|
@@ -1072,39 +1355,181 @@ async function computeMetric(storage, metric) {
|
|
|
1072
1355
|
return computeAgg(sorted, metric.field, metric.fn);
|
|
1073
1356
|
}
|
|
1074
1357
|
|
|
1075
|
-
// src/
|
|
1076
|
-
|
|
1358
|
+
// src/backfill-window.ts
|
|
1359
|
+
var WINDOW_UNIT_MS = {
|
|
1360
|
+
h: 36e5,
|
|
1361
|
+
d: 864e5,
|
|
1362
|
+
w: 6048e5,
|
|
1363
|
+
m: 2592e6
|
|
1364
|
+
};
|
|
1365
|
+
function parseWindowMs2(window) {
|
|
1366
|
+
const match = /^(\d+)(h|d|w|m)$/.exec(window);
|
|
1367
|
+
if (!match) {
|
|
1368
|
+
return void 0;
|
|
1369
|
+
}
|
|
1370
|
+
const unitMs = WINDOW_UNIT_MS[match[2]];
|
|
1371
|
+
if (unitMs === void 0) {
|
|
1372
|
+
return void 0;
|
|
1373
|
+
}
|
|
1374
|
+
return parseInt(match[1]) * unitMs;
|
|
1375
|
+
}
|
|
1376
|
+
function widgetWindow(widget) {
|
|
1377
|
+
switch (widget.kind) {
|
|
1378
|
+
case "stat":
|
|
1379
|
+
return widget.window ?? widget.metric.window;
|
|
1380
|
+
case "timeseries":
|
|
1381
|
+
case "distribution":
|
|
1382
|
+
return widget.window;
|
|
1383
|
+
case "status":
|
|
1384
|
+
return void 0;
|
|
1385
|
+
}
|
|
1386
|
+
}
|
|
1387
|
+
function widgetReference(widget) {
|
|
1077
1388
|
if (widget.kind === "status") {
|
|
1078
|
-
return {
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1389
|
+
return { connectorName: widget.source, resourceName: void 0 };
|
|
1390
|
+
}
|
|
1391
|
+
return {
|
|
1392
|
+
connectorName: widget.metric.connectorId,
|
|
1393
|
+
resourceName: widget.metric.name ?? widget.metric.entityType
|
|
1394
|
+
};
|
|
1395
|
+
}
|
|
1396
|
+
function mergeWindow(existing, next) {
|
|
1397
|
+
if (next === void 0) {
|
|
1398
|
+
return existing;
|
|
1399
|
+
}
|
|
1400
|
+
if (existing === void 0) {
|
|
1401
|
+
return next;
|
|
1402
|
+
}
|
|
1403
|
+
return Math.max(existing, next);
|
|
1404
|
+
}
|
|
1405
|
+
function computeConnectorBackfill(config) {
|
|
1406
|
+
const result = /* @__PURE__ */ new Map();
|
|
1407
|
+
for (const dashboard of Object.values(config.dashboards)) {
|
|
1408
|
+
for (const widget of Object.values(dashboard.widgets)) {
|
|
1409
|
+
const { connectorName, resourceName } = widgetReference(widget);
|
|
1410
|
+
const windowStr = widgetWindow(widget);
|
|
1411
|
+
const windowMs = windowStr ? parseWindowMs2(windowStr) : void 0;
|
|
1412
|
+
let resources = result.get(connectorName);
|
|
1413
|
+
if (!resources) {
|
|
1414
|
+
resources = /* @__PURE__ */ new Map();
|
|
1415
|
+
result.set(connectorName, resources);
|
|
1416
|
+
}
|
|
1417
|
+
if (resourceName === void 0) {
|
|
1418
|
+
continue;
|
|
1419
|
+
}
|
|
1420
|
+
const existing = resources.get(resourceName);
|
|
1421
|
+
resources.set(resourceName, {
|
|
1422
|
+
requiredWindowMs: mergeWindow(existing?.requiredWindowMs, windowMs)
|
|
1423
|
+
});
|
|
1424
|
+
}
|
|
1425
|
+
}
|
|
1426
|
+
return result;
|
|
1427
|
+
}
|
|
1428
|
+
|
|
1429
|
+
// src/resolve-widget.ts
|
|
1430
|
+
var FAILING_CONNECTOR_STATUSES = /* @__PURE__ */ new Set(["error", "auth_failed", "paused"]);
|
|
1431
|
+
function deriveSyncStateFromHealth(health) {
|
|
1432
|
+
if (health.status === "syncing") {
|
|
1433
|
+
return "syncing";
|
|
1434
|
+
}
|
|
1435
|
+
if (FAILING_CONNECTOR_STATUSES.has(health.status)) {
|
|
1436
|
+
return "failing";
|
|
1437
|
+
}
|
|
1438
|
+
if (!health.lastSyncAt) {
|
|
1439
|
+
return "unsynced";
|
|
1440
|
+
}
|
|
1441
|
+
const ageMs = Date.now() - new Date(health.lastSyncAt).getTime();
|
|
1442
|
+
const windowMs = 2 * health.syncIntervalSeconds * 1e3;
|
|
1443
|
+
return ageMs <= windowMs ? "fresh" : "stale";
|
|
1444
|
+
}
|
|
1445
|
+
function buildMetaFromHealth(health) {
|
|
1446
|
+
const meta = { connectorStatus: health.status };
|
|
1447
|
+
if (health.lastError) {
|
|
1448
|
+
meta["lastError"] = health.lastError;
|
|
1084
1449
|
}
|
|
1085
|
-
|
|
1086
|
-
|
|
1450
|
+
return meta;
|
|
1451
|
+
}
|
|
1452
|
+
async function resolveWidget(dashboardId, widgetId, widget, connectors, storage) {
|
|
1453
|
+
const connectorId = widget.kind === "status" ? widget.source : widget.metric.connectorId;
|
|
1454
|
+
if (connectors !== void 0 && !connectors.includes(connectorId)) {
|
|
1087
1455
|
return void 0;
|
|
1088
1456
|
}
|
|
1089
1457
|
const handle = storage.getStorageHandle(connectorId);
|
|
1090
|
-
const
|
|
1458
|
+
const health = await handle.getHealth?.() ?? null;
|
|
1459
|
+
let data = null;
|
|
1460
|
+
if (widget.kind !== "status") {
|
|
1461
|
+
data = await computeMetric(handle, widget.metric);
|
|
1462
|
+
}
|
|
1463
|
+
let syncState;
|
|
1464
|
+
let meta;
|
|
1465
|
+
if (health) {
|
|
1466
|
+
syncState = deriveSyncStateFromHealth(health);
|
|
1467
|
+
meta = buildMetaFromHealth(health);
|
|
1468
|
+
} else if (data === null || data === void 0) {
|
|
1469
|
+
syncState = "unsynced";
|
|
1470
|
+
} else {
|
|
1471
|
+
syncState = "fresh";
|
|
1472
|
+
}
|
|
1091
1473
|
return {
|
|
1092
1474
|
widgetId,
|
|
1093
1475
|
connectorId,
|
|
1094
1476
|
data,
|
|
1095
|
-
cachedAt:
|
|
1477
|
+
cachedAt: health?.lastSyncAt ?? null,
|
|
1478
|
+
syncState,
|
|
1479
|
+
syncIntervalSeconds: health?.syncIntervalSeconds,
|
|
1480
|
+
meta
|
|
1096
1481
|
};
|
|
1097
1482
|
}
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1483
|
+
|
|
1484
|
+
// src/widget-etag.ts
|
|
1485
|
+
function stableStringify(value) {
|
|
1486
|
+
if (value === null || typeof value !== "object") {
|
|
1487
|
+
return JSON.stringify(value) ?? "null";
|
|
1101
1488
|
}
|
|
1102
|
-
if (
|
|
1103
|
-
return
|
|
1489
|
+
if (Array.isArray(value)) {
|
|
1490
|
+
return "[" + value.map(stableStringify).join(",") + "]";
|
|
1104
1491
|
}
|
|
1105
|
-
|
|
1106
|
-
|
|
1492
|
+
const keys = Object.keys(value).sort();
|
|
1493
|
+
const parts = keys.map(
|
|
1494
|
+
(k) => JSON.stringify(k) + ":" + stableStringify(value[k])
|
|
1107
1495
|
);
|
|
1496
|
+
return "{" + parts.join(",") + "}";
|
|
1497
|
+
}
|
|
1498
|
+
function hashWidgetConfig(widget) {
|
|
1499
|
+
const s = stableStringify(widget);
|
|
1500
|
+
let h = 2166136261;
|
|
1501
|
+
for (let i = 0; i < s.length; i++) {
|
|
1502
|
+
h ^= s.charCodeAt(i);
|
|
1503
|
+
h = Math.imul(h, 16777619);
|
|
1504
|
+
}
|
|
1505
|
+
return (h >>> 0).toString(16).padStart(8, "0");
|
|
1506
|
+
}
|
|
1507
|
+
function computeWidgetEtag(lastSyncAt, widget) {
|
|
1508
|
+
return `"${lastSyncAt ?? "null"}-${hashWidgetConfig(widget)}"`;
|
|
1509
|
+
}
|
|
1510
|
+
|
|
1511
|
+
// src/registry.ts
|
|
1512
|
+
function instantiateConnector(entry, registry, secretsResolver, logger) {
|
|
1513
|
+
const Cls = registry[entry.connectorId];
|
|
1514
|
+
if (!Cls) {
|
|
1515
|
+
throw new Error(
|
|
1516
|
+
`Unknown connector type "${entry.connectorId}" for instance "${entry.name}". Add it to the connectorRegistry.`
|
|
1517
|
+
);
|
|
1518
|
+
}
|
|
1519
|
+
const credSchema = Cls.credentials;
|
|
1520
|
+
const settings = {};
|
|
1521
|
+
const creds = {};
|
|
1522
|
+
for (const [key, value] of Object.entries(entry.config)) {
|
|
1523
|
+
if (credSchema && Object.prototype.hasOwnProperty.call(credSchema, key)) {
|
|
1524
|
+
creds[key] = value;
|
|
1525
|
+
} else {
|
|
1526
|
+
settings[key] = value;
|
|
1527
|
+
}
|
|
1528
|
+
}
|
|
1529
|
+
return new Cls(settings, credSchema ? creds : void 0, {
|
|
1530
|
+
secretsResolver,
|
|
1531
|
+
logger
|
|
1532
|
+
});
|
|
1108
1533
|
}
|
|
1109
1534
|
|
|
1110
1535
|
// src/storage-handle-guard.ts
|
|
@@ -1202,7 +1627,8 @@ function withAbortSignal(handle, signal) {
|
|
|
1202
1627
|
queryEntities: (q) => handle.queryEntities(q),
|
|
1203
1628
|
queryMetrics: (q) => handle.queryMetrics(q),
|
|
1204
1629
|
traverse: (q) => handle.traverse(q),
|
|
1205
|
-
queryDistributions: (q) => handle.queryDistributions(q)
|
|
1630
|
+
queryDistributions: (q) => handle.queryDistributions(q),
|
|
1631
|
+
...handle.getHealth ? { getHealth: handle.getHealth.bind(handle) } : {}
|
|
1206
1632
|
};
|
|
1207
1633
|
}
|
|
1208
1634
|
|
|
@@ -1213,6 +1639,7 @@ var InMemoryStorage = class {
|
|
|
1213
1639
|
metricStore = /* @__PURE__ */ new Map();
|
|
1214
1640
|
edgeStore = /* @__PURE__ */ new Map();
|
|
1215
1641
|
distributionStore = /* @__PURE__ */ new Map();
|
|
1642
|
+
lastWriteAt = /* @__PURE__ */ new Map();
|
|
1216
1643
|
syncState = {
|
|
1217
1644
|
status: "idle",
|
|
1218
1645
|
queuedAt: null,
|
|
@@ -1225,6 +1652,9 @@ var InMemoryStorage = class {
|
|
|
1225
1652
|
return options?.signal ? withAbortSignal(handle, options.signal) : handle;
|
|
1226
1653
|
}
|
|
1227
1654
|
buildHandle(connectorId) {
|
|
1655
|
+
const touch = () => {
|
|
1656
|
+
this.lastWriteAt.set(connectorId, (/* @__PURE__ */ new Date()).toISOString());
|
|
1657
|
+
};
|
|
1228
1658
|
const getEntityMap = () => {
|
|
1229
1659
|
if (!this.entityStore.has(connectorId)) {
|
|
1230
1660
|
this.entityStore.set(connectorId, /* @__PURE__ */ new Map());
|
|
@@ -1268,24 +1698,29 @@ var InMemoryStorage = class {
|
|
|
1268
1698
|
this.eventStore.set(connectorId, []);
|
|
1269
1699
|
}
|
|
1270
1700
|
this.eventStore.get(connectorId).push(e);
|
|
1701
|
+
touch();
|
|
1271
1702
|
},
|
|
1272
1703
|
entity: async (e) => {
|
|
1273
1704
|
upsertEntities([e]);
|
|
1705
|
+
touch();
|
|
1274
1706
|
},
|
|
1275
1707
|
metric: async (m) => {
|
|
1276
1708
|
if (!this.metricStore.has(connectorId)) {
|
|
1277
1709
|
this.metricStore.set(connectorId, []);
|
|
1278
1710
|
}
|
|
1279
1711
|
this.metricStore.get(connectorId).push(m);
|
|
1712
|
+
touch();
|
|
1280
1713
|
},
|
|
1281
1714
|
edge: async (e) => {
|
|
1282
1715
|
upsertEdges([e]);
|
|
1716
|
+
touch();
|
|
1283
1717
|
},
|
|
1284
1718
|
distribution: async (d) => {
|
|
1285
1719
|
if (!this.distributionStore.has(connectorId)) {
|
|
1286
1720
|
this.distributionStore.set(connectorId, []);
|
|
1287
1721
|
}
|
|
1288
1722
|
this.distributionStore.get(connectorId).push(d);
|
|
1723
|
+
touch();
|
|
1289
1724
|
},
|
|
1290
1725
|
events: async (es, scope) => {
|
|
1291
1726
|
const names = new Set(scope?.names ?? es.map((e) => e.name));
|
|
@@ -1293,6 +1728,7 @@ var InMemoryStorage = class {
|
|
|
1293
1728
|
(e) => !names.has(e.name)
|
|
1294
1729
|
);
|
|
1295
1730
|
this.eventStore.set(connectorId, [...kept, ...es]);
|
|
1731
|
+
touch();
|
|
1296
1732
|
},
|
|
1297
1733
|
entities: async (es, scope) => {
|
|
1298
1734
|
const byType = getEntityMap();
|
|
@@ -1301,6 +1737,7 @@ var InMemoryStorage = class {
|
|
|
1301
1737
|
byType.set(type, /* @__PURE__ */ new Map());
|
|
1302
1738
|
}
|
|
1303
1739
|
upsertEntities(es);
|
|
1740
|
+
touch();
|
|
1304
1741
|
},
|
|
1305
1742
|
metrics: async (ms, scope) => {
|
|
1306
1743
|
const names = new Set(scope?.names ?? ms.map((m) => m.name));
|
|
@@ -1308,6 +1745,7 @@ var InMemoryStorage = class {
|
|
|
1308
1745
|
(m) => !names.has(m.name)
|
|
1309
1746
|
);
|
|
1310
1747
|
this.metricStore.set(connectorId, [...kept, ...ms]);
|
|
1748
|
+
touch();
|
|
1311
1749
|
},
|
|
1312
1750
|
edges: async (es, scope) => {
|
|
1313
1751
|
const kinds = new Set(scope?.kinds ?? es.map((e) => e.kind));
|
|
@@ -1316,6 +1754,7 @@ var InMemoryStorage = class {
|
|
|
1316
1754
|
);
|
|
1317
1755
|
this.edgeStore.set(connectorId, kept);
|
|
1318
1756
|
upsertEdges(es);
|
|
1757
|
+
touch();
|
|
1319
1758
|
},
|
|
1320
1759
|
distributions: async (ds, scope) => {
|
|
1321
1760
|
const names = new Set(scope?.names ?? ds.map((d) => d.name));
|
|
@@ -1323,6 +1762,7 @@ var InMemoryStorage = class {
|
|
|
1323
1762
|
(d) => !names.has(d.name)
|
|
1324
1763
|
);
|
|
1325
1764
|
this.distributionStore.set(connectorId, [...kept, ...ds]);
|
|
1765
|
+
touch();
|
|
1326
1766
|
},
|
|
1327
1767
|
queryEvents: async (q) => {
|
|
1328
1768
|
let results = this.eventStore.get(connectorId) ?? [];
|
|
@@ -1413,6 +1853,14 @@ var InMemoryStorage = class {
|
|
|
1413
1853
|
`Unsupported shape for deleteOlderThan: ${String(shape)}`
|
|
1414
1854
|
);
|
|
1415
1855
|
}
|
|
1856
|
+
},
|
|
1857
|
+
getHealth: async () => {
|
|
1858
|
+
return {
|
|
1859
|
+
status: "idle",
|
|
1860
|
+
lastSyncAt: this.lastWriteAt.get(connectorId) ?? null,
|
|
1861
|
+
lastError: null,
|
|
1862
|
+
syncIntervalSeconds: 0
|
|
1863
|
+
};
|
|
1416
1864
|
}
|
|
1417
1865
|
};
|
|
1418
1866
|
}
|
|
@@ -1464,34 +1912,34 @@ var InMemoryStorage = class {
|
|
|
1464
1912
|
};
|
|
1465
1913
|
|
|
1466
1914
|
// src/wire-config.ts
|
|
1467
|
-
import { z as
|
|
1468
|
-
var wireConnectorSchema =
|
|
1469
|
-
name:
|
|
1470
|
-
connectorId:
|
|
1471
|
-
displayName:
|
|
1472
|
-
config:
|
|
1473
|
-
syncIntervalSeconds:
|
|
1474
|
-
enabled:
|
|
1915
|
+
import { z as z5 } from "zod";
|
|
1916
|
+
var wireConnectorSchema = z5.object({
|
|
1917
|
+
name: z5.string(),
|
|
1918
|
+
connectorId: z5.string(),
|
|
1919
|
+
displayName: z5.string().optional(),
|
|
1920
|
+
config: z5.record(z5.string(), z5.unknown()),
|
|
1921
|
+
syncIntervalSeconds: z5.number().optional(),
|
|
1922
|
+
enabled: z5.boolean().optional()
|
|
1475
1923
|
});
|
|
1476
|
-
var wireDashboardSchema =
|
|
1477
|
-
id:
|
|
1478
|
-
name:
|
|
1479
|
-
slug:
|
|
1480
|
-
config:
|
|
1924
|
+
var wireDashboardSchema = z5.object({
|
|
1925
|
+
id: z5.string().optional(),
|
|
1926
|
+
name: z5.string(),
|
|
1927
|
+
slug: z5.string(),
|
|
1928
|
+
config: z5.record(z5.string(), z5.unknown())
|
|
1481
1929
|
});
|
|
1482
|
-
var wireConfigSchema =
|
|
1483
|
-
connectors:
|
|
1484
|
-
dashboards:
|
|
1930
|
+
var wireConfigSchema = z5.object({
|
|
1931
|
+
connectors: z5.array(wireConnectorSchema).optional(),
|
|
1932
|
+
dashboards: z5.array(wireDashboardSchema).optional()
|
|
1485
1933
|
});
|
|
1486
1934
|
function toWireConfig(config) {
|
|
1487
1935
|
return {
|
|
1488
|
-
connectors: config.connectors.map((
|
|
1489
|
-
name:
|
|
1490
|
-
connectorId:
|
|
1491
|
-
displayName:
|
|
1492
|
-
config:
|
|
1493
|
-
syncIntervalSeconds: 300,
|
|
1494
|
-
enabled: true
|
|
1936
|
+
connectors: config.connectors.map((entry) => ({
|
|
1937
|
+
name: entry.name,
|
|
1938
|
+
connectorId: entry.connectorId,
|
|
1939
|
+
displayName: entry.displayName ?? entry.name,
|
|
1940
|
+
config: entry.config,
|
|
1941
|
+
syncIntervalSeconds: entry.syncIntervalSeconds ?? 300,
|
|
1942
|
+
enabled: entry.enabled ?? true
|
|
1495
1943
|
})),
|
|
1496
1944
|
dashboards: Object.entries(config.dashboards).map(([id, dash]) => ({
|
|
1497
1945
|
id,
|
|
@@ -1507,14 +1955,21 @@ export {
|
|
|
1507
1955
|
EnvSecretsResolver,
|
|
1508
1956
|
InMemoryStorage,
|
|
1509
1957
|
aggFnSchema,
|
|
1958
|
+
computeConnectorBackfill,
|
|
1510
1959
|
computeMetric,
|
|
1511
1960
|
computeRetention,
|
|
1961
|
+
computeWidgetEtag,
|
|
1512
1962
|
computedMetricSchema,
|
|
1963
|
+
connectorCategorySchema,
|
|
1964
|
+
connectorDocSchema,
|
|
1965
|
+
createDefaultConnectorLogger,
|
|
1513
1966
|
defineConfig,
|
|
1514
1967
|
defineConfigFields,
|
|
1515
1968
|
defineConnector,
|
|
1969
|
+
defineConnectorDoc,
|
|
1516
1970
|
defineDashboard,
|
|
1517
1971
|
defineMetric,
|
|
1972
|
+
defineResources,
|
|
1518
1973
|
distributionWidgetSchema,
|
|
1519
1974
|
extractSecretNames,
|
|
1520
1975
|
filterClauseSchema,
|
|
@@ -1522,12 +1977,19 @@ export {
|
|
|
1522
1977
|
filterOperatorSchema,
|
|
1523
1978
|
getWidgetSchema,
|
|
1524
1979
|
groupBySchema,
|
|
1980
|
+
hashWidgetConfig,
|
|
1981
|
+
instantiateConnector,
|
|
1525
1982
|
isSecret,
|
|
1526
1983
|
isSyncActive,
|
|
1984
|
+
makeChunkedCursorGuard,
|
|
1985
|
+
noopConnectorLogger,
|
|
1527
1986
|
paginateChunked,
|
|
1528
1987
|
resolveSecrets,
|
|
1529
1988
|
resolveWidget,
|
|
1989
|
+
schemasFromResources,
|
|
1530
1990
|
secret,
|
|
1991
|
+
secretRefSchema,
|
|
1992
|
+
selectActivePhases,
|
|
1531
1993
|
selectForDeletion,
|
|
1532
1994
|
shapeSchema,
|
|
1533
1995
|
statWidgetSchema,
|
|
@@ -1539,6 +2001,7 @@ export {
|
|
|
1539
2001
|
wireConfigSchema,
|
|
1540
2002
|
wireConnectorSchema,
|
|
1541
2003
|
wireDashboardSchema,
|
|
1542
|
-
withAbortSignal
|
|
2004
|
+
withAbortSignal,
|
|
2005
|
+
withSecretRef
|
|
1543
2006
|
};
|
|
1544
2007
|
//# sourceMappingURL=index.js.map
|