@useairfoil/producer-shopify 0.1.1 → 0.2.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
@@ -72,11 +72,11 @@ SHOPIFY_API_VERSION=2026-07
72
72
  # SHOPIFY_GRAPHQL_RETRY_BASE_DELAY_MS=500
73
73
  # SHOPIFY_RETRY_AFTER_FALLBACK_SECONDS=1
74
74
  # SHOPIFY_REQUEST_TIMEOUT_SECONDS=120
75
- SHOPIFY_WEBHOOK_PORT=8080
75
+ AIRFOIL_HTTP_PORT=8080
76
76
  OTEL_ENABLED=false
77
77
  OTEL_SERVICE_NAME=producer-shopify
78
78
  # OTEL_SERVICE_VERSION=0.1.0
79
- # OTEL_RESOURCE_ATTRIBUTES=deployment.environment=production,team=data
79
+ # OTEL_RESOURCE_ATTRIBUTES=service.instance.id=team-acme-shopify-primary,airfoil.connector.revision=1,airfoil.team.id=team-acme
80
80
  OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4318
81
81
  # OTEL_EXPORTER_OTLP_HEADERS=Authorization=Bearer <token>,X-Axiom-Dataset=<dataset>
82
82
  ```
@@ -88,8 +88,7 @@ Production `start` also requires platform-owned Wings, table, and PostgreSQL sta
88
88
  ```env
89
89
  WINGS_HOST=localhost:7777
90
90
  WINGS_NAMESPACE=namespaces/default
91
- SHOPIFY_PRODUCTS_TABLE=namespaces/default/tables/shopify-products
92
- SHOPIFY_CART_EVENTS_TABLE=namespaces/default/tables/shopify-cart-events
91
+ AIRFOIL_TABLE_BINDINGS={"products":"namespaces/default/tables/shopify-products","cart_events":"namespaces/default/tables/shopify-cart-events"}
93
92
  AIRFOIL_CONFIG_PATH=/var/run/airfoil/config/config.json
94
93
  AIRFOIL_CONNECTOR_INSTANCE_ID=team-acme-shopify-primary
95
94
  # AIRFOIL_STATE_TABLE=_airfoil_connectors_state
@@ -123,7 +122,7 @@ pnpm --filter @useairfoil/producer-shopify run start
123
122
 
124
123
  `sandbox` runs the real connector with `Publisher.layerConsole`. `start` passes the configured Wings table names to `Publisher.layerWings`.
125
124
 
126
- 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`.
125
+ 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.
127
126
 
128
127
  Before provisioning, the dashboard backend passes `ShopifyConnector.ShopifyConnector` and `ShopifyConnector.layerConfig(ShopifyConnector.ShopifyConfigDef.config)` to `ConnectorApp.check(...)`. `products` requests one product ID only, while webhook-only `cart_events` uses a minimal shop identity query that does not require product access.
129
128
 
package/dist/main.js CHANGED
@@ -9,39 +9,20 @@ import { PgClient } from "@effect/sql-pg";
9
9
  import { WingsClient } from "@useairfoil/wings";
10
10
 
11
11
  //#region package.json
12
- var version = "0.1.0";
13
-
14
- //#endregion
15
- //#region src/constants.ts
16
- /** Connector-specific runtime keys injected by the Airfoil platform. */
17
- const ShopifyRuntimeKey = {
18
- webhookPort: "SHOPIFY_WEBHOOK_PORT",
19
- productsTable: "SHOPIFY_PRODUCTS_TABLE",
20
- cartEventsTable: "SHOPIFY_CART_EVENTS_TABLE"
21
- };
12
+ var version = "0.1.1";
22
13
 
23
14
  //#endregion
24
15
  //#region src/sandbox.ts
25
- const HttpServerConfig$1 = Config.all({ port: Config.port(ShopifyRuntimeKey.webhookPort).pipe(Config.withDefault(8080)) });
26
16
  const ConnectorLayer$1 = layerConfig(ShopifyConfigDef.config);
27
17
  const TelemetryLayer$1 = Layer.mergeAll(Telemetry.layerOtlp({ redactedHeaders: ["x-shopify-access-token"] }), Telemetry.layerMetricsConsoleDump());
28
18
  const sandboxCommand = Command.make("sandbox", {}, () => Effect.gen(function* () {
29
- const config = yield* HttpServerConfig$1;
19
+ const port = yield* RuntimeConfig.httpPort;
30
20
  const entrypoint = yield* ShopifyConnector;
31
- return yield* ConnectorApp.start(entrypoint, { port: config.port });
21
+ return yield* ConnectorApp.start(entrypoint, { port });
32
22
  }).pipe(Effect.annotateLogs({ component: "producer-shopify" }), Effect.provide(Layer.mergeAll(StateStore.layerMemory, Publisher.layerConsole, ConnectorLayer$1, Logger.layer([Logger.consolePretty()]), TelemetryLayer$1)))).pipe(Command.withDescription("Run the connector locally and log ingested data"));
33
23
 
34
24
  //#endregion
35
25
  //#region src/start.ts
36
- const HttpServerConfig = Config.all({ port: Config.port(ShopifyRuntimeKey.webhookPort).pipe(Config.withDefault(8080)) });
37
- const ShopifyTablesConfig = Config.all({
38
- products: Config.nonEmptyString(ShopifyRuntimeKey.productsTable),
39
- cartEvents: Config.nonEmptyString(ShopifyRuntimeKey.cartEventsTable)
40
- });
41
- const WingsConfig = Config.all({
42
- host: Config.nonEmptyString(RuntimeConfig.PlatformRuntimeKey.wingsHost),
43
- namespace: Config.nonEmptyString(RuntimeConfig.PlatformRuntimeKey.wingsNamespace)
44
- });
45
26
  const ConnectorLayer = layerConfig(ShopifyConfigDef.config);
46
27
  const TelemetryLayer = Telemetry.layerOtlp({ redactedHeaders: ["x-shopify-access-token"] });
47
28
  const PostgresLayer = PgClient.layerConfig({
@@ -52,17 +33,10 @@ const PostgresLayer = PgClient.layerConfig({
52
33
  });
53
34
  const StateStoreLayer = StateStore.layerSql().pipe(Layer.provide(PostgresLayer));
54
35
  const startCommand = Command.make("start", {}, () => Effect.gen(function* () {
55
- const runtimeConfig = yield* HttpServerConfig;
56
- const tableConfig = yield* ShopifyTablesConfig;
36
+ const port = yield* RuntimeConfig.httpPort;
57
37
  const entrypoint = yield* ShopifyConnector;
58
- return yield* ConnectorApp.start(entrypoint, { port: runtimeConfig.port }).pipe(Effect.provide(Publisher.layerWings({
59
- connector: entrypoint,
60
- tables: {
61
- products: tableConfig.products,
62
- cart_events: tableConfig.cartEvents
63
- }
64
- })));
65
- }).pipe(Effect.annotateLogs({ component: "producer-shopify" }), 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"));
38
+ return yield* ConnectorApp.start(entrypoint, { port }).pipe(Effect.provide(Publisher.layerWingsConfig(entrypoint)));
39
+ }).pipe(Effect.annotateLogs({ component: "producer-shopify" }), 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"));
66
40
 
67
41
  //#endregion
68
42
  //#region src/main.ts
package/dist/main.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"main.js","names":["HttpServerConfig","ConnectorLayer","ShopifyConnector.layerConfig","TelemetryLayer","ShopifyConnector.ShopifyConnector","ShopifyConnector.layerConfig","ShopifyConnector.ShopifyConnector","packageJson.version"],"sources":["../package.json","../src/constants.ts","../src/sandbox.ts","../src/start.ts","../src/main.ts"],"sourcesContent":["{\n \"name\": \"@useairfoil/producer-shopify\",\n \"version\": \"0.1.0\",\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-shopify: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 },\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 ShopifyRuntimeKey = {\n webhookPort: \"SHOPIFY_WEBHOOK_PORT\",\n productsTable: \"SHOPIFY_PRODUCTS_TABLE\",\n cartEventsTable: \"SHOPIFY_CART_EVENTS_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 { ShopifyRuntimeKey } from \"./constants\";\nimport { ShopifyConnector } from \"./index\";\n\nconst HttpServerConfig = Config.all({\n port: Config.port(ShopifyRuntimeKey.webhookPort).pipe(Config.withDefault(8080)),\n});\n\nconst ConnectorLayer = ShopifyConnector.layerConfig(ShopifyConnector.ShopifyConfigDef.config);\n\nconst TelemetryLayer = Layer.mergeAll(\n Telemetry.layerOtlp({ redactedHeaders: [\"x-shopify-access-token\"] }),\n Telemetry.layerMetricsConsoleDump(),\n);\n\nexport const sandboxCommand = Command.make(\"sandbox\", {}, () =>\n Effect.gen(function* () {\n const config = yield* HttpServerConfig;\n const entrypoint = yield* ShopifyConnector.ShopifyConnector;\n\n return yield* ConnectorApp.start(entrypoint, { port: config.port });\n }).pipe(\n Effect.annotateLogs({ component: \"producer-shopify\" }),\n Effect.provide(\n Layer.mergeAll(\n StateStore.layerMemory,\n Publisher.layerConsole,\n ConnectorLayer,\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 { ShopifyRuntimeKey } from \"./constants\";\nimport { ShopifyConnector } 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(ShopifyRuntimeKey.webhookPort).pipe(Config.withDefault(8080)),\n});\n\nconst ShopifyTablesConfig = Config.all({\n products: Config.nonEmptyString(ShopifyRuntimeKey.productsTable),\n cartEvents: Config.nonEmptyString(ShopifyRuntimeKey.cartEventsTable),\n});\n\nconst WingsConfig = Config.all({\n host: Config.nonEmptyString(RuntimeConfig.PlatformRuntimeKey.wingsHost),\n namespace: Config.nonEmptyString(RuntimeConfig.PlatformRuntimeKey.wingsNamespace),\n});\n\nconst ConnectorLayer = ShopifyConnector.layerConfig(ShopifyConnector.ShopifyConfigDef.config);\n\nconst TelemetryLayer = Telemetry.layerOtlp({\n redactedHeaders: [\"x-shopify-access-token\"],\n});\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-shopify\"),\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* ShopifyTablesConfig;\n const entrypoint = yield* ShopifyConnector.ShopifyConnector;\n\n return yield* ConnectorApp.start(entrypoint, { port: runtimeConfig.port }).pipe(\n Effect.provide(\n Publisher.layerWings({\n connector: entrypoint,\n tables: {\n products: tableConfig.products,\n cart_events: tableConfig.cartEvents,\n },\n }),\n ),\n );\n }).pipe(\n Effect.annotateLogs({ component: \"producer-shopify\" }),\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","import { 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-shopify\", {}, () => 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":["ConnectorLayer","ShopifyConnector.layerConfig","TelemetryLayer","ShopifyConnector.ShopifyConnector","ShopifyConnector.layerConfig","ShopifyConnector.ShopifyConnector","packageJson.version"],"sources":["../package.json","../src/sandbox.ts","../src/start.ts","../src/main.ts"],"sourcesContent":["{\n \"name\": \"@useairfoil/producer-shopify\",\n \"version\": \"0.1.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-shopify: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 },\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 { Effect, Layer, Logger } from \"effect\";\nimport { Command } from \"effect/unstable/cli\";\n\nimport { ShopifyConnector } from \"./index\";\n\nconst ConnectorLayer = ShopifyConnector.layerConfig(ShopifyConnector.ShopifyConfigDef.config);\n\nconst TelemetryLayer = Layer.mergeAll(\n Telemetry.layerOtlp({ redactedHeaders: [\"x-shopify-access-token\"] }),\n Telemetry.layerMetricsConsoleDump(),\n);\n\nexport const sandboxCommand = Command.make(\"sandbox\", {}, () =>\n Effect.gen(function* () {\n const port = yield* RuntimeConfig.httpPort;\n const entrypoint = yield* ShopifyConnector.ShopifyConnector;\n\n return yield* ConnectorApp.start(entrypoint, { port });\n }).pipe(\n Effect.annotateLogs({ component: \"producer-shopify\" }),\n Effect.provide(\n Layer.mergeAll(\n StateStore.layerMemory,\n Publisher.layerConsole,\n ConnectorLayer,\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 { ShopifyConnector } from \"./index\";\n\nconst ConnectorLayer = ShopifyConnector.layerConfig(ShopifyConnector.ShopifyConfigDef.config);\n\nconst TelemetryLayer = Telemetry.layerOtlp({\n redactedHeaders: [\"x-shopify-access-token\"],\n});\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-shopify\"),\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* ShopifyConnector.ShopifyConnector;\n\n return yield* ConnectorApp.start(entrypoint, { port }).pipe(\n Effect.provide(Publisher.layerWingsConfig(entrypoint)),\n );\n }).pipe(\n Effect.annotateLogs({ component: \"producer-shopify\" }),\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","import { 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-shopify\", {}, () => 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,MAAMA,mBAAiBC,6BAA+D,OAAO;AAE7F,MAAMC,mBAAiB,MAAM,SAC3B,UAAU,UAAU,EAAE,iBAAiB,CAAC,yBAAyB,EAAE,CAAC,EACpE,UAAU,yBAAyB,CACpC;AAED,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,oBAAoB,CAAC,EACtD,OAAO,QACL,MAAM,SACJ,WAAW,aACX,UAAU,cACVH,kBACA,OAAO,MAAM,CAAC,OAAO,eAAe,CAAC,CAAC,EACtCE,iBACD,CACF,CACF,CACF,CAAC,KAAK,QAAQ,gBAAgB,kDAAkD,CAAC;;;;ACvBlF,MAAM,iBAAiBE,6BAA+D,OAAO;AAE7F,MAAM,iBAAiB,UAAU,UAAU,EACzC,iBAAiB,CAAC,yBAAyB,EAC5C,CAAC;AACF,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,2BAA2B;CAC5D,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,oBAAoB,CAAC,EACtD,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;;;;AC1C7E,MAAM,iBAAiB,MAAM,SAAS,gBAAgB,OAAO,aAAa,MAAM;AAEhF,MAAM,UAAU,QAAQ,KAAK,oBAAoB,EAAE,QAAQ,OAAO,KAAK,CAAC,KACtE,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-shopify",
3
- "version": "0.1.1",
3
+ "version": "0.2.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
  },
41
41
  "devDependencies": {
package/src/sandbox.ts CHANGED
@@ -1,14 +1,15 @@
1
- import { ConnectorApp, Publisher, StateStore, Telemetry } from "@useairfoil/connector-kit";
2
- import { Config, Effect, Layer, Logger } from "effect";
1
+ import {
2
+ ConnectorApp,
3
+ Publisher,
4
+ RuntimeConfig,
5
+ StateStore,
6
+ Telemetry,
7
+ } from "@useairfoil/connector-kit";
8
+ import { Effect, Layer, Logger } from "effect";
3
9
  import { Command } from "effect/unstable/cli";
4
10
 
5
- import { ShopifyRuntimeKey } from "./constants";
6
11
  import { ShopifyConnector } from "./index";
7
12
 
8
- const HttpServerConfig = Config.all({
9
- port: Config.port(ShopifyRuntimeKey.webhookPort).pipe(Config.withDefault(8080)),
10
- });
11
-
12
13
  const ConnectorLayer = ShopifyConnector.layerConfig(ShopifyConnector.ShopifyConfigDef.config);
13
14
 
14
15
  const TelemetryLayer = Layer.mergeAll(
@@ -18,10 +19,10 @@ const TelemetryLayer = Layer.mergeAll(
18
19
 
19
20
  export const sandboxCommand = Command.make("sandbox", {}, () =>
20
21
  Effect.gen(function* () {
21
- const config = yield* HttpServerConfig;
22
+ const port = yield* RuntimeConfig.httpPort;
22
23
  const entrypoint = yield* ShopifyConnector.ShopifyConnector;
23
24
 
24
- return yield* ConnectorApp.start(entrypoint, { port: config.port });
25
+ return yield* ConnectorApp.start(entrypoint, { port });
25
26
  }).pipe(
26
27
  Effect.annotateLogs({ component: "producer-shopify" }),
27
28
  Effect.provide(
package/src/start.ts CHANGED
@@ -10,25 +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 { ShopifyRuntimeKey } from "./constants";
14
13
  import { ShopifyConnector } 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(ShopifyRuntimeKey.webhookPort).pipe(Config.withDefault(8080)),
20
- });
21
-
22
- const ShopifyTablesConfig = Config.all({
23
- products: Config.nonEmptyString(ShopifyRuntimeKey.productsTable),
24
- cartEvents: Config.nonEmptyString(ShopifyRuntimeKey.cartEventsTable),
25
- });
26
-
27
- const WingsConfig = Config.all({
28
- host: Config.nonEmptyString(RuntimeConfig.PlatformRuntimeKey.wingsHost),
29
- namespace: Config.nonEmptyString(RuntimeConfig.PlatformRuntimeKey.wingsNamespace),
30
- });
31
-
32
15
  const ConnectorLayer = ShopifyConnector.layerConfig(ShopifyConnector.ShopifyConfigDef.config);
33
16
 
34
17
  const TelemetryLayer = Telemetry.layerOtlp({
@@ -47,20 +30,11 @@ const StateStoreLayer = StateStore.layerSql().pipe(Layer.provide(PostgresLayer))
47
30
 
48
31
  export const startCommand = Command.make("start", {}, () =>
49
32
  Effect.gen(function* () {
50
- const runtimeConfig = yield* HttpServerConfig;
51
- const tableConfig = yield* ShopifyTablesConfig;
33
+ const port = yield* RuntimeConfig.httpPort;
52
34
  const entrypoint = yield* ShopifyConnector.ShopifyConnector;
53
35
 
54
- return yield* ConnectorApp.start(entrypoint, { port: runtimeConfig.port }).pipe(
55
- Effect.provide(
56
- Publisher.layerWings({
57
- connector: entrypoint,
58
- tables: {
59
- products: tableConfig.products,
60
- cart_events: tableConfig.cartEvents,
61
- },
62
- }),
63
- ),
36
+ return yield* ConnectorApp.start(entrypoint, { port }).pipe(
37
+ Effect.provide(Publisher.layerWingsConfig(entrypoint)),
64
38
  );
65
39
  }).pipe(
66
40
  Effect.annotateLogs({ component: "producer-shopify" }),
@@ -68,7 +42,7 @@ export const startCommand = Command.make("start", {}, () =>
68
42
  Layer.mergeAll(
69
43
  StateStoreLayer,
70
44
  ConnectorLayer,
71
- WingsClient.layerConfig(WingsConfig),
45
+ WingsClient.layerConfig(RuntimeConfig.wingsClient),
72
46
  Logger.layer([Logger.consolePretty()]),
73
47
  TelemetryLayer,
74
48
  ),
package/src/constants.ts DELETED
@@ -1,6 +0,0 @@
1
- /** Connector-specific runtime keys injected by the Airfoil platform. */
2
- export const ShopifyRuntimeKey = {
3
- webhookPort: "SHOPIFY_WEBHOOK_PORT",
4
- productsTable: "SHOPIFY_PRODUCTS_TABLE",
5
- cartEventsTable: "SHOPIFY_CART_EVENTS_TABLE",
6
- } as const;