@automate.ax/integration-contracts 0.83.2 → 0.84.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/dist/stripe/index.d.ts +45 -0
- package/dist/stripe/index.js +110 -0
- package/dist/stripe/schemas.d.ts +26 -0
- package/dist/stripe/schemas.js +94 -0
- package/dist/triggers.d.ts +2 -1
- package/package.json +9 -2
- package/src/stripe/index.ts +165 -0
- package/src/stripe/schemas.ts +120 -0
- package/src/triggers.ts +2 -0
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import * as z from "zod";
|
|
2
|
+
import type { StripeEvent, StripeSemanticEvent } from "./schemas.js";
|
|
3
|
+
export * from "./schemas.js";
|
|
4
|
+
export declare const STRIPE_TRIGGER_CONFIG_SCHEMA: z.ZodObject<{}, z.core.$strip>;
|
|
5
|
+
type StripeTriggerContract<TEvent> = {
|
|
6
|
+
readonly configSchema: typeof STRIPE_TRIGGER_CONFIG_SCHEMA;
|
|
7
|
+
readonly eventSchema: z.ZodType<TEvent>;
|
|
8
|
+
};
|
|
9
|
+
type StripeSemanticTriggerEventTypes = {
|
|
10
|
+
readonly "stripe.charge.dispute.closed": "charge.dispute.closed";
|
|
11
|
+
readonly "stripe.charge.dispute.created": "charge.dispute.created";
|
|
12
|
+
readonly "stripe.checkout.session.asyncPaymentFailed": "checkout.session.async_payment_failed";
|
|
13
|
+
readonly "stripe.checkout.session.asyncPaymentSucceeded": "checkout.session.async_payment_succeeded";
|
|
14
|
+
readonly "stripe.checkout.session.completed": "checkout.session.completed";
|
|
15
|
+
readonly "stripe.checkout.session.expired": "checkout.session.expired";
|
|
16
|
+
readonly "stripe.customer.created": "customer.created";
|
|
17
|
+
readonly "stripe.customer.deleted": "customer.deleted";
|
|
18
|
+
readonly "stripe.customer.subscription.created": "customer.subscription.created";
|
|
19
|
+
readonly "stripe.customer.subscription.deleted": "customer.subscription.deleted";
|
|
20
|
+
readonly "stripe.customer.subscription.trialWillEnd": "customer.subscription.trial_will_end";
|
|
21
|
+
readonly "stripe.customer.subscription.updated": "customer.subscription.updated";
|
|
22
|
+
readonly "stripe.customer.updated": "customer.updated";
|
|
23
|
+
readonly "stripe.invoice.finalized": "invoice.finalized";
|
|
24
|
+
readonly "stripe.invoice.overdue": "invoice.overdue";
|
|
25
|
+
readonly "stripe.invoice.paid": "invoice.paid";
|
|
26
|
+
readonly "stripe.invoice.paymentFailed": "invoice.payment_failed";
|
|
27
|
+
readonly "stripe.invoice.voided": "invoice.voided";
|
|
28
|
+
readonly "stripe.paymentIntent.canceled": "payment_intent.canceled";
|
|
29
|
+
readonly "stripe.paymentIntent.paymentFailed": "payment_intent.payment_failed";
|
|
30
|
+
readonly "stripe.paymentIntent.succeeded": "payment_intent.succeeded";
|
|
31
|
+
readonly "stripe.payout.failed": "payout.failed";
|
|
32
|
+
readonly "stripe.payout.paid": "payout.paid";
|
|
33
|
+
readonly "stripe.refund.created": "refund.created";
|
|
34
|
+
readonly "stripe.refund.failed": "refund.failed";
|
|
35
|
+
};
|
|
36
|
+
/**
|
|
37
|
+
* Named registry shape keeps declaration emit independent of Stripe's private
|
|
38
|
+
* resource modules.
|
|
39
|
+
*/
|
|
40
|
+
type StripeTriggerContracts = {
|
|
41
|
+
readonly [TTrigger in keyof StripeSemanticTriggerEventTypes]: StripeTriggerContract<StripeSemanticEvent<StripeSemanticTriggerEventTypes[TTrigger]>>;
|
|
42
|
+
} & {
|
|
43
|
+
readonly "stripe.event": StripeTriggerContract<StripeEvent>;
|
|
44
|
+
};
|
|
45
|
+
export declare const stripeTriggerContracts: StripeTriggerContracts;
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import * as z from "zod";
|
|
2
|
+
import { STRIPE_EVENT_SCHEMA, stripeSemanticEventSchema } from "./schemas.js";
|
|
3
|
+
export * from "./schemas.js";
|
|
4
|
+
export const STRIPE_TRIGGER_CONFIG_SCHEMA = z.object({});
|
|
5
|
+
export const stripeTriggerContracts = {
|
|
6
|
+
"stripe.charge.dispute.closed": {
|
|
7
|
+
configSchema: STRIPE_TRIGGER_CONFIG_SCHEMA,
|
|
8
|
+
eventSchema: stripeSemanticEventSchema("charge.dispute.closed"),
|
|
9
|
+
},
|
|
10
|
+
"stripe.charge.dispute.created": {
|
|
11
|
+
configSchema: STRIPE_TRIGGER_CONFIG_SCHEMA,
|
|
12
|
+
eventSchema: stripeSemanticEventSchema("charge.dispute.created"),
|
|
13
|
+
},
|
|
14
|
+
"stripe.checkout.session.completed": {
|
|
15
|
+
configSchema: STRIPE_TRIGGER_CONFIG_SCHEMA,
|
|
16
|
+
eventSchema: stripeSemanticEventSchema("checkout.session.completed"),
|
|
17
|
+
},
|
|
18
|
+
"stripe.checkout.session.asyncPaymentFailed": {
|
|
19
|
+
configSchema: STRIPE_TRIGGER_CONFIG_SCHEMA,
|
|
20
|
+
eventSchema: stripeSemanticEventSchema("checkout.session.async_payment_failed"),
|
|
21
|
+
},
|
|
22
|
+
"stripe.checkout.session.asyncPaymentSucceeded": {
|
|
23
|
+
configSchema: STRIPE_TRIGGER_CONFIG_SCHEMA,
|
|
24
|
+
eventSchema: stripeSemanticEventSchema("checkout.session.async_payment_succeeded"),
|
|
25
|
+
},
|
|
26
|
+
"stripe.checkout.session.expired": {
|
|
27
|
+
configSchema: STRIPE_TRIGGER_CONFIG_SCHEMA,
|
|
28
|
+
eventSchema: stripeSemanticEventSchema("checkout.session.expired"),
|
|
29
|
+
},
|
|
30
|
+
"stripe.customer.created": {
|
|
31
|
+
configSchema: STRIPE_TRIGGER_CONFIG_SCHEMA,
|
|
32
|
+
eventSchema: stripeSemanticEventSchema("customer.created"),
|
|
33
|
+
},
|
|
34
|
+
"stripe.customer.deleted": {
|
|
35
|
+
configSchema: STRIPE_TRIGGER_CONFIG_SCHEMA,
|
|
36
|
+
eventSchema: stripeSemanticEventSchema("customer.deleted"),
|
|
37
|
+
},
|
|
38
|
+
"stripe.customer.subscription.created": {
|
|
39
|
+
configSchema: STRIPE_TRIGGER_CONFIG_SCHEMA,
|
|
40
|
+
eventSchema: stripeSemanticEventSchema("customer.subscription.created"),
|
|
41
|
+
},
|
|
42
|
+
"stripe.customer.subscription.deleted": {
|
|
43
|
+
configSchema: STRIPE_TRIGGER_CONFIG_SCHEMA,
|
|
44
|
+
eventSchema: stripeSemanticEventSchema("customer.subscription.deleted"),
|
|
45
|
+
},
|
|
46
|
+
"stripe.customer.subscription.trialWillEnd": {
|
|
47
|
+
configSchema: STRIPE_TRIGGER_CONFIG_SCHEMA,
|
|
48
|
+
eventSchema: stripeSemanticEventSchema("customer.subscription.trial_will_end"),
|
|
49
|
+
},
|
|
50
|
+
"stripe.customer.subscription.updated": {
|
|
51
|
+
configSchema: STRIPE_TRIGGER_CONFIG_SCHEMA,
|
|
52
|
+
eventSchema: stripeSemanticEventSchema("customer.subscription.updated"),
|
|
53
|
+
},
|
|
54
|
+
"stripe.customer.updated": {
|
|
55
|
+
configSchema: STRIPE_TRIGGER_CONFIG_SCHEMA,
|
|
56
|
+
eventSchema: stripeSemanticEventSchema("customer.updated"),
|
|
57
|
+
},
|
|
58
|
+
"stripe.event": {
|
|
59
|
+
configSchema: STRIPE_TRIGGER_CONFIG_SCHEMA,
|
|
60
|
+
eventSchema: STRIPE_EVENT_SCHEMA,
|
|
61
|
+
},
|
|
62
|
+
"stripe.invoice.finalized": {
|
|
63
|
+
configSchema: STRIPE_TRIGGER_CONFIG_SCHEMA,
|
|
64
|
+
eventSchema: stripeSemanticEventSchema("invoice.finalized"),
|
|
65
|
+
},
|
|
66
|
+
"stripe.invoice.overdue": {
|
|
67
|
+
configSchema: STRIPE_TRIGGER_CONFIG_SCHEMA,
|
|
68
|
+
eventSchema: stripeSemanticEventSchema("invoice.overdue"),
|
|
69
|
+
},
|
|
70
|
+
"stripe.invoice.paid": {
|
|
71
|
+
configSchema: STRIPE_TRIGGER_CONFIG_SCHEMA,
|
|
72
|
+
eventSchema: stripeSemanticEventSchema("invoice.paid"),
|
|
73
|
+
},
|
|
74
|
+
"stripe.invoice.paymentFailed": {
|
|
75
|
+
configSchema: STRIPE_TRIGGER_CONFIG_SCHEMA,
|
|
76
|
+
eventSchema: stripeSemanticEventSchema("invoice.payment_failed"),
|
|
77
|
+
},
|
|
78
|
+
"stripe.invoice.voided": {
|
|
79
|
+
configSchema: STRIPE_TRIGGER_CONFIG_SCHEMA,
|
|
80
|
+
eventSchema: stripeSemanticEventSchema("invoice.voided"),
|
|
81
|
+
},
|
|
82
|
+
"stripe.paymentIntent.canceled": {
|
|
83
|
+
configSchema: STRIPE_TRIGGER_CONFIG_SCHEMA,
|
|
84
|
+
eventSchema: stripeSemanticEventSchema("payment_intent.canceled"),
|
|
85
|
+
},
|
|
86
|
+
"stripe.paymentIntent.paymentFailed": {
|
|
87
|
+
configSchema: STRIPE_TRIGGER_CONFIG_SCHEMA,
|
|
88
|
+
eventSchema: stripeSemanticEventSchema("payment_intent.payment_failed"),
|
|
89
|
+
},
|
|
90
|
+
"stripe.paymentIntent.succeeded": {
|
|
91
|
+
configSchema: STRIPE_TRIGGER_CONFIG_SCHEMA,
|
|
92
|
+
eventSchema: stripeSemanticEventSchema("payment_intent.succeeded"),
|
|
93
|
+
},
|
|
94
|
+
"stripe.payout.failed": {
|
|
95
|
+
configSchema: STRIPE_TRIGGER_CONFIG_SCHEMA,
|
|
96
|
+
eventSchema: stripeSemanticEventSchema("payout.failed"),
|
|
97
|
+
},
|
|
98
|
+
"stripe.payout.paid": {
|
|
99
|
+
configSchema: STRIPE_TRIGGER_CONFIG_SCHEMA,
|
|
100
|
+
eventSchema: stripeSemanticEventSchema("payout.paid"),
|
|
101
|
+
},
|
|
102
|
+
"stripe.refund.created": {
|
|
103
|
+
configSchema: STRIPE_TRIGGER_CONFIG_SCHEMA,
|
|
104
|
+
eventSchema: stripeSemanticEventSchema("refund.created"),
|
|
105
|
+
},
|
|
106
|
+
"stripe.refund.failed": {
|
|
107
|
+
configSchema: STRIPE_TRIGGER_CONFIG_SCHEMA,
|
|
108
|
+
eventSchema: stripeSemanticEventSchema("refund.failed"),
|
|
109
|
+
},
|
|
110
|
+
};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { Encodable } from "@automate.ax/codec";
|
|
2
|
+
import type Stripe from "stripe";
|
|
3
|
+
import type { CamelCasedPropertiesDeep } from "type-fest";
|
|
4
|
+
import * as z from "zod";
|
|
5
|
+
export declare const STRIPE_SEMANTIC_EVENT_TYPES: readonly ["charge.dispute.closed", "charge.dispute.created", "checkout.session.async_payment_failed", "checkout.session.async_payment_succeeded", "checkout.session.completed", "checkout.session.expired", "customer.created", "customer.deleted", "customer.subscription.created", "customer.subscription.deleted", "customer.subscription.trial_will_end", "customer.subscription.updated", "customer.updated", "invoice.finalized", "invoice.overdue", "invoice.paid", "invoice.payment_failed", "invoice.voided", "payment_intent.canceled", "payment_intent.payment_failed", "payment_intent.succeeded", "payout.failed", "payout.paid", "refund.created", "refund.failed"];
|
|
6
|
+
/** Public camelCase representation of an official Stripe event type. */
|
|
7
|
+
export type StripeEvent<TEvent extends Stripe.Event = Stripe.Event> = CamelCasedPropertiesDeep<TEvent> & Encodable;
|
|
8
|
+
/** Public event type for one exact Stripe event name. */
|
|
9
|
+
export type StripeSemanticEvent<TType extends Stripe.Event.Type> = StripeEvent<Extract<Stripe.Event, {
|
|
10
|
+
type: TType;
|
|
11
|
+
}>>;
|
|
12
|
+
export declare const STRIPE_EVENT_SCHEMA: z.ZodType<StripeEvent>;
|
|
13
|
+
/**
|
|
14
|
+
* Converts a verified provider event to its public camelCase representation.
|
|
15
|
+
*
|
|
16
|
+
* @param event - Verified provider event.
|
|
17
|
+
* @returns Validated public Stripe event.
|
|
18
|
+
*/
|
|
19
|
+
export declare function normalizeStripeEvent(event: unknown): StripeEvent;
|
|
20
|
+
/**
|
|
21
|
+
* Builds a schema that narrows a verified broad event to one Stripe type.
|
|
22
|
+
*
|
|
23
|
+
* @param type - Exact Stripe event name.
|
|
24
|
+
* @returns Runtime schema for the semantic event.
|
|
25
|
+
*/
|
|
26
|
+
export declare function stripeSemanticEventSchema<TType extends (typeof STRIPE_SEMANTIC_EVENT_TYPES)[number]>(type: TType): z.ZodType<StripeSemanticEvent<TType>>;
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import * as z from "zod";
|
|
2
|
+
export const STRIPE_SEMANTIC_EVENT_TYPES = [
|
|
3
|
+
"charge.dispute.closed",
|
|
4
|
+
"charge.dispute.created",
|
|
5
|
+
"checkout.session.async_payment_failed",
|
|
6
|
+
"checkout.session.async_payment_succeeded",
|
|
7
|
+
"checkout.session.completed",
|
|
8
|
+
"checkout.session.expired",
|
|
9
|
+
"customer.created",
|
|
10
|
+
"customer.deleted",
|
|
11
|
+
"customer.subscription.created",
|
|
12
|
+
"customer.subscription.deleted",
|
|
13
|
+
"customer.subscription.trial_will_end",
|
|
14
|
+
"customer.subscription.updated",
|
|
15
|
+
"customer.updated",
|
|
16
|
+
"invoice.finalized",
|
|
17
|
+
"invoice.overdue",
|
|
18
|
+
"invoice.paid",
|
|
19
|
+
"invoice.payment_failed",
|
|
20
|
+
"invoice.voided",
|
|
21
|
+
"payment_intent.canceled",
|
|
22
|
+
"payment_intent.payment_failed",
|
|
23
|
+
"payment_intent.succeeded",
|
|
24
|
+
"payout.failed",
|
|
25
|
+
"payout.paid",
|
|
26
|
+
"refund.created",
|
|
27
|
+
"refund.failed",
|
|
28
|
+
];
|
|
29
|
+
const STRIPE_EVENT_BASE_SCHEMA = z.looseObject({
|
|
30
|
+
apiVersion: z.string().nullable(),
|
|
31
|
+
created: z.number().int().nonnegative(),
|
|
32
|
+
data: z.looseObject({ object: z.looseObject({ object: z.string() }) }),
|
|
33
|
+
id: z.string().startsWith("evt_"),
|
|
34
|
+
livemode: z.boolean(),
|
|
35
|
+
object: z.literal("event"),
|
|
36
|
+
pendingWebhooks: z.number().int().nonnegative(),
|
|
37
|
+
request: z
|
|
38
|
+
.looseObject({
|
|
39
|
+
id: z.string().nullable(),
|
|
40
|
+
idempotencyKey: z.string().nullable(),
|
|
41
|
+
})
|
|
42
|
+
.nullable(),
|
|
43
|
+
type: z.string().min(1),
|
|
44
|
+
});
|
|
45
|
+
export const STRIPE_EVENT_SCHEMA = z.custom((value) => STRIPE_EVENT_BASE_SCHEMA.safeParse(value).success);
|
|
46
|
+
/**
|
|
47
|
+
* Converts a verified provider event to its public camelCase representation.
|
|
48
|
+
*
|
|
49
|
+
* @param event - Verified provider event.
|
|
50
|
+
* @returns Validated public Stripe event.
|
|
51
|
+
*/
|
|
52
|
+
export function normalizeStripeEvent(event) {
|
|
53
|
+
return STRIPE_EVENT_SCHEMA.parse(camelizeStripeValue(event));
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Builds a schema that narrows a verified broad event to one Stripe type.
|
|
57
|
+
*
|
|
58
|
+
* @param type - Exact Stripe event name.
|
|
59
|
+
* @returns Runtime schema for the semantic event.
|
|
60
|
+
*/
|
|
61
|
+
export function stripeSemanticEventSchema(type) {
|
|
62
|
+
return z.custom((value) => {
|
|
63
|
+
const event = STRIPE_EVENT_SCHEMA.safeParse(value);
|
|
64
|
+
return event.success && event.data.type === type;
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Converts provider object keys recursively while preserving metadata keys.
|
|
69
|
+
*
|
|
70
|
+
* @param value - Provider value to normalize.
|
|
71
|
+
* @returns Public value with camel-cased object keys.
|
|
72
|
+
*/
|
|
73
|
+
function camelizeStripeValue(value) {
|
|
74
|
+
if (Array.isArray(value))
|
|
75
|
+
return value.map(camelizeStripeValue);
|
|
76
|
+
if (!isPlainRecord(value))
|
|
77
|
+
return value;
|
|
78
|
+
return Object.fromEntries(Object.entries(value).map(([key, item]) => [
|
|
79
|
+
key.replace(/_([a-z0-9])/g, (_match, character) => character.toUpperCase()),
|
|
80
|
+
key === "metadata" ? item : camelizeStripeValue(item),
|
|
81
|
+
]));
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Checks whether a value is a plain record safe for key conversion.
|
|
85
|
+
*
|
|
86
|
+
* @param value - Value to inspect.
|
|
87
|
+
* @returns Whether the value is a plain record.
|
|
88
|
+
*/
|
|
89
|
+
function isPlainRecord(value) {
|
|
90
|
+
if (value === null || typeof value !== "object")
|
|
91
|
+
return false;
|
|
92
|
+
const prototype = Object.getPrototypeOf(value);
|
|
93
|
+
return prototype === null || prototype === Object.prototype;
|
|
94
|
+
}
|
package/dist/triggers.d.ts
CHANGED
|
@@ -11,12 +11,13 @@ import type { linearTriggerContracts } from "./linear/index.js";
|
|
|
11
11
|
import type { outlookTriggerContracts } from "./outlook/index.js";
|
|
12
12
|
import type { resendTriggerContracts } from "./resend/index.js";
|
|
13
13
|
import type { slackTriggerContracts } from "./slack/index.js";
|
|
14
|
+
import type { stripeTriggerContracts } from "./stripe/index.js";
|
|
14
15
|
import type { teamsTriggerContracts } from "./teams/index.js";
|
|
15
16
|
import type { trelloTriggerContracts } from "./trello/index.js";
|
|
16
17
|
import type { vercelTriggerContracts } from "./vercel/index.js";
|
|
17
18
|
import type { whatsappTriggerContracts } from "./whatsapp/index.js";
|
|
18
19
|
import type { z } from "zod";
|
|
19
|
-
export type TriggerContractMap = typeof airtableTriggerContracts & typeof asanaTriggerContracts & typeof brevoTriggerContracts & typeof convexTriggerContracts & typeof githubTriggerContracts & typeof gmailTriggerContracts & typeof googleCalendarTriggerContracts & typeof googleFormsTriggerContracts & typeof googleMeetTriggerContracts & typeof linearTriggerContracts & typeof outlookTriggerContracts & typeof resendTriggerContracts & typeof slackTriggerContracts & typeof teamsTriggerContracts & typeof trelloTriggerContracts & typeof vercelTriggerContracts & typeof whatsappTriggerContracts;
|
|
20
|
+
export type TriggerContractMap = typeof airtableTriggerContracts & typeof asanaTriggerContracts & typeof brevoTriggerContracts & typeof convexTriggerContracts & typeof githubTriggerContracts & typeof gmailTriggerContracts & typeof googleCalendarTriggerContracts & typeof googleFormsTriggerContracts & typeof googleMeetTriggerContracts & typeof linearTriggerContracts & typeof outlookTriggerContracts & typeof resendTriggerContracts & typeof slackTriggerContracts & typeof stripeTriggerContracts & typeof teamsTriggerContracts & typeof trelloTriggerContracts & typeof vercelTriggerContracts & typeof whatsappTriggerContracts;
|
|
20
21
|
export type IntegrationTriggerType = keyof TriggerContractMap;
|
|
21
22
|
/** Canonical authoring configuration for one integration trigger type. */
|
|
22
23
|
export type TriggerConfig<TType extends IntegrationTriggerType> = z.input<TriggerContractMap[TType]["configSchema"]> extends Record<string, never> ? object : z.input<TriggerContractMap[TType]["configSchema"]>;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@automate.ax/integration-contracts",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.84.0",
|
|
4
4
|
"description": "Shared integration payload contracts and provider primitives for Automate.ax.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -31,6 +31,7 @@
|
|
|
31
31
|
"./outlook": "./src/outlook/index.ts",
|
|
32
32
|
"./resend": "./src/resend/index.ts",
|
|
33
33
|
"./slack": "./src/slack/index.ts",
|
|
34
|
+
"./stripe": "./src/stripe/index.ts",
|
|
34
35
|
"./teams": "./src/teams/index.ts",
|
|
35
36
|
"./trello": "./src/trello/index.ts",
|
|
36
37
|
"./triggers": "./src/triggers.ts",
|
|
@@ -43,7 +44,7 @@
|
|
|
43
44
|
}
|
|
44
45
|
},
|
|
45
46
|
"dependencies": {
|
|
46
|
-
"@automate.ax/codec": "0.
|
|
47
|
+
"@automate.ax/codec": "0.84.0",
|
|
47
48
|
"@googleapis/calendar": "^15.0.0",
|
|
48
49
|
"@googleapis/forms": "^6.0.1",
|
|
49
50
|
"@googleapis/gmail": "^12.0.0",
|
|
@@ -54,6 +55,7 @@
|
|
|
54
55
|
"html-to-text": "^10.0.0",
|
|
55
56
|
"nodemailer": "^9.0.3",
|
|
56
57
|
"postal-mime": "^2.7.5",
|
|
58
|
+
"stripe": "^22.1.0",
|
|
57
59
|
"type-fest": "^5.6.0",
|
|
58
60
|
"zod": "^4.3.6"
|
|
59
61
|
},
|
|
@@ -153,6 +155,11 @@
|
|
|
153
155
|
"types": "./dist/slack/index.d.ts",
|
|
154
156
|
"default": "./dist/slack/index.js"
|
|
155
157
|
},
|
|
158
|
+
"./stripe": {
|
|
159
|
+
"bun": "./src/stripe/index.ts",
|
|
160
|
+
"types": "./dist/stripe/index.d.ts",
|
|
161
|
+
"default": "./dist/stripe/index.js"
|
|
162
|
+
},
|
|
156
163
|
"./teams": {
|
|
157
164
|
"bun": "./src/teams/index.ts",
|
|
158
165
|
"types": "./dist/teams/index.d.ts",
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
import * as z from "zod"
|
|
2
|
+
import type { StripeEvent, StripeSemanticEvent } from "./schemas"
|
|
3
|
+
import { STRIPE_EVENT_SCHEMA, stripeSemanticEventSchema } from "./schemas"
|
|
4
|
+
|
|
5
|
+
export * from "./schemas"
|
|
6
|
+
|
|
7
|
+
export const STRIPE_TRIGGER_CONFIG_SCHEMA = z.object({})
|
|
8
|
+
|
|
9
|
+
type StripeTriggerContract<TEvent> = {
|
|
10
|
+
readonly configSchema: typeof STRIPE_TRIGGER_CONFIG_SCHEMA
|
|
11
|
+
readonly eventSchema: z.ZodType<TEvent>
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
type StripeSemanticTriggerEventTypes = {
|
|
15
|
+
readonly "stripe.charge.dispute.closed": "charge.dispute.closed"
|
|
16
|
+
readonly "stripe.charge.dispute.created": "charge.dispute.created"
|
|
17
|
+
readonly "stripe.checkout.session.asyncPaymentFailed": "checkout.session.async_payment_failed"
|
|
18
|
+
readonly "stripe.checkout.session.asyncPaymentSucceeded": "checkout.session.async_payment_succeeded"
|
|
19
|
+
readonly "stripe.checkout.session.completed": "checkout.session.completed"
|
|
20
|
+
readonly "stripe.checkout.session.expired": "checkout.session.expired"
|
|
21
|
+
readonly "stripe.customer.created": "customer.created"
|
|
22
|
+
readonly "stripe.customer.deleted": "customer.deleted"
|
|
23
|
+
readonly "stripe.customer.subscription.created": "customer.subscription.created"
|
|
24
|
+
readonly "stripe.customer.subscription.deleted": "customer.subscription.deleted"
|
|
25
|
+
readonly "stripe.customer.subscription.trialWillEnd": "customer.subscription.trial_will_end"
|
|
26
|
+
readonly "stripe.customer.subscription.updated": "customer.subscription.updated"
|
|
27
|
+
readonly "stripe.customer.updated": "customer.updated"
|
|
28
|
+
readonly "stripe.invoice.finalized": "invoice.finalized"
|
|
29
|
+
readonly "stripe.invoice.overdue": "invoice.overdue"
|
|
30
|
+
readonly "stripe.invoice.paid": "invoice.paid"
|
|
31
|
+
readonly "stripe.invoice.paymentFailed": "invoice.payment_failed"
|
|
32
|
+
readonly "stripe.invoice.voided": "invoice.voided"
|
|
33
|
+
readonly "stripe.paymentIntent.canceled": "payment_intent.canceled"
|
|
34
|
+
readonly "stripe.paymentIntent.paymentFailed": "payment_intent.payment_failed"
|
|
35
|
+
readonly "stripe.paymentIntent.succeeded": "payment_intent.succeeded"
|
|
36
|
+
readonly "stripe.payout.failed": "payout.failed"
|
|
37
|
+
readonly "stripe.payout.paid": "payout.paid"
|
|
38
|
+
readonly "stripe.refund.created": "refund.created"
|
|
39
|
+
readonly "stripe.refund.failed": "refund.failed"
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Named registry shape keeps declaration emit independent of Stripe's private
|
|
44
|
+
* resource modules.
|
|
45
|
+
*/
|
|
46
|
+
type StripeTriggerContracts = {
|
|
47
|
+
readonly [TTrigger in keyof StripeSemanticTriggerEventTypes]: StripeTriggerContract<
|
|
48
|
+
StripeSemanticEvent<StripeSemanticTriggerEventTypes[TTrigger]>
|
|
49
|
+
>
|
|
50
|
+
} & {
|
|
51
|
+
readonly "stripe.event": StripeTriggerContract<StripeEvent>
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export const stripeTriggerContracts: StripeTriggerContracts = {
|
|
55
|
+
"stripe.charge.dispute.closed": {
|
|
56
|
+
configSchema: STRIPE_TRIGGER_CONFIG_SCHEMA,
|
|
57
|
+
eventSchema: stripeSemanticEventSchema("charge.dispute.closed"),
|
|
58
|
+
},
|
|
59
|
+
"stripe.charge.dispute.created": {
|
|
60
|
+
configSchema: STRIPE_TRIGGER_CONFIG_SCHEMA,
|
|
61
|
+
eventSchema: stripeSemanticEventSchema("charge.dispute.created"),
|
|
62
|
+
},
|
|
63
|
+
"stripe.checkout.session.completed": {
|
|
64
|
+
configSchema: STRIPE_TRIGGER_CONFIG_SCHEMA,
|
|
65
|
+
eventSchema: stripeSemanticEventSchema("checkout.session.completed"),
|
|
66
|
+
},
|
|
67
|
+
"stripe.checkout.session.asyncPaymentFailed": {
|
|
68
|
+
configSchema: STRIPE_TRIGGER_CONFIG_SCHEMA,
|
|
69
|
+
eventSchema: stripeSemanticEventSchema(
|
|
70
|
+
"checkout.session.async_payment_failed",
|
|
71
|
+
),
|
|
72
|
+
},
|
|
73
|
+
"stripe.checkout.session.asyncPaymentSucceeded": {
|
|
74
|
+
configSchema: STRIPE_TRIGGER_CONFIG_SCHEMA,
|
|
75
|
+
eventSchema: stripeSemanticEventSchema(
|
|
76
|
+
"checkout.session.async_payment_succeeded",
|
|
77
|
+
),
|
|
78
|
+
},
|
|
79
|
+
"stripe.checkout.session.expired": {
|
|
80
|
+
configSchema: STRIPE_TRIGGER_CONFIG_SCHEMA,
|
|
81
|
+
eventSchema: stripeSemanticEventSchema("checkout.session.expired"),
|
|
82
|
+
},
|
|
83
|
+
"stripe.customer.created": {
|
|
84
|
+
configSchema: STRIPE_TRIGGER_CONFIG_SCHEMA,
|
|
85
|
+
eventSchema: stripeSemanticEventSchema("customer.created"),
|
|
86
|
+
},
|
|
87
|
+
"stripe.customer.deleted": {
|
|
88
|
+
configSchema: STRIPE_TRIGGER_CONFIG_SCHEMA,
|
|
89
|
+
eventSchema: stripeSemanticEventSchema("customer.deleted"),
|
|
90
|
+
},
|
|
91
|
+
"stripe.customer.subscription.created": {
|
|
92
|
+
configSchema: STRIPE_TRIGGER_CONFIG_SCHEMA,
|
|
93
|
+
eventSchema: stripeSemanticEventSchema("customer.subscription.created"),
|
|
94
|
+
},
|
|
95
|
+
"stripe.customer.subscription.deleted": {
|
|
96
|
+
configSchema: STRIPE_TRIGGER_CONFIG_SCHEMA,
|
|
97
|
+
eventSchema: stripeSemanticEventSchema("customer.subscription.deleted"),
|
|
98
|
+
},
|
|
99
|
+
"stripe.customer.subscription.trialWillEnd": {
|
|
100
|
+
configSchema: STRIPE_TRIGGER_CONFIG_SCHEMA,
|
|
101
|
+
eventSchema: stripeSemanticEventSchema(
|
|
102
|
+
"customer.subscription.trial_will_end",
|
|
103
|
+
),
|
|
104
|
+
},
|
|
105
|
+
"stripe.customer.subscription.updated": {
|
|
106
|
+
configSchema: STRIPE_TRIGGER_CONFIG_SCHEMA,
|
|
107
|
+
eventSchema: stripeSemanticEventSchema("customer.subscription.updated"),
|
|
108
|
+
},
|
|
109
|
+
"stripe.customer.updated": {
|
|
110
|
+
configSchema: STRIPE_TRIGGER_CONFIG_SCHEMA,
|
|
111
|
+
eventSchema: stripeSemanticEventSchema("customer.updated"),
|
|
112
|
+
},
|
|
113
|
+
"stripe.event": {
|
|
114
|
+
configSchema: STRIPE_TRIGGER_CONFIG_SCHEMA,
|
|
115
|
+
eventSchema: STRIPE_EVENT_SCHEMA,
|
|
116
|
+
},
|
|
117
|
+
"stripe.invoice.finalized": {
|
|
118
|
+
configSchema: STRIPE_TRIGGER_CONFIG_SCHEMA,
|
|
119
|
+
eventSchema: stripeSemanticEventSchema("invoice.finalized"),
|
|
120
|
+
},
|
|
121
|
+
"stripe.invoice.overdue": {
|
|
122
|
+
configSchema: STRIPE_TRIGGER_CONFIG_SCHEMA,
|
|
123
|
+
eventSchema: stripeSemanticEventSchema("invoice.overdue"),
|
|
124
|
+
},
|
|
125
|
+
"stripe.invoice.paid": {
|
|
126
|
+
configSchema: STRIPE_TRIGGER_CONFIG_SCHEMA,
|
|
127
|
+
eventSchema: stripeSemanticEventSchema("invoice.paid"),
|
|
128
|
+
},
|
|
129
|
+
"stripe.invoice.paymentFailed": {
|
|
130
|
+
configSchema: STRIPE_TRIGGER_CONFIG_SCHEMA,
|
|
131
|
+
eventSchema: stripeSemanticEventSchema("invoice.payment_failed"),
|
|
132
|
+
},
|
|
133
|
+
"stripe.invoice.voided": {
|
|
134
|
+
configSchema: STRIPE_TRIGGER_CONFIG_SCHEMA,
|
|
135
|
+
eventSchema: stripeSemanticEventSchema("invoice.voided"),
|
|
136
|
+
},
|
|
137
|
+
"stripe.paymentIntent.canceled": {
|
|
138
|
+
configSchema: STRIPE_TRIGGER_CONFIG_SCHEMA,
|
|
139
|
+
eventSchema: stripeSemanticEventSchema("payment_intent.canceled"),
|
|
140
|
+
},
|
|
141
|
+
"stripe.paymentIntent.paymentFailed": {
|
|
142
|
+
configSchema: STRIPE_TRIGGER_CONFIG_SCHEMA,
|
|
143
|
+
eventSchema: stripeSemanticEventSchema("payment_intent.payment_failed"),
|
|
144
|
+
},
|
|
145
|
+
"stripe.paymentIntent.succeeded": {
|
|
146
|
+
configSchema: STRIPE_TRIGGER_CONFIG_SCHEMA,
|
|
147
|
+
eventSchema: stripeSemanticEventSchema("payment_intent.succeeded"),
|
|
148
|
+
},
|
|
149
|
+
"stripe.payout.failed": {
|
|
150
|
+
configSchema: STRIPE_TRIGGER_CONFIG_SCHEMA,
|
|
151
|
+
eventSchema: stripeSemanticEventSchema("payout.failed"),
|
|
152
|
+
},
|
|
153
|
+
"stripe.payout.paid": {
|
|
154
|
+
configSchema: STRIPE_TRIGGER_CONFIG_SCHEMA,
|
|
155
|
+
eventSchema: stripeSemanticEventSchema("payout.paid"),
|
|
156
|
+
},
|
|
157
|
+
"stripe.refund.created": {
|
|
158
|
+
configSchema: STRIPE_TRIGGER_CONFIG_SCHEMA,
|
|
159
|
+
eventSchema: stripeSemanticEventSchema("refund.created"),
|
|
160
|
+
},
|
|
161
|
+
"stripe.refund.failed": {
|
|
162
|
+
configSchema: STRIPE_TRIGGER_CONFIG_SCHEMA,
|
|
163
|
+
eventSchema: stripeSemanticEventSchema("refund.failed"),
|
|
164
|
+
},
|
|
165
|
+
}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import type { Encodable } from "@automate.ax/codec"
|
|
2
|
+
import type Stripe from "stripe"
|
|
3
|
+
import type { CamelCasedPropertiesDeep } from "type-fest"
|
|
4
|
+
import * as z from "zod"
|
|
5
|
+
|
|
6
|
+
export const STRIPE_SEMANTIC_EVENT_TYPES = [
|
|
7
|
+
"charge.dispute.closed",
|
|
8
|
+
"charge.dispute.created",
|
|
9
|
+
"checkout.session.async_payment_failed",
|
|
10
|
+
"checkout.session.async_payment_succeeded",
|
|
11
|
+
"checkout.session.completed",
|
|
12
|
+
"checkout.session.expired",
|
|
13
|
+
"customer.created",
|
|
14
|
+
"customer.deleted",
|
|
15
|
+
"customer.subscription.created",
|
|
16
|
+
"customer.subscription.deleted",
|
|
17
|
+
"customer.subscription.trial_will_end",
|
|
18
|
+
"customer.subscription.updated",
|
|
19
|
+
"customer.updated",
|
|
20
|
+
"invoice.finalized",
|
|
21
|
+
"invoice.overdue",
|
|
22
|
+
"invoice.paid",
|
|
23
|
+
"invoice.payment_failed",
|
|
24
|
+
"invoice.voided",
|
|
25
|
+
"payment_intent.canceled",
|
|
26
|
+
"payment_intent.payment_failed",
|
|
27
|
+
"payment_intent.succeeded",
|
|
28
|
+
"payout.failed",
|
|
29
|
+
"payout.paid",
|
|
30
|
+
"refund.created",
|
|
31
|
+
"refund.failed",
|
|
32
|
+
] as const satisfies readonly Stripe.Event.Type[]
|
|
33
|
+
|
|
34
|
+
const STRIPE_EVENT_BASE_SCHEMA = z.looseObject({
|
|
35
|
+
apiVersion: z.string().nullable(),
|
|
36
|
+
created: z.number().int().nonnegative(),
|
|
37
|
+
data: z.looseObject({ object: z.looseObject({ object: z.string() }) }),
|
|
38
|
+
id: z.string().startsWith("evt_"),
|
|
39
|
+
livemode: z.boolean(),
|
|
40
|
+
object: z.literal("event"),
|
|
41
|
+
pendingWebhooks: z.number().int().nonnegative(),
|
|
42
|
+
request: z
|
|
43
|
+
.looseObject({
|
|
44
|
+
id: z.string().nullable(),
|
|
45
|
+
idempotencyKey: z.string().nullable(),
|
|
46
|
+
})
|
|
47
|
+
.nullable(),
|
|
48
|
+
type: z.string().min(1),
|
|
49
|
+
})
|
|
50
|
+
|
|
51
|
+
/** Public camelCase representation of an official Stripe event type. */
|
|
52
|
+
export type StripeEvent<TEvent extends Stripe.Event = Stripe.Event> =
|
|
53
|
+
CamelCasedPropertiesDeep<TEvent> & Encodable
|
|
54
|
+
|
|
55
|
+
/** Public event type for one exact Stripe event name. */
|
|
56
|
+
export type StripeSemanticEvent<TType extends Stripe.Event.Type> = StripeEvent<
|
|
57
|
+
Extract<Stripe.Event, { type: TType }>
|
|
58
|
+
>
|
|
59
|
+
|
|
60
|
+
export const STRIPE_EVENT_SCHEMA: z.ZodType<StripeEvent> =
|
|
61
|
+
z.custom<StripeEvent>(
|
|
62
|
+
(value) => STRIPE_EVENT_BASE_SCHEMA.safeParse(value).success,
|
|
63
|
+
)
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Converts a verified provider event to its public camelCase representation.
|
|
67
|
+
*
|
|
68
|
+
* @param event - Verified provider event.
|
|
69
|
+
* @returns Validated public Stripe event.
|
|
70
|
+
*/
|
|
71
|
+
export function normalizeStripeEvent(event: unknown): StripeEvent {
|
|
72
|
+
return STRIPE_EVENT_SCHEMA.parse(camelizeStripeValue(event))
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Builds a schema that narrows a verified broad event to one Stripe type.
|
|
77
|
+
*
|
|
78
|
+
* @param type - Exact Stripe event name.
|
|
79
|
+
* @returns Runtime schema for the semantic event.
|
|
80
|
+
*/
|
|
81
|
+
export function stripeSemanticEventSchema<
|
|
82
|
+
TType extends (typeof STRIPE_SEMANTIC_EVENT_TYPES)[number],
|
|
83
|
+
>(type: TType): z.ZodType<StripeSemanticEvent<TType>> {
|
|
84
|
+
return z.custom<StripeSemanticEvent<TType>>((value) => {
|
|
85
|
+
const event = STRIPE_EVENT_SCHEMA.safeParse(value)
|
|
86
|
+
return event.success && event.data.type === type
|
|
87
|
+
})
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Converts provider object keys recursively while preserving metadata keys.
|
|
92
|
+
*
|
|
93
|
+
* @param value - Provider value to normalize.
|
|
94
|
+
* @returns Public value with camel-cased object keys.
|
|
95
|
+
*/
|
|
96
|
+
function camelizeStripeValue(value: unknown): unknown {
|
|
97
|
+
if (Array.isArray(value)) return value.map(camelizeStripeValue)
|
|
98
|
+
if (!isPlainRecord(value)) return value
|
|
99
|
+
|
|
100
|
+
return Object.fromEntries(
|
|
101
|
+
Object.entries(value).map(([key, item]) => [
|
|
102
|
+
key.replace(/_([a-z0-9])/g, (_match, character: string) =>
|
|
103
|
+
character.toUpperCase(),
|
|
104
|
+
),
|
|
105
|
+
key === "metadata" ? item : camelizeStripeValue(item),
|
|
106
|
+
]),
|
|
107
|
+
)
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Checks whether a value is a plain record safe for key conversion.
|
|
112
|
+
*
|
|
113
|
+
* @param value - Value to inspect.
|
|
114
|
+
* @returns Whether the value is a plain record.
|
|
115
|
+
*/
|
|
116
|
+
function isPlainRecord(value: unknown): value is Record<string, unknown> {
|
|
117
|
+
if (value === null || typeof value !== "object") return false
|
|
118
|
+
const prototype = Object.getPrototypeOf(value)
|
|
119
|
+
return prototype === null || prototype === Object.prototype
|
|
120
|
+
}
|
package/src/triggers.ts
CHANGED
|
@@ -11,6 +11,7 @@ import type { linearTriggerContracts } from "./linear"
|
|
|
11
11
|
import type { outlookTriggerContracts } from "./outlook"
|
|
12
12
|
import type { resendTriggerContracts } from "./resend"
|
|
13
13
|
import type { slackTriggerContracts } from "./slack"
|
|
14
|
+
import type { stripeTriggerContracts } from "./stripe"
|
|
14
15
|
import type { teamsTriggerContracts } from "./teams"
|
|
15
16
|
import type { trelloTriggerContracts } from "./trello"
|
|
16
17
|
import type { vercelTriggerContracts } from "./vercel"
|
|
@@ -30,6 +31,7 @@ export type TriggerContractMap = typeof airtableTriggerContracts &
|
|
|
30
31
|
typeof outlookTriggerContracts &
|
|
31
32
|
typeof resendTriggerContracts &
|
|
32
33
|
typeof slackTriggerContracts &
|
|
34
|
+
typeof stripeTriggerContracts &
|
|
33
35
|
typeof teamsTriggerContracts &
|
|
34
36
|
typeof trelloTriggerContracts &
|
|
35
37
|
typeof vercelTriggerContracts &
|