v3: no bundle builds for the dev CLI (#923)

* WIP no bundling

* Convert dev CLI to use an unbundled build process to support otel instrumentation

* Fix pnpm lock file

* A couple of fixes to get typechecking to work
This commit is contained in:
Eric Allam
2024-03-04 15:36:09 +00:00
committed by GitHub
parent 52c9d485f8
commit b7845685eb
18 changed files with 489 additions and 94 deletions
+2 -3
View File
@@ -10,8 +10,7 @@
"build:bundle": "esbuild src/index.ts --bundle --outfile=dist/index.cjs --platform=node",
"build:image": "docker build -f Containerfile . -t kubernetes-provider",
"dev": "tsx --no-warnings=ExperimentalWarning --require dotenv/config --watch src/index.ts",
"start": "tsx src/index.ts",
"typecheck": "tsc --noEmit"
"start": "tsx src/index.ts"
},
"keywords": [],
"author": "",
@@ -28,4 +27,4 @@
"tsx": "^4.7.0",
"typescript": "^5.3.3"
}
}
}
+7 -2
View File
@@ -38,10 +38,12 @@
"@trigger.dev/core": "workspace:*",
"@trigger.dev/tsconfig": "workspace:*",
"@types/gradient-string": "^1.1.2",
"@types/jsonlines": "^0.1.5",
"@types/mock-fs": "^4.13.1",
"@types/node": "18",
"@types/object-hash": "^3.0.6",
"@types/react": "^18.2.48",
"@types/semver": "^7.3.13",
"@types/ws": "^8.5.3",
"cpy-cli": "^5.0.0",
"npm-run-all": "^4.1.5",
@@ -59,7 +61,7 @@
"build:prod-containerfile": "src/Containerfile.prod"
},
"scripts": {
"typecheck": "tsc",
"typecheck": "tsc -p tsconfig.check.json",
"build": "npm run clean && run-p build:**",
"build:main": "tsup",
"build:facade": "tsup --config tsup.facade.config.ts",
@@ -95,6 +97,7 @@
"@opentelemetry/semantic-conventions": "^1.21.0",
"@traceloop/instrumentation-openai": "^0.3.9",
"@trigger.dev/core": "workspace:*",
"@trigger.dev/core-apps": "workspace:*",
"@types/degit": "^2.8.3",
"chalk": "^5.2.0",
"chokidar": "^3.5.3",
@@ -104,11 +107,12 @@
"dotenv": "^16.4.4",
"esbuild": "^0.19.11",
"evt": "^2.4.13",
"execa": "^7.0.0",
"execa": "^8.0.0",
"find-up": "^7.0.0",
"gradient-string": "^2.0.2",
"import-meta-resolve": "^4.0.0",
"ink": "^4.4.1",
"jsonlines": "^0.1.1",
"liquidjs": "^10.9.2",
"mock-fs": "^5.2.0",
"nanoid": "^4.0.2",
@@ -121,6 +125,7 @@
"proxy-agent": "^6.3.0",
"react": "^18.2.0",
"react-error-boundary": "^4.0.12",
"semver": "^7.5.0",
"simple-git": "^3.19.0",
"socket.io-client": "^4.7.4",
"source-map-support": "^0.5.21",
+65 -13
View File
@@ -10,7 +10,7 @@ import {
import chalk from "chalk";
import { watch } from "chokidar";
import { Command } from "commander";
import { BuildContext, context } from "esbuild";
import { BuildContext, Metafile, context } from "esbuild";
import { resolve as importResolve } from "import-meta-resolve";
import { Box, Text, render, useApp, useInput } from "ink";
import { createHash } from "node:crypto";
@@ -23,14 +23,14 @@ import React, { Suspense, useEffect } from "react";
import { ClientOptions, WebSocket as wsWebSocket } from "ws";
import { z } from "zod";
import * as packageJson from "../../package.json";
import { CliApiClient } from "../apiClient";
import { CommonCommandOptions } from "../cli/common.js";
import { BackgroundWorker, BackgroundWorkerCoordinator } from "../dev/backgroundWorker.js";
import { getConfigPath, readConfig } from "../utilities/configFiles";
import { printStandloneInitialBanner } from "../utilities/initialBanner.js";
import { logger } from "../utilities/logger.js";
import { isLoggedIn } from "../utilities/session.js";
import { CommonCommandOptions } from "../cli/common.js";
import { getConfigPath, readConfig } from "../utilities/configFiles";
import { createTaskFileImports, gatherTaskFiles } from "../utilities/taskFiles";
import { CliApiClient } from "../apiClient";
let apiClient: CliApiClient | undefined;
@@ -298,10 +298,14 @@ function useDev({
new URL(importResolve("./worker-facade.js", import.meta.url)).href.replace("file://", ""),
"utf-8"
);
const entryPointContents = workerFacade.replace(
"__TASKS__",
createTaskFileImports(taskFiles)
);
const registerTracingPath = new URL(
importResolve("./register-tracing.js", import.meta.url)
).href.replace("file://", "");
const entryPointContents = workerFacade
.replace("__TASKS__", createTaskFileImports(taskFiles))
.replace("__REGISTER_TRACING__", `import { tracingSDK } from "${registerTracingPath}";`);
let firstBuild = true;
@@ -318,17 +322,15 @@ function useDev({
write: false,
minify: false,
sourcemap: "external", // does not set the //# sourceMappingURL= comment in the file, we handle it ourselves
packages: "external", // https://esbuild.github.io/api/#packages
logLevel: "warning",
platform: "node",
format: "esm",
format: "cjs", // This is needed to support opentelemetry instrumentation that uses module patching
target: ["node18", "es2020"],
outdir: "out",
define: {
TRIGGER_API_URL: `"${config.triggerUrl}"`,
},
banner: {
js: `import { createRequire } from 'module';const require = createRequire(import.meta.url);`,
},
plugins: [
{
name: "trigger.dev v3",
@@ -379,7 +381,7 @@ function useDev({
}
// Create a file at join(dir, ".trigger", path) with the fileContents
const fullPath = join(config.projectDir, ".trigger", `${contentHash}.mjs`);
const fullPath = join(config.projectDir, ".trigger", `${contentHash}.js`);
const sourceMapPath = `${fullPath}.map`;
const outputFileWithSourceMap = `${
@@ -389,6 +391,10 @@ function useDev({
await fs.promises.mkdir(dirname(fullPath), { recursive: true });
await fs.promises.writeFile(fullPath, outputFileWithSourceMap);
logger.debug(`Wrote background worker to ${fullPath}`);
const dependencies = gatherRequiredDependencies(metaOutput);
if (sourceMapFile) {
const sourceMapPath = `${fullPath}.map`;
await fs.promises.writeFile(sourceMapPath, sourceMapFile.text);
@@ -399,6 +405,7 @@ function useDev({
const backgroundWorker = new BackgroundWorker(fullPath, {
projectDir: config.projectDir,
dependencies,
env: {
TRIGGER_API_URL: apiUrl,
TRIGGER_API_KEY: apiKey,
@@ -608,3 +615,48 @@ function WebsocketFactory(apiKey: string) {
}
};
}
// Returns the dependencies that are required by the output that are found in output and the CLI package dependencies
// Returns the dependency names and the version to use (taken from the CLI deps package.json)
function gatherRequiredDependencies(outputMeta: Metafile["outputs"][string]) {
const dependencies: Record<string, string> = {};
for (const file of outputMeta.imports) {
if (file.kind !== "require-call" || !file.external) {
continue;
}
const packageName = detectPackageNameFromImportPath(file.path);
if (dependencies[packageName]) {
continue;
}
const internalDependencyVersion = (packageJson.dependencies as Record<string, string>)[
packageName
];
if (internalDependencyVersion) {
dependencies[packageName] = internalDependencyVersion;
}
}
return dependencies;
}
// Expects path to be in the format:
// - source-map-support/register.js
// - @opentelemetry/api
// - zod
//
// With the result being:
// - source-map-support
// - @opentelemetry/api
// - zod
function detectPackageNameFromImportPath(path: string): string {
if (path.startsWith("@")) {
return path.split("/").slice(0, 2).join("/");
} else {
return path.split("/")[0] as string;
}
}
+10 -2
View File
@@ -20,10 +20,11 @@ import chalk from "chalk";
import dotenv from "dotenv";
import { Evt } from "evt";
import { ChildProcess, fork } from "node:child_process";
import { resolve } from "node:path";
import { dirname, resolve } from "node:path";
import terminalLink from "terminal-link";
import { logger } from "../utilities/logger.js";
import { safeDeleteFileSync } from "../utilities/fileSystem.js";
import { installPackages } from "../utilities/installPackages.js";
import { logger } from "../utilities/logger.js";
export type CurrentWorkers = BackgroundWorkerCoordinator["currentWorkers"];
export class BackgroundWorkerCoordinator {
@@ -202,6 +203,7 @@ class CleanupProcessError extends Error {
export type BackgroundWorkerParams = {
env: Record<string, string>;
dependencies?: Record<string, string>;
projectDir: string;
debuggerOn: boolean;
debugOtel?: boolean;
@@ -253,6 +255,11 @@ export class BackgroundWorker {
throw new Error("Worker already initialized");
}
// Install the dependencies in dirname(this.path) using npm and child_process
if (this.params.dependencies) {
await installPackages(this.params.dependencies, { cwd: dirname(this.path) });
}
let resolved = false;
this.tasks = await new Promise<Array<TaskMetadataWithFilePath>>((resolve, reject) => {
@@ -469,6 +476,7 @@ class TaskRunProcess {
async initialize() {
this._child = fork(this.path, {
stdio: [/*stdin*/ "ignore", /*stdout*/ "pipe", /*stderr*/ "pipe", "ipc"],
cwd: dirname(this.path),
env: {
...this.env,
OTEL_RESOURCE_ATTRIBUTES: JSON.stringify({
@@ -0,0 +1,16 @@
import { Resource } from "@opentelemetry/resources";
import { OpenAIInstrumentation } from "@traceloop/instrumentation-openai";
import {
SemanticInternalAttributes,
TracingDiagnosticLogLevel,
TracingSDK,
} from "@trigger.dev/core/v3";
export const tracingSDK = new TracingSDK({
url: process.env.OTEL_EXPORTER_OTLP_ENDPOINT ?? "http://0.0.0.0:4318",
resource: new Resource({
[SemanticInternalAttributes.CLI_VERSION]: "3.0.0",
}),
instrumentations: [new OpenAIInstrumentation()],
diagLogLevel: (process.env.OTEL_LOG_LEVEL as TracingDiagnosticLogLevel) ?? "none",
});
@@ -1,20 +1,9 @@
import "source-map-support/register";
import { TracingSDK } from "@trigger.dev/core/v3/otel";
// import { OpenAIInstrumentation } from "@traceloop/instrumentation-openai";
import "source-map-support/register.js";
import { type TracingSDK } from "@trigger.dev/core/v3";
// IMPORTANT: this needs to be the first import to work properly
// WARNING: [WARNING] Constructing "ImportInTheMiddle" will crash at run-time because it's an import namespace object, not a constructor [call-import-namespace]
// TODO: https://github.com/open-telemetry/opentelemetry-js/issues/3954
const tracingSDK = new TracingSDK({
url: process.env.OTEL_EXPORTER_OTLP_ENDPOINT ?? "http://0.0.0.0:4318",
resource: new Resource({
[SemanticInternalAttributes.CLI_VERSION]: packageJson.version,
}),
instrumentations: [
// new OpenAIInstrumentation(),
],
diagLogLevel: (process.env.OTEL_LOG_LEVEL as TracingDiagnosticLogLevel) ?? "none",
});
__REGISTER_TRACING__;
declare const __REGISTER_TRACING__: unknown;
declare const tracingSDK: TracingSDK;
const otelTracer = tracingSDK.getTracer("trigger-dev-worker", packageJson.version);
const otelLogger = tracingSDK.getLogger("trigger-dev-worker", packageJson.version);
@@ -42,13 +31,13 @@ import {
taskContextManager,
workerToChildMessages,
type BackgroundWorkerProperties,
type TracingDiagnosticLogLevel,
} from "@trigger.dev/core/v3";
import * as packageJson from "../package.json";
import * as packageJson from "../../package.json";
import { Resource } from "@opentelemetry/resources";
import { flattenAttributes } from "@trigger.dev/core/v3";
import { TaskMetadataWithFunctions } from "./types.js";
import { TracingDiagnosticLogLevel } from "@trigger.dev/core/v3/otel/tracingSDK";
import { TaskMetadataWithFunctions } from "../types.js";
const tracer = new TriggerTracer({ tracer: otelTracer, logger: otelLogger });
const consoleInterceptor = new ConsoleInterceptor(otelLogger);
+2 -2
View File
@@ -1,5 +1,5 @@
// import "source-map-support/register";
import { TracingSDK } from "@trigger.dev/core/v3/otel";
import { TracingSDK } from "@trigger.dev/core/v3";
// import { OpenAIInstrumentation } from "@traceloop/instrumentation-openai";
// IMPORTANT: this needs to be the first import to work properly
@@ -48,7 +48,7 @@ import * as packageJson from "../package.json";
import { Resource } from "@opentelemetry/resources";
import { flattenAttributes } from "@trigger.dev/core/v3";
import { TaskMetadataWithFunctions } from "./types";
import { TracingDiagnosticLogLevel } from "@trigger.dev/core/v3/otel/tracingSDK";
import { TracingDiagnosticLogLevel } from "@trigger.dev/core/v3";
const tracer = new TriggerTracer({ tracer: otelTracer, logger: otelLogger });
const consoleInterceptor = new ConsoleInterceptor(otelLogger);
@@ -0,0 +1,92 @@
import semver from "semver";
import { execa } from "execa";
import { logger } from "./logger";
import { join } from "node:path";
import { readJSONFile } from "./fileSystem";
export type InstallPackagesOptions = { cwd?: string };
export async function installPackages(
packages: Record<string, string>,
options?: InstallPackagesOptions
) {
const cwd = options?.cwd ?? process.cwd();
// Make sure the cwd has a package.json file (if not create a barebones one)
try {
await readJSONFile(join(cwd, "package.json"));
} catch (error) {
await execa("npm", ["init", "-y"], { cwd });
}
// Detect with packages have already been installed at the specified version (use semver to compare)
// and only install the ones that are missing or have a different version
const installablePackages = await Promise.all(
Object.entries(packages).map(async ([name, version]) => {
try {
const latestVersion = await getPackageVersion(join(cwd, "node_modules", name));
if (!latestVersion) {
return { name, version };
}
return semver.satisfies(latestVersion, version) ? undefined : { name, version };
} catch (error) {
return { name, version };
}
})
)
.then((packages) => packages.filter(Boolean))
.then((packages) =>
packages.reduce((acc: Record<string, string>, p) => ({ ...acc, [p!.name]: p!.version }), {})
);
if (Object.keys(installablePackages).length === 0) {
return;
}
logger.debug(`Installing packages at ${cwd}:`);
logger.table(
Object.entries(installablePackages).map(([name, version]) => ({ name, version })),
"debug"
);
const childProcess = execa(
"npm",
[
"install",
...Object.entries(installablePackages).map(([name, version]) => `${name}@${version}`),
"--install-strategy",
"nested",
"--ignore-scripts",
"--no-package-lock",
"--no-audit",
"--no-fund",
"--no-save",
],
{
cwd,
stderr: "inherit",
}
);
await new Promise<void>((res, rej) => {
childProcess.on("error", (e) => rej(e));
childProcess.on("close", () => res());
});
await childProcess;
return;
}
async function getPackageVersion(path: string) {
try {
const packageJsonPath = join(path, "package.json");
const packageJson = await readJSONFile(packageJsonPath);
return packageJson.version;
} catch (error) {
return undefined;
}
}
@@ -0,0 +1,39 @@
type Index<T = any> = { [key: string]: T };
type KeyValueGenerator<K, V, R> = (key: K, value: V, accum: Index<R>) => Index<R> | null;
type ArrayKeyValueGenerator<T, R> = KeyValueGenerator<T, number, R>;
type ObjectKeyValueGenerator<T, R> = KeyValueGenerator<string, T, R>;
export function keyValueBy<T>(arr: T[]): Index<true>;
export function keyValueBy<T, R>(
arr: T[],
keyValue: KeyValueGenerator<T, number, R>,
initialValue?: Index<R>
): Index<R>;
export function keyValueBy<T, R>(
obj: Index<T>,
keyValue: KeyValueGenerator<string, T, R>,
initialValue?: Index<R>
): Index<R>;
/** Generates an object from an array or object. Simpler than reduce or _.transform. The KeyValueGenerator passes (key, value) if the input is an object, and (value, i) if it is an array. The return object from each iteration is merged into the accumulated object. Return null to skip an item. */
export function keyValueBy<T, R = true>(
input: T[] | Index<T>,
// if no keyValue is given, sets all values to true
keyValue?: ArrayKeyValueGenerator<T, R> | ObjectKeyValueGenerator<T, R>,
accum: Index<R> = {}
): Index<R> {
const isArray = Array.isArray(input);
keyValue =
keyValue || ((key: T): Index<R> => ({ [key as unknown as string]: true as unknown as R }));
// considerably faster than Array.prototype.reduce
Object.entries(input || {}).forEach(([key, value], i) => {
const o = isArray
? (keyValue as ArrayKeyValueGenerator<T, R>)(value, i, accum)
: (keyValue as ObjectKeyValueGenerator<T, R>)(key, value, accum);
Object.entries(o || {}).forEach((entry) => {
accum[entry[0]] = entry[1];
});
});
return accum;
}
+2 -2
View File
@@ -62,7 +62,7 @@ export class Logger {
log = (...args: unknown[]) => this.doLog("log", args);
warn = (...args: unknown[]) => this.doLog("warn", args);
error = (...args: unknown[]) => this.doLog("error", args);
table<Keys extends string>(data: TableRow<Keys>[]) {
table<Keys extends string>(data: TableRow<Keys>[], level?: Exclude<LoggerLevel, "none">) {
const keys: Keys[] = data.length === 0 ? [] : (Object.keys(data[0]!) as Keys[]);
const t = new CLITable({
head: keys,
@@ -72,7 +72,7 @@ export class Logger {
},
});
t.push(...data.map((row) => keys.map((k) => row[k])));
return this.doLog("log", [t.toString()]);
return this.doLog(level ?? "log", [t.toString()]);
}
private doLog(messageLevel: Exclude<LoggerLevel, "none">, args: unknown[]) {
@@ -0,0 +1,171 @@
import { $ } from "execa";
import jsonlines from "jsonlines";
import { getUserPackageManager } from "./getUserPackageManager";
import { keyValueBy } from "./keyValueBy";
export async function listPackageDependencies(
path: string,
tag: string | undefined = undefined
): Promise<Record<string, string | undefined>> {
const packageManager = await getPackageManagerCommands(path);
const list = await packageManager.list({ cwd: path });
return Object.keys(list).reduce(
(acc, dependency) => {
const version = list[dependency];
if (!version) {
return acc;
}
if (dependency.startsWith("@trigger.dev/") && version.startsWith("link:")) {
acc[dependency] = tag ?? "latest";
} else {
acc[dependency] = version;
}
return acc;
},
{} as Record<string, string | undefined>
);
}
type PnpmList = {
path: string;
private: boolean;
dependencies: Record<
string,
{
from: string;
version: string;
resolved: string;
}
>;
}[];
async function getPackageManagerCommands(path: string): Promise<PackageManagerCommands> {
const packageManager = await getUserPackageManager(path);
switch (packageManager) {
case "npm":
return new NPMCommands();
case "pnpm":
return new PNPMCommands();
case "yarn":
return new YarnCommands();
}
}
type ListOptions = {
cwd?: string;
};
interface PackageManagerCommands {
list(options: ListOptions): Promise<Record<string, string | undefined>>;
}
class PNPMCommands implements PackageManagerCommands {
async list(options: ListOptions): Promise<Record<string, string | undefined>> {
const cmd = process.platform === "win32" ? "pnpm.cmd" : "pnpm";
const { stdout } = await $({ cwd: options.cwd })`${cmd} ls --depth 1 --json --long`;
const result = JSON.parse(stdout) as PnpmList;
const list = keyValueBy(result[0]?.dependencies ?? {}, (name, { version }) => ({
[name]: version,
}));
return list;
}
}
class NPMCommands implements PackageManagerCommands {
async list(options: ListOptions): Promise<Record<string, string | undefined>> {
const cmd = process.platform === "win32" ? "npm.cmd" : "npm";
const { stdout } = await $({ cwd: options.cwd })`${cmd} ls --depth=0 --json`;
const dependencies = (
JSON.parse(stdout) as {
dependencies: Record<string, { version?: string; required?: { version: string } }>;
}
).dependencies;
return keyValueBy(dependencies, (name, info) => ({
// unmet peer dependencies have a different structure
[name]: info.version || info.required?.version,
}));
}
}
interface YarnParsedDep {
version: string;
from: string;
required?: {
version: string;
};
}
class YarnCommands implements PackageManagerCommands {
async list(options: ListOptions): Promise<Record<string, string | undefined>> {
const cmd = process.platform === "win32" ? "yarn.cmd" : "yarn";
const { stdout } = await $`${cmd} list --depth=0 --json --no-progress`;
const json: { dependencies: Record<string, YarnParsedDep> } = await this.#parseJsonLines(
stdout
);
const keyValues: Record<string, string | undefined> = keyValueBy<
YarnParsedDep,
string | undefined
>(json.dependencies, (name, info): { [key: string]: string | undefined } => ({
// unmet peer dependencies have a different structure
[name]: info.version || info.required?.version,
}));
return keyValues;
}
/**
* Parse JSON lines and throw an informative error on failure.
*
* Note: although this is similar to the NPM parseJson() function we always return the
* same concrete-type here, for now.
*
* @param result Output from `yarn list --json` to be parsed
*/
#parseJsonLines(result: string): Promise<{ dependencies: Record<string, YarnParsedDep> }> {
return new Promise((resolve, reject) => {
const dependencies: Record<string, YarnParsedDep> = {};
const parser = jsonlines.parse();
parser.on("data", (d) => {
// only parse info data
// ignore error info, e.g. "Visit https://yarnpkg.com/en/docs/cli/list for documentation about this command."
if (d.type === "info" && !d.data.match(/^Visit/)) {
// parse package name and version number from info data, e.g. "nodemon@2.0.4" has binaries
const [, pkgName, pkgVersion] = d.data.match(/"(@?.*)@(.*)"/) || [];
dependencies[pkgName] = {
version: pkgVersion,
from: pkgName,
};
} else if (d.type === "error") {
reject(new Error(d.data));
}
});
parser.on("end", () => {
resolve({ dependencies });
});
parser.on("error", reject);
parser.write(result);
parser.end();
});
}
}
+7
View File
@@ -0,0 +1,7 @@
{
"extends": "./tsconfig.json",
"compilerOptions": {
"noEmit": true,
"paths": {}
}
}
+3 -4
View File
@@ -2,15 +2,14 @@ import { defineConfig } from "tsup";
export default defineConfig({
clean: false,
dts: true,
dts: false,
tsconfig: "tsconfig.json",
splitting: false,
entry: ["src/worker-facade.ts"],
entry: ["src/dev/worker-facade.ts", "src/dev/register-tracing.ts"],
format: ["esm"],
minify: false,
metafile: false,
sourcemap: true,
sourcemap: false,
target: "esnext",
outDir: "dist",
noExternal: ["zod", /traceloop/, /opentelemetry/, /source-map/],
});
+1
View File
@@ -45,3 +45,4 @@ export { defaultRetryOptions, calculateNextRetryDelay, calculateResetAt } from "
export { accessoryAttributes } from "./utils/styleAttributes";
export { eventFilterMatches } from "../eventFilterMatches";
export { omit } from "./utils/omit";
export { TracingSDK, type TracingDiagnosticLogLevel } from "./otel";
+1 -1
View File
@@ -1,2 +1,2 @@
export { TracingSDK, type TracingSDKConfig } from "./tracingSDK";
export { TracingSDK, type TracingSDKConfig, type TracingDiagnosticLogLevel } from "./tracingSDK";
export { HttpInstrumentation, FetchInstrumentation } from "./instrumentations";
+1
View File
@@ -117,6 +117,7 @@ export class TracingSDK {
registerInstrumentations({
instrumentations: config.instrumentations ?? [],
tracerProvider: traceProvider,
});
const logExporter = new OTLPLogExporter({
+61 -45
View File
@@ -1046,13 +1046,16 @@ importers:
'@opentelemetry/semantic-conventions': ^1.21.0
'@traceloop/instrumentation-openai': ^0.3.9
'@trigger.dev/core': workspace:*
'@trigger.dev/core-apps': workspace:*
'@trigger.dev/tsconfig': workspace:*
'@types/degit': ^2.8.3
'@types/gradient-string': ^1.1.2
'@types/jsonlines': ^0.1.5
'@types/mock-fs': ^4.13.1
'@types/node': '18'
'@types/object-hash': ^3.0.6
'@types/react': ^18.2.48
'@types/semver': ^7.3.13
'@types/ws': ^8.5.3
chalk: ^5.2.0
chokidar: ^3.5.3
@@ -1063,11 +1066,12 @@ importers:
dotenv: ^16.4.4
esbuild: ^0.19.11
evt: ^2.4.13
execa: ^7.0.0
execa: ^8.0.0
find-up: ^7.0.0
gradient-string: ^2.0.2
import-meta-resolve: ^4.0.0
ink: ^4.4.1
jsonlines: ^0.1.1
liquidjs: ^10.9.2
mock-fs: ^5.2.0
nanoid: ^4.0.2
@@ -1085,6 +1089,7 @@ importers:
react: ^18.2.0
react-error-boundary: ^4.0.12
rimraf: ^3.0.2
semver: ^7.5.0
simple-git: ^3.19.0
socket.io-client: ^4.7.4
source-map-support: ^0.5.21
@@ -1118,6 +1123,7 @@ importers:
'@opentelemetry/semantic-conventions': 1.21.0
'@traceloop/instrumentation-openai': 0.3.9_rr4fxqkzz7nhz3auplkqn4p6em
'@trigger.dev/core': link:../core
'@trigger.dev/core-apps': link:../core-apps
'@types/degit': 2.8.3
chalk: 5.3.0
chokidar: 3.5.3
@@ -1127,11 +1133,12 @@ importers:
dotenv: 16.4.4
esbuild: 0.19.11
evt: 2.4.13
execa: 7.0.0
execa: 8.0.1
find-up: 7.0.0
gradient-string: 2.0.2
import-meta-resolve: 4.0.0
ink: 4.4.1_7kh72gklg5qjlh5zc6s6v3p6v4
jsonlines: 0.1.1
liquidjs: 10.9.3
mock-fs: 5.2.0
nanoid: 4.0.2
@@ -1144,6 +1151,7 @@ importers:
proxy-agent: 6.3.0_supports-color@9.4.0
react: 18.2.0
react-error-boundary: 4.0.12_react@18.2.0
semver: 7.5.4
simple-git: 3.19.0_supports-color@9.4.0
socket.io-client: 4.7.4_supports-color@9.4.0
source-map-support: 0.5.21
@@ -1156,10 +1164,12 @@ importers:
devDependencies:
'@trigger.dev/tsconfig': link:../../config-packages/tsconfig
'@types/gradient-string': 1.1.2
'@types/jsonlines': 0.1.5
'@types/mock-fs': 4.13.1
'@types/node': 18.17.1
'@types/object-hash': 3.0.6
'@types/react': 18.2.48
'@types/semver': 7.5.1
'@types/ws': 8.5.4
cpy-cli: 5.0.0
npm-run-all: 4.1.5
@@ -7294,7 +7304,7 @@ packages:
engines: {node: ^8.13.0 || >=10.10.0}
dependencies:
'@grpc/proto-loader': 0.7.7
'@types/node': 20.6.0
'@types/node': 20.11.22
dev: false
/@grpc/proto-loader/0.7.7:
@@ -7567,7 +7577,7 @@ packages:
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
dependencies:
'@jest/types': 29.6.1
'@types/node': 20.6.0
'@types/node': 20.11.22
chalk: 4.1.2
jest-message-util: 29.6.2
jest-util: 29.6.2
@@ -7588,14 +7598,14 @@ packages:
'@jest/test-result': 29.6.2
'@jest/transform': 29.6.2
'@jest/types': 29.6.1
'@types/node': 20.6.0
'@types/node': 20.11.22
ansi-escapes: 4.3.2
chalk: 4.1.2
ci-info: 3.8.0
exit: 0.1.2
graceful-fs: 4.2.10
jest-changed-files: 29.5.0
jest-config: 29.6.2_@types+node@20.6.0
jest-config: 29.6.2_@types+node@20.11.22
jest-haste-map: 29.6.2
jest-message-util: 29.6.2
jest-regex-util: 29.4.3
@@ -7683,7 +7693,7 @@ packages:
'@jest/transform': 29.6.2
'@jest/types': 29.6.1
'@jridgewell/trace-mapping': 0.3.19
'@types/node': 20.6.0
'@types/node': 20.11.22
chalk: 4.1.2
collect-v8-coverage: 1.0.2
exit: 0.1.2
@@ -7792,7 +7802,7 @@ packages:
dependencies:
'@types/istanbul-lib-coverage': 2.0.4
'@types/istanbul-reports': 3.0.1
'@types/node': 20.6.0
'@types/node': 20.11.22
'@types/yargs': 16.0.5
chalk: 4.1.2
dev: true
@@ -7804,7 +7814,7 @@ packages:
'@jest/schemas': 29.6.0
'@types/istanbul-lib-coverage': 2.0.4
'@types/istanbul-reports': 3.0.1
'@types/node': 20.6.0
'@types/node': 20.11.22
'@types/yargs': 17.0.32
chalk: 4.1.2
dev: true
@@ -15133,7 +15143,7 @@ packages:
resolution: {integrity: sha512-DTuBFbqu4gGfajREEMrkq5jBhcnskinhr4+AnfJEk48zhVeEv3XnUKGIX98B74kxhYsIMfApGGySTn7V3b5yBA==}
engines: {node: '>= 12.13.0', npm: '>= 6.12.0'}
dependencies:
'@types/node': 20.6.0
'@types/node': 20.11.22
dev: false
/@slack/types/2.8.0:
@@ -17538,7 +17548,7 @@ packages:
resolution: {integrity: sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g==}
dependencies:
'@types/connect': 3.4.35
'@types/node': 20.6.0
'@types/node': 20.11.22
/@types/btoa-lite/1.0.0:
resolution: {integrity: sha512-wJsiX1tosQ+J5+bY5LrSahHxr2wT+uME5UDwdN1kg4frt40euqA+wzECkmq4t5QbveHiJepfdThgQrPw6KiSlg==}
@@ -17553,7 +17563,7 @@ packages:
/@types/bunyan/1.8.9:
resolution: {integrity: sha512-ZqS9JGpBxVOvsawzmVt30sP++gSQMTejCkIAQ3VdadOcRE8izTyW66hufvwLeH+YEGP6Js2AW7Gz+RMyvrEbmw==}
dependencies:
'@types/node': 20.6.0
'@types/node': 20.11.22
dev: false
/@types/cacheable-request/6.0.3:
@@ -17561,7 +17571,7 @@ packages:
dependencies:
'@types/http-cache-semantics': 4.0.1
'@types/keyv': 3.1.4
'@types/node': 20.6.0
'@types/node': 20.11.22
'@types/responselike': 1.0.0
/@types/caseless/0.12.5:
@@ -17589,12 +17599,12 @@ packages:
/@types/connect/3.4.35:
resolution: {integrity: sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==}
dependencies:
'@types/node': 20.6.0
'@types/node': 20.11.22
/@types/connect/3.4.36:
resolution: {integrity: sha512-P63Zd/JUGq+PdrM1lv0Wv5SBYeA2+CORvbrXbngriYY0jzLUWfQMQQxOhjONEz/wlHOAxOdY7CY65rgQdTjq2w==}
dependencies:
'@types/node': 20.6.0
'@types/node': 20.11.22
dev: false
/@types/content-disposition/0.5.5:
@@ -17627,7 +17637,7 @@ packages:
/@types/cors/2.8.17:
resolution: {integrity: sha512-8CGDvrBj1zgo2qE+oS3pOCyYNqCPryMWY2bGfwA0dcfopWGgxs+78df0Rs3rc9THP4JkOhLsAa+15VdpAqkcUA==}
dependencies:
'@types/node': 20.6.0
'@types/node': 20.11.22
/@types/d3-array/3.0.8:
resolution: {integrity: sha512-2xAVyAUgaXHX9fubjcCbGAUOqYfRJN1em1EKR2HfzWBpObZhwfnZKvofTN4TplMqJdFQao61I+NVSai/vnBvDQ==}
@@ -17736,7 +17746,7 @@ packages:
/@types/express-serve-static-core/4.17.32:
resolution: {integrity: sha512-aI5h/VOkxOF2Z1saPy0Zsxs5avets/iaiAJYznQFm5By/pamU31xWKL//epiF4OfUA2qTOc9PV6tCUjhO8wlZA==}
dependencies:
'@types/node': 20.6.0
'@types/node': 20.11.22
'@types/qs': 6.9.7
'@types/range-parser': 1.2.4
dev: true
@@ -17744,7 +17754,7 @@ packages:
/@types/express-serve-static-core/4.17.37:
resolution: {integrity: sha512-ZohaCYTgGFcOP7u6aJOhY9uIZQgZ2vxC2yWoArY+FeDXlqeH66ZVBjgvg+RLVAS/DWNq4Ap9ZXu1+SUQiiWYMg==}
dependencies:
'@types/node': 20.6.0
'@types/node': 20.11.22
'@types/qs': 6.9.7
'@types/range-parser': 1.2.4
'@types/send': 0.17.2
@@ -17824,7 +17834,7 @@ packages:
'@types/hapi__catbox': 10.2.4
'@types/hapi__mimos': 4.1.4
'@types/hapi__shot': 4.1.2
'@types/node': 20.6.0
'@types/node': 20.11.22
joi: 17.7.0
dev: false
@@ -17899,7 +17909,7 @@ packages:
/@types/is-stream/1.1.0:
resolution: {integrity: sha512-jkZatu4QVbR60mpIzjINmtS1ZF4a/FqdTUTBeQDVOQ2PYyidtwFKr0B5G6ERukKwliq+7mIXvxyppwzG5EgRYg==}
dependencies:
'@types/node': 20.6.0
'@types/node': 20.11.22
dev: false
/@types/istanbul-lib-coverage/2.0.4:
@@ -17955,6 +17965,12 @@ packages:
/@types/json5/0.0.30:
resolution: {integrity: sha512-sqm9g7mHlPY/43fcSNrCYfOeX9zkTTK+euO5E6+CVijSMm5tTjkVdwdqRkY3ljjIAf8679vps5jKUoJBCLsMDA==}
/@types/jsonlines/0.1.5:
resolution: {integrity: sha512-/zOl7I350g4/G6fEW9dktpTrkcKqZDMRkr2SuDla0utgwkUXrm7OFXq2WZT0W9Jl7BYoisGbn1EZsV/Z2F9LGg==}
dependencies:
'@types/node': 20.11.22
dev: true
/@types/jsonwebtoken/9.0.1:
resolution: {integrity: sha512-c5ltxazpWabia/4UzhIoaDcIza4KViOQhdbjRlfcIGVnsE3c3brkz9Z+F/EeJIECOQP7W7US2hNE930cWWkPiw==}
dependencies:
@@ -17999,7 +18015,7 @@ packages:
'@types/http-errors': 2.0.1
'@types/keygrip': 1.0.2
'@types/koa-compose': 3.2.5
'@types/node': 20.6.0
'@types/node': 20.11.22
dev: false
/@types/koa__router/12.0.3:
@@ -18048,7 +18064,7 @@ packages:
/@types/memcached/2.2.7:
resolution: {integrity: sha512-ImJbz1i8pl+OnyhYdIDnHe8jAuM8TOwM/7VsciqhYX3IL0jPPUToAtVxklfcWFGYckahEYZxhd9FS0z3MM1dpA==}
dependencies:
'@types/node': 20.6.0
'@types/node': 20.11.22
dev: false
/@types/mime-db/1.43.1:
@@ -18101,7 +18117,7 @@ packages:
/@types/mysql/2.15.22:
resolution: {integrity: sha512-wK1pzsJVVAjYCSZWQoWHziQZbNggXFDUEIGf54g4ZM/ERuP86uGdWeKZWMYlqTPMZfHJJvLPyogXGvCOg87yLQ==}
dependencies:
'@types/node': 20.6.0
'@types/node': 20.11.22
dev: false
/@types/nlcst/1.0.1:
@@ -18119,13 +18135,13 @@ packages:
/@types/node-fetch/2.6.4:
resolution: {integrity: sha512-1ZX9fcN4Rvkvgv4E6PAY5WXUFWFcRWxZa3EW83UjycOB9ljJCedb2CupIP4RZMEwF/M3eTcCihbBRgwtGbg5Rg==}
dependencies:
'@types/node': 20.6.0
'@types/node': 20.11.22
form-data: 3.0.1
/@types/node-forge/1.3.10:
resolution: {integrity: sha512-y6PJDYN4xYBxwd22l+OVH35N+1fCYWiuC3aiP2SlXVE6Lo7SS+rSx9r89hLxrP4pn6n1lBGhHJ12pj3F3Mpttw==}
dependencies:
'@types/node': 20.6.0
'@types/node': 20.11.22
dev: true
/@types/node/12.20.55:
@@ -18209,7 +18225,7 @@ packages:
/@types/pg/8.6.1:
resolution: {integrity: sha512-1Kc4oAGzAl7uqUStZCDvaLFqZrW9qWSjXOmBfdgyBP5La7Us6Mg4GBvRlSoaZMhQF/zSj1C8CtKMBkoiT8eL8w==}
dependencies:
'@types/node': 20.6.0
'@types/node': 20.11.22
pg-protocol: 1.6.0
pg-types: 2.2.0
dev: false
@@ -18217,7 +18233,7 @@ packages:
/@types/pg/8.6.6:
resolution: {integrity: sha512-O2xNmXebtwVekJDD+02udOncjVcMZQuTEQEMpKJ0ZRf5E7/9JJX3izhKUcUifBkyKpljyUM6BTgy2trmviKlpw==}
dependencies:
'@types/node': 20.6.0
'@types/node': 20.11.22
pg-protocol: 1.6.0
pg-types: 2.2.0
dev: false
@@ -18287,7 +18303,7 @@ packages:
/@types/responselike/1.0.0:
resolution: {integrity: sha512-85Y2BjiufFzaMIlvJDvTTB8Fxl2xfLo4HgmHzVBz08w4wDePCTjYw66PdrolO0kzli3yam/YCgRufyo1DdQVTA==}
dependencies:
'@types/node': 20.6.0
'@types/node': 20.11.22
/@types/retry/0.12.0:
resolution: {integrity: sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA==}
@@ -18314,13 +18330,13 @@ packages:
resolution: {integrity: sha512-aAG6yRf6r0wQ29bkS+x97BIs64ZLxeE/ARwyS6wrldMm3C1MdKwCcnnEwMC1slI8wuxJOpiUH9MioC0A0i+GJw==}
dependencies:
'@types/mime': 1.3.3
'@types/node': 20.6.0
'@types/node': 20.11.22
/@types/serve-static/1.15.0:
resolution: {integrity: sha512-z5xyF6uh8CbjAu9760KDKsH2FcDxZ2tFCsA4HIMWE6IkiYMXfVoa+4f9KX+FN0ZLsaMw1WNG2ETLA6N+/YA+cg==}
dependencies:
'@types/mime': 3.0.1
'@types/node': 20.6.0
'@types/node': 20.11.22
/@types/set-cookie-parser/2.4.2:
resolution: {integrity: sha512-fBZgytwhYAUkj/jC/FAV4RQ5EerRup1YQsXQCh8rZfiHkc4UahC192oH0smGwsXol3cL3A5oETuAHeQHmhXM4w==}
@@ -18351,7 +18367,7 @@ packages:
resolution: {integrity: sha512-McM1mlc7PBZpCaw0fw/36uFqo0YeA6m8JqoyE4OfqXsZCIg0hPP2xdE6FM7r6fdprDZHlJwDpydUj1R++93hCA==}
dependencies:
'@types/cookiejar': 2.1.2
'@types/node': 20.6.0
'@types/node': 20.11.22
dev: true
/@types/supertest/2.0.14:
@@ -18370,13 +18386,13 @@ packages:
/@types/tedious/4.0.14:
resolution: {integrity: sha512-KHPsfX/FoVbUGbyYvk1q9MMQHLPeRZhRJZdO45Q4YjvFkv4hMNghCWTvy7rdKessBsmtz4euWCWAB6/tVpI1Iw==}
dependencies:
'@types/node': 20.6.0
'@types/node': 20.11.22
dev: false
/@types/through/0.0.30:
resolution: {integrity: sha512-FvnCJljyxhPM3gkRgWmxmDZyAQSiBQQWLI0A0VFL0K7W1oRUrPJSqNO0NvTnLkBcotdlp3lKvaT0JrnyRDkzOg==}
dependencies:
'@types/node': 20.6.0
'@types/node': 20.11.22
dev: true
/@types/tinycolor2/1.4.3:
@@ -18400,7 +18416,7 @@ packages:
/@types/websocket/1.0.5:
resolution: {integrity: sha512-NbsqiNX9CnEfC1Z0Vf4mE1SgAJ07JnRYcNex7AJ9zAVzmiGHmjKFEk7O4TJIsgv2B1sLEb6owKFZrACwdYngsQ==}
dependencies:
'@types/node': 20.6.0
'@types/node': 20.11.22
dev: false
/@types/wrap-ansi/3.0.0:
@@ -18438,7 +18454,7 @@ packages:
resolution: {integrity: sha512-CHzgNU3qYBnp/O4S3yv2tXPlvMTq0YWSTVg2/JYLqWZGHwwgJGAwd00poay/11asPq8wLFwHzubyInqHIFmmiw==}
requiresBuild: true
dependencies:
'@types/node': 20.6.0
'@types/node': 20.11.22
dev: false
optional: true
@@ -24702,7 +24718,7 @@ packages:
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
dependencies:
'@jest/expect-utils': 29.6.2
'@types/node': 20.6.0
'@types/node': 20.11.22
jest-get-type: 29.4.3
jest-matcher-utils: 29.6.2
jest-message-util: 29.6.2
@@ -27752,7 +27768,7 @@ packages:
- supports-color
dev: true
/jest-config/29.6.2_@types+node@20.6.0:
/jest-config/29.6.2_@types+node@20.11.22:
resolution: {integrity: sha512-VxwFOC8gkiJbuodG9CPtMRjBUNZEHxwfQXmIudSTzFWxaci3Qub1ddTRbFNQlD/zUeaifLndh/eDccFX4wCMQw==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
peerDependencies:
@@ -27767,7 +27783,7 @@ packages:
'@babel/core': 7.22.17
'@jest/test-sequencer': 29.6.2
'@jest/types': 29.6.1
'@types/node': 20.6.0
'@types/node': 20.11.22
babel-jest: 29.6.2_@babel+core@7.22.17
chalk: 4.1.2
ci-info: 3.8.0
@@ -27843,7 +27859,7 @@ packages:
dependencies:
'@jest/types': 29.6.1
'@types/graceful-fs': 4.1.6
'@types/node': 20.6.0
'@types/node': 20.11.22
anymatch: 3.1.3
fb-watchman: 2.0.2
graceful-fs: 4.2.10
@@ -27894,7 +27910,7 @@ packages:
engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0}
dependencies:
'@jest/types': 27.5.1
'@types/node': 20.6.0
'@types/node': 20.11.22
dev: true
/jest-mock/29.6.2:
@@ -27957,7 +27973,7 @@ packages:
'@jest/test-result': 29.6.2
'@jest/transform': 29.6.2
'@jest/types': 29.6.1
'@types/node': 20.6.0
'@types/node': 20.11.22
chalk: 4.1.2
emittery: 0.13.1
graceful-fs: 4.2.10
@@ -27988,7 +28004,7 @@ packages:
'@jest/test-result': 29.6.2
'@jest/transform': 29.6.2
'@jest/types': 29.6.1
'@types/node': 20.6.0
'@types/node': 20.11.22
chalk: 4.1.2
cjs-module-lexer: 1.2.3
collect-v8-coverage: 1.0.2
@@ -28040,7 +28056,7 @@ packages:
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
dependencies:
'@jest/types': 29.6.1
'@types/node': 20.6.0
'@types/node': 20.11.22
chalk: 4.1.2
ci-info: 3.8.0
graceful-fs: 4.2.10
@@ -28065,7 +28081,7 @@ packages:
dependencies:
'@jest/test-result': 29.6.2
'@jest/types': 29.6.1
'@types/node': 20.6.0
'@types/node': 20.11.22
ansi-escapes: 4.3.2
chalk: 4.1.2
emittery: 0.13.1
@@ -32663,7 +32679,7 @@ packages:
'@protobufjs/path': 1.1.2
'@protobufjs/pool': 1.1.0
'@protobufjs/utf8': 1.1.0
'@types/node': 20.6.0
'@types/node': 20.11.22
long: 5.2.3
/proxy-addr/2.0.7:
+1 -1
View File
@@ -8,7 +8,7 @@ export const simplestTask = task({
body: JSON.stringify({
hello: "world",
taskId: "fetch-post-task",
foo: "barrrrrrrrrrrrrrrrrrrrrr",
foo: "barrrrrrrrrrrrrrrrrrr",
}),
});