@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.
Files changed (178) hide show
  1. package/METRICS.md +20 -19
  2. package/README.md +127 -430
  3. package/dist/annotations-BE74YmAO.d.mts +39 -0
  4. package/dist/auth/index.d.mts +2 -0
  5. package/dist/{auth-DvU_CZ7C.js → auth/index.mjs} +6 -8
  6. package/dist/auth/index.mjs.map +1 -0
  7. package/dist/connector-app/index.d.mts +2 -0
  8. package/dist/connector-app/index.mjs +2 -0
  9. package/dist/connector-app-C-L4QqG6.mjs +123 -0
  10. package/dist/connector-app-C-L4QqG6.mjs.map +1 -0
  11. package/dist/{constants-BRhIX_rz.js → constants-D-GQzpHZ.mjs} +10 -6
  12. package/dist/constants-D-GQzpHZ.mjs.map +1 -0
  13. package/dist/demo/index.d.mts +2 -0
  14. package/dist/demo/index.mjs +2 -0
  15. package/dist/demo-B30Vlkk2.mjs +191 -0
  16. package/dist/demo-B30Vlkk2.mjs.map +1 -0
  17. package/dist/errors/index.d.mts +2 -0
  18. package/dist/errors/index.mjs +2 -0
  19. package/dist/{errors-DHWylqRZ.js → errors-pT0YVJU5.mjs} +2 -3
  20. package/dist/errors-pT0YVJU5.mjs.map +1 -0
  21. package/dist/iceberg/index.d.mts +3 -0
  22. package/dist/iceberg/index.mjs +3 -0
  23. package/dist/iceberg-D6L8I6vA.mjs +39 -0
  24. package/dist/iceberg-D6L8I6vA.mjs.map +1 -0
  25. package/dist/{index-Cq2IzY7T.d.ts → index-BUHSGm9Q.d.mts} +11 -13
  26. package/dist/{index-CTHVudvQ.d.ts → index-BX8G7d41.d.mts} +1 -2
  27. package/dist/{index-J42AZaXU.d.ts → index-BfXpgxk9.d.mts} +9 -10
  28. package/dist/{index-DKWIh6M1.d.ts → index-CRVAwJ5-.d.mts} +10 -8
  29. package/dist/index-CUPP2A_m.d.mts +27 -0
  30. package/dist/{index-Coh_SkBs.d.ts → index-CgvFomO6.d.mts} +6 -7
  31. package/dist/index-DJhDp4Xc.d.mts +58 -0
  32. package/dist/index-Dk7urvpF.d.mts +76 -0
  33. package/dist/{index-D54ySAKn.d.ts → index-DkVNO6ks.d.mts} +2 -5
  34. package/dist/{index-DtJX_tic.d.ts → index-NnCutIqM.d.mts} +77 -38
  35. package/dist/{index-CBT-JX-T.d.ts → index-eFuoMZZ3.d.mts} +18 -20
  36. package/dist/index-ygpml2kC.d.mts +73 -0
  37. package/dist/index.d.mts +16 -0
  38. package/dist/index.mjs +45 -0
  39. package/dist/index.mjs.map +1 -0
  40. package/dist/ingestion/index.d.mts +2 -0
  41. package/dist/ingestion/index.mjs +2 -0
  42. package/dist/ingestion-q0WwqUSt.mjs +275 -0
  43. package/dist/ingestion-q0WwqUSt.mjs.map +1 -0
  44. package/dist/ingestor/index.d.mts +3 -0
  45. package/dist/ingestor/index.mjs +4 -0
  46. package/dist/ingestor-D4L-HPkg.mjs +26 -0
  47. package/dist/ingestor-D4L-HPkg.mjs.map +1 -0
  48. package/dist/instrumented-Bhp7fyvh.mjs +29 -0
  49. package/dist/instrumented-Bhp7fyvh.mjs.map +1 -0
  50. package/dist/manifest/index.d.mts +2 -0
  51. package/dist/manifest/{index.js → index.mjs} +2 -4
  52. package/dist/{manifest-ByE6YPG0.js → manifest-BGKxmKLy.mjs} +14 -19
  53. package/dist/manifest-BGKxmKLy.mjs.map +1 -0
  54. package/dist/metrics-BaEX__MN.mjs +352 -0
  55. package/dist/metrics-BaEX__MN.mjs.map +1 -0
  56. package/dist/metrics-CVXFL7YT.d.mts +64 -0
  57. package/dist/metrics.d.mts +2 -0
  58. package/dist/metrics.mjs +2 -0
  59. package/dist/{chunk-Bp6m_JJh.js → rolldown-runtime-D7D4PA-g.mjs} +4 -4
  60. package/dist/runtime-config/index.d.mts +2 -0
  61. package/dist/runtime-config/index.mjs +3 -0
  62. package/dist/runtime-config-Oa55gAew.mjs +97 -0
  63. package/dist/runtime-config-Oa55gAew.mjs.map +1 -0
  64. package/dist/{server-CXTQ7odl.js → server-CMnxz3h0.mjs} +21 -60
  65. package/dist/server-CMnxz3h0.mjs.map +1 -0
  66. package/dist/service-DLkhuxYl.d.mts +27 -0
  67. package/dist/service-jWxxfEht.mjs +7 -0
  68. package/dist/service-jWxxfEht.mjs.map +1 -0
  69. package/dist/state-store/index.d.mts +2 -0
  70. package/dist/state-store/index.mjs +2 -0
  71. package/dist/{state-store-yl6LiTQ0.js → state-store-uFvHY7Ax.mjs} +15 -22
  72. package/dist/state-store-uFvHY7Ax.mjs.map +1 -0
  73. package/dist/status/{index.d.ts → index.d.mts} +1 -4
  74. package/dist/status/{index.js → index.mjs} +2 -6
  75. package/dist/{status-B-oZBc33.js → status-CKb9IhQ9.mjs} +14 -16
  76. package/dist/status-CKb9IhQ9.mjs.map +1 -0
  77. package/dist/table-V0tgUC5i.mjs +370 -0
  78. package/dist/table-V0tgUC5i.mjs.map +1 -0
  79. package/dist/types-xZtSmrGA.d.mts +220 -0
  80. package/dist/webhook/index.d.mts +3 -0
  81. package/dist/webhook/index.mjs +12 -0
  82. package/dist/webhook/index.mjs.map +1 -0
  83. package/dist/wings-I56hGtNv.mjs +325 -0
  84. package/dist/wings-I56hGtNv.mjs.map +1 -0
  85. package/package.json +64 -51
  86. package/src/catalog/table.ts +201 -0
  87. package/src/connector-app/create-table.ts +47 -0
  88. package/src/connector-app/demo.ts +42 -0
  89. package/src/connector-app/index.ts +2 -0
  90. package/src/connector-app/start.ts +1 -1
  91. package/src/core/builder.ts +15 -23
  92. package/src/core/index.ts +11 -1
  93. package/src/core/types.ts +114 -39
  94. package/src/demo/definition.ts +68 -0
  95. package/src/demo/generate.ts +167 -0
  96. package/src/demo/index.ts +3 -0
  97. package/src/demo/run.ts +142 -0
  98. package/src/iceberg/annotations.ts +62 -0
  99. package/src/iceberg/error.ts +9 -0
  100. package/src/iceberg/index.ts +3 -0
  101. package/src/iceberg/table.ts +511 -0
  102. package/src/index.ts +3 -1
  103. package/src/ingestion/engine.ts +240 -60
  104. package/src/ingestor/arrow.ts +248 -0
  105. package/src/ingestor/console.ts +13 -0
  106. package/src/ingestor/index.ts +9 -0
  107. package/src/ingestor/instrumented.ts +61 -0
  108. package/src/ingestor/service.ts +30 -0
  109. package/src/ingestor/wings.ts +143 -0
  110. package/src/manifest/config.ts +3 -3
  111. package/src/metrics.ts +125 -33
  112. package/src/runtime-config/config.ts +14 -0
  113. package/src/runtime-config/constants.ts +5 -2
  114. package/src/runtime-config/error.ts +4 -1
  115. package/src/runtime-config/index.ts +2 -0
  116. package/src/runtime-config/layer.ts +1 -1
  117. package/src/runtime-config/table-bindings.ts +92 -0
  118. package/src/state-store/layer-key-value-store.ts +8 -3
  119. package/src/state-store/layer-memory.ts +1 -1
  120. package/src/state-store/layer-sql.ts +4 -4
  121. package/src/state-store/schema.ts +2 -2
  122. package/src/state-store/state.ts +14 -2
  123. package/src/status/route.ts +2 -2
  124. package/src/telemetry.ts +25 -10
  125. package/src/webhook/server.ts +39 -40
  126. package/dist/auth/index.d.ts +0 -2
  127. package/dist/auth/index.js +0 -3
  128. package/dist/auth-DvU_CZ7C.js.map +0 -1
  129. package/dist/connector-app/index.d.ts +0 -14
  130. package/dist/connector-app/index.js +0 -11
  131. package/dist/connector-app-d7Z-SZLQ.js +0 -64
  132. package/dist/connector-app-d7Z-SZLQ.js.map +0 -1
  133. package/dist/constants-BRhIX_rz.js.map +0 -1
  134. package/dist/errors/index.d.ts +0 -2
  135. package/dist/errors/index.js +0 -3
  136. package/dist/errors-DHWylqRZ.js.map +0 -1
  137. package/dist/index-Byr0Lf0C.d.ts +0 -25
  138. package/dist/index-o1-Z3n7V.d.ts +0 -55
  139. package/dist/index.d.ts +0 -14
  140. package/dist/index.js +0 -58
  141. package/dist/index.js.map +0 -1
  142. package/dist/ingestion/index.d.ts +0 -6
  143. package/dist/ingestion/index.js +0 -10
  144. package/dist/ingestion-BQo4cbGw.js +0 -200
  145. package/dist/ingestion-BQo4cbGw.js.map +0 -1
  146. package/dist/manifest/index.d.ts +0 -2
  147. package/dist/manifest-ByE6YPG0.js.map +0 -1
  148. package/dist/metrics-CVAk1ALR.d.ts +0 -53
  149. package/dist/metrics-CWPy2Aqc.js +0 -96
  150. package/dist/metrics-CWPy2Aqc.js.map +0 -1
  151. package/dist/metrics.d.ts +0 -4
  152. package/dist/metrics.js +0 -3
  153. package/dist/publisher/index.d.ts +0 -5
  154. package/dist/publisher/index.js +0 -6
  155. package/dist/publisher-BYT3RLVO.js +0 -131
  156. package/dist/publisher-BYT3RLVO.js.map +0 -1
  157. package/dist/runtime-config/index.d.ts +0 -2
  158. package/dist/runtime-config/index.js +0 -4
  159. package/dist/runtime-config-BpB-d_bF.js +0 -51
  160. package/dist/runtime-config-BpB-d_bF.js.map +0 -1
  161. package/dist/server-CXTQ7odl.js.map +0 -1
  162. package/dist/service-DuFiQwid.js +0 -191
  163. package/dist/service-DuFiQwid.js.map +0 -1
  164. package/dist/service-IE5qaf9x.d.ts +0 -32
  165. package/dist/state-store/index.d.ts +0 -3
  166. package/dist/state-store/index.js +0 -5
  167. package/dist/state-store-yl6LiTQ0.js.map +0 -1
  168. package/dist/status-B-oZBc33.js.map +0 -1
  169. package/dist/types-B35J5YPu.d.ts +0 -174
  170. package/dist/webhook/index.d.ts +0 -6
  171. package/dist/webhook/index.js +0 -8
  172. package/dist/webhook-DI-Afxkg.js +0 -13
  173. package/dist/webhook-DI-Afxkg.js.map +0 -1
  174. package/src/publisher/console.ts +0 -18
  175. package/src/publisher/index.ts +0 -7
  176. package/src/publisher/instrumented.ts +0 -68
  177. package/src/publisher/service.ts +0 -37
  178. package/src/publisher/wings.ts +0 -204
@@ -1,5 +1,5 @@
1
1
  import { Layer } from "effect";
2
- import { KeyValueStore } from "effect/unstable/persistence";
2
+ import { KeyValueStore } from "effect/persistence";
3
3
 
4
4
  import type { StateStore } from "./service";
5
5
 
@@ -1,6 +1,6 @@
1
1
  import { Config, Effect, Layer } from "effect";
2
- import { KeyValueStore } from "effect/unstable/persistence";
3
- import { SqlClient } from "effect/unstable/sql";
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.nonEmptyString(PlatformRuntimeKey.connectorInstanceId),
36
- table: Config.nonEmptyString(PlatformRuntimeKey.stateTable).pipe(
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", "publish", "checkpoint"]);
21
+ export const StateOperationSchema = Schema.Literals(["fetch", "ingest", "checkpoint"]);
22
22
 
23
23
  export const StateErrorCodeSchema = Schema.Literals([
24
24
  "fetch_failed",
25
- "publish_failed",
25
+ "ingest_failed",
26
26
  "checkpoint_failed",
27
27
  ]);
28
28
 
@@ -1,16 +1,28 @@
1
- import type { Cursor, ResourceDefinition, ResourceState, SyncState } from "../core/types";
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.changes) return "live";
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";
@@ -1,5 +1,5 @@
1
1
  import { Cause, Effect } from "effect";
2
- import { HttpRouter, HttpServerResponse } from "effect/unstable/http";
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/unstable/http";
3
- import * as Observability from "effect/unstable/observability";
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
- publish: "connector.publish",
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
- batchMutations: "airfoil.batch.mutations",
23
+ batchRows: "airfoil.batch.rows",
24
+ batchOutcome: "airfoil.batch.outcome",
24
25
  webhookPath: "airfoil.webhook.path",
25
- publisherSuccess: "airfoil.publisher.success",
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.boolean(PlatformRuntimeKey.otelEnabled).pipe(Config.withDefault(false)),
51
- baseUrl: Config.option(Config.string(PlatformRuntimeKey.otelExporterOtlpEndpoint)),
52
- rawHeaders: Config.option(Config.string(PlatformRuntimeKey.otelExporterOtlpHeaders)),
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.boolean("MY_OTEL_ENABLED"),
215
- * endpoint: Config.string("MY_COLLECTOR_URL"),
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* () {
@@ -1,18 +1,16 @@
1
1
  import { Cause, Context, Effect, Queue, Schema } from "effect";
2
- import { HttpRouter, HttpServerRequest, HttpServerResponse } from "effect/unstable/http";
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
- mutations: ReadonlyArray<ResourceMutation<Row>>,
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
- const mutations = yield* decodeAndHandleWebhook(resource.name, resource.webhook, payload);
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(mutations),
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, ResourceMutation[]>();
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.mutations]);
66
+ grouped.set(item.resource, [...current, ...item.batch.rows]);
84
67
  }
85
- return Array.from(grouped.entries()).map(([resource, mutations]) => ({
68
+ return Array.from(grouped.entries()).map(([resource, rows]) => ({
86
69
  resource,
87
- batch: resourceBatch(mutations),
70
+ batch: resourceBatch(rows),
88
71
  }));
89
72
  };
90
73
 
91
- const publishBatches = (
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
- publishBatch({
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
- const makeHandler = (route: WebhookRoute, options: { readonly connectorName: string }) =>
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(makeRouteContext(request, rawBodyResult.value, payloadResult.value, collected))
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
- publishBatches(batches, { connectorName: options.connectorName }).pipe(
196
- Effect.tapError((error) => annotateError("webhook_publish", error)),
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
  );
@@ -1,2 +0,0 @@
1
- import { i as makeTokenCache, n as ExpiringToken, r as TokenCache } from "../index-CTHVudvQ.js";
2
- export { ExpiringToken, TokenCache, makeTokenCache };
@@ -1,3 +0,0 @@
1
- import { n as makeTokenCache } from "../auth-DvU_CZ7C.js";
2
-
3
- export { makeTokenCache };
@@ -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"}
@@ -1,2 +0,0 @@
1
- import { t as ConnectorError } from "../index-D54ySAKn.js";
2
- export { ConnectorError };
@@ -1,3 +0,0 @@
1
- import { t as ConnectorError } from "../errors-DHWylqRZ.js";
2
-
3
- export { ConnectorError };
@@ -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"}
@@ -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
@@ -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 };