Getting slack/chat.postMessage to work

- Added ability for integrations to cache values
- Integrations now determine if a request is retryable
- Retried requests are now scheduled with a delay
This commit is contained in:
Eric Allam
2022-12-30 15:58:29 +00:00
parent 89ac379ce0
commit 8908d44206
19 changed files with 577 additions and 225 deletions
+1
View File
@@ -30,6 +30,7 @@ const EnvironmentSchema = z.object({
.string()
.default("0")
.transform((v) => v === "1"),
REDIS_URL: z.string().default("redis://localhost:6379"),
});
export type Environment = z.infer<typeof EnvironmentSchema>;
@@ -0,0 +1,18 @@
import type { CacheService } from "internal-integrations";
import { redis } from "./redis.server";
export class RedisCacheService implements CacheService {
constructor(private readonly namespace: string) {}
async get(key: string) {
return redis.get(`${this.namespace}:${key}`);
}
async set(key: string, value: string, ttl?: number): Promise<void> {
if (ttl) {
await redis.set(`${this.namespace}:${key}`, value, "EX", ttl);
} else {
await redis.set(`${this.namespace}:${key}`, value);
}
}
}
@@ -236,9 +236,22 @@ async function createRequestPubSub() {
PERFORM_INTEGRATION_REQUEST: async (id, data, properties) => {
const service = new PerformIntegrationRequest();
const success = await service.call(data.id);
const response = await service.call(data.id);
return success;
if (response.stop) {
return true;
} else {
await pubSub.publish(
"PERFORM_INTEGRATION_REQUEST",
{
id: data.id,
},
{},
{ deliverAfter: response.retryInSeconds * 1000 }
);
return true;
}
},
},
});
+23
View File
@@ -0,0 +1,23 @@
import type { Redis as RedisType } from "ioredis";
import Redis from "ioredis";
import { env } from "~/env.server";
let redis: RedisType;
declare global {
var __redis: RedisType | undefined;
}
// this is needed because in development we don't want to restart
// the server with every change, but we want to make sure we don't
// create a new connection to the Redis with every change either.
if (process.env.NODE_ENV === "production") {
redis = new Redis(env.REDIS_URL);
} else {
if (!global.__redis) {
global.__redis = new Redis(env.REDIS_URL);
}
redis = global.__redis;
}
export { redis };
@@ -74,6 +74,7 @@ export class CreateIntegrationRequest {
service: data.service,
type: "HTTP_API",
connectionId: existingConnection?.id,
status: existingConnection ? "READY" : "CREATED",
},
});
} else {
@@ -91,6 +92,7 @@ export class CreateIntegrationRequest {
},
data: {
connectionId: existingConnection.id,
status: existingConnection ? "READY" : "CREATED",
},
});
}
@@ -1,10 +1,24 @@
import type { NormalizedResponse } from "internal-integrations";
import type {
CacheService,
NormalizedResponse,
PerformedRequestResponse,
} from "internal-integrations";
import { slack } from "internal-integrations";
import type { PrismaClient } from "~/db.server";
import { prisma } from "~/db.server";
import type { IntegrationRequest } from "~/models/integrationRequest.server";
import { RedisCacheService } from "../cacheService.server";
import { pizzly } from "../pizzly.server";
type CallResponse =
| {
stop: true;
}
| {
stop: false;
retryInSeconds: number;
};
export class PerformIntegrationRequest {
#prismaClient: PrismaClient;
@@ -12,7 +26,7 @@ export class PerformIntegrationRequest {
this.#prismaClient = prismaClient;
}
async call(id: string): Promise<boolean> {
async call(id: string): Promise<CallResponse> {
const integrationRequest =
await this.#prismaClient.integrationRequest.findUnique({
where: { id },
@@ -26,11 +40,11 @@ export class PerformIntegrationRequest {
});
if (!integrationRequest) {
return false;
return { stop: true };
}
if (!integrationRequest.externalService.connection) {
return false;
return { stop: true };
}
const accessToken = await pizzly.accessToken(
@@ -39,34 +53,32 @@ export class PerformIntegrationRequest {
);
if (!accessToken) {
return false;
return { stop: true };
}
const response = await this.#performRequest(
integrationRequest.externalService.connection.apiIdentifier,
accessToken,
integrationRequest
const cache = new RedisCacheService(
integrationRequest.externalService.connection.id
);
switch (statusCodeToType(response.statusCode)) {
case "informational": {
return this.#completeWithSuccess(integrationRequest, response);
}
case "success": {
return this.#completeWithSuccess(integrationRequest, response);
}
case "redirect": {
return this.#completeWithFailure(integrationRequest, response);
}
case "clientError": {
return this.#completeWithFailure(integrationRequest, response);
}
case "serverError": {
return this.#attemptRetry(integrationRequest, response);
}
default: {
return this.#unknownError(integrationRequest, response);
}
const performedRequest = await this.#performRequest(
integrationRequest.externalService.connection.apiIdentifier,
accessToken,
integrationRequest,
cache
);
if (performedRequest.ok) {
return this.#completeWithSuccess(
integrationRequest,
performedRequest.response
);
} else if (performedRequest.isRetryable) {
return this.#attemptRetry(integrationRequest, performedRequest.response);
} else {
return this.#completeWithFailure(
integrationRequest,
performedRequest.response
);
}
}
@@ -100,7 +112,7 @@ export class PerformIntegrationRequest {
},
});
return true;
return { stop: true as const };
}
async #completeWithFailure(
@@ -133,7 +145,7 @@ export class PerformIntegrationRequest {
},
});
return true;
return { stop: true as const };
}
async #attemptRetry(
@@ -157,26 +169,39 @@ export class PerformIntegrationRequest {
await this.#createResponse(integrationRequest, response);
await this.#prismaClient.integrationRequest.update({
where: {
id: integrationRequest.id,
},
data: {
status: "RETRYING",
retryCount: {
increment: 1,
const updatedIntegrationRequest =
await this.#prismaClient.integrationRequest.update({
where: {
id: integrationRequest.id,
},
},
});
data: {
status: "RETRYING",
retryCount: {
increment: 1,
},
},
});
return false;
return {
stop: false as const,
retryInSeconds: this.#calculateRetryInSeconds(
updatedIntegrationRequest.retryCount
),
};
}
async #unknownError(
integrationRequest: IntegrationRequest,
response: NormalizedResponse
// Exponential backoff with a configurable factor and a configurable maximum
#calculateRetryInSeconds(
retryCount: number,
options: { factor: number; maxTimeout: number; minTimeout: number } = {
factor: 2,
minTimeout: 1000,
maxTimeout: Infinity,
}
) {
return false;
const timeout = options.factor ** retryCount * options.minTimeout;
return Math.min(timeout, options.maxTimeout);
}
async #createResponse(
@@ -193,7 +218,7 @@ export class PerformIntegrationRequest {
},
statusCode: response.statusCode,
headers: response.headers,
body: response.body,
body: response.body ? response.body : undefined,
},
});
@@ -203,14 +228,16 @@ export class PerformIntegrationRequest {
async #performRequest(
service: string,
accessToken: string,
integrationRequest: IntegrationRequest
): Promise<NormalizedResponse> {
integrationRequest: IntegrationRequest,
cache: CacheService
): Promise<PerformedRequestResponse> {
switch (service) {
case "slack": {
return slack.requests.perform({
accessToken,
endpoint: integrationRequest.endpoint,
params: integrationRequest.params,
cache,
});
}
default: {
@@ -219,29 +246,3 @@ export class PerformIntegrationRequest {
}
}
}
function statusCodeToType(
statusCode: number
): "informational" | "success" | "redirect" | "clientError" | "serverError" {
if (statusCode >= 100 && statusCode < 200) {
return "informational";
}
if (statusCode >= 200 && statusCode < 300) {
return "success";
}
if (statusCode >= 300 && statusCode < 400) {
return "redirect";
}
if (statusCode >= 400 && statusCode < 500) {
return "clientError";
}
if (statusCode >= 500 && statusCode < 600) {
return "serverError";
}
throw new Error(`Unknown status code: ${statusCode}`);
}
+1
View File
@@ -15,6 +15,7 @@
icon: /integrations/slack.png
scopes:
- channels:read
- channels:join
- chat:write
environments:
development:
+2 -1
View File
@@ -76,9 +76,10 @@
"date-fns": "2.0.0-alpha.7 || >=2.0.0",
"express": "^4.18.1",
"humanize-duration": "^3.27.3",
"internal-catalog": "workspace:*",
"internal-integrations": "workspace:*",
"internal-platform": "workspace:*",
"internal-catalog": "workspace:*",
"ioredis": "^5.2.4",
"javascript-time-ago": "^2.5.7",
"json-query": "^2.2.2",
"jsonata": "^1.8.6",
+1 -1
View File
@@ -122,7 +122,7 @@ model Workflow {
rules EventRule[]
externalServices ExternalService[]
service String @default("trigger")
service String @default("trigger")
eventNames String[]
@@unique([organizationId, slug])
+8
View File
@@ -20,6 +20,14 @@ services:
- database:/var/lib/postgresql/data
networks:
- app_network
redis:
image: redis:latest
container_name: redis
restart: always
ports:
- "6379:6379"
networks:
- app_network
pizzly-server:
image: nangohq/pizzly-server:0.4.3
container_name: pizzly-server
@@ -7,12 +7,14 @@
"types": "./src/index.ts",
"devDependencies": {
"@trigger.dev/tsconfig": "workspace:*",
"@types/debug": "^4.1.7",
"@types/node": "^18.11.9",
"typescript": "^4.9.4"
},
"scripts": {},
"dependencies": {
"@octokit/webhooks": "^10.4.0",
"debug": "^4.3.4",
"zod": "^3.20.2"
}
}
@@ -0,0 +1,116 @@
import { z } from "zod";
import { normalizeHeaders } from "../headers";
import debug from "debug";
const log = debug("trigger:integrations:services");
export type HttpServiceOptions = {
accessToken: string;
baseUrl: string;
};
export type HttpResponse<TResponseSchema extends z.ZodTypeAny> =
| {
success: true;
statusCode: number;
headers: Record<string, string>;
data: z.infer<TResponseSchema>;
}
| {
success: false;
statusCode: number;
headers: Record<string, string>;
};
export class HttpService {
constructor(private readonly options: HttpServiceOptions) {}
async performRequest<
TResponseSchema extends z.ZodTypeAny,
TBodySchema extends z.ZodTypeAny = z.ZodUndefined
>(
endpoint: HttpEndpoint<TResponseSchema, TBodySchema>,
body?: z.infer<TBodySchema>
): Promise<HttpResponse<TResponseSchema>> {
const response = await fetch(
`${this.options.baseUrl}${endpoint.options.path}`,
{
method: endpoint.options.method,
headers: {
Authorization: `Bearer ${this.options.accessToken}`,
"Content-Type": "application/json",
},
body: body ? JSON.stringify(body) : undefined,
}
);
log(
"%s%s response %d",
this.options.baseUrl,
endpoint.options.path,
response.status
);
const json = await this.#safeGetJson(response);
if (json) {
log(
"%s%s response %O",
this.options.baseUrl,
endpoint.options.path,
json
);
const parsedJson = endpoint.options.response.safeParse(json);
if (parsedJson.success) {
return {
success: true,
data: parsedJson.data,
statusCode: response.status,
headers: normalizeHeaders(response.headers),
};
}
log(
"response json failed to parse %O, errors: %O",
parsedJson,
parsedJson.error
);
}
return {
success: false,
statusCode: response.status,
headers: normalizeHeaders(response.headers),
};
}
#safeGetJson = async (response: Response) => {
try {
return await response.json();
} catch (error) {
return undefined;
}
};
}
export type HttpEndpointOptions<
TResponseSchema extends z.ZodTypeAny,
TBodySchema extends z.ZodTypeAny = z.ZodUndefined
> = {
response: TResponseSchema;
body?: TBodySchema;
method: "GET" | "POST" | "PUT" | "PATCH" | "DELETE";
path: string;
};
export class HttpEndpoint<
TResponseSchema extends z.ZodTypeAny,
TBodySchema extends z.ZodTypeAny = z.ZodUndefined
> {
constructor(
public options: HttpEndpointOptions<TResponseSchema, TBodySchema>
) {}
}
+148 -39
View File
@@ -1,22 +1,63 @@
import { normalizeHeaders } from "../headers";
import { HttpEndpoint, HttpService } from "../services";
import {
DisplayProperties,
NormalizedResponse,
CacheService,
PerformedRequestResponse,
PerformRequestOptions,
RequestIntegration,
} from "../types";
import { PostMessageResponseSchema, PostMessageBodySchema } from "./schemas";
import {
PostMessageResponseSchema,
PostMessageBodySchema,
JoinConversationResponseSchema,
JoinConversationBodySchema,
ListConversationsResponseSchema,
} from "./schemas";
export const schemas = {
PostMessageResponseSchema,
PostMessageBodySchema,
};
import debug from "debug";
const log = debug("trigger:integrations:slack");
class SlackRequestIntegration implements RequestIntegration {
perform(options: PerformRequestOptions): Promise<NormalizedResponse> {
#joinChannelEndpoint = new HttpEndpoint<
typeof JoinConversationResponseSchema,
typeof JoinConversationBodySchema
>({
response: JoinConversationResponseSchema,
method: "POST",
path: "/conversations.join",
});
#listConversationsEndpoint = new HttpEndpoint({
response: ListConversationsResponseSchema,
method: "GET",
path: "/conversations.list",
});
#postMessageEndpoint = new HttpEndpoint<
typeof PostMessageResponseSchema,
typeof PostMessageBodySchema
>({
response: PostMessageResponseSchema,
method: "POST",
path: "/chat.postMessage",
});
constructor(private readonly baseUrl: string = "https://slack.com/api") {}
perform(options: PerformRequestOptions): Promise<PerformedRequestResponse> {
switch (options.endpoint) {
case "chat.postMessage": {
return this.#postMessage(options.accessToken, options.params);
return this.#postMessage(
options.accessToken,
options.params,
options.cache
);
}
default: {
throw new Error(`Unknown endpoint: ${options.endpoint}`);
@@ -45,60 +86,128 @@ class SlackRequestIntegration implements RequestIntegration {
async #postMessage(
accessToken: string,
params: any
): Promise<NormalizedResponse> {
params: any,
cache?: CacheService
): Promise<PerformedRequestResponse> {
const parsedParams = PostMessageBodySchema.parse(params);
const channelId = await this.#findChannelId(
accessToken,
parsedParams.channel
);
log("chat.postMessage %O", parsedParams);
const response = await fetch("https://slack.com/api/chat.postMessage", {
method: "POST",
headers: {
Authorization: `Bearer ${accessToken}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
...parsedParams,
channel: channelId,
}),
const service = new HttpService({
accessToken,
baseUrl: this.baseUrl,
});
return {
statusCode: response.status,
headers: normalizeHeaders(response.headers),
body: await response.json(),
const channel = await this.#findChannelId(
service,
parsedParams.channel,
cache
);
log("found channelId %s", channel);
const response = await service.performRequest(this.#postMessageEndpoint, {
...parsedParams,
channel,
});
if (!response.success) {
log("chat.postMessage failed %O", response);
return {
ok: false,
isRetryable: this.#isRetryable(response.statusCode),
response: {
statusCode: response.statusCode,
headers: response.headers,
body: null,
},
};
}
if (!response.data.ok && response.data.error === "not_in_channel") {
log(
"chat.postMessage failed with not_in_channel, attempting to join channel %s",
channel
);
// Attempt to join the channel, and then retry the request
const joinResponse = await service.performRequest(
this.#joinChannelEndpoint,
{
channel,
}
);
if (joinResponse.success && joinResponse.data.ok) {
log("joined channel %s, retrying postMessage", channel);
return this.#postMessage(accessToken, params);
}
}
const ok = response.data.ok;
const performedRequest = {
ok,
isRetryable: this.#isRetryable(response.statusCode),
response: {
statusCode: response.statusCode,
headers: response.headers,
body: response.data,
},
};
log("chat.postMessage performedRequest %O", performedRequest);
return performedRequest;
}
#isRetryable(statusCode: number): boolean {
return (
statusCode === 408 ||
statusCode === 429 ||
statusCode === 500 ||
statusCode === 502 ||
statusCode === 503 ||
statusCode === 504
);
}
// Will use the conversations.list API (using fetch) to find the channel ID
// unless the channel is already provided in the format of a channelID (for example: "D8572TUFR" or "C01BQJZLJGZ")
async #findChannelId(
accessToken: string,
channel: string
): Promise<string | undefined> {
service: HttpService,
channel: string,
cache?: CacheService
): Promise<string> {
if (channel.startsWith("C") || channel.startsWith("D")) {
return channel;
}
const response = await fetch("https://slack.com/api/conversations.list", {
method: "GET",
headers: {
Authorization: `Bearer ${accessToken}`,
},
});
const cachedChannelId = await cache?.get(channel);
if (!response.ok) {
throw new Error("Failed to fetch channels");
if (cachedChannelId) {
return cachedChannelId;
}
const { channels } = await response.json();
const response = await service.performRequest(
this.#listConversationsEndpoint
);
const channelInfo = channels.find((c: any) => c.name === channel);
if (response.success && response.data.ok) {
const { channels } = response.data;
return channelInfo?.id;
const channelInfo = channels.find((c: any) => c.name === channel);
if (channelInfo) {
await cache?.set(channel, channelInfo.id, 60 * 60 * 24);
}
return channelInfo?.id || channel;
}
return channel;
}
}
@@ -1,21 +1,62 @@
import { z } from "zod";
export const PostMessageResponseSchema = z.object({
ok: z.boolean(),
export const PostMessageSuccessResponseSchema = z.object({
ok: z.literal(true),
channel: z.string(),
ts: z.string(),
message: z.object({
text: z.string(),
username: z.string(),
user: z.string(),
bot_id: z.string(),
attachments: z.array(z.unknown()),
attachments: z.array(z.unknown()).optional(),
type: z.string(),
subtype: z.string(),
subtype: z.string().optional(),
ts: z.string(),
}),
});
export const ErrorResponseSchema = z.object({
ok: z.literal(false),
error: z.string(),
});
export const PostMessageResponseSchema = z.discriminatedUnion("ok", [
PostMessageSuccessResponseSchema,
ErrorResponseSchema,
]);
export const PostMessageBodySchema = z.object({
channel: z.string(),
text: z.string(),
});
export const JoinConversationSuccessResponseSchema = z.object({
ok: z.literal(true),
channel: z.object({
id: z.string(),
}),
});
export const JoinConversationResponseSchema = z.discriminatedUnion("ok", [
JoinConversationSuccessResponseSchema,
ErrorResponseSchema,
]);
export const JoinConversationBodySchema = z.object({
channel: z.string(),
});
export const ListConversationsSuccessResponseSchema = z.object({
ok: z.literal(true),
channels: z.array(
z.object({
id: z.string(),
name: z.string(),
})
),
});
export const ListConversationsResponseSchema = z.discriminatedUnion("ok", [
ListConversationsSuccessResponseSchema,
ErrorResponseSchema,
]);
+15 -1
View File
@@ -33,6 +33,7 @@ export type PerformRequestOptions = {
accessToken: string;
endpoint: string;
params: any;
cache?: CacheService;
};
export type DisplayProperties = {
@@ -40,8 +41,16 @@ export type DisplayProperties = {
properties?: { key: string; value: string | number | boolean }[];
};
export interface PerformedRequestResponse {
response: NormalizedResponse;
isRetryable: boolean;
ok: boolean;
}
export interface RequestIntegration {
perform: (options: PerformRequestOptions) => Promise<NormalizedResponse>;
perform: (
options: PerformRequestOptions
) => Promise<PerformedRequestResponse>;
displayProperties: (endpoint: string, params: any) => DisplayProperties;
}
@@ -55,3 +64,8 @@ export interface WebhookIntegration {
| { status: "ignored"; reason: string }
| { status: "error"; error: string };
}
export interface CacheService {
get: (key: string) => Promise<string | null>;
set: (key: string, value: string, ttl?: number) => Promise<void>;
}
@@ -6,7 +6,7 @@ import {
import { MessageCatalogSchema } from "./messageCatalogSchema";
import { z } from "zod";
import { ZodPublisher } from "./zodPublisher";
import { PublishOptions, ZodPublisher } from "./zodPublisher";
import { ZodSubscriber, ZodSubscriberHandlers } from "./zodSubscriber";
export type ZodPubSubOptions<TPubSubSchema extends MessageCatalogSchema> = {
@@ -65,8 +65,9 @@ export class ZodPubSub<TPubSubSchema extends MessageCatalogSchema> {
public async publish<K extends keyof TPubSubSchema>(
type: K,
data: z.infer<TPubSubSchema[K]["data"]>,
properties?: z.infer<TPubSubSchema[K]["properties"]>
properties?: z.infer<TPubSubSchema[K]["properties"]>,
options?: PublishOptions
): Promise<string | undefined> {
return this.#publisher.publish(type, data, properties);
return this.#publisher.publish(type, data, properties, options);
}
}
@@ -9,6 +9,11 @@ import { ulid } from "ulid";
import { z, ZodError } from "zod";
export type PublishOptions = {
deliverAfter?: number;
deliverAt?: number;
};
export type ZodPublisherOptions<PublisherSchema extends MessageCatalogSchema> =
{
client: PulsarClient;
@@ -57,14 +62,15 @@ export class ZodPublisher<PublisherSchema extends MessageCatalogSchema> {
public async publish<K extends keyof PublisherSchema>(
type: K,
data: z.infer<PublisherSchema[K]["data"]>,
properties?: z.infer<PublisherSchema[K]["properties"]>
properties?: z.infer<PublisherSchema[K]["properties"]>,
options?: PublishOptions
): Promise<string | undefined> {
if (!this.#producer) {
throw new Error("Cannot publish before establishing connection");
}
try {
return this.#handlePublish(type, data, properties);
return this.#handlePublish(type, data, properties, options);
} catch (e) {
if (e instanceof ZodError) {
this.#logger.error(
@@ -81,7 +87,8 @@ export class ZodPublisher<PublisherSchema extends MessageCatalogSchema> {
async #handlePublish<K extends keyof PublisherSchema>(
type: K,
data: z.infer<PublisherSchema[K]["data"]>,
properties?: z.infer<PublisherSchema[K]["properties"]>
properties?: z.infer<PublisherSchema[K]["properties"]>,
options?: PublishOptions
): Promise<string> {
const messageSchema = this.#schema[type];
@@ -112,6 +119,8 @@ export class ZodPublisher<PublisherSchema extends MessageCatalogSchema> {
const response = await this.#producer!.send({
data: Buffer.from(message),
properties: parsedProperties,
deliverAfter: options?.deliverAfter,
deliverAt: options?.deliverAt,
});
return response.toString();
+55 -84
View File
@@ -152,6 +152,7 @@ importers:
internal-catalog: workspace:*
internal-integrations: workspace:*
internal-platform: workspace:*
ioredis: ^5.2.4
javascript-time-ago: ^2.5.7
json-query: ^2.2.2
jsonata: ^1.8.6
@@ -209,7 +210,7 @@ importers:
'@aws-sdk/client-s3': 3.226.0
'@aws-sdk/s3-request-presigner': 3.226.0
'@cfworker/json-schema': 1.12.5
'@codemirror/autocomplete': 6.3.4_jvia4rcxqiacrvood3734bhyuy
'@codemirror/autocomplete': 6.3.4_4npvozs3agsv66jx2b7pfvr53q
'@codemirror/commands': 6.1.2
'@codemirror/lang-javascript': 6.1.1
'@codemirror/lang-json': 6.0.1
@@ -235,7 +236,7 @@ importers:
'@tailwindcss/forms': 0.5.3_tailwindcss@3.1.8
'@tanstack/react-table': 8.7.0_biqbaboplfbrettd7655fr4n2y
'@trigger.dev/common-schemas': link:../../packages/common-schemas
'@uiw/react-codemirror': 4.17.1_c746qxthrd2ism2rvn4crnq5om
'@uiw/react-codemirror': 4.17.1_c6ric56h4625lhpbtenqifztqq
bcryptjs: 2.4.3
classnames: 2.3.2
clsx: 1.2.1
@@ -249,6 +250,7 @@ importers:
internal-catalog: link:../../packages/internal-catalog
internal-integrations: link:../../packages/internal-integrations
internal-platform: link:../../packages/internal-platform
ioredis: 5.2.4
javascript-time-ago: 2.5.9
json-query: 2.2.2
jsonata: 1.8.6
@@ -534,14 +536,18 @@ importers:
specifiers:
'@octokit/webhooks': ^10.4.0
'@trigger.dev/tsconfig': workspace:*
'@types/debug': ^4.1.7
'@types/node': ^18.11.9
debug: ^4.3.4
typescript: ^4.9.4
zod: ^3.20.2
dependencies:
'@octokit/webhooks': 10.4.0
debug: 4.3.4
zod: 3.20.2
devDependencies:
'@trigger.dev/tsconfig': link:../../config-packages/tsconfig
'@types/debug': 4.1.7
'@types/node': 18.11.15
typescript: 4.9.4
@@ -3301,13 +3307,12 @@ packages:
resolution: {integrity: sha512-LDQvVDv5Kb50ny2s25Fhm3d9QSZimsoUGBsUioj6MC3qbMUCuC8GPIvk/M6IvXx3lYhAs0lwWUQLb+VIEUCECw==}
dev: true
/@codemirror/autocomplete/6.3.4_jvia4rcxqiacrvood3734bhyuy:
/@codemirror/autocomplete/6.3.4_4npvozs3agsv66jx2b7pfvr53q:
resolution: {integrity: sha512-irxKsTSjS0OkfMWWt9YxtNK97++/E+XIHfKnRpSVfZyHzda/amYF0BR+T8mMkrGQWidx2zApxHx08GT13egyQA==}
peerDependencies:
'@codemirror/language': ^6.0.0
'@codemirror/state': ^6.0.0
'@codemirror/view': ^6.0.0
'@lezer/common': ^1.0.0
dependencies:
'@codemirror/language': 6.3.1
'@codemirror/state': 6.1.4
@@ -3327,7 +3332,7 @@ packages:
/@codemirror/lang-javascript/6.1.1:
resolution: {integrity: sha512-F4+kiuC5d5dUSJmff96tJQwpEXs/tX/4bapMRnZWW6bHKK1Fx6MunTzopkCUWRa9bF87GPmb9m7Qtg7Yv8f3uQ==}
dependencies:
'@codemirror/autocomplete': 6.3.4_jvia4rcxqiacrvood3734bhyuy
'@codemirror/autocomplete': 6.3.4_4npvozs3agsv66jx2b7pfvr53q
'@codemirror/language': 6.3.1
'@codemirror/lint': 6.1.0
'@codemirror/state': 6.1.4
@@ -3403,7 +3408,6 @@ packages:
engines: {node: '>=12'}
dependencies:
'@jridgewell/trace-mapping': 0.3.9
dev: true
/@cush/relative/1.0.0:
resolution: {integrity: sha512-RpfLEtTlyIxeNPGKcokS+p3BZII/Q3bYxryFRglh5H3A3T8q9fsLYm72VYAMEOOIBLEa8o93kFLiBDUWKrwXZA==}
@@ -3635,7 +3639,6 @@ packages:
/@jridgewell/resolve-uri/3.1.0:
resolution: {integrity: sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==}
engines: {node: '>=6.0.0'}
dev: true
/@jridgewell/set-array/1.1.2:
resolution: {integrity: sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==}
@@ -3644,7 +3647,6 @@ packages:
/@jridgewell/sourcemap-codec/1.4.14:
resolution: {integrity: sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==}
dev: true
/@jridgewell/trace-mapping/0.3.17:
resolution: {integrity: sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g==}
@@ -3658,7 +3660,6 @@ packages:
dependencies:
'@jridgewell/resolve-uri': 3.1.0
'@jridgewell/sourcemap-codec': 1.4.14
dev: true
/@jsonhero/fetch-hero/0.2.2:
resolution: {integrity: sha512-wO+JrqBfQDTtrGbxmAilJFaBLxdfVdeT7lsi+OaTqAv4taCU7aUzsGeDEtYvNF84xo/tCKi8F+YHiXM6k7er9Q==}
@@ -4051,7 +4052,7 @@ packages:
eslint: 8.29.0
eslint-import-resolver-node: 0.3.6
eslint-import-resolver-typescript: 3.5.2_lt3hqehuojhfcbzgzqfngbtmrq
eslint-plugin-import: 2.26.0_i656iqvetrvx3ajhg4t6psfrl4
eslint-plugin-import: 2.26.0_qfsg7upu5e4dqco5ntekgyqxwu
eslint-plugin-jest: 26.9.0_gtacs36c3cng3fu32eiajkw5qm
eslint-plugin-jest-dom: 4.0.3_eslint@8.29.0
eslint-plugin-jsx-a11y: 6.6.1_eslint@8.29.0
@@ -4401,7 +4402,6 @@ packages:
cpu: [arm64]
os: [darwin]
requiresBuild: true
dev: true
optional: true
/@swc/core-darwin-x64/1.3.21:
@@ -4410,7 +4410,6 @@ packages:
cpu: [x64]
os: [darwin]
requiresBuild: true
dev: true
optional: true
/@swc/core-linux-arm-gnueabihf/1.3.21:
@@ -4419,7 +4418,6 @@ packages:
cpu: [arm]
os: [linux]
requiresBuild: true
dev: true
optional: true
/@swc/core-linux-arm64-gnu/1.3.21:
@@ -4428,7 +4426,6 @@ packages:
cpu: [arm64]
os: [linux]
requiresBuild: true
dev: true
optional: true
/@swc/core-linux-arm64-musl/1.3.21:
@@ -4437,7 +4434,6 @@ packages:
cpu: [arm64]
os: [linux]
requiresBuild: true
dev: true
optional: true
/@swc/core-linux-x64-gnu/1.3.21:
@@ -4446,7 +4442,6 @@ packages:
cpu: [x64]
os: [linux]
requiresBuild: true
dev: true
optional: true
/@swc/core-linux-x64-musl/1.3.21:
@@ -4455,7 +4450,6 @@ packages:
cpu: [x64]
os: [linux]
requiresBuild: true
dev: true
optional: true
/@swc/core-win32-arm64-msvc/1.3.21:
@@ -4464,7 +4458,6 @@ packages:
cpu: [arm64]
os: [win32]
requiresBuild: true
dev: true
optional: true
/@swc/core-win32-ia32-msvc/1.3.21:
@@ -4473,7 +4466,6 @@ packages:
cpu: [ia32]
os: [win32]
requiresBuild: true
dev: true
optional: true
/@swc/core-win32-x64-msvc/1.3.21:
@@ -4482,7 +4474,6 @@ packages:
cpu: [x64]
os: [win32]
requiresBuild: true
dev: true
optional: true
/@swc/core/1.3.21:
@@ -4501,7 +4492,6 @@ packages:
'@swc/core-win32-arm64-msvc': 1.3.21
'@swc/core-win32-ia32-msvc': 1.3.21
'@swc/core-win32-x64-msvc': 1.3.21
dev: true
/@swc/helpers/0.4.14:
resolution: {integrity: sha512-4C7nX/dvpzB7za4Ql9K81xK3HPxCpHMgwTZVyf+9JQ6VUbn9jjZVN7/Nkdz/Ugzs2CSjqnL/UPXroiVBVHUWUw==}
@@ -4528,7 +4518,7 @@ packages:
tailwindcss: '>=3.0.0 || >= 3.0.0-alpha.1'
dependencies:
mini-svg-data-uri: 1.4.4
tailwindcss: 3.1.8_postcss@8.4.19
tailwindcss: 3.1.8_v776zzvn44o7tpgzieipaairwm
/@tailwindcss/typography/0.5.8_tailwindcss@3.1.8:
resolution: {integrity: sha512-xGQEp8KXN8Sd8m6R4xYmwxghmswrd0cPnNI2Lc6fmrC3OojysTBJJGSIVwPV56q4t6THFUK3HJ0EaWwpglSxWw==}
@@ -4539,7 +4529,7 @@ packages:
lodash.isplainobject: 4.0.6
lodash.merge: 4.6.2
postcss-selector-parser: 6.0.10
tailwindcss: 3.1.8_postcss@8.4.19
tailwindcss: 3.1.8_v776zzvn44o7tpgzieipaairwm
dev: true
/@tanstack/react-table/8.7.0_biqbaboplfbrettd7655fr4n2y:
@@ -4629,19 +4619,15 @@ packages:
/@tsconfig/node10/1.0.9:
resolution: {integrity: sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==}
dev: true
/@tsconfig/node12/1.0.11:
resolution: {integrity: sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==}
dev: true
/@tsconfig/node14/1.0.3:
resolution: {integrity: sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==}
dev: true
/@tsconfig/node16/1.0.3:
resolution: {integrity: sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==}
dev: true
/@types/acorn/4.0.6:
resolution: {integrity: sha512-veQTnWP+1D/xbxVrPC3zHnCZRjSrKfhbMUlEA43iMZLu7EsnTtkJklIuwrCPbOi8YkvDQAiW05VQQFvvz9oieQ==}
@@ -5140,18 +5126,17 @@ packages:
eslint-visitor-keys: 3.3.0
dev: true
/@uiw/codemirror-extensions-basic-setup/4.17.1_yoq5blswu3ydocenanojwujrum:
/@uiw/codemirror-extensions-basic-setup/4.17.1_mldjzacanzbudgr2aukt2yvcyy:
resolution: {integrity: sha512-lFH3gFPcpKDckaioYL2KonTYeeoP7gGtaDtDai7DV5UVEyuVPlkGukKCmHz6u0ol/Krs/RTbF4ylt8cDlBT1uA==}
peerDependencies:
'@codemirror/autocomplete': '>=6.0.0'
'@codemirror/commands': '>=6.0.0'
'@codemirror/language': '>=6.0.0'
'@codemirror/lint': '>=6.0.0'
'@codemirror/search': '>=6.0.0'
'@codemirror/state': '>=6.0.0'
'@codemirror/view': '>=6.0.0'
dependencies:
'@codemirror/autocomplete': 6.3.4_jvia4rcxqiacrvood3734bhyuy
'@codemirror/autocomplete': 6.3.4_4npvozs3agsv66jx2b7pfvr53q
'@codemirror/commands': 6.1.2
'@codemirror/language': 6.3.1
'@codemirror/lint': 6.1.0
@@ -5160,14 +5145,11 @@ packages:
'@codemirror/view': 6.6.0
dev: false
/@uiw/react-codemirror/4.17.1_c746qxthrd2ism2rvn4crnq5om:
/@uiw/react-codemirror/4.17.1_c6ric56h4625lhpbtenqifztqq:
resolution: {integrity: sha512-ah7wFhvVW/uKbQR5D12AqDK51XGZaZI1WYO9/sraZzq32TGphL5BU3vcQd1P0YEZR6YLc23+KWNi2DCQ+EEAbA==}
peerDependencies:
'@babel/runtime': '>=7.11.0'
'@codemirror/state': '>=6.0.0'
'@codemirror/theme-one-dark': '>=6.0.0'
'@codemirror/view': '>=6.0.0'
codemirror: '>=6.0.0'
react: '>=16.8.0'
react-dom: '>=16.8.0'
dependencies:
@@ -5176,14 +5158,13 @@ packages:
'@codemirror/state': 6.1.4
'@codemirror/theme-one-dark': 6.1.0
'@codemirror/view': 6.6.0
'@uiw/codemirror-extensions-basic-setup': 4.17.1_yoq5blswu3ydocenanojwujrum
codemirror: 6.0.1_@lezer+common@1.0.2
'@uiw/codemirror-extensions-basic-setup': 4.17.1_mldjzacanzbudgr2aukt2yvcyy
codemirror: 6.0.1
react: 18.2.0
react-dom: 18.2.0_react@18.2.0
transitivePeerDependencies:
- '@codemirror/autocomplete'
- '@codemirror/language'
- '@codemirror/lint'
- '@codemirror/search'
dev: false
@@ -5277,7 +5258,6 @@ packages:
/acorn-walk/8.2.0:
resolution: {integrity: sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==}
engines: {node: '>=0.4.0'}
dev: true
/acorn/7.4.1:
resolution: {integrity: sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==}
@@ -5288,7 +5268,6 @@ packages:
resolution: {integrity: sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA==}
engines: {node: '>=0.4.0'}
hasBin: true
dev: true
/agent-base/4.2.1:
resolution: {integrity: sha512-JVwXMr9nHYTUXsBFKUqhJwvlcYU/blreOEUkhNR2eXZIvwd+c+o5V4MgDPKWnMS/56awN3TRzIP+KoPn+roQtg==}
@@ -5416,7 +5395,6 @@ packages:
/arg/4.1.3:
resolution: {integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==}
dev: true
/arg/5.0.2:
resolution: {integrity: sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==}
@@ -6305,18 +6283,16 @@ packages:
engines: {node: '>=0.10.0'}
dev: false
/codemirror/6.0.1_@lezer+common@1.0.2:
/codemirror/6.0.1:
resolution: {integrity: sha512-J8j+nZ+CdWmIeFIGXEFbFPtpiYacFMDR8GlHK3IyHQJMCaVRfGx9NT+Hxivv1ckLWPvNdZqndbr/7lVhrf/Svg==}
dependencies:
'@codemirror/autocomplete': 6.3.4_jvia4rcxqiacrvood3734bhyuy
'@codemirror/autocomplete': 6.3.4_4npvozs3agsv66jx2b7pfvr53q
'@codemirror/commands': 6.1.2
'@codemirror/language': 6.3.1
'@codemirror/lint': 6.1.0
'@codemirror/search': 6.2.3
'@codemirror/state': 6.1.4
'@codemirror/view': 6.6.0
transitivePeerDependencies:
- '@lezer/common'
dev: false
/collection-visit/1.0.0:
@@ -6487,7 +6463,6 @@ packages:
/create-require/1.1.1:
resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==}
dev: true
/crelt/1.0.5:
resolution: {integrity: sha512-+BO9wPPi+DWTDcNYhr/W90myha8ptzftZT+LwcmUbbok0rcP/fequmFYCw8NMoH7pkAZQzU78b3kYrlua5a9eA==}
@@ -6924,7 +6899,6 @@ packages:
/diff/4.0.2:
resolution: {integrity: sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==}
engines: {node: '>=0.3.1'}
dev: true
/diff/5.1.0:
resolution: {integrity: sha512-D+mk+qE8VC/PAUrlAU34N+VfXev0ghe5ywmpqrawphmVZc1bEfn56uo9qpyGp1p4xpzOHkSW4ztBd6L7Xx4ACw==}
@@ -7626,7 +7600,7 @@ packages:
debug: 4.3.4
enhanced-resolve: 5.12.0
eslint: 8.29.0
eslint-plugin-import: 2.26.0_i656iqvetrvx3ajhg4t6psfrl4
eslint-plugin-import: 2.26.0_qfsg7upu5e4dqco5ntekgyqxwu
get-tsconfig: 4.2.0
globby: 13.1.2
is-core-module: 2.11.0
@@ -7636,35 +7610,6 @@ packages:
- supports-color
dev: true
/eslint-module-utils/2.7.4_jnakocfte2jywffz4vixv5kpsq:
resolution: {integrity: sha512-j4GT+rqzCoRKHwURX7pddtIPGySnX9Si/cgMI5ztrcqOPtk5dDEeZ34CQVPphnqkJytlc97Vuk05Um2mJ3gEQA==}
engines: {node: '>=4'}
peerDependencies:
'@typescript-eslint/parser': '*'
eslint: '*'
eslint-import-resolver-node: '*'
eslint-import-resolver-typescript: '*'
eslint-import-resolver-webpack: '*'
peerDependenciesMeta:
'@typescript-eslint/parser':
optional: true
eslint:
optional: true
eslint-import-resolver-node:
optional: true
eslint-import-resolver-typescript:
optional: true
eslint-import-resolver-webpack:
optional: true
dependencies:
'@typescript-eslint/parser': 5.45.1_s5ps7njkmjlaqajutnox5ntcla
debug: 3.2.7
eslint: 8.29.0
eslint-import-resolver-node: 0.3.6
transitivePeerDependencies:
- supports-color
dev: true
/eslint-module-utils/2.7.4_uplb3bqnui63takc5j27khdnpm:
resolution: {integrity: sha512-j4GT+rqzCoRKHwURX7pddtIPGySnX9Si/cgMI5ztrcqOPtk5dDEeZ34CQVPphnqkJytlc97Vuk05Um2mJ3gEQA==}
engines: {node: '>=4'}
@@ -7693,6 +7638,36 @@ packages:
- supports-color
dev: true
/eslint-module-utils/2.7.4_wbv6cezew2qbikiravago3ef2u:
resolution: {integrity: sha512-j4GT+rqzCoRKHwURX7pddtIPGySnX9Si/cgMI5ztrcqOPtk5dDEeZ34CQVPphnqkJytlc97Vuk05Um2mJ3gEQA==}
engines: {node: '>=4'}
peerDependencies:
'@typescript-eslint/parser': '*'
eslint: '*'
eslint-import-resolver-node: '*'
eslint-import-resolver-typescript: '*'
eslint-import-resolver-webpack: '*'
peerDependenciesMeta:
'@typescript-eslint/parser':
optional: true
eslint:
optional: true
eslint-import-resolver-node:
optional: true
eslint-import-resolver-typescript:
optional: true
eslint-import-resolver-webpack:
optional: true
dependencies:
'@typescript-eslint/parser': 5.45.1_s5ps7njkmjlaqajutnox5ntcla
debug: 3.2.7
eslint: 8.29.0
eslint-import-resolver-node: 0.3.6
eslint-import-resolver-typescript: 3.5.2_lt3hqehuojhfcbzgzqfngbtmrq
transitivePeerDependencies:
- supports-color
dev: true
/eslint-plugin-cypress/2.12.1_eslint@8.29.0:
resolution: {integrity: sha512-c2W/uPADl5kospNDihgiLc7n87t5XhUbFDoTl6CfVkmG+kDAb5Ux10V9PoLPu9N+r7znpc+iQlcmAqT1A/89HA==}
peerDependencies:
@@ -7743,7 +7718,7 @@ packages:
- supports-color
dev: true
/eslint-plugin-import/2.26.0_i656iqvetrvx3ajhg4t6psfrl4:
/eslint-plugin-import/2.26.0_qfsg7upu5e4dqco5ntekgyqxwu:
resolution: {integrity: sha512-hYfi3FXaM8WPLf4S1cikh/r4IxnO6zrhZbEGz2b660EJRbuxgpDS5gkCuYgGWg2xxh2rBuIr4Pvhve/7c31koA==}
engines: {node: '>=4'}
peerDependencies:
@@ -7760,7 +7735,7 @@ packages:
doctrine: 2.1.0
eslint: 8.29.0
eslint-import-resolver-node: 0.3.6
eslint-module-utils: 2.7.4_jnakocfte2jywffz4vixv5kpsq
eslint-module-utils: 2.7.4_wbv6cezew2qbikiravago3ef2u
has: 1.0.3
is-core-module: 2.11.0
is-glob: 4.0.3
@@ -10392,7 +10367,6 @@ packages:
/make-error/1.3.6:
resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==}
dev: true
/map-cache/0.2.2:
resolution: {integrity: sha512-8y/eV9QQZCiyn1SprXSrCmqJN0yNRATe+PO8ztwqrvrbdRLA3eYJF0yaR0YayLWkMbsQSKWS9N2gPcGEc4UsZg==}
@@ -11834,6 +11808,7 @@ packages:
lilconfig: 2.0.6
postcss: 8.4.19
yaml: 1.10.2
dev: true
/postcss-load-config/3.1.4_v776zzvn44o7tpgzieipaairwm:
resolution: {integrity: sha512-6DiM4E7v4coTE4uzA8U//WhtPwyhiim3eyjEMFCnUpzbrkK9wJHgKDT2mR+HbtSrd/NubVaYTOpSpjUl8NQeRg==}
@@ -11851,7 +11826,6 @@ packages:
postcss: 8.4.19
ts-node: 10.9.1_fww2c4adio7pltl52sxaeea2ii
yaml: 1.10.2
dev: true
/postcss-nested/5.0.6_postcss@8.4.19:
resolution: {integrity: sha512-rKqm2Fk0KbA8Vt3AdGN0FB9OBOMDVajMG6ZCf/GoHgdxUJ4sBFp0A/uMIRm+MJUdo33YXEtjqIz8u7DAp8B7DA==}
@@ -13509,6 +13483,7 @@ packages:
resolve: 1.22.1
transitivePeerDependencies:
- ts-node
dev: true
/tailwindcss/3.1.8_v776zzvn44o7tpgzieipaairwm:
resolution: {integrity: sha512-YSneUCZSFDYMwk+TGq8qYFdCA3yfBRdBlS7txSq0LUmzyeqRe3a8fBQzbz9M3WS/iFT4BNf/nmw9mEzrnSaC0g==}
@@ -13541,7 +13516,6 @@ packages:
resolve: 1.22.1
transitivePeerDependencies:
- ts-node
dev: true
/tapable/2.2.1:
resolution: {integrity: sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==}
@@ -13808,7 +13782,6 @@ packages:
typescript: 4.9.3
v8-compile-cache-lib: 3.0.1
yn: 3.1.1
dev: true
/ts-toolbelt/9.6.0:
resolution: {integrity: sha512-nsZd8ZeNUzukXPlJmTBwUAuABDe/9qtVDelJeT/qW0ow3ZS3BsQJtNkan1802aM9Uf68/Y8ljw86Hu0h5IUW3w==}
@@ -14305,7 +14278,6 @@ packages:
/v8-compile-cache-lib/3.0.1:
resolution: {integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==}
dev: true
/v8-to-istanbul/9.0.1:
resolution: {integrity: sha512-74Y4LqY74kLE6IFyIjPtkSTWzUZmj8tdHT9Ii/26dvQ6K9Dl2NbEfj0XgU2sHCtKgt5VupqhlO/5aWuqS+IY1w==}
@@ -14763,7 +14735,6 @@ packages:
/yn/3.1.1:
resolution: {integrity: sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==}
engines: {node: '>=6'}
dev: true
/yocto-queue/0.1.0:
resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==}
+33 -12
View File
@@ -2,7 +2,9 @@
"$schema": "https://turborepo.org/schema.json",
"pipeline": {
"build": {
"dependsOn": ["^build"],
"dependsOn": [
"^build"
],
"outputs": [
"dist/**",
"public/build/**",
@@ -12,12 +14,20 @@
]
},
"webapp#start": {
"dependsOn": ["^build"],
"outputs": ["public/build/**"]
"dependsOn": [
"^build"
],
"outputs": [
"public/build/**"
]
},
"start": {
"dependsOn": ["^build"],
"outputs": ["public/build/**"]
"dependsOn": [
"^build"
],
"outputs": [
"public/build/**"
]
},
"db:migrate:deploy": {
"outputs": []
@@ -39,7 +49,9 @@
"cache": false
},
"generate": {
"dependsOn": ["^generate"]
"dependsOn": [
"^generate"
]
},
"lint": {
"outputs": []
@@ -56,16 +68,22 @@
"cache": false
},
"test:e2e:dev": {
"dependsOn": ["^build"],
"dependsOn": [
"^build"
],
"outputs": [],
"cache": false
},
"test:e2e:ci": {
"dependsOn": ["^build"],
"dependsOn": [
"^build"
],
"outputs": []
},
"typecheck": {
"dependsOn": ["^build"],
"dependsOn": [
"^build"
],
"outputs": []
},
"clean": {
@@ -75,7 +93,9 @@
"cache": false
}
},
"globalDependencies": [".env"],
"globalDependencies": [
".env"
],
"globalEnv": [
"NODE_ENV",
"REMIX_APP_PORT",
@@ -93,6 +113,7 @@
"MAILGUN_KEY",
"FROM_EMAIL",
"MERGENT_KEY",
"PIZZLY_HOST"
"PIZZLY_HOST",
"DEBUG"
]
}
}