@useairfoil/connector-kit 0.5.3 → 0.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/METRICS.md +20 -19
- package/README.md +127 -430
- package/dist/annotations-BE74YmAO.d.mts +39 -0
- package/dist/auth/index.d.mts +2 -0
- package/dist/{auth-DvU_CZ7C.js → auth/index.mjs} +6 -8
- package/dist/auth/index.mjs.map +1 -0
- package/dist/connector-app/index.d.mts +2 -0
- package/dist/connector-app/index.mjs +2 -0
- package/dist/connector-app-C-L4QqG6.mjs +123 -0
- package/dist/connector-app-C-L4QqG6.mjs.map +1 -0
- package/dist/{constants-BRhIX_rz.js → constants-D-GQzpHZ.mjs} +10 -6
- package/dist/constants-D-GQzpHZ.mjs.map +1 -0
- package/dist/demo/index.d.mts +2 -0
- package/dist/demo/index.mjs +2 -0
- package/dist/demo-B30Vlkk2.mjs +191 -0
- package/dist/demo-B30Vlkk2.mjs.map +1 -0
- package/dist/errors/index.d.mts +2 -0
- package/dist/errors/index.mjs +2 -0
- package/dist/{errors-DHWylqRZ.js → errors-pT0YVJU5.mjs} +2 -3
- package/dist/errors-pT0YVJU5.mjs.map +1 -0
- package/dist/iceberg/index.d.mts +3 -0
- package/dist/iceberg/index.mjs +3 -0
- package/dist/iceberg-D6L8I6vA.mjs +39 -0
- package/dist/iceberg-D6L8I6vA.mjs.map +1 -0
- package/dist/{index-Cq2IzY7T.d.ts → index-BUHSGm9Q.d.mts} +11 -13
- package/dist/{index-CTHVudvQ.d.ts → index-BX8G7d41.d.mts} +1 -2
- package/dist/{index-J42AZaXU.d.ts → index-BfXpgxk9.d.mts} +9 -10
- package/dist/{index-DKWIh6M1.d.ts → index-CRVAwJ5-.d.mts} +10 -8
- package/dist/index-CUPP2A_m.d.mts +27 -0
- package/dist/{index-Coh_SkBs.d.ts → index-CgvFomO6.d.mts} +6 -7
- package/dist/index-DJhDp4Xc.d.mts +58 -0
- package/dist/index-Dk7urvpF.d.mts +76 -0
- package/dist/{index-D54ySAKn.d.ts → index-DkVNO6ks.d.mts} +2 -5
- package/dist/{index-DtJX_tic.d.ts → index-NnCutIqM.d.mts} +77 -38
- package/dist/{index-CBT-JX-T.d.ts → index-eFuoMZZ3.d.mts} +18 -20
- package/dist/index-ygpml2kC.d.mts +73 -0
- package/dist/index.d.mts +16 -0
- package/dist/index.mjs +45 -0
- package/dist/index.mjs.map +1 -0
- package/dist/ingestion/index.d.mts +2 -0
- package/dist/ingestion/index.mjs +2 -0
- package/dist/ingestion-q0WwqUSt.mjs +275 -0
- package/dist/ingestion-q0WwqUSt.mjs.map +1 -0
- package/dist/ingestor/index.d.mts +3 -0
- package/dist/ingestor/index.mjs +4 -0
- package/dist/ingestor-D4L-HPkg.mjs +26 -0
- package/dist/ingestor-D4L-HPkg.mjs.map +1 -0
- package/dist/instrumented-Bhp7fyvh.mjs +29 -0
- package/dist/instrumented-Bhp7fyvh.mjs.map +1 -0
- package/dist/manifest/index.d.mts +2 -0
- package/dist/manifest/{index.js → index.mjs} +2 -4
- package/dist/{manifest-ByE6YPG0.js → manifest-BGKxmKLy.mjs} +14 -19
- package/dist/manifest-BGKxmKLy.mjs.map +1 -0
- package/dist/metrics-BaEX__MN.mjs +352 -0
- package/dist/metrics-BaEX__MN.mjs.map +1 -0
- package/dist/metrics-CVXFL7YT.d.mts +64 -0
- package/dist/metrics.d.mts +2 -0
- package/dist/metrics.mjs +2 -0
- package/dist/{chunk-Bp6m_JJh.js → rolldown-runtime-D7D4PA-g.mjs} +4 -4
- package/dist/runtime-config/index.d.mts +2 -0
- package/dist/runtime-config/index.mjs +3 -0
- package/dist/runtime-config-Oa55gAew.mjs +97 -0
- package/dist/runtime-config-Oa55gAew.mjs.map +1 -0
- package/dist/{server-CXTQ7odl.js → server-CMnxz3h0.mjs} +21 -60
- package/dist/server-CMnxz3h0.mjs.map +1 -0
- package/dist/service-DLkhuxYl.d.mts +27 -0
- package/dist/service-jWxxfEht.mjs +7 -0
- package/dist/service-jWxxfEht.mjs.map +1 -0
- package/dist/state-store/index.d.mts +2 -0
- package/dist/state-store/index.mjs +2 -0
- package/dist/{state-store-yl6LiTQ0.js → state-store-uFvHY7Ax.mjs} +15 -22
- package/dist/state-store-uFvHY7Ax.mjs.map +1 -0
- package/dist/status/{index.d.ts → index.d.mts} +1 -4
- package/dist/status/{index.js → index.mjs} +2 -6
- package/dist/{status-B-oZBc33.js → status-CKb9IhQ9.mjs} +14 -16
- package/dist/status-CKb9IhQ9.mjs.map +1 -0
- package/dist/table-V0tgUC5i.mjs +370 -0
- package/dist/table-V0tgUC5i.mjs.map +1 -0
- package/dist/types-xZtSmrGA.d.mts +220 -0
- package/dist/webhook/index.d.mts +3 -0
- package/dist/webhook/index.mjs +12 -0
- package/dist/webhook/index.mjs.map +1 -0
- package/dist/wings-I56hGtNv.mjs +325 -0
- package/dist/wings-I56hGtNv.mjs.map +1 -0
- package/package.json +64 -51
- package/src/catalog/table.ts +201 -0
- package/src/connector-app/create-table.ts +47 -0
- package/src/connector-app/demo.ts +42 -0
- package/src/connector-app/index.ts +2 -0
- package/src/connector-app/start.ts +1 -1
- package/src/core/builder.ts +15 -23
- package/src/core/index.ts +11 -1
- package/src/core/types.ts +114 -39
- package/src/demo/definition.ts +68 -0
- package/src/demo/generate.ts +167 -0
- package/src/demo/index.ts +3 -0
- package/src/demo/run.ts +142 -0
- package/src/iceberg/annotations.ts +62 -0
- package/src/iceberg/error.ts +9 -0
- package/src/iceberg/index.ts +3 -0
- package/src/iceberg/table.ts +511 -0
- package/src/index.ts +3 -1
- package/src/ingestion/engine.ts +240 -60
- package/src/ingestor/arrow.ts +248 -0
- package/src/ingestor/console.ts +13 -0
- package/src/ingestor/index.ts +9 -0
- package/src/ingestor/instrumented.ts +61 -0
- package/src/ingestor/service.ts +30 -0
- package/src/ingestor/wings.ts +143 -0
- package/src/manifest/config.ts +3 -3
- package/src/metrics.ts +125 -33
- package/src/runtime-config/config.ts +14 -0
- package/src/runtime-config/constants.ts +5 -2
- package/src/runtime-config/error.ts +4 -1
- package/src/runtime-config/index.ts +2 -0
- package/src/runtime-config/layer.ts +1 -1
- package/src/runtime-config/table-bindings.ts +92 -0
- package/src/state-store/layer-key-value-store.ts +8 -3
- package/src/state-store/layer-memory.ts +1 -1
- package/src/state-store/layer-sql.ts +4 -4
- package/src/state-store/schema.ts +2 -2
- package/src/state-store/state.ts +14 -2
- package/src/status/route.ts +2 -2
- package/src/telemetry.ts +25 -10
- package/src/webhook/server.ts +39 -40
- package/dist/auth/index.d.ts +0 -2
- package/dist/auth/index.js +0 -3
- package/dist/auth-DvU_CZ7C.js.map +0 -1
- package/dist/connector-app/index.d.ts +0 -14
- package/dist/connector-app/index.js +0 -11
- package/dist/connector-app-d7Z-SZLQ.js +0 -64
- package/dist/connector-app-d7Z-SZLQ.js.map +0 -1
- package/dist/constants-BRhIX_rz.js.map +0 -1
- package/dist/errors/index.d.ts +0 -2
- package/dist/errors/index.js +0 -3
- package/dist/errors-DHWylqRZ.js.map +0 -1
- package/dist/index-Byr0Lf0C.d.ts +0 -25
- package/dist/index-o1-Z3n7V.d.ts +0 -55
- package/dist/index.d.ts +0 -14
- package/dist/index.js +0 -58
- package/dist/index.js.map +0 -1
- package/dist/ingestion/index.d.ts +0 -6
- package/dist/ingestion/index.js +0 -10
- package/dist/ingestion-BQo4cbGw.js +0 -200
- package/dist/ingestion-BQo4cbGw.js.map +0 -1
- package/dist/manifest/index.d.ts +0 -2
- package/dist/manifest-ByE6YPG0.js.map +0 -1
- package/dist/metrics-CVAk1ALR.d.ts +0 -53
- package/dist/metrics-CWPy2Aqc.js +0 -96
- package/dist/metrics-CWPy2Aqc.js.map +0 -1
- package/dist/metrics.d.ts +0 -4
- package/dist/metrics.js +0 -3
- package/dist/publisher/index.d.ts +0 -5
- package/dist/publisher/index.js +0 -6
- package/dist/publisher-BYT3RLVO.js +0 -131
- package/dist/publisher-BYT3RLVO.js.map +0 -1
- package/dist/runtime-config/index.d.ts +0 -2
- package/dist/runtime-config/index.js +0 -4
- package/dist/runtime-config-BpB-d_bF.js +0 -51
- package/dist/runtime-config-BpB-d_bF.js.map +0 -1
- package/dist/server-CXTQ7odl.js.map +0 -1
- package/dist/service-DuFiQwid.js +0 -191
- package/dist/service-DuFiQwid.js.map +0 -1
- package/dist/service-IE5qaf9x.d.ts +0 -32
- package/dist/state-store/index.d.ts +0 -3
- package/dist/state-store/index.js +0 -5
- package/dist/state-store-yl6LiTQ0.js.map +0 -1
- package/dist/status-B-oZBc33.js.map +0 -1
- package/dist/types-B35J5YPu.d.ts +0 -174
- package/dist/webhook/index.d.ts +0 -6
- package/dist/webhook/index.js +0 -8
- package/dist/webhook-DI-Afxkg.js +0 -13
- package/dist/webhook-DI-Afxkg.js.map +0 -1
- package/src/publisher/console.ts +0 -18
- package/src/publisher/index.ts +0 -7
- package/src/publisher/instrumented.ts +0 -68
- package/src/publisher/service.ts +0 -37
- package/src/publisher/wings.ts +0 -204
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Config, Effect, Layer } from "effect";
|
|
2
|
-
import { KeyValueStore } from "effect/
|
|
3
|
-
import { SqlClient } from "effect/
|
|
2
|
+
import { KeyValueStore } from "effect/persistence";
|
|
3
|
+
import { SqlClient } from "effect/sql";
|
|
4
4
|
|
|
5
5
|
import type { StateStore } from "./service";
|
|
6
6
|
|
|
@@ -32,8 +32,8 @@ const scopedKeyValueStore = (connectorInstanceId: string) =>
|
|
|
32
32
|
export const layerSql = (): Layer.Layer<StateStore, Config.ConfigError, SqlClient.SqlClient> =>
|
|
33
33
|
Layer.unwrap(
|
|
34
34
|
Config.all({
|
|
35
|
-
connectorInstanceId: Config.
|
|
36
|
-
table: Config.
|
|
35
|
+
connectorInstanceId: Config.NonEmptyString(PlatformRuntimeKey.connectorInstanceId),
|
|
36
|
+
table: Config.NonEmptyString(PlatformRuntimeKey.stateTable).pipe(
|
|
37
37
|
Config.withDefault(PlatformRuntimeDefault.stateTable),
|
|
38
38
|
),
|
|
39
39
|
}).pipe(
|
|
@@ -18,11 +18,11 @@ export const ChangesStateSchema = Schema.Struct({
|
|
|
18
18
|
|
|
19
19
|
export const StateSourceSchema = Schema.Literals(["backfill", "changes"]);
|
|
20
20
|
|
|
21
|
-
export const StateOperationSchema = Schema.Literals(["fetch", "
|
|
21
|
+
export const StateOperationSchema = Schema.Literals(["fetch", "ingest", "checkpoint"]);
|
|
22
22
|
|
|
23
23
|
export const StateErrorCodeSchema = Schema.Literals([
|
|
24
24
|
"fetch_failed",
|
|
25
|
-
"
|
|
25
|
+
"ingest_failed",
|
|
26
26
|
"checkpoint_failed",
|
|
27
27
|
]);
|
|
28
28
|
|
package/src/state-store/state.ts
CHANGED
|
@@ -1,16 +1,28 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type {
|
|
2
|
+
ConnectorDefinition,
|
|
3
|
+
Cursor,
|
|
4
|
+
ResourceDefinition,
|
|
5
|
+
ResourceState,
|
|
6
|
+
SyncState,
|
|
7
|
+
} from "../core/types";
|
|
2
8
|
|
|
3
9
|
/** Normalizes a cursor value to its persisted/wire representation (never a Date). */
|
|
4
10
|
export const normalizeCursor = (value: Cursor.Value): string | number =>
|
|
5
11
|
value instanceof Date ? value.toISOString() : value;
|
|
6
12
|
|
|
13
|
+
/** Whether a resource gets changes, from its own `changes` or the connector's feed. */
|
|
14
|
+
export const hasChanges = (connector: ConnectorDefinition, resource: ResourceDefinition) =>
|
|
15
|
+
resource.changes !== undefined ||
|
|
16
|
+
(connector.changes?.resources.some((member) => member.name === resource.name) ?? false);
|
|
17
|
+
|
|
7
18
|
/** Derives connector-facing sync state from durable state and resource capabilities. */
|
|
8
19
|
export const deriveSyncState = (
|
|
20
|
+
connector: ConnectorDefinition,
|
|
9
21
|
resource: ResourceDefinition,
|
|
10
22
|
state: ResourceState | undefined,
|
|
11
23
|
): SyncState => {
|
|
12
24
|
if (state?.lastError) return "error";
|
|
13
|
-
if (!resource.backfill && !resource
|
|
25
|
+
if (!resource.backfill && !hasChanges(connector, resource)) return "live";
|
|
14
26
|
if (!state) return "pending";
|
|
15
27
|
if (resource.backfill && (!state.backfill || !state.backfill.completed)) return "backfilling";
|
|
16
28
|
return "live";
|
package/src/status/route.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Cause, Effect } from "effect";
|
|
2
|
-
import { HttpRouter, HttpServerResponse } from "effect/
|
|
2
|
+
import { HttpRouter, HttpServerResponse } from "effect/http";
|
|
3
3
|
|
|
4
4
|
import type { ConnectorDefinition } from "../core/types";
|
|
5
5
|
import type { ResourceStatus, StatusUnavailableResponse } from "./types";
|
|
@@ -24,7 +24,7 @@ export const statusRoute = (
|
|
|
24
24
|
Effect.map(
|
|
25
25
|
(state): ResourceStatus => ({
|
|
26
26
|
name: resource.name,
|
|
27
|
-
state: deriveSyncState(resource, state),
|
|
27
|
+
state: deriveSyncState(connector, resource, state),
|
|
28
28
|
...(state?.backfill
|
|
29
29
|
? {
|
|
30
30
|
backfill: {
|
package/src/telemetry.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Cause, Config, Effect, Layer, Metric, Option, type Duration } from "effect";
|
|
2
|
-
import { Headers } from "effect/
|
|
3
|
-
import * as Observability from "effect/
|
|
2
|
+
import { Headers } from "effect/http";
|
|
3
|
+
import * as Observability from "effect/observability";
|
|
4
4
|
|
|
5
5
|
import { PlatformRuntimeKey } from "./runtime-config/constants";
|
|
6
6
|
|
|
@@ -9,7 +9,7 @@ export const SpanName = {
|
|
|
9
9
|
batchProcess: "connector.batch.process",
|
|
10
10
|
webhookDecode: "connector.webhook.decode",
|
|
11
11
|
webhookHandle: "connector.webhook.handle",
|
|
12
|
-
|
|
12
|
+
ingest: "connector.ingest",
|
|
13
13
|
stateSet: "connector.state.set",
|
|
14
14
|
apiFetch: "connector.api.fetch",
|
|
15
15
|
} as const;
|
|
@@ -20,9 +20,13 @@ export const Attr = {
|
|
|
20
20
|
connectorResourcesCount: "airfoil.connector.resources.count",
|
|
21
21
|
resourceName: "airfoil.resource.name",
|
|
22
22
|
resourceSource: "airfoil.resource.source",
|
|
23
|
-
|
|
23
|
+
batchRows: "airfoil.batch.rows",
|
|
24
|
+
batchOutcome: "airfoil.batch.outcome",
|
|
24
25
|
webhookPath: "airfoil.webhook.path",
|
|
25
|
-
|
|
26
|
+
webhookOutcome: "airfoil.webhook.outcome",
|
|
27
|
+
syncState: "airfoil.connector.sync.state",
|
|
28
|
+
apiRetryReason: "airfoil.connector.api.retry.reason",
|
|
29
|
+
ingestionSuccess: "airfoil.ingestion.success",
|
|
26
30
|
stateKey: "airfoil.state.key",
|
|
27
31
|
apiPath: "airfoil.api.path",
|
|
28
32
|
errorPhase: "airfoil.error.phase",
|
|
@@ -31,6 +35,13 @@ export const Attr = {
|
|
|
31
35
|
errorDetails: "airfoil.error.details",
|
|
32
36
|
} as const;
|
|
33
37
|
|
|
38
|
+
/** Resource attributes injected by the hosted operator through standard OTel environment keys. */
|
|
39
|
+
export const ResourceAttr = {
|
|
40
|
+
serviceInstanceId: "service.instance.id",
|
|
41
|
+
connectorRevision: "airfoil.connector.revision",
|
|
42
|
+
teamId: "airfoil.team.id",
|
|
43
|
+
} as const;
|
|
44
|
+
|
|
34
45
|
/** Span event names for high-cardinality reproduction details. */
|
|
35
46
|
export const EventName = {
|
|
36
47
|
batchCheckpoint: "airfoil.batch.checkpoint",
|
|
@@ -47,9 +58,9 @@ const isRecord = (value: unknown): value is Record<string, unknown> =>
|
|
|
47
58
|
const maxErrorMessageLength = 500;
|
|
48
59
|
|
|
49
60
|
const OtlpEnvConfig = Config.all({
|
|
50
|
-
enabled: Config.
|
|
51
|
-
baseUrl: Config.option(Config.
|
|
52
|
-
rawHeaders: Config.option(Config.
|
|
61
|
+
enabled: Config.Boolean(PlatformRuntimeKey.otelEnabled).pipe(Config.withDefault(false)),
|
|
62
|
+
baseUrl: Config.option(Config.String(PlatformRuntimeKey.otelExporterOtlpEndpoint)),
|
|
63
|
+
rawHeaders: Config.option(Config.String(PlatformRuntimeKey.otelExporterOtlpHeaders)),
|
|
53
64
|
});
|
|
54
65
|
|
|
55
66
|
const defaultRedactedHeaders: ReadonlyArray<string | RegExp> = [
|
|
@@ -165,6 +176,7 @@ export type OtlpTracingOptions = {
|
|
|
165
176
|
readonly redactedHeaders?: ReadonlyArray<string | RegExp>;
|
|
166
177
|
};
|
|
167
178
|
|
|
179
|
+
/** OTLP metric export settings. */
|
|
168
180
|
export type OtlpMetricsOptions = {
|
|
169
181
|
readonly exportInterval?: Duration.Input;
|
|
170
182
|
};
|
|
@@ -211,8 +223,8 @@ export const layer = (config: OtlpTracingConfig = {}, options: OtlpTracingOption
|
|
|
211
223
|
*
|
|
212
224
|
* @example
|
|
213
225
|
* Telemetry.layerConfig({
|
|
214
|
-
* enabled: Config.
|
|
215
|
-
* endpoint: Config.
|
|
226
|
+
* enabled: Config.Boolean("MY_OTEL_ENABLED"),
|
|
227
|
+
* endpoint: Config.String("MY_COLLECTOR_URL"),
|
|
216
228
|
* })
|
|
217
229
|
*/
|
|
218
230
|
export const layerConfig = (
|
|
@@ -251,6 +263,7 @@ export const layerOtlpTracing = (options: OtlpTracingOptions = {}) =>
|
|
|
251
263
|
}),
|
|
252
264
|
);
|
|
253
265
|
|
|
266
|
+
/** Exports connector metrics over OTLP when telemetry is enabled. */
|
|
254
267
|
export const layerOtlpMetrics = (options: OtlpMetricsOptions = {}) =>
|
|
255
268
|
Layer.unwrap(
|
|
256
269
|
Effect.gen(function* () {
|
|
@@ -270,9 +283,11 @@ export const layerOtlpMetrics = (options: OtlpMetricsOptions = {}) =>
|
|
|
270
283
|
}),
|
|
271
284
|
);
|
|
272
285
|
|
|
286
|
+
/** Enables OTLP traces and metrics with shared environment configuration. */
|
|
273
287
|
export const layerOtlp = (options: OtlpTracingOptions & OtlpMetricsOptions = {}) =>
|
|
274
288
|
Layer.mergeAll(layerOtlpTracing(options), layerOtlpMetrics(options));
|
|
275
289
|
|
|
290
|
+
/** Periodically logs the in-memory metric snapshot for local debugging. */
|
|
276
291
|
export const layerMetricsConsoleDump = (interval: Duration.Input = "30 seconds") =>
|
|
277
292
|
Layer.effectDiscard(
|
|
278
293
|
Effect.gen(function* () {
|
package/src/webhook/server.ts
CHANGED
|
@@ -1,18 +1,16 @@
|
|
|
1
1
|
import { Cause, Context, Effect, Queue, Schema } from "effect";
|
|
2
|
-
import { HttpRouter, HttpServerRequest, HttpServerResponse } from "effect/
|
|
2
|
+
import { HttpRouter, HttpServerRequest, HttpServerResponse } from "effect/http";
|
|
3
3
|
|
|
4
4
|
import type {
|
|
5
5
|
ResourceBatch,
|
|
6
6
|
ResourceDefinition,
|
|
7
|
-
ResourceMutation,
|
|
8
|
-
WebhookHandler,
|
|
9
7
|
WebhookRoute,
|
|
10
8
|
WebhookRouteContext,
|
|
11
9
|
} from "../core/types";
|
|
12
10
|
|
|
13
11
|
import { ConnectorError } from "../errors";
|
|
12
|
+
import { ingestBatch } from "../ingestor/instrumented";
|
|
14
13
|
import * as Metrics from "../metrics";
|
|
15
|
-
import { publishBatch } from "../publisher/instrumented";
|
|
16
14
|
import { Attr, SpanName, annotateError } from "../telemetry";
|
|
17
15
|
|
|
18
16
|
export type QueuedWebhookBatch = {
|
|
@@ -27,39 +25,23 @@ export class WebhookQueue extends Context.Service<
|
|
|
27
25
|
}
|
|
28
26
|
>()("@useairfoil/connector-kit/WebhookQueue") {}
|
|
29
27
|
|
|
30
|
-
const resourceBatch = <Row extends object>(
|
|
31
|
-
|
|
32
|
-
): ResourceBatch<Row> => ({
|
|
33
|
-
mutations,
|
|
28
|
+
const resourceBatch = <Row extends object>(rows: ReadonlyArray<Row>): ResourceBatch<Row> => ({
|
|
29
|
+
rows,
|
|
34
30
|
});
|
|
35
31
|
|
|
36
|
-
const decodeAndHandleWebhook = <Row extends object, Payload>(
|
|
37
|
-
resourceName: string,
|
|
38
|
-
webhook: WebhookHandler<Row, Payload>,
|
|
39
|
-
payload: unknown,
|
|
40
|
-
) =>
|
|
41
|
-
Schema.decodeUnknownEffect(webhook.schema)(payload).pipe(
|
|
42
|
-
Effect.mapError(
|
|
43
|
-
(cause) =>
|
|
44
|
-
new ConnectorError({
|
|
45
|
-
message: `Invalid webhook payload for resource ${resourceName}`,
|
|
46
|
-
cause,
|
|
47
|
-
}),
|
|
48
|
-
),
|
|
49
|
-
Effect.flatMap((decoded) => webhook.handler({ payload: decoded })),
|
|
50
|
-
);
|
|
51
|
-
|
|
52
32
|
const makeRouteContext = (
|
|
53
33
|
request: HttpServerRequest.HttpServerRequest,
|
|
54
34
|
rawBody: Uint8Array,
|
|
55
35
|
payload: unknown,
|
|
56
36
|
batches: Array<QueuedWebhookBatch>,
|
|
37
|
+
resourceNames: ReadonlyArray<string>,
|
|
57
38
|
): WebhookRouteContext<ReadonlyArray<ResourceDefinition>, unknown> => ({
|
|
58
39
|
request,
|
|
59
40
|
rawBody,
|
|
60
41
|
payload,
|
|
61
42
|
to: (resource, payload) =>
|
|
62
43
|
Effect.gen(function* () {
|
|
44
|
+
if (!resourceNames.includes(resource.name)) return;
|
|
63
45
|
if (!resource.webhook) {
|
|
64
46
|
return yield* Effect.fail(
|
|
65
47
|
new ConnectorError({
|
|
@@ -68,27 +50,28 @@ const makeRouteContext = (
|
|
|
68
50
|
);
|
|
69
51
|
}
|
|
70
52
|
|
|
71
|
-
|
|
53
|
+
// The route already decoded the payload, so don't decode it again.
|
|
54
|
+
const rows = yield* resource.webhook.handler({ payload });
|
|
72
55
|
batches.push({
|
|
73
56
|
resource: resource.name,
|
|
74
|
-
batch: resourceBatch(
|
|
57
|
+
batch: resourceBatch(rows),
|
|
75
58
|
});
|
|
76
59
|
}),
|
|
77
60
|
});
|
|
78
61
|
|
|
79
62
|
const compactBatches = (batches: ReadonlyArray<QueuedWebhookBatch>) => {
|
|
80
|
-
const grouped = new Map<string,
|
|
63
|
+
const grouped = new Map<string, object[]>();
|
|
81
64
|
for (const item of batches) {
|
|
82
65
|
const current = grouped.get(item.resource) ?? [];
|
|
83
|
-
grouped.set(item.resource, [...current, ...item.batch.
|
|
66
|
+
grouped.set(item.resource, [...current, ...item.batch.rows]);
|
|
84
67
|
}
|
|
85
|
-
return Array.from(grouped.entries()).map(([resource,
|
|
68
|
+
return Array.from(grouped.entries()).map(([resource, rows]) => ({
|
|
86
69
|
resource,
|
|
87
|
-
batch: resourceBatch(
|
|
70
|
+
batch: resourceBatch(rows),
|
|
88
71
|
}));
|
|
89
72
|
};
|
|
90
73
|
|
|
91
|
-
const
|
|
74
|
+
const ingestBatches = (
|
|
92
75
|
batches: ReadonlyArray<QueuedWebhookBatch>,
|
|
93
76
|
options: { readonly connectorName: string },
|
|
94
77
|
) =>
|
|
@@ -96,7 +79,7 @@ const publishBatches = (
|
|
|
96
79
|
yield* Effect.forEach(
|
|
97
80
|
batches,
|
|
98
81
|
(batch) =>
|
|
99
|
-
|
|
82
|
+
ingestBatch({
|
|
100
83
|
connector: options.connectorName,
|
|
101
84
|
resource: batch.resource,
|
|
102
85
|
source: "webhook",
|
|
@@ -118,7 +101,13 @@ const parseJson = (rawBody: Uint8Array) =>
|
|
|
118
101
|
catch: (cause) => new ConnectorError({ message: "Invalid webhook JSON", cause }),
|
|
119
102
|
});
|
|
120
103
|
|
|
121
|
-
|
|
104
|
+
type RouterOptions = {
|
|
105
|
+
readonly connectorName: string;
|
|
106
|
+
/** Events for other resources are skipped. */
|
|
107
|
+
readonly resourceNames: ReadonlyArray<string>;
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
const makeHandler = (route: WebhookRoute, options: RouterOptions) =>
|
|
122
111
|
Effect.gen(function* () {
|
|
123
112
|
const request = yield* HttpServerRequest.HttpServerRequest;
|
|
124
113
|
const collected: Array<QueuedWebhookBatch> = [];
|
|
@@ -129,6 +118,7 @@ const makeHandler = (route: WebhookRoute, options: { readonly connectorName: str
|
|
|
129
118
|
onSuccess: (value) => ({ _tag: "Success" as const, value }),
|
|
130
119
|
}),
|
|
131
120
|
);
|
|
121
|
+
|
|
132
122
|
if (rawBodyResult._tag === "Error") {
|
|
133
123
|
yield* Metrics.recordWebhookRequest({
|
|
134
124
|
connector: options.connectorName,
|
|
@@ -144,6 +134,7 @@ const makeHandler = (route: WebhookRoute, options: { readonly connectorName: str
|
|
|
144
134
|
onSuccess: (value) => ({ _tag: "Success" as const, value }),
|
|
145
135
|
}),
|
|
146
136
|
);
|
|
137
|
+
|
|
147
138
|
if (jsonResult._tag === "Error") {
|
|
148
139
|
yield* Metrics.recordWebhookRequest({
|
|
149
140
|
connector: options.connectorName,
|
|
@@ -159,6 +150,7 @@ const makeHandler = (route: WebhookRoute, options: { readonly connectorName: str
|
|
|
159
150
|
onSuccess: (value) => ({ _tag: "Success" as const, value }),
|
|
160
151
|
}),
|
|
161
152
|
);
|
|
153
|
+
|
|
162
154
|
if (payloadResult._tag === "Error") {
|
|
163
155
|
yield* Metrics.recordWebhookRequest({
|
|
164
156
|
connector: options.connectorName,
|
|
@@ -170,7 +162,15 @@ const makeHandler = (route: WebhookRoute, options: { readonly connectorName: str
|
|
|
170
162
|
|
|
171
163
|
const response = yield* Effect.withSpan(
|
|
172
164
|
route
|
|
173
|
-
.handler(
|
|
165
|
+
.handler(
|
|
166
|
+
makeRouteContext(
|
|
167
|
+
request,
|
|
168
|
+
rawBodyResult.value,
|
|
169
|
+
payloadResult.value,
|
|
170
|
+
collected,
|
|
171
|
+
options.resourceNames,
|
|
172
|
+
),
|
|
173
|
+
)
|
|
174
174
|
.pipe(Effect.tapError((error) => annotateError("webhook_handle", error))),
|
|
175
175
|
SpanName.webhookHandle,
|
|
176
176
|
{ attributes: { [Attr.webhookPath]: route.path } },
|
|
@@ -188,12 +188,13 @@ const makeHandler = (route: WebhookRoute, options: { readonly connectorName: str
|
|
|
188
188
|
path: String(route.path),
|
|
189
189
|
outcome: response.status >= 400 ? "rejected" : "ok",
|
|
190
190
|
});
|
|
191
|
+
|
|
191
192
|
return response;
|
|
192
193
|
}
|
|
193
194
|
|
|
194
195
|
yield* Effect.withSpan(
|
|
195
|
-
|
|
196
|
-
Effect.tapError((error) => annotateError("
|
|
196
|
+
ingestBatches(batches, { connectorName: options.connectorName }).pipe(
|
|
197
|
+
Effect.tapError((error) => annotateError("webhook_ingest", error)),
|
|
197
198
|
),
|
|
198
199
|
SpanName.webhookHandle,
|
|
199
200
|
{ attributes: { [Attr.webhookPath]: route.path } },
|
|
@@ -204,6 +205,7 @@ const makeHandler = (route: WebhookRoute, options: { readonly connectorName: str
|
|
|
204
205
|
path: String(route.path),
|
|
205
206
|
outcome: response.status >= 400 ? "rejected" : "ok",
|
|
206
207
|
});
|
|
208
|
+
|
|
207
209
|
return response;
|
|
208
210
|
}).pipe(
|
|
209
211
|
Effect.catchCause((cause) =>
|
|
@@ -225,10 +227,7 @@ const makeHandler = (route: WebhookRoute, options: { readonly connectorName: str
|
|
|
225
227
|
),
|
|
226
228
|
);
|
|
227
229
|
|
|
228
|
-
export const router = (
|
|
229
|
-
routes: ReadonlyArray<WebhookRoute>,
|
|
230
|
-
options: { readonly connectorName: string },
|
|
231
|
-
) =>
|
|
230
|
+
export const router = (routes: ReadonlyArray<WebhookRoute>, options: RouterOptions) =>
|
|
232
231
|
HttpRouter.addAll(
|
|
233
232
|
routes.map((route) => HttpRouter.route("POST", route.path, makeHandler(route, options))),
|
|
234
233
|
);
|
package/dist/auth/index.d.ts
DELETED
package/dist/auth/index.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"auth-DvU_CZ7C.js","names":[],"sources":["../src/auth/token-cache.ts","../src/auth/index.ts"],"sourcesContent":["import { Cache, Duration, Effect, Exit, Number, Redacted } from \"effect\";\n\nexport interface ExpiringToken {\n /** The credential kept in memory by the cache. */\n readonly value: Redacted.Redacted<string>;\n /** The lifetime reported by the provider. */\n readonly expiresIn: Duration.Duration;\n}\n\nexport interface TokenCache<E> {\n /** Returns the cached token or performs one shared acquisition. */\n readonly get: Effect.Effect<Redacted.Redacted<string>, E>;\n /** Removes the cached token so the next `get` reacquires it. */\n readonly invalidate: Effect.Effect<void>;\n}\n\n/**\n * Creates a lazy, in-memory token cache around an acquisition effect.\n *\n * `refreshFactor` controls how much of the provider lifetime is cached. It is\n * clamped between `0` and `1`.\n *\n * @example\n * ```ts\n * const cache = yield* makeTokenCache({\n * acquire: exchangeCredentials,\n * refreshFactor: 0.5,\n * })\n *\n * const token = yield* cache.get\n * ```\n */\nexport const makeTokenCache = <E, R>(options: {\n readonly acquire: Effect.Effect<ExpiringToken, E, R>;\n readonly refreshFactor?: number;\n}): Effect.Effect<TokenCache<E>, never, R> =>\n Effect.gen(function* () {\n const refreshFactor = Number.clamp(options.refreshFactor ?? 0.5, {\n minimum: 0,\n maximum: 1,\n });\n const cache = yield* Cache.makeWith((_: void) => options.acquire, {\n capacity: 1,\n timeToLive: (exit) =>\n Exit.isSuccess(exit)\n ? Duration.millis(Duration.toMillis(exit.value.expiresIn) * refreshFactor)\n : Duration.zero,\n });\n\n return {\n get: Cache.get(cache, undefined).pipe(Effect.map((token) => token.value)),\n invalidate: Cache.invalidate(cache, undefined),\n };\n });\n","export * from \"./token-cache\";\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAgCA,MAAa,kBAAwB,YAInC,OAAO,IAAI,aAAa;CACtB,MAAM,gBAAgB,OAAO,MAAM,QAAQ,iBAAiB,IAAK;EAC/D,SAAS;EACT,SAAS;EACV,CAAC;CACF,MAAM,QAAQ,OAAO,MAAM,UAAU,MAAY,QAAQ,SAAS;EAChE,UAAU;EACV,aAAa,SACX,KAAK,UAAU,KAAK,GAChB,SAAS,OAAO,SAAS,SAAS,KAAK,MAAM,UAAU,GAAG,cAAc,GACxE,SAAS;EAChB,CAAC;AAEF,QAAO;EACL,KAAK,MAAM,IAAI,OAAO,OAAU,CAAC,KAAK,OAAO,KAAK,UAAU,MAAM,MAAM,CAAC;EACzE,YAAY,MAAM,WAAW,OAAO,OAAU;EAC/C;EACD"}
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import "../index-CTHVudvQ.js";
|
|
2
|
-
import "../index-D54ySAKn.js";
|
|
3
|
-
import "../types-B35J5YPu.js";
|
|
4
|
-
import { d as CheckResult, f as ResourceCheckResult, i as start, n as App, p as check, r as StartOptions, u as CheckOptions } from "../index-DtJX_tic.js";
|
|
5
|
-
import "../service-IE5qaf9x.js";
|
|
6
|
-
import "../index-Coh_SkBs.js";
|
|
7
|
-
import "../index-J42AZaXU.js";
|
|
8
|
-
import "../index-CBT-JX-T.js";
|
|
9
|
-
import "../metrics-CVAk1ALR.js";
|
|
10
|
-
import "../index-Byr0Lf0C.js";
|
|
11
|
-
import "../index-o1-Z3n7V.js";
|
|
12
|
-
import "../index-Cq2IzY7T.js";
|
|
13
|
-
import "../index-DKWIh6M1.js";
|
|
14
|
-
export { App, CheckOptions, CheckResult, ResourceCheckResult, StartOptions, check, start };
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import "../errors-DHWylqRZ.js";
|
|
2
|
-
import { n as start, r as check } from "../connector-app-d7Z-SZLQ.js";
|
|
3
|
-
import "../metrics-CWPy2Aqc.js";
|
|
4
|
-
import "../constants-BRhIX_rz.js";
|
|
5
|
-
import "../service-DuFiQwid.js";
|
|
6
|
-
import "../server-CXTQ7odl.js";
|
|
7
|
-
import "../state-store-yl6LiTQ0.js";
|
|
8
|
-
import "../status-B-oZBc33.js";
|
|
9
|
-
import "../ingestion-BQo4cbGw.js";
|
|
10
|
-
|
|
11
|
-
export { check, start };
|
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
import { t as __export } from "./chunk-Bp6m_JJh.js";
|
|
2
|
-
import { n as run } from "./ingestion-BQo4cbGw.js";
|
|
3
|
-
import { Context, DateTime, Effect, Layer, Tuple } from "effect";
|
|
4
|
-
import { NodeHttpServer } from "@effect/platform-node";
|
|
5
|
-
import { HttpRouter } from "effect/unstable/http";
|
|
6
|
-
import { createServer } from "node:http";
|
|
7
|
-
|
|
8
|
-
//#region src/connector-app/check.ts
|
|
9
|
-
const ok = { _tag: "ok" };
|
|
10
|
-
const error = (message) => ({
|
|
11
|
-
_tag: "error",
|
|
12
|
-
message
|
|
13
|
-
});
|
|
14
|
-
const fromEntries = (entries) => Object.fromEntries(entries);
|
|
15
|
-
const resultsFor = (names, result) => fromEntries(names.map((name) => Tuple.make(name, result)));
|
|
16
|
-
/**
|
|
17
|
-
* Builds the connector service from its layer and validates only the selected
|
|
18
|
-
* resources. The layer remains open until every check finishes.
|
|
19
|
-
*/
|
|
20
|
-
function check(service, layer, options) {
|
|
21
|
-
if (options.resources.length === 0) return Effect.succeed(fromEntries([]));
|
|
22
|
-
return service.pipe(Effect.flatMap((connector) => Effect.forEach(options.resources, (name) => {
|
|
23
|
-
const resource = connector.resources.find((candidate) => candidate.name === name);
|
|
24
|
-
return (resource ? resource.check.pipe(Effect.match({
|
|
25
|
-
onFailure: (failure) => error(failure.message),
|
|
26
|
-
onSuccess: () => ok
|
|
27
|
-
})) : Effect.succeed(error(`Unknown connector resource: ${name}`))).pipe(Effect.map((result) => Tuple.make(name, result)));
|
|
28
|
-
}).pipe(Effect.map(fromEntries))), Effect.provide(layer), Effect.match({
|
|
29
|
-
onFailure: (failure) => resultsFor(options.resources, error(failure.message)),
|
|
30
|
-
onSuccess: (results) => results
|
|
31
|
-
}));
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
//#endregion
|
|
35
|
-
//#region src/connector-app/start.ts
|
|
36
|
-
const start = (app, options) => Effect.gen(function* () {
|
|
37
|
-
const initialCutoff = options.initialCutoff ?? (yield* DateTime.now.pipe(Effect.map(DateTime.formatIso)));
|
|
38
|
-
const routes = app.webhooks?.map((route) => route.path) ?? [];
|
|
39
|
-
yield* Effect.logInfo("webhook server ready").pipe(Effect.annotateLogs({
|
|
40
|
-
port: options.port,
|
|
41
|
-
routes
|
|
42
|
-
}));
|
|
43
|
-
return yield* run(app, {
|
|
44
|
-
initialCutoff,
|
|
45
|
-
webhook: {
|
|
46
|
-
routes: app.webhooks ?? [],
|
|
47
|
-
healthPath: options.healthPath ?? "/health",
|
|
48
|
-
metricsPath: options.metricsPath,
|
|
49
|
-
statusPath: options.statusPath,
|
|
50
|
-
disableHttpLogger: options.disableHttpLogger ?? true
|
|
51
|
-
}
|
|
52
|
-
}).pipe(Effect.provide(NodeHttpServer.layer(createServer, { port: options.port })));
|
|
53
|
-
});
|
|
54
|
-
|
|
55
|
-
//#endregion
|
|
56
|
-
//#region src/connector-app/index.ts
|
|
57
|
-
var connector_app_exports = /* @__PURE__ */ __export({
|
|
58
|
-
check: () => check,
|
|
59
|
-
start: () => start
|
|
60
|
-
});
|
|
61
|
-
|
|
62
|
-
//#endregion
|
|
63
|
-
export { start as n, check as r, connector_app_exports as t };
|
|
64
|
-
//# sourceMappingURL=connector-app-d7Z-SZLQ.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"connector-app-d7Z-SZLQ.js","names":["ok: ResourceCheckResult","runIngestion"],"sources":["../src/connector-app/check.ts","../src/connector-app/start.ts","../src/connector-app/index.ts"],"sourcesContent":["import { Context, Effect, Layer, Tuple } from \"effect\";\n\nimport type { ConnectorDefinition, ResourceDefinition, ResourceName } from \"../core/types\";\n\nexport type ResourceCheckResult =\n | { readonly _tag: \"ok\" }\n | { readonly _tag: \"error\"; readonly message: string };\n\nexport type CheckOptions<Name extends string> = {\n readonly resources: ReadonlyArray<Name>;\n};\n\ntype ResourceCheckResults<Name extends PropertyKey> = {\n readonly [Key in Name]: ResourceCheckResult;\n};\n\nexport type CheckResult<\n Resources extends ReadonlyArray<ResourceDefinition>,\n Name extends ResourceName<Resources> = ResourceName<Resources>,\n> = ResourceCheckResults<Name>;\n\ntype CheckFailure = { readonly message: string };\n\nconst ok: ResourceCheckResult = { _tag: \"ok\" };\n\nconst error = (message: string): ResourceCheckResult => ({ _tag: \"error\", message });\n\nconst fromEntries = <Name extends string>(\n entries: ReadonlyArray<readonly [Name, ResourceCheckResult]>,\n): ResourceCheckResults<Name> => Object.fromEntries(entries) as ResourceCheckResults<Name>;\n\nconst resultsFor = <Name extends string>(names: ReadonlyArray<Name>, result: ResourceCheckResult) =>\n fromEntries(names.map((name) => Tuple.make(name, result)));\n\n/**\n * Builds the connector service from its layer and validates only the selected\n * resources. The layer remains open until every check finishes.\n */\nexport function check<\n Identifier,\n const Resources extends ReadonlyArray<ResourceDefinition>,\n E extends CheckFailure,\n R,\n const Name extends ResourceName<Resources>,\n>(\n service: Context.Key<Identifier, ConnectorDefinition<Resources>>,\n layer: Layer.Layer<Identifier, E, R>,\n options: CheckOptions<Name>,\n): Effect.Effect<CheckResult<Resources, Name>, never, R> {\n if (options.resources.length === 0) {\n return Effect.succeed(fromEntries<Name>([]));\n }\n\n return service.pipe(\n Effect.flatMap((connector) =>\n Effect.forEach(options.resources, (name) => {\n const resource = connector.resources.find((candidate) => candidate.name === name);\n const result = resource\n ? resource.check.pipe(\n Effect.match({\n onFailure: (failure) => error(failure.message),\n onSuccess: () => ok,\n }),\n )\n : Effect.succeed(error(`Unknown connector resource: ${name}`));\n\n return result.pipe(Effect.map((result) => Tuple.make(name, result)));\n }).pipe(Effect.map(fromEntries)),\n ),\n Effect.provide(layer),\n Effect.match({\n onFailure: (failure) => resultsFor(options.resources, error(failure.message)),\n onSuccess: (results) => results,\n }),\n );\n}\n","import { NodeHttpServer } from \"@effect/platform-node\";\nimport { DateTime, Effect } from \"effect\";\nimport { HttpRouter } from \"effect/unstable/http\";\nimport { createServer } from \"node:http\";\n\nimport type { ConnectorDefinition } from \"../core\";\nimport type { Cursor } from \"../core/types\";\n\nimport { run as runIngestion } from \"../ingestion\";\n\nexport type App = ConnectorDefinition;\n\nexport type StartOptions = {\n readonly port: number;\n readonly initialCutoff?: Cursor.Value;\n readonly healthPath?: HttpRouter.PathInput;\n readonly metricsPath?: HttpRouter.PathInput | false;\n readonly statusPath?: HttpRouter.PathInput | false;\n readonly disableHttpLogger?: boolean;\n};\n\nexport const start = (app: App, options: StartOptions) =>\n Effect.gen(function* () {\n const initialCutoff =\n options.initialCutoff ?? (yield* DateTime.now.pipe(Effect.map(DateTime.formatIso)));\n const routes = app.webhooks?.map((route) => route.path) ?? [];\n\n yield* Effect.logInfo(\"webhook server ready\").pipe(\n Effect.annotateLogs({ port: options.port, routes }),\n );\n\n return yield* runIngestion(app, {\n initialCutoff,\n webhook: {\n routes: app.webhooks ?? [],\n healthPath: options.healthPath ?? \"/health\",\n metricsPath: options.metricsPath,\n statusPath: options.statusPath,\n disableHttpLogger: options.disableHttpLogger ?? true,\n },\n }).pipe(Effect.provide(NodeHttpServer.layer(createServer, { port: options.port })));\n });\n","export { check, type CheckOptions, type CheckResult, type ResourceCheckResult } from \"./check\";\nexport { start, type App, type StartOptions } from \"./start\";\n"],"mappings":";;;;;;;;AAuBA,MAAMA,KAA0B,EAAE,MAAM,MAAM;AAE9C,MAAM,SAAS,aAA0C;CAAE,MAAM;CAAS;CAAS;AAEnF,MAAM,eACJ,YAC+B,OAAO,YAAY,QAAQ;AAE5D,MAAM,cAAmC,OAA4B,WACnE,YAAY,MAAM,KAAK,SAAS,MAAM,KAAK,MAAM,OAAO,CAAC,CAAC;;;;;AAM5D,SAAgB,MAOd,SACA,OACA,SACuD;AACvD,KAAI,QAAQ,UAAU,WAAW,EAC/B,QAAO,OAAO,QAAQ,YAAkB,EAAE,CAAC,CAAC;AAG9C,QAAO,QAAQ,KACb,OAAO,SAAS,cACd,OAAO,QAAQ,QAAQ,YAAY,SAAS;EAC1C,MAAM,WAAW,UAAU,UAAU,MAAM,cAAc,UAAU,SAAS,KAAK;AAUjF,UATe,WACX,SAAS,MAAM,KACb,OAAO,MAAM;GACX,YAAY,YAAY,MAAM,QAAQ,QAAQ;GAC9C,iBAAiB;GAClB,CAAC,CACH,GACD,OAAO,QAAQ,MAAM,+BAA+B,OAAO,CAAC,EAElD,KAAK,OAAO,KAAK,WAAW,MAAM,KAAK,MAAM,OAAO,CAAC,CAAC;GACpE,CAAC,KAAK,OAAO,IAAI,YAAY,CAAC,CACjC,EACD,OAAO,QAAQ,MAAM,EACrB,OAAO,MAAM;EACX,YAAY,YAAY,WAAW,QAAQ,WAAW,MAAM,QAAQ,QAAQ,CAAC;EAC7E,YAAY,YAAY;EACzB,CAAC,CACH;;;;;ACrDH,MAAa,SAAS,KAAU,YAC9B,OAAO,IAAI,aAAa;CACtB,MAAM,gBACJ,QAAQ,kBAAkB,OAAO,SAAS,IAAI,KAAK,OAAO,IAAI,SAAS,UAAU,CAAC;CACpF,MAAM,SAAS,IAAI,UAAU,KAAK,UAAU,MAAM,KAAK,IAAI,EAAE;AAE7D,QAAO,OAAO,QAAQ,uBAAuB,CAAC,KAC5C,OAAO,aAAa;EAAE,MAAM,QAAQ;EAAM;EAAQ,CAAC,CACpD;AAED,QAAO,OAAOC,IAAa,KAAK;EAC9B;EACA,SAAS;GACP,QAAQ,IAAI,YAAY,EAAE;GAC1B,YAAY,QAAQ,cAAc;GAClC,aAAa,QAAQ;GACrB,YAAY,QAAQ;GACpB,mBAAmB,QAAQ,qBAAqB;GACjD;EACF,CAAC,CAAC,KAAK,OAAO,QAAQ,eAAe,MAAM,cAAc,EAAE,MAAM,QAAQ,MAAM,CAAC,CAAC,CAAC;EACnF"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"constants-BRhIX_rz.js","names":[],"sources":["../src/runtime-config/constants.ts"],"sourcesContent":["import { HashSet } from \"effect\";\n\n/** Shared runtime keys owned by Airfoil rather than an individual connector. */\nexport const PlatformRuntimeKey = {\n configPath: \"AIRFOIL_CONFIG_PATH\",\n connectorInstanceId: \"AIRFOIL_CONNECTOR_INSTANCE_ID\",\n stateTable: \"AIRFOIL_STATE_TABLE\",\n postgresConnectionString: \"POSTGRES_CONNECTION_STRING\",\n wingsHost: \"WINGS_HOST\",\n wingsNamespace: \"WINGS_NAMESPACE\",\n otelEnabled: \"OTEL_ENABLED\",\n otelExporterOtlpEndpoint: \"OTEL_EXPORTER_OTLP_ENDPOINT\",\n otelExporterOtlpHeaders: \"OTEL_EXPORTER_OTLP_HEADERS\",\n otelServiceName: \"OTEL_SERVICE_NAME\",\n otelServiceVersion: \"OTEL_SERVICE_VERSION\",\n otelResourceAttributes: \"OTEL_RESOURCE_ATTRIBUTES\",\n} as const;\n\n/** Defaults for optional platform-owned runtime configuration. */\nexport const PlatformRuntimeDefault = {\n stateTable: \"_airfoil_connectors_state\",\n} as const;\n\nconst platformRuntimeKeys = HashSet.fromIterable(Object.values(PlatformRuntimeKey));\n\n/** @internal */\nexport const isPlatformRuntimeKey = (key: string): boolean => HashSet.has(platformRuntimeKeys, key);\n"],"mappings":";;;;AAGA,MAAa,qBAAqB;CAChC,YAAY;CACZ,qBAAqB;CACrB,YAAY;CACZ,0BAA0B;CAC1B,WAAW;CACX,gBAAgB;CAChB,aAAa;CACb,0BAA0B;CAC1B,yBAAyB;CACzB,iBAAiB;CACjB,oBAAoB;CACpB,wBAAwB;CACzB;;AAGD,MAAa,yBAAyB,EACpC,YAAY,6BACb;AAED,MAAM,sBAAsB,QAAQ,aAAa,OAAO,OAAO,mBAAmB,CAAC;;AAGnF,MAAa,wBAAwB,QAAyB,QAAQ,IAAI,qBAAqB,IAAI"}
|
package/dist/errors/index.d.ts
DELETED
package/dist/errors/index.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"errors-DHWylqRZ.js","names":[],"sources":["../src/errors/connector-error.ts"],"sourcesContent":["import { Data } from \"effect\";\n\nexport class ConnectorError extends Data.TaggedError(\"ConnectorError\")<{\n readonly message: string;\n readonly cause?: unknown;\n}> {}\n"],"mappings":";;;AAEA,IAAa,iBAAb,cAAoC,KAAK,YAAY,iBAAiB,CAGnE"}
|
package/dist/index-Byr0Lf0C.d.ts
DELETED
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
import { t as ConnectorError } from "./index-D54ySAKn.js";
|
|
2
|
-
import { c as ResourceBatch, n as ConnectorDefinition } from "./types-B35J5YPu.js";
|
|
3
|
-
import { a as PublisherService, i as Publisher, n as PublishOptions, r as PublishSource, t as PublishAck } from "./service-IE5qaf9x.js";
|
|
4
|
-
import { Layer } from "effect";
|
|
5
|
-
import * as Wings from "@useairfoil/wings";
|
|
6
|
-
|
|
7
|
-
//#region src/publisher/wings.d.ts
|
|
8
|
-
type WingsTableMapping = {
|
|
9
|
-
readonly name: string;
|
|
10
|
-
readonly partitionValue?: Wings.PartitionValue.PartitionValue;
|
|
11
|
-
};
|
|
12
|
-
type WingsPublisherConfig = {
|
|
13
|
-
readonly connector: ConnectorDefinition;
|
|
14
|
-
readonly tables: Record<string, string | WingsTableMapping>;
|
|
15
|
-
};
|
|
16
|
-
declare const layerWings: (config: WingsPublisherConfig) => Layer.Layer<Publisher, ConnectorError, Wings.WingsClient.WingsClient>;
|
|
17
|
-
//#endregion
|
|
18
|
-
//#region src/publisher/console.d.ts
|
|
19
|
-
declare const layerConsole: Layer.Layer<Publisher, never, never>;
|
|
20
|
-
declare namespace index_d_exports {
|
|
21
|
-
export { PublishAck, PublishOptions, PublishSource, Publisher, PublisherService, ResourceBatch, WingsPublisherConfig, layerConsole, layerWings };
|
|
22
|
-
}
|
|
23
|
-
//#endregion
|
|
24
|
-
export { layerWings as i, layerConsole as n, WingsPublisherConfig as r, index_d_exports as t };
|
|
25
|
-
//# sourceMappingURL=index-Byr0Lf0C.d.ts.map
|
package/dist/index-o1-Z3n7V.d.ts
DELETED
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
import { FileSystem } from "effect";
|
|
2
|
-
import * as effect_Types0 from "effect/Types";
|
|
3
|
-
import * as effect_Cause0 from "effect/Cause";
|
|
4
|
-
import * as effect_Layer0 from "effect/Layer";
|
|
5
|
-
|
|
6
|
-
//#region src/runtime-config/error.d.ts
|
|
7
|
-
type RuntimeConfigErrorCode = "CONFIG_PATH_MISSING" | "CONFIG_FILE_UNREADABLE" | "CONFIG_JSON_INVALID";
|
|
8
|
-
declare const RuntimeConfigError_base: new <A extends Record<string, any> = {}>(args: effect_Types0.VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P] }>) => effect_Cause0.YieldableError & {
|
|
9
|
-
readonly _tag: "RuntimeConfigError";
|
|
10
|
-
} & Readonly<A>;
|
|
11
|
-
/** Expected hosted-config failure with a stable code and diagnostic cause. */
|
|
12
|
-
declare class RuntimeConfigError extends RuntimeConfigError_base<{
|
|
13
|
-
readonly code: RuntimeConfigErrorCode;
|
|
14
|
-
readonly message: string;
|
|
15
|
-
readonly cause: Error;
|
|
16
|
-
}> {}
|
|
17
|
-
//#endregion
|
|
18
|
-
//#region src/runtime-config/constants.d.ts
|
|
19
|
-
/** Shared runtime keys owned by Airfoil rather than an individual connector. */
|
|
20
|
-
declare const PlatformRuntimeKey: {
|
|
21
|
-
readonly configPath: "AIRFOIL_CONFIG_PATH";
|
|
22
|
-
readonly connectorInstanceId: "AIRFOIL_CONNECTOR_INSTANCE_ID";
|
|
23
|
-
readonly stateTable: "AIRFOIL_STATE_TABLE";
|
|
24
|
-
readonly postgresConnectionString: "POSTGRES_CONNECTION_STRING";
|
|
25
|
-
readonly wingsHost: "WINGS_HOST";
|
|
26
|
-
readonly wingsNamespace: "WINGS_NAMESPACE";
|
|
27
|
-
readonly otelEnabled: "OTEL_ENABLED";
|
|
28
|
-
readonly otelExporterOtlpEndpoint: "OTEL_EXPORTER_OTLP_ENDPOINT";
|
|
29
|
-
readonly otelExporterOtlpHeaders: "OTEL_EXPORTER_OTLP_HEADERS";
|
|
30
|
-
readonly otelServiceName: "OTEL_SERVICE_NAME";
|
|
31
|
-
readonly otelServiceVersion: "OTEL_SERVICE_VERSION";
|
|
32
|
-
readonly otelResourceAttributes: "OTEL_RESOURCE_ATTRIBUTES";
|
|
33
|
-
};
|
|
34
|
-
/** Defaults for optional platform-owned runtime configuration. */
|
|
35
|
-
declare const PlatformRuntimeDefault: {
|
|
36
|
-
readonly stateTable: "_airfoil_connectors_state";
|
|
37
|
-
};
|
|
38
|
-
//#endregion
|
|
39
|
-
//#region src/runtime-config/layer.d.ts
|
|
40
|
-
/**
|
|
41
|
-
* Loads the required JSON file and lets environment values override it per key.
|
|
42
|
-
* Connector field validation remains in the connector's Effect Config.
|
|
43
|
-
*
|
|
44
|
-
* @example
|
|
45
|
-
* ```ts
|
|
46
|
-
* program.pipe(Effect.provide(layerHosted()));
|
|
47
|
-
* ```
|
|
48
|
-
*/
|
|
49
|
-
declare const layerHosted: () => effect_Layer0.Layer<never, RuntimeConfigError, FileSystem.FileSystem>;
|
|
50
|
-
declare namespace index_d_exports {
|
|
51
|
-
export { PlatformRuntimeDefault, PlatformRuntimeKey, RuntimeConfigError, RuntimeConfigErrorCode, layerHosted };
|
|
52
|
-
}
|
|
53
|
-
//#endregion
|
|
54
|
-
export { RuntimeConfigError as a, PlatformRuntimeKey as i, layerHosted as n, RuntimeConfigErrorCode as o, PlatformRuntimeDefault as r, index_d_exports as t };
|
|
55
|
-
//# sourceMappingURL=index-o1-Z3n7V.d.ts.map
|
package/dist/index.d.ts
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import { t as index_d_exports } from "./index-CTHVudvQ.js";
|
|
2
|
-
import { t as ConnectorError } from "./index-D54ySAKn.js";
|
|
3
|
-
import { S as WebhookRouteContext, _ as ResourceState, a as FetchChangesResult, b as WebhookHandler, c as ResourceBatch, d as ResourceMutation, g as ResourceSchema, h as ResourceRows, l as ResourceDefinition, m as ResourceRow, n as ConnectorDefinition, o as FetchPageResult, p as ResourcePayload, r as Cursor$1, s as PageFetch, t as ChangesFetch, u as ResourceField, x as WebhookRoute, y as WebhookAckMode } from "./types-B35J5YPu.js";
|
|
4
|
-
import { a as telemetry_d_exports, c as Fetch, l as Resource, o as Connector, s as Cursor, t as index_d_exports$1 } from "./index-DtJX_tic.js";
|
|
5
|
-
import "./service-IE5qaf9x.js";
|
|
6
|
-
import { t as index_d_exports$6 } from "./index-Coh_SkBs.js";
|
|
7
|
-
import { t as index_d_exports$2 } from "./index-J42AZaXU.js";
|
|
8
|
-
import { t as index_d_exports$3 } from "./index-CBT-JX-T.js";
|
|
9
|
-
import { g as metrics_d_exports } from "./metrics-CVAk1ALR.js";
|
|
10
|
-
import { t as index_d_exports$4 } from "./index-Byr0Lf0C.js";
|
|
11
|
-
import { t as index_d_exports$5 } from "./index-o1-Z3n7V.js";
|
|
12
|
-
import { t as index_d_exports$7 } from "./index-Cq2IzY7T.js";
|
|
13
|
-
import { t as index_d_exports$8 } from "./index-DKWIh6M1.js";
|
|
14
|
-
export { index_d_exports as Auth, ChangesFetch, Connector, index_d_exports$1 as ConnectorApp, ConnectorDefinition, ConnectorError, Cursor, Cursor$1 as CursorTypes, Fetch, FetchChangesResult, FetchPageResult, index_d_exports$2 as Ingestion, index_d_exports$3 as Manifest, metrics_d_exports as Metrics, PageFetch, index_d_exports$4 as Publisher, Resource, ResourceBatch, ResourceDefinition, ResourceField, ResourceMutation, ResourcePayload, ResourceRow, ResourceRows, ResourceSchema, ResourceState, index_d_exports$5 as RuntimeConfig, index_d_exports$6 as StateStore, index_d_exports$7 as Status, telemetry_d_exports as Telemetry, index_d_exports$8 as Webhook, WebhookAckMode, WebhookHandler, WebhookRoute, WebhookRouteContext };
|