@useairfoil/producer-polar 0.2.2 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -50,11 +50,11 @@ POLAR_ORGANIZATION_ID=org_xxx
50
50
  # POLAR_TRANSIENT_MAX_RETRIES=5
51
51
  # POLAR_RETRY_BASE_DELAY_MS=200
52
52
  # POLAR_REQUEST_TIMEOUT_SECONDS=120
53
- POLAR_WEBHOOK_PORT=8080
53
+ AIRFOIL_HTTP_PORT=8080
54
54
  OTEL_ENABLED=false
55
55
  OTEL_SERVICE_NAME=producer-polar
56
56
  # OTEL_SERVICE_VERSION=0.1.0
57
- # OTEL_RESOURCE_ATTRIBUTES=deployment.environment=production,team=data
57
+ # OTEL_RESOURCE_ATTRIBUTES=service.instance.id=team-acme-polar-primary,airfoil.connector.revision=1,airfoil.team.id=team-acme
58
58
  OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4318
59
59
  OTEL_EXPORTER_OTLP_HEADERS=Authorization=Bearer token,X-Axiom-Dataset=airfoil-traces
60
60
  ```
@@ -66,10 +66,7 @@ Production `start` also requires platform-owned Wings, table, and PostgreSQL sta
66
66
  ```env
67
67
  WINGS_HOST=localhost:7777
68
68
  WINGS_NAMESPACE=namespaces/default
69
- POLAR_CUSTOMERS_TABLE=namespaces/default/tables/polar-customers
70
- POLAR_CHECKOUTS_TABLE=namespaces/default/tables/polar-checkouts
71
- POLAR_ORDERS_TABLE=namespaces/default/tables/polar-orders
72
- POLAR_SUBSCRIPTIONS_TABLE=namespaces/default/tables/polar-subscriptions
69
+ AIRFOIL_TABLE_BINDINGS={"customers":"namespaces/default/tables/polar-customers","checkouts":"namespaces/default/tables/polar-checkouts","orders":"namespaces/default/tables/polar-orders","subscriptions":"namespaces/default/tables/polar-subscriptions"}
73
70
  AIRFOIL_CONFIG_PATH=/var/run/airfoil/config/config.json
74
71
  AIRFOIL_CONNECTOR_INSTANCE_ID=team-acme-polar-primary
75
72
  # AIRFOIL_STATE_TABLE=_airfoil_connectors_state
@@ -87,9 +84,9 @@ pnpm --filter @useairfoil/producer-polar run sandbox
87
84
  pnpm --filter @useairfoil/producer-polar run start
88
85
  ```
89
86
 
90
- `sandbox` runs the real connector against Polar sandbox with `Publisher.layerConsole`. `start` runs against the configured `POLAR_API_BASE_URL` and passes the configured Wings table names to `Publisher.layerWings`.
87
+ `sandbox` runs the real connector against Polar sandbox with `Publisher.layerConsole`. `start` runs against the configured `POLAR_API_BASE_URL` and loads the complete platform-owned Wings map through `Publisher.layerWingsConfig`.
91
88
 
92
- The CLI assembly lives in `src/main.ts`; connector-specific platform keys live in `src/constants.ts`; production runtime wiring lives in `src/start.ts`; sandbox runtime wiring lives in `src/sandbox.ts`.
89
+ The CLI assembly lives in `src/main.ts`; production runtime wiring lives in `src/start.ts`; sandbox runtime wiring lives in `src/sandbox.ts`. Port and table bindings use Connector Kit's shared platform keys.
93
90
 
94
91
  Before provisioning, the dashboard backend passes `PolarConnector.PolarConnector` and `PolarConnector.layerConfig(PolarConnector.PolarConfigDef.config)` to `ConnectorApp.check(...)`. Each selected entity performs a read-only one-item request against its corresponding Polar list endpoint; unselected entities are not contacted.
95
92
 
package/dist/main.js CHANGED
@@ -10,22 +10,10 @@ import { PgClient } from "@effect/sql-pg";
10
10
  import { WingsClient } from "@useairfoil/wings";
11
11
 
12
12
  //#region package.json
13
- var version = "0.2.1";
14
-
15
- //#endregion
16
- //#region src/constants.ts
17
- /** Connector-specific runtime keys injected by the Airfoil platform. */
18
- const PolarRuntimeKey = {
19
- webhookPort: "POLAR_WEBHOOK_PORT",
20
- customersTable: "POLAR_CUSTOMERS_TABLE",
21
- checkoutsTable: "POLAR_CHECKOUTS_TABLE",
22
- ordersTable: "POLAR_ORDERS_TABLE",
23
- subscriptionsTable: "POLAR_SUBSCRIPTIONS_TABLE"
24
- };
13
+ var version = "0.2.2";
25
14
 
26
15
  //#endregion
27
16
  //#region src/sandbox.ts
28
- const HttpServerConfig$1 = Config.all({ port: Config.port(PolarRuntimeKey.webhookPort).pipe(Config.withDefault(8080)) });
29
17
  const SandboxConfig = Config.unwrap({
30
18
  ...PolarConfigDef.fields,
31
19
  apiBaseUrl: Config.succeed("https://sandbox-api.polar.sh/v1/")
@@ -33,24 +21,13 @@ const SandboxConfig = Config.unwrap({
33
21
  const SandboxConnectorLayer = layerConfig(SandboxConfig);
34
22
  const TelemetryLayer$1 = Layer.mergeAll(Telemetry.layerOtlp(), Telemetry.layerMetricsConsoleDump());
35
23
  const sandboxCommand = Command.make("sandbox", {}, () => Effect.gen(function* () {
36
- const config = yield* HttpServerConfig$1;
24
+ const port = yield* RuntimeConfig.httpPort;
37
25
  const entrypoint = yield* PolarConnector;
38
- return yield* ConnectorApp.start(entrypoint, { port: config.port });
26
+ return yield* ConnectorApp.start(entrypoint, { port });
39
27
  }).pipe(Effect.annotateLogs({ component: "polar" }), Effect.provide(Layer.mergeAll(StateStore.layerMemory, Publisher.layerConsole, SandboxConnectorLayer, Logger.layer([Logger.consolePretty()]), TelemetryLayer$1)))).pipe(Command.withDescription("Run the connector locally and log ingested data"));
40
28
 
41
29
  //#endregion
42
30
  //#region src/start.ts
43
- const HttpServerConfig = Config.all({ port: Config.port(PolarRuntimeKey.webhookPort).pipe(Config.withDefault(8080)) });
44
- const PolarTablesConfig = Config.all({
45
- customers: Config.nonEmptyString(PolarRuntimeKey.customersTable),
46
- checkouts: Config.nonEmptyString(PolarRuntimeKey.checkoutsTable),
47
- orders: Config.nonEmptyString(PolarRuntimeKey.ordersTable),
48
- subscriptions: Config.nonEmptyString(PolarRuntimeKey.subscriptionsTable)
49
- });
50
- const WingsConfig = Config.all({
51
- host: Config.nonEmptyString(RuntimeConfig.PlatformRuntimeKey.wingsHost),
52
- namespace: Config.nonEmptyString(RuntimeConfig.PlatformRuntimeKey.wingsNamespace)
53
- });
54
31
  const ConnectorLayer = layerConfig(PolarConfigDef.config);
55
32
  const TelemetryLayer = Telemetry.layerOtlp();
56
33
  const PostgresLayer = PgClient.layerConfig({
@@ -61,19 +38,10 @@ const PostgresLayer = PgClient.layerConfig({
61
38
  });
62
39
  const StateStoreLayer = StateStore.layerSql().pipe(Layer.provide(PostgresLayer));
63
40
  const startCommand = Command.make("start", {}, () => Effect.gen(function* () {
64
- const runtimeConfig = yield* HttpServerConfig;
65
- const tableConfig = yield* PolarTablesConfig;
41
+ const port = yield* RuntimeConfig.httpPort;
66
42
  const entrypoint = yield* PolarConnector;
67
- return yield* ConnectorApp.start(entrypoint, { port: runtimeConfig.port }).pipe(Effect.provide(Publisher.layerWings({
68
- connector: entrypoint,
69
- tables: {
70
- customers: tableConfig.customers,
71
- checkouts: tableConfig.checkouts,
72
- orders: tableConfig.orders,
73
- subscriptions: tableConfig.subscriptions
74
- }
75
- })));
76
- }).pipe(Effect.annotateLogs({ component: "polar" }), Effect.provide(Layer.mergeAll(StateStoreLayer, ConnectorLayer, WingsClient.layerConfig(WingsConfig), Logger.layer([Logger.consolePretty()]), TelemetryLayer)), Effect.provide(RuntimeConfig.layerHosted()))).pipe(Command.withDescription("Run the production connector against Wings"));
43
+ return yield* ConnectorApp.start(entrypoint, { port }).pipe(Effect.provide(Publisher.layerWingsConfig(entrypoint)));
44
+ }).pipe(Effect.annotateLogs({ component: "polar" }), Effect.provide(Layer.mergeAll(StateStoreLayer, ConnectorLayer, WingsClient.layerConfig(RuntimeConfig.wingsClient), Logger.layer([Logger.consolePretty()]), TelemetryLayer)), Effect.provide(RuntimeConfig.layerHosted()))).pipe(Command.withDescription("Run the production connector against Wings"));
77
45
 
78
46
  //#endregion
79
47
  //#region src/main.ts
package/dist/main.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"main.js","names":["HttpServerConfig","PolarConnector.layerConfig","TelemetryLayer","PolarConnector.PolarConnector","PolarConnector.layerConfig","PolarConnector.PolarConnector","packageJson.version"],"sources":["../package.json","../src/constants.ts","../src/sandbox.ts","../src/start.ts","../src/main.ts"],"sourcesContent":["{\n \"name\": \"@useairfoil/producer-polar\",\n \"version\": \"0.2.1\",\n \"repository\": \"useairfoil/typescript-sdk\",\n \"files\": [\n \"dist\",\n \"src\",\n \"README.md\"\n ],\n \"type\": \"module\",\n \"main\": \"./dist/index.js\",\n \"types\": \"./dist/index.d.ts\",\n \"exports\": {\n \".\": {\n \"types\": \"./dist/index.d.ts\",\n \"import\": \"./dist/index.js\",\n \"default\": \"./dist/index.js\"\n },\n \"./manifest\": {\n \"types\": \"./dist/manifest.d.ts\",\n \"import\": \"./dist/manifest.js\",\n \"default\": \"./dist/manifest.js\"\n }\n },\n \"scripts\": {\n \"build\": \"tsdown\",\n \"docker:build\": \"docker build --load --file Dockerfile --tag airfoil/producer-polar:local ../..\",\n \"start\": \"tsx --env-file=.env src/main.ts start\",\n \"sandbox\": \"tsx --env-file=.env src/main.ts sandbox\",\n \"test\": \"dotenvx run --ignore=MISSING_ENV_FILE --quiet -- vitest\",\n \"test:ci\": \"dotenvx run --ignore=MISSING_ENV_FILE --quiet -- vitest run\",\n \"typecheck\": \"tsc --noEmit\"\n },\n \"dependencies\": {\n \"@effect/platform-node\": \"catalog:\",\n \"@effect/sql-pg\": \"catalog:\",\n \"@useairfoil/connector-kit\": \"workspace:*\",\n \"@useairfoil/wings\": \"workspace:*\",\n \"effect\": \"catalog:\",\n \"standardwebhooks\": \"^1.0.0\"\n },\n \"devDependencies\": {\n \"@dotenvx/dotenvx\": \"^1.62.0\",\n \"@effect/vitest\": \"catalog:\",\n \"@types/node\": \"catalog:\",\n \"@useairfoil/effect-vcr\": \"workspace:*\",\n \"tsdown\": \"catalog:\",\n \"tsx\": \"^4.21.0\",\n \"vitest\": \"catalog:\"\n }\n}\n","/** Connector-specific runtime keys injected by the Airfoil platform. */\nexport const PolarRuntimeKey = {\n webhookPort: \"POLAR_WEBHOOK_PORT\",\n customersTable: \"POLAR_CUSTOMERS_TABLE\",\n checkoutsTable: \"POLAR_CHECKOUTS_TABLE\",\n ordersTable: \"POLAR_ORDERS_TABLE\",\n subscriptionsTable: \"POLAR_SUBSCRIPTIONS_TABLE\",\n} as const;\n","import { ConnectorApp, Publisher, StateStore, Telemetry } from \"@useairfoil/connector-kit\";\nimport { Config, Effect, Layer, Logger } from \"effect\";\nimport { Command } from \"effect/unstable/cli\";\n\nimport { PolarRuntimeKey } from \"./constants\";\nimport { PolarConnector } from \"./index\";\n\nconst HttpServerConfig = Config.all({\n port: Config.port(PolarRuntimeKey.webhookPort).pipe(Config.withDefault(8080)),\n});\n\nconst SandboxConfig = Config.unwrap<PolarConnector.PolarConfig>({\n ...PolarConnector.PolarConfigDef.fields,\n apiBaseUrl: Config.succeed(\"https://sandbox-api.polar.sh/v1/\"),\n});\n\nconst SandboxConnectorLayer = PolarConnector.layerConfig(SandboxConfig);\nconst TelemetryLayer = Layer.mergeAll(Telemetry.layerOtlp(), Telemetry.layerMetricsConsoleDump());\n\nexport const sandboxCommand = Command.make(\"sandbox\", {}, () =>\n Effect.gen(function* () {\n const config = yield* HttpServerConfig;\n const entrypoint = yield* PolarConnector.PolarConnector;\n\n return yield* ConnectorApp.start(entrypoint, { port: config.port });\n }).pipe(\n Effect.annotateLogs({ component: \"polar\" }),\n Effect.provide(\n Layer.mergeAll(\n StateStore.layerMemory,\n Publisher.layerConsole,\n SandboxConnectorLayer,\n Logger.layer([Logger.consolePretty()]),\n TelemetryLayer,\n ),\n ),\n ),\n).pipe(Command.withDescription(\"Run the connector locally and log ingested data\"));\n","import { PgClient } from \"@effect/sql-pg\";\nimport {\n ConnectorApp,\n Publisher,\n RuntimeConfig,\n StateStore,\n Telemetry,\n} from \"@useairfoil/connector-kit\";\nimport { WingsClient } from \"@useairfoil/wings\";\nimport { Config, Effect, Layer, Logger, Schema } from \"effect\";\nimport { Command } from \"effect/unstable/cli\";\n\nimport { PolarRuntimeKey } from \"./constants\";\nimport { PolarConnector } from \"./index\";\n\n// The operator injects runtime wiring; these values are intentionally absent\n// from the user-facing connector manifest.\nconst HttpServerConfig = Config.all({\n port: Config.port(PolarRuntimeKey.webhookPort).pipe(Config.withDefault(8080)),\n});\n\nconst PolarTablesConfig = Config.all({\n customers: Config.nonEmptyString(PolarRuntimeKey.customersTable),\n checkouts: Config.nonEmptyString(PolarRuntimeKey.checkoutsTable),\n orders: Config.nonEmptyString(PolarRuntimeKey.ordersTable),\n subscriptions: Config.nonEmptyString(PolarRuntimeKey.subscriptionsTable),\n});\n\nconst WingsConfig = Config.all({\n host: Config.nonEmptyString(RuntimeConfig.PlatformRuntimeKey.wingsHost),\n namespace: Config.nonEmptyString(RuntimeConfig.PlatformRuntimeKey.wingsNamespace),\n});\n\nconst ConnectorLayer = PolarConnector.layerConfig(PolarConnector.PolarConfigDef.config);\nconst TelemetryLayer = Telemetry.layerOtlp();\nconst PostgresLayer = PgClient.layerConfig({\n url: Config.schema(\n Schema.Redacted(Schema.NonEmptyString),\n RuntimeConfig.PlatformRuntimeKey.postgresConnectionString,\n ),\n maxConnections: Config.succeed(2),\n connectTimeout: Config.succeed(\"5 seconds\"),\n applicationName: Config.succeed(\"airfoil-producer-polar\"),\n});\nconst StateStoreLayer = StateStore.layerSql().pipe(Layer.provide(PostgresLayer));\n\nexport const startCommand = Command.make(\"start\", {}, () =>\n Effect.gen(function* () {\n const runtimeConfig = yield* HttpServerConfig;\n const tableConfig = yield* PolarTablesConfig;\n const entrypoint = yield* PolarConnector.PolarConnector;\n\n return yield* ConnectorApp.start(entrypoint, { port: runtimeConfig.port }).pipe(\n Effect.provide(\n Publisher.layerWings({\n connector: entrypoint,\n tables: {\n customers: tableConfig.customers,\n checkouts: tableConfig.checkouts,\n orders: tableConfig.orders,\n subscriptions: tableConfig.subscriptions,\n },\n }),\n ),\n );\n }).pipe(\n Effect.annotateLogs({ component: \"polar\" }),\n Effect.provide(\n Layer.mergeAll(\n StateStoreLayer,\n ConnectorLayer,\n WingsClient.layerConfig(WingsConfig),\n Logger.layer([Logger.consolePretty()]),\n TelemetryLayer,\n ),\n ),\n Effect.provide(RuntimeConfig.layerHosted()),\n ),\n).pipe(Command.withDescription(\"Run the production connector against Wings\"));\n","#!/usr/bin/env node\n\nimport { NodeRuntime, NodeServices } from \"@effect/platform-node\";\nimport { Effect, Layer } from \"effect\";\nimport { Command } from \"effect/unstable/cli\";\nimport { FetchHttpClient } from \"effect/unstable/http\";\n\nimport packageJson from \"../package.json\";\nimport { sandboxCommand } from \"./sandbox\";\nimport { startCommand } from \"./start\";\n\nconst BootstrapLayer = Layer.mergeAll(FetchHttpClient.layer, NodeServices.layer);\n\nconst program = Command.make(\"producer-polar\", {}, () => Effect.void).pipe(\n Command.withSubcommands([startCommand, sandboxCommand]),\n);\n\nCommand.run(program, { version: packageJson.version }).pipe(\n Effect.provide(BootstrapLayer),\n Effect.scoped,\n NodeRuntime.runMain,\n);\n"],"mappings":"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"}
1
+ {"version":3,"file":"main.js","names":["PolarConnector.layerConfig","TelemetryLayer","PolarConnector.PolarConnector","PolarConnector.layerConfig","PolarConnector.PolarConnector","packageJson.version"],"sources":["../package.json","../src/sandbox.ts","../src/start.ts","../src/main.ts"],"sourcesContent":["{\n \"name\": \"@useairfoil/producer-polar\",\n \"version\": \"0.2.2\",\n \"repository\": \"useairfoil/typescript-sdk\",\n \"files\": [\n \"dist\",\n \"src\",\n \"README.md\"\n ],\n \"type\": \"module\",\n \"main\": \"./dist/index.js\",\n \"types\": \"./dist/index.d.ts\",\n \"exports\": {\n \".\": {\n \"types\": \"./dist/index.d.ts\",\n \"import\": \"./dist/index.js\",\n \"default\": \"./dist/index.js\"\n },\n \"./manifest\": {\n \"types\": \"./dist/manifest.d.ts\",\n \"import\": \"./dist/manifest.js\",\n \"default\": \"./dist/manifest.js\"\n }\n },\n \"scripts\": {\n \"build\": \"tsdown\",\n \"docker:build\": \"docker build --load --file Dockerfile --tag airfoil/producer-polar:local ../..\",\n \"start\": \"tsx --env-file=.env src/main.ts start\",\n \"sandbox\": \"tsx --env-file=.env src/main.ts sandbox\",\n \"test\": \"dotenvx run --ignore=MISSING_ENV_FILE --quiet -- vitest\",\n \"test:ci\": \"dotenvx run --ignore=MISSING_ENV_FILE --quiet -- vitest run\",\n \"typecheck\": \"tsc --noEmit\"\n },\n \"dependencies\": {\n \"@effect/platform-node\": \"catalog:\",\n \"@effect/sql-pg\": \"catalog:\",\n \"@useairfoil/connector-kit\": \"workspace:*\",\n \"@useairfoil/wings\": \"workspace:*\",\n \"effect\": \"catalog:\",\n \"standardwebhooks\": \"^1.0.0\"\n },\n \"devDependencies\": {\n \"@dotenvx/dotenvx\": \"^1.62.0\",\n \"@effect/vitest\": \"catalog:\",\n \"@types/node\": \"catalog:\",\n \"@useairfoil/effect-vcr\": \"workspace:*\",\n \"tsdown\": \"catalog:\",\n \"tsx\": \"^4.21.0\",\n \"vitest\": \"catalog:\"\n }\n}\n","import {\n ConnectorApp,\n Publisher,\n RuntimeConfig,\n StateStore,\n Telemetry,\n} from \"@useairfoil/connector-kit\";\nimport { Config, Effect, Layer, Logger } from \"effect\";\nimport { Command } from \"effect/unstable/cli\";\n\nimport { PolarConnector } from \"./index\";\n\nconst SandboxConfig = Config.unwrap<PolarConnector.PolarConfig>({\n ...PolarConnector.PolarConfigDef.fields,\n apiBaseUrl: Config.succeed(\"https://sandbox-api.polar.sh/v1/\"),\n});\n\nconst SandboxConnectorLayer = PolarConnector.layerConfig(SandboxConfig);\nconst TelemetryLayer = Layer.mergeAll(Telemetry.layerOtlp(), Telemetry.layerMetricsConsoleDump());\n\nexport const sandboxCommand = Command.make(\"sandbox\", {}, () =>\n Effect.gen(function* () {\n const port = yield* RuntimeConfig.httpPort;\n const entrypoint = yield* PolarConnector.PolarConnector;\n\n return yield* ConnectorApp.start(entrypoint, { port });\n }).pipe(\n Effect.annotateLogs({ component: \"polar\" }),\n Effect.provide(\n Layer.mergeAll(\n StateStore.layerMemory,\n Publisher.layerConsole,\n SandboxConnectorLayer,\n Logger.layer([Logger.consolePretty()]),\n TelemetryLayer,\n ),\n ),\n ),\n).pipe(Command.withDescription(\"Run the connector locally and log ingested data\"));\n","import { PgClient } from \"@effect/sql-pg\";\nimport {\n ConnectorApp,\n Publisher,\n RuntimeConfig,\n StateStore,\n Telemetry,\n} from \"@useairfoil/connector-kit\";\nimport { WingsClient } from \"@useairfoil/wings\";\nimport { Config, Effect, Layer, Logger, Schema } from \"effect\";\nimport { Command } from \"effect/unstable/cli\";\n\nimport { PolarConnector } from \"./index\";\n\nconst ConnectorLayer = PolarConnector.layerConfig(PolarConnector.PolarConfigDef.config);\nconst TelemetryLayer = Telemetry.layerOtlp();\nconst PostgresLayer = PgClient.layerConfig({\n url: Config.schema(\n Schema.Redacted(Schema.NonEmptyString),\n RuntimeConfig.PlatformRuntimeKey.postgresConnectionString,\n ),\n maxConnections: Config.succeed(2),\n connectTimeout: Config.succeed(\"5 seconds\"),\n applicationName: Config.succeed(\"airfoil-producer-polar\"),\n});\nconst StateStoreLayer = StateStore.layerSql().pipe(Layer.provide(PostgresLayer));\n\nexport const startCommand = Command.make(\"start\", {}, () =>\n Effect.gen(function* () {\n const port = yield* RuntimeConfig.httpPort;\n const entrypoint = yield* PolarConnector.PolarConnector;\n\n return yield* ConnectorApp.start(entrypoint, { port }).pipe(\n Effect.provide(Publisher.layerWingsConfig(entrypoint)),\n );\n }).pipe(\n Effect.annotateLogs({ component: \"polar\" }),\n Effect.provide(\n Layer.mergeAll(\n StateStoreLayer,\n ConnectorLayer,\n WingsClient.layerConfig(RuntimeConfig.wingsClient),\n Logger.layer([Logger.consolePretty()]),\n TelemetryLayer,\n ),\n ),\n Effect.provide(RuntimeConfig.layerHosted()),\n ),\n).pipe(Command.withDescription(\"Run the production connector against Wings\"));\n","#!/usr/bin/env node\n\nimport { NodeRuntime, NodeServices } from \"@effect/platform-node\";\nimport { Effect, Layer } from \"effect\";\nimport { Command } from \"effect/unstable/cli\";\nimport { FetchHttpClient } from \"effect/unstable/http\";\n\nimport packageJson from \"../package.json\";\nimport { sandboxCommand } from \"./sandbox\";\nimport { startCommand } from \"./start\";\n\nconst BootstrapLayer = Layer.mergeAll(FetchHttpClient.layer, NodeServices.layer);\n\nconst program = Command.make(\"producer-polar\", {}, () => Effect.void).pipe(\n Command.withSubcommands([startCommand, sandboxCommand]),\n);\n\nCommand.run(program, { version: packageJson.version }).pipe(\n Effect.provide(BootstrapLayer),\n Effect.scoped,\n NodeRuntime.runMain,\n);\n"],"mappings":";;;;;;;;;;;;cAEa;;;;ACUb,MAAM,gBAAgB,OAAO,OAAmC;CAC9D,kBAAiC;CACjC,YAAY,OAAO,QAAQ,mCAAmC;CAC/D,CAAC;AAEF,MAAM,wBAAwBA,YAA2B,cAAc;AACvE,MAAMC,mBAAiB,MAAM,SAAS,UAAU,WAAW,EAAE,UAAU,yBAAyB,CAAC;AAEjG,MAAa,iBAAiB,QAAQ,KAAK,WAAW,EAAE,QACtD,OAAO,IAAI,aAAa;CACtB,MAAM,OAAO,OAAO,cAAc;CAClC,MAAM,aAAa,OAAOC;AAE1B,QAAO,OAAO,aAAa,MAAM,YAAY,EAAE,MAAM,CAAC;EACtD,CAAC,KACD,OAAO,aAAa,EAAE,WAAW,SAAS,CAAC,EAC3C,OAAO,QACL,MAAM,SACJ,WAAW,aACX,UAAU,cACV,uBACA,OAAO,MAAM,CAAC,OAAO,eAAe,CAAC,CAAC,EACtCD,iBACD,CACF,CACF,CACF,CAAC,KAAK,QAAQ,gBAAgB,kDAAkD,CAAC;;;;ACxBlF,MAAM,iBAAiBE,2BAAyD,OAAO;AACvF,MAAM,iBAAiB,UAAU,WAAW;AAC5C,MAAM,gBAAgB,SAAS,YAAY;CACzC,KAAK,OAAO,OACV,OAAO,SAAS,OAAO,eAAe,EACtC,cAAc,mBAAmB,yBAClC;CACD,gBAAgB,OAAO,QAAQ,EAAE;CACjC,gBAAgB,OAAO,QAAQ,YAAY;CAC3C,iBAAiB,OAAO,QAAQ,yBAAyB;CAC1D,CAAC;AACF,MAAM,kBAAkB,WAAW,UAAU,CAAC,KAAK,MAAM,QAAQ,cAAc,CAAC;AAEhF,MAAa,eAAe,QAAQ,KAAK,SAAS,EAAE,QAClD,OAAO,IAAI,aAAa;CACtB,MAAM,OAAO,OAAO,cAAc;CAClC,MAAM,aAAa,OAAOC;AAE1B,QAAO,OAAO,aAAa,MAAM,YAAY,EAAE,MAAM,CAAC,CAAC,KACrD,OAAO,QAAQ,UAAU,iBAAiB,WAAW,CAAC,CACvD;EACD,CAAC,KACD,OAAO,aAAa,EAAE,WAAW,SAAS,CAAC,EAC3C,OAAO,QACL,MAAM,SACJ,iBACA,gBACA,YAAY,YAAY,cAAc,YAAY,EAClD,OAAO,MAAM,CAAC,OAAO,eAAe,CAAC,CAAC,EACtC,eACD,CACF,EACD,OAAO,QAAQ,cAAc,aAAa,CAAC,CAC5C,CACF,CAAC,KAAK,QAAQ,gBAAgB,6CAA6C,CAAC;;;;ACrC7E,MAAM,iBAAiB,MAAM,SAAS,gBAAgB,OAAO,aAAa,MAAM;AAEhF,MAAM,UAAU,QAAQ,KAAK,kBAAkB,EAAE,QAAQ,OAAO,KAAK,CAAC,KACpE,QAAQ,gBAAgB,CAAC,cAAc,eAAe,CAAC,CACxD;AAED,QAAQ,IAAI,SAAS,EAAWC,SAAqB,CAAC,CAAC,KACrD,OAAO,QAAQ,eAAe,EAC9B,OAAO,QACP,YAAY,QACb"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@useairfoil/producer-polar",
3
- "version": "0.2.2",
3
+ "version": "0.3.0",
4
4
  "repository": "useairfoil/typescript-sdk",
5
5
  "files": [
6
6
  "dist",
@@ -34,8 +34,8 @@
34
34
  "dependencies": {
35
35
  "@effect/platform-node": "^4.0.0-rc.108",
36
36
  "@effect/sql-pg": "^4.0.0-rc.108",
37
- "@useairfoil/connector-kit": "0.5.3",
38
- "@useairfoil/wings": "0.4.4",
37
+ "@useairfoil/connector-kit": "0.6.0",
38
+ "@useairfoil/wings": "0.4.5",
39
39
  "effect": "^4.0.0-rc.108",
40
40
  "standardwebhooks": "^1.0.0"
41
41
  },
package/src/sandbox.ts CHANGED
@@ -1,14 +1,15 @@
1
- import { ConnectorApp, Publisher, StateStore, Telemetry } from "@useairfoil/connector-kit";
1
+ import {
2
+ ConnectorApp,
3
+ Publisher,
4
+ RuntimeConfig,
5
+ StateStore,
6
+ Telemetry,
7
+ } from "@useairfoil/connector-kit";
2
8
  import { Config, Effect, Layer, Logger } from "effect";
3
9
  import { Command } from "effect/unstable/cli";
4
10
 
5
- import { PolarRuntimeKey } from "./constants";
6
11
  import { PolarConnector } from "./index";
7
12
 
8
- const HttpServerConfig = Config.all({
9
- port: Config.port(PolarRuntimeKey.webhookPort).pipe(Config.withDefault(8080)),
10
- });
11
-
12
13
  const SandboxConfig = Config.unwrap<PolarConnector.PolarConfig>({
13
14
  ...PolarConnector.PolarConfigDef.fields,
14
15
  apiBaseUrl: Config.succeed("https://sandbox-api.polar.sh/v1/"),
@@ -19,10 +20,10 @@ const TelemetryLayer = Layer.mergeAll(Telemetry.layerOtlp(), Telemetry.layerMetr
19
20
 
20
21
  export const sandboxCommand = Command.make("sandbox", {}, () =>
21
22
  Effect.gen(function* () {
22
- const config = yield* HttpServerConfig;
23
+ const port = yield* RuntimeConfig.httpPort;
23
24
  const entrypoint = yield* PolarConnector.PolarConnector;
24
25
 
25
- return yield* ConnectorApp.start(entrypoint, { port: config.port });
26
+ return yield* ConnectorApp.start(entrypoint, { port });
26
27
  }).pipe(
27
28
  Effect.annotateLogs({ component: "polar" }),
28
29
  Effect.provide(
package/src/start.ts CHANGED
@@ -10,27 +10,8 @@ import { WingsClient } from "@useairfoil/wings";
10
10
  import { Config, Effect, Layer, Logger, Schema } from "effect";
11
11
  import { Command } from "effect/unstable/cli";
12
12
 
13
- import { PolarRuntimeKey } from "./constants";
14
13
  import { PolarConnector } from "./index";
15
14
 
16
- // The operator injects runtime wiring; these values are intentionally absent
17
- // from the user-facing connector manifest.
18
- const HttpServerConfig = Config.all({
19
- port: Config.port(PolarRuntimeKey.webhookPort).pipe(Config.withDefault(8080)),
20
- });
21
-
22
- const PolarTablesConfig = Config.all({
23
- customers: Config.nonEmptyString(PolarRuntimeKey.customersTable),
24
- checkouts: Config.nonEmptyString(PolarRuntimeKey.checkoutsTable),
25
- orders: Config.nonEmptyString(PolarRuntimeKey.ordersTable),
26
- subscriptions: Config.nonEmptyString(PolarRuntimeKey.subscriptionsTable),
27
- });
28
-
29
- const WingsConfig = Config.all({
30
- host: Config.nonEmptyString(RuntimeConfig.PlatformRuntimeKey.wingsHost),
31
- namespace: Config.nonEmptyString(RuntimeConfig.PlatformRuntimeKey.wingsNamespace),
32
- });
33
-
34
15
  const ConnectorLayer = PolarConnector.layerConfig(PolarConnector.PolarConfigDef.config);
35
16
  const TelemetryLayer = Telemetry.layerOtlp();
36
17
  const PostgresLayer = PgClient.layerConfig({
@@ -46,22 +27,11 @@ const StateStoreLayer = StateStore.layerSql().pipe(Layer.provide(PostgresLayer))
46
27
 
47
28
  export const startCommand = Command.make("start", {}, () =>
48
29
  Effect.gen(function* () {
49
- const runtimeConfig = yield* HttpServerConfig;
50
- const tableConfig = yield* PolarTablesConfig;
30
+ const port = yield* RuntimeConfig.httpPort;
51
31
  const entrypoint = yield* PolarConnector.PolarConnector;
52
32
 
53
- return yield* ConnectorApp.start(entrypoint, { port: runtimeConfig.port }).pipe(
54
- Effect.provide(
55
- Publisher.layerWings({
56
- connector: entrypoint,
57
- tables: {
58
- customers: tableConfig.customers,
59
- checkouts: tableConfig.checkouts,
60
- orders: tableConfig.orders,
61
- subscriptions: tableConfig.subscriptions,
62
- },
63
- }),
64
- ),
33
+ return yield* ConnectorApp.start(entrypoint, { port }).pipe(
34
+ Effect.provide(Publisher.layerWingsConfig(entrypoint)),
65
35
  );
66
36
  }).pipe(
67
37
  Effect.annotateLogs({ component: "polar" }),
@@ -69,7 +39,7 @@ export const startCommand = Command.make("start", {}, () =>
69
39
  Layer.mergeAll(
70
40
  StateStoreLayer,
71
41
  ConnectorLayer,
72
- WingsClient.layerConfig(WingsConfig),
42
+ WingsClient.layerConfig(RuntimeConfig.wingsClient),
73
43
  Logger.layer([Logger.consolePretty()]),
74
44
  TelemetryLayer,
75
45
  ),
package/src/constants.ts DELETED
@@ -1,8 +0,0 @@
1
- /** Connector-specific runtime keys injected by the Airfoil platform. */
2
- export const PolarRuntimeKey = {
3
- webhookPort: "POLAR_WEBHOOK_PORT",
4
- customersTable: "POLAR_CUSTOMERS_TABLE",
5
- checkoutsTable: "POLAR_CHECKOUTS_TABLE",
6
- ordersTable: "POLAR_ORDERS_TABLE",
7
- subscriptionsTable: "POLAR_SUBSCRIPTIONS_TABLE",
8
- } as const;