@shdan/submesh 0.1.0 → 1.0.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.
Files changed (73) hide show
  1. package/README.md +2 -2
  2. package/dist/contracts.d.ts +39 -2
  3. package/dist/contracts.d.ts.map +1 -1
  4. package/dist/drizzle/ensure-schema.d.ts.map +1 -1
  5. package/dist/drizzle/ensure-schema.js +12 -0
  6. package/dist/drizzle/ensure-schema.js.map +1 -1
  7. package/dist/drizzle/schema.d.ts.map +1 -1
  8. package/dist/drizzle/schema.js +4 -1
  9. package/dist/drizzle/schema.js.map +1 -1
  10. package/dist/drizzle/subject-repository.d.ts.map +1 -1
  11. package/dist/drizzle/subject-repository.js +7 -3
  12. package/dist/drizzle/subject-repository.js.map +1 -1
  13. package/dist/drizzle/summary-repository.d.ts.map +1 -1
  14. package/dist/drizzle/summary-repository.js +16 -7
  15. package/dist/drizzle/summary-repository.js.map +1 -1
  16. package/dist/index.d.ts +2 -1
  17. package/dist/index.d.ts.map +1 -1
  18. package/dist/index.js +1 -0
  19. package/dist/index.js.map +1 -1
  20. package/dist/logger.d.ts +27 -0
  21. package/dist/logger.d.ts.map +1 -1
  22. package/dist/logger.js +61 -0
  23. package/dist/logger.js.map +1 -1
  24. package/dist/plugins/builtin-plugins.d.ts.map +1 -1
  25. package/dist/plugins/builtin-plugins.js +2 -1
  26. package/dist/plugins/builtin-plugins.js.map +1 -1
  27. package/dist/providers/stripe/plugin/stripe-plan-sync.d.ts +4 -0
  28. package/dist/providers/stripe/plugin/stripe-plan-sync.d.ts.map +1 -0
  29. package/dist/providers/stripe/plugin/stripe-plan-sync.js +83 -0
  30. package/dist/providers/stripe/plugin/stripe-plan-sync.js.map +1 -0
  31. package/dist/providers/stripe/plugin/stripe.d.ts +20 -0
  32. package/dist/providers/stripe/plugin/stripe.d.ts.map +1 -0
  33. package/dist/providers/stripe/plugin/stripe.js +238 -0
  34. package/dist/providers/stripe/plugin/stripe.js.map +1 -0
  35. package/dist/providers/stripe/security/stripe-signature-verification.d.ts +3 -0
  36. package/dist/providers/stripe/security/stripe-signature-verification.d.ts.map +1 -0
  37. package/dist/providers/stripe/security/stripe-signature-verification.js +162 -0
  38. package/dist/providers/stripe/security/stripe-signature-verification.js.map +1 -0
  39. package/dist/providers/stripe/services/stripe-subscription-verification-service.d.ts +3 -0
  40. package/dist/providers/stripe/services/stripe-subscription-verification-service.d.ts.map +1 -0
  41. package/dist/providers/stripe/services/stripe-subscription-verification-service.js +65 -0
  42. package/dist/providers/stripe/services/stripe-subscription-verification-service.js.map +1 -0
  43. package/dist/services/managed-subscription-service.d.ts +2 -1
  44. package/dist/services/managed-subscription-service.d.ts.map +1 -1
  45. package/dist/services/managed-subscription-service.js +7 -1
  46. package/dist/services/managed-subscription-service.js.map +1 -1
  47. package/dist/services/plan-provisioning-service.d.ts +2 -1
  48. package/dist/services/plan-provisioning-service.d.ts.map +1 -1
  49. package/dist/services/plan-provisioning-service.js +16 -1
  50. package/dist/services/plan-provisioning-service.js.map +1 -1
  51. package/dist/services/provider-subscription-sync-service.d.ts +2 -1
  52. package/dist/services/provider-subscription-sync-service.d.ts.map +1 -1
  53. package/dist/services/provider-subscription-sync-service.js +7 -1
  54. package/dist/services/provider-subscription-sync-service.js.map +1 -1
  55. package/dist/services/retry-event-replay.d.ts +4 -0
  56. package/dist/services/retry-event-replay.d.ts.map +1 -0
  57. package/dist/services/retry-event-replay.js +53 -0
  58. package/dist/services/retry-event-replay.js.map +1 -0
  59. package/dist/services/webhook-ingestion-service.d.ts.map +1 -1
  60. package/dist/services/webhook-ingestion-service.js +23 -7
  61. package/dist/services/webhook-ingestion-service.js.map +1 -1
  62. package/dist/submesh.d.ts +15 -1
  63. package/dist/submesh.d.ts.map +1 -1
  64. package/dist/submesh.js +117 -27
  65. package/dist/submesh.js.map +1 -1
  66. package/dist/utils/validation.d.ts +6 -0
  67. package/dist/utils/validation.d.ts.map +1 -1
  68. package/dist/utils/validation.js +7 -1
  69. package/dist/utils/validation.js.map +1 -1
  70. package/drizzle/0001_steady_perf_indexes.sql +8 -0
  71. package/drizzle/meta/_journal.json +7 -0
  72. package/package.json +10 -10
  73. package/LICENSE +0 -21
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stripe.d.ts","sourceRoot":"","sources":["../../../../src/providers/stripe/plugin/stripe.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAEV,kBAAkB,EAEnB,MAAM,qBAAqB,CAAC;AAE7B,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAgRhE,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;CAkCyB,CAAC"}
@@ -0,0 +1,238 @@
1
+ import { randomUUID } from "node:crypto";
2
+ import { verifyStripeWebhook } from "../security/stripe-signature-verification.js";
3
+ import { verifyTrustedRelayWebhook } from "../../../security/plugin-webhook-verification.js";
4
+ import { hashPayload } from "../../../plugins/hash-payload.js";
5
+ import { deprovisionStripePlan, provisionStripePlan } from "./stripe-plan-sync.js";
6
+ function asObject(value) {
7
+ if (!value || typeof value !== "object" || Array.isArray(value)) {
8
+ return {};
9
+ }
10
+ return value;
11
+ }
12
+ function getString(value) {
13
+ return typeof value === "string" && value.length > 0 ? value : undefined;
14
+ }
15
+ function getBoolean(value) {
16
+ return typeof value === "boolean" ? value : undefined;
17
+ }
18
+ function getNumericString(value) {
19
+ if (typeof value === "number" && Number.isFinite(value)) {
20
+ return value.toString();
21
+ }
22
+ return getString(value);
23
+ }
24
+ function toStripeDateString(value) {
25
+ const raw = getNumericString(value);
26
+ if (raw) {
27
+ const numeric = Number(raw);
28
+ if (Number.isFinite(numeric)) {
29
+ return raw.length >= 13
30
+ ? new Date(numeric).toISOString()
31
+ : new Date(numeric * 1000).toISOString();
32
+ }
33
+ }
34
+ return getString(value) ?? null;
35
+ }
36
+ function isFutureTimestamp(value) {
37
+ if (!value) {
38
+ return false;
39
+ }
40
+ const time = Date.parse(value);
41
+ return Number.isFinite(time) && time > Date.now();
42
+ }
43
+ function normalizeStripeStatus(input) {
44
+ if (input.eventType === "customer.subscription.deleted") {
45
+ return "canceled";
46
+ }
47
+ if (input.eventType === "customer.subscription.paused") {
48
+ return "paused";
49
+ }
50
+ if (input.eventType === "customer.subscription.resumed") {
51
+ return "active";
52
+ }
53
+ if (input.eventType === "customer.subscription.trial_will_end") {
54
+ return "trialing";
55
+ }
56
+ switch (input.status) {
57
+ case "trialing":
58
+ return "trialing";
59
+ case "active":
60
+ return "active";
61
+ case "past_due":
62
+ case "unpaid":
63
+ return "billing_issue";
64
+ case "paused":
65
+ return "paused";
66
+ case "incomplete":
67
+ case "incomplete_expired":
68
+ return "canceled";
69
+ case "canceled":
70
+ return input.cancelAtPeriodEnd && isFutureTimestamp(input.currentPeriodEnd)
71
+ ? "active"
72
+ : "canceled";
73
+ default:
74
+ return "active";
75
+ }
76
+ }
77
+ function parsePayload(body) {
78
+ if (typeof body === "string") {
79
+ return asObject(JSON.parse(body));
80
+ }
81
+ if (body && typeof body === "object" && !Array.isArray(body)) {
82
+ return body;
83
+ }
84
+ throw new Error("Stripe plugin expects a JSON object payload.");
85
+ }
86
+ function resolveExternalProductId(payload, subscription) {
87
+ const items = asObject(subscription.items);
88
+ const data = Array.isArray(items.data)
89
+ ? items.data.filter((entry) => Boolean(entry) && typeof entry === "object" && !Array.isArray(entry))
90
+ : [];
91
+ const firstItem = asObject(data[0]);
92
+ const price = asObject(firstItem.price || subscription.price || subscription.plan);
93
+ return (getString(payload.externalProductId) ??
94
+ getString(payload.priceId) ??
95
+ getString(payload.productId) ??
96
+ getString(price.id) ??
97
+ getString(price.product) ??
98
+ getString(asObject(price.product).id));
99
+ }
100
+ function resolveExternalCustomerId(payload, subscription) {
101
+ const customer = subscription.customer;
102
+ return (getString(payload.externalCustomerId) ??
103
+ getString(payload.externalSubjectId) ??
104
+ getString(payload.customerId) ??
105
+ getString(customer) ??
106
+ getString(asObject(customer).id));
107
+ }
108
+ function buildRecord(input) {
109
+ const metadata = asObject(input.subscription.metadata);
110
+ const currentPeriodStart = toStripeDateString(input.subscription.current_period_start) ??
111
+ toStripeDateString(input.payload.currentPeriodStart);
112
+ const currentPeriodEnd = toStripeDateString(input.subscription.current_period_end) ??
113
+ toStripeDateString(input.payload.currentPeriodEnd);
114
+ const cancelAtPeriodEnd = getBoolean(input.subscription.cancel_at_period_end) ?? false;
115
+ const cancelAt = toStripeDateString(input.subscription.cancel_at) ??
116
+ toStripeDateString(input.payload.cancelAt) ??
117
+ (cancelAtPeriodEnd && isFutureTimestamp(currentPeriodEnd) ? currentPeriodEnd : null);
118
+ const externalCustomerId = resolveExternalCustomerId(input.payload, input.subscription);
119
+ return {
120
+ pluginKey: "stripe",
121
+ sourceType: getString(input.payload.sourceType) ?? "stripe",
122
+ sourceRef: input.sourceRef,
123
+ status: normalizeStripeStatus({
124
+ status: getString(input.subscription.status) ?? getString(input.payload.status),
125
+ eventType: input.eventType,
126
+ currentPeriodEnd,
127
+ cancelAtPeriodEnd,
128
+ }),
129
+ subjectId: getString(input.payload.subjectId) ??
130
+ getString(input.payload.userId) ??
131
+ getString(metadata.subjectId) ??
132
+ getString(metadata.userId),
133
+ externalSubjectId: externalCustomerId,
134
+ externalCustomerId,
135
+ planCode: getString(input.payload.planCode) ?? getString(metadata.planCode),
136
+ externalProductId: resolveExternalProductId(input.payload, input.subscription),
137
+ currentPeriodStart,
138
+ currentPeriodEnd,
139
+ trialEndAt: toStripeDateString(input.subscription.trial_end),
140
+ cancelAt,
141
+ metadata: {
142
+ eventType: input.eventType,
143
+ lifecycle: input.eventType.split(".").slice(-1)[0] ?? "updated",
144
+ payload: input.payload,
145
+ subscription: input.subscription,
146
+ },
147
+ };
148
+ }
149
+ function toNormalizedEvent(payload) {
150
+ const sourceRef = String(payload.sourceRef ?? payload.subscriptionId ?? payload.id ?? randomUUID());
151
+ const record = buildRecord({
152
+ payload,
153
+ subscription: {
154
+ id: sourceRef,
155
+ status: payload.status,
156
+ customer: payload.externalCustomerId ?? payload.externalSubjectId ?? payload.customerId,
157
+ current_period_start: payload.currentPeriodStart,
158
+ current_period_end: payload.currentPeriodEnd,
159
+ trial_end: payload.trialEndAt,
160
+ cancel_at: payload.cancelAt,
161
+ items: {
162
+ data: [
163
+ {
164
+ price: {
165
+ id: payload.priceId ?? payload.externalProductId,
166
+ product: payload.productId,
167
+ },
168
+ },
169
+ ],
170
+ },
171
+ metadata: asObject(payload.metadata),
172
+ },
173
+ eventType: getString(payload.eventType) ?? "stripe.subscription.updated",
174
+ sourceRef,
175
+ });
176
+ return {
177
+ eventKey: getString(payload.eventKey) ?? hashPayload(payload),
178
+ eventType: getString(payload.eventType) ?? "stripe.subscription.updated",
179
+ sourceRef,
180
+ records: [record],
181
+ };
182
+ }
183
+ function toStripeEvent(payload) {
184
+ const eventType = getString(payload.type) ?? "stripe.event";
185
+ const data = asObject(payload.data);
186
+ const object = asObject(data.object);
187
+ if (!eventType.startsWith("customer.subscription.")) {
188
+ return {
189
+ eventKey: getString(payload.id) ?? hashPayload(payload),
190
+ eventType,
191
+ sourceRef: null,
192
+ records: [],
193
+ };
194
+ }
195
+ const sourceRef = String(object.id ?? payload.id ?? randomUUID());
196
+ const record = buildRecord({
197
+ payload,
198
+ subscription: object,
199
+ eventType,
200
+ sourceRef,
201
+ });
202
+ return {
203
+ eventKey: getString(payload.id) ?? hashPayload(payload),
204
+ eventType,
205
+ sourceRef,
206
+ records: [record],
207
+ };
208
+ }
209
+ export const stripePlugin = {
210
+ key: "stripe",
211
+ displayName: "Stripe Billing",
212
+ description: "Normalizes Stripe Billing subscription webhook events and syncs verified subscriptions into canonical records.",
213
+ capabilities: ["webhooks", "subscription-sync", "billing"],
214
+ async provisionPlan(input, context) {
215
+ return provisionStripePlan(input, context.config);
216
+ },
217
+ async deprovisionPlan(input, context) {
218
+ return deprovisionStripePlan(input, context.config, context.result);
219
+ },
220
+ async verifyWebhook(envelope, context) {
221
+ const stripeVerification = verifyStripeWebhook(envelope, context.config);
222
+ if (stripeVerification) {
223
+ return stripeVerification;
224
+ }
225
+ return verifyTrustedRelayWebhook(envelope, context.config);
226
+ },
227
+ async parseWebhook(envelope) {
228
+ const payload = parsePayload(envelope.body);
229
+ if (typeof payload.status === "string") {
230
+ return toNormalizedEvent(payload);
231
+ }
232
+ if (typeof payload.type === "string") {
233
+ return toStripeEvent(payload);
234
+ }
235
+ throw new Error("Stripe plugin expects either a normalized payload with status or a Stripe event payload with type.");
236
+ },
237
+ };
238
+ //# sourceMappingURL=stripe.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stripe.js","sourceRoot":"","sources":["../../../../src/providers/stripe/plugin/stripe.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { PluginWebhookEnvelope, PluginWebhookVerification } from "@shdan/submesh-core";
2
+ export declare function verifyStripeWebhook(envelope: PluginWebhookEnvelope, config: Record<string, unknown>): PluginWebhookVerification | undefined;
3
+ //# sourceMappingURL=stripe-signature-verification.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stripe-signature-verification.d.ts","sourceRoot":"","sources":["../../../../src/providers/stripe/security/stripe-signature-verification.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,qBAAqB,EACrB,yBAAyB,EAC1B,MAAM,qBAAqB,CAAC;AA4G7B,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,qBAAqB,EAC/B,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC9B,yBAAyB,GAAG,SAAS,CAqFvC"}
@@ -0,0 +1,162 @@
1
+ import { createHmac, timingSafeEqual } from "node:crypto";
2
+ const DEFAULT_WEBHOOK_TOLERANCE_SECONDS = 300;
3
+ function readHeader(headers, key) {
4
+ const value = headers[key] ?? headers[key.toLowerCase()];
5
+ return Array.isArray(value) ? value[0] : value;
6
+ }
7
+ function getString(value) {
8
+ return typeof value === "string" && value.length > 0 ? value : undefined;
9
+ }
10
+ function getNumber(value) {
11
+ return typeof value === "number" && Number.isFinite(value) ? value : undefined;
12
+ }
13
+ function hasStripeVerificationConfig(config) {
14
+ return typeof config.stripeWebhookSigningSecret === "string";
15
+ }
16
+ function toRawPayload(envelope) {
17
+ const raw = envelope.rawBody ?? envelope.body;
18
+ if (typeof raw === "string") {
19
+ return raw;
20
+ }
21
+ if (raw instanceof Uint8Array) {
22
+ return Buffer.from(raw).toString("utf8");
23
+ }
24
+ return undefined;
25
+ }
26
+ function safeEqualHex(expectedHex, candidateHex) {
27
+ if (expectedHex.length !== candidateHex.length) {
28
+ return false;
29
+ }
30
+ try {
31
+ const expected = Buffer.from(expectedHex, "hex");
32
+ const candidate = Buffer.from(candidateHex, "hex");
33
+ if (expected.length !== candidate.length) {
34
+ return false;
35
+ }
36
+ return timingSafeEqual(expected, candidate);
37
+ }
38
+ catch {
39
+ return false;
40
+ }
41
+ }
42
+ function parseSignatureHeader(value) {
43
+ const signatures = [];
44
+ let timestamp;
45
+ for (const entry of value.split(",")) {
46
+ const [rawKey, rawValue] = entry.trim().split("=", 2);
47
+ if (!rawKey || !rawValue) {
48
+ continue;
49
+ }
50
+ if (rawKey === "t") {
51
+ const parsed = Number(rawValue);
52
+ if (Number.isFinite(parsed)) {
53
+ timestamp = parsed;
54
+ }
55
+ continue;
56
+ }
57
+ if (rawKey === "v1") {
58
+ signatures.push(rawValue);
59
+ }
60
+ }
61
+ if (!Number.isFinite(timestamp) || signatures.length === 0) {
62
+ return null;
63
+ }
64
+ return {
65
+ timestamp: timestamp,
66
+ signatures,
67
+ };
68
+ }
69
+ function resolveToleranceSeconds(config) {
70
+ const direct = getNumber(config.stripeWebhookToleranceSeconds);
71
+ if (direct !== undefined && direct >= 0) {
72
+ return direct;
73
+ }
74
+ const configured = getString(config.stripeWebhookToleranceSeconds);
75
+ if (configured) {
76
+ const parsed = Number(configured);
77
+ if (Number.isFinite(parsed) && parsed >= 0) {
78
+ return parsed;
79
+ }
80
+ }
81
+ return DEFAULT_WEBHOOK_TOLERANCE_SECONDS;
82
+ }
83
+ export function verifyStripeWebhook(envelope, config) {
84
+ if (!hasStripeVerificationConfig(config)) {
85
+ return undefined;
86
+ }
87
+ const secret = getString(config.stripeWebhookSigningSecret);
88
+ if (!secret) {
89
+ return {
90
+ verified: false,
91
+ strategy: "custom",
92
+ metadata: {
93
+ provider: "stripe",
94
+ reason: "missing_signing_secret",
95
+ },
96
+ };
97
+ }
98
+ const signatureHeader = readHeader(envelope.headers, "stripe-signature");
99
+ if (!signatureHeader) {
100
+ return {
101
+ verified: false,
102
+ strategy: "custom",
103
+ metadata: {
104
+ provider: "stripe",
105
+ reason: "missing_signature_header",
106
+ },
107
+ };
108
+ }
109
+ const parsed = parseSignatureHeader(signatureHeader);
110
+ if (!parsed) {
111
+ return {
112
+ verified: false,
113
+ strategy: "custom",
114
+ metadata: {
115
+ provider: "stripe",
116
+ reason: "invalid_signature_header",
117
+ },
118
+ };
119
+ }
120
+ const payload = toRawPayload(envelope);
121
+ if (!payload) {
122
+ return {
123
+ verified: false,
124
+ strategy: "custom",
125
+ metadata: {
126
+ provider: "stripe",
127
+ reason: "missing_raw_body",
128
+ },
129
+ };
130
+ }
131
+ const toleranceSeconds = resolveToleranceSeconds(config);
132
+ const nowSeconds = Math.floor(Date.now() / 1000);
133
+ if (Math.abs(nowSeconds - parsed.timestamp) > toleranceSeconds) {
134
+ return {
135
+ verified: false,
136
+ strategy: "custom",
137
+ metadata: {
138
+ provider: "stripe",
139
+ reason: "timestamp_out_of_tolerance",
140
+ timestamp: parsed.timestamp,
141
+ },
142
+ };
143
+ }
144
+ const signedPayload = `${parsed.timestamp}.${payload}`;
145
+ const expected = createHmac("sha256", secret).update(signedPayload).digest("hex");
146
+ const matched = parsed.signatures.some((signature) => safeEqualHex(expected, signature));
147
+ return {
148
+ verified: matched,
149
+ strategy: "custom",
150
+ metadata: matched
151
+ ? {
152
+ provider: "stripe",
153
+ timestamp: parsed.timestamp,
154
+ }
155
+ : {
156
+ provider: "stripe",
157
+ reason: "signature_mismatch",
158
+ timestamp: parsed.timestamp,
159
+ },
160
+ };
161
+ }
162
+ //# sourceMappingURL=stripe-signature-verification.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stripe-signature-verification.js","sourceRoot":"","sources":["../../../../src/providers/stripe/security/stripe-signature-verification.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { VerifiedProviderSubscription, VerifyStripeSubscriptionInput } from "../../../contracts.js";
2
+ export declare function verifyStripeSubscription(input: VerifyStripeSubscriptionInput, config?: Record<string, unknown>): Promise<VerifiedProviderSubscription>;
3
+ //# sourceMappingURL=stripe-subscription-verification-service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stripe-subscription-verification-service.d.ts","sourceRoot":"","sources":["../../../../src/providers/stripe/services/stripe-subscription-verification-service.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,4BAA4B,EAC5B,6BAA6B,EAC9B,MAAM,uBAAuB,CAAC;AAsE/B,wBAAsB,wBAAwB,CAC5C,KAAK,EAAE,6BAA6B,EACpC,MAAM,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,GACnC,OAAO,CAAC,4BAA4B,CAAC,CAoBvC"}
@@ -0,0 +1,65 @@
1
+ import { ValidationError } from "../../../errors.js";
2
+ import { stripePlugin } from "../plugin/stripe.js";
3
+ function asObject(value) {
4
+ return value && typeof value === "object" && !Array.isArray(value)
5
+ ? value
6
+ : {};
7
+ }
8
+ function getString(value) {
9
+ return typeof value === "string" && value.length > 0 ? value : undefined;
10
+ }
11
+ function resolveApiKey(input, config) {
12
+ const apiKey = input.apiKey ?? getString(config.stripeApiKey);
13
+ if (!apiKey) {
14
+ throw new ValidationError("Stripe subscription verification requires apiKey in the method input or plugin config.stripeApiKey.");
15
+ }
16
+ return apiKey;
17
+ }
18
+ async function parseStripeRecord(body) {
19
+ const parsed = await stripePlugin.parseWebhook?.({
20
+ body,
21
+ headers: {},
22
+ receivedAt: new Date().toISOString(),
23
+ });
24
+ const [event] = Array.isArray(parsed) ? parsed : [parsed];
25
+ const record = event?.records[0];
26
+ if (!record) {
27
+ throw new Error("Stripe verification did not produce a canonical subscription record.");
28
+ }
29
+ return record;
30
+ }
31
+ async function loadStripeSubscription(input, config) {
32
+ const apiKey = resolveApiKey(input, config);
33
+ const url = new URL(`https://api.stripe.com/v1/subscriptions/${encodeURIComponent(input.subscriptionId)}`);
34
+ url.searchParams.append("expand[]", "items.data.price.product");
35
+ const response = await fetch(url, {
36
+ headers: {
37
+ authorization: `Bearer ${apiKey}`,
38
+ },
39
+ });
40
+ if (!response.ok) {
41
+ throw new ValidationError(`Stripe subscription lookup failed for ${input.subscriptionId} with status ${response.status}.`);
42
+ }
43
+ return asObject(await response.json());
44
+ }
45
+ export async function verifyStripeSubscription(input, config = {}) {
46
+ const subscription = await loadStripeSubscription(input, config);
47
+ const raw = {
48
+ id: `stripe.verify:${input.subscriptionId}`,
49
+ type: "customer.subscription.updated",
50
+ subjectId: input.subjectId,
51
+ planCode: input.planCode,
52
+ data: {
53
+ object: subscription,
54
+ },
55
+ };
56
+ const canonical = await parseStripeRecord(raw);
57
+ return {
58
+ provider: "stripe",
59
+ sourceRef: canonical.sourceRef,
60
+ status: canonical.status,
61
+ canonical,
62
+ raw: subscription,
63
+ };
64
+ }
65
+ //# sourceMappingURL=stripe-subscription-verification-service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stripe-subscription-verification-service.js","sourceRoot":"","sources":["../../../../src/providers/stripe/services/stripe-subscription-verification-service.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,6 @@
1
1
  import type { Subscription } from "@shdan/submesh-core";
2
2
  import type { CreateManagedSubscriptionInput } from "../contracts.js";
3
3
  import type { SubmeshRepositories } from "../repositories/index.js";
4
- export declare function createManagedSubscription(repositories: SubmeshRepositories, input: CreateManagedSubscriptionInput): Promise<Subscription>;
4
+ import type { SubmeshLogger } from "../logger.js";
5
+ export declare function createManagedSubscription(repositories: SubmeshRepositories, input: CreateManagedSubscriptionInput, logger?: SubmeshLogger): Promise<Subscription>;
5
6
  //# sourceMappingURL=managed-subscription-service.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"managed-subscription-service.d.ts","sourceRoot":"","sources":["../../src/services/managed-subscription-service.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAExD,OAAO,KAAK,EAAE,8BAA8B,EAAE,MAAM,iBAAiB,CAAC;AAEtE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAEpE,wBAAsB,yBAAyB,CAC7C,YAAY,EAAE,mBAAmB,EACjC,KAAK,EAAE,8BAA8B,GACpC,OAAO,CAAC,YAAY,CAAC,CAsBvB"}
1
+ {"version":3,"file":"managed-subscription-service.d.ts","sourceRoot":"","sources":["../../src/services/managed-subscription-service.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAExD,OAAO,KAAK,EAAE,8BAA8B,EAAE,MAAM,iBAAiB,CAAC;AAEtE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAEpE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAGlD,wBAAsB,yBAAyB,CAC7C,YAAY,EAAE,mBAAmB,EACjC,KAAK,EAAE,8BAA8B,EACrC,MAAM,GAAE,aAA0B,GACjC,OAAO,CAAC,YAAY,CAAC,CA4BvB"}
@@ -1,9 +1,15 @@
1
1
  import { NotFoundError } from "../errors.js";
2
- export async function createManagedSubscription(repositories, input) {
2
+ import { noopLogger } from "../logger.js";
3
+ export async function createManagedSubscription(repositories, input, logger = noopLogger) {
3
4
  const plan = await repositories.plans.getByCode(input.planCode);
4
5
  if (!plan) {
5
6
  throw new NotFoundError(`Plan ${input.planCode} was not found.`);
6
7
  }
8
+ logger.info("Creating managed subscription", {
9
+ subjectId: input.subjectId,
10
+ planCode: input.planCode,
11
+ status: input.status,
12
+ });
7
13
  return repositories.transaction(async (tx) => {
8
14
  await tx.subjects.upsert({ id: input.subjectId });
9
15
  return tx.subscriptions.upsert({
@@ -1 +1 @@
1
- {"version":3,"file":"managed-subscription-service.js","sourceRoot":"","sources":["../../src/services/managed-subscription-service.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAG7C,MAAM,CAAC,KAAK,UAAU,yBAAyB,CAC7C,YAAiC,EACjC,KAAqC;IAErC,MAAM,IAAI,GAAG,MAAM,YAAY,CAAC,KAAK,CAAC,SAAS,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;IAChE,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,MAAM,IAAI,aAAa,CAAC,QAAQ,KAAK,CAAC,QAAQ,iBAAiB,CAAC,CAAC;IACnE,CAAC;IAED,OAAO,YAAY,CAAC,WAAW,CAAC,KAAK,EAAE,EAAE,EAAE,EAAE;QAC3C,MAAM,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,EAAE,EAAE,KAAK,CAAC,SAAS,EAAE,CAAC,CAAC;QAClD,OAAO,EAAE,CAAC,aAAa,CAAC,MAAM,CAAC;YAC7B,SAAS,EAAE,KAAK,CAAC,SAAS;YAC1B,MAAM,EAAE,IAAI,CAAC,EAAE;YACf,SAAS,EAAE,KAAK,CAAC,SAAS,IAAI,QAAQ;YACtC,UAAU,EAAE,KAAK,CAAC,UAAU,IAAI,QAAQ;YACxC,SAAS,EAAE,KAAK,CAAC,SAAS,IAAI,GAAG,KAAK,CAAC,SAAS,IAAI,IAAI,CAAC,IAAI,EAAE;YAC/D,MAAM,EAAE,KAAK,CAAC,MAAM,IAAI,QAAQ;YAChC,kBAAkB,EAAE,KAAK,CAAC,kBAAkB,IAAI,IAAI;YACpD,gBAAgB,EAAE,KAAK,CAAC,gBAAgB,IAAI,IAAI;YAChD,UAAU,EAAE,KAAK,CAAC,UAAU,IAAI,IAAI;YACpC,QAAQ,EAAE,KAAK,CAAC,QAAQ,IAAI,IAAI;YAChC,QAAQ,EAAE,KAAK,CAAC,QAAQ,IAAI,EAAE;SAC/B,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC"}
1
+ {"version":3,"file":"managed-subscription-service.js","sourceRoot":"","sources":["../../src/services/managed-subscription-service.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAI7C,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAE1C,MAAM,CAAC,KAAK,UAAU,yBAAyB,CAC7C,YAAiC,EACjC,KAAqC,EACrC,SAAwB,UAAU;IAElC,MAAM,IAAI,GAAG,MAAM,YAAY,CAAC,KAAK,CAAC,SAAS,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;IAChE,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,MAAM,IAAI,aAAa,CAAC,QAAQ,KAAK,CAAC,QAAQ,iBAAiB,CAAC,CAAC;IACnE,CAAC;IAED,MAAM,CAAC,IAAI,CAAC,+BAA+B,EAAE;QAC3C,SAAS,EAAE,KAAK,CAAC,SAAS;QAC1B,QAAQ,EAAE,KAAK,CAAC,QAAQ;QACxB,MAAM,EAAE,KAAK,CAAC,MAAM;KACrB,CAAC,CAAC;IAEH,OAAO,YAAY,CAAC,WAAW,CAAC,KAAK,EAAE,EAAE,EAAE,EAAE;QAC3C,MAAM,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,EAAE,EAAE,KAAK,CAAC,SAAS,EAAE,CAAC,CAAC;QAClD,OAAO,EAAE,CAAC,aAAa,CAAC,MAAM,CAAC;YAC7B,SAAS,EAAE,KAAK,CAAC,SAAS;YAC1B,MAAM,EAAE,IAAI,CAAC,EAAE;YACf,SAAS,EAAE,KAAK,CAAC,SAAS,IAAI,QAAQ;YACtC,UAAU,EAAE,KAAK,CAAC,UAAU,IAAI,QAAQ;YACxC,SAAS,EAAE,KAAK,CAAC,SAAS,IAAI,GAAG,KAAK,CAAC,SAAS,IAAI,IAAI,CAAC,IAAI,EAAE;YAC/D,MAAM,EAAE,KAAK,CAAC,MAAM,IAAI,QAAQ;YAChC,kBAAkB,EAAE,KAAK,CAAC,kBAAkB,IAAI,IAAI;YACpD,gBAAgB,EAAE,KAAK,CAAC,gBAAgB,IAAI,IAAI;YAChD,UAAU,EAAE,KAAK,CAAC,UAAU,IAAI,IAAI;YACpC,QAAQ,EAAE,KAAK,CAAC,QAAQ,IAAI,IAAI;YAChC,QAAQ,EAAE,KAAK,CAAC,QAAQ,IAAI,EAAE;SAC/B,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC"}
@@ -1,5 +1,6 @@
1
1
  import type { CreatePlanInput } from "../contracts.js";
2
2
  import type { PluginRegistry } from "../plugins/plugin-registry.js";
3
3
  import type { SubmeshRepositories } from "../repositories/index.js";
4
- export declare function createPlanWithProvisioning(repositories: SubmeshRepositories, pluginRegistry: PluginRegistry, input: CreatePlanInput): Promise<import("@shdan/submesh-core").Plan>;
4
+ import { SubmeshLogger } from "../logger.js";
5
+ export declare function createPlanWithProvisioning(repositories: SubmeshRepositories, pluginRegistry: PluginRegistry, input: CreatePlanInput, logger?: SubmeshLogger): Promise<import("@shdan/submesh-core").Plan>;
5
6
  //# sourceMappingURL=plan-provisioning-service.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"plan-provisioning-service.d.ts","sourceRoot":"","sources":["../../src/services/plan-provisioning-service.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,eAAe,EAGhB,MAAM,iBAAiB,CAAC;AAEzB,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AACpE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAoEpE,wBAAsB,0BAA0B,CAC9C,YAAY,EAAE,mBAAmB,EACjC,cAAc,EAAE,cAAc,EAC9B,KAAK,EAAE,eAAe,+CA0EvB"}
1
+ {"version":3,"file":"plan-provisioning-service.d.ts","sourceRoot":"","sources":["../../src/services/plan-provisioning-service.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,eAAe,EAGhB,MAAM,iBAAiB,CAAC;AAEzB,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AACpE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAoEpE,OAAO,EAAE,aAAa,EAAc,MAAM,cAAc,CAAC;AAEzD,wBAAsB,0BAA0B,CAC9C,YAAY,EAAE,mBAAmB,EACjC,cAAc,EAAE,cAAc,EAC9B,KAAK,EAAE,eAAe,EACtB,MAAM,GAAE,aAA0B,+CA4FnC"}
@@ -39,8 +39,12 @@ async function rollbackProvisioning(pluginRegistry, input, provisions) {
39
39
  }
40
40
  return failures;
41
41
  }
42
- export async function createPlanWithProvisioning(repositories, pluginRegistry, input) {
42
+ import { noopLogger } from "../logger.js";
43
+ export async function createPlanWithProvisioning(repositories, pluginRegistry, input, logger = noopLogger) {
43
44
  const provisions = [];
45
+ logger.info("Starting plan creation with provider provisioning", {
46
+ planCode: input.code,
47
+ });
44
48
  try {
45
49
  const installations = await repositories.pluginInstallations.list();
46
50
  for (const installation of installations) {
@@ -51,6 +55,10 @@ export async function createPlanWithProvisioning(repositories, pluginRegistry, i
51
55
  if (!plugin?.provisionPlan) {
52
56
  continue;
53
57
  }
58
+ logger.debug("Triggering plan provisioning for plugin", {
59
+ pluginKey: installation.pluginKey,
60
+ planCode: input.code,
61
+ });
54
62
  const result = await plugin.provisionPlan(input, {
55
63
  config: installation.config ?? {},
56
64
  });
@@ -80,10 +88,17 @@ export async function createPlanWithProvisioning(repositories, pluginRegistry, i
80
88
  await tx.catalogMappings.upsert(mapping);
81
89
  }
82
90
  }
91
+ logger.info("Plan creation with provisioning completed", {
92
+ planCode: input.code,
93
+ });
83
94
  return created;
84
95
  });
85
96
  }
86
97
  catch (error) {
98
+ logger.error("Plan creation with provisioning failed", {
99
+ planCode: input.code,
100
+ error,
101
+ });
87
102
  const rollbackFailures = await rollbackProvisioning(pluginRegistry, input, provisions);
88
103
  if (rollbackFailures.length > 0) {
89
104
  const baseMessage = error instanceof Error
@@ -1 +1 @@
1
- {"version":3,"file":"plan-provisioning-service.js","sourceRoot":"","sources":["../../src/services/plan-provisioning-service.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"plan-provisioning-service.js","sourceRoot":"","sources":["../../src/services/plan-provisioning-service.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,5 @@
1
1
  import type { CanonicalSubscriptionInput, Subscription } from "@shdan/submesh-core";
2
2
  import type { SubmeshRepositories } from "../repositories/index.js";
3
- export declare function syncVerifiedProviderSubscription(repositories: SubmeshRepositories, input: CanonicalSubscriptionInput): Promise<Subscription>;
3
+ import { SubmeshLogger } from "../logger.js";
4
+ export declare function syncVerifiedProviderSubscription(repositories: SubmeshRepositories, input: CanonicalSubscriptionInput, logger?: SubmeshLogger): Promise<Subscription>;
4
5
  //# sourceMappingURL=provider-subscription-sync-service.d.ts.map