@cosmicdrift/kumiko-server-runtime 0.393.0 → 0.395.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.
@@ -1,25 +1,25 @@
1
1
  import { type TierSyncResult } from "@cosmicdrift/kumiko-bundled-features/billing-foundation";
2
- import { type SubscriptionDodoOptions } from "@cosmicdrift/kumiko-bundled-features/subscription-dodo";
2
+ import { type SubscriptionPaddleOptions } from "@cosmicdrift/kumiko-bundled-features/subscription-paddle";
3
3
  import { type SubscriptionStripeOptions } from "@cosmicdrift/kumiko-bundled-features/subscription-stripe";
4
4
  import type { ExtraRouteDefinition } from "@cosmicdrift/kumiko-framework/api";
5
5
  import type { FeatureDefinition } from "@cosmicdrift/kumiko-framework/engine";
6
- /** Mounts `subscription-stripe` and/or `subscription-dodo` plus one webhook
6
+ /** Mounts `subscription-stripe` and/or `subscription-paddle` plus one webhook
7
7
  * route that writes the subscription and syncs the tenant's tier
8
8
  * (`tier-engine`). Needs `billing-foundation`, `tier-engine`, `config` and
9
9
  * `secrets` in `features`. The env keys (`STRIPE_API_KEY` /
10
- * `STRIPE_WEBHOOK_SECRET`, `DODO_PAYMENTS_API_KEY` /
11
- * `DODO_PAYMENTS_WEBHOOK_KEY`) are only the bridge fallback; the keys
10
+ * `STRIPE_WEBHOOK_SECRET`, `PADDLE_API_KEY` / `PADDLE_WEBHOOK_SECRET` /
11
+ * `PADDLE_TENANT_BINDING_KEY` / `PADDLE_CLIENT_TOKEN`) are only the bridge fallback; the keys
12
12
  * normally live in the secrets store.
13
13
  *
14
14
  * @example
15
15
  * runProdApp({ ..., billing: {
16
16
  * stripe: { priceToTier: { [env.STRIPE_PRICE_PRO]: "pro" } },
17
- * dodo: { priceToTier: { [env.DODO_PRODUCT_PRO]: "pro" } },
17
+ * paddle: { priceToTier: { [env.PADDLE_PRICE_PRO]: "pro" } },
18
18
  * defaultTier: "free",
19
19
  * } })
20
20
  */
21
21
  export type BillingBootOption = {
22
- /** At least one of `stripe` and `dodo` is required. */
22
+ /** At least one of `stripe` and `paddle` is required. */
23
23
  readonly stripe?: {
24
24
  readonly priceToTier: Readonly<Record<string, string>>;
25
25
  /** Default `SUBSCRIPTION_WEBHOOK_PATH`; must contain `:providerName`. Applies to every provider. */
@@ -27,9 +27,9 @@ export type BillingBootOption = {
27
27
  readonly oneOffPriceIds?: SubscriptionStripeOptions["oneOffPriceIds"];
28
28
  readonly paymentInvoiceCreation?: boolean;
29
29
  };
30
- readonly dodo?: {
30
+ readonly paddle?: {
31
31
  readonly priceToTier: Readonly<Record<string, string>>;
32
- readonly oneOffPriceIds?: SubscriptionDodoOptions["oneOffPriceIds"];
32
+ readonly oneOffPriceIds?: SubscriptionPaddleOptions["oneOffPriceIds"];
33
33
  };
34
34
  /** Tier a tenant falls back to without an active subscription. */
35
35
  readonly defaultTier: string;
@@ -1,5 +1,5 @@
1
1
  import { createSubscriptionTierSync, SUBSCRIPTION_WEBHOOK_PATH, } from "@cosmicdrift/kumiko-bundled-features/billing-foundation";
2
- import { createSubscriptionDodoFeature, } from "@cosmicdrift/kumiko-bundled-features/subscription-dodo";
2
+ import { createSubscriptionPaddleFeature, } from "@cosmicdrift/kumiko-bundled-features/subscription-paddle";
3
3
  import { createSubscriptionStripeFeature, } from "@cosmicdrift/kumiko-bundled-features/subscription-stripe";
4
4
  const PROVIDER_NAME_PARAM = ":providerName";
5
5
  function warnOnEmptyPriceMap(provider, priceToTier) {
@@ -13,7 +13,7 @@ function bridgeCredentials(envSource, apiKeyName, webhookSecretName) {
13
13
  const webhookSecret = envSource[webhookSecretName];
14
14
  return { ...(apiKey && { apiKey }), ...(webhookSecret && { webhookSecret }) };
15
15
  }
16
- function providerFeatures({ stripe, dodo }, envSource) {
16
+ function providerFeatures({ stripe, paddle }, envSource) {
17
17
  const features = [];
18
18
  if (stripe) {
19
19
  warnOnEmptyPriceMap("stripe", stripe.priceToTier);
@@ -26,20 +26,24 @@ function providerFeatures({ stripe, dodo }, envSource) {
26
26
  ...bridgeCredentials(envSource, "STRIPE_API_KEY", "STRIPE_WEBHOOK_SECRET"),
27
27
  }));
28
28
  }
29
- if (dodo) {
30
- warnOnEmptyPriceMap("dodo", dodo.priceToTier);
31
- features.push(createSubscriptionDodoFeature({
32
- priceToTier: dodo.priceToTier,
33
- ...(dodo.oneOffPriceIds && { oneOffPriceIds: dodo.oneOffPriceIds }),
34
- ...bridgeCredentials(envSource, "DODO_PAYMENTS_API_KEY", "DODO_PAYMENTS_WEBHOOK_KEY"),
29
+ if (paddle) {
30
+ const tenantBindingKey = envSource["PADDLE_TENANT_BINDING_KEY"];
31
+ const clientToken = envSource["PADDLE_CLIENT_TOKEN"];
32
+ warnOnEmptyPriceMap("paddle", paddle.priceToTier);
33
+ features.push(createSubscriptionPaddleFeature({
34
+ priceToTier: paddle.priceToTier,
35
+ ...(paddle.oneOffPriceIds && { oneOffPriceIds: paddle.oneOffPriceIds }),
36
+ ...bridgeCredentials(envSource, "PADDLE_API_KEY", "PADDLE_WEBHOOK_SECRET"),
37
+ ...(tenantBindingKey && { tenantBindingKey }),
38
+ ...(clientToken && { clientToken }),
35
39
  }));
36
40
  }
37
41
  return features;
38
42
  }
39
43
  export function resolveBillingOption(billing, envSource) {
40
- const { stripe, dodo } = billing;
41
- if (!stripe && !dodo) {
42
- throw new Error("[runProdApp] billing needs at least one provider: set billing.stripe or billing.dodo.");
44
+ const { stripe, paddle } = billing;
45
+ if (!stripe && !paddle) {
46
+ throw new Error("[runProdApp] billing needs at least one provider: set billing.stripe or billing.paddle.");
43
47
  }
44
48
  const webhookPath = stripe?.webhookPath ?? SUBSCRIPTION_WEBHOOK_PATH;
45
49
  if (!webhookPath.includes(PROVIDER_NAME_PARAM)) {
@@ -49,7 +53,7 @@ export function resolveBillingOption(billing, envSource) {
49
53
  const tierNames = new Set([
50
54
  billing.defaultTier,
51
55
  ...Object.values(stripe?.priceToTier ?? {}),
52
- ...Object.values(dodo?.priceToTier ?? {}),
56
+ ...Object.values(paddle?.priceToTier ?? {}),
53
57
  ...(billing.tierNames ?? []),
54
58
  ]);
55
59
  const tierSync = createSubscriptionTierSync({
@@ -1,7 +1,7 @@
1
1
  import { BILLING_FOUNDATION_FEATURE } from "@cosmicdrift/kumiko-bundled-features/billing-foundation";
2
2
  import { DELIVERY_FEATURE } from "@cosmicdrift/kumiko-bundled-features/delivery";
3
3
  import { FEATURE_TOGGLES_FEATURE } from "@cosmicdrift/kumiko-bundled-features/feature-toggles";
4
- import { SUBSCRIPTION_DODO_FEATURE } from "@cosmicdrift/kumiko-bundled-features/subscription-dodo";
4
+ import { SUBSCRIPTION_PADDLE_FEATURE } from "@cosmicdrift/kumiko-bundled-features/subscription-paddle";
5
5
  import { SUBSCRIPTION_STRIPE_FEATURE } from "@cosmicdrift/kumiko-bundled-features/subscription-stripe";
6
6
  import { TIER_ENGINE_FEATURE } from "@cosmicdrift/kumiko-bundled-features/tier-engine";
7
7
  import { resolveBillingOption } from "./billing-option.js";
@@ -87,8 +87,8 @@ export async function resolveBootOptionWiring(options, envSource) {
87
87
  if (options.billing.stripe) {
88
88
  rejectDoubleMount(mounted, "billing.stripe", SUBSCRIPTION_STRIPE_FEATURE);
89
89
  }
90
- if (options.billing.dodo) {
91
- rejectDoubleMount(mounted, "billing.dodo", SUBSCRIPTION_DODO_FEATURE);
90
+ if (options.billing.paddle) {
91
+ rejectDoubleMount(mounted, "billing.paddle", SUBSCRIPTION_PADDLE_FEATURE);
92
92
  }
93
93
  const billing = resolveBillingOption(options.billing, envSource);
94
94
  features.push(...billing.features);
@@ -23,7 +23,7 @@ const OPTION_CHECKS = {
23
23
  },
24
24
  billing: {
25
25
  isSatisfied: (options, mounted) => options.billing !== undefined || mountsExtension(mounted, SUBSCRIPTION_PROVIDER_EXTENSION),
26
- hint: "set billing: { stripe: { priceToTier }, defaultTier } (or dodo)",
26
+ hint: "set billing: { stripe: { priceToTier }, defaultTier } (or paddle)",
27
27
  },
28
28
  featureToggles: {
29
29
  isSatisfied: (options) => options.featureToggles === true,
@@ -395,7 +395,7 @@ export type RunProdAppOptions = {
395
395
  * @example
396
396
  * fileStorage: { provider: "auto" } */
397
397
  readonly fileStorage?: FileStorageBootOption;
398
- /** Billing: `subscription-stripe` and/or `subscription-dodo` plus one tier-syncing webhook
398
+ /** Billing: `subscription-stripe` and/or `subscription-paddle` plus one tier-syncing webhook
399
399
  * route. Needs `billing-foundation` and `tier-engine`. See `BillingBootOption`.
400
400
  * @example
401
401
  * billing: { stripe: { priceToTier: { [env.STRIPE_PRICE_PRO]: "pro" } }, defaultTier: "free" } */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cosmicdrift/kumiko-server-runtime",
3
- "version": "0.393.0",
3
+ "version": "0.395.0",
4
4
  "description": "Production server-boot runtime for Kumiko apps: connections, schema-drift-gate, seeds, lifecycle, graceful shutdown. Symmetric to kumiko-dev-server's runDevApp, without dev/scaffold tooling.",
5
5
  "license": "MIT",
6
6
  "author": "Marc Frost <marc@cosmicdriftgamestudio.com>",
@@ -96,11 +96,11 @@
96
96
  }
97
97
  },
98
98
  "dependencies": {
99
- "@cosmicdrift/kumiko-bundled-features": "0.393.0",
100
- "@cosmicdrift/kumiko-framework": "0.393.0",
101
- "@cosmicdrift/kumiko-renderer": "0.393.0",
102
- "@cosmicdrift/kumiko-renderer-mail-html": "0.393.0",
103
- "@cosmicdrift/kumiko-types": "0.393.0",
99
+ "@cosmicdrift/kumiko-bundled-features": "0.395.0",
100
+ "@cosmicdrift/kumiko-framework": "0.395.0",
101
+ "@cosmicdrift/kumiko-renderer": "0.395.0",
102
+ "@cosmicdrift/kumiko-renderer-mail-html": "0.395.0",
103
+ "@cosmicdrift/kumiko-types": "0.395.0",
104
104
  "ioredis": "^5.10.1",
105
105
  "temporal-polyfill": "^0.3.2",
106
106
  "zod": "^4.6.7"
@@ -109,7 +109,7 @@
109
109
  "bun-types": "^1.4.4"
110
110
  },
111
111
  "devDependencies": {
112
- "@cosmicdrift/kumiko-testing": "0.393.0",
112
+ "@cosmicdrift/kumiko-testing": "0.395.0",
113
113
  "bun-types": "^1.4.4"
114
114
  },
115
115
  "publishConfig": {