@kernhq/module-billing 0.4.1 → 0.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/contract.d.ts +16 -1
- package/dist/contract.d.ts.map +1 -1
- package/dist/contract.js +20 -3
- package/dist/contract.js.map +1 -1
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +125 -5
- package/dist/server/index.js.map +1 -1
- package/dist/server/router.d.ts +6 -4
- package/dist/server/router.d.ts.map +1 -1
- package/dist/server/router.js +12 -1
- package/dist/server/router.js.map +1 -1
- package/dist/server/services/catalogue.d.ts +30 -0
- package/dist/server/services/catalogue.d.ts.map +1 -0
- package/dist/server/services/catalogue.js +87 -0
- package/dist/server/services/catalogue.js.map +1 -0
- package/dist/server/services/entitlements.d.ts.map +1 -1
- package/dist/server/services/entitlements.js +28 -8
- package/dist/server/services/entitlements.js.map +1 -1
- package/dist/server/services/stripe.d.ts +34 -0
- package/dist/server/services/stripe.d.ts.map +1 -1
- package/dist/server/services/stripe.js +202 -15
- package/dist/server/services/stripe.js.map +1 -1
- package/package.json +2 -1
- package/src/client/i18n.ts +64 -0
- package/src/client/settings/PlanSettings.svelte +163 -8
- package/src/contract.ts +22 -3
package/dist/contract.d.ts
CHANGED
|
@@ -604,13 +604,28 @@ export declare const billingContract: {
|
|
|
604
604
|
}, z.core.$strip>;
|
|
605
605
|
};
|
|
606
606
|
}>, Record<never, never>>;
|
|
607
|
-
/**
|
|
607
|
+
/**
|
|
608
|
+
* Buy a plan, or move to a different one.
|
|
609
|
+
*
|
|
610
|
+
* Two different acts behind one procedure, because the caller does not know which it is: a
|
|
611
|
+
* workspace with no Stripe subscription needs Checkout (a card has to be collected), and one
|
|
612
|
+
* that already has a subscription needs its existing subscription repriced — opening a second
|
|
613
|
+
* Checkout there leaves the first subscription running and bills the customer twice.
|
|
614
|
+
*
|
|
615
|
+
* `changed` says which happened. When it is true the plan is already live and `url` is simply
|
|
616
|
+
* where to send the person back to; when it is false `url` is Stripe's hosted Checkout.
|
|
617
|
+
*
|
|
618
|
+
* `returnPath` is the workspace-relative path to come back to, exactly as `portal` takes it —
|
|
619
|
+
* billing knows workspace ids and not slugs, so the caller supplies the route.
|
|
620
|
+
*/
|
|
608
621
|
checkout: import("@orpc/contract").ContractProcedureBuilderWithInputOutput<z.ZodObject<{
|
|
609
622
|
workspaceId: z.core.$ZodBranded<z.ZodUUID, "WorkspaceId", "out">;
|
|
610
623
|
planSlug: z.ZodString;
|
|
611
624
|
seats: z.ZodOptional<z.ZodNumber>;
|
|
625
|
+
returnPath: z.ZodDefault<z.ZodString>;
|
|
612
626
|
}, z.core.$strip>, z.ZodObject<{
|
|
613
627
|
url: z.ZodString;
|
|
628
|
+
changed: z.ZodDefault<z.ZodBoolean>;
|
|
614
629
|
}, z.core.$strip>, import("@orpc/contract").MergedErrorMap<Record<never, never>, {
|
|
615
630
|
BAD_REQUEST: {
|
|
616
631
|
data: z.ZodOptional<z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>>;
|
package/dist/contract.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"contract.d.ts","sourceRoot":"","sources":["../src/contract.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAEvB,eAAO,MAAM,SAAS,YAAY,CAAA;AAElC;;;;;;;;;GASG;AACH,eAAO,MAAM,UAAU;;;;;;;iBASrB,CAAA;AACF,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,UAAU,CAAC,CAAA;AAEnD;;;;;;GAMG;AACH,eAAO,MAAM,eAAe;;;;;;;iBAO1B,CAAA;AACF,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,CAAA;AAE7D,eAAO,MAAM,eAAe;;;EAA4B,CAAA;AACxD,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,CAAA;AAE7D,eAAO,MAAM,IAAI;;;;;;;;;;;;;;;;;;;;;;;;;;;iBA0Bf,CAAA;AACF,MAAM,MAAM,IAAI,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,IAAI,CAAC,CAAA;AAEvC;;;;GAIG;AACH,eAAO,MAAM,UAAU;;;;;;;;;;;;;;;;;;;;;;iBAWU,CAAA;AACjC,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,UAAU,CAAC,CAAA;AAEnD,eAAO,MAAM,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;iBAErB,CAAA;AACF,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,UAAU,CAAC,CAAA;AAEnD;;;;GAIG;AACH,eAAO,MAAM,kBAAkB;;;;;;EAAsE,CAAA;AACrG,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAA;AAEnE,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;;;iBAavB,CAAA;AACF,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,YAAY,CAAC,CAAA;AAEvD,eAAO,MAAM,KAAK;;;;iBAIhB,CAAA;AACF,MAAM,MAAM,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,KAAK,CAAC,CAAA;AAEzC,8EAA8E;AAC9E,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAQ3B,CAAA;AACF,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAA;AAE/D,eAAO,MAAM,OAAO;;;;;;;;;;;;iBAYlB,CAAA;AACF,MAAM,MAAM,OAAO,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,OAAO,CAAC,CAAA;AAE7C,iFAAiF;AACjF,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;iBAkB5B,CAAA;AACF,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAA;AAIjE,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QAMxB;;;WAGG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QA2BH,
|
|
1
|
+
{"version":3,"file":"contract.d.ts","sourceRoot":"","sources":["../src/contract.ts"],"names":[],"mappings":"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"}
|
package/dist/contract.js
CHANGED
|
@@ -189,11 +189,28 @@ export const billingContract = {
|
|
|
189
189
|
.route({ method: 'GET', path: '/subscription/invoices', tags: ['billing'] })
|
|
190
190
|
.input(ws.extend(PageInput.shape))
|
|
191
191
|
.output(page(Invoice)),
|
|
192
|
-
/**
|
|
192
|
+
/**
|
|
193
|
+
* Buy a plan, or move to a different one.
|
|
194
|
+
*
|
|
195
|
+
* Two different acts behind one procedure, because the caller does not know which it is: a
|
|
196
|
+
* workspace with no Stripe subscription needs Checkout (a card has to be collected), and one
|
|
197
|
+
* that already has a subscription needs its existing subscription repriced — opening a second
|
|
198
|
+
* Checkout there leaves the first subscription running and bills the customer twice.
|
|
199
|
+
*
|
|
200
|
+
* `changed` says which happened. When it is true the plan is already live and `url` is simply
|
|
201
|
+
* where to send the person back to; when it is false `url` is Stripe's hosted Checkout.
|
|
202
|
+
*
|
|
203
|
+
* `returnPath` is the workspace-relative path to come back to, exactly as `portal` takes it —
|
|
204
|
+
* billing knows workspace ids and not slugs, so the caller supplies the route.
|
|
205
|
+
*/
|
|
193
206
|
checkout: baseContract
|
|
194
207
|
.route({ method: 'POST', path: '/subscription/checkout', tags: ['billing'] })
|
|
195
|
-
.input(ws.extend({
|
|
196
|
-
|
|
208
|
+
.input(ws.extend({
|
|
209
|
+
planSlug: z.string(),
|
|
210
|
+
seats: z.number().int().positive().optional(),
|
|
211
|
+
returnPath: z.string().default('/'),
|
|
212
|
+
}))
|
|
213
|
+
.output(z.object({ url: z.string(), changed: z.boolean().default(false) })),
|
|
197
214
|
/** Stripe's own billing portal: payment method, cancellation, invoice download. */
|
|
198
215
|
portal: baseContract
|
|
199
216
|
.route({ method: 'POST', path: '/subscription/portal', tags: ['billing'] })
|
package/dist/contract.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"contract.js","sourceRoot":"","sources":["../src/contract.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"contract.js","sourceRoot":"","sources":["../src/contract.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"AAYA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAWvB,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAC3C,cAAc,aAAa,CAAA;AAC3B,OAAO,KAAK,mBAAmB,MAAM,4BAA4B,CAAA;AACjE,OAAO,KAAK,YAAY,MAAM,qBAAqB,CAAA;AACnD,OAAO,KAAK,aAAa,MAAM,sBAAsB,CAAA;AACrD,OAAO,KAAK,oBAAoB,MAAM,6BAA6B,CAAA;AACnE,OAAO,KAAK,YAAY,MAAM,qBAAqB,CAAA;AAiBnD,eAAO,MAAM,aAAa,gHAkRxB,CAAA;AAEF,eAAe,aAAa,CAAA"}
|
package/dist/server/index.js
CHANGED
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
import { dirname, join } from 'node:path';
|
|
2
2
|
import { fileURLToPath } from 'node:url';
|
|
3
3
|
import { WorkspaceId } from '@kernhq/contracts';
|
|
4
|
-
import { defineModule, defineServerModule, KernError, packageVersion } from '@kernhq/kernel';
|
|
5
|
-
import { and, eq, isNotNull, lte } from 'drizzle-orm';
|
|
4
|
+
import { defineModule, defineServerModule, httpStatusFor, KernError, packageVersion, } from '@kernhq/kernel';
|
|
5
|
+
import { and, eq, isNotNull, isNull, lte } from 'drizzle-orm';
|
|
6
6
|
import { z } from 'zod';
|
|
7
7
|
import { billingContract, billingEvents, billingPermissions, MODULE_ID } from '../contract.js';
|
|
8
8
|
import { billingRouter } from './router.js';
|
|
9
9
|
import { schema, subscriptions } from './schema.js';
|
|
10
|
+
import { assertDefaultPlan, seedPlansFromFile } from './services/catalogue.js';
|
|
10
11
|
import * as entitlements from './services/entitlements.js';
|
|
12
|
+
import * as plansSvc from './services/plans.js';
|
|
11
13
|
import * as stripeSvc from './services/stripe.js';
|
|
12
14
|
import * as subsSvc from './services/subscriptions.js';
|
|
13
15
|
import * as usageSvc from './services/usage.js';
|
|
@@ -46,6 +48,72 @@ export const billingModule = defineServerModule({
|
|
|
46
48
|
migrationsFolder: join(dirname(fileURLToPath(import.meta.url)), '../../migrations'),
|
|
47
49
|
contract: billingContract,
|
|
48
50
|
router: billingRouter,
|
|
51
|
+
/**
|
|
52
|
+
* The one thing oRPC cannot carry: Stripe picks the URL, the method and the content type, and the
|
|
53
|
+
* signature covers the exact bytes it sent. `raw: true` is what hands the handler those bytes —
|
|
54
|
+
* anything that parses and re-encodes the JSON breaks every signature, and breaks it in a way that
|
|
55
|
+
* reads as a wrong secret.
|
|
56
|
+
*
|
|
57
|
+
* `/webhook` under billing's prefix, so `https://<instance>/api/billing/webhook` — which is the
|
|
58
|
+
* URL `selfhost/.env.example` has been telling operators to give Stripe all along, and which
|
|
59
|
+
* answered 404 because nothing was ever mounted here.
|
|
60
|
+
*
|
|
61
|
+
* No principal, no permission and no workspace: Stripe is not a Kern caller. The signature is the
|
|
62
|
+
* authentication, and it is checked before anything touches the database.
|
|
63
|
+
*/
|
|
64
|
+
httpRoutes: [
|
|
65
|
+
{
|
|
66
|
+
method: 'POST',
|
|
67
|
+
path: '/webhook',
|
|
68
|
+
raw: true,
|
|
69
|
+
// Stripe's own limit for an event body; well under the server's 25 MB, and it means a body
|
|
70
|
+
// that could not be a Stripe event is refused before it is buffered.
|
|
71
|
+
bodyLimit: 1024 * 1024,
|
|
72
|
+
handler: async ({ kernel, request, reply, body }) => {
|
|
73
|
+
const signature = request.headers['stripe-signature'];
|
|
74
|
+
if (typeof signature !== 'string' || !signature)
|
|
75
|
+
return reply.status(400).send({ error: 'Missing the stripe-signature header' });
|
|
76
|
+
try {
|
|
77
|
+
const result = await stripeSvc.handleWebhook(kernel, body, signature);
|
|
78
|
+
return { received: true, ...result };
|
|
79
|
+
}
|
|
80
|
+
catch (err) {
|
|
81
|
+
// A 4xx tells Stripe to stop retrying, so only the two failures a retry cannot fix get
|
|
82
|
+
// one: a body that is not from Stripe, and an instance with no webhook secret. Anything
|
|
83
|
+
// else — the database being down, the bus being unreachable — is 500 on purpose, because
|
|
84
|
+
// Stripe retrying for three days is exactly what should happen to an event we dropped.
|
|
85
|
+
if (err instanceof KernError && (err.code === 'BAD_REQUEST' || err.code === 'CONFLICT')) {
|
|
86
|
+
kernel.log.warn({ err: err.message }, 'billing: refused a Stripe webhook');
|
|
87
|
+
return reply.status(httpStatusFor(err.code)).send({ error: err.message });
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* 500, set explicitly, and never by rethrowing.
|
|
91
|
+
*
|
|
92
|
+
* Fastify answers a thrown error with that error's own `statusCode`, and a Stripe SDK
|
|
93
|
+
* error carries the status *Stripe's API* returned — so a `StripeInvalidRequestError` from
|
|
94
|
+
* `subscriptions.retrieve` came back to Stripe as **404**. Stripe reads 4xx as "delivered,
|
|
95
|
+
* do not send this again" and stops retrying, which loses the event permanently: the same
|
|
96
|
+
* failure the claim-and-release above exists to prevent, arriving by a different door.
|
|
97
|
+
* Caught by a test that made the retrieve fail and asserted the status.
|
|
98
|
+
*
|
|
99
|
+
* The message is not passed on either. Stripe does not read it, and it is the internals of
|
|
100
|
+
* this instance.
|
|
101
|
+
*/
|
|
102
|
+
kernel.log.error({ err: String(err) }, 'billing: a Stripe webhook failed; Stripe will retry');
|
|
103
|
+
return reply.status(500).send({ error: 'The webhook could not be applied' });
|
|
104
|
+
}
|
|
105
|
+
},
|
|
106
|
+
},
|
|
107
|
+
],
|
|
108
|
+
/**
|
|
109
|
+
* Seed the catalogue before anything reads it, then refuse to start an instance that sells
|
|
110
|
+
* subscriptions and has no default plan to sell — see `services/catalogue.ts` for why one of
|
|
111
|
+
* those two conditions throws and the other only shouts.
|
|
112
|
+
*/
|
|
113
|
+
onBoot: async (kernel) => {
|
|
114
|
+
await seedPlansFromFile(kernel);
|
|
115
|
+
await assertDefaultPlan(kernel);
|
|
116
|
+
},
|
|
49
117
|
procedures: {
|
|
50
118
|
/**
|
|
51
119
|
* The one the kernel calls. Its mere presence on the broker is what switches limits on for the
|
|
@@ -105,10 +173,18 @@ export const billingModule = defineServerModule({
|
|
|
105
173
|
const slug = process.env.KERN_DEFAULT_PLAN_SLUG;
|
|
106
174
|
if (!slug)
|
|
107
175
|
return;
|
|
108
|
-
const
|
|
109
|
-
const plan = await bySlug(kernel, slug);
|
|
176
|
+
const plan = await plansSvc.bySlug(kernel, slug);
|
|
110
177
|
if (!plan) {
|
|
111
|
-
|
|
178
|
+
const message = `billing: KERN_DEFAULT_PLAN_SLUG names "${slug}", which is not a plan on this instance`;
|
|
179
|
+
// On an instance that takes payments this is not a warning, it is a workspace being handed
|
|
180
|
+
// the whole product for nothing — so it throws, the bus retries, and the workspace picks up
|
|
181
|
+
// its subscription as soon as the plan exists. An instance with no Stripe key is a
|
|
182
|
+
// self-hosted Kern, where unlimited is the intended answer and nothing should fail.
|
|
183
|
+
if (stripeSvc.paymentsEnabled()) {
|
|
184
|
+
kernel.log.error({ slug, workspaceId: p.workspaceId }, message);
|
|
185
|
+
throw KernError.conflict(message, 'billing.plan.default_missing');
|
|
186
|
+
}
|
|
187
|
+
kernel.log.warn({ slug }, message);
|
|
112
188
|
return;
|
|
113
189
|
}
|
|
114
190
|
const trialEndsAt = new Date();
|
|
@@ -141,10 +217,54 @@ export const billingModule = defineServerModule({
|
|
|
141
217
|
}
|
|
142
218
|
},
|
|
143
219
|
},
|
|
220
|
+
{
|
|
221
|
+
/**
|
|
222
|
+
* End a trial that nobody ever put a card behind.
|
|
223
|
+
*
|
|
224
|
+
* Signup writes `status: 'trialing'` with a `trialEndsAt` and — until this job existed —
|
|
225
|
+
* absolutely nothing read that column again. `trialing` is an entitled status, so every
|
|
226
|
+
* workspace that ever signed up stayed on the trial plan for ever, free, with no card.
|
|
227
|
+
*
|
|
228
|
+
* A trial with a `stripeSubscriptionId` behind it is **not** this job's business: Stripe owns
|
|
229
|
+
* that clock and says what happened to it through `customer.subscription.updated`. Expiring
|
|
230
|
+
* it here would race Stripe and suspend a workspace whose card was about to be charged.
|
|
231
|
+
*/
|
|
232
|
+
name: 'billing.expire-trials',
|
|
233
|
+
cron: '23 * * * *',
|
|
234
|
+
handler: async (_input, { kernel }) => {
|
|
235
|
+
const due = await kernel.database.db
|
|
236
|
+
.select({ workspaceId: subscriptions.workspaceId })
|
|
237
|
+
.from(subscriptions)
|
|
238
|
+
.where(and(eq(subscriptions.status, 'trialing'), isNotNull(subscriptions.trialEndsAt), lte(subscriptions.trialEndsAt, new Date()), isNull(subscriptions.stripeSubscriptionId)));
|
|
239
|
+
for (const row of due) {
|
|
240
|
+
// Suspended, not cancelled: the workspace is read-only and everything in it survives, so
|
|
241
|
+
// paying — or an admin extending the trial — brings it straight back. See ADR 0003 §6.
|
|
242
|
+
await subsSvc.upsert(kernel, row.workspaceId, { status: 'suspended', graceEndsAt: null });
|
|
243
|
+
await kernel.emit(billingEvents.subscriptionSuspended, {
|
|
244
|
+
workspaceId: row.workspaceId,
|
|
245
|
+
reason: 'the trial ended and no subscription was started',
|
|
246
|
+
}, { workspaceId: row.workspaceId });
|
|
247
|
+
kernel.log.info({ workspaceId: row.workspaceId }, 'billing: trial ended, workspace suspended');
|
|
248
|
+
}
|
|
249
|
+
},
|
|
250
|
+
},
|
|
144
251
|
{
|
|
145
252
|
name: 'billing.close-grace-periods',
|
|
146
253
|
cron: '7 * * * *',
|
|
147
254
|
handler: async (_input, { kernel }) => {
|
|
255
|
+
/**
|
|
256
|
+
* A `past_due` row with no clock cannot be closed by the query below, so it would stay
|
|
257
|
+
* entitled for ever. That is how every row written before the grace period stopped being
|
|
258
|
+
* wiped by `customer.subscription.updated` looks, and starting the clock here is what lets
|
|
259
|
+
* those rows reach a decision instead of sitting past due indefinitely.
|
|
260
|
+
*/
|
|
261
|
+
const started = await kernel.database.db
|
|
262
|
+
.update(subscriptions)
|
|
263
|
+
.set({ graceEndsAt: stripeSvc.graceFrom(), updatedAt: new Date() })
|
|
264
|
+
.where(and(eq(subscriptions.status, 'past_due'), isNull(subscriptions.graceEndsAt)))
|
|
265
|
+
.returning({ workspaceId: subscriptions.workspaceId });
|
|
266
|
+
if (started.length)
|
|
267
|
+
kernel.log.warn({ workspaces: started.map((r) => r.workspaceId) }, 'billing: found past-due workspaces with no grace period and started one');
|
|
148
268
|
const due = await kernel.database.db
|
|
149
269
|
.select({ workspaceId: subscriptions.workspaceId })
|
|
150
270
|
.from(subscriptions)
|
package/dist/server/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AACzC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;AACxC,OAAO,EAAkB,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAC/D,OAAO,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AACzC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;AACxC,OAAO,EAAkB,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAC/D,OAAO,EACL,YAAY,EACZ,kBAAkB,EAClB,aAAa,EACb,SAAS,EAET,cAAc,GACf,MAAM,gBAAgB,CAAA;AACvB,OAAO,EAAE,GAAG,EAAE,EAAE,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,aAAa,CAAA;AAC7D,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AACvB,OAAO,EAAE,eAAe,EAAE,aAAa,EAAE,kBAAkB,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAC9F,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAC3C,OAAO,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AACnD,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAA;AAC9E,OAAO,KAAK,YAAY,MAAM,4BAA4B,CAAA;AAC1D,OAAO,KAAK,QAAQ,MAAM,qBAAqB,CAAA;AAC/C,OAAO,KAAK,SAAS,MAAM,sBAAsB,CAAA;AACjD,OAAO,KAAK,OAAO,MAAM,6BAA6B,CAAA;AACtD,OAAO,KAAK,QAAQ,MAAM,qBAAqB,CAAA;AAE/C,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAC3C,cAAc,aAAa,CAAA;AAC3B,OAAO,KAAK,mBAAmB,MAAM,4BAA4B,CAAA;AACjE,OAAO,KAAK,YAAY,MAAM,qBAAqB,CAAA;AACnD,OAAO,KAAK,aAAa,MAAM,sBAAsB,CAAA;AACrD,OAAO,KAAK,oBAAoB,MAAM,6BAA6B,CAAA;AACnE,OAAO,KAAK,YAAY,MAAM,qBAAqB,CAAA;AAEnD;;;;GAIG;AACH,SAAS,cAAc,CAAC,SAAoB;IAC1C,IAAI,SAAS,CAAC,IAAI,KAAK,SAAS,IAAI,CAAC,SAAS,CAAC,aAAa;QAAE,MAAM,SAAS,CAAC,SAAS,EAAE,CAAA;AAC3F,CAAC;AAED,0FAA0F;AAC1F,KAAK,UAAU,eAAe,CAAC,MAAc;IAC3C,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,IAAI,CAAwB,sBAAsB,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAA;IAChG,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAA;AAC9B,CAAC;AAED,MAAM,CAAC,MAAM,aAAa,GAAG,kBAAkB,CAAC;IAC9C,UAAU,EAAE,YAAY,CAAC;QACvB,EAAE,EAAE,SAAS;QACb,IAAI,EAAE,SAAS;QACf,OAAO,EAAE,cAAc,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC;QACxC,WAAW,EAAE,oFAAoF;QACjG,IAAI,EAAE,aAAa;QACnB,WAAW,EAAE,kBAAkB;QAC/B,MAAM,EAAE,aAAa;KACtB,CAAC;IACF,MAAM;IACN,gBAAgB,EAAE,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,kBAAkB,CAAC;IACnF,QAAQ,EAAE,eAAe;IACzB,MAAM,EAAE,aAAa;IAErB;;;;;;;;;;;;OAYG;IACH,UAAU,EAAE;QACV;YACE,MAAM,EAAE,MAAM;YACd,IAAI,EAAE,UAAU;YAChB,GAAG,EAAE,IAAI;YACT,2FAA2F;YAC3F,qEAAqE;YACrE,SAAS,EAAE,IAAI,GAAG,IAAI;YACtB,OAAO,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,EAAE;gBAClD,MAAM,SAAS,GAAG,OAAO,CAAC,OAAO,CAAC,kBAAkB,CAAC,CAAA;gBACrD,IAAI,OAAO,SAAS,KAAK,QAAQ,IAAI,CAAC,SAAS;oBAC7C,OAAO,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,qCAAqC,EAAE,CAAC,CAAA;gBACjF,IAAI,CAAC;oBACH,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,aAAa,CAAC,MAAM,EAAE,IAAc,EAAE,SAAS,CAAC,CAAA;oBAC/E,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,GAAG,MAAM,EAAE,CAAA;gBACtC,CAAC;gBAAC,OAAO,GAAG,EAAE,CAAC;oBACb,uFAAuF;oBACvF,wFAAwF;oBACxF,yFAAyF;oBACzF,uFAAuF;oBACvF,IAAI,GAAG,YAAY,SAAS,IAAI,CAAC,GAAG,CAAC,IAAI,KAAK,aAAa,IAAI,GAAG,CAAC,IAAI,KAAK,UAAU,CAAC,EAAE,CAAC;wBACxF,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,GAAG,CAAC,OAAO,EAAE,EAAE,mCAAmC,CAAC,CAAA;wBAC1E,OAAO,KAAK,CAAC,MAAM,CAAC,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,GAAG,CAAC,OAAO,EAAE,CAAC,CAAA;oBAC3E,CAAC;oBACD;;;;;;;;;;;;uBAYG;oBACH,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,GAAG,EAAE,MAAM,CAAC,GAAG,CAAC,EAAE,EAAE,qDAAqD,CAAC,CAAA;oBAC7F,OAAO,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,kCAAkC,EAAE,CAAC,CAAA;gBAC9E,CAAC;YACH,CAAC;SACF;KACF;IAED;;;;OAIG;IACH,MAAM,EAAE,KAAK,EAAE,MAAc,EAAE,EAAE;QAC/B,MAAM,iBAAiB,CAAC,MAAM,CAAC,CAAA;QAC/B,MAAM,iBAAiB,CAAC,MAAM,CAAC,CAAA;IACjC,CAAC;IAED,UAAU,EAAE;QACV;;;;WAIG;QACH,kBAAkB,EAAE;YAClB,KAAK,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,WAAW,EAAE,WAAW,EAAE,CAAC;YAC7C,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,EAAE,EAAE;gBAC9C,cAAc,CAAC,SAAS,CAAC,CAAA;gBACzB,OAAO,YAAY,CAAC,OAAO,CAAC,MAAM,EAAE,KAAK,CAAC,WAAW,CAAC,CAAA;YACxD,CAAC;SACF;QACD,wFAAwF;QACxF,iBAAiB,EAAE;YACjB,KAAK,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,WAAW,EAAE,WAAW,EAAE,CAAC;YAC7C,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,EAAE,EAAE;gBAC9C,cAAc,CAAC,SAAS,CAAC,CAAA;gBACzB,OAAO,QAAQ,CAAC,SAAS,CAAC,MAAM,EAAE,KAAK,CAAC,WAAW,CAAC,CAAA;YACtD,CAAC;SACF;KACF;IAED,aAAa,EAAE;QACb;;;;;;;;WAQG;QACH,eAAe,EAAE,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,EAAE;YACnC,MAAM,CAAC,GAAG,CAAC,CAAC,OAAmC,CAAA;YAC/C,IAAI,CAAC,CAAC,CAAC,WAAW;gBAAE,OAAM;YAC1B,MAAM,KAAK,GAAG,MAAM,QAAQ,CAAC,YAAY,CAAC,MAAM,EAAE,CAAC,CAAC,WAAW,CAAC,CAAA;YAChE,MAAM,SAAS,CAAC,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,WAAW,EAAE,KAAK,CAAC,CAAA;QACzD,CAAC;QACD,iBAAiB,EAAE,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,EAAE;YACrC,MAAM,CAAC,GAAG,CAAC,CAAC,OAAiD,CAAA;YAC7D,IAAI,OAAO,CAAC,CAAC,IAAI,KAAK,QAAQ;gBAAE,OAAM;YACtC,MAAM,QAAQ,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,WAAW,EAAE,EAAE,YAAY,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAA;QACtE,CAAC;QACD,mBAAmB,EAAE,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,EAAE;YACvC,MAAM,CAAC,GAAG,CAAC,CAAC,OAAgD,CAAA;YAC5D,MAAM,QAAQ,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,WAAW,EAAE,EAAE,YAAY,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAA;QACvE,CAAC;QACD;;;;WAIG;QACH,wBAAwB,EAAE,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,EAAE;YAC5C,MAAM,CAAC,GAAG,CAAC,CAAC,OAAkC,CAAA;YAC9C,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,sBAAsB,CAAA;YAC/C,IAAI,CAAC,IAAI;gBAAE,OAAM;YACjB,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,CAAA;YAChD,IAAI,CAAC,IAAI,EAAE,CAAC;gBACV,MAAM,OAAO,GAAG,0CAA0C,IAAI,yCAAyC,CAAA;gBACvG,2FAA2F;gBAC3F,4FAA4F;gBAC5F,mFAAmF;gBACnF,oFAAoF;gBACpF,IAAI,SAAS,CAAC,eAAe,EAAE,EAAE,CAAC;oBAChC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC,CAAC,WAAW,EAAE,EAAE,OAAO,CAAC,CAAA;oBAC/D,MAAM,SAAS,CAAC,QAAQ,CAAC,OAAO,EAAE,8BAA8B,CAAC,CAAA;gBACnE,CAAC;gBACD,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,EAAE,OAAO,CAAC,CAAA;gBAClC,OAAM;YACR,CAAC;YACD,MAAM,WAAW,GAAG,IAAI,IAAI,EAAE,CAAA;YAC9B,WAAW,CAAC,UAAU,CAAC,WAAW,CAAC,UAAU,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,CAAA;YACjE,MAAM,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,WAAW,EAAE;gBAC1C,MAAM,EAAE,IAAI,CAAC,EAAE;gBACf,MAAM,EAAE,IAAI,CAAC,SAAS,GAAG,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,QAAQ;gBAClD,WAAW,EAAE,IAAI,CAAC,SAAS,GAAG,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI;aACrD,CAAC,CAAA;QACJ,CAAC;KACF;IAED,IAAI,EAAE;QACJ;YACE,IAAI,EAAE,yBAAyB;YAC/B,mFAAmF;YACnF,IAAI,EAAE,YAAY;YAClB,OAAO,EAAE,KAAK,EAAE,MAAe,EAAE,EAAE,MAAM,EAAsB,EAAE,EAAE;gBACjE,KAAK,MAAM,WAAW,IAAI,MAAM,eAAe,CAAC,MAAM,CAAC,EAAE,CAAC;oBACxD,IAAI,CAAC;wBACH,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,QAAQ,CAAC,SAAS,CAAC,MAAM,EAAE,WAAW,CAAC,CAAA;wBAC/D,qFAAqF;wBACrF,oFAAoF;wBACpF,wBAAwB;wBACxB,IAAI,KAAK,CAAC,KAAK,KAAK,CAAC,IAAI,KAAK,CAAC,YAAY,KAAK,CAAC;4BAC/C,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,WAAW,EAAE,KAAK,EAAE,EAAE,qCAAqC,CAAC,CAAA;oBAClF,CAAC;oBAAC,OAAO,GAAG,EAAE,CAAC;wBACb,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,MAAM,CAAC,GAAG,CAAC,EAAE,WAAW,EAAE,EAAE,2BAA2B,CAAC,CAAA;oBACjF,CAAC;gBACH,CAAC;YACH,CAAC;SACF;QACD;YACE;;;;;;;;;;eAUG;YACH,IAAI,EAAE,uBAAuB;YAC7B,IAAI,EAAE,YAAY;YAClB,OAAO,EAAE,KAAK,EAAE,MAAe,EAAE,EAAE,MAAM,EAAsB,EAAE,EAAE;gBACjE,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,QAAQ,CAAC,EAAE;qBACjC,MAAM,CAAC,EAAE,WAAW,EAAE,aAAa,CAAC,WAAW,EAAE,CAAC;qBAClD,IAAI,CAAC,aAAa,CAAC;qBACnB,KAAK,CACJ,GAAG,CACD,EAAE,CAAC,aAAa,CAAC,MAAM,EAAE,UAAU,CAAC,EACpC,SAAS,CAAC,aAAa,CAAC,WAAW,CAAC,EACpC,GAAG,CAAC,aAAa,CAAC,WAAW,EAAE,IAAI,IAAI,EAAE,CAAC,EAC1C,MAAM,CAAC,aAAa,CAAC,oBAAoB,CAAC,CAC3C,CACF,CAAA;gBACH,KAAK,MAAM,GAAG,IAAI,GAAG,EAAE,CAAC;oBACtB,yFAAyF;oBACzF,uFAAuF;oBACvF,MAAM,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,WAAW,EAAE,EAAE,MAAM,EAAE,WAAW,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC,CAAA;oBACzF,MAAM,MAAM,CAAC,IAAI,CACf,aAAa,CAAC,qBAAqB,EACnC;wBACE,WAAW,EAAE,GAAG,CAAC,WAA0B;wBAC3C,MAAM,EAAE,iDAAiD;qBAC1D,EACD,EAAE,WAAW,EAAE,GAAG,CAAC,WAAW,EAAE,CACjC,CAAA;oBACD,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,WAAW,EAAE,GAAG,CAAC,WAAW,EAAE,EAAE,2CAA2C,CAAC,CAAA;gBAChG,CAAC;YACH,CAAC;SACF;QACD;YACE,IAAI,EAAE,6BAA6B;YACnC,IAAI,EAAE,WAAW;YACjB,OAAO,EAAE,KAAK,EAAE,MAAe,EAAE,EAAE,MAAM,EAAsB,EAAE,EAAE;gBACjE;;;;;mBAKG;gBACH,MAAM,OAAO,GAAG,MAAM,MAAM,CAAC,QAAQ,CAAC,EAAE;qBACrC,MAAM,CAAC,aAAa,CAAC;qBACrB,GAAG,CAAC,EAAE,WAAW,EAAE,SAAS,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,IAAI,EAAE,EAAE,CAAC;qBAClE,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,aAAa,CAAC,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,CAAC,aAAa,CAAC,WAAW,CAAC,CAAC,CAAC;qBACnF,SAAS,CAAC,EAAE,WAAW,EAAE,aAAa,CAAC,WAAW,EAAE,CAAC,CAAA;gBACxD,IAAI,OAAO,CAAC,MAAM;oBAChB,MAAM,CAAC,GAAG,CAAC,IAAI,CACb,EAAE,UAAU,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,CAAC,EAAE,EACjD,yEAAyE,CAC1E,CAAA;gBAEH,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,QAAQ,CAAC,EAAE;qBACjC,MAAM,CAAC,EAAE,WAAW,EAAE,aAAa,CAAC,WAAW,EAAE,CAAC;qBAClD,IAAI,CAAC,aAAa,CAAC;qBACnB,KAAK,CACJ,GAAG,CACD,EAAE,CAAC,aAAa,CAAC,MAAM,EAAE,UAAU,CAAC,EACpC,SAAS,CAAC,aAAa,CAAC,WAAW,CAAC,EACpC,GAAG,CAAC,aAAa,CAAC,WAAW,EAAE,IAAI,IAAI,EAAE,CAAC,CAC3C,CACF,CAAA;gBACH,KAAK,MAAM,GAAG,IAAI,GAAG,EAAE,CAAC;oBACtB,MAAM,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,WAAW,EAAE,EAAE,MAAM,EAAE,WAAW,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC,CAAA;oBACzF,MAAM,MAAM,CAAC,IAAI,CACf,aAAa,CAAC,qBAAqB,EACnC;wBACE,WAAW,EAAE,GAAG,CAAC,WAA0B;wBAC3C,MAAM,EAAE,+CAA+C;qBACxD,EACD,EAAE,WAAW,EAAE,GAAG,CAAC,WAAW,EAAE,CACjC,CAAA;oBACD,MAAM,CAAC,GAAG,CAAC,IAAI,CACb,EAAE,WAAW,EAAE,GAAG,CAAC,WAAW,EAAE,EAChC,kDAAkD,CACnD,CAAA;gBACH,CAAC;YACH,CAAC;SACF;KACF;CACF,CAAC,CAAA;AAEF,eAAe,aAAa,CAAA"}
|
package/dist/server/router.d.ts
CHANGED
|
@@ -372,19 +372,21 @@ export declare function billingRouter(kernel: Kernel): {
|
|
|
372
372
|
}, import("zod/v4/core").$strip>;
|
|
373
373
|
};
|
|
374
374
|
}>>, Record<never, never>>;
|
|
375
|
-
checkout: import("@orpc/server").Procedure<import("@orpc/server").MergedInitialContext<import("@kernhq/kernel").RequestContext & Record<never, never>, import("@kernhq/kernel").RequestContext & Record<never, never> & Omit<import("@kernhq/kernel").RequestContext & Record<never, never>, keyof import("@kernhq/kernel").RequestContext> & Omit<import("@kernhq/kernel").RequestContext & Record<never, never>, "workspaceId" | "kernel" | "principal" | "requestId" | "ip" | "headers">, import("@kernhq/kernel").RequestContext>, Omit<import("@orpc/server").MergedCurrentContext<import("@kernhq/kernel").RequestContext, {
|
|
375
|
+
checkout: import("@orpc/server").Procedure<import("@orpc/server").MergedInitialContext<import("@kernhq/kernel").RequestContext & Record<never, never>, import("@kernhq/kernel").RequestContext & Record<never, never> & Omit<import("@kernhq/kernel").RequestContext & Record<never, never>, keyof import("@kernhq/kernel").RequestContext> & Omit<import("@kernhq/kernel").RequestContext & Record<never, never>, "workspaceId" | "kernel" | "principal" | "requestId" | "ip" | "headers">, import("@kernhq/kernel").RequestContext>, Omit<import("@orpc/server").MergedCurrentContext<import("@orpc/server").MergedCurrentContext<import("@kernhq/kernel").RequestContext, {
|
|
376
376
|
workspaceId: string;
|
|
377
377
|
kernel: Kernel;
|
|
378
378
|
principal: import("@kernhq/contracts").Principal;
|
|
379
379
|
requestId: string;
|
|
380
380
|
ip: string;
|
|
381
381
|
headers: Record<string, string | string[] | undefined>;
|
|
382
|
-
}>, never> & Record<never, never>, import("zod").ZodObject<{
|
|
382
|
+
}>, Record<never, never>>, never> & Record<never, never>, import("zod").ZodObject<{
|
|
383
383
|
workspaceId: import("zod/v4/core").$ZodBranded<import("zod").ZodUUID, "WorkspaceId", "out">;
|
|
384
384
|
planSlug: import("zod").ZodString;
|
|
385
385
|
seats: import("zod").ZodOptional<import("zod").ZodNumber>;
|
|
386
|
+
returnPath: import("zod").ZodDefault<import("zod").ZodString>;
|
|
386
387
|
}, import("zod/v4/core").$strip>, import("zod").ZodObject<{
|
|
387
388
|
url: import("zod").ZodString;
|
|
389
|
+
changed: import("zod").ZodDefault<import("zod").ZodBoolean>;
|
|
388
390
|
}, import("zod/v4/core").$strip>, import("@orpc/server").MergedErrorMap<Record<never, never>, import("@orpc/server").MergedErrorMap<Record<never, never>, {
|
|
389
391
|
BAD_REQUEST: {
|
|
390
392
|
data: import("zod").ZodOptional<import("zod").ZodOptional<import("zod").ZodRecord<import("zod").ZodString, import("zod").ZodUnknown>>>;
|
|
@@ -408,14 +410,14 @@ export declare function billingRouter(kernel: Kernel): {
|
|
|
408
410
|
}, import("zod/v4/core").$strip>;
|
|
409
411
|
};
|
|
410
412
|
}>>, Record<never, never>>;
|
|
411
|
-
portal: import("@orpc/server").Procedure<import("@orpc/server").MergedInitialContext<import("@kernhq/kernel").RequestContext & Record<never, never>, import("@kernhq/kernel").RequestContext & Record<never, never> & Omit<import("@kernhq/kernel").RequestContext & Record<never, never>, keyof import("@kernhq/kernel").RequestContext> & Omit<import("@kernhq/kernel").RequestContext & Record<never, never>, "workspaceId" | "kernel" | "principal" | "requestId" | "ip" | "headers">, import("@kernhq/kernel").RequestContext>, Omit<import("@orpc/server").MergedCurrentContext<import("@kernhq/kernel").RequestContext, {
|
|
413
|
+
portal: import("@orpc/server").Procedure<import("@orpc/server").MergedInitialContext<import("@kernhq/kernel").RequestContext & Record<never, never>, import("@kernhq/kernel").RequestContext & Record<never, never> & Omit<import("@kernhq/kernel").RequestContext & Record<never, never>, keyof import("@kernhq/kernel").RequestContext> & Omit<import("@kernhq/kernel").RequestContext & Record<never, never>, "workspaceId" | "kernel" | "principal" | "requestId" | "ip" | "headers">, import("@kernhq/kernel").RequestContext>, Omit<import("@orpc/server").MergedCurrentContext<import("@orpc/server").MergedCurrentContext<import("@kernhq/kernel").RequestContext, {
|
|
412
414
|
workspaceId: string;
|
|
413
415
|
kernel: Kernel;
|
|
414
416
|
principal: import("@kernhq/contracts").Principal;
|
|
415
417
|
requestId: string;
|
|
416
418
|
ip: string;
|
|
417
419
|
headers: Record<string, string | string[] | undefined>;
|
|
418
|
-
}>, never> & Record<never, never>, import("zod").ZodObject<{
|
|
420
|
+
}>, Record<never, never>>, never> & Record<never, never>, import("zod").ZodObject<{
|
|
419
421
|
workspaceId: import("zod/v4/core").$ZodBranded<import("zod").ZodUUID, "WorkspaceId", "out">;
|
|
420
422
|
returnPath: import("zod").ZodDefault<import("zod").ZodString>;
|
|
421
423
|
}, import("zod/v4/core").$strip>, import("zod").ZodObject<{
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../../src/server/router.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../../src/server/router.ts"],"names":[],"mappings":"AAAA,OAAO,EAAuB,KAAK,MAAM,EAAgC,MAAM,gBAAgB,CAAA;AAgC/F,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAiI3C"}
|
package/dist/server/router.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { o, requires, workspaceScoped } from '@kernhq/kernel';
|
|
1
|
+
import { allowWhileSuspended, o, requires, workspaceScoped } from '@kernhq/kernel';
|
|
2
2
|
import { implement, ORPCError } from '@orpc/server';
|
|
3
3
|
import { BILLING_PERMISSIONS, billingContract, billingEvents, MODULE_ID, PlanLimits } from '../contract.js';
|
|
4
4
|
import * as entitlements from './services/entitlements.js';
|
|
@@ -83,16 +83,27 @@ export function billingRouter(kernel) {
|
|
|
83
83
|
items: await subsSvc.listInvoices(kernel, input.workspaceId, input.limit),
|
|
84
84
|
nextCursor: null,
|
|
85
85
|
})),
|
|
86
|
+
/**
|
|
87
|
+
* `allowWhileSuspended` on both, and it is not a convenience.
|
|
88
|
+
*
|
|
89
|
+
* A suspended workspace is read-only, and these two POSTs are the only way out of it — one
|
|
90
|
+
* opens Checkout, the other opens Stripe's portal where the card is fixed. Gated, suspension
|
|
91
|
+
* would be a trap sprung on the exact customer trying to pay their way out of it, and only an
|
|
92
|
+
* operator could undo it.
|
|
93
|
+
*/
|
|
86
94
|
checkout: scoped.subscription.checkout
|
|
95
|
+
.use(allowWhileSuspended)
|
|
87
96
|
.use(requires(BILLING_PERMISSIONS.manage))
|
|
88
97
|
.handler(async ({ input, context }) => stripeSvc.checkout(kernel, {
|
|
89
98
|
workspaceId: input.workspaceId,
|
|
90
99
|
planSlug: input.planSlug,
|
|
91
100
|
seats: input.seats,
|
|
101
|
+
returnPath: input.returnPath,
|
|
92
102
|
email: context.principal.email ?? undefined,
|
|
93
103
|
baseUrl: kernel.env.KERN_BASE_URL,
|
|
94
104
|
})),
|
|
95
105
|
portal: scoped.subscription.portal
|
|
106
|
+
.use(allowWhileSuspended)
|
|
96
107
|
.use(requires(BILLING_PERMISSIONS.manage))
|
|
97
108
|
.handler(async ({ input }) => stripeSvc.portal(kernel, {
|
|
98
109
|
workspaceId: input.workspaceId,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"router.js","sourceRoot":"","sources":["../../src/server/router.ts"],"names":[],"mappings":"AAAA,OAAO,EAAe,CAAC,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAA;
|
|
1
|
+
{"version":3,"file":"router.js","sourceRoot":"","sources":["../../src/server/router.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { Kernel } from '@kernhq/kernel';
|
|
2
|
+
/**
|
|
3
|
+
* Create any plan in `KERN_PLANS_FILE` whose slug this instance does not have yet.
|
|
4
|
+
*
|
|
5
|
+
* **Create, never update.** A plan is data an instance admin edits — prices, limits, what the
|
|
6
|
+
* pricing page says — and an image that rewrote the catalogue on every boot would silently revert
|
|
7
|
+
* their work at the next deploy. So a slug that already exists is left exactly as it is, and the
|
|
8
|
+
* file is only ever the answer to "a fresh instance has no plans at all".
|
|
9
|
+
*
|
|
10
|
+
* Returns the slugs it created, so the boot log says what happened rather than that something did.
|
|
11
|
+
*/
|
|
12
|
+
export declare function seedPlansFromFile(kernel: Kernel): Promise<string[]>;
|
|
13
|
+
/**
|
|
14
|
+
* Refuse to start, or say loudly why every new workspace is about to be unlimited.
|
|
15
|
+
*
|
|
16
|
+
* Two conditions, and they are not equally recoverable:
|
|
17
|
+
*
|
|
18
|
+
* - **No `KERN_DEFAULT_PLAN_SLUG` on an instance with a Stripe key.** Pure configuration, fixable
|
|
19
|
+
* in the environment without the service running, and it means every single signup is unlimited.
|
|
20
|
+
* That one throws.
|
|
21
|
+
* - **A slug naming a plan that does not exist.** Also wrong, and it is what a brand-new instance
|
|
22
|
+
* looks like for as long as it takes somebody to create the plan — so refusing here would lock
|
|
23
|
+
* the operator out of the console they need in order to fix it. That one is an `error` in the log
|
|
24
|
+
* and a refusal on the path that matters, which is `core.workspace.created`.
|
|
25
|
+
*
|
|
26
|
+
* An instance with no Stripe key is a self-hosted Kern: unlimited is the correct and intended
|
|
27
|
+
* answer there, and nothing here fires.
|
|
28
|
+
*/
|
|
29
|
+
export declare function assertDefaultPlan(kernel: Kernel): Promise<void>;
|
|
30
|
+
//# sourceMappingURL=catalogue.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"catalogue.d.ts","sourceRoot":"","sources":["../../../src/server/services/catalogue.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAA;AAmB5C;;;;;;;;;GASG;AACH,wBAAsB,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CA4BzE;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAmBrE"}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { readFile } from 'node:fs/promises';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
import { UpsertPlan } from '../../contract.js';
|
|
4
|
+
import * as plans from './plans.js';
|
|
5
|
+
import { paymentsEnabled } from './stripe.js';
|
|
6
|
+
/**
|
|
7
|
+
* Getting the plan catalogue onto an instance, and refusing to pretend one is there when it is not.
|
|
8
|
+
*
|
|
9
|
+
* Both halves exist for the same failure: a new workspace whose default plan is missing gets **no
|
|
10
|
+
* subscription row at all**, and no row resolves to *unlimited* — which is the right answer for
|
|
11
|
+
* every self-hosted Kern and exactly the wrong one for an instance that takes money. The only
|
|
12
|
+
* signal used to be a `warn` nobody reads, so a Kern Cloud one typo away from giving everything
|
|
13
|
+
* away looked completely healthy.
|
|
14
|
+
*/
|
|
15
|
+
/** The file `KERN_PLANS_FILE` points at: a JSON array of plans, in the shape the admin console writes. */
|
|
16
|
+
const PlansFile = z.array(UpsertPlan);
|
|
17
|
+
/**
|
|
18
|
+
* Create any plan in `KERN_PLANS_FILE` whose slug this instance does not have yet.
|
|
19
|
+
*
|
|
20
|
+
* **Create, never update.** A plan is data an instance admin edits — prices, limits, what the
|
|
21
|
+
* pricing page says — and an image that rewrote the catalogue on every boot would silently revert
|
|
22
|
+
* their work at the next deploy. So a slug that already exists is left exactly as it is, and the
|
|
23
|
+
* file is only ever the answer to "a fresh instance has no plans at all".
|
|
24
|
+
*
|
|
25
|
+
* Returns the slugs it created, so the boot log says what happened rather than that something did.
|
|
26
|
+
*/
|
|
27
|
+
export async function seedPlansFromFile(kernel) {
|
|
28
|
+
const path = process.env.KERN_PLANS_FILE;
|
|
29
|
+
if (!path)
|
|
30
|
+
return [];
|
|
31
|
+
let parsed;
|
|
32
|
+
try {
|
|
33
|
+
parsed = PlansFile.parse(JSON.parse(await readFile(path, 'utf8')));
|
|
34
|
+
}
|
|
35
|
+
catch (err) {
|
|
36
|
+
// Loud, and not fatal: an unreadable seed file must not take down a service that is otherwise
|
|
37
|
+
// configured, and the boot check below is what refuses when the result is actually unusable.
|
|
38
|
+
kernel.log.error({ err: String(err), path }, 'billing: KERN_PLANS_FILE could not be read as a list of plans; no plan was seeded');
|
|
39
|
+
return [];
|
|
40
|
+
}
|
|
41
|
+
const created = [];
|
|
42
|
+
for (const plan of parsed) {
|
|
43
|
+
if (await plans.bySlug(kernel, plan.slug))
|
|
44
|
+
continue;
|
|
45
|
+
// `id` is dropped: the file describes a catalogue, not this database's primary keys, and two
|
|
46
|
+
// instances seeded from one file must not be told they share a row.
|
|
47
|
+
const { id: _ignored, ...rest } = plan;
|
|
48
|
+
await plans.upsert(kernel, rest);
|
|
49
|
+
created.push(plan.slug);
|
|
50
|
+
}
|
|
51
|
+
if (created.length)
|
|
52
|
+
kernel.log.info({ created, path }, 'billing: seeded plans from KERN_PLANS_FILE');
|
|
53
|
+
return created;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Refuse to start, or say loudly why every new workspace is about to be unlimited.
|
|
57
|
+
*
|
|
58
|
+
* Two conditions, and they are not equally recoverable:
|
|
59
|
+
*
|
|
60
|
+
* - **No `KERN_DEFAULT_PLAN_SLUG` on an instance with a Stripe key.** Pure configuration, fixable
|
|
61
|
+
* in the environment without the service running, and it means every single signup is unlimited.
|
|
62
|
+
* That one throws.
|
|
63
|
+
* - **A slug naming a plan that does not exist.** Also wrong, and it is what a brand-new instance
|
|
64
|
+
* looks like for as long as it takes somebody to create the plan — so refusing here would lock
|
|
65
|
+
* the operator out of the console they need in order to fix it. That one is an `error` in the log
|
|
66
|
+
* and a refusal on the path that matters, which is `core.workspace.created`.
|
|
67
|
+
*
|
|
68
|
+
* An instance with no Stripe key is a self-hosted Kern: unlimited is the correct and intended
|
|
69
|
+
* answer there, and nothing here fires.
|
|
70
|
+
*/
|
|
71
|
+
export async function assertDefaultPlan(kernel) {
|
|
72
|
+
if (!paymentsEnabled())
|
|
73
|
+
return;
|
|
74
|
+
const slug = process.env.KERN_DEFAULT_PLAN_SLUG;
|
|
75
|
+
if (!slug)
|
|
76
|
+
throw new Error('STRIPE_SECRET_KEY is set, so this instance sells subscriptions, but KERN_DEFAULT_PLAN_SLUG is ' +
|
|
77
|
+
'empty. A workspace created without a plan has no subscription row, and no subscription row ' +
|
|
78
|
+
'means unlimited seats, unlimited storage and SSO included — every signup would get the whole ' +
|
|
79
|
+
'product for nothing.\n' +
|
|
80
|
+
'Set KERN_DEFAULT_PLAN_SLUG to the slug of the plan new workspaces start on, or unset ' +
|
|
81
|
+
'STRIPE_SECRET_KEY if this instance is not meant to take payments.');
|
|
82
|
+
if (!(await plans.bySlug(kernel, slug)))
|
|
83
|
+
kernel.log.error({ slug }, 'billing: KERN_DEFAULT_PLAN_SLUG names a plan that does not exist, so every new workspace ' +
|
|
84
|
+
'will be created without a subscription and resolve to unlimited. Create the plan in the ' +
|
|
85
|
+
'instance console, seed it with KERN_PLANS_FILE, or point the variable at a plan that exists.');
|
|
86
|
+
}
|
|
87
|
+
//# sourceMappingURL=catalogue.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"catalogue.js","sourceRoot":"","sources":["../../../src/server/services/catalogue.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAA;AAE3C,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AACvB,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAA;AAC9C,OAAO,KAAK,KAAK,MAAM,YAAY,CAAA;AACnC,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAE7C;;;;;;;;GAQG;AAEH,0GAA0G;AAC1G,MAAM,SAAS,GAAG,CAAC,CAAC,KAAK,CAAC,UAAU,CAAC,CAAA;AAErC;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,MAAc;IACpD,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,eAAe,CAAA;IACxC,IAAI,CAAC,IAAI;QAAE,OAAO,EAAE,CAAA;IAEpB,IAAI,MAAiC,CAAA;IACrC,IAAI,CAAC;QACH,MAAM,GAAG,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,CAAA;IACpE,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,8FAA8F;QAC9F,6FAA6F;QAC7F,MAAM,CAAC,GAAG,CAAC,KAAK,CACd,EAAE,GAAG,EAAE,MAAM,CAAC,GAAG,CAAC,EAAE,IAAI,EAAE,EAC1B,mFAAmF,CACpF,CAAA;QACD,OAAO,EAAE,CAAA;IACX,CAAC;IAED,MAAM,OAAO,GAAa,EAAE,CAAA;IAC5B,KAAK,MAAM,IAAI,IAAI,MAAM,EAAE,CAAC;QAC1B,IAAI,MAAM,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,IAAI,CAAC;YAAE,SAAQ;QACnD,6FAA6F;QAC7F,oEAAoE;QACpE,MAAM,EAAE,EAAE,EAAE,QAAQ,EAAE,GAAG,IAAI,EAAE,GAAG,IAAI,CAAA;QACtC,MAAM,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,CAAA;QAChC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IACzB,CAAC;IACD,IAAI,OAAO,CAAC,MAAM;QAAE,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE,4CAA4C,CAAC,CAAA;IACpG,OAAO,OAAO,CAAA;AAChB,CAAC;AAED;;;;;;;;;;;;;;;GAeG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,MAAc;IACpD,IAAI,CAAC,eAAe,EAAE;QAAE,OAAM;IAC9B,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,sBAAsB,CAAA;IAC/C,IAAI,CAAC,IAAI;QACP,MAAM,IAAI,KAAK,CACb,gGAAgG;YAC9F,6FAA6F;YAC7F,+FAA+F;YAC/F,wBAAwB;YACxB,uFAAuF;YACvF,mEAAmE,CACtE,CAAA;IACH,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;QACrC,MAAM,CAAC,GAAG,CAAC,KAAK,CACd,EAAE,IAAI,EAAE,EACR,2FAA2F;YACzF,0FAA0F;YAC1F,8FAA8F,CACjG,CAAA;AACL,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"entitlements.d.ts","sourceRoot":"","sources":["../../../src/server/services/entitlements.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAA;
|
|
1
|
+
{"version":3,"file":"entitlements.d.ts","sourceRoot":"","sources":["../../../src/server/services/entitlements.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAA;AAsDzD,wBAAsB,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,CA6ChG"}
|