Adding compound triggers to Stripe and added a WIP express adapter

This commit is contained in:
Eric Allam
2023-08-01 16:06:42 +01:00
parent a489fd465f
commit 9544624e00
15 changed files with 956 additions and 7 deletions
+6
View File
@@ -0,0 +1,6 @@
---
"@trigger.dev/stripe": patch
"@trigger.dev/express": patch
---
Adding compound triggers to Stripe and added a WIP express adapter
@@ -4,6 +4,10 @@ import { ActionArgs } from "@remix-run/server-runtime";
To use this route, use the stripe CLI to forward events to this route:
stripe listen --forward-to localhost:3030/api/internal/stripe_webhooks
Then you can trigger events using the stripe CLI:
stripe trigger price.created
*/
export async function action({ request }: ActionArgs) {
const body: any = await request.json();
+2
View File
@@ -0,0 +1,2 @@
TRIGGER_API_KEY=
TRIGGER_API_URL=http://localhost:3030
+59
View File
@@ -0,0 +1,59 @@
## Example Job Catalog
This project is meant to be used to create a catalog of jobs, usually to test something in an integration or the SDK.
### Running
Each file in `src` is a separate set of jobs that can be run separately. For example, the `src/stripe.ts` file can be run with:
```sh
cd examples/job-catalog
pnpm run stripe
```
This will open up a local server using `express` on port 8080. Then in a new terminal window you can run the trigger-cli dev command:
```sh
cd examples/job-catalog
pnpm run trigger:dev
```
### Adding a new file
You can add a new file to `src` with it's own `TriggerClient` and set of jobs (e.g. `src/events.ts`)
```ts
import { TriggerClient, eventTrigger } from "@trigger.dev/sdk";
import { createExpressServer } from "@trigger.dev/express";
import { z } from "zod";
export const client = new TriggerClient({
id: "job-catalog",
apiKey: process.env["TRIGGER_API_KEY"],
apiUrl: process.env["TRIGGER_API_URL"],
verbose: false,
ioLogLocalEnabled: true,
});
client.defineJob({
id: "example-job-1",
name: "Example Job 1",
version: "0.1.0",
trigger: eventTrigger({
name: "example.one",
}),
run: async (payload, io, ctx) => {},
});
createExpressServer(client);
```
Then add a new script in [`package.json`](./package.json):
```json
{
"scripts": {
"events": "nodemon --watch src/events.ts -r tsconfig-paths/register -r dotenv/config src/events.ts"
}
}
```
+35
View File
@@ -0,0 +1,35 @@
{
"name": "@examples/job-catalog",
"version": "0.1.0",
"private": true,
"scripts": {
"stripe": "nodemon --watch src/stripe.ts -r tsconfig-paths/register -r dotenv/config src/stripe.ts",
"dev:trigger": "trigger-cli dev --port 8080"
},
"dependencies": {
"@trigger.dev/express": "workspace:*",
"@trigger.dev/github": "workspace:*",
"@trigger.dev/openai": "workspace:*",
"@trigger.dev/plain": "workspace:*",
"@trigger.dev/resend": "workspace:*",
"@trigger.dev/sdk": "workspace:*",
"@trigger.dev/slack": "workspace:*",
"@trigger.dev/stripe": "workspace:*",
"@trigger.dev/typeform": "workspace:*",
"@types/node": "20.4.2",
"typescript": "5.1.6",
"zod": "3.21.4"
},
"trigger.dev": {
"endpointId": "job-catalog"
},
"devDependencies": {
"@trigger.dev/cli": "workspace:*",
"@trigger.dev/tsconfig": "workspace:*",
"concurrently": "^8.2.0",
"dotenv": "^16.3.1",
"nodemon": "^3.0.1",
"ts-node": "^10.9.1",
"tsconfig-paths": "^3.14.1"
}
}
+184
View File
@@ -0,0 +1,184 @@
import { TriggerClient, eventTrigger } from "@trigger.dev/sdk";
import { createExpressServer } from "@trigger.dev/express";
import { z } from "zod";
import { Stripe } from "@trigger.dev/stripe";
export const client = new TriggerClient({
id: "job-catalog",
apiKey: process.env["TRIGGER_API_KEY"],
apiUrl: process.env["TRIGGER_API_URL"],
verbose: false,
ioLogLocalEnabled: true,
});
const stripe = new Stripe({
id: "stripe",
apiKey: process.env["STRIPE_API_KEY"]!,
});
client.defineJob({
id: "stripe-example-1",
name: "Stripe Example 1",
version: "0.1.0",
trigger: eventTrigger({
name: "stripe.example",
schema: z.object({
customerId: z.string(),
source: z.string(),
}),
}),
integrations: {
stripe,
},
run: async (payload, io, ctx) => {
await io.stripe.createCharge("create-charge", {
amount: 100,
currency: "usd",
source: payload.source,
customer: payload.customerId,
});
},
});
client.defineJob({
id: "stripe-example-1",
name: "Stripe Example 1",
version: "0.1.0",
trigger: eventTrigger({
name: "stripe.example",
schema: z.object({
customerId: z.string(),
source: z.string(),
}),
}),
integrations: {
stripe,
},
run: async (payload, io, ctx) => {
await io.stripe.createCharge("create-charge", {
amount: 100,
currency: "usd",
source: payload.source,
customer: payload.customerId,
});
},
});
client.defineJob({
id: "stripe-create-customer",
name: "Stripe Create Customer",
version: "0.1.0",
trigger: eventTrigger({
name: "stripe.new.customer",
schema: z.object({
email: z.string(),
name: z.string(),
}),
}),
integrations: {
stripe,
},
run: async (payload, io, ctx) => {
await io.stripe.createCustomer("create-customer", {
email: payload.email,
name: payload.name,
});
},
});
client.defineJob({
id: "stripe-update-customer",
name: "Stripe Update Customer",
version: "0.1.0",
trigger: eventTrigger({
name: "stripe.update.customer",
schema: z.object({
customerId: z.string(),
name: z.string(),
}),
}),
integrations: {
stripe,
},
run: async (payload, io, ctx) => {
await io.stripe.updateCustomer("update-customer", {
id: payload.customerId,
name: payload.name,
});
},
});
client.defineJob({
id: "stripe-retrieve-subscription",
name: "Stripe Retrieve Subscription",
version: "0.1.0",
trigger: eventTrigger({
name: "stripe.retrieve.subscription",
schema: z.object({
id: z.string(),
}),
}),
integrations: {
stripe,
},
run: async (payload, io, ctx) => {
const subscription = await io.stripe.retrieveSubscription("get", {
id: payload.id,
expand: ["customer"],
});
},
});
client.defineJob({
id: "stripe-on-price",
name: "Stripe On Price",
version: "0.1.0",
trigger: stripe.onPrice({ events: ["price.created", "price.updated"] }),
run: async (payload, io, ctx) => {
if (ctx.event.name === "price.created") {
await io.logger.info("price created!", { ctx });
} else {
await io.logger.info("price updated!", { ctx });
}
},
});
client.defineJob({
id: "stripe-on-product",
name: "Stripe On Product",
version: "0.1.0",
trigger: stripe.onProduct({ events: ["product.created", "product.deleted"] }),
run: async (payload, io, ctx) => {
if (ctx.event.name === "product.created") {
await io.logger.info("product created!", { ctx });
} else {
await io.logger.info("product deleted!", { ctx });
}
},
});
client.defineJob({
id: "stripe-on-price-created",
name: "Stripe On Price Created",
version: "0.1.0",
trigger: stripe.onPriceCreated(),
run: async (payload, io, ctx) => {
await io.logger.info("ctx", { ctx });
},
});
client.defineJob({
id: "stripe-on-subscription-created",
name: "Stripe On Subscription Created",
version: "0.1.0",
trigger: stripe.onCustomerSubscriptionCreated({
filter: {
currency: ["usd"],
},
}),
run: async (payload, io, ctx) => {
await io.logger.info("ctx", { ctx });
},
});
createExpressServer(client);
+35
View File
@@ -0,0 +1,35 @@
{
"extends": "@trigger.dev/tsconfig/node18.json",
"include": ["./src/**/*.ts"],
"compilerOptions": {
"baseUrl": ".",
"lib": ["DOM", "DOM.Iterable"],
"paths": {
"@/*": ["./src/*"],
"@trigger.dev/sdk": ["../../packages/trigger-sdk/src/index"],
"@trigger.dev/sdk/*": ["../../packages/trigger-sdk/src/*"],
"@trigger.dev/express": ["../../packages/express/src/index"],
"@trigger.dev/express/*": ["../../packages/express/src/*"],
"@trigger.dev/core": ["../../packages/core/src/index"],
"@trigger.dev/core/*": ["../../packages/core/src/*"],
"@trigger.dev/integration-kit": ["../../packages/integration-kit/src/index"],
"@trigger.dev/integration-kit/*": ["../../packages/integration-kit/src/*"],
"@trigger.dev/github": ["../../integrations/github/src/index"],
"@trigger.dev/github/*": ["../../integrations/github/src/*"],
"@trigger.dev/slack": ["../../integrations/slack/src/index"],
"@trigger.dev/slack/*": ["../../integrations/slack/src/*"],
"@trigger.dev/openai": ["../../integrations/openai/src/index"],
"@trigger.dev/openai/*": ["../../integrations/openai/src/*"],
"@trigger.dev/resend": ["../../integrations/resend/src/index"],
"@trigger.dev/resend/*": ["../../integrations/resend/src/*"],
"@trigger.dev/typeform": ["../../integrations/typeform/src/index"],
"@trigger.dev/typeform/*": ["../../integrations/typeform/src/*"],
"@trigger.dev/plain": ["../../integrations/plain/src/index"],
"@trigger.dev/plain/*": ["../../integrations/plain/src/*"],
"@trigger.dev/supabase": ["../../integrations/supabase/src/index"],
"@trigger.dev/supabase/*": ["../../integrations/supabase/src/*"],
"@trigger.dev/stripe": ["../../integrations/stripe/src/index"],
"@trigger.dev/stripe/*": ["../../integrations/stripe/src/*"]
}
}
}
@@ -121,6 +121,20 @@ client.defineJob({
},
});
client.defineJob({
id: "stripe-on-price",
name: "Stripe On Price",
version: "0.1.0",
trigger: stripe.onPrice({ events: ["price.created", "price.updated"] }),
run: async (payload, io, ctx) => {
if (ctx.event.name === "price.created") {
await io.logger.info("price created!", { ctx });
} else {
await io.logger.info("price updated!", { ctx });
}
},
});
client.defineJob({
id: "stripe-on-price-created",
name: "Stripe On Price Created",
+117
View File
@@ -139,6 +139,86 @@ export const onPriceDeleted: EventSpecification<OnPriceEvent> = {
runProperties: (payload) => [{ label: "Price ID", text: payload.id }],
};
export const onPrice: EventSpecification<OnPriceEvent> = {
name: ["price.created", "price.updated", "price.deleted"],
title: "On Price",
source: "stripe.com",
icon: "stripe",
examples: [
{
id: "recurring",
name: "Recurring Price",
icon: "stripe",
payload: {
id: "plan_OLCbCoAUbHPcHT",
object: "price",
active: false,
billing_scheme: "per_unit",
created: 1690472058,
currency: "usd",
custom_unit_amount: null,
livemode: false,
lookup_key: null,
metadata: {},
nickname: null,
product: "prod_OLCbckE3tpR34b",
recurring: {
aggregate_usage: null,
interval: "month",
interval_count: 1,
trial_period_days: null,
usage_type: "licensed",
},
tax_behavior: "unspecified",
tiers_mode: null,
transform_quantity: null,
type: "recurring",
unit_amount: 2000,
unit_amount_decimal: "2000",
},
},
],
parsePayload: (payload) => payload as OnPriceEvent,
runProperties: (payload) => [{ label: "Price ID", text: payload.id }],
};
export const onProduct: EventSpecification<OnProductEvent> = {
name: ["product.created", "product.updated", "product.deleted"],
title: "On Product",
source: "stripe.com",
icon: "stripe",
examples: [
{
id: "mock_product",
name: "Mock Product",
icon: "stripe",
payload: {
id: "prod_OLBTh0QPxDXkIU",
object: "product",
active: true,
attributes: [],
created: 1690467853,
default_price: null,
description: "(created by Stripe CLI)",
images: [],
livemode: false,
metadata: {},
name: "myproduct",
package_dimensions: null,
shippable: null,
statement_descriptor: null,
tax_code: null,
type: "service",
unit_label: null,
updated: 1690467853,
url: null,
},
},
],
parsePayload: (payload) => payload as OnProductEvent,
runProperties: (payload) => [{ label: "Product ID", text: payload.id }],
};
export const onProductCreated: EventSpecification<OnProductEvent> = {
name: "product.created",
title: "On Product Created",
@@ -250,6 +330,21 @@ export const onProductDeleted: EventSpecification<OnProductEvent> = {
runProperties: (payload) => [{ label: "Product ID", text: payload.id }],
};
export const onCheckoutSession: EventSpecification<OnCheckoutSession> = {
name: [
"checkout.session.completed",
"checkout.session.async_payment_succeeded",
"checkout.session.async_payment_failed",
"checkout.session.expired",
],
title: "On Checkout Session",
source: "stripe.com",
icon: "stripe",
examples: [checkoutSessionExample],
parsePayload: (payload) => payload as OnCheckoutSession,
runProperties: (payload) => [{ label: "Session ID", text: payload.id }],
};
export const onCheckoutSessionCompleted: EventSpecification<OnCheckoutSession> = {
name: "checkout.session.completed",
title: "On Checkout Session Completed",
@@ -270,6 +365,28 @@ export const onCheckoutSessionExpired: EventSpecification<OnCheckoutSession> = {
runProperties: (payload) => [{ label: "Session ID", text: payload.id }],
};
export const onCustomerSubscription: EventSpecification<OnCustomerSubscription> = {
name: [
"customer.subscription.created",
"customer.subscription.deleted",
"customer.subscription.updated",
"customer.subscription.paused",
"customer.subscription.pending_update_applied",
"customer.subscription.pending_update_expired",
"customer.subscription.resumed",
"customer.subscription.trial_will_end",
],
title: "On Customer Subscription",
source: "stripe.com",
icon: "stripe",
examples: [customerSubscriptionExample],
parsePayload: (payload) => payload as OnCustomerSubscription,
runProperties: (payload) => [
{ label: "Subscription ID", text: payload.id },
{ label: "Status", text: payload.status },
],
};
export const onCustomerSubscriptionCreated: EventSpecification<OnCustomerSubscription> = {
name: "customer.subscription.created",
title: "On Customer Subscription Created",
+148 -3
View File
@@ -1,4 +1,3 @@
import { Stripe as StripeClient } from "stripe";
import {
EventFilter,
ExternalSource,
@@ -8,11 +7,12 @@ import {
type Logger,
type TriggerIntegration,
} from "@trigger.dev/sdk";
import type { StripeSDK, StripeIntegrationOptions, WebhookEvents } from "./types";
import { Stripe as StripeClient } from "stripe";
import type { StripeIntegrationOptions, StripeSDK, WebhookEvents } from "./types";
import * as tasks from "./tasks";
import z from "zod";
import * as events from "./events";
import * as tasks from "./tasks";
export * from "./types";
@@ -75,6 +75,36 @@ export class Stripe implements StripeIntegration {
return createWebhookEventSource(this);
}
/**
* Occurs whenever a price is created, updated, or deleted. Accepts an optional array of events to filter on. By default it will listen to all price events.
*
* @example
* ```ts
* stripe.onPrice({ events: ["price.created", "price.updated"] })
* ```
*
* You can detect the event name in your job by using the `ctx.event.name` property:
*
* ```ts
* client.defineJob({
* id: "stripe-price",
* name: "Stripe Price",
* version: "0.1.0",
* trigger: stripe.onPrice({ events: ["price.created", "price.updated"] }),
* run: async (payload, io, ctx) => {
* console.log(ctx.event.name); // "price.created" or "price.updated"
* },
* });
* ```
*/
onPrice(
params?: TriggerParams & { events?: Array<"price.created" | "price.updated" | "price.deleted"> }
) {
const event = { ...events.onPrice, name: params?.events ?? events.onPrice.name };
return createTrigger(this.source, event, params ?? { connect: false });
}
/**
* Occurs whenever a price is created.
*/
@@ -96,6 +126,38 @@ export class Stripe implements StripeIntegration {
return createTrigger(this.source, events.onPriceDeleted, params ?? { connect: false });
}
/**
* Occurs whenever a product is created, updated, or deleted. Accepts an optional array of events to filter on. By default it will listen to all product events.
*
* @example
* ```ts
* stripe.onProduct({ events: ["product.created", "product.updated"] })
* ```
*
* You can detect the event name in your job by using the `ctx.event.name` property:
*
* ```ts
* client.defineJob({
* id: "stripe-example",
* name: "Stripe Example",
* version: "0.1.0",
* trigger: stripe.onProduct({ events: ["product.created", "product.updated"] }),
* run: async (payload, io, ctx) => {
* console.log(ctx.event.name); // "product.created" or "product.updated"
* },
* });
* ```
*/
onProduct(
params?: TriggerParams & {
events?: Array<"product.created" | "product.updated" | "product.deleted">;
}
) {
const event = { ...events.onProduct, name: params?.events ?? events.onProduct.name };
return createTrigger(this.source, event, params ?? { connect: false });
}
/**
* Occurs whenever a product is created.
*/
@@ -117,6 +179,46 @@ export class Stripe implements StripeIntegration {
return createTrigger(this.source, events.onProductDeleted, params ?? { connect: false });
}
/**
* Occurs whenever a checkout.session is completed, expired, async_payment_succeeded, or async_payment_failed. Accepts an optional array of events to filter on. By default it will listen to all checkout.session events.
*
* @example
* ```ts
* stripe.onCheckoutSession({ events: ["session.checkout.completed", "session.checkout.expired"] })
* ```
*
* You can detect the event name in your job by using the `ctx.event.name` property:
*
* ```ts
* client.defineJob({
* id: "stripe-example",
* name: "Stripe Example",
* version: "0.1.0",
* trigger: stripe.onCheckoutSession({ events: ["checkout.session.completed", "checkout.session.expired"] }),
* run: async (payload, io, ctx) => {
* console.log(ctx.event.name); // "checkout.session.completed" or "checkout.session.expired"
* },
* });
* ```
*/
onCheckoutSession(
params?: TriggerParams & {
events?: Array<
| "checkout.session.completed"
| "checkout.session.async_payment_succeeded"
| "checkout.session.async_payment_failed"
| "checkout.session.expired"
>;
}
) {
const event = {
...events.onCheckoutSession,
name: params?.events ?? events.onCheckoutSession.name,
};
return createTrigger(this.source, event, params ?? { connect: false });
}
/**
* Occurs when a Checkout Session has been successfully completed.
*/
@@ -139,6 +241,49 @@ export class Stripe implements StripeIntegration {
);
}
/**
* Occurs on any customer.subscription.* event. Accepts an optional array of events to filter on. By default it will listen to all customer.subscription.* events.
*
* @example
* ```ts
* stripe.onCustomerSubscription({ events: ["customer.subscription.created", "customer.subscription.resumed"] })
* ```
*
* You can detect the event name in your job by using the `ctx.event.name` property:
*
* ```ts
* client.defineJob({
* id: "stripe-example",
* name: "Stripe Example",
* version: "0.1.0",
* trigger: stripe.onCustomerSubscription({ events: ["customer.subscription.created", "customer.subscription.resumed"] }),
* run: async (payload, io, ctx) => {
* console.log(ctx.event.name); // "customer.subscription.created" or "customer.subscription.resumed"
* },
* });
* ```
*/
onCustomerSubscription(
params?: TriggerParams & {
events?: Array<
| "customer.subscription.created"
| "customer.subscription.deleted"
| "customer.subscription.updated"
| "customer.subscription.paused"
| "customer.subscription.pending_update_applied"
| "customer.subscription.pending_update_expired"
| "customer.subscription.resumed"
>;
}
) {
const event = {
...events.onCustomerSubscription,
name: params?.events ?? events.onCustomerSubscription.name,
};
return createTrigger(this.source, event, params ?? { connect: false });
}
/**
* Occurs whenever a customer is signed up for a new plan.
*/
+45
View File
@@ -0,0 +1,45 @@
{
"name": "@trigger.dev/express",
"version": "1.0.0",
"description": "Official Express adapter for Trigger.dev",
"main": "./dist/index.js",
"types": "./dist/index.d.ts",
"publishConfig": {
"access": "public"
},
"files": [
"dist"
],
"exports": {
".": {
"import": "./dist/index.js",
"require": "./dist/index.js"
},
"./package.json": "./package.json"
},
"devDependencies": {
"@trigger.dev/sdk": "workspace:^2.0.0-next.22",
"@trigger.dev/tsconfig": "workspace:*",
"@types/debug": "^4.1.7",
"@types/express": "^4.17.13",
"rimraf": "^3.0.2",
"tsup": "^6.5.0",
"tsx": "^3.12.1"
},
"scripts": {
"clean": "rimraf dist",
"build": "npm run clean && npm run build:tsup",
"build:tsup": "tsup"
},
"peerDependencies": {
"@trigger.dev/sdk": "workspace:^2.0.0-next.22"
},
"dependencies": {
"@remix-run/web-fetch": "^4.3.5",
"debug": "^4.3.4",
"express": "^4.18.2"
},
"engines": {
"node": ">=16.8.0"
}
}
+93
View File
@@ -0,0 +1,93 @@
import express, { Express } from "express";
import { TriggerClient } from "@trigger.dev/sdk";
import { Request as StandardRequest, Headers as StandardHeaders } from "@remix-run/web-fetch";
/**
* This is a convienence function to create an express server for the TriggerClient. If you want to use Trigger.dev with an existing express server, use `createMiddleware` instead.
* @param client - The TriggerClient to use for the server.
* @param port - The port to listen on, defaults to 8080.
*/
export function createExpressServer(
client: TriggerClient,
port: number = 8080,
path: string = "/api/trigger"
): Express {
const app = express();
const middleware = createMiddleware(client, path);
app.use(middleware);
app.listen(port, () => {
console.log(`Endpoint ${client.id} listening on port ${port}`);
});
return app;
}
/**
* This function configures a middleware to use with an existing express server.
* @param client - The TriggerClient to use for the middleware.
* @param path - The path to listen on, defaults to "/api/trigger".
*
* @example
* ```ts
* import express from "express";
* import { TriggerClient } from "@trigger.dev/sdk";
* import { createMiddleware } from "@trigger.dev/express";
*
* const client = new TriggerClient({
* id: "my-client",
* apiKey: process.env["TRIGGER_API_KEY"]!,
* });
*
* const app = express();
*
* const middleware = createMiddleware(client);
*
* app.use(middleware);
*
* app.listen(8080, () => {
* console.log("Listening on port 8080");
* });
* ```
*/
export function createMiddleware(client: TriggerClient, path: string = "/api/trigger") {
return async (req: express.Request, res: express.Response, next: express.NextFunction) => {
if (req.path !== path) {
next();
return;
}
const request = convertToStandardRequest(req);
const response = await client.handleRequest(request);
if (!response) {
res.status(404).json({ error: "Not found" });
return;
}
res.status(response.status).json(response.body);
};
}
function convertToStandardRequest(req: express.Request): StandardRequest {
const { headers: nextHeaders, method } = req;
const headers = new StandardHeaders();
Object.entries(nextHeaders).forEach(([key, value]) => {
headers.set(key, value as string);
});
// Create a new Request object (hardcode the url because it doesn't really matter what it is)
return new StandardRequest("https://express.js/api/trigger", {
headers,
method,
// @ts-ignore
body: req,
});
}
+11
View File
@@ -0,0 +1,11 @@
{
"extends": "@trigger.dev/tsconfig/node18.json",
"include": ["./src/**/*.ts", "tsup.config.ts"],
"compilerOptions": {
"experimentalDecorators": true,
"emitDecoratorMetadata": true,
"declaration": false,
"declarationMap": false
},
"exclude": ["node_modules"]
}
+19
View File
@@ -0,0 +1,19 @@
import { defineConfig } from "tsup";
export default defineConfig([
{
name: "main",
entry: ["./src/index.ts"],
outDir: "./dist",
platform: "node",
format: ["cjs"],
legacyOutput: true,
sourcemap: true,
clean: true,
bundle: true,
splitting: false,
dts: true,
external: ["http", "https", "util", "events", "tty", "os", "timers"],
esbuildPlugins: [],
},
]);
+184 -4
View File
@@ -348,6 +348,49 @@ importers:
config-packages/tsconfig:
specifiers: {}
examples/job-catalog:
specifiers:
'@trigger.dev/cli': workspace:*
'@trigger.dev/express': workspace:*
'@trigger.dev/github': workspace:*
'@trigger.dev/openai': workspace:*
'@trigger.dev/plain': workspace:*
'@trigger.dev/resend': workspace:*
'@trigger.dev/sdk': workspace:*
'@trigger.dev/slack': workspace:*
'@trigger.dev/stripe': workspace:*
'@trigger.dev/tsconfig': workspace:*
'@trigger.dev/typeform': workspace:*
'@types/node': 20.4.2
concurrently: ^8.2.0
dotenv: ^16.3.1
nodemon: ^3.0.1
ts-node: ^10.9.1
tsconfig-paths: ^3.14.1
typescript: 5.1.6
zod: 3.21.4
dependencies:
'@trigger.dev/express': link:../../packages/express
'@trigger.dev/github': link:../../integrations/github
'@trigger.dev/openai': link:../../integrations/openai
'@trigger.dev/plain': link:../../integrations/plain
'@trigger.dev/resend': link:../../integrations/resend
'@trigger.dev/sdk': link:../../packages/trigger-sdk
'@trigger.dev/slack': link:../../integrations/slack
'@trigger.dev/stripe': link:../../integrations/stripe
'@trigger.dev/typeform': link:../../integrations/typeform
'@types/node': 20.4.2
typescript: 5.1.6
zod: 3.21.4
devDependencies:
'@trigger.dev/cli': link:../../packages/cli
'@trigger.dev/tsconfig': link:../../config-packages/tsconfig
concurrently: 8.2.0
dotenv: 16.3.1
nodemon: 3.0.1
ts-node: 10.9.1_xj5cs2fmhcigm4w5bhhtewqeja
tsconfig-paths: 3.14.1
examples/jobs-starter:
specifiers:
'@trigger.dev/cli': workspace:*
@@ -836,6 +879,31 @@ importers:
'@types/react': 18.2.17
typescript: 4.9.5
packages/express:
specifiers:
'@remix-run/web-fetch': ^4.3.5
'@trigger.dev/sdk': workspace:^2.0.0-next.22
'@trigger.dev/tsconfig': workspace:*
'@types/debug': ^4.1.7
'@types/express': ^4.17.13
debug: ^4.3.4
express: ^4.18.2
rimraf: ^3.0.2
tsup: ^6.5.0
tsx: ^3.12.1
dependencies:
'@remix-run/web-fetch': 4.3.5
debug: 4.3.4
express: 4.18.2
devDependencies:
'@trigger.dev/sdk': link:../trigger-sdk
'@trigger.dev/tsconfig': link:../../config-packages/tsconfig
'@types/debug': 4.1.7
'@types/express': 4.17.15
rimraf: 3.0.2
tsup: 6.6.3
tsx: 3.12.2
packages/integration-kit:
specifiers:
'@trigger.dev/tsconfig': workspace:*
@@ -8460,6 +8528,19 @@ packages:
data-uri-to-buffer: 3.0.1
mrmime: 1.0.1
/@remix-run/web-fetch/4.3.5:
resolution: {integrity: sha512-cLLeNLvLRyFRhJLulzS98bb07kJ+ENkGaqUkBisdG4FNEoZF6tXtrTGLWJNJa1nAP/wFkMKEDxIP77LgAPyeow==}
engines: {node: ^10.17 || >=12.3}
dependencies:
'@remix-run/web-blob': 3.0.4
'@remix-run/web-form-data': 3.0.4
'@remix-run/web-stream': 1.0.3
'@web3-storage/multipart-parser': 1.0.0
abort-controller: 3.0.0
data-uri-to-buffer: 3.0.1
mrmime: 1.0.1
dev: false
/@remix-run/web-file/3.0.2:
resolution: {integrity: sha512-eFC93Onh/rZ5kUNpCQersmBtxedGpaXK2/gsUl49BYSGK/DvuPu3l06vmquEDdcPaEuXcsdGP0L7zrmUqrqo4A==}
dependencies:
@@ -10726,7 +10807,6 @@ packages:
/@types/node/20.4.2:
resolution: {integrity: sha512-Dd0BYtWgnWJKwO1jkmTrzofjK2QXXcai0dmtzvIBhcA+RsG5h8R3xlyta0kGOZRNfL9GuRtb1knmPEhQrePCEw==}
dev: false
/@types/node/20.4.5:
resolution: {integrity: sha512-rt40Nk13II9JwQBdeYqmbn2Q6IVTA5uPhvSO+JVqdXw/6/4glI6oR9ezty/A9Hg5u7JH4OmYmuQ+XvjKm0Datg==}
@@ -11428,7 +11508,6 @@ packages:
/abbrev/1.1.1:
resolution: {integrity: sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==}
dev: false
/abort-controller/3.0.0:
resolution: {integrity: sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==}
@@ -11498,6 +11577,7 @@ packages:
resolution: {integrity: sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA==}
engines: {node: '>=0.4.0'}
hasBin: true
dev: true
/address/1.2.2:
resolution: {integrity: sha512-4B/qKCfeE/ODUaAUpSwfzazo5x29WD4r3vXiWsB7I2mSDAihwEqKO+g8GELZUQSSAo5e1XTYh3ZVfLyxBc12nA==}
@@ -13368,6 +13448,18 @@ packages:
dependencies:
ms: 2.1.3
/debug/3.2.7_supports-color@5.5.0:
resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==}
peerDependencies:
supports-color: '*'
peerDependenciesMeta:
supports-color:
optional: true
dependencies:
ms: 2.1.3
supports-color: 5.5.0
dev: true
/debug/4.3.2:
resolution: {integrity: sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==}
engines: {node: '>=6.0'}
@@ -17063,6 +17155,10 @@ packages:
/ieee754/1.2.1:
resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==}
/ignore-by-default/1.0.1:
resolution: {integrity: sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==}
dev: true
/ignore/4.0.6:
resolution: {integrity: sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==}
engines: {node: '>= 4'}
@@ -19592,6 +19688,30 @@ packages:
/node-releases/2.0.12:
resolution: {integrity: sha512-QzsYKWhXTWx8h1kIvqfnC++o0pEmpRQA/aenALsL2F4pqNVr7YzcdMlDij5WBnwftRbJCNJL/O7zdKaxKPHqgQ==}
/nodemon/3.0.1:
resolution: {integrity: sha512-g9AZ7HmkhQkqXkRc20w+ZfQ73cHLbE8hnPbtaFbFtCumZsjyMhKk9LajQ07U5Ux28lvFjZ5X7HvWR1xzU8jHVw==}
engines: {node: '>=10'}
hasBin: true
dependencies:
chokidar: 3.5.3
debug: 3.2.7_supports-color@5.5.0
ignore-by-default: 1.0.1
minimatch: 3.1.2
pstree.remy: 1.1.8
semver: 7.5.4
simple-update-notifier: 2.0.0
supports-color: 5.5.0
touch: 3.1.0
undefsafe: 2.0.5
dev: true
/nopt/1.0.10:
resolution: {integrity: sha512-NWmpvLSqUrgrAC9HCuxEvb+PSloHpqVu+FqcO4eeF2h5qYRhA7ev6KvelyQAKtegUbC6RypJnlEOhd8vloNKYg==}
hasBin: true
dependencies:
abbrev: 1.1.1
dev: true
/nopt/6.0.0:
resolution: {integrity: sha512-ZwLpbTgdhuZUnZzjd7nb1ZV+4DoiC6/sfiVKok72ym/4Tlf+DFdlHYmT2JPmcNNWV6Pi3SDf1kT+A4r9RTuT9g==}
engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0}
@@ -21084,6 +21204,10 @@ packages:
/pseudomap/1.0.2:
resolution: {integrity: sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ==}
/pstree.remy/1.1.8:
resolution: {integrity: sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==}
dev: true
/pump/2.0.1:
resolution: {integrity: sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==}
dependencies:
@@ -22191,6 +22315,14 @@ packages:
dependencies:
lru-cache: 6.0.0
/semver/7.5.4:
resolution: {integrity: sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==}
engines: {node: '>=10'}
hasBin: true
dependencies:
lru-cache: 6.0.0
dev: true
/send/0.18.0:
resolution: {integrity: sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==}
engines: {node: '>= 0.8.0'}
@@ -22360,6 +22492,13 @@ packages:
semver: 7.0.0
dev: true
/simple-update-notifier/2.0.0:
resolution: {integrity: sha512-a2B9Y0KlNXl9u/vsW6sTIu9vGEpfKu2wRV6l1H3XEas/0gUIzGzBoP/IouTcUQbm9JWZLH3COxyn03TYlFax6w==}
engines: {node: '>=10'}
dependencies:
semver: 7.5.4
dev: true
/simplur/3.0.1:
resolution: {integrity: sha512-bBAoTn75tuKh83opmZ1VoyVoQIsvLCKzSxuasAxbnKofrT8eGyOEIaXSuNfhi/hI160+fwsR7ObcbBpOyzDvXg==}
dev: false
@@ -23402,6 +23541,13 @@ packages:
resolution: {integrity: sha512-y/mWCZinnvxjTKYhJ+pYxwD0mRLVvOtdS2Awbgxln6iEnt4rk0yBxeSBHkGJcPucRiG0e55mwWp+g/05rsrd6w==}
dev: true
/touch/3.1.0:
resolution: {integrity: sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA==}
hasBin: true
dependencies:
nopt: 1.0.10
dev: true
/tr46/0.0.3:
resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==}
@@ -23485,7 +23631,7 @@ packages:
'@tsconfig/node14': 1.0.3
'@tsconfig/node16': 1.0.3
'@types/node': 18.11.18
acorn: 8.8.1
acorn: 8.10.0
acorn-walk: 8.2.0
arg: 4.1.3
create-require: 1.1.1
@@ -23495,6 +23641,37 @@ packages:
v8-compile-cache-lib: 3.0.1
yn: 3.1.1
/ts-node/10.9.1_xj5cs2fmhcigm4w5bhhtewqeja:
resolution: {integrity: sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==}
hasBin: true
peerDependencies:
'@swc/core': '>=1.2.50'
'@swc/wasm': '>=1.2.50'
'@types/node': '*'
typescript: '>=2.7'
peerDependenciesMeta:
'@swc/core':
optional: true
'@swc/wasm':
optional: true
dependencies:
'@cspotcode/source-map-support': 0.8.1
'@tsconfig/node10': 1.0.9
'@tsconfig/node12': 1.0.11
'@tsconfig/node14': 1.0.3
'@tsconfig/node16': 1.0.3
'@types/node': 20.4.2
acorn: 8.10.0
acorn-walk: 8.2.0
arg: 4.1.3
create-require: 1.1.1
diff: 4.0.2
make-error: 1.3.6
typescript: 5.1.6
v8-compile-cache-lib: 3.0.1
yn: 3.1.1
dev: true
/tsafe/1.4.1:
resolution: {integrity: sha512-3IDBalvf6SyvHFS14UiwCWzqdSdo+Q0k2J7DZyJYaHW/iraW9DJpaBKDJpry3yQs3o/t/A+oGaRW3iVt2lKxzA==}
dev: false
@@ -24001,7 +24178,6 @@ packages:
resolution: {integrity: sha512-zaWCozRZ6DLEWAWFrVDz1H6FVXzUSfTy5FUMWsQlU8Ym5JP9eO4xkTIROFCQvhQf61z6O/G6ugw3SgAnvvm+HA==}
engines: {node: '>=14.17'}
hasBin: true
dev: false
/ufo/1.1.0:
resolution: {integrity: sha512-LQc2s/ZDMaCN3QLpa+uzHUOQ7SdV0qgv3VBXOolQGXTaaZpIur6PwUclF5nN2hNkiTRcUugXd1zFOW3FLJ135Q==}
@@ -24028,6 +24204,10 @@ packages:
has-symbols: 1.0.3
which-boxed-primitive: 1.0.2
/undefsafe/2.0.5:
resolution: {integrity: sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==}
dev: true
/unfetch/4.2.0:
resolution: {integrity: sha512-F9p7yYCn6cIW9El1zi0HI6vqpeIvBsr3dSuRO6Xuppb1u5rXpCPmMvLSyECLhybr9isec8Ohl0hPekMVrEinDA==}
dev: true