v3: new build system (#1265)
* upgrade @opentelemetry packages to the latest versions * remove v2 only packages, will be moved to a dedicated repo * remove more v2 code and run pnpm install * use the npm yalt package in the webapp * convert @trigger.dev/core to tshy * Switch from jest to vitest in @trigger.dev/core * Fixed core test * move core-backend code into core subpath export * convert @trigger.dev/sdk to tshy * Removed hono * move core-apps to core/v3/apps, remove core-apps, start converting cli-v3 * Fix up some of the commands * cli now building and loadable * using package-json-from-dist to get package version now in core and cli * dev command WIP * cleaned up some repetition and structure of the entry point stuff * bringing back the background worker stuff * Indexing of the v3 catalog * getting closer to executing dev runs... * centralize dev logging using event emitter * Move indexing to it’s own entry point, simplify code * dev runs working * Get instrumentation to work with openai * debugging achieved internally * provide worker files as part of the worker creation on the server * support for cjs and esm javascript * Fixed timeout * worker manifest now has the config path * auto-upgrade config to non-deprecated alternatives * Adding package preview release * deployment WIP * improve the syncEnvVars output and adapt resolveEnvVars * WIP bun runtime * WIP bun support * seed tasks with the machine preset if listed in the config * deploy run executions WIP, extracted TaskRunProcess into 1 place * deployed tasks running and executing 🎉 * support for waits and better flushing & process cleanup * Fixed the heartbeating * Better warning messages * Improve and unify the indexing between dev and deploy * Support for external deps that need node-gyp to build * build extensions can now install custom packages and run instructions in the image. Also prisma extension now works and also works with multiple schema files * Add back in the main/types/module to sdk * dev no longer is Ink/React, grace period for disconnections in dev * Fix the changeset config * More changeset fixes * Remove config packages * More changeset fixes * Fixed typescript issues (needed to revert back to zod 3.22.3 * Fix pr_checks workflow * Remove the prepare script * Fixed tests and package versions * Remove cli test script * Remove packages from tailwind watch paths * Add repo to public packages * Just commit the generated files and do the building at dev time * Try and get pkg.pr.new working * Try again * Fix emitDecoratorMetadata importing named export from typescript * config file backwards compat with export const config * Fixed issue where import errors weren’t coming through * p-retry is a prod dep * typescript needs to be a prod dependency for emitDecoratorMetadata * Add better debug logging to help track down import-in-the-middle bug * An external is only considered resolvable if it resolves to the same path as the collected external * Fix runtime checks to allow >=18.20 * Move extensions to a new build package * Fixed building packages in dockerfile * Remove the e2e test from publish workflow for now * Don’t treat pkg.pr.new versions has needing upgrading * making sure config handleError works, and discovered path aliases don’t work in config files * Strip empty string env vars so they accidentally override real values * Couple of things * Update version to use preview instead of beta * Hopefully fix re-attempts with >30s delay * Match socket emit messages to current latest in main * Initial guide * Go back to beta * Go back to the preview, and update guide to use pr preview tags * Go back to beta --------- Co-authored-by: Matt Aitken <matt@mattaitken.com>
This commit is contained in:
@@ -16,11 +16,11 @@
|
|||||||
"webapp",
|
"webapp",
|
||||||
"emails",
|
"emails",
|
||||||
"proxy",
|
"proxy",
|
||||||
"yalt",
|
|
||||||
"@trigger.dev/database",
|
"@trigger.dev/database",
|
||||||
"coordinator",
|
"coordinator",
|
||||||
"docker-provider",
|
"docker-provider",
|
||||||
"kubernetes-provider"
|
"kubernetes-provider",
|
||||||
|
"@trigger.dev/otlp-importer"
|
||||||
],
|
],
|
||||||
"___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH": {
|
"___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH": {
|
||||||
"onlyUpdatePeerDependentsWhenOutOfRange": true
|
"onlyUpdatePeerDependentsWhenOutOfRange": true
|
||||||
|
|||||||
@@ -0,0 +1,7 @@
|
|||||||
|
---
|
||||||
|
"@trigger.dev/sdk": patch
|
||||||
|
"trigger.dev": patch
|
||||||
|
"@trigger.dev/core": patch
|
||||||
|
---
|
||||||
|
|
||||||
|
New Build System
|
||||||
+2
-30
@@ -8,40 +8,12 @@
|
|||||||
"proxy": "0.0.11",
|
"proxy": "0.0.11",
|
||||||
"webapp": "1.0.0",
|
"webapp": "1.0.0",
|
||||||
"yalt": "0.0.1",
|
"yalt": "0.0.1",
|
||||||
"@trigger.dev/airtable": "2.3.18",
|
|
||||||
"@trigger.dev/github": "2.3.18",
|
|
||||||
"@trigger.dev/linear": "2.3.18",
|
|
||||||
"@trigger.dev/openai": "2.3.18",
|
|
||||||
"@trigger.dev/plain": "2.3.18",
|
|
||||||
"@trigger.dev/replicate": "2.3.18",
|
|
||||||
"@trigger.dev/resend": "2.3.18",
|
|
||||||
"@trigger.dev/sendgrid": "2.3.18",
|
|
||||||
"@trigger.dev/shopify": "2.3.18",
|
|
||||||
"@trigger.dev/slack": "2.3.18",
|
|
||||||
"@trigger.dev/stripe": "2.3.18",
|
|
||||||
"@trigger.dev/supabase": "2.3.18",
|
|
||||||
"@trigger.dev/typeform": "2.3.18",
|
|
||||||
"@trigger.dev/astro": "2.3.18",
|
|
||||||
"@trigger.dev/cli": "2.3.18",
|
|
||||||
"trigger.dev": "2.3.18",
|
"trigger.dev": "2.3.18",
|
||||||
"@trigger.dev/core": "2.3.18",
|
"@trigger.dev/core": "2.3.18",
|
||||||
"@trigger.dev/core-apps": "0.0.0",
|
|
||||||
"@trigger.dev/core-backend": "2.3.18",
|
|
||||||
"@trigger.dev/database": "0.0.1",
|
"@trigger.dev/database": "0.0.1",
|
||||||
"emails": "1.0.0",
|
"emails": "1.0.0",
|
||||||
"@trigger.dev/eslint-plugin": "2.3.18",
|
|
||||||
"@trigger.dev/express": "2.3.18",
|
|
||||||
"@trigger.dev/hono": "2.3.18",
|
|
||||||
"@trigger.dev/integration-kit": "2.3.18",
|
|
||||||
"@trigger.dev/nestjs": "2.3.18",
|
|
||||||
"@trigger.dev/nextjs": "2.3.18",
|
|
||||||
"@trigger.dev/otlp-importer": "2.3.11",
|
"@trigger.dev/otlp-importer": "2.3.11",
|
||||||
"@trigger.dev/react": "2.3.18",
|
"@trigger.dev/sdk": "2.3.18"
|
||||||
"@trigger.dev/remix": "2.3.18",
|
|
||||||
"@trigger.dev/sveltekit": "2.3.18",
|
|
||||||
"@trigger.dev/testing": "2.3.18",
|
|
||||||
"@trigger.dev/sdk": "2.3.18",
|
|
||||||
"@trigger.dev/yalt": "2.3.18"
|
|
||||||
},
|
},
|
||||||
"changesets": [
|
"changesets": [
|
||||||
"afraid-sheep-joke",
|
"afraid-sheep-joke",
|
||||||
@@ -197,4 +169,4 @@
|
|||||||
"young-jars-wait",
|
"young-jars-wait",
|
||||||
"young-snails-sell"
|
"young-snails-sell"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,4 @@
|
|||||||
---
|
---
|
||||||
"@trigger.dev/otlp-importer": patch
|
|
||||||
"trigger.dev": patch
|
"trigger.dev": patch
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
---
|
---
|
||||||
"trigger.dev": major
|
"trigger.dev": major
|
||||||
"@trigger.dev/core": major
|
"@trigger.dev/core": major
|
||||||
"@trigger.dev/otlp-importer": major
|
|
||||||
"@trigger.dev/sdk": major
|
"@trigger.dev/sdk": major
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
"@trigger.dev/build": patch
|
||||||
|
---
|
||||||
|
|
||||||
|
Added new @trigger.dev/build package that currently has all the build extensions
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"target": "es2022",
|
||||||
|
"lib": ["ES2022", "DOM", "DOM.Iterable"],
|
||||||
|
"module": "NodeNext",
|
||||||
|
"moduleResolution": "NodeNext",
|
||||||
|
"moduleDetection": "force",
|
||||||
|
"verbatimModuleSyntax": false,
|
||||||
|
"jsx": "react",
|
||||||
|
|
||||||
|
"strict": true,
|
||||||
|
"alwaysStrict": true,
|
||||||
|
"strictPropertyInitialization": false,
|
||||||
|
"skipLibCheck": true,
|
||||||
|
"forceConsistentCasingInFileNames": true,
|
||||||
|
"noUnusedLocals": false,
|
||||||
|
"noUnusedParameters": false,
|
||||||
|
"noImplicitAny": true,
|
||||||
|
"noImplicitReturns": true,
|
||||||
|
"noImplicitThis": true,
|
||||||
|
|
||||||
|
"noFallthroughCasesInSwitch": true,
|
||||||
|
"resolveJsonModule": true,
|
||||||
|
|
||||||
|
"removeComments": false,
|
||||||
|
"esModuleInterop": true,
|
||||||
|
"emitDecoratorMetadata": false,
|
||||||
|
"experimentalDecorators": false,
|
||||||
|
"downlevelIteration": true,
|
||||||
|
"isolatedModules": true,
|
||||||
|
"noUncheckedIndexedAccess": true,
|
||||||
|
|
||||||
|
"pretty": true,
|
||||||
|
"customConditions": ["@triggerdotdev/source"]
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -37,6 +37,7 @@ packages/\*\*/dist
|
|||||||
.vercel
|
.vercel
|
||||||
.cache
|
.cache
|
||||||
.output
|
.output
|
||||||
|
.trigger
|
||||||
apps/\*\*/public/build
|
apps/\*\*/public/build
|
||||||
|
|
||||||
cypress/screenshots
|
cypress/screenshots
|
||||||
|
|||||||
@@ -76,11 +76,6 @@ jobs:
|
|||||||
node-version: 20.11.1
|
node-version: 20.11.1
|
||||||
cache: "pnpm"
|
cache: "pnpm"
|
||||||
|
|
||||||
- name: Install Protoc
|
|
||||||
uses: arduino/setup-protoc@v3
|
|
||||||
with:
|
|
||||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
|
|
||||||
- name: 📥 Download deps
|
- name: 📥 Download deps
|
||||||
run: pnpm install --frozen-lockfile
|
run: pnpm install --frozen-lockfile
|
||||||
|
|
||||||
|
|||||||
@@ -2,13 +2,7 @@ name: 🤖 PR Checks
|
|||||||
|
|
||||||
on:
|
on:
|
||||||
pull_request:
|
pull_request:
|
||||||
branches:
|
types: [opened, synchronize, reopened]
|
||||||
- main
|
|
||||||
paths-ignore:
|
|
||||||
- "**.md"
|
|
||||||
- "**.mdx"
|
|
||||||
- ".github/CODEOWNERS"
|
|
||||||
- ".github/ISSUE_TEMPLATE/**"
|
|
||||||
|
|
||||||
concurrency:
|
concurrency:
|
||||||
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
|
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
|
||||||
@@ -27,6 +21,38 @@ jobs:
|
|||||||
uses: ./.github/workflows/unit-tests.yml
|
uses: ./.github/workflows/unit-tests.yml
|
||||||
secrets: inherit
|
secrets: inherit
|
||||||
|
|
||||||
|
preview-release:
|
||||||
|
name: Preview Release
|
||||||
|
needs: [typecheck, units]
|
||||||
|
if: |
|
||||||
|
github.repository == 'triggerdotdev/trigger.dev'
|
||||||
|
runs-on: buildjet-8vcpu-ubuntu-2204
|
||||||
|
steps:
|
||||||
|
- name: ⬇️ Checkout repo
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
|
|
||||||
|
- name: ⎔ Setup pnpm
|
||||||
|
uses: pnpm/action-setup@v4
|
||||||
|
with:
|
||||||
|
version: 8.15.5
|
||||||
|
|
||||||
|
- name: ⎔ Setup node
|
||||||
|
uses: buildjet/setup-node@v3
|
||||||
|
with:
|
||||||
|
node-version: 20.11.1
|
||||||
|
cache: "pnpm"
|
||||||
|
|
||||||
|
- name: 📥 Download deps
|
||||||
|
run: pnpm install --frozen-lockfile
|
||||||
|
|
||||||
|
- name: 🏗️ Build
|
||||||
|
run: pnpm run build --filter "@trigger.dev/*" --filter "trigger.dev"
|
||||||
|
|
||||||
|
- name: ⚡ publish preview release
|
||||||
|
run: npx pkg-pr-new publish --no-template $(ls -d ./packages/*)
|
||||||
|
|
||||||
# e2e:
|
# e2e:
|
||||||
# uses: ./.github/workflows/e2e.yml
|
# uses: ./.github/workflows/e2e.yml
|
||||||
# with:
|
# with:
|
||||||
|
|||||||
@@ -49,12 +49,6 @@ jobs:
|
|||||||
uses: ./.github/workflows/unit-tests.yml
|
uses: ./.github/workflows/unit-tests.yml
|
||||||
secrets: inherit
|
secrets: inherit
|
||||||
|
|
||||||
e2e:
|
|
||||||
uses: ./.github/workflows/e2e.yml
|
|
||||||
with:
|
|
||||||
package: cli-v3
|
|
||||||
secrets: inherit
|
|
||||||
|
|
||||||
publish:
|
publish:
|
||||||
needs: [typecheck, units]
|
needs: [typecheck, units]
|
||||||
uses: ./.github/workflows/publish-docker.yml
|
uses: ./.github/workflows/publish-docker.yml
|
||||||
|
|||||||
@@ -38,11 +38,6 @@ jobs:
|
|||||||
node-version: 20.11.1
|
node-version: 20.11.1
|
||||||
cache: "pnpm"
|
cache: "pnpm"
|
||||||
|
|
||||||
- name: Install Protoc
|
|
||||||
uses: arduino/setup-protoc@v3
|
|
||||||
with:
|
|
||||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
|
|
||||||
- name: 📥 Download deps
|
- name: 📥 Download deps
|
||||||
run: pnpm install --frozen-lockfile
|
run: pnpm install --frozen-lockfile
|
||||||
|
|
||||||
|
|||||||
@@ -22,11 +22,6 @@ jobs:
|
|||||||
node-version: 20.11.1
|
node-version: 20.11.1
|
||||||
cache: "pnpm"
|
cache: "pnpm"
|
||||||
|
|
||||||
- name: Install Protoc
|
|
||||||
uses: arduino/setup-protoc@v3
|
|
||||||
with:
|
|
||||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
|
|
||||||
- name: 📥 Download deps
|
- name: 📥 Download deps
|
||||||
run: pnpm install --frozen-lockfile
|
run: pnpm install --frozen-lockfile
|
||||||
|
|
||||||
|
|||||||
@@ -22,21 +22,6 @@ jobs:
|
|||||||
node-version: 20.11.1
|
node-version: 20.11.1
|
||||||
cache: "pnpm"
|
cache: "pnpm"
|
||||||
|
|
||||||
- name: Install Protoc
|
|
||||||
uses: arduino/setup-protoc@v3
|
|
||||||
with:
|
|
||||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
|
|
||||||
- name: ⎔ Setup Deno
|
|
||||||
uses: denoland/setup-deno@v1
|
|
||||||
with:
|
|
||||||
deno-version: v1.x
|
|
||||||
|
|
||||||
- name: ⎔ Setup bun
|
|
||||||
uses: oven-sh/setup-bun@v1
|
|
||||||
with:
|
|
||||||
bun-version: "1.0.15"
|
|
||||||
|
|
||||||
- name: 📥 Download deps
|
- name: 📥 Download deps
|
||||||
run: pnpm install --frozen-lockfile
|
run: pnpm install --frozen-lockfile
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -12,7 +12,6 @@ coverage
|
|||||||
# next.js
|
# next.js
|
||||||
.next/
|
.next/
|
||||||
out/
|
out/
|
||||||
build
|
|
||||||
dist
|
dist
|
||||||
packages/**/dist
|
packages/**/dist
|
||||||
|
|
||||||
@@ -54,4 +53,5 @@ apps/**/public/build
|
|||||||
/playwright/.cache/
|
/playwright/.cache/
|
||||||
|
|
||||||
.cosine
|
.cosine
|
||||||
.trigger/
|
.trigger/
|
||||||
|
.tshy*
|
||||||
@@ -7,5 +7,4 @@ tailwind.css
|
|||||||
**/.react-email/
|
**/.react-email/
|
||||||
**/storybook-static/
|
**/storybook-static/
|
||||||
**/.changeset/
|
**/.changeset/
|
||||||
**/build/
|
|
||||||
**/dist/
|
**/dist/
|
||||||
Vendored
+18
-2
@@ -33,7 +33,7 @@
|
|||||||
"type": "node-terminal",
|
"type": "node-terminal",
|
||||||
"request": "launch",
|
"request": "launch",
|
||||||
"name": "Debug V3 Dev CLI",
|
"name": "Debug V3 Dev CLI",
|
||||||
"command": "pnpm exec triggerdev dev --log-level debug",
|
"command": "pnpm exec triggerdev dev",
|
||||||
"cwd": "${workspaceFolder}/references/v3-catalog",
|
"cwd": "${workspaceFolder}/references/v3-catalog",
|
||||||
"sourceMaps": true
|
"sourceMaps": true
|
||||||
},
|
},
|
||||||
@@ -41,7 +41,23 @@
|
|||||||
"type": "node-terminal",
|
"type": "node-terminal",
|
||||||
"request": "launch",
|
"request": "launch",
|
||||||
"name": "Debug V3 Deploy CLI",
|
"name": "Debug V3 Deploy CLI",
|
||||||
"command": "pnpm exec triggerdev deploy",
|
"command": "pnpm exec triggerdev deploy --self-hosted --load-image",
|
||||||
|
"cwd": "${workspaceFolder}/references/v3-catalog",
|
||||||
|
"sourceMaps": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "node-terminal",
|
||||||
|
"request": "launch",
|
||||||
|
"name": "Debug V3 list-profiles CLI",
|
||||||
|
"command": "pnpm exec triggerdev list-profiles --log-level debug",
|
||||||
|
"cwd": "${workspaceFolder}/references/v3-catalog",
|
||||||
|
"sourceMaps": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "node-terminal",
|
||||||
|
"request": "launch",
|
||||||
|
"name": "Debug V3 update CLI",
|
||||||
|
"command": "pnpm exec triggerdev update",
|
||||||
"cwd": "${workspaceFolder}/references/v3-catalog",
|
"cwd": "${workspaceFolder}/references/v3-catalog",
|
||||||
"sourceMaps": true
|
"sourceMaps": true
|
||||||
},
|
},
|
||||||
|
|||||||
Vendored
+6
-1
@@ -1,4 +1,9 @@
|
|||||||
{
|
{
|
||||||
"deno.enablePaths": ["references/deno-reference", "runtime_tests/tests/deno"],
|
"deno.enablePaths": ["references/deno-reference", "runtime_tests/tests/deno"],
|
||||||
"debug.toolBarLocation": "commandCenter"
|
"debug.toolBarLocation": "commandCenter",
|
||||||
|
"typescript.tsdk": "node_modules/typescript/lib",
|
||||||
|
"search.exclude": {
|
||||||
|
"**/node_modules/**": true,
|
||||||
|
"packages/cli-v3/e2e": true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,7 +17,6 @@
|
|||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@trigger.dev/core": "workspace:*",
|
"@trigger.dev/core": "workspace:*",
|
||||||
"@trigger.dev/core-apps": "workspace:*",
|
|
||||||
"execa": "^8.0.1",
|
"execa": "^8.0.1",
|
||||||
"nanoid": "^5.0.6",
|
"nanoid": "^5.0.6",
|
||||||
"prom-client": "^15.1.0",
|
"prom-client": "^15.1.0",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { ExponentialBackoff } from "@trigger.dev/core-apps/backoff";
|
import { ExponentialBackoff } from "@trigger.dev/core/v3/apps";
|
||||||
import { isExecaChildProcess, testDockerCheckpoint } from "@trigger.dev/core-apps/checkpoints";
|
import { testDockerCheckpoint, isExecaChildProcess } from "@trigger.dev/core/v3/apps";
|
||||||
import { SimpleLogger } from "@trigger.dev/core-apps/logger";
|
import { SimpleLogger } from "@trigger.dev/core/v3/apps";
|
||||||
import { $ } from "execa";
|
import { $ } from "execa";
|
||||||
import { nanoid } from "nanoid";
|
import { nanoid } from "nanoid";
|
||||||
import fs from "node:fs/promises";
|
import fs from "node:fs/promises";
|
||||||
|
|||||||
@@ -10,8 +10,8 @@ import {
|
|||||||
} from "@trigger.dev/core/v3";
|
} from "@trigger.dev/core/v3";
|
||||||
import { ZodNamespace } from "@trigger.dev/core/v3/zodNamespace";
|
import { ZodNamespace } from "@trigger.dev/core/v3/zodNamespace";
|
||||||
import { ZodSocketConnection } from "@trigger.dev/core/v3/zodSocket";
|
import { ZodSocketConnection } from "@trigger.dev/core/v3/zodSocket";
|
||||||
import { HttpReply, getTextBody } from "@trigger.dev/core-apps/http";
|
import { HttpReply, getTextBody } from "@trigger.dev/core/v3/apps";
|
||||||
import { SimpleLogger } from "@trigger.dev/core-apps/logger";
|
import { SimpleLogger } from "@trigger.dev/core/v3/apps";
|
||||||
import { ChaosMonkey } from "./chaosMonkey";
|
import { ChaosMonkey } from "./chaosMonkey";
|
||||||
import { Checkpointer } from "./checkpointer";
|
import { Checkpointer } from "./checkpointer";
|
||||||
|
|
||||||
|
|||||||
@@ -11,9 +11,7 @@
|
|||||||
"skipLibCheck": true,
|
"skipLibCheck": true,
|
||||||
"paths": {
|
"paths": {
|
||||||
"@trigger.dev/core/v3": ["../../packages/core/src/v3"],
|
"@trigger.dev/core/v3": ["../../packages/core/src/v3"],
|
||||||
"@trigger.dev/core/v3/*": ["../../packages/core/src/v3/*"],
|
"@trigger.dev/core/v3/*": ["../../packages/core/src/v3/*"]
|
||||||
"@trigger.dev/core-apps": ["../../packages/core-apps/src"],
|
|
||||||
"@trigger.dev/core-apps/*": ["../../packages/core-apps/src/*"]
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,7 +17,6 @@
|
|||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@trigger.dev/core": "workspace:*",
|
"@trigger.dev/core": "workspace:*",
|
||||||
"@trigger.dev/core-apps": "workspace:*",
|
|
||||||
"execa": "^8.0.1"
|
"execa": "^8.0.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
|||||||
@@ -5,9 +5,9 @@ import {
|
|||||||
TaskOperationsCreateOptions,
|
TaskOperationsCreateOptions,
|
||||||
TaskOperationsIndexOptions,
|
TaskOperationsIndexOptions,
|
||||||
TaskOperationsRestoreOptions,
|
TaskOperationsRestoreOptions,
|
||||||
} from "@trigger.dev/core-apps/provider";
|
} from "@trigger.dev/core/v3/apps";
|
||||||
import { SimpleLogger } from "@trigger.dev/core-apps/logger";
|
import { SimpleLogger } from "@trigger.dev/core/v3/apps";
|
||||||
import { isExecaChildProcess, testDockerCheckpoint } from "@trigger.dev/core-apps/checkpoints";
|
import { isExecaChildProcess, testDockerCheckpoint } from "@trigger.dev/core/v3/apps";
|
||||||
import { setTimeout } from "node:timers/promises";
|
import { setTimeout } from "node:timers/promises";
|
||||||
import { PostStartCauses, PreStopCauses } from "@trigger.dev/core/v3";
|
import { PostStartCauses, PreStopCauses } from "@trigger.dev/core/v3";
|
||||||
|
|
||||||
|
|||||||
@@ -9,9 +9,7 @@
|
|||||||
"skipLibCheck": true,
|
"skipLibCheck": true,
|
||||||
"paths": {
|
"paths": {
|
||||||
"@trigger.dev/core/v3": ["../../packages/core/src/v3"],
|
"@trigger.dev/core/v3": ["../../packages/core/src/v3"],
|
||||||
"@trigger.dev/core/v3/*": ["../../packages/core/src/v3/*"],
|
"@trigger.dev/core/v3/*": ["../../packages/core/src/v3/*"]
|
||||||
"@trigger.dev/core-apps": ["../../packages/core-apps/src"],
|
|
||||||
"@trigger.dev/core-apps/*": ["../../packages/core-apps/src/*"]
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,7 +18,6 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@kubernetes/client-node": "^0.20.0",
|
"@kubernetes/client-node": "^0.20.0",
|
||||||
"@trigger.dev/core": "workspace:*",
|
"@trigger.dev/core": "workspace:*",
|
||||||
"@trigger.dev/core-apps": "workspace:*",
|
|
||||||
"p-queue": "^8.0.1"
|
"p-queue": "^8.0.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
|||||||
@@ -6,8 +6,8 @@ import {
|
|||||||
TaskOperationsIndexOptions,
|
TaskOperationsIndexOptions,
|
||||||
TaskOperationsPrePullDeploymentOptions,
|
TaskOperationsPrePullDeploymentOptions,
|
||||||
TaskOperationsRestoreOptions,
|
TaskOperationsRestoreOptions,
|
||||||
} from "@trigger.dev/core-apps/provider";
|
} from "@trigger.dev/core/v3/apps";
|
||||||
import { SimpleLogger } from "@trigger.dev/core-apps/logger";
|
import { SimpleLogger } from "@trigger.dev/core/v3/apps";
|
||||||
import {
|
import {
|
||||||
MachinePreset,
|
MachinePreset,
|
||||||
PostStartCauses,
|
PostStartCauses,
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import * as k8s from "@kubernetes/client-node";
|
import * as k8s from "@kubernetes/client-node";
|
||||||
import { SimpleLogger } from "@trigger.dev/core-apps/logger";
|
import { SimpleLogger } from "@trigger.dev/core/v3/apps";
|
||||||
|
|
||||||
type PodCleanerOptions = {
|
type PodCleanerOptions = {
|
||||||
runtimeEnv: "local" | "kubernetes";
|
runtimeEnv: "local" | "kubernetes";
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import * as k8s from "@kubernetes/client-node";
|
import * as k8s from "@kubernetes/client-node";
|
||||||
import { SimpleLogger } from "@trigger.dev/core-apps/logger";
|
import { SimpleLogger } from "@trigger.dev/core/v3/apps";
|
||||||
import { EXIT_CODE_ALREADY_HANDLED, EXIT_CODE_CHILD_NONZERO } from "@trigger.dev/core-apps/process";
|
import { EXIT_CODE_ALREADY_HANDLED, EXIT_CODE_CHILD_NONZERO } from "@trigger.dev/core/v3/apps";
|
||||||
import { setTimeout } from "timers/promises";
|
import { setTimeout } from "timers/promises";
|
||||||
import PQueue from "p-queue";
|
import PQueue from "p-queue";
|
||||||
import type { Prettify } from "@trigger.dev/core/v3";
|
import type { Prettify } from "@trigger.dev/core/v3";
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import * as k8s from "@kubernetes/client-node";
|
import * as k8s from "@kubernetes/client-node";
|
||||||
import { SimpleLogger } from "@trigger.dev/core-apps/logger";
|
import { SimpleLogger } from "@trigger.dev/core/v3/apps";
|
||||||
|
|
||||||
type UptimeHeartbeatOptions = {
|
type UptimeHeartbeatOptions = {
|
||||||
runtimeEnv: "local" | "kubernetes";
|
runtimeEnv: "local" | "kubernetes";
|
||||||
|
|||||||
@@ -9,9 +9,7 @@
|
|||||||
"skipLibCheck": true,
|
"skipLibCheck": true,
|
||||||
"paths": {
|
"paths": {
|
||||||
"@trigger.dev/core/v3": ["../../packages/core/src/v3"],
|
"@trigger.dev/core/v3": ["../../packages/core/src/v3"],
|
||||||
"@trigger.dev/core/v3/*": ["../../packages/core/src/v3/*"],
|
"@trigger.dev/core/v3/*": ["../../packages/core/src/v3/*"]
|
||||||
"@trigger.dev/core-apps": ["../../packages/core-apps/src"],
|
|
||||||
"@trigger.dev/core-apps/*": ["../../packages/core-apps/src/*"]
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,4 +18,4 @@
|
|||||||
"zod": "3.22.3",
|
"zod": "3.22.3",
|
||||||
"zod-error": "1.5.0"
|
"zod-error": "1.5.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,10 +1,10 @@
|
|||||||
import { Form, useFetcher, useNavigation, useSubmit } from "@remix-run/react";
|
import { Form, useNavigation, useSubmit } from "@remix-run/react";
|
||||||
import { useCallback, useEffect, useRef } from "react";
|
import { useCallback, useEffect, useRef } from "react";
|
||||||
import { UseDataFunctionReturn, useTypedFetcher } from "remix-typedjson";
|
import { UseDataFunctionReturn, useTypedFetcher } from "remix-typedjson";
|
||||||
import { JSONEditor } from "~/components/code/JSONEditor";
|
import { JSONEditor } from "~/components/code/JSONEditor";
|
||||||
import { EnvironmentLabel } from "~/components/environments/EnvironmentLabel";
|
import { EnvironmentLabel } from "~/components/environments/EnvironmentLabel";
|
||||||
import { Button } from "~/components/primitives/Buttons";
|
import { Button } from "~/components/primitives/Buttons";
|
||||||
import { DialogContent, DialogDescription, DialogHeader } from "~/components/primitives/Dialog";
|
import { DialogContent, DialogHeader } from "~/components/primitives/Dialog";
|
||||||
import { Header3 } from "~/components/primitives/Headers";
|
import { Header3 } from "~/components/primitives/Headers";
|
||||||
import { InputGroup } from "~/components/primitives/InputGroup";
|
import { InputGroup } from "~/components/primitives/InputGroup";
|
||||||
import { Label } from "~/components/primitives/Label";
|
import { Label } from "~/components/primitives/Label";
|
||||||
@@ -27,7 +27,7 @@ export function ReplayRunDialog({ runFriendlyId, failedRedirect }: ReplayRunDial
|
|||||||
|
|
||||||
function ReplayContent({ runFriendlyId, failedRedirect }: ReplayRunDialogProps) {
|
function ReplayContent({ runFriendlyId, failedRedirect }: ReplayRunDialogProps) {
|
||||||
const fetcher = useTypedFetcher<typeof loader>();
|
const fetcher = useTypedFetcher<typeof loader>();
|
||||||
const isLoading = fetcher.state !== "idle";
|
const isLoading = fetcher.state === "loading";
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
fetcher.load(`/resources/taskruns/${runFriendlyId}/replay`);
|
fetcher.load(`/resources/taskruns/${runFriendlyId}/replay`);
|
||||||
|
|||||||
@@ -116,6 +116,19 @@ export async function disconnectSession(environmentId: string) {
|
|||||||
return session;
|
return session;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function findLatestSession(environmentId: string) {
|
||||||
|
const session = await prisma.runtimeEnvironmentSession.findFirst({
|
||||||
|
where: {
|
||||||
|
environmentId,
|
||||||
|
},
|
||||||
|
orderBy: {
|
||||||
|
createdAt: "desc",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
return session;
|
||||||
|
}
|
||||||
|
|
||||||
export type DisplayableInputEnvironment = Prisma.RuntimeEnvironmentGetPayload<{
|
export type DisplayableInputEnvironment = Prisma.RuntimeEnvironmentGetPayload<{
|
||||||
select: {
|
select: {
|
||||||
id: true;
|
id: true;
|
||||||
|
|||||||
@@ -1,16 +1,13 @@
|
|||||||
import {
|
import {
|
||||||
DeploymentErrorData,
|
DeploymentErrorData,
|
||||||
ExternalBuildData,
|
ExternalBuildData,
|
||||||
TaskMetadataFailedToParseData,
|
prepareDeploymentError,
|
||||||
groupTaskMetadataIssuesByTask,
|
|
||||||
} from "@trigger.dev/core/v3";
|
} from "@trigger.dev/core/v3";
|
||||||
import { WorkerDeployment, WorkerDeploymentStatus } from "@trigger.dev/database";
|
import { WorkerDeployment } from "@trigger.dev/database";
|
||||||
import { z } from "zod";
|
|
||||||
import { PrismaClient, prisma } from "~/db.server";
|
import { PrismaClient, prisma } from "~/db.server";
|
||||||
import { Organization } from "~/models/organization.server";
|
import { Organization } from "~/models/organization.server";
|
||||||
import { Project } from "~/models/project.server";
|
import { Project } from "~/models/project.server";
|
||||||
import { User } from "~/models/user.server";
|
import { User } from "~/models/user.server";
|
||||||
import { safeJsonParse } from "~/utils/json";
|
|
||||||
import { getUsername } from "~/utils/username";
|
import { getUsername } from "~/utils/username";
|
||||||
|
|
||||||
export type ErrorData = {
|
export type ErrorData = {
|
||||||
@@ -164,75 +161,12 @@ export class DeploymentPresenter {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const parsedErrorData = DeploymentErrorData.safeParse(errorData);
|
const deploymentError = DeploymentErrorData.safeParse(errorData);
|
||||||
|
|
||||||
if (!parsedErrorData.success) {
|
if (!deploymentError.success) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (parsedErrorData.data.name === "TaskMetadataParseError") {
|
return prepareDeploymentError(deploymentError.data);
|
||||||
const errorJson = safeJsonParse(parsedErrorData.data.stack);
|
|
||||||
|
|
||||||
if (errorJson) {
|
|
||||||
const parsedError = TaskMetadataFailedToParseData.safeParse(errorJson);
|
|
||||||
|
|
||||||
if (parsedError.success) {
|
|
||||||
return {
|
|
||||||
name: parsedErrorData.data.name,
|
|
||||||
message: parsedErrorData.data.message,
|
|
||||||
stack: createTaskMetadataFailedErrorStack(parsedError.data),
|
|
||||||
stderr: parsedErrorData.data.stderr,
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
return {
|
|
||||||
name: parsedErrorData.data.name,
|
|
||||||
message: parsedErrorData.data.message,
|
|
||||||
stderr: parsedErrorData.data.stderr,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return {
|
|
||||||
name: parsedErrorData.data.name,
|
|
||||||
message: parsedErrorData.data.message,
|
|
||||||
stderr: parsedErrorData.data.stderr,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
name: parsedErrorData.data.name,
|
|
||||||
message: parsedErrorData.data.message,
|
|
||||||
stack: parsedErrorData.data.stack,
|
|
||||||
stderr: parsedErrorData.data.stderr,
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function createTaskMetadataFailedErrorStack(
|
|
||||||
data: z.infer<typeof TaskMetadataFailedToParseData>
|
|
||||||
): string {
|
|
||||||
const stack = [];
|
|
||||||
|
|
||||||
const groupedIssues = groupTaskMetadataIssuesByTask(data.tasks, data.zodIssues);
|
|
||||||
|
|
||||||
for (const key in groupedIssues) {
|
|
||||||
const taskWithIssues = groupedIssues[key];
|
|
||||||
|
|
||||||
if (!taskWithIssues) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
stack.push("\n");
|
|
||||||
stack.push(` ❯ ${taskWithIssues.exportName} in ${taskWithIssues.filePath}`);
|
|
||||||
|
|
||||||
for (const issue of taskWithIssues.issues) {
|
|
||||||
if (issue.path) {
|
|
||||||
stack.push(` x ${issue.path} ${issue.message}`);
|
|
||||||
} else {
|
|
||||||
stack.push(` x ${issue.message}`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return stack.join("\n");
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -0,0 +1,73 @@
|
|||||||
|
import { ActionFunctionArgs, json } from "@remix-run/server-runtime";
|
||||||
|
import { CreateBackgroundWorkerRequestBody } from "@trigger.dev/core/v3";
|
||||||
|
import { z } from "zod";
|
||||||
|
import { authenticateApiRequest } from "~/services/apiAuth.server";
|
||||||
|
import { logger } from "~/services/logger.server";
|
||||||
|
import { ServiceValidationError } from "~/v3/services/baseService.server";
|
||||||
|
import { CreateDeclarativeScheduleError } from "~/v3/services/createBackgroundWorker.server";
|
||||||
|
import { CreateDeploymentBackgroundWorkerService } from "~/v3/services/createDeploymentBackgroundWorker.server";
|
||||||
|
|
||||||
|
const ParamsSchema = z.object({
|
||||||
|
deploymentId: z.string(),
|
||||||
|
});
|
||||||
|
|
||||||
|
export async function action({ request, params }: ActionFunctionArgs) {
|
||||||
|
// Ensure this is a POST request
|
||||||
|
if (request.method.toUpperCase() !== "POST") {
|
||||||
|
return { status: 405, body: "Method Not Allowed" };
|
||||||
|
}
|
||||||
|
|
||||||
|
const parsedParams = ParamsSchema.safeParse(params);
|
||||||
|
|
||||||
|
if (!parsedParams.success) {
|
||||||
|
return json({ error: "Invalid params" }, { status: 400 });
|
||||||
|
}
|
||||||
|
|
||||||
|
// Next authenticate the request
|
||||||
|
const authenticationResult = await authenticateApiRequest(request);
|
||||||
|
|
||||||
|
if (!authenticationResult) {
|
||||||
|
logger.info("Invalid or missing api key", { url: request.url });
|
||||||
|
return json({ error: "Invalid or Missing API key" }, { status: 401 });
|
||||||
|
}
|
||||||
|
|
||||||
|
const authenticatedEnv = authenticationResult.environment;
|
||||||
|
|
||||||
|
const { deploymentId } = parsedParams.data;
|
||||||
|
|
||||||
|
const rawBody = await request.json();
|
||||||
|
const body = CreateBackgroundWorkerRequestBody.safeParse(rawBody);
|
||||||
|
|
||||||
|
if (!body.success) {
|
||||||
|
return json({ error: "Invalid body", issues: body.error.issues }, { status: 400 });
|
||||||
|
}
|
||||||
|
|
||||||
|
const service = new CreateDeploymentBackgroundWorkerService();
|
||||||
|
|
||||||
|
try {
|
||||||
|
const backgroundWorker = await service.call(authenticatedEnv, deploymentId, body.data);
|
||||||
|
|
||||||
|
if (!backgroundWorker) {
|
||||||
|
return json({ error: "Failed to create background worker" }, { status: 500 });
|
||||||
|
}
|
||||||
|
|
||||||
|
return json(
|
||||||
|
{
|
||||||
|
id: backgroundWorker.friendlyId,
|
||||||
|
version: backgroundWorker.version,
|
||||||
|
contentHash: backgroundWorker.contentHash,
|
||||||
|
},
|
||||||
|
{ status: 200 }
|
||||||
|
);
|
||||||
|
} catch (e) {
|
||||||
|
logger.error("Failed to create background worker", { error: e });
|
||||||
|
|
||||||
|
if (e instanceof ServiceValidationError) {
|
||||||
|
return json({ error: e.message }, { status: 400 });
|
||||||
|
} else if (e instanceof CreateDeclarativeScheduleError) {
|
||||||
|
return json({ error: e.message }, { status: 400 });
|
||||||
|
}
|
||||||
|
|
||||||
|
return json({ error: "Failed to create background worker" }, { status: 500 });
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,52 @@
|
|||||||
|
import { ActionFunctionArgs, json } from "@remix-run/server-runtime";
|
||||||
|
import { FailDeploymentRequestBody } from "@trigger.dev/core/v3";
|
||||||
|
import { z } from "zod";
|
||||||
|
import { authenticateApiRequest } from "~/services/apiAuth.server";
|
||||||
|
import { logger } from "~/services/logger.server";
|
||||||
|
import { FailDeploymentService } from "~/v3/services/failDeployment.server";
|
||||||
|
|
||||||
|
const ParamsSchema = z.object({
|
||||||
|
deploymentId: z.string(),
|
||||||
|
});
|
||||||
|
|
||||||
|
export async function action({ request, params }: ActionFunctionArgs) {
|
||||||
|
// Ensure this is a POST request
|
||||||
|
if (request.method.toUpperCase() !== "POST") {
|
||||||
|
return { status: 405, body: "Method Not Allowed" };
|
||||||
|
}
|
||||||
|
|
||||||
|
const parsedParams = ParamsSchema.safeParse(params);
|
||||||
|
|
||||||
|
if (!parsedParams.success) {
|
||||||
|
return json({ error: "Invalid params" }, { status: 400 });
|
||||||
|
}
|
||||||
|
|
||||||
|
// Next authenticate the request
|
||||||
|
const authenticationResult = await authenticateApiRequest(request);
|
||||||
|
|
||||||
|
if (!authenticationResult) {
|
||||||
|
logger.info("Invalid or missing api key", { url: request.url });
|
||||||
|
return json({ error: "Invalid or Missing API key" }, { status: 401 });
|
||||||
|
}
|
||||||
|
|
||||||
|
const authenticatedEnv = authenticationResult.environment;
|
||||||
|
|
||||||
|
const { deploymentId } = parsedParams.data;
|
||||||
|
|
||||||
|
const rawBody = await request.json();
|
||||||
|
const body = FailDeploymentRequestBody.safeParse(rawBody);
|
||||||
|
|
||||||
|
if (!body.success) {
|
||||||
|
return json({ error: "Invalid body", issues: body.error.issues }, { status: 400 });
|
||||||
|
}
|
||||||
|
|
||||||
|
const service = new FailDeploymentService();
|
||||||
|
await service.call(authenticatedEnv, deploymentId, body.data);
|
||||||
|
|
||||||
|
return json(
|
||||||
|
{
|
||||||
|
id: deploymentId,
|
||||||
|
},
|
||||||
|
{ status: 200 }
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,65 @@
|
|||||||
|
import { ActionFunctionArgs, json } from "@remix-run/server-runtime";
|
||||||
|
import { FinalizeDeploymentRequestBody } from "@trigger.dev/core/v3";
|
||||||
|
import { z } from "zod";
|
||||||
|
import { authenticateApiRequest } from "~/services/apiAuth.server";
|
||||||
|
import { logger } from "~/services/logger.server";
|
||||||
|
import { ServiceValidationError } from "~/v3/services/baseService.server";
|
||||||
|
import { FinalizeDeploymentService } from "~/v3/services/finalizeDeployment.server";
|
||||||
|
|
||||||
|
const ParamsSchema = z.object({
|
||||||
|
deploymentId: z.string(),
|
||||||
|
});
|
||||||
|
|
||||||
|
export async function action({ request, params }: ActionFunctionArgs) {
|
||||||
|
// Ensure this is a POST request
|
||||||
|
if (request.method.toUpperCase() !== "POST") {
|
||||||
|
return { status: 405, body: "Method Not Allowed" };
|
||||||
|
}
|
||||||
|
|
||||||
|
const parsedParams = ParamsSchema.safeParse(params);
|
||||||
|
|
||||||
|
if (!parsedParams.success) {
|
||||||
|
return json({ error: "Invalid params" }, { status: 400 });
|
||||||
|
}
|
||||||
|
|
||||||
|
// Next authenticate the request
|
||||||
|
const authenticationResult = await authenticateApiRequest(request);
|
||||||
|
|
||||||
|
if (!authenticationResult) {
|
||||||
|
logger.info("Invalid or missing api key", { url: request.url });
|
||||||
|
return json({ error: "Invalid or Missing API key" }, { status: 401 });
|
||||||
|
}
|
||||||
|
|
||||||
|
const authenticatedEnv = authenticationResult.environment;
|
||||||
|
|
||||||
|
const { deploymentId } = parsedParams.data;
|
||||||
|
|
||||||
|
const rawBody = await request.json();
|
||||||
|
const body = FinalizeDeploymentRequestBody.safeParse(rawBody);
|
||||||
|
|
||||||
|
if (!body.success) {
|
||||||
|
return json({ error: "Invalid body", issues: body.error.issues }, { status: 400 });
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const service = new FinalizeDeploymentService();
|
||||||
|
await service.call(authenticatedEnv, deploymentId, body.data);
|
||||||
|
|
||||||
|
return json(
|
||||||
|
{
|
||||||
|
id: deploymentId,
|
||||||
|
},
|
||||||
|
{ status: 200 }
|
||||||
|
);
|
||||||
|
} catch (error) {
|
||||||
|
if (error instanceof ServiceValidationError) {
|
||||||
|
return json({ error: error.message }, { status: 400 });
|
||||||
|
} else if (error instanceof Error) {
|
||||||
|
logger.error("Error finalizing deployment", { error: error.message });
|
||||||
|
return json({ error: `Internal server error: ${error.message}` }, { status: 500 });
|
||||||
|
} else {
|
||||||
|
logger.error("Error finalizing deployment", { error: String(error) });
|
||||||
|
return json({ error: "Internal server error" }, { status: 500 });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -89,6 +89,7 @@ export async function loader({ request, params }: LoaderFunctionArgs) {
|
|||||||
apiKey: runtimeEnv.apiKey,
|
apiKey: runtimeEnv.apiKey,
|
||||||
name: project.name,
|
name: project.name,
|
||||||
apiUrl: processEnv.APP_ORIGIN,
|
apiUrl: processEnv.APP_ORIGIN,
|
||||||
|
projectId: project.id,
|
||||||
};
|
};
|
||||||
|
|
||||||
return json(result);
|
return json(result);
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { Logger } from "@trigger.dev/core-backend";
|
import { Logger } from "@trigger.dev/core/logger";
|
||||||
import type { PoolClient } from "pg";
|
import type { PoolClient } from "pg";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
import { logger } from "~/services/logger.server";
|
import { logger } from "~/services/logger.server";
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import type { LogLevel } from "@trigger.dev/core-backend";
|
import type { LogLevel } from "@trigger.dev/core/logger";
|
||||||
import { Logger } from "@trigger.dev/core-backend";
|
import { Logger } from "@trigger.dev/core/logger";
|
||||||
import { sensitiveDataReplacer } from "./sensitiveDataReplacer";
|
import { sensitiveDataReplacer } from "./sensitiveDataReplacer";
|
||||||
import { AsyncLocalStorage } from "async_hooks";
|
import { AsyncLocalStorage } from "async_hooks";
|
||||||
import { getHttpContext } from "./httpAsyncStorage.server";
|
import { getHttpContext } from "./httpAsyncStorage.server";
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ import {
|
|||||||
RunSourceContextSchema,
|
RunSourceContextSchema,
|
||||||
supportsFeature,
|
supportsFeature,
|
||||||
} from "@trigger.dev/core";
|
} from "@trigger.dev/core";
|
||||||
import { BloomFilter } from "@trigger.dev/core-backend";
|
import { BloomFilter } from "@trigger.dev/core/bloom";
|
||||||
import { ConcurrencyLimitGroup, Job, JobRun, JobVersion } from "@trigger.dev/database";
|
import { ConcurrencyLimitGroup, Job, JobRun, JobVersion } from "@trigger.dev/database";
|
||||||
import { generateErrorMessage } from "zod-error";
|
import { generateErrorMessage } from "zod-error";
|
||||||
import { eventRecordToApiJson } from "~/api.server";
|
import { eventRecordToApiJson } from "~/api.server";
|
||||||
|
|||||||
@@ -50,6 +50,10 @@ import { PerformTaskOperationService } from "./tasks/performTaskOperation.server
|
|||||||
import { ProcessCallbackTimeoutService } from "./tasks/processCallbackTimeout.server";
|
import { ProcessCallbackTimeoutService } from "./tasks/processCallbackTimeout.server";
|
||||||
import { ResumeTaskService } from "./tasks/resumeTask.server";
|
import { ResumeTaskService } from "./tasks/resumeTask.server";
|
||||||
import { PerformTaskRunAlertsService } from "~/v3/services/alerts/performTaskRunAlerts.server";
|
import { PerformTaskRunAlertsService } from "~/v3/services/alerts/performTaskRunAlerts.server";
|
||||||
|
import {
|
||||||
|
CancelDevSessionRunsService,
|
||||||
|
CancelDevSessionRunsServiceOptions,
|
||||||
|
} from "~/v3/services/cancelDevSessionRuns.server";
|
||||||
|
|
||||||
const workerCatalog = {
|
const workerCatalog = {
|
||||||
indexEndpoint: z.object({
|
indexEndpoint: z.object({
|
||||||
@@ -191,6 +195,7 @@ const workerCatalog = {
|
|||||||
"v3.cancelTaskAttemptDependencies": z.object({
|
"v3.cancelTaskAttemptDependencies": z.object({
|
||||||
attemptId: z.string(),
|
attemptId: z.string(),
|
||||||
}),
|
}),
|
||||||
|
"v3.cancelDevSessionRuns": CancelDevSessionRunsServiceOptions,
|
||||||
};
|
};
|
||||||
|
|
||||||
const executionWorkerCatalog = {
|
const executionWorkerCatalog = {
|
||||||
@@ -710,6 +715,15 @@ function getWorkerQueue() {
|
|||||||
return await service.call(payload.attemptId);
|
return await service.call(payload.attemptId);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
"v3.cancelDevSessionRuns": {
|
||||||
|
priority: 0,
|
||||||
|
maxAttempts: 5,
|
||||||
|
handler: async (payload, job) => {
|
||||||
|
const service = new CancelDevSessionRunsService();
|
||||||
|
|
||||||
|
return await service.call(payload);
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { Logger } from "@trigger.dev/core-backend";
|
import { Logger } from "@trigger.dev/core/logger";
|
||||||
import { Redis } from "ioredis";
|
import { Redis } from "ioredis";
|
||||||
import { prisma } from "~/db.server";
|
import { prisma } from "~/db.server";
|
||||||
import { logger } from "~/services/logger.server";
|
import { logger } from "~/services/logger.server";
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ import { Context, ROOT_CONTEXT, Span, SpanKind, context, trace } from "@opentele
|
|||||||
import {
|
import {
|
||||||
TaskRunExecution,
|
TaskRunExecution,
|
||||||
TaskRunExecutionLazyAttemptPayload,
|
TaskRunExecutionLazyAttemptPayload,
|
||||||
TaskRunExecutionPayload,
|
|
||||||
TaskRunExecutionResult,
|
TaskRunExecutionResult,
|
||||||
TaskRunFailedExecutionResult,
|
TaskRunFailedExecutionResult,
|
||||||
serverWebsocketMessages,
|
serverWebsocketMessages,
|
||||||
@@ -17,9 +16,8 @@ import { logger } from "~/services/logger.server";
|
|||||||
import { marqs, sanitizeQueueName } from "~/v3/marqs/index.server";
|
import { marqs, sanitizeQueueName } from "~/v3/marqs/index.server";
|
||||||
import { resolveVariablesForEnvironment } from "../environmentVariables/environmentVariablesRepository.server";
|
import { resolveVariablesForEnvironment } from "../environmentVariables/environmentVariablesRepository.server";
|
||||||
import { FailedTaskRunService } from "../failedTaskRun.server";
|
import { FailedTaskRunService } from "../failedTaskRun.server";
|
||||||
import { CancelTaskRunService } from "../services/cancelTaskRun.server";
|
import { CancelDevSessionRunsService } from "../services/cancelDevSessionRuns.server";
|
||||||
import { CompleteAttemptService } from "../services/completeAttempt.server";
|
import { CompleteAttemptService } from "../services/completeAttempt.server";
|
||||||
import { CreateTaskRunAttemptService } from "../services/createTaskRunAttempt.server";
|
|
||||||
import {
|
import {
|
||||||
SEMINTATTRS_FORCE_RECORDING,
|
SEMINTATTRS_FORCE_RECORDING,
|
||||||
attributesFromAuthenticatedEnv,
|
attributesFromAuthenticatedEnv,
|
||||||
@@ -194,10 +192,22 @@ export class DevQueueConsumer {
|
|||||||
this._enabled = false;
|
this._enabled = false;
|
||||||
|
|
||||||
// Create the session
|
// Create the session
|
||||||
await disconnectSession(this.env.id);
|
const session = await disconnectSession(this.env.id);
|
||||||
|
|
||||||
// We need to cancel all the in progress task run attempts and ack the messages so they will stop processing
|
const runIds = Array.from(this._inProgressRuns.values());
|
||||||
await this.#cancelInProgressRunsAndAttempts(reason);
|
this._inProgressRuns.clear();
|
||||||
|
|
||||||
|
if (runIds.length > 0) {
|
||||||
|
await CancelDevSessionRunsService.enqueue(
|
||||||
|
{
|
||||||
|
runIds,
|
||||||
|
cancelledAt: new Date(),
|
||||||
|
reason,
|
||||||
|
cancelledSessionId: session?.id,
|
||||||
|
},
|
||||||
|
new Date(Date.now() + 1000 * 10) // 10 seconds from now
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
// We need to unsubscribe from the background worker channels
|
// We need to unsubscribe from the background worker channels
|
||||||
for (const [id, subscriber] of this._backgroundWorkerSubscriber) {
|
for (const [id, subscriber] of this._backgroundWorkerSubscriber) {
|
||||||
@@ -215,54 +225,6 @@ export class DevQueueConsumer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async #cancelInProgressRunsAndAttempts(reason: string) {
|
|
||||||
const cancelTaskRunService = new CancelTaskRunService();
|
|
||||||
|
|
||||||
const cancelledAt = new Date();
|
|
||||||
|
|
||||||
const inProgressRuns = new Map(this._inProgressRuns);
|
|
||||||
|
|
||||||
this._inProgressRuns.clear();
|
|
||||||
|
|
||||||
logger.debug("Cancelling in progress runs and attempts", {
|
|
||||||
runs: Array.from(inProgressRuns.keys()),
|
|
||||||
});
|
|
||||||
|
|
||||||
for (const [_, runId] of inProgressRuns) {
|
|
||||||
await this.#cancelInProgressRun(runId, cancelTaskRunService, cancelledAt, reason);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async #cancelInProgressRun(
|
|
||||||
runId: string,
|
|
||||||
service: CancelTaskRunService,
|
|
||||||
cancelledAt: Date,
|
|
||||||
reason: string
|
|
||||||
) {
|
|
||||||
logger.debug("Cancelling in progress run", { runId });
|
|
||||||
|
|
||||||
const taskRun = runId.startsWith("run_")
|
|
||||||
? await prisma.taskRun.findUnique({
|
|
||||||
where: { friendlyId: runId },
|
|
||||||
})
|
|
||||||
: await prisma.taskRun.findUnique({
|
|
||||||
where: { id: runId },
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!taskRun) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
await service.call(taskRun, { reason, cancelAttempts: true, cancelledAt });
|
|
||||||
} catch (e) {
|
|
||||||
logger.error("Failed to cancel in progress run", {
|
|
||||||
runId,
|
|
||||||
error: e,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async #enable() {
|
async #enable() {
|
||||||
if (this._enabled) {
|
if (this._enabled) {
|
||||||
return;
|
return;
|
||||||
@@ -534,63 +496,13 @@ export class DevQueueConsumer {
|
|||||||
setTimeout(() => this.#doWork(), 100);
|
setTimeout(() => this.#doWork(), 100);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
const service = new CreateTaskRunAttemptService();
|
logger.debug("We no longer support non-lazy attempts, aborting this run", {
|
||||||
const { execution } = await service.call(lockedTaskRun.friendlyId, this.env);
|
messageId: message.messageId,
|
||||||
|
backgroundWorker,
|
||||||
|
});
|
||||||
|
await marqs?.acknowledgeMessage(message.messageId);
|
||||||
|
|
||||||
const payload: TaskRunExecutionPayload = {
|
setTimeout(() => this.#doWork(), 100);
|
||||||
traceContext: lockedTaskRun.traceContext as Record<string, unknown>,
|
|
||||||
environment: variables.reduce((acc: Record<string, string>, curr) => {
|
|
||||||
acc[curr.key] = curr.value;
|
|
||||||
return acc;
|
|
||||||
}, {}),
|
|
||||||
execution,
|
|
||||||
};
|
|
||||||
|
|
||||||
try {
|
|
||||||
await this._sender.send("BACKGROUND_WORKER_MESSAGE", {
|
|
||||||
backgroundWorkerId: backgroundWorker.friendlyId,
|
|
||||||
data: {
|
|
||||||
type: "EXECUTE_RUNS",
|
|
||||||
payloads: [payload],
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
logger.debug("Executing the run", {
|
|
||||||
messageId: message.messageId,
|
|
||||||
});
|
|
||||||
|
|
||||||
this._inProgressRuns.set(lockedTaskRun.friendlyId, message.messageId);
|
|
||||||
} catch (e) {
|
|
||||||
if (e instanceof Error) {
|
|
||||||
this._currentSpan?.recordException(e);
|
|
||||||
} else {
|
|
||||||
this._currentSpan?.recordException(new Error(String(e)));
|
|
||||||
}
|
|
||||||
|
|
||||||
this._endSpanInNextIteration = true;
|
|
||||||
|
|
||||||
// We now need to unlock the task run and delete the task run attempt
|
|
||||||
await prisma.$transaction([
|
|
||||||
prisma.taskRun.update({
|
|
||||||
where: {
|
|
||||||
id: lockedTaskRun.id,
|
|
||||||
},
|
|
||||||
data: {
|
|
||||||
lockedAt: null,
|
|
||||||
lockedById: null,
|
|
||||||
status: "PENDING",
|
|
||||||
startedAt: existingTaskRun.startedAt,
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
]);
|
|
||||||
|
|
||||||
this._inProgressRuns.delete(lockedTaskRun.friendlyId);
|
|
||||||
|
|
||||||
// Finally we need to nack the message so it can be retried
|
|
||||||
await marqs?.nackMessage(message.messageId);
|
|
||||||
} finally {
|
|
||||||
setTimeout(() => this.#doWork(), 100);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,103 @@
|
|||||||
|
import { workerQueue } from "~/services/worker.server";
|
||||||
|
import { BaseService } from "./baseService.server";
|
||||||
|
import { PrismaClientOrTransaction } from "~/db.server";
|
||||||
|
import { z } from "zod";
|
||||||
|
import { logger } from "~/services/logger.server";
|
||||||
|
import { CancelTaskRunService } from "./cancelTaskRun.server";
|
||||||
|
import { findLatestSession } from "~/models/runtimeEnvironment.server";
|
||||||
|
|
||||||
|
export const CancelDevSessionRunsServiceOptions = z.object({
|
||||||
|
runIds: z.array(z.string()),
|
||||||
|
cancelledAt: z.coerce.date(),
|
||||||
|
reason: z.string(),
|
||||||
|
cancelledSessionId: z.string().optional(),
|
||||||
|
});
|
||||||
|
|
||||||
|
export type CancelDevSessionRunsServiceOptions = z.infer<typeof CancelDevSessionRunsServiceOptions>;
|
||||||
|
|
||||||
|
export class CancelDevSessionRunsService extends BaseService {
|
||||||
|
public async call(options: CancelDevSessionRunsServiceOptions) {
|
||||||
|
const cancelledSession = options.cancelledSessionId
|
||||||
|
? await this._prisma.runtimeEnvironmentSession.findFirst({
|
||||||
|
where: { id: options.cancelledSessionId },
|
||||||
|
})
|
||||||
|
: undefined;
|
||||||
|
|
||||||
|
if (cancelledSession) {
|
||||||
|
const latestSession = await findLatestSession(cancelledSession.environmentId);
|
||||||
|
|
||||||
|
if (
|
||||||
|
latestSession &&
|
||||||
|
latestSession.id !== cancelledSession.id &&
|
||||||
|
!latestSession.disconnectedAt
|
||||||
|
) {
|
||||||
|
logger.debug("Not cancelling runs because there is a newer session", {
|
||||||
|
cancelledSessionId: cancelledSession.id,
|
||||||
|
latestSessionId: latestSession.id,
|
||||||
|
});
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.debug(
|
||||||
|
"Cancelling in progress runs for dev session because there isn't a newer connected session",
|
||||||
|
{
|
||||||
|
options,
|
||||||
|
cancelledSession,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
const cancelTaskRunService = new CancelTaskRunService();
|
||||||
|
|
||||||
|
for (const runId of options.runIds) {
|
||||||
|
await this.#cancelInProgressRun(
|
||||||
|
runId,
|
||||||
|
cancelTaskRunService,
|
||||||
|
options.cancelledAt,
|
||||||
|
options.reason
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async #cancelInProgressRun(
|
||||||
|
runId: string,
|
||||||
|
service: CancelTaskRunService,
|
||||||
|
cancelledAt: Date,
|
||||||
|
reason: string
|
||||||
|
) {
|
||||||
|
logger.debug("Cancelling in progress run", { runId });
|
||||||
|
|
||||||
|
const taskRun = runId.startsWith("run_")
|
||||||
|
? await this._prisma.taskRun.findUnique({
|
||||||
|
where: { friendlyId: runId },
|
||||||
|
})
|
||||||
|
: await this._prisma.taskRun.findUnique({
|
||||||
|
where: { id: runId },
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!taskRun) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
await service.call(taskRun, { reason, cancelAttempts: true, cancelledAt });
|
||||||
|
} catch (e) {
|
||||||
|
logger.error("Failed to cancel in progress run", {
|
||||||
|
runId,
|
||||||
|
error: e,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static async enqueue(
|
||||||
|
options: CancelDevSessionRunsServiceOptions,
|
||||||
|
runAt?: Date,
|
||||||
|
tx?: PrismaClientOrTransaction
|
||||||
|
) {
|
||||||
|
return await workerQueue.enqueue("v3.cancelDevSessionRuns", options, {
|
||||||
|
tx,
|
||||||
|
runAt: runAt,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,4 +1,8 @@
|
|||||||
import { CreateBackgroundWorkerRequestBody, TaskResource } from "@trigger.dev/core/v3";
|
import {
|
||||||
|
BackgroundWorkerSourceFileMetadata,
|
||||||
|
CreateBackgroundWorkerRequestBody,
|
||||||
|
TaskResource,
|
||||||
|
} from "@trigger.dev/core/v3";
|
||||||
import type { BackgroundWorker } from "@trigger.dev/database";
|
import type { BackgroundWorker } from "@trigger.dev/database";
|
||||||
import { Prisma, PrismaClientOrTransaction } from "~/db.server";
|
import { Prisma, PrismaClientOrTransaction } from "~/db.server";
|
||||||
import { AuthenticatedEnvironment } from "~/services/apiAuth.server";
|
import { AuthenticatedEnvironment } from "~/services/apiAuth.server";
|
||||||
@@ -70,7 +74,19 @@ export class CreateBackgroundWorkerService extends BaseService {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
await createBackgroundTasks(body.metadata.tasks, backgroundWorker, environment, this._prisma);
|
const tasksToBackgroundFiles = await createBackgroundFiles(
|
||||||
|
body.metadata.sourceFiles,
|
||||||
|
backgroundWorker,
|
||||||
|
environment,
|
||||||
|
this._prisma
|
||||||
|
);
|
||||||
|
await createBackgroundTasks(
|
||||||
|
body.metadata.tasks,
|
||||||
|
backgroundWorker,
|
||||||
|
environment,
|
||||||
|
this._prisma,
|
||||||
|
tasksToBackgroundFiles
|
||||||
|
);
|
||||||
await syncDeclarativeSchedules(
|
await syncDeclarativeSchedules(
|
||||||
body.metadata.tasks,
|
body.metadata.tasks,
|
||||||
backgroundWorker,
|
backgroundWorker,
|
||||||
@@ -121,7 +137,8 @@ export async function createBackgroundTasks(
|
|||||||
tasks: TaskResource[],
|
tasks: TaskResource[],
|
||||||
worker: BackgroundWorker,
|
worker: BackgroundWorker,
|
||||||
environment: AuthenticatedEnvironment,
|
environment: AuthenticatedEnvironment,
|
||||||
prisma: PrismaClientOrTransaction
|
prisma: PrismaClientOrTransaction,
|
||||||
|
tasksToBackgroundFiles?: Map<string, string>
|
||||||
) {
|
) {
|
||||||
for (const task of tasks) {
|
for (const task of tasks) {
|
||||||
try {
|
try {
|
||||||
@@ -138,6 +155,7 @@ export async function createBackgroundTasks(
|
|||||||
queueConfig: task.queue,
|
queueConfig: task.queue,
|
||||||
machineConfig: task.machine,
|
machineConfig: task.machine,
|
||||||
triggerSource: task.triggerSource === "schedule" ? "SCHEDULED" : "STANDARD",
|
triggerSource: task.triggerSource === "schedule" ? "SCHEDULED" : "STANDARD",
|
||||||
|
fileId: tasksToBackgroundFiles?.get(task.id) ?? null,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -381,3 +399,53 @@ export async function syncDeclarativeSchedules(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function createBackgroundFiles(
|
||||||
|
files: Array<BackgroundWorkerSourceFileMetadata> | undefined,
|
||||||
|
worker: BackgroundWorker,
|
||||||
|
environment: AuthenticatedEnvironment,
|
||||||
|
prisma: PrismaClientOrTransaction
|
||||||
|
) {
|
||||||
|
// Maps from each taskId to the backgroundWorkerFileId
|
||||||
|
const results = new Map<string, string>();
|
||||||
|
|
||||||
|
if (!files) {
|
||||||
|
return results;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const file of files) {
|
||||||
|
const backgroundWorkerFile = await prisma.backgroundWorkerFile.upsert({
|
||||||
|
where: {
|
||||||
|
projectId_contentHash: {
|
||||||
|
projectId: environment.projectId,
|
||||||
|
contentHash: file.contentHash,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
create: {
|
||||||
|
friendlyId: generateFriendlyId("file"),
|
||||||
|
projectId: environment.projectId,
|
||||||
|
contentHash: file.contentHash,
|
||||||
|
filePath: file.filePath,
|
||||||
|
contents: Buffer.from(file.contents),
|
||||||
|
backgroundWorkers: {
|
||||||
|
connect: {
|
||||||
|
id: worker.id,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
update: {
|
||||||
|
backgroundWorkers: {
|
||||||
|
connect: {
|
||||||
|
id: worker.id,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
for (const taskId of file.taskIds) {
|
||||||
|
results.set(taskId, backgroundWorkerFile.id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return results;
|
||||||
|
}
|
||||||
|
|||||||
@@ -0,0 +1,108 @@
|
|||||||
|
import { CreateBackgroundWorkerRequestBody } from "@trigger.dev/core/v3";
|
||||||
|
import type { BackgroundWorker } from "@trigger.dev/database";
|
||||||
|
import { AuthenticatedEnvironment } from "~/services/apiAuth.server";
|
||||||
|
import { generateFriendlyId } from "../friendlyIdentifiers";
|
||||||
|
import { BaseService } from "./baseService.server";
|
||||||
|
import {
|
||||||
|
createBackgroundFiles,
|
||||||
|
createBackgroundTasks,
|
||||||
|
syncDeclarativeSchedules,
|
||||||
|
} from "./createBackgroundWorker.server";
|
||||||
|
import { TimeoutDeploymentService } from "./timeoutDeployment.server";
|
||||||
|
|
||||||
|
export class CreateDeploymentBackgroundWorkerService extends BaseService {
|
||||||
|
public async call(
|
||||||
|
environment: AuthenticatedEnvironment,
|
||||||
|
deploymentId: string,
|
||||||
|
body: CreateBackgroundWorkerRequestBody
|
||||||
|
): Promise<BackgroundWorker | undefined> {
|
||||||
|
return this.traceWithEnv("call", environment, async (span) => {
|
||||||
|
span.setAttribute("deploymentId", deploymentId);
|
||||||
|
|
||||||
|
const deployment = await this._prisma.workerDeployment.findUnique({
|
||||||
|
where: {
|
||||||
|
friendlyId: deploymentId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!deployment) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (deployment.status !== "BUILDING") {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const backgroundWorker = await this._prisma.backgroundWorker.create({
|
||||||
|
data: {
|
||||||
|
friendlyId: generateFriendlyId("worker"),
|
||||||
|
version: deployment.version,
|
||||||
|
runtimeEnvironmentId: environment.id,
|
||||||
|
projectId: environment.projectId,
|
||||||
|
metadata: body.metadata,
|
||||||
|
contentHash: body.metadata.contentHash,
|
||||||
|
cliVersion: body.metadata.cliPackageVersion,
|
||||||
|
sdkVersion: body.metadata.packageVersion,
|
||||||
|
supportsLazyAttempts: body.supportsLazyAttempts,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
try {
|
||||||
|
const tasksToBackgroundFiles = await createBackgroundFiles(
|
||||||
|
body.metadata.sourceFiles,
|
||||||
|
backgroundWorker,
|
||||||
|
environment,
|
||||||
|
this._prisma
|
||||||
|
);
|
||||||
|
await createBackgroundTasks(
|
||||||
|
body.metadata.tasks,
|
||||||
|
backgroundWorker,
|
||||||
|
environment,
|
||||||
|
this._prisma,
|
||||||
|
tasksToBackgroundFiles
|
||||||
|
);
|
||||||
|
await syncDeclarativeSchedules(
|
||||||
|
body.metadata.tasks,
|
||||||
|
backgroundWorker,
|
||||||
|
environment,
|
||||||
|
this._prisma
|
||||||
|
);
|
||||||
|
} catch (error) {
|
||||||
|
const name = error instanceof Error ? error.name : "UnknownError";
|
||||||
|
const message = error instanceof Error ? error.message : JSON.stringify(error);
|
||||||
|
|
||||||
|
await this._prisma.workerDeployment.update({
|
||||||
|
where: {
|
||||||
|
id: deployment.id,
|
||||||
|
},
|
||||||
|
data: {
|
||||||
|
status: "FAILED",
|
||||||
|
failedAt: new Date(),
|
||||||
|
errorData: {
|
||||||
|
name,
|
||||||
|
message,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Link the deployment with the background worker
|
||||||
|
await this._prisma.workerDeployment.update({
|
||||||
|
where: {
|
||||||
|
id: deployment.id,
|
||||||
|
},
|
||||||
|
data: {
|
||||||
|
status: "DEPLOYING",
|
||||||
|
workerId: backgroundWorker.id,
|
||||||
|
deployedAt: new Date(),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
await TimeoutDeploymentService.dequeue(deployment.id, this._prisma);
|
||||||
|
|
||||||
|
return backgroundWorker;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,56 @@
|
|||||||
|
import { PerformDeploymentAlertsService } from "./alerts/performDeploymentAlerts.server";
|
||||||
|
import { BaseService } from "./baseService.server";
|
||||||
|
import { logger } from "~/services/logger.server";
|
||||||
|
import { WorkerDeploymentStatus } from "@trigger.dev/database";
|
||||||
|
import { FailDeploymentRequestBody } from "@trigger.dev/core/v3/schemas";
|
||||||
|
import { AuthenticatedEnvironment } from "~/services/apiAuth.server";
|
||||||
|
|
||||||
|
const FINAL_DEPLOYMENT_STATUSES: WorkerDeploymentStatus[] = [
|
||||||
|
"CANCELED",
|
||||||
|
"DEPLOYED",
|
||||||
|
"FAILED",
|
||||||
|
"TIMED_OUT",
|
||||||
|
];
|
||||||
|
|
||||||
|
export class FailDeploymentService extends BaseService {
|
||||||
|
public async call(
|
||||||
|
authenticatedEnv: AuthenticatedEnvironment,
|
||||||
|
id: string,
|
||||||
|
params: FailDeploymentRequestBody
|
||||||
|
) {
|
||||||
|
const deployment = await this._prisma.workerDeployment.findUnique({
|
||||||
|
where: {
|
||||||
|
friendlyId: id,
|
||||||
|
environmentId: authenticatedEnv.id,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!deployment) {
|
||||||
|
logger.error("Worker deployment not found", { id });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (FINAL_DEPLOYMENT_STATUSES.includes(deployment.status)) {
|
||||||
|
logger.error("Worker deployment already in final state", {
|
||||||
|
id: deployment.id,
|
||||||
|
status: deployment.status,
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const failedDeployment = await this._prisma.workerDeployment.update({
|
||||||
|
where: {
|
||||||
|
id: deployment.id,
|
||||||
|
},
|
||||||
|
data: {
|
||||||
|
status: "FAILED",
|
||||||
|
failedAt: new Date(),
|
||||||
|
errorData: params.error,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
await PerformDeploymentAlertsService.enqueue(failedDeployment.id, this._prisma);
|
||||||
|
|
||||||
|
return failedDeployment;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,122 @@
|
|||||||
|
import { FinalizeDeploymentRequestBody } from "@trigger.dev/core/v3/schemas";
|
||||||
|
import { CURRENT_DEPLOYMENT_LABEL } from "~/consts";
|
||||||
|
import { AuthenticatedEnvironment } from "~/services/apiAuth.server";
|
||||||
|
import { logger } from "~/services/logger.server";
|
||||||
|
import { socketIo } from "../handleSocketIo.server";
|
||||||
|
import { marqs } from "../marqs/index.server";
|
||||||
|
import { registryProxy } from "../registryProxy.server";
|
||||||
|
import { PerformDeploymentAlertsService } from "./alerts/performDeploymentAlerts.server";
|
||||||
|
import { BaseService, ServiceValidationError } from "./baseService.server";
|
||||||
|
import { ExecuteTasksWaitingForDeployService } from "./executeTasksWaitingForDeploy";
|
||||||
|
import { projectPubSub } from "./projectPubSub.server";
|
||||||
|
|
||||||
|
export class FinalizeDeploymentService extends BaseService {
|
||||||
|
public async call(
|
||||||
|
authenticatedEnv: AuthenticatedEnvironment,
|
||||||
|
id: string,
|
||||||
|
body: FinalizeDeploymentRequestBody
|
||||||
|
) {
|
||||||
|
const deployment = await this._prisma.workerDeployment.findUnique({
|
||||||
|
where: {
|
||||||
|
friendlyId: id,
|
||||||
|
environmentId: authenticatedEnv.id,
|
||||||
|
},
|
||||||
|
include: {
|
||||||
|
worker: {
|
||||||
|
include: {
|
||||||
|
tasks: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!deployment) {
|
||||||
|
logger.error("Worker deployment not found", { id });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!deployment.worker) {
|
||||||
|
logger.error("Worker deployment does not have a worker", { id });
|
||||||
|
|
||||||
|
// TODO: We need to fail the deployment here because it's not possible to deploy a worker without a worker
|
||||||
|
|
||||||
|
throw new ServiceValidationError("Worker deployment does not have a worker");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (deployment.status !== "DEPLOYING") {
|
||||||
|
logger.error("Worker deployment is not in DEPLOYING status", { id });
|
||||||
|
throw new ServiceValidationError("Worker deployment is not in DEPLOYING status");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Link the deployment with the background worker
|
||||||
|
const finalizedDeployment = await this._prisma.workerDeployment.update({
|
||||||
|
where: {
|
||||||
|
id: deployment.id,
|
||||||
|
},
|
||||||
|
data: {
|
||||||
|
status: "DEPLOYED",
|
||||||
|
deployedAt: new Date(),
|
||||||
|
imageReference:
|
||||||
|
registryProxy && body.selfHosted !== true
|
||||||
|
? registryProxy.rewriteImageReference(body.imageReference)
|
||||||
|
: body.imageReference,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
//set this deployment as the current deployment for this environment
|
||||||
|
await this._prisma.workerDeploymentPromotion.upsert({
|
||||||
|
where: {
|
||||||
|
environmentId_label: {
|
||||||
|
environmentId: authenticatedEnv.id,
|
||||||
|
label: CURRENT_DEPLOYMENT_LABEL,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
create: {
|
||||||
|
deploymentId: finalizedDeployment.id,
|
||||||
|
environmentId: authenticatedEnv.id,
|
||||||
|
label: CURRENT_DEPLOYMENT_LABEL,
|
||||||
|
},
|
||||||
|
update: {
|
||||||
|
deploymentId: finalizedDeployment.id,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
try {
|
||||||
|
//send a notification that a new worker has been created
|
||||||
|
await projectPubSub.publish(
|
||||||
|
`project:${authenticatedEnv.projectId}:env:${authenticatedEnv.id}`,
|
||||||
|
"WORKER_CREATED",
|
||||||
|
{
|
||||||
|
environmentId: authenticatedEnv.id,
|
||||||
|
environmentType: authenticatedEnv.type,
|
||||||
|
createdAt: authenticatedEnv.createdAt,
|
||||||
|
taskCount: deployment.worker.tasks.length,
|
||||||
|
type: "deployed",
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
await marqs?.updateEnvConcurrencyLimits(authenticatedEnv);
|
||||||
|
} catch (err) {
|
||||||
|
logger.error("Failed to publish WORKER_CREATED event", { err });
|
||||||
|
}
|
||||||
|
|
||||||
|
if (deployment.imageReference) {
|
||||||
|
socketIo.providerNamespace.emit("PRE_PULL_DEPLOYMENT", {
|
||||||
|
version: "v1",
|
||||||
|
imageRef: deployment.imageReference,
|
||||||
|
shortCode: deployment.shortCode,
|
||||||
|
// identifiers
|
||||||
|
deploymentId: deployment.id,
|
||||||
|
envId: authenticatedEnv.id,
|
||||||
|
envType: authenticatedEnv.type,
|
||||||
|
orgId: authenticatedEnv.organizationId,
|
||||||
|
projectId: deployment.projectId,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
await ExecuteTasksWaitingForDeployService.enqueue(deployment.worker.id, this._prisma);
|
||||||
|
await PerformDeploymentAlertsService.enqueue(deployment.id, this._prisma);
|
||||||
|
|
||||||
|
return finalizedDeployment;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -12,7 +12,7 @@ import {
|
|||||||
trace,
|
trace,
|
||||||
} from "@opentelemetry/api";
|
} from "@opentelemetry/api";
|
||||||
import { OTLPTraceExporter } from "@opentelemetry/exporter-trace-otlp-http";
|
import { OTLPTraceExporter } from "@opentelemetry/exporter-trace-otlp-http";
|
||||||
import { InstrumentationOption, registerInstrumentations } from "@opentelemetry/instrumentation";
|
import { type Instrumentation, registerInstrumentations } from "@opentelemetry/instrumentation";
|
||||||
import { ExpressInstrumentation } from "@opentelemetry/instrumentation-express";
|
import { ExpressInstrumentation } from "@opentelemetry/instrumentation-express";
|
||||||
import { HttpInstrumentation } from "@opentelemetry/instrumentation-http";
|
import { HttpInstrumentation } from "@opentelemetry/instrumentation-http";
|
||||||
import { Resource } from "@opentelemetry/resources";
|
import { Resource } from "@opentelemetry/resources";
|
||||||
@@ -167,7 +167,7 @@ function getTracer() {
|
|||||||
|
|
||||||
provider.register();
|
provider.register();
|
||||||
|
|
||||||
let instrumentations: InstrumentationOption[] = [
|
let instrumentations: Instrumentation[] = [
|
||||||
new HttpInstrumentation(),
|
new HttpInstrumentation(),
|
||||||
new ExpressInstrumentation(),
|
new ExpressInstrumentation(),
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { Logger } from "@trigger.dev/core-backend";
|
import { Logger } from "@trigger.dev/core/logger";
|
||||||
import { ZodMessageCatalogSchema, ZodMessageHandler } from "@trigger.dev/core/v3/zodMessageHandler";
|
import { ZodMessageCatalogSchema, ZodMessageHandler } from "@trigger.dev/core/v3/zodMessageHandler";
|
||||||
import { Evt } from "evt";
|
import { Evt } from "evt";
|
||||||
import Redis, { RedisOptions } from "ioredis";
|
import Redis, { RedisOptions } from "ioredis";
|
||||||
|
|||||||
+14
-16
@@ -50,19 +50,19 @@
|
|||||||
"@heroicons/react": "^2.0.12",
|
"@heroicons/react": "^2.0.12",
|
||||||
"@internationalized/date": "^3.5.1",
|
"@internationalized/date": "^3.5.1",
|
||||||
"@lezer/highlight": "^1.1.6",
|
"@lezer/highlight": "^1.1.6",
|
||||||
"@opentelemetry/api": "^1.8.0",
|
"@opentelemetry/api": "1.9.0",
|
||||||
"@opentelemetry/core": "^1.22.0",
|
"@opentelemetry/core": "1.25.1",
|
||||||
"@opentelemetry/exporter-logs-otlp-http": "^0.49.1",
|
"@opentelemetry/exporter-logs-otlp-http": "0.52.1",
|
||||||
"@opentelemetry/exporter-trace-otlp-http": "^0.49.1",
|
"@opentelemetry/exporter-trace-otlp-http": "0.52.1",
|
||||||
"@opentelemetry/instrumentation": "^0.49.1",
|
"@opentelemetry/instrumentation": "0.52.1",
|
||||||
"@opentelemetry/instrumentation-express": "^0.36.1",
|
"@opentelemetry/instrumentation-express": "^0.36.1",
|
||||||
"@opentelemetry/instrumentation-http": "^0.49.1",
|
"@opentelemetry/instrumentation-http": "0.52.1",
|
||||||
"@opentelemetry/resources": "^1.22.0",
|
"@opentelemetry/resources": "1.25.1",
|
||||||
"@opentelemetry/sdk-logs": "^0.49.1",
|
"@opentelemetry/sdk-logs": "0.52.1",
|
||||||
"@opentelemetry/sdk-node": "^0.49.1",
|
"@opentelemetry/sdk-node": "0.52.1",
|
||||||
"@opentelemetry/sdk-trace-base": "^1.22.0",
|
"@opentelemetry/sdk-trace-base": "1.25.1",
|
||||||
"@opentelemetry/sdk-trace-node": "^1.22.0",
|
"@opentelemetry/sdk-trace-node": "1.25.1",
|
||||||
"@opentelemetry/semantic-conventions": "^1.22.0",
|
"@opentelemetry/semantic-conventions": "1.25.1",
|
||||||
"@popperjs/core": "^2.11.8",
|
"@popperjs/core": "^2.11.8",
|
||||||
"@prisma/instrumentation": "^5.11.0",
|
"@prisma/instrumentation": "^5.11.0",
|
||||||
"@radix-ui/react-alert-dialog": "^1.0.4",
|
"@radix-ui/react-alert-dialog": "^1.0.4",
|
||||||
@@ -93,12 +93,11 @@
|
|||||||
"@team-plain/typescript-sdk": "^3.5.0",
|
"@team-plain/typescript-sdk": "^3.5.0",
|
||||||
"@trigger.dev/companyicons": "^1.5.35",
|
"@trigger.dev/companyicons": "^1.5.35",
|
||||||
"@trigger.dev/core": "workspace:*",
|
"@trigger.dev/core": "workspace:*",
|
||||||
"@trigger.dev/core-backend": "workspace:*",
|
|
||||||
"@trigger.dev/database": "workspace:*",
|
"@trigger.dev/database": "workspace:*",
|
||||||
"@trigger.dev/otlp-importer": "workspace:*",
|
"@trigger.dev/otlp-importer": "workspace:*",
|
||||||
"@trigger.dev/platform": "1.0.12",
|
"@trigger.dev/platform": "1.0.12",
|
||||||
"@trigger.dev/sdk": "workspace:*",
|
"@trigger.dev/sdk": "workspace:*",
|
||||||
"@trigger.dev/yalt": "workspace:*",
|
"@trigger.dev/yalt": "npm:@trigger.dev/yalt",
|
||||||
"@types/pg": "8.6.6",
|
"@types/pg": "8.6.6",
|
||||||
"@uiw/react-codemirror": "^4.19.5",
|
"@uiw/react-codemirror": "^4.19.5",
|
||||||
"@upstash/ratelimit": "^1.1.3",
|
"@upstash/ratelimit": "^1.1.3",
|
||||||
@@ -189,7 +188,6 @@
|
|||||||
"@tailwindcss/forms": "^0.5.3",
|
"@tailwindcss/forms": "^0.5.3",
|
||||||
"@tailwindcss/typography": "^0.5.9",
|
"@tailwindcss/typography": "^0.5.9",
|
||||||
"@total-typescript/ts-reset": "^0.4.2",
|
"@total-typescript/ts-reset": "^0.4.2",
|
||||||
"@trigger.dev/eslint-plugin": "workspace:*",
|
|
||||||
"@types/bcryptjs": "^2.4.2",
|
"@types/bcryptjs": "^2.4.2",
|
||||||
"@types/compression": "^1.7.2",
|
"@types/compression": "^1.7.2",
|
||||||
"@types/eslint": "^8.4.6",
|
"@types/eslint": "^8.4.6",
|
||||||
@@ -245,4 +243,4 @@
|
|||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=16.0.0"
|
"node": ">=16.0.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -12,7 +12,6 @@ module.exports = {
|
|||||||
"marked",
|
"marked",
|
||||||
"axios",
|
"axios",
|
||||||
"@trigger.dev/core",
|
"@trigger.dev/core",
|
||||||
"@trigger.dev/core-backend",
|
|
||||||
"@trigger.dev/sdk",
|
"@trigger.dev/sdk",
|
||||||
"@trigger.dev/platform",
|
"@trigger.dev/platform",
|
||||||
"@trigger.dev/yalt",
|
"@trigger.dev/yalt",
|
||||||
@@ -25,12 +24,6 @@ module.exports = {
|
|||||||
],
|
],
|
||||||
browserNodeBuiltinsPolyfill: { modules: { path: true, os: true, crypto: true } },
|
browserNodeBuiltinsPolyfill: { modules: { path: true, os: true, crypto: true } },
|
||||||
watchPaths: async () => {
|
watchPaths: async () => {
|
||||||
return [
|
return ["../../packages/core/src/**/*", "../../packages/emails/src/**/*"];
|
||||||
"../../packages/core/src/**/*",
|
|
||||||
"../../packages/core-backend/src/**/*",
|
|
||||||
"../../packages/trigger-sdk/src/**/*",
|
|
||||||
"../../packages/yalt/src/**/*",
|
|
||||||
"../../packages/emails/src/**/*",
|
|
||||||
];
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -154,11 +154,7 @@ const radius = "0.5rem";
|
|||||||
|
|
||||||
/** @type {import('tailwindcss').Config} */
|
/** @type {import('tailwindcss').Config} */
|
||||||
module.exports = {
|
module.exports = {
|
||||||
content: [
|
content: ["./app/**/*.{ts,jsx,tsx}"],
|
||||||
"./app/**/*.{ts,jsx,tsx}",
|
|
||||||
// include packages if not transpiling
|
|
||||||
"../../packages/**/*.{ts,tsx}",
|
|
||||||
],
|
|
||||||
theme: {
|
theme: {
|
||||||
container: {
|
container: {
|
||||||
center: true,
|
center: true,
|
||||||
|
|||||||
@@ -24,8 +24,6 @@
|
|||||||
"@trigger.dev/sdk/*": ["../../packages/trigger-sdk/src/*"],
|
"@trigger.dev/sdk/*": ["../../packages/trigger-sdk/src/*"],
|
||||||
"@trigger.dev/core": ["../../packages/core/src/index"],
|
"@trigger.dev/core": ["../../packages/core/src/index"],
|
||||||
"@trigger.dev/core/*": ["../../packages/core/src/*"],
|
"@trigger.dev/core/*": ["../../packages/core/src/*"],
|
||||||
"@trigger.dev/core-backend": ["../../packages/core-backend/src/index"],
|
|
||||||
"@trigger.dev/core-backend/*": ["../../packages/core-backend/src/*"],
|
|
||||||
"@trigger.dev/database": ["../../packages/database/src/index"],
|
"@trigger.dev/database": ["../../packages/database/src/index"],
|
||||||
"@trigger.dev/database/*": ["../../packages/database/src/*"],
|
"@trigger.dev/database/*": ["../../packages/database/src/*"],
|
||||||
"@trigger.dev/yalt": ["../../packages/yalt/src/index"],
|
"@trigger.dev/yalt": ["../../packages/yalt/src/index"],
|
||||||
|
|||||||
@@ -1 +0,0 @@
|
|||||||
SECRET_KEY=
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
# http://editorconfig.org
|
|
||||||
root = true
|
|
||||||
|
|
||||||
[*]
|
|
||||||
indent_style = tab
|
|
||||||
tab_width = 2
|
|
||||||
end_of_line = lf
|
|
||||||
charset = utf-8
|
|
||||||
trim_trailing_whitespace = true
|
|
||||||
insert_final_newline = true
|
|
||||||
|
|
||||||
[*.yml]
|
|
||||||
indent_style = space
|
|
||||||
@@ -1,172 +0,0 @@
|
|||||||
# Logs
|
|
||||||
|
|
||||||
logs
|
|
||||||
_.log
|
|
||||||
npm-debug.log_
|
|
||||||
yarn-debug.log*
|
|
||||||
yarn-error.log*
|
|
||||||
lerna-debug.log*
|
|
||||||
.pnpm-debug.log*
|
|
||||||
|
|
||||||
# Diagnostic reports (https://nodejs.org/api/report.html)
|
|
||||||
|
|
||||||
report.[0-9]_.[0-9]_.[0-9]_.[0-9]_.json
|
|
||||||
|
|
||||||
# Runtime data
|
|
||||||
|
|
||||||
pids
|
|
||||||
_.pid
|
|
||||||
_.seed
|
|
||||||
\*.pid.lock
|
|
||||||
|
|
||||||
# Directory for instrumented libs generated by jscoverage/JSCover
|
|
||||||
|
|
||||||
lib-cov
|
|
||||||
|
|
||||||
# Coverage directory used by tools like istanbul
|
|
||||||
|
|
||||||
coverage
|
|
||||||
\*.lcov
|
|
||||||
|
|
||||||
# nyc test coverage
|
|
||||||
|
|
||||||
.nyc_output
|
|
||||||
|
|
||||||
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
|
|
||||||
|
|
||||||
.grunt
|
|
||||||
|
|
||||||
# Bower dependency directory (https://bower.io/)
|
|
||||||
|
|
||||||
bower_components
|
|
||||||
|
|
||||||
# node-waf configuration
|
|
||||||
|
|
||||||
.lock-wscript
|
|
||||||
|
|
||||||
# Compiled binary addons (https://nodejs.org/api/addons.html)
|
|
||||||
|
|
||||||
build/Release
|
|
||||||
|
|
||||||
# Dependency directories
|
|
||||||
|
|
||||||
node_modules/
|
|
||||||
jspm_packages/
|
|
||||||
|
|
||||||
# Snowpack dependency directory (https://snowpack.dev/)
|
|
||||||
|
|
||||||
web_modules/
|
|
||||||
|
|
||||||
# TypeScript cache
|
|
||||||
|
|
||||||
\*.tsbuildinfo
|
|
||||||
|
|
||||||
# Optional npm cache directory
|
|
||||||
|
|
||||||
.npm
|
|
||||||
|
|
||||||
# Optional eslint cache
|
|
||||||
|
|
||||||
.eslintcache
|
|
||||||
|
|
||||||
# Optional stylelint cache
|
|
||||||
|
|
||||||
.stylelintcache
|
|
||||||
|
|
||||||
# Microbundle cache
|
|
||||||
|
|
||||||
.rpt2_cache/
|
|
||||||
.rts2_cache_cjs/
|
|
||||||
.rts2_cache_es/
|
|
||||||
.rts2_cache_umd/
|
|
||||||
|
|
||||||
# Optional REPL history
|
|
||||||
|
|
||||||
.node_repl_history
|
|
||||||
|
|
||||||
# Output of 'npm pack'
|
|
||||||
|
|
||||||
\*.tgz
|
|
||||||
|
|
||||||
# Yarn Integrity file
|
|
||||||
|
|
||||||
.yarn-integrity
|
|
||||||
|
|
||||||
# dotenv environment variable files
|
|
||||||
|
|
||||||
.env
|
|
||||||
.env.development.local
|
|
||||||
.env.test.local
|
|
||||||
.env.production.local
|
|
||||||
.env.local
|
|
||||||
|
|
||||||
# parcel-bundler cache (https://parceljs.org/)
|
|
||||||
|
|
||||||
.cache
|
|
||||||
.parcel-cache
|
|
||||||
|
|
||||||
# Next.js build output
|
|
||||||
|
|
||||||
.next
|
|
||||||
out
|
|
||||||
|
|
||||||
# Nuxt.js build / generate output
|
|
||||||
|
|
||||||
.nuxt
|
|
||||||
dist
|
|
||||||
|
|
||||||
# Gatsby files
|
|
||||||
|
|
||||||
.cache/
|
|
||||||
|
|
||||||
# Comment in the public line in if your project uses Gatsby and not Next.js
|
|
||||||
|
|
||||||
# https://nextjs.org/blog/next-9-1#public-directory-support
|
|
||||||
|
|
||||||
# public
|
|
||||||
|
|
||||||
# vuepress build output
|
|
||||||
|
|
||||||
.vuepress/dist
|
|
||||||
|
|
||||||
# vuepress v2.x temp and cache directory
|
|
||||||
|
|
||||||
.temp
|
|
||||||
.cache
|
|
||||||
|
|
||||||
# Docusaurus cache and generated files
|
|
||||||
|
|
||||||
.docusaurus
|
|
||||||
|
|
||||||
# Serverless directories
|
|
||||||
|
|
||||||
.serverless/
|
|
||||||
|
|
||||||
# FuseBox cache
|
|
||||||
|
|
||||||
.fusebox/
|
|
||||||
|
|
||||||
# DynamoDB Local files
|
|
||||||
|
|
||||||
.dynamodb/
|
|
||||||
|
|
||||||
# TernJS port file
|
|
||||||
|
|
||||||
.tern-port
|
|
||||||
|
|
||||||
# Stores VSCode versions used for testing VSCode extensions
|
|
||||||
|
|
||||||
.vscode-test
|
|
||||||
|
|
||||||
# yarn v2
|
|
||||||
|
|
||||||
.yarn/cache
|
|
||||||
.yarn/unplugged
|
|
||||||
.yarn/build-state.yml
|
|
||||||
.yarn/install-state.gz
|
|
||||||
.pnp.\*
|
|
||||||
|
|
||||||
# wrangler project
|
|
||||||
|
|
||||||
.dev.vars
|
|
||||||
.wrangler/
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
{
|
|
||||||
"printWidth": 140,
|
|
||||||
"singleQuote": true,
|
|
||||||
"semi": true,
|
|
||||||
"useTabs": true
|
|
||||||
}
|
|
||||||
@@ -1,26 +0,0 @@
|
|||||||
## Trigger.dev Yalt Server
|
|
||||||
|
|
||||||
Yalt (Yet Another Local Tunnel) is the Trigger.dev tunneling service that powers the local development of Trigger.dev cloud users.
|
|
||||||
|
|
||||||
## Why?
|
|
||||||
|
|
||||||
The Trigger.dev server communicates with user endpoints over HTTP, so during local development we need a way for the Trigger.dev server to make HTTP requests over the public internet to the user's local machine. This is accomplished via a tunneling service like ngrok, which we've been using up until now. Unfortunately, the ngrok free plan has pretty aggressive rate limits and some Trigger.dev users have faced issues with their local jobs not running/working because of this. Yalt.dev is our solution.
|
|
||||||
|
|
||||||
## How does it work?
|
|
||||||
|
|
||||||
Yalt.dev is a Cloudflare Worker that uses Durable Objects to persist a websocket connection from the `@trigger.dev/cli dev` command and proxies requests through the websocket connection and then returns responses from the websocket connection.
|
|
||||||
|
|
||||||
- There is an admin API available at `admin.trigger.dev` that allows tunnels to be created (authenticated via a SECRET_KEY)
|
|
||||||
- The Cloudflare Worker has a wildcard subdomain route `*.yalt.dev/*`
|
|
||||||
- When the client receives the tunnel ID, they can connect to the server via `wss://${tunnelId}.yalt.dev/connect`
|
|
||||||
- Now, requests to `https://${tunnelId}.yalt.dev/api/trigger` are sent to the Durable Object (`YaltConnection`) using the subdomain/tunnelId
|
|
||||||
- Requests are serialized to a JSON string and sent to the WebSocket
|
|
||||||
- The WebSocket client running in `@trigger.dev/cli dev` receives the request message and makes a real request to the local dev server
|
|
||||||
- The `@trigger.dev/cli dev` serializes the response and sends it back to the server.
|
|
||||||
- The server responds to the original request
|
|
||||||
|
|
||||||
Along with this server there is a package called `@trigger.dev/yalt` that has shared code and is used in:
|
|
||||||
|
|
||||||
- Yalt.dev server (this project)
|
|
||||||
- `@trigger.dev/cli dev` command
|
|
||||||
- The Trigger.dev server (to create the tunnels)
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "yalt",
|
|
||||||
"version": "0.0.1",
|
|
||||||
"private": true,
|
|
||||||
"scripts": {
|
|
||||||
"deploy": "wrangler deploy",
|
|
||||||
"dev": "wrangler dev --port 8787",
|
|
||||||
"start": "wrangler dev"
|
|
||||||
},
|
|
||||||
"devDependencies": {
|
|
||||||
"@cloudflare/workers-types": "~4.20231121.0",
|
|
||||||
"wrangler": "^3.21.0"
|
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"@trigger.dev/yalt": "workspace:*"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,259 +0,0 @@
|
|||||||
import { ClientMessages, createRequestMessage } from '@trigger.dev/yalt';
|
|
||||||
|
|
||||||
export interface Env {
|
|
||||||
// environemnt variables
|
|
||||||
SECRET_KEY: string;
|
|
||||||
WORKER_HOST: string;
|
|
||||||
|
|
||||||
// bindings
|
|
||||||
connections: DurableObjectNamespace;
|
|
||||||
tunnelIds: KVNamespace;
|
|
||||||
}
|
|
||||||
|
|
||||||
export default {
|
|
||||||
async fetch(request: Request, env: Env, ctx: ExecutionContext): Promise<Response> {
|
|
||||||
const url = new URL(request.url);
|
|
||||||
const route = routeUrl(url, env);
|
|
||||||
|
|
||||||
switch (route.type) {
|
|
||||||
case 'management': {
|
|
||||||
return handleManagementRequest(request, env, ctx);
|
|
||||||
}
|
|
||||||
case 'tunnel': {
|
|
||||||
console.log(`Handling tunnel request for ${route.name}`);
|
|
||||||
|
|
||||||
const id = await env.tunnelIds.get(route.name);
|
|
||||||
|
|
||||||
if (!id) {
|
|
||||||
return new Response('Not Found', { status: 404 });
|
|
||||||
}
|
|
||||||
|
|
||||||
const tunnel = env.connections.get(env.connections.idFromString(id));
|
|
||||||
return tunnel.fetch(request);
|
|
||||||
}
|
|
||||||
case 'not_found': {
|
|
||||||
return new Response('Not Found', { status: 404 });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return new Response('Not Found', { status: 404 });
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
type RouteDecision =
|
|
||||||
| {
|
|
||||||
type: 'management';
|
|
||||||
}
|
|
||||||
| {
|
|
||||||
type: 'tunnel';
|
|
||||||
name: string;
|
|
||||||
}
|
|
||||||
| { type: 'not_found' };
|
|
||||||
|
|
||||||
function routeUrl(url: URL, env: Env): RouteDecision {
|
|
||||||
const searchParams = new URLSearchParams(url.search);
|
|
||||||
|
|
||||||
if (searchParams.has('t')) {
|
|
||||||
const name = searchParams.get('t');
|
|
||||||
|
|
||||||
if (name) {
|
|
||||||
return { type: 'tunnel', name };
|
|
||||||
}
|
|
||||||
|
|
||||||
return { type: 'management' };
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!url.host.includes(env.WORKER_HOST)) {
|
|
||||||
return { type: 'not_found' };
|
|
||||||
}
|
|
||||||
|
|
||||||
const parts = url.host.split('.');
|
|
||||||
|
|
||||||
if (parts.length === 2) {
|
|
||||||
return { type: 'management' };
|
|
||||||
}
|
|
||||||
|
|
||||||
const tunnelName = parts[0];
|
|
||||||
|
|
||||||
if (tunnelName === 'admin') {
|
|
||||||
return { type: 'management' };
|
|
||||||
}
|
|
||||||
|
|
||||||
if (parts.length === 3) {
|
|
||||||
return { type: 'tunnel', name: parts[0] };
|
|
||||||
}
|
|
||||||
|
|
||||||
return { type: 'not_found' };
|
|
||||||
}
|
|
||||||
|
|
||||||
async function handleManagementRequest(request: Request, env: Env, ctx: ExecutionContext): Promise<Response> {
|
|
||||||
const authHeader = request.headers.get('authorization');
|
|
||||||
if (!authHeader) {
|
|
||||||
return new Response('Authorization header is required', { status: 401 });
|
|
||||||
}
|
|
||||||
|
|
||||||
const authHeaderParts = authHeader.split(' ');
|
|
||||||
if (authHeaderParts.length !== 2) {
|
|
||||||
return new Response('Authorization header is invalid', { status: 401 });
|
|
||||||
}
|
|
||||||
|
|
||||||
const [authType, authKey] = authHeaderParts;
|
|
||||||
|
|
||||||
if (authType !== 'Bearer') {
|
|
||||||
return new Response('Authorization header is invalid', { status: 401 });
|
|
||||||
}
|
|
||||||
|
|
||||||
if (authKey !== env.SECRET_KEY) {
|
|
||||||
return new Response('Authorization header is invalid', { status: 401 });
|
|
||||||
}
|
|
||||||
|
|
||||||
// Okay now we can actually handle the request
|
|
||||||
// We need to look at the path and see what we are doing
|
|
||||||
// POST /api/tunnels -> create a new tunnel
|
|
||||||
const url = new URL(request.url);
|
|
||||||
|
|
||||||
if (url.pathname === '/api/tunnels' && request.method === 'POST') {
|
|
||||||
return handleCreateTunnel(request, env, ctx);
|
|
||||||
}
|
|
||||||
|
|
||||||
return new Response('Not Found', { status: 404 });
|
|
||||||
}
|
|
||||||
|
|
||||||
async function handleCreateTunnel(request: Request, env: Env, ctx: ExecutionContext): Promise<Response> {
|
|
||||||
const tunnelId = env.connections.newUniqueId();
|
|
||||||
const tunnelName = crypto.randomUUID();
|
|
||||||
|
|
||||||
await env.tunnelIds.put(tunnelName, tunnelId.toString());
|
|
||||||
|
|
||||||
return new Response(JSON.stringify({ id: tunnelName }), { status: 201 });
|
|
||||||
}
|
|
||||||
|
|
||||||
type Resolver<T> = {
|
|
||||||
resolve: (value: T) => void;
|
|
||||||
reject: (error: Error) => void;
|
|
||||||
};
|
|
||||||
|
|
||||||
export class YaltConnection implements DurableObject {
|
|
||||||
private socket?: WebSocket;
|
|
||||||
private responseResolvers: Record<string, Resolver<Response>> = {};
|
|
||||||
|
|
||||||
constructor(
|
|
||||||
private state: DurableObjectState,
|
|
||||||
private env: Env,
|
|
||||||
) {}
|
|
||||||
|
|
||||||
async fetch(request: Request<unknown, CfProperties<unknown>>): Promise<Response> {
|
|
||||||
const url = new URL(request.url);
|
|
||||||
|
|
||||||
switch (url.pathname) {
|
|
||||||
case '/connect': {
|
|
||||||
console.log(`Handling connect request`);
|
|
||||||
|
|
||||||
// This is a request from the client to connect to the tunnel
|
|
||||||
if (request.headers.get('Upgrade') !== 'websocket') {
|
|
||||||
return new Response('expected websocket', { status: 400 });
|
|
||||||
}
|
|
||||||
|
|
||||||
const pair = new WebSocketPair();
|
|
||||||
const [clientSocket, serverSocket] = Object.values(pair);
|
|
||||||
|
|
||||||
await this.handleSocket(serverSocket);
|
|
||||||
|
|
||||||
console.log(`Successfully connected to tunnel`);
|
|
||||||
|
|
||||||
return new Response(null, { status: 101, webSocket: clientSocket });
|
|
||||||
}
|
|
||||||
case '/api/trigger': {
|
|
||||||
return this.handleTunnelRequest(request);
|
|
||||||
}
|
|
||||||
default: {
|
|
||||||
return new Response('Not Found', { status: 404 });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private async handleSocket(socket: WebSocket) {
|
|
||||||
if (this.socket) {
|
|
||||||
this.socket.close(1000, 'replaced');
|
|
||||||
}
|
|
||||||
|
|
||||||
this.socket = socket;
|
|
||||||
|
|
||||||
this.socket.addEventListener('message', (event) => {
|
|
||||||
// Here we need to listen for "response" messages from the client and send them to the server via stored promises on this object
|
|
||||||
const data = JSON.parse(typeof event.data === 'string' ? event.data : new TextDecoder('utf-8').decode(event.data));
|
|
||||||
|
|
||||||
const message = ClientMessages.safeParse(data);
|
|
||||||
|
|
||||||
if (!message.success) {
|
|
||||||
console.error(message.error);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (message.data.type) {
|
|
||||||
case 'response': {
|
|
||||||
const { id, ...response } = message.data;
|
|
||||||
|
|
||||||
const resolver = this.responseResolvers[id];
|
|
||||||
|
|
||||||
if (!resolver) {
|
|
||||||
console.error(`No resolver found for ${id}`);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
delete this.responseResolvers[id];
|
|
||||||
|
|
||||||
resolver.resolve(
|
|
||||||
new Response(response.body, {
|
|
||||||
status: response.status,
|
|
||||||
headers: response.headers,
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
this.socket.accept();
|
|
||||||
}
|
|
||||||
|
|
||||||
private async handleTunnelRequest(request: Request): Promise<Response> {
|
|
||||||
if (!this.socket) {
|
|
||||||
return createErrorResponse();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.socket.readyState !== WebSocket.READY_STATE_OPEN) {
|
|
||||||
return createErrorResponse();
|
|
||||||
}
|
|
||||||
|
|
||||||
const id = crypto.randomUUID();
|
|
||||||
|
|
||||||
const promise = new Promise<Response>((resolve, reject) => {
|
|
||||||
this.responseResolvers[id] = { resolve, reject };
|
|
||||||
});
|
|
||||||
|
|
||||||
try {
|
|
||||||
const message = await createRequestMessage(id, request);
|
|
||||||
this.socket.send(JSON.stringify(message));
|
|
||||||
} catch (error) {
|
|
||||||
console.error(error);
|
|
||||||
delete this.responseResolvers[id];
|
|
||||||
|
|
||||||
return createErrorResponse();
|
|
||||||
}
|
|
||||||
|
|
||||||
return promise;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const createErrorResponse = () =>
|
|
||||||
new Response(
|
|
||||||
JSON.stringify({
|
|
||||||
message: 'Could not connect to your dev server. Make sure you are running the `npx @trigger.dev/cli@latest dev` command',
|
|
||||||
}),
|
|
||||||
{
|
|
||||||
status: 400,
|
|
||||||
headers: { 'Content-Type': 'application/json' },
|
|
||||||
},
|
|
||||||
);
|
|
||||||
@@ -1,107 +0,0 @@
|
|||||||
{
|
|
||||||
"compilerOptions": {
|
|
||||||
/* Visit https://aka.ms/tsconfig.json to read more about this file */
|
|
||||||
|
|
||||||
/* Projects */
|
|
||||||
// "incremental": true, /* Enable incremental compilation */
|
|
||||||
// "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */
|
|
||||||
// "tsBuildInfoFile": "./", /* Specify the folder for .tsbuildinfo incremental compilation files. */
|
|
||||||
// "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects */
|
|
||||||
// "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */
|
|
||||||
// "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */
|
|
||||||
|
|
||||||
/* Language and Environment */
|
|
||||||
"target": "es2021" /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */,
|
|
||||||
"lib": ["es2021"] /* Specify a set of bundled library declaration files that describe the target runtime environment. */,
|
|
||||||
"jsx": "react" /* Specify what JSX code is generated. */,
|
|
||||||
// "experimentalDecorators": true, /* Enable experimental support for TC39 stage 2 draft decorators. */
|
|
||||||
// "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */
|
|
||||||
// "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h' */
|
|
||||||
// "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */
|
|
||||||
// "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using `jsx: react-jsx*`.` */
|
|
||||||
// "reactNamespace": "", /* Specify the object invoked for `createElement`. This only applies when targeting `react` JSX emit. */
|
|
||||||
// "noLib": true, /* Disable including any library files, including the default lib.d.ts. */
|
|
||||||
// "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */
|
|
||||||
|
|
||||||
/* Modules */
|
|
||||||
"module": "es2022" /* Specify what module code is generated. */,
|
|
||||||
// "rootDir": "./", /* Specify the root folder within your source files. */
|
|
||||||
"moduleResolution": "node" /* Specify how TypeScript looks up a file from a given module specifier. */,
|
|
||||||
// "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */
|
|
||||||
// "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */
|
|
||||||
// "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */
|
|
||||||
// "typeRoots": [], /* Specify multiple folders that act like `./node_modules/@types`. */
|
|
||||||
"types": [
|
|
||||||
"@cloudflare/workers-types/2023-07-01"
|
|
||||||
] /* Specify type package names to be included without being referenced in a source file. */,
|
|
||||||
// "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */
|
|
||||||
"resolveJsonModule": true /* Enable importing .json files */,
|
|
||||||
// "noResolve": true, /* Disallow `import`s, `require`s or `<reference>`s from expanding the number of files TypeScript should add to a project. */
|
|
||||||
|
|
||||||
/* JavaScript Support */
|
|
||||||
"allowJs": true /* Allow JavaScript files to be a part of your program. Use the `checkJS` option to get errors from these files. */,
|
|
||||||
"checkJs": false /* Enable error reporting in type-checked JavaScript files. */,
|
|
||||||
// "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from `node_modules`. Only applicable with `allowJs`. */
|
|
||||||
|
|
||||||
/* Emit */
|
|
||||||
// "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */
|
|
||||||
// "declarationMap": true, /* Create sourcemaps for d.ts files. */
|
|
||||||
// "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */
|
|
||||||
// "sourceMap": true, /* Create source map files for emitted JavaScript files. */
|
|
||||||
// "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If `declaration` is true, also designates a file that bundles all .d.ts output. */
|
|
||||||
// "outDir": "./", /* Specify an output folder for all emitted files. */
|
|
||||||
// "removeComments": true, /* Disable emitting comments. */
|
|
||||||
"noEmit": true /* Disable emitting files from a compilation. */,
|
|
||||||
// "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */
|
|
||||||
// "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types */
|
|
||||||
// "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */
|
|
||||||
// "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */
|
|
||||||
// "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */
|
|
||||||
// "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */
|
|
||||||
// "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */
|
|
||||||
// "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */
|
|
||||||
// "newLine": "crlf", /* Set the newline character for emitting files. */
|
|
||||||
// "stripInternal": true, /* Disable emitting declarations that have `@internal` in their JSDoc comments. */
|
|
||||||
// "noEmitHelpers": true, /* Disable generating custom helper functions like `__extends` in compiled output. */
|
|
||||||
// "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */
|
|
||||||
// "preserveConstEnums": true, /* Disable erasing `const enum` declarations in generated code. */
|
|
||||||
// "declarationDir": "./", /* Specify the output directory for generated declaration files. */
|
|
||||||
// "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */
|
|
||||||
|
|
||||||
/* Interop Constraints */
|
|
||||||
"isolatedModules": true /* Ensure that each file can be safely transpiled without relying on other imports. */,
|
|
||||||
"allowSyntheticDefaultImports": true /* Allow 'import x from y' when a module doesn't have a default export. */,
|
|
||||||
// "esModuleInterop": true /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables `allowSyntheticDefaultImports` for type compatibility. */,
|
|
||||||
// "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */
|
|
||||||
"forceConsistentCasingInFileNames": true /* Ensure that casing is correct in imports. */,
|
|
||||||
|
|
||||||
/* Type Checking */
|
|
||||||
"strict": true /* Enable all strict type-checking options. */,
|
|
||||||
// "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied `any` type.. */
|
|
||||||
// "strictNullChecks": true, /* When type checking, take into account `null` and `undefined`. */
|
|
||||||
// "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */
|
|
||||||
// "strictBindCallApply": true, /* Check that the arguments for `bind`, `call`, and `apply` methods match the original function. */
|
|
||||||
// "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */
|
|
||||||
// "noImplicitThis": true, /* Enable error reporting when `this` is given the type `any`. */
|
|
||||||
// "useUnknownInCatchVariables": true, /* Type catch clause variables as 'unknown' instead of 'any'. */
|
|
||||||
// "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */
|
|
||||||
// "noUnusedLocals": true, /* Enable error reporting when a local variables aren't read. */
|
|
||||||
// "noUnusedParameters": true, /* Raise an error when a function parameter isn't read */
|
|
||||||
// "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */
|
|
||||||
// "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */
|
|
||||||
// "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */
|
|
||||||
// "noUncheckedIndexedAccess": true, /* Include 'undefined' in index signature results */
|
|
||||||
// "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */
|
|
||||||
// "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type */
|
|
||||||
// "allowUnusedLabels": true, /* Disable error reporting for unused labels. */
|
|
||||||
// "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */
|
|
||||||
|
|
||||||
/* Completeness */
|
|
||||||
// "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */
|
|
||||||
"skipLibCheck": true /* Skip type checking all .d.ts files. */,
|
|
||||||
"paths": {
|
|
||||||
"@trigger.dev/yalt": ["../../packages/yalt/src/index"],
|
|
||||||
"@trigger.dev/yalt/*": ["../../packages/yalt/src/*"]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,25 +0,0 @@
|
|||||||
name = "yalt"
|
|
||||||
main = "src/index.ts"
|
|
||||||
compatibility_date = "2023-12-06"
|
|
||||||
workers_dev = false
|
|
||||||
logpush = true
|
|
||||||
|
|
||||||
routes = [
|
|
||||||
{ pattern = "*.yalt.dev/*", zone_name = "yalt.dev" },
|
|
||||||
{ pattern = "yalt.dev/*", zone_name = "yalt.dev" },
|
|
||||||
]
|
|
||||||
|
|
||||||
[vars]
|
|
||||||
WORKER_HOST = "yalt.dev"
|
|
||||||
|
|
||||||
[[kv_namespaces]]
|
|
||||||
binding = "tunnelIds"
|
|
||||||
id = "e8cf1fcc9ad34fa0819694d86afa97ca"
|
|
||||||
|
|
||||||
[[durable_objects.bindings]]
|
|
||||||
name = "connections"
|
|
||||||
class_name = "YaltConnection"
|
|
||||||
|
|
||||||
[[migrations]]
|
|
||||||
tag = "v1"
|
|
||||||
new_classes = ["YaltConnection"]
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
module.exports = {
|
|
||||||
extends: ["turbo", "prettier"],
|
|
||||||
settings: {
|
|
||||||
react: {
|
|
||||||
version: "detect",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "eslint-config-custom",
|
|
||||||
"version": "0.0.0",
|
|
||||||
"private": true,
|
|
||||||
"license": "MIT",
|
|
||||||
"main": "index.js",
|
|
||||||
"devDependencies": {
|
|
||||||
"eslint": "^8.24.0",
|
|
||||||
"eslint-config-prettier": "^8.3.0",
|
|
||||||
"eslint-config-turbo": "latest",
|
|
||||||
"eslint-plugin-react": "7.31.8",
|
|
||||||
"typescript": "^4.8.4"
|
|
||||||
},
|
|
||||||
"publishConfig": {
|
|
||||||
"access": "public"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,25 +0,0 @@
|
|||||||
{
|
|
||||||
"$schema": "https://json.schemastore.org/tsconfig",
|
|
||||||
"display": "Default",
|
|
||||||
"compilerOptions": {
|
|
||||||
"composite": false,
|
|
||||||
"declaration": true,
|
|
||||||
"declarationMap": true,
|
|
||||||
"esModuleInterop": true,
|
|
||||||
"forceConsistentCasingInFileNames": true,
|
|
||||||
"inlineSources": false,
|
|
||||||
"isolatedModules": true,
|
|
||||||
"moduleResolution": "node",
|
|
||||||
"noUnusedLocals": false,
|
|
||||||
"noUnusedParameters": false,
|
|
||||||
"preserveWatchOutput": true,
|
|
||||||
"skipLibCheck": true,
|
|
||||||
"strict": true,
|
|
||||||
"experimentalDecorators": true,
|
|
||||||
"emitDecoratorMetadata": true,
|
|
||||||
"sourceMap": true,
|
|
||||||
"resolveJsonModule": true
|
|
||||||
},
|
|
||||||
"exclude": ["node_modules", "**/*/lib", "**/*/dist"],
|
|
||||||
"references": [{ "path": "../utils/" }]
|
|
||||||
}
|
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
{
|
|
||||||
"$schema": "https://json.schemastore.org/tsconfig",
|
|
||||||
"display": "Workflow example",
|
|
||||||
"extends": "./base.json",
|
|
||||||
"compilerOptions": {
|
|
||||||
"module": "commonjs",
|
|
||||||
"target": "ES2021",
|
|
||||||
"strict": true,
|
|
||||||
"esModuleInterop": true,
|
|
||||||
"skipLibCheck": true,
|
|
||||||
"forceConsistentCasingInFileNames": true,
|
|
||||||
"experimentalDecorators": true,
|
|
||||||
"emitDecoratorMetadata": true,
|
|
||||||
"lib": ["esnext", "dom"],
|
|
||||||
"outDir": "lib",
|
|
||||||
"moduleResolution": "node",
|
|
||||||
"paths": {
|
|
||||||
"@trigger.dev/sdk": ["../../packages/trigger-sdk/src/index"],
|
|
||||||
"@trigger.dev/sdk/*": ["../../packages/trigger-sdk/src/*"],
|
|
||||||
"@trigger.dev/github": ["../../integrations/github/src/index"],
|
|
||||||
"@trigger.dev/github/*": ["../../integrations/github/src/*"]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,37 +0,0 @@
|
|||||||
{
|
|
||||||
"extends": "./node18.json",
|
|
||||||
"compilerOptions": {
|
|
||||||
"lib": [
|
|
||||||
"DOM",
|
|
||||||
"DOM.Iterable",
|
|
||||||
"ES2019"
|
|
||||||
],
|
|
||||||
"paths": {
|
|
||||||
"@trigger.dev/tsup/*": [
|
|
||||||
"../../config-packages/tsup/src/*"
|
|
||||||
],
|
|
||||||
"@trigger.dev/tsup": [
|
|
||||||
"../../config-packages/tsup/src/index"
|
|
||||||
],
|
|
||||||
"@trigger.dev/sdk/*": [
|
|
||||||
"../../packages/trigger-sdk/src/*"
|
|
||||||
],
|
|
||||||
"@trigger.dev/sdk": [
|
|
||||||
"../../packages/trigger-sdk/src/index"
|
|
||||||
],
|
|
||||||
"@trigger.dev/integration-kit/*": [
|
|
||||||
"../../packages/integration-kit/src/*"
|
|
||||||
],
|
|
||||||
"@trigger.dev/integration-kit": [
|
|
||||||
"../../packages/integration-kit/src/index"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"declaration": false,
|
|
||||||
"declarationMap": false,
|
|
||||||
"baseUrl": ".",
|
|
||||||
"stripInternal": true
|
|
||||||
},
|
|
||||||
"exclude": [
|
|
||||||
"node_modules"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
{
|
|
||||||
"$schema": "https://json.schemastore.org/tsconfig",
|
|
||||||
"display": "Next.js",
|
|
||||||
"extends": "./base.json",
|
|
||||||
"compilerOptions": {
|
|
||||||
"target": "es5",
|
|
||||||
"lib": ["dom", "dom.iterable", "esnext"],
|
|
||||||
"allowJs": true,
|
|
||||||
"skipLibCheck": true,
|
|
||||||
"strict": false,
|
|
||||||
"forceConsistentCasingInFileNames": true,
|
|
||||||
"noEmit": true,
|
|
||||||
"incremental": true,
|
|
||||||
"esModuleInterop": true,
|
|
||||||
"module": "esnext",
|
|
||||||
"resolveJsonModule": true,
|
|
||||||
"isolatedModules": true,
|
|
||||||
"jsx": "preserve"
|
|
||||||
},
|
|
||||||
"include": ["src", "next-env.d.ts"],
|
|
||||||
"exclude": ["node_modules"]
|
|
||||||
}
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
{
|
|
||||||
"$schema": "https://json.schemastore.org/tsconfig",
|
|
||||||
"display": "Node 18",
|
|
||||||
"extends": "./base.json",
|
|
||||||
"compilerOptions": {
|
|
||||||
"lib": ["ES2021"],
|
|
||||||
"module": "commonjs",
|
|
||||||
"target": "ES2021",
|
|
||||||
"strict": true,
|
|
||||||
"esModuleInterop": true,
|
|
||||||
"skipLibCheck": true,
|
|
||||||
"forceConsistentCasingInFileNames": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "@trigger.dev/tsconfig",
|
|
||||||
"version": "0.0.0",
|
|
||||||
"private": true,
|
|
||||||
"license": "MIT",
|
|
||||||
"publishConfig": {
|
|
||||||
"access": "public"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
{
|
|
||||||
"$schema": "https://json.schemastore.org/tsconfig",
|
|
||||||
"display": "React Library",
|
|
||||||
"extends": "./base.json",
|
|
||||||
"compilerOptions": {
|
|
||||||
"lib": ["ES2015"],
|
|
||||||
"module": "ESNext",
|
|
||||||
"target": "ES6",
|
|
||||||
"jsx": "react-jsx"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "@trigger.dev/tsup",
|
|
||||||
"version": "0.0.0",
|
|
||||||
"private": true,
|
|
||||||
"license": "MIT",
|
|
||||||
"main": "./src/index.ts",
|
|
||||||
"types": "./src/index.ts",
|
|
||||||
"dependencies": {
|
|
||||||
"esbuild": "^0.19.11",
|
|
||||||
"tsup": "^8.0.1"
|
|
||||||
},
|
|
||||||
"devDependencies": {
|
|
||||||
"@types/node": "18",
|
|
||||||
"typescript": "^5.3.0"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=18.0.0"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
export { defineConfig } from "tsup";
|
|
||||||
export { deepMergeOptions } from "./utils";
|
|
||||||
export { options as integrationOptions } from "./integration";
|
|
||||||
export { options as packageOptions, defineConfig as defineConfigPackage } from "./package";
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
import { Options, defineConfig } from "tsup";
|
|
||||||
|
|
||||||
export const options: Options = {
|
|
||||||
name: "main",
|
|
||||||
entry: ["./src/index.ts"],
|
|
||||||
outDir: "./dist",
|
|
||||||
platform: "node",
|
|
||||||
format: ["cjs"],
|
|
||||||
legacyOutput: true,
|
|
||||||
sourcemap: true,
|
|
||||||
clean: true,
|
|
||||||
bundle: true,
|
|
||||||
splitting: false,
|
|
||||||
dts: true,
|
|
||||||
treeshake: {
|
|
||||||
preset: "smallest",
|
|
||||||
},
|
|
||||||
esbuildPlugins: [],
|
|
||||||
external: ["http", "https", "util", "events", "tty", "os", "timers"],
|
|
||||||
};
|
|
||||||
|
|
||||||
export default defineConfig(options);
|
|
||||||
@@ -1,39 +0,0 @@
|
|||||||
import { Plugin } from "esbuild";
|
|
||||||
import { Options, defineConfig as defineConfigTSUP } from "tsup";
|
|
||||||
|
|
||||||
const restoreNodeProtocolPlugin = (): Plugin => {
|
|
||||||
return {
|
|
||||||
name: "node-protocol-plugin-restorer",
|
|
||||||
setup(build) {
|
|
||||||
build.onResolve(
|
|
||||||
{
|
|
||||||
filter: /node:/,
|
|
||||||
},
|
|
||||||
async (args) => {
|
|
||||||
return { path: args.path, external: true };
|
|
||||||
}
|
|
||||||
);
|
|
||||||
},
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
export const options: Options = {
|
|
||||||
name: "main",
|
|
||||||
config: "tsconfig.json",
|
|
||||||
entry: ["./src/index.ts"],
|
|
||||||
outDir: "./dist",
|
|
||||||
platform: "node",
|
|
||||||
format: ["cjs", "esm"],
|
|
||||||
legacyOutput: false,
|
|
||||||
sourcemap: true,
|
|
||||||
clean: true,
|
|
||||||
bundle: true,
|
|
||||||
splitting: false,
|
|
||||||
dts: true,
|
|
||||||
treeshake: {
|
|
||||||
preset: "recommended",
|
|
||||||
},
|
|
||||||
esbuildPlugins: [restoreNodeProtocolPlugin()],
|
|
||||||
};
|
|
||||||
|
|
||||||
export const defineConfig = defineConfigTSUP(options);
|
|
||||||
@@ -1,32 +0,0 @@
|
|||||||
import { Options } from "tsup";
|
|
||||||
|
|
||||||
export const deepMergeOptions = deepMergeRecords<Options>;
|
|
||||||
|
|
||||||
function deepMergeRecords<TRecord extends Record<any, any>>(...options: TRecord[]): TRecord {
|
|
||||||
const result = {} as TRecord;
|
|
||||||
|
|
||||||
for (const option of options) {
|
|
||||||
for (const key in option) {
|
|
||||||
if (option.hasOwnProperty(key)) {
|
|
||||||
const optionValue = option[key];
|
|
||||||
const existingValue = result[key];
|
|
||||||
|
|
||||||
if (
|
|
||||||
existingValue &&
|
|
||||||
typeof existingValue === "object" &&
|
|
||||||
typeof optionValue === "object" &&
|
|
||||||
!Array.isArray(existingValue) &&
|
|
||||||
!Array.isArray(optionValue) &&
|
|
||||||
existingValue !== null &&
|
|
||||||
optionValue !== null
|
|
||||||
) {
|
|
||||||
result[key] = deepMergeRecords(existingValue, optionValue);
|
|
||||||
} else {
|
|
||||||
result[key] = optionValue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
+2
-2
@@ -40,8 +40,6 @@ FROM base AS builder
|
|||||||
WORKDIR /triggerdotdev
|
WORKDIR /triggerdotdev
|
||||||
# Corepack is used to install pnpm
|
# Corepack is used to install pnpm
|
||||||
RUN corepack enable
|
RUN corepack enable
|
||||||
# Install protobuf compiler
|
|
||||||
RUN apt-get update && apt-get install -y protobuf-compiler
|
|
||||||
|
|
||||||
COPY --from=pruner --chown=node:node /triggerdotdev/out/full/ .
|
COPY --from=pruner --chown=node:node /triggerdotdev/out/full/ .
|
||||||
COPY --from=dev-deps --chown=node:node /triggerdotdev/ .
|
COPY --from=dev-deps --chown=node:node /triggerdotdev/ .
|
||||||
@@ -49,6 +47,8 @@ COPY --chown=node:node turbo.json turbo.json
|
|||||||
COPY --chown=node:node docker/scripts ./scripts
|
COPY --chown=node:node docker/scripts ./scripts
|
||||||
RUN chmod +x ./scripts/wait-for-it.sh
|
RUN chmod +x ./scripts/wait-for-it.sh
|
||||||
RUN chmod +x ./scripts/entrypoint.sh
|
RUN chmod +x ./scripts/entrypoint.sh
|
||||||
|
COPY --chown=node:node .configs/tsconfig.base.json .configs/tsconfig.base.json
|
||||||
|
COPY --chown=node:node scripts/updateVersion.ts scripts/updateVersion.ts
|
||||||
RUN pnpm run generate
|
RUN pnpm run generate
|
||||||
RUN pnpm run build --filter=webapp...
|
RUN pnpm run build --filter=webapp...
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,251 @@
|
|||||||
|
---
|
||||||
|
title: "Upgrade to new build system"
|
||||||
|
description: "How to use the new build system preview release"
|
||||||
|
---
|
||||||
|
|
||||||
|
Based on feedback and a steady flow of issues from our previous build system, we're happy to share with you a preview release of our new build system that (hopefully) fixes most of the issues you may have faced.
|
||||||
|
|
||||||
|
The main features of the new build sytem are:
|
||||||
|
|
||||||
|
- **Bundling by default**: All dependencies are bundled by default, so you no longer need to specify which dependencies to bundle. This solves a whole bunch of issues related to monorepos.
|
||||||
|
- **Build extensions**: A new way to extend the build process with custom logic. This is a more flexible and powerful way to extend the build process compared to the old system. (including custom esbuild plugin support)
|
||||||
|
- **Improved configuration**: We've migrated to using [c12](https://github.com/unjs/c12) to power our configuration system.
|
||||||
|
- **Improved error handling**: We now do a much better job of reporting of any errors that happen during the indexing process by loading your trigger task files dynamically.
|
||||||
|
- **Improved cold start times**: Previously, we would load all your trigger task files at once, which could lead to long cold start times. Now we load your trigger task files dynamically, which should improve cold start times.
|
||||||
|
|
||||||
|
## Update packages
|
||||||
|
|
||||||
|
To use the new build system, you have to update to use our preview packages. Update the `@trigger.dev/sdk` package in your package.json:
|
||||||
|
|
||||||
|
```json
|
||||||
|
"@trigger.dev/sdk": "https://pkg.pr.new/triggerdotdev/trigger.dev/@trigger.dev/sdk@1265"
|
||||||
|
```
|
||||||
|
|
||||||
|
You will also need to update your usage of the `trigger.dev` CLI to use the preview release. If you run the CLI via `npx` you can update to the preview release like so:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
# old way
|
||||||
|
npx trigger.dev@beta dev
|
||||||
|
|
||||||
|
# using the preview release
|
||||||
|
npx https://pkg.pr.new/triggerdotdev/trigger.dev@1265 dev
|
||||||
|
```
|
||||||
|
|
||||||
|
If you've added the `trigger.dev` CLI to your `devDependencies`, then you should update the version to point to the preview release:
|
||||||
|
|
||||||
|
```json
|
||||||
|
"trigger.dev": "https://pkg.pr.new/triggerdotdev/trigger.dev@1265"
|
||||||
|
```
|
||||||
|
|
||||||
|
Once you do that make sure you re-install your dependencies using `npm i` or the equivalent with your preferred package manager.
|
||||||
|
|
||||||
|
## Update your `trigger.config.ts`
|
||||||
|
|
||||||
|
The new build system does not effect your trigger task files at all, so those can remain unchanged. However, you may need to make changes to your `trigger.config.ts` file.
|
||||||
|
|
||||||
|
### `defineConfig`
|
||||||
|
|
||||||
|
You should now import the `defineConfig` function from `@trigger.dev/sdk/v3` and export the config as the default export:
|
||||||
|
|
||||||
|
```
|
||||||
|
import { defineConfig } from "@trigger.dev/sdk/v3";
|
||||||
|
|
||||||
|
export default defineConfig({
|
||||||
|
project: "<project ref>",
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
### Deprecated: `dependenciesToBundle`
|
||||||
|
|
||||||
|
The new build system will bundle all dependencies by default, so `dependenciesToBundle` no longer makes any sense and can be removed.
|
||||||
|
|
||||||
|
#### Externals
|
||||||
|
|
||||||
|
Now that all dependencies are bundled, there are some situations where bundling a dependency doesn't work, and needs to be made external (e.g. when a dependency includes a native module). You can now specify these dependencies as build externals in the `defineConfig` function:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
import { defineConfig } from "@trigger.dev/sdk/v3";
|
||||||
|
|
||||||
|
export default defineConfig({
|
||||||
|
project: "<project ref>",
|
||||||
|
build: {
|
||||||
|
externals: ["native-module"],
|
||||||
|
},
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
`externals` is an array of strings, where each string is the name of a dependency that should be made external. Glob expressions are also supported and use the [minimatch](https://github.com/isaacs/minimatch) matcher.
|
||||||
|
|
||||||
|
### `additionalFiles`
|
||||||
|
|
||||||
|
The `additionalFiles` option has been moved to our new build extension system.
|
||||||
|
|
||||||
|
To use build extensions, you'll need to add the `@trigger.dev/build` package to your `devDependencies`:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
npm add https://pkg.pr.new/triggerdotdev/trigger.dev/@trigger.dev/build@1265 -D
|
||||||
|
```
|
||||||
|
|
||||||
|
Now you can import the `additionalFiles` build extension and use it in your `trigger.config.ts` file:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
import { defineConfig } from "@trigger.dev/sdk/v3";
|
||||||
|
import { additionalFiles } from "@trigger.dev/build/extensions/core";
|
||||||
|
|
||||||
|
export default defineConfig({
|
||||||
|
project: "<project ref>",
|
||||||
|
build: {
|
||||||
|
extensions: [
|
||||||
|
additionalFiles({ files: ["wrangler/wrangler.toml", "./assets/**", "./fonts/**"] }),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
### `additionalPackages`
|
||||||
|
|
||||||
|
The `additionalPackages` option has been moved to our new build extension system.
|
||||||
|
|
||||||
|
To use build extensions, you'll need to add the `@trigger.dev/build` package to your `devDependencies`:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
npm add https://pkg.pr.new/triggerdotdev/trigger.dev/@trigger.dev/build@1265 -D
|
||||||
|
```
|
||||||
|
|
||||||
|
Now you can import the `additionalPackages` build extension and use it in your `trigger.config.ts` file:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
import { defineConfig } from "@trigger.dev/sdk/v3";
|
||||||
|
import { additionalPackages } from "@trigger.dev/build/extensions/core";
|
||||||
|
|
||||||
|
export default defineConfig({
|
||||||
|
project: "<project ref>",
|
||||||
|
build: {
|
||||||
|
extensions: [additionalPackages({ packages: ["wrangler"] })],
|
||||||
|
},
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
### `resolveEnvVars`
|
||||||
|
|
||||||
|
The `resolveEnvVars` export has been moved to our new build extension system.
|
||||||
|
|
||||||
|
To use build extensions, you'll need to add the `@trigger.dev/build` package to your `devDependencies`:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
npm add https://pkg.pr.new/triggerdotdev/trigger.dev/@trigger.dev/build@1265 -D
|
||||||
|
```
|
||||||
|
|
||||||
|
Now you can import the `syncEnvVars` build extension and use it in your `trigger.config.ts` file:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
import { defineConfig } from "@trigger.dev/sdk/v3";
|
||||||
|
import { syncEnvVars } from "@trigger.dev/build/extensions/core";
|
||||||
|
|
||||||
|
export default defineConfig({
|
||||||
|
project: "<project ref>",
|
||||||
|
build: {
|
||||||
|
extensions: [
|
||||||
|
syncEnvVars(async (params) => {
|
||||||
|
return {
|
||||||
|
MY_ENV_VAR: "my-value",
|
||||||
|
};
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
The `syncEnvVars` callback function works very similarly to the [`resolveEnvVars`](/deploy-environment-variables#sync-env-vars-from-another-service) callback, but now instead of returning an object with a `variables` key that contains the environment variables, you return an object with the environment variables directly (see the example above).
|
||||||
|
|
||||||
|
One other difference is now `params.env` only contains the environment variables that are set in the Trigger.dev environment variables, and not the environment variables from the process. If you want to access the environment variables from the process, you can use `process.env`.
|
||||||
|
|
||||||
|
### emitDecoratorMetadata
|
||||||
|
|
||||||
|
If you make use of decorators in your code, and have enabled the `emitDecoratorMetadata` tsconfig compiler option, you'll need to enable this in the new build sytem using the `emitDecoratorMetadata` build extension:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
import { defineConfig } from "@trigger.dev/sdk/v3";
|
||||||
|
import { emitDecoratorMetadata } from "@trigger.dev/build/extensions/typescript";
|
||||||
|
|
||||||
|
export default defineConfig({
|
||||||
|
project: "<project ref>",
|
||||||
|
build: {
|
||||||
|
extensions: [emitDecoratorMetadata()],
|
||||||
|
},
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
### Prisma
|
||||||
|
|
||||||
|
We've created a build extension to support using Prisma in your Trigger.dev tasks. To use this extension, you'll need to add the `@trigger.dev/build` package to your `devDependencies`:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
npm add https://pkg.pr.new/triggerdotdev/trigger.dev/@trigger.dev/build@1265 -D
|
||||||
|
```
|
||||||
|
|
||||||
|
Then you can import the `prismaExtension` build extension and use it in your `trigger.config.ts` file, passing in the path to your Prisma schema file:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
import { defineConfig } from "@trigger.dev/sdk/v3";
|
||||||
|
import { prismaExtension } from "@trigger.dev/build/extensions/prisma";
|
||||||
|
|
||||||
|
export default defineConfig({
|
||||||
|
project: "<project ref>",
|
||||||
|
build: {
|
||||||
|
extensions: [
|
||||||
|
prismaExtension({
|
||||||
|
schema: "prisma/schema.prisma",
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
This will make sure that your prisma client is generated during the build process when deploying to Trigger.dev.
|
||||||
|
|
||||||
|
<Note>
|
||||||
|
This does not have any effect when running the `dev` command, so you'll need to make sure you
|
||||||
|
generate your client locally first.
|
||||||
|
</Note>
|
||||||
|
|
||||||
|
If you want to also run migrations during the build process, you can pass in the `migrate` option:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
import { defineConfig } from "@trigger.dev/sdk/v3";
|
||||||
|
import { prismaExtension } from "@trigger.dev/build/extensions/prisma";
|
||||||
|
|
||||||
|
export default defineConfig({
|
||||||
|
project: "<project ref>",
|
||||||
|
build: {
|
||||||
|
extensions: [
|
||||||
|
prismaExtension({
|
||||||
|
schema: "prisma/schema.prisma",
|
||||||
|
migrate: true,
|
||||||
|
directUrlEnvVarName: "DATABASE_URL_UNPOOLED", // optional - the name of the environment variable that contains the direct database URL if you are using a direct database URL
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
### audioWaveform
|
||||||
|
|
||||||
|
Previously, we installed [Audio Waveform](https://github.com/bbc/audiowaveform) in the build image. That's been moved to a build extension:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
import { defineConfig } from "@trigger.dev/sdk/v3";
|
||||||
|
import { audioWaveform } from "@trigger.dev/build/extensions/audioWaveform";
|
||||||
|
|
||||||
|
export default defineConfig({
|
||||||
|
project: "<project ref>",
|
||||||
|
build: {
|
||||||
|
extensions: [audioWaveform()], // uses verson 1.1.0 of audiowaveform by default
|
||||||
|
},
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
## Known issues
|
||||||
|
|
||||||
|
- Path aliases are not yet support in your `trigger.config.ts` file. To workaround this issue you'll need to rewrite path aliases to their relative paths. (See [this](https://github.com/unjs/jiti/issues/166) and [this](https://knip.dev/reference/known-issues#path-aliases-in-config-files)) for more info.
|
||||||
|
- Some events in the run trace view may get permanently stuck in a loading state. This is a known issue and we're working on a fix.
|
||||||
@@ -1,604 +0,0 @@
|
|||||||
import { z } from "zod";
|
|
||||||
import * as v from "valibot";
|
|
||||||
import { wrap } from "@typeschema/valibot";
|
|
||||||
|
|
||||||
export type ParserZodEsque<TInput, TParsedInput> = {
|
|
||||||
_input: TInput;
|
|
||||||
_output: TParsedInput;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type ParserMyZodEsque<TInput> = {
|
|
||||||
parse: (input: any) => TInput;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type ParserSuperstructEsque<TInput> = {
|
|
||||||
create: (input: unknown) => TInput;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type ParserCustomValidatorEsque<TInput> = (input: unknown) => Promise<TInput> | TInput;
|
|
||||||
|
|
||||||
export type ParserYupEsque<TInput> = {
|
|
||||||
validateSync: (input: unknown) => TInput;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type ParserScaleEsque<TInput> = {
|
|
||||||
assert(value: unknown): asserts value is TInput;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type ParserWithoutInput<TInput> =
|
|
||||||
| ParserCustomValidatorEsque<TInput>
|
|
||||||
| ParserMyZodEsque<TInput>
|
|
||||||
| ParserScaleEsque<TInput>
|
|
||||||
| ParserSuperstructEsque<TInput>
|
|
||||||
| ParserYupEsque<TInput>;
|
|
||||||
|
|
||||||
export type ParserWithInputOutput<TInput, TParsedInput> = ParserZodEsque<TInput, TParsedInput>;
|
|
||||||
|
|
||||||
export type Parser = ParserWithInputOutput<any, any> | ParserWithoutInput<any>;
|
|
||||||
|
|
||||||
export type inferParser<TParser extends Parser> = TParser extends ParserWithInputOutput<
|
|
||||||
infer $TIn,
|
|
||||||
infer $TOut
|
|
||||||
>
|
|
||||||
? {
|
|
||||||
in: $TIn;
|
|
||||||
out: $TOut;
|
|
||||||
}
|
|
||||||
: TParser extends ParserWithoutInput<infer $InOut>
|
|
||||||
? {
|
|
||||||
in: $InOut;
|
|
||||||
out: $InOut;
|
|
||||||
}
|
|
||||||
: never;
|
|
||||||
|
|
||||||
export type Simplify<TType> = TType extends any[] | Date ? TType : { [K in keyof TType]: TType[K] };
|
|
||||||
|
|
||||||
export type TriggerResult = {
|
|
||||||
id: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type TaskRunResult<TOutput = any> =
|
|
||||||
| {
|
|
||||||
ok: true;
|
|
||||||
id: string;
|
|
||||||
output: TOutput;
|
|
||||||
}
|
|
||||||
| {
|
|
||||||
ok: false;
|
|
||||||
id: string;
|
|
||||||
error: unknown;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type RunMetadata = {
|
|
||||||
run: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type inferContext<TContextBuilder extends AnyContextBuilder> =
|
|
||||||
TContextBuilder extends ContextBuilder<infer TContext, infer TContextOverrides>
|
|
||||||
? TContext extends UnsetMarker
|
|
||||||
? unknown
|
|
||||||
: TContextOverrides extends UnsetMarker
|
|
||||||
? Simplify<TContext>
|
|
||||||
: Simplify<Overwrite<TContext, TContextOverrides>>
|
|
||||||
: never;
|
|
||||||
|
|
||||||
export type RunFnParams<TPayload, TContext extends AnyContextBuilder> = {
|
|
||||||
/** Metadata about the task, run, attempt, queue, environment, organization, project and batch. */
|
|
||||||
meta: RunMetadata;
|
|
||||||
|
|
||||||
/** Context added by task middleware */
|
|
||||||
ctx: inferContext<TContext>;
|
|
||||||
|
|
||||||
payload: TPayload;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* See https://github.com/microsoft/TypeScript/issues/41966#issuecomment-758187996
|
|
||||||
* Fixes issues with iterating over keys of objects with index signatures.
|
|
||||||
* Without this, iterations over keys of objects with index signatures will lose
|
|
||||||
* type information about the keys and only the index signature will remain.
|
|
||||||
* @internal
|
|
||||||
*/
|
|
||||||
export type WithoutIndexSignature<TObj> = {
|
|
||||||
[K in keyof TObj as string extends K ? never : number extends K ? never : K]: TObj[K];
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @internal
|
|
||||||
* Overwrite properties in `TType` with properties in `TWith`
|
|
||||||
* Only overwrites properties when the type to be overwritten
|
|
||||||
* is an object. Otherwise it will just use the type from `TWith`.
|
|
||||||
*/
|
|
||||||
export type Overwrite<TType, TWith> = TWith extends any
|
|
||||||
? TType extends object
|
|
||||||
? {
|
|
||||||
[K in
|
|
||||||
| keyof WithoutIndexSignature<TType>
|
|
||||||
| keyof WithoutIndexSignature<TWith>]: K extends keyof TWith // Exclude index signature from keys
|
|
||||||
? TWith[K]
|
|
||||||
: K extends keyof TType
|
|
||||||
? TType[K]
|
|
||||||
: never;
|
|
||||||
} & (string extends keyof TWith // Handle cases with an index signature
|
|
||||||
? { [key: string]: TWith[string] }
|
|
||||||
: number extends keyof TWith
|
|
||||||
? { [key: number]: TWith[number] }
|
|
||||||
: // eslint-disable-next-line @typescript-eslint/ban-types
|
|
||||||
{})
|
|
||||||
: TWith
|
|
||||||
: never;
|
|
||||||
|
|
||||||
/** @internal */
|
|
||||||
export const contextMiddlewareMarker = "contextMiddlewareMarker" as "contextMiddlewareMarker" & {
|
|
||||||
__brand: "contextMiddlewareMarker";
|
|
||||||
};
|
|
||||||
type ContextMiddlewareMarker = typeof contextMiddlewareMarker;
|
|
||||||
|
|
||||||
interface ContextMiddlewareResultBase {
|
|
||||||
/**
|
|
||||||
* All middlewares should pass through their `next()`'s output.
|
|
||||||
* Requiring this marker makes sure that can't be forgotten at compile-time.
|
|
||||||
*/
|
|
||||||
readonly marker: ContextMiddlewareMarker;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface ContextMiddlewareOKResult<_TContextOverride> extends ContextMiddlewareResultBase {
|
|
||||||
ok: true;
|
|
||||||
data: unknown;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface ContextMiddlewareErrorResult<_TContextOverride> extends ContextMiddlewareResultBase {
|
|
||||||
ok: false;
|
|
||||||
error: Error; // should be our error
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @internal
|
|
||||||
*/
|
|
||||||
export type ContextMiddlewareResult<_TContextOverride> =
|
|
||||||
| ContextMiddlewareErrorResult<_TContextOverride>
|
|
||||||
| ContextMiddlewareOKResult<_TContextOverride>;
|
|
||||||
|
|
||||||
export type ContextMiddlewareFunction<TContext, TContextOverridesIn, $ContextOverridesOut> = {
|
|
||||||
(opts: {
|
|
||||||
ctx: Simplify<Overwrite<TContext, TContextOverridesIn>>;
|
|
||||||
meta: RunMetadata;
|
|
||||||
next: {
|
|
||||||
(): Promise<ContextMiddlewareResult<TContextOverridesIn>>;
|
|
||||||
<$ContextOverride>(ctx: $ContextOverride): Promise<ContextMiddlewareResult<$ContextOverride>>;
|
|
||||||
};
|
|
||||||
}): Promise<ContextMiddlewareResult<$ContextOverridesOut>>;
|
|
||||||
};
|
|
||||||
|
|
||||||
export const unsetMarker = Symbol("unsetMarker");
|
|
||||||
export type UnsetMarker = typeof unsetMarker;
|
|
||||||
|
|
||||||
export interface ContextBuilder<TContext extends object, TContextOverrides> {
|
|
||||||
use<$ContextOverridesOut>(
|
|
||||||
fn: ContextMiddlewareFunction<TContext, TContextOverrides, $ContextOverridesOut>
|
|
||||||
): ContextBuilder<TContext, Overwrite<TContextOverrides, $ContextOverridesOut>>;
|
|
||||||
}
|
|
||||||
|
|
||||||
export type AnyContextBuilder = ContextBuilder<any, any>;
|
|
||||||
|
|
||||||
export function createContext<TContext extends object>(
|
|
||||||
initialContext?: TContext
|
|
||||||
): ContextBuilder<TContext, UnsetMarker> {
|
|
||||||
const builder: AnyContextBuilder = {
|
|
||||||
use(middlewareFn) {
|
|
||||||
return {} as AnyContextBuilder;
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
return builder;
|
|
||||||
}
|
|
||||||
|
|
||||||
const contextBuilder = createContext({ foo: "bar" });
|
|
||||||
const context = contextBuilder
|
|
||||||
.use((opts) => {
|
|
||||||
return opts.next({
|
|
||||||
baz: "whatever",
|
|
||||||
});
|
|
||||||
})
|
|
||||||
.use((opts) => {
|
|
||||||
return opts.next({
|
|
||||||
db: {
|
|
||||||
find: async (id: string) => {
|
|
||||||
return "hello";
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
type ctx = inferContext<typeof context>;
|
|
||||||
|
|
||||||
const contextBuilder2 = createContext();
|
|
||||||
|
|
||||||
type ctx2 = inferContext<typeof contextBuilder2>;
|
|
||||||
|
|
||||||
const contextBuilder3 = createContext({ bar: "baz" });
|
|
||||||
|
|
||||||
type ctx3 = inferContext<typeof contextBuilder3>;
|
|
||||||
|
|
||||||
const contextBuilder4 = createContext().use((opts) => {
|
|
||||||
return opts.next({
|
|
||||||
hello: "world",
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
type ctx4 = inferContext<typeof contextBuilder4>;
|
|
||||||
|
|
||||||
export type TaskOptions<
|
|
||||||
TOutput,
|
|
||||||
TContext extends AnyContextBuilder,
|
|
||||||
TIdentifier extends string,
|
|
||||||
TParser extends Parser | undefined = undefined,
|
|
||||||
> = {
|
|
||||||
/** An id for your task. This must be unique inside your project and not change between versions. */
|
|
||||||
id: TIdentifier;
|
|
||||||
|
|
||||||
schema?: TParser;
|
|
||||||
|
|
||||||
context?: TContext;
|
|
||||||
|
|
||||||
/** This gets called when a task is triggered. It's where you put the code you want to execute.
|
|
||||||
*
|
|
||||||
* @param payload - The payload that is passed to your task when it's triggered. This must be JSON serializable.
|
|
||||||
* @param params - Metadata about the run.
|
|
||||||
*/
|
|
||||||
run: (params: Simplify<RunFnParams<inferParserOut<TParser>, TContext>>) => Promise<TOutput>;
|
|
||||||
};
|
|
||||||
|
|
||||||
export interface Task<
|
|
||||||
TOutput,
|
|
||||||
TIdentifier extends string,
|
|
||||||
TParser extends Parser | undefined = undefined,
|
|
||||||
> {
|
|
||||||
/**
|
|
||||||
* The id of the task.
|
|
||||||
*/
|
|
||||||
id: TIdentifier;
|
|
||||||
/**
|
|
||||||
* Trigger a task with the given payload, and continue without waiting for the result. If you want to wait for the result, use `triggerAndWait`. Returns the id of the triggered task run.
|
|
||||||
* @param payload
|
|
||||||
* @param options
|
|
||||||
* @returns TriggerResult
|
|
||||||
* - `id` - The id of the triggered task run.
|
|
||||||
*/
|
|
||||||
trigger: (
|
|
||||||
payload: Simplify<inferParserIn<TParser, any>>,
|
|
||||||
options?: TriggerTaskOptions
|
|
||||||
) => Promise<TriggerResult>;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Trigger a task with the given payload, and wait for the result. Returns the result of the task run
|
|
||||||
* @param payload
|
|
||||||
* @param options - Options for the task run
|
|
||||||
* @returns TaskRunResult
|
|
||||||
* @example
|
|
||||||
* ```
|
|
||||||
* const result = await task.triggerAndWait({ foo: "bar" });
|
|
||||||
*
|
|
||||||
* if (result.ok) {
|
|
||||||
* console.log(result.output);
|
|
||||||
* } else {
|
|
||||||
* console.error(result.error);
|
|
||||||
* }
|
|
||||||
* ```
|
|
||||||
*/
|
|
||||||
triggerAndWait: (
|
|
||||||
payload: Simplify<inferParserIn<TParser, any>>,
|
|
||||||
options?: TriggerTaskOptions
|
|
||||||
) => Promise<TaskRunResult<TOutput>>;
|
|
||||||
}
|
|
||||||
|
|
||||||
export type AnyTask = Task<any, string, any>;
|
|
||||||
|
|
||||||
type inferParserIn<TParser extends Parser | undefined, TDefault = unknown> = TParser extends Parser
|
|
||||||
? inferParser<TParser>["in"]
|
|
||||||
: TDefault;
|
|
||||||
type inferParserOut<TParser extends Parser | undefined, TDefault = unknown> = TParser extends Parser
|
|
||||||
? inferParser<TParser>["out"]
|
|
||||||
: TDefault;
|
|
||||||
|
|
||||||
export type TaskPayloadIn<TTask extends AnyTask> = TTask extends Task<any, string, infer TParser>
|
|
||||||
? inferParserIn<TParser>
|
|
||||||
: never;
|
|
||||||
|
|
||||||
export type TaskPayloadOut<TTask extends AnyTask> = TTask extends Task<any, string, infer TParser>
|
|
||||||
? inferParserOut<TParser>
|
|
||||||
: never;
|
|
||||||
|
|
||||||
export type TaskOutput<TTask extends AnyTask> = TTask extends Task<infer TOutput, string, any>
|
|
||||||
? TOutput
|
|
||||||
: never;
|
|
||||||
|
|
||||||
export type TaskIdentifier<TTask extends AnyTask> = TTask extends Task<any, infer TIdentifier, any>
|
|
||||||
? TIdentifier
|
|
||||||
: never;
|
|
||||||
|
|
||||||
export type TaskTypes<TTask extends AnyTask> = TTask extends Task<
|
|
||||||
infer TOutput,
|
|
||||||
infer TIdentifier,
|
|
||||||
infer TParser
|
|
||||||
>
|
|
||||||
? {
|
|
||||||
id: TIdentifier;
|
|
||||||
payloadIn: inferParserIn<TParser>;
|
|
||||||
payloadOut: inferParserOut<TParser>;
|
|
||||||
output: TOutput;
|
|
||||||
}
|
|
||||||
: never;
|
|
||||||
|
|
||||||
export type TriggerTaskOptions = {
|
|
||||||
idempotencyKey?: string;
|
|
||||||
maxAttempts?: number;
|
|
||||||
startAt?: Date;
|
|
||||||
startAfter?: number;
|
|
||||||
concurrencyKey?: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type Prettify<T> = {
|
|
||||||
[K in keyof T]: T[K];
|
|
||||||
} & {};
|
|
||||||
|
|
||||||
export function task<
|
|
||||||
TOutput,
|
|
||||||
TContext extends AnyContextBuilder,
|
|
||||||
TIdentifier extends string,
|
|
||||||
TParser extends Parser | undefined = undefined,
|
|
||||||
>(
|
|
||||||
options: TaskOptions<TOutput, TContext, TIdentifier, TParser>
|
|
||||||
): Task<TOutput, TIdentifier, TParser> {
|
|
||||||
return createTask(options);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function createTask<
|
|
||||||
TOutput,
|
|
||||||
TContext extends AnyContextBuilder,
|
|
||||||
TIndentifier extends string,
|
|
||||||
TParser extends Parser | undefined = undefined,
|
|
||||||
>(
|
|
||||||
params: TaskOptions<TOutput, TContext, TIndentifier, TParser>
|
|
||||||
): Task<TOutput, TIndentifier, TParser> {
|
|
||||||
const task: Task<TOutput, TIndentifier, TParser> = {
|
|
||||||
id: params.id,
|
|
||||||
trigger: async (payload, options) => {
|
|
||||||
return {
|
|
||||||
id: "run_1234",
|
|
||||||
};
|
|
||||||
},
|
|
||||||
triggerAndWait: async (payload, options) => {
|
|
||||||
const output = await params.run({
|
|
||||||
meta: { run: "run_1234" },
|
|
||||||
payload: payload as unknown as inferParserOut<TParser>, // Actually do the parsing
|
|
||||||
ctx: {} as inferContext<TContext>,
|
|
||||||
});
|
|
||||||
|
|
||||||
return {
|
|
||||||
ok: true,
|
|
||||||
id: "run_1234",
|
|
||||||
output,
|
|
||||||
};
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
return task;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface TaskLibraryRecord {
|
|
||||||
[key: string]: AnyTask | TaskLibraryRecord;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface TaskLibrary<TRecord extends TaskLibraryRecord> {
|
|
||||||
_def: { record: TRecord };
|
|
||||||
}
|
|
||||||
|
|
||||||
export type AnyTaskLibrary = TaskLibrary<any>;
|
|
||||||
|
|
||||||
export type CreateTaskLibraryOptions = {
|
|
||||||
[key: string]: AnyTask | AnyTaskLibrary | CreateTaskLibraryOptions;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type DecorateCreateTaskLibraryOptions<TTaskLibraryOptions extends CreateTaskLibraryOptions> =
|
|
||||||
{
|
|
||||||
[K in keyof TTaskLibraryOptions]: TTaskLibraryOptions[K] extends infer $Value
|
|
||||||
? $Value extends AnyTask
|
|
||||||
? $Value
|
|
||||||
: $Value extends TaskLibrary<infer TRecord>
|
|
||||||
? TRecord
|
|
||||||
: $Value extends CreateTaskLibraryOptions
|
|
||||||
? DecorateCreateTaskLibraryOptions<$Value>
|
|
||||||
: never
|
|
||||||
: never;
|
|
||||||
};
|
|
||||||
|
|
||||||
function taskLibrary<TInput extends CreateTaskLibraryOptions>(
|
|
||||||
input: TInput
|
|
||||||
): TaskLibrary<DecorateCreateTaskLibraryOptions<TInput>>;
|
|
||||||
function taskLibrary<TInput extends TaskLibraryRecord>(input: TInput): TaskLibrary<TInput>;
|
|
||||||
function taskLibrary(input: TaskLibraryRecord | CreateTaskLibraryOptions) {
|
|
||||||
// TODO: reserved words
|
|
||||||
|
|
||||||
return {
|
|
||||||
_def: {
|
|
||||||
record: input,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
// ======== client side
|
|
||||||
type DecorateTask<TTask extends AnyTask> = {
|
|
||||||
trigger: (id: TaskIdentifier<TTask>, payload: TaskPayloadIn<TTask>) => Promise<{ id: string }>;
|
|
||||||
};
|
|
||||||
|
|
||||||
type DecoratedTaskLibraryRecord<
|
|
||||||
TTaskLibrary extends AnyTaskLibrary,
|
|
||||||
TRecord extends TaskLibraryRecord,
|
|
||||||
> = {
|
|
||||||
[TKey in keyof TRecord]: TRecord[TKey] extends infer $Value
|
|
||||||
? $Value extends TaskLibraryRecord
|
|
||||||
? DecoratedTaskLibraryRecord<TTaskLibrary, $Value>
|
|
||||||
: $Value extends AnyTask
|
|
||||||
? DecorateTask<$Value>
|
|
||||||
: never
|
|
||||||
: never;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type inferTaskLibraryClient<TTaskLibrary extends AnyTaskLibrary> =
|
|
||||||
DecoratedTaskLibraryRecord<TTaskLibrary, TTaskLibrary["_def"]["record"]>;
|
|
||||||
|
|
||||||
export type CreateTriggerClient<TTaskLibrary extends AnyTaskLibrary> = {
|
|
||||||
lib: inferTaskLibraryClient<TTaskLibrary>;
|
|
||||||
runs: {
|
|
||||||
retrieve: (id: string) => Promise<{ status: boolean }>;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
export type CreateTriggerClientOptions = {
|
|
||||||
secretKey?: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
export function createTriggerClient<TTaskLibrary extends AnyTaskLibrary>(
|
|
||||||
options?: CreateTriggerClientOptions
|
|
||||||
): CreateTriggerClient<TTaskLibrary> {
|
|
||||||
return {} as CreateTriggerClient<TTaskLibrary>;
|
|
||||||
}
|
|
||||||
|
|
||||||
// trigger/my-tasks.ts
|
|
||||||
const taskOne = task({
|
|
||||||
id: "task-1",
|
|
||||||
run: async () => {
|
|
||||||
const handle = await taskTwo.trigger({ url: "https://trigger.dev" });
|
|
||||||
const result = await taskTwo.triggerAndWait({ url: "https://trigger.dev" });
|
|
||||||
|
|
||||||
return "foo-bar";
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const taskTwo = task({
|
|
||||||
id: "task-2",
|
|
||||||
async run(params) {
|
|
||||||
return {
|
|
||||||
hello: "world",
|
|
||||||
payload: params.payload.other,
|
|
||||||
};
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const userTaskOne = task({
|
|
||||||
id: "user/task-1",
|
|
||||||
context: contextBuilder4,
|
|
||||||
run: async (params) => {
|
|
||||||
return "foo-bar";
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const userTaskTwo = task({
|
|
||||||
id: "user/task-2",
|
|
||||||
context: contextBuilder3,
|
|
||||||
run: async (params) => {
|
|
||||||
return "foo-bar";
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const zodTaskOne = task({
|
|
||||||
id: "zod/task-1",
|
|
||||||
context: contextBuilder,
|
|
||||||
schema: z.object({ foo: z.string() }),
|
|
||||||
run: async (params) => {},
|
|
||||||
});
|
|
||||||
|
|
||||||
const zodTaskTwo = task({
|
|
||||||
id: "zod/task-2",
|
|
||||||
schema: z.object({ foo: z.string(), isAdmin: z.boolean().default(false) }),
|
|
||||||
context: contextBuilder2,
|
|
||||||
run: async (params) => {
|
|
||||||
console.log(params.payload.foo, params.meta.run);
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const valibotTaskOne = task({
|
|
||||||
id: "valibot/task-1",
|
|
||||||
schema: wrap(
|
|
||||||
v.object({
|
|
||||||
foo: v.string(),
|
|
||||||
})
|
|
||||||
),
|
|
||||||
run: async (params) => {
|
|
||||||
await zodTaskOne.trigger({ foo: "bar" });
|
|
||||||
await zodTaskTwo.trigger({ foo: "bar" });
|
|
||||||
|
|
||||||
await valibotTaskTwo.trigger({ foo: "bar" });
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const valibotTaskTwo = task({
|
|
||||||
id: "valibot/task-2",
|
|
||||||
schema: wrap(
|
|
||||||
v.object({
|
|
||||||
foo: v.string(),
|
|
||||||
isAdmin: v.optional(v.boolean(), true),
|
|
||||||
})
|
|
||||||
),
|
|
||||||
run: async (params) => {
|
|
||||||
await valibotTaskOne.trigger({ foo: "bar" });
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
// in trigger/lib.ts
|
|
||||||
const myTaskLibrary = taskLibrary({
|
|
||||||
myTasks: { taskOne, taskTwo },
|
|
||||||
});
|
|
||||||
|
|
||||||
const userTaskLibrary = taskLibrary({
|
|
||||||
userTaskOne,
|
|
||||||
userTaskTwo,
|
|
||||||
});
|
|
||||||
|
|
||||||
const zodTaskLibrary = taskLibrary({
|
|
||||||
zodTaskOne,
|
|
||||||
zodTaskTwo,
|
|
||||||
});
|
|
||||||
|
|
||||||
const valibotTaskLibrary = taskLibrary({
|
|
||||||
valibotTaskOne,
|
|
||||||
valibotTaskTwo,
|
|
||||||
});
|
|
||||||
|
|
||||||
export const library = taskLibrary({
|
|
||||||
foo: myTaskLibrary,
|
|
||||||
bar: userTaskLibrary,
|
|
||||||
zod: zodTaskLibrary,
|
|
||||||
valibot: valibotTaskLibrary,
|
|
||||||
});
|
|
||||||
|
|
||||||
// Export the library type
|
|
||||||
export type Library = typeof library;
|
|
||||||
|
|
||||||
// Now on the client
|
|
||||||
const client = createTriggerClient<Library>({
|
|
||||||
secretKey: "tr_dev_1234",
|
|
||||||
});
|
|
||||||
|
|
||||||
client.runs.retrieve("run_12343"); // Call regular API client calls
|
|
||||||
|
|
||||||
// Tasks are now available under lib
|
|
||||||
client.lib.foo.myTasks.taskOne.trigger("task-1", { hello: "world" });
|
|
||||||
client.lib.bar.userTaskOne.trigger("user/task-1", { userId: "user_123" });
|
|
||||||
client.lib.bar.userTaskTwo.trigger("user/task-2", {
|
|
||||||
userId: "user_123",
|
|
||||||
isAdmin: true,
|
|
||||||
});
|
|
||||||
client.lib.bar.userTaskTwo.trigger("user/task-2", {
|
|
||||||
userId: "user_123",
|
|
||||||
isAdmin: false,
|
|
||||||
});
|
|
||||||
client.lib.zod.zodTaskOne.trigger("zod/task-1", { foo: "bar" });
|
|
||||||
client.lib.zod.zodTaskTwo.trigger("zod/task-2", { foo: "bar" });
|
|
||||||
client.lib.zod.zodTaskTwo.trigger("zod/task-2", { foo: "bar", isAdmin: false });
|
|
||||||
client.lib.valibot.valibotTaskTwo.trigger("valibot/task-2", { foo: "bar" });
|
|
||||||
client.lib.valibot.valibotTaskTwo.trigger("valibot/task-2", {
|
|
||||||
foo: "bar",
|
|
||||||
isAdmin: true,
|
|
||||||
});
|
|
||||||
@@ -1,444 +0,0 @@
|
|||||||
import { z } from "zod";
|
|
||||||
import * as v from "valibot";
|
|
||||||
import { wrap } from "@typeschema/valibot";
|
|
||||||
|
|
||||||
export type ParserZodEsque<TInput, TParsedInput> = {
|
|
||||||
_input: TInput;
|
|
||||||
_output: TParsedInput;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type ParserMyZodEsque<TInput> = {
|
|
||||||
parse: (input: any) => TInput;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type ParserSuperstructEsque<TInput> = {
|
|
||||||
create: (input: unknown) => TInput;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type ParserCustomValidatorEsque<TInput> = (input: unknown) => Promise<TInput> | TInput;
|
|
||||||
|
|
||||||
export type ParserYupEsque<TInput> = {
|
|
||||||
validateSync: (input: unknown) => TInput;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type ParserScaleEsque<TInput> = {
|
|
||||||
assert(value: unknown): asserts value is TInput;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type ParserWithoutInput<TInput> =
|
|
||||||
| ParserCustomValidatorEsque<TInput>
|
|
||||||
| ParserMyZodEsque<TInput>
|
|
||||||
| ParserScaleEsque<TInput>
|
|
||||||
| ParserSuperstructEsque<TInput>
|
|
||||||
| ParserYupEsque<TInput>;
|
|
||||||
|
|
||||||
export type ParserWithInputOutput<TInput, TParsedInput> = ParserZodEsque<TInput, TParsedInput>;
|
|
||||||
|
|
||||||
export type Parser = ParserWithInputOutput<any, any> | ParserWithoutInput<any>;
|
|
||||||
|
|
||||||
export type inferParser<TParser extends Parser> = TParser extends ParserWithInputOutput<
|
|
||||||
infer $TIn,
|
|
||||||
infer $TOut
|
|
||||||
>
|
|
||||||
? {
|
|
||||||
in: $TIn;
|
|
||||||
out: $TOut;
|
|
||||||
}
|
|
||||||
: TParser extends ParserWithoutInput<infer $InOut>
|
|
||||||
? {
|
|
||||||
in: $InOut;
|
|
||||||
out: $InOut;
|
|
||||||
}
|
|
||||||
: never;
|
|
||||||
|
|
||||||
export type Simplify<TType> = TType extends any[] | Date ? TType : { [K in keyof TType]: TType[K] };
|
|
||||||
|
|
||||||
export type TriggerResult = {
|
|
||||||
id: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type TaskRunResult<TOutput = any> =
|
|
||||||
| {
|
|
||||||
ok: true;
|
|
||||||
id: string;
|
|
||||||
output: TOutput;
|
|
||||||
}
|
|
||||||
| {
|
|
||||||
ok: false;
|
|
||||||
id: string;
|
|
||||||
error: unknown;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type RunMetadata = {
|
|
||||||
run: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type RunFnParams<TPayload, TContext extends object> = {
|
|
||||||
/** Metadata about the task, run, attempt, queue, environment, organization, project and batch. */
|
|
||||||
meta: RunMetadata;
|
|
||||||
|
|
||||||
/** Context added by task middleware */
|
|
||||||
ctx: TContext;
|
|
||||||
|
|
||||||
payload: TPayload;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type TaskOptions<
|
|
||||||
TOutput,
|
|
||||||
TContext extends object,
|
|
||||||
TIdentifier extends string,
|
|
||||||
TParser extends Parser | undefined = undefined,
|
|
||||||
> = {
|
|
||||||
/** An id for your task. This must be unique inside your project and not change between versions. */
|
|
||||||
id: TIdentifier;
|
|
||||||
|
|
||||||
schema?: TParser;
|
|
||||||
|
|
||||||
/** This gets called when a task is triggered. It's where you put the code you want to execute.
|
|
||||||
*
|
|
||||||
* @param payload - The payload that is passed to your task when it's triggered. This must be JSON serializable.
|
|
||||||
* @param params - Metadata about the run.
|
|
||||||
*/
|
|
||||||
run: (params: Simplify<RunFnParams<inferParserOut<TParser>, TContext>>) => Promise<TOutput>;
|
|
||||||
};
|
|
||||||
|
|
||||||
export interface Task<
|
|
||||||
TOutput,
|
|
||||||
TIdentifier extends string,
|
|
||||||
TParser extends Parser | undefined = undefined,
|
|
||||||
> {
|
|
||||||
/**
|
|
||||||
* The id of the task.
|
|
||||||
*/
|
|
||||||
id: TIdentifier;
|
|
||||||
/**
|
|
||||||
* Trigger a task with the given payload, and continue without waiting for the result. If you want to wait for the result, use `triggerAndWait`. Returns the id of the triggered task run.
|
|
||||||
* @param payload
|
|
||||||
* @param options
|
|
||||||
* @returns TriggerResult
|
|
||||||
* - `id` - The id of the triggered task run.
|
|
||||||
*/
|
|
||||||
trigger: (
|
|
||||||
payload: Simplify<inferParserIn<TParser, any>>,
|
|
||||||
options?: TriggerTaskOptions
|
|
||||||
) => Promise<TriggerResult>;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Trigger a task with the given payload, and wait for the result. Returns the result of the task run
|
|
||||||
* @param payload
|
|
||||||
* @param options - Options for the task run
|
|
||||||
* @returns TaskRunResult
|
|
||||||
* @example
|
|
||||||
* ```
|
|
||||||
* const result = await task.triggerAndWait({ foo: "bar" });
|
|
||||||
*
|
|
||||||
* if (result.ok) {
|
|
||||||
* console.log(result.output);
|
|
||||||
* } else {
|
|
||||||
* console.error(result.error);
|
|
||||||
* }
|
|
||||||
* ```
|
|
||||||
*/
|
|
||||||
triggerAndWait: (
|
|
||||||
payload: Simplify<inferParserIn<TParser, any>>,
|
|
||||||
options?: TriggerTaskOptions
|
|
||||||
) => Promise<TaskRunResult<TOutput>>;
|
|
||||||
}
|
|
||||||
|
|
||||||
export type AnyTask = Task<any, string, any>;
|
|
||||||
|
|
||||||
type inferParserIn<TParser extends Parser | undefined, TDefault = unknown> = TParser extends Parser
|
|
||||||
? inferParser<TParser>["in"]
|
|
||||||
: TDefault;
|
|
||||||
type inferParserOut<TParser extends Parser | undefined, TDefault = unknown> = TParser extends Parser
|
|
||||||
? inferParser<TParser>["out"]
|
|
||||||
: TDefault;
|
|
||||||
|
|
||||||
export type TaskPayloadIn<TTask extends AnyTask> = TTask extends Task<any, string, infer TParser>
|
|
||||||
? inferParserIn<TParser>
|
|
||||||
: never;
|
|
||||||
|
|
||||||
export type TaskPayloadOut<TTask extends AnyTask> = TTask extends Task<any, string, infer TParser>
|
|
||||||
? inferParserOut<TParser>
|
|
||||||
: never;
|
|
||||||
|
|
||||||
export type TaskOutput<TTask extends AnyTask> = TTask extends Task<infer TOutput, string, any>
|
|
||||||
? TOutput
|
|
||||||
: never;
|
|
||||||
|
|
||||||
export type TaskIdentifier<TTask extends AnyTask> = TTask extends Task<any, infer TIdentifier, any>
|
|
||||||
? TIdentifier
|
|
||||||
: never;
|
|
||||||
|
|
||||||
export type TaskTypes<TTask extends AnyTask> = TTask extends Task<
|
|
||||||
infer TOutput,
|
|
||||||
infer TIdentifier,
|
|
||||||
infer TParser
|
|
||||||
>
|
|
||||||
? {
|
|
||||||
id: TIdentifier;
|
|
||||||
payloadIn: inferParserIn<TParser>;
|
|
||||||
payloadOut: inferParserOut<TParser>;
|
|
||||||
output: TOutput;
|
|
||||||
}
|
|
||||||
: never;
|
|
||||||
|
|
||||||
export type TriggerTaskOptions = {
|
|
||||||
idempotencyKey?: string;
|
|
||||||
maxAttempts?: number;
|
|
||||||
startAt?: Date;
|
|
||||||
startAfter?: number;
|
|
||||||
concurrencyKey?: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type Prettify<T> = {
|
|
||||||
[K in keyof T]: T[K];
|
|
||||||
} & {};
|
|
||||||
|
|
||||||
export function task<
|
|
||||||
TOutput,
|
|
||||||
TContext extends object,
|
|
||||||
TIdentifier extends string,
|
|
||||||
TParser extends Parser | undefined = undefined,
|
|
||||||
>(
|
|
||||||
options: TaskOptions<TOutput, TContext, TIdentifier, TParser>
|
|
||||||
): Task<TOutput, TIdentifier, TParser> {
|
|
||||||
return createTask(options);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function createTask<
|
|
||||||
TOutput,
|
|
||||||
TContext extends object,
|
|
||||||
TIndentifier extends string,
|
|
||||||
TParser extends Parser | undefined = undefined,
|
|
||||||
>(
|
|
||||||
params: TaskOptions<TOutput, TContext, TIndentifier, TParser>
|
|
||||||
): Task<TOutput, TIndentifier, TParser> {
|
|
||||||
const task: Task<TOutput, TIndentifier, TParser> = {
|
|
||||||
id: params.id,
|
|
||||||
trigger: async (payload, options) => {
|
|
||||||
return {
|
|
||||||
id: "run_1234",
|
|
||||||
};
|
|
||||||
},
|
|
||||||
triggerAndWait: async (payload, options) => {
|
|
||||||
const output = await params.run({
|
|
||||||
meta: { run: "run_1234" },
|
|
||||||
payload: payload as unknown as inferParserOut<TParser>, // Actually do the parsing
|
|
||||||
ctx: {} as TContext,
|
|
||||||
});
|
|
||||||
|
|
||||||
return {
|
|
||||||
ok: true,
|
|
||||||
id: "run_1234",
|
|
||||||
output,
|
|
||||||
};
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
return task;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface TaskLibraryRecord {
|
|
||||||
[key: string]: AnyTask | TaskLibraryRecord;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface TaskLibrary<TRecord extends TaskLibraryRecord> {
|
|
||||||
_def: { record: TRecord };
|
|
||||||
}
|
|
||||||
|
|
||||||
export type AnyTaskLibrary = TaskLibrary<any>;
|
|
||||||
|
|
||||||
export type CreateTaskLibraryOptions = {
|
|
||||||
[key: string]: AnyTask | AnyTaskLibrary | CreateTaskLibraryOptions;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type DecorateCreateTaskLibraryOptions<TTaskLibraryOptions extends CreateTaskLibraryOptions> =
|
|
||||||
{
|
|
||||||
[K in keyof TTaskLibraryOptions]: TTaskLibraryOptions[K] extends infer $Value
|
|
||||||
? $Value extends AnyTask
|
|
||||||
? $Value
|
|
||||||
: $Value extends TaskLibrary<infer TRecord>
|
|
||||||
? TRecord
|
|
||||||
: $Value extends CreateTaskLibraryOptions
|
|
||||||
? DecorateCreateTaskLibraryOptions<$Value>
|
|
||||||
: never
|
|
||||||
: never;
|
|
||||||
};
|
|
||||||
|
|
||||||
function taskLibrary<TInput extends CreateTaskLibraryOptions>(
|
|
||||||
input: TInput
|
|
||||||
): TaskLibrary<DecorateCreateTaskLibraryOptions<TInput>>;
|
|
||||||
function taskLibrary<TInput extends TaskLibraryRecord>(input: TInput): TaskLibrary<TInput>;
|
|
||||||
function taskLibrary(input: TaskLibraryRecord | CreateTaskLibraryOptions) {
|
|
||||||
// TODO: reserved words
|
|
||||||
|
|
||||||
return {
|
|
||||||
_def: {
|
|
||||||
record: input,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
// ======== client side
|
|
||||||
type DecorateTask<TTask extends AnyTask> = {
|
|
||||||
trigger: (id: TaskIdentifier<TTask>, payload: TaskPayloadIn<TTask>) => Promise<{ id: string }>;
|
|
||||||
};
|
|
||||||
|
|
||||||
type DecoratedTaskLibraryRecord<
|
|
||||||
TTaskLibrary extends AnyTaskLibrary,
|
|
||||||
TRecord extends TaskLibraryRecord,
|
|
||||||
> = {
|
|
||||||
[TKey in keyof TRecord]: TRecord[TKey] extends infer $Value
|
|
||||||
? $Value extends TaskLibraryRecord
|
|
||||||
? DecoratedTaskLibraryRecord<TTaskLibrary, $Value>
|
|
||||||
: $Value extends AnyTask
|
|
||||||
? DecorateTask<$Value>
|
|
||||||
: never
|
|
||||||
: never;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type inferTaskLibraryClient<TTaskLibrary extends AnyTaskLibrary> =
|
|
||||||
DecoratedTaskLibraryRecord<TTaskLibrary, TTaskLibrary["_def"]["record"]>;
|
|
||||||
|
|
||||||
export type CreateTriggerClient<TTaskLibrary extends AnyTaskLibrary> = {
|
|
||||||
lib: inferTaskLibraryClient<TTaskLibrary>;
|
|
||||||
runs: {
|
|
||||||
retrieve: (id: string) => Promise<{ status: boolean }>;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
export type CreateTriggerClientOptions = {
|
|
||||||
secretKey?: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
export function createTriggerClient<TTaskLibrary extends AnyTaskLibrary>(
|
|
||||||
options?: CreateTriggerClientOptions
|
|
||||||
): CreateTriggerClient<TTaskLibrary> {
|
|
||||||
return {} as CreateTriggerClient<TTaskLibrary>;
|
|
||||||
}
|
|
||||||
|
|
||||||
// trigger/my-tasks.ts
|
|
||||||
const taskOne = task({
|
|
||||||
id: "task-1",
|
|
||||||
run: async () => {
|
|
||||||
const handle = await taskTwo.trigger({ url: "https://trigger.dev" });
|
|
||||||
const result = await taskTwo.triggerAndWait({ url: "https://trigger.dev" });
|
|
||||||
|
|
||||||
return "foo-bar";
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const taskTwo = task({
|
|
||||||
id: "task-2",
|
|
||||||
async run(params) {
|
|
||||||
return {
|
|
||||||
hello: "world",
|
|
||||||
payload: params.payload.other,
|
|
||||||
};
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const userTaskOne = task({
|
|
||||||
id: "user/task-1",
|
|
||||||
run: async (params) => {
|
|
||||||
return "foo-bar";
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const userTaskTwo = task({
|
|
||||||
id: "user/task-2",
|
|
||||||
run: async (params) => {
|
|
||||||
return "foo-bar";
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const zodTaskOne = task({
|
|
||||||
id: "zod/task-1",
|
|
||||||
schema: z.object({ foo: z.string() }),
|
|
||||||
run: async (params) => {},
|
|
||||||
});
|
|
||||||
|
|
||||||
const zodTaskTwo = task({
|
|
||||||
id: "zod/task-2",
|
|
||||||
schema: z.object({ foo: z.string(), isAdmin: z.boolean().default(false) }),
|
|
||||||
run: async (params) => {
|
|
||||||
console.log(params.payload.foo, params.meta.run);
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const valibotTaskOne = task({
|
|
||||||
id: "valibot/task-1",
|
|
||||||
schema: wrap(
|
|
||||||
v.object({
|
|
||||||
foo: v.string(),
|
|
||||||
})
|
|
||||||
),
|
|
||||||
run: async (params) => {
|
|
||||||
await zodTaskOne.trigger({ foo: "bar" });
|
|
||||||
await zodTaskTwo.trigger({ foo: "bar" });
|
|
||||||
|
|
||||||
await valibotTaskTwo.trigger({ foo: "bar" });
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const valibotTaskTwo = task({
|
|
||||||
id: "valibot/task-2",
|
|
||||||
schema: wrap(
|
|
||||||
v.object({
|
|
||||||
foo: v.string(),
|
|
||||||
isAdmin: v.optional(v.boolean(), true),
|
|
||||||
})
|
|
||||||
),
|
|
||||||
run: async (params) => {
|
|
||||||
await valibotTaskOne.trigger({ foo: "bar" });
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
// in trigger/lib.ts
|
|
||||||
const myTaskLibrary = taskLibrary({
|
|
||||||
myTasks: { taskOne, taskTwo },
|
|
||||||
});
|
|
||||||
|
|
||||||
const userTaskLibrary = taskLibrary({
|
|
||||||
userTaskOne,
|
|
||||||
userTaskTwo,
|
|
||||||
});
|
|
||||||
|
|
||||||
const zodTaskLibrary = taskLibrary({
|
|
||||||
zodTaskOne,
|
|
||||||
zodTaskTwo,
|
|
||||||
});
|
|
||||||
|
|
||||||
const valibotTaskLibrary = taskLibrary({
|
|
||||||
valibotTaskOne,
|
|
||||||
valibotTaskTwo,
|
|
||||||
});
|
|
||||||
|
|
||||||
export const library = taskLibrary({
|
|
||||||
foo: myTaskLibrary,
|
|
||||||
bar: userTaskLibrary,
|
|
||||||
zod: zodTaskLibrary,
|
|
||||||
valibot: valibotTaskLibrary,
|
|
||||||
});
|
|
||||||
|
|
||||||
// Export the library type
|
|
||||||
export type Library = typeof library;
|
|
||||||
|
|
||||||
// Now on the client
|
|
||||||
const client = createTriggerClient<Library>({
|
|
||||||
secretKey: "tr_dev_1234",
|
|
||||||
});
|
|
||||||
|
|
||||||
client.runs.retrieve("run_12343"); // Call regular API client calls
|
|
||||||
|
|
||||||
// Tasks are now available under lib
|
|
||||||
client.lib.foo.myTasks.taskOne.trigger("task-1", { hello: "world" });
|
|
||||||
client.lib.bar.userTaskOne.trigger("user/task-1", { userId: "user_123" });
|
|
||||||
client.lib.bar.userTaskTwo.trigger("user/task-2", { userId: "user_123", isAdmin: true });
|
|
||||||
client.lib.bar.userTaskTwo.trigger("user/task-2", { userId: "user_123", isAdmin: false });
|
|
||||||
client.lib.zod.zodTaskOne.trigger("zod/task-1", { foo: "bar" });
|
|
||||||
client.lib.zod.zodTaskTwo.trigger("zod/task-2", { foo: "bar" });
|
|
||||||
client.lib.zod.zodTaskTwo.trigger("zod/task-2", { foo: "bar", isAdmin: false });
|
|
||||||
client.lib.valibot.valibotTaskTwo.trigger("valibot/task-2", { foo: "bar" });
|
|
||||||
client.lib.valibot.valibotTaskTwo.trigger("valibot/task-2", { foo: "bar", isAdmin: true });
|
|
||||||
@@ -1,499 +0,0 @@
|
|||||||
import { z } from "zod";
|
|
||||||
import * as v from "valibot";
|
|
||||||
|
|
||||||
export type ParserZodEsque<TInput, TParsedInput> = {
|
|
||||||
_input: TInput;
|
|
||||||
_output: TParsedInput;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type ParserMyZodEsque<TInput> = {
|
|
||||||
parse: (input: any) => TInput;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type ParserSuperstructEsque<TInput> = {
|
|
||||||
create: (input: unknown) => TInput;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type ParserCustomValidatorEsque<TInput> = (input: unknown) => Promise<TInput> | TInput;
|
|
||||||
|
|
||||||
export type ParserYupEsque<TInput> = {
|
|
||||||
validateSync: (input: unknown) => TInput;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type ParserScaleEsque<TInput> = {
|
|
||||||
assert(value: unknown): asserts value is TInput;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type ParserWithoutInput<TInput> =
|
|
||||||
| ParserCustomValidatorEsque<TInput>
|
|
||||||
| ParserMyZodEsque<TInput>
|
|
||||||
| ParserScaleEsque<TInput>
|
|
||||||
| ParserSuperstructEsque<TInput>
|
|
||||||
| ParserYupEsque<TInput>;
|
|
||||||
|
|
||||||
export type ParserWithInputOutput<TInput, TParsedInput> = ParserZodEsque<TInput, TParsedInput>;
|
|
||||||
|
|
||||||
export type Parser = ParserWithInputOutput<any, any> | ParserWithoutInput<any>;
|
|
||||||
|
|
||||||
export type inferParser<TParser extends Parser> = TParser extends ParserWithInputOutput<
|
|
||||||
infer $TIn,
|
|
||||||
infer $TOut
|
|
||||||
>
|
|
||||||
? {
|
|
||||||
in: $TIn;
|
|
||||||
out: $TOut;
|
|
||||||
}
|
|
||||||
: TParser extends ParserWithoutInput<infer $InOut>
|
|
||||||
? {
|
|
||||||
in: $InOut;
|
|
||||||
out: $InOut;
|
|
||||||
}
|
|
||||||
: never;
|
|
||||||
|
|
||||||
export type Simplify<TType> = TType extends any[] | Date ? TType : { [K in keyof TType]: TType[K] };
|
|
||||||
|
|
||||||
export type TriggerResult = {
|
|
||||||
id: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type TaskRunResult<TOutput = any> =
|
|
||||||
| {
|
|
||||||
ok: true;
|
|
||||||
id: string;
|
|
||||||
output: TOutput;
|
|
||||||
}
|
|
||||||
| {
|
|
||||||
ok: false;
|
|
||||||
id: string;
|
|
||||||
error: unknown;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type RunMetadata = {
|
|
||||||
run: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type RunFnParams<TPayload, TContext extends object> = {
|
|
||||||
/** Metadata about the task, run, attempt, queue, environment, organization, project and batch. */
|
|
||||||
meta: RunMetadata;
|
|
||||||
|
|
||||||
/** Context added by task middleware */
|
|
||||||
ctx: TContext;
|
|
||||||
|
|
||||||
payload: TPayload;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type TaskOptions<
|
|
||||||
TPayloadIn,
|
|
||||||
TPayloadOut,
|
|
||||||
TOutput,
|
|
||||||
TContext extends object,
|
|
||||||
TIdentifier extends string,
|
|
||||||
> = {
|
|
||||||
/** An id for your task. This must be unique inside your project and not change between versions. */
|
|
||||||
id: TIdentifier;
|
|
||||||
|
|
||||||
schema?: Parser;
|
|
||||||
|
|
||||||
/** This gets called when a task is triggered. It's where you put the code you want to execute.
|
|
||||||
*
|
|
||||||
* @param payload - The payload that is passed to your task when it's triggered. This must be JSON serializable.
|
|
||||||
* @param params - Metadata about the run.
|
|
||||||
*/
|
|
||||||
run: (
|
|
||||||
params: Simplify<RunFnParams<inferTaskPayloadOut<TPayloadIn, TPayloadOut>, TContext>>
|
|
||||||
) => Promise<TOutput>;
|
|
||||||
};
|
|
||||||
|
|
||||||
export interface Task<TPayloadIn, TPayloadOut, TOutput, TIdentifier extends string> {
|
|
||||||
/**
|
|
||||||
* The id of the task.
|
|
||||||
*/
|
|
||||||
id: TIdentifier;
|
|
||||||
/**
|
|
||||||
* Trigger a task with the given payload, and continue without waiting for the result. If you want to wait for the result, use `triggerAndWait`. Returns the id of the triggered task run.
|
|
||||||
* @param payload
|
|
||||||
* @param options
|
|
||||||
* @returns TriggerResult
|
|
||||||
* - `id` - The id of the triggered task run.
|
|
||||||
*/
|
|
||||||
trigger: (
|
|
||||||
payload: Simplify<inferTaskPayloadIn<TPayloadIn, TPayloadOut>>,
|
|
||||||
options?: TriggerTaskOptions
|
|
||||||
) => Promise<TriggerResult>;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Trigger a task with the given payload, and wait for the result. Returns the result of the task run
|
|
||||||
* @param payload
|
|
||||||
* @param options - Options for the task run
|
|
||||||
* @returns TaskRunResult
|
|
||||||
* @example
|
|
||||||
* ```
|
|
||||||
* const result = await task.triggerAndWait({ foo: "bar" });
|
|
||||||
*
|
|
||||||
* if (result.ok) {
|
|
||||||
* console.log(result.output);
|
|
||||||
* } else {
|
|
||||||
* console.error(result.error);
|
|
||||||
* }
|
|
||||||
* ```
|
|
||||||
*/
|
|
||||||
triggerAndWait: (
|
|
||||||
payload: Simplify<inferTaskPayloadIn<TPayloadIn, TPayloadOut>>,
|
|
||||||
options?: TriggerTaskOptions
|
|
||||||
) => Promise<TaskRunResult<TOutput>>;
|
|
||||||
}
|
|
||||||
|
|
||||||
export type AnyTask = Task<any, any, any, string>;
|
|
||||||
|
|
||||||
type IsUnknown<T> = unknown extends T ? (T extends unknown ? true : false) : false;
|
|
||||||
type NonUnknown<T> = IsUnknown<T> extends true ? never : T;
|
|
||||||
|
|
||||||
export type inferTaskPayloadIn<TPayloadIn, TPayloadOut> = NonUnknown<TPayloadIn> extends never
|
|
||||||
? TPayloadOut
|
|
||||||
: TPayloadIn;
|
|
||||||
export type inferTaskPayloadOut<TPayloadIn, TPayloadOut> = NonUnknown<TPayloadOut> extends never
|
|
||||||
? TPayloadIn
|
|
||||||
: TPayloadOut;
|
|
||||||
|
|
||||||
export type TaskPayloadIn<TTask extends AnyTask> = TTask extends Task<
|
|
||||||
infer TPayloadIn,
|
|
||||||
infer TPayloadOut,
|
|
||||||
any,
|
|
||||||
string
|
|
||||||
>
|
|
||||||
? inferTaskPayloadIn<TPayloadIn, TPayloadOut>
|
|
||||||
: never;
|
|
||||||
|
|
||||||
export type TaskPayloadOut<TTask extends AnyTask> = TTask extends Task<
|
|
||||||
infer TPayloadIn,
|
|
||||||
infer TPayloadOut,
|
|
||||||
any,
|
|
||||||
string
|
|
||||||
>
|
|
||||||
? inferTaskPayloadOut<TPayloadIn, TPayloadOut>
|
|
||||||
: never;
|
|
||||||
|
|
||||||
export type TaskOutput<TTask extends AnyTask> = TTask extends Task<any, any, infer TOutput, string>
|
|
||||||
? TOutput
|
|
||||||
: never;
|
|
||||||
|
|
||||||
export type TaskIdentifier<TTask extends AnyTask> = TTask extends Task<
|
|
||||||
any,
|
|
||||||
any,
|
|
||||||
any,
|
|
||||||
infer TIdentifier
|
|
||||||
>
|
|
||||||
? TIdentifier
|
|
||||||
: never;
|
|
||||||
|
|
||||||
export type TaskTypes<TTask extends AnyTask> = TTask extends Task<
|
|
||||||
infer TPayloadIn,
|
|
||||||
infer TPayloadOut,
|
|
||||||
infer TOutput,
|
|
||||||
infer TIdentifier
|
|
||||||
>
|
|
||||||
? {
|
|
||||||
id: TIdentifier;
|
|
||||||
payloadIn: TPayloadIn;
|
|
||||||
payloadOut: TPayloadOut;
|
|
||||||
output: TOutput;
|
|
||||||
}
|
|
||||||
: never;
|
|
||||||
|
|
||||||
export type TriggerTaskOptions = {
|
|
||||||
idempotencyKey?: string;
|
|
||||||
maxAttempts?: number;
|
|
||||||
startAt?: Date;
|
|
||||||
startAfter?: number;
|
|
||||||
concurrencyKey?: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type Prettify<T> = {
|
|
||||||
[K in keyof T]: T[K];
|
|
||||||
} & {};
|
|
||||||
|
|
||||||
export function task<
|
|
||||||
TPayloadIn,
|
|
||||||
TPayloadOut,
|
|
||||||
TOutput,
|
|
||||||
TContext extends object,
|
|
||||||
TIdentifier extends string,
|
|
||||||
>(
|
|
||||||
options: TaskOptions<TPayloadIn, TPayloadOut, TOutput, TContext, TIdentifier>
|
|
||||||
): Task<TPayloadIn, TPayloadOut, TOutput, TIdentifier> {
|
|
||||||
return createTask<TPayloadIn, TPayloadOut, TOutput, TContext, TIdentifier>(options);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function createTask<
|
|
||||||
TPayloadIn,
|
|
||||||
TPayloadOut,
|
|
||||||
TOutput,
|
|
||||||
TContext extends object,
|
|
||||||
TIndentifier extends string,
|
|
||||||
>(
|
|
||||||
params: TaskOptions<TPayloadIn, TPayloadOut, TOutput, TContext, TIndentifier>
|
|
||||||
): Task<TPayloadIn, TPayloadOut, TOutput, TIndentifier> {
|
|
||||||
const task: Task<TPayloadIn, TPayloadOut, TOutput, TIndentifier> = {
|
|
||||||
id: params.id,
|
|
||||||
trigger: async (payload, options) => {
|
|
||||||
return {
|
|
||||||
id: "run_1234",
|
|
||||||
};
|
|
||||||
},
|
|
||||||
triggerAndWait: async (payload, options) => {
|
|
||||||
const output = await params.run({
|
|
||||||
meta: { run: "run_1234" },
|
|
||||||
payload: payload as unknown as inferTaskPayloadOut<TPayloadIn, TPayloadOut>,
|
|
||||||
ctx: {} as TContext,
|
|
||||||
});
|
|
||||||
|
|
||||||
return {
|
|
||||||
ok: true,
|
|
||||||
id: "run_1234",
|
|
||||||
output,
|
|
||||||
};
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
return task;
|
|
||||||
}
|
|
||||||
|
|
||||||
export type ZodTaskOptions<
|
|
||||||
TOutput,
|
|
||||||
TContext extends object,
|
|
||||||
TIdentifier extends string,
|
|
||||||
TSchema extends z.ZodTypeAny = z.ZodTypeAny,
|
|
||||||
> = {
|
|
||||||
schema: TSchema;
|
|
||||||
} & TaskOptions<z.input<TSchema>, z.output<TSchema>, TOutput, TContext, TIdentifier>;
|
|
||||||
|
|
||||||
export function zodTask<
|
|
||||||
TOutput,
|
|
||||||
TContext extends object,
|
|
||||||
TIdentifier extends string,
|
|
||||||
TSchema extends z.ZodTypeAny = z.ZodTypeAny,
|
|
||||||
>(
|
|
||||||
options: ZodTaskOptions<TOutput, TContext, TIdentifier, TSchema>
|
|
||||||
): Task<z.input<TSchema>, z.output<TSchema>, TOutput, TIdentifier> {
|
|
||||||
return createTask<z.input<TSchema>, z.output<TSchema>, TOutput, TContext, TIdentifier>(options);
|
|
||||||
}
|
|
||||||
|
|
||||||
export type ValibotTaskOptions<
|
|
||||||
TOutput,
|
|
||||||
TContext extends object,
|
|
||||||
TIdentifier extends string,
|
|
||||||
TSchema extends v.BaseSchema = v.AnySchema,
|
|
||||||
> = {
|
|
||||||
schema: TSchema;
|
|
||||||
} & TaskOptions<v.Input<TSchema>, v.Output<TSchema>, TOutput, TContext, TIdentifier>;
|
|
||||||
|
|
||||||
export function valibotTask<
|
|
||||||
TOutput,
|
|
||||||
TContext extends object,
|
|
||||||
TIdentifier extends string,
|
|
||||||
TSchema extends v.BaseSchema = v.AnySchema,
|
|
||||||
>(
|
|
||||||
options: ValibotTaskOptions<TOutput, TContext, TIdentifier, TSchema>
|
|
||||||
): Task<v.Input<TSchema>, v.Output<TSchema>, TOutput, TIdentifier> {
|
|
||||||
return createTask<v.Input<TSchema>, v.Output<TSchema>, TOutput, TContext, TIdentifier>(options);
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface TaskLibraryRecord {
|
|
||||||
[key: string]: AnyTask | TaskLibraryRecord;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface TaskLibrary<TRecord extends TaskLibraryRecord> {
|
|
||||||
_def: { record: TRecord };
|
|
||||||
}
|
|
||||||
|
|
||||||
export type AnyTaskLibrary = TaskLibrary<any>;
|
|
||||||
|
|
||||||
export type CreateTaskLibraryOptions = {
|
|
||||||
[key: string]: AnyTask | AnyTaskLibrary | CreateTaskLibraryOptions;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type DecorateCreateTaskLibraryOptions<TTaskLibraryOptions extends CreateTaskLibraryOptions> =
|
|
||||||
{
|
|
||||||
[K in keyof TTaskLibraryOptions]: TTaskLibraryOptions[K] extends infer $Value
|
|
||||||
? $Value extends AnyTask
|
|
||||||
? $Value
|
|
||||||
: $Value extends TaskLibrary<infer TRecord>
|
|
||||||
? TRecord
|
|
||||||
: $Value extends CreateTaskLibraryOptions
|
|
||||||
? DecorateCreateTaskLibraryOptions<$Value>
|
|
||||||
: never
|
|
||||||
: never;
|
|
||||||
};
|
|
||||||
|
|
||||||
function taskLibrary<TInput extends CreateTaskLibraryOptions>(
|
|
||||||
input: TInput
|
|
||||||
): TaskLibrary<DecorateCreateTaskLibraryOptions<TInput>>;
|
|
||||||
function taskLibrary<TInput extends TaskLibraryRecord>(input: TInput): TaskLibrary<TInput>;
|
|
||||||
function taskLibrary(input: TaskLibraryRecord | CreateTaskLibraryOptions) {
|
|
||||||
// TODO: reserved words
|
|
||||||
|
|
||||||
return {
|
|
||||||
_def: {
|
|
||||||
record: input,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
// ======== client side
|
|
||||||
type DecorateTask<TTask extends AnyTask> = {
|
|
||||||
trigger: (id: TaskIdentifier<TTask>, payload: TaskPayloadIn<TTask>) => Promise<{ id: string }>;
|
|
||||||
};
|
|
||||||
|
|
||||||
type DecoratedTaskLibraryRecord<
|
|
||||||
TTaskLibrary extends AnyTaskLibrary,
|
|
||||||
TRecord extends TaskLibraryRecord,
|
|
||||||
> = {
|
|
||||||
[TKey in keyof TRecord]: TRecord[TKey] extends infer $Value
|
|
||||||
? $Value extends TaskLibraryRecord
|
|
||||||
? DecoratedTaskLibraryRecord<TTaskLibrary, $Value>
|
|
||||||
: $Value extends AnyTask
|
|
||||||
? DecorateTask<$Value>
|
|
||||||
: never
|
|
||||||
: never;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type inferTaskLibraryClient<TTaskLibrary extends AnyTaskLibrary> =
|
|
||||||
DecoratedTaskLibraryRecord<TTaskLibrary, TTaskLibrary["_def"]["record"]>;
|
|
||||||
|
|
||||||
export type CreateTriggerClient<TTaskLibrary extends AnyTaskLibrary> = {
|
|
||||||
lib: inferTaskLibraryClient<TTaskLibrary>;
|
|
||||||
runs: {
|
|
||||||
retrieve: (id: string) => Promise<{ status: boolean }>;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
export type CreateTriggerClientOptions = {
|
|
||||||
secretKey?: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
export function createTriggerClient<TTaskLibrary extends AnyTaskLibrary>(
|
|
||||||
options?: CreateTriggerClientOptions
|
|
||||||
): CreateTriggerClient<TTaskLibrary> {
|
|
||||||
return {} as CreateTriggerClient<TTaskLibrary>;
|
|
||||||
}
|
|
||||||
|
|
||||||
// trigger/my-tasks.ts
|
|
||||||
const taskOne = task({
|
|
||||||
id: "task-1",
|
|
||||||
run: async () => {
|
|
||||||
const handle = await taskTwo.trigger({ url: "https://trigger.dev" });
|
|
||||||
const result = await taskTwo.triggerAndWait({ url: "https://trigger.dev" });
|
|
||||||
|
|
||||||
return "foo-bar";
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const taskTwo = task({
|
|
||||||
id: "task-2",
|
|
||||||
async run(params) {
|
|
||||||
return {
|
|
||||||
hello: "world",
|
|
||||||
payload: params.payload,
|
|
||||||
};
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const userTaskOne = task({
|
|
||||||
id: "user/task-1",
|
|
||||||
run: async (params: { payload: { userId: string } }) => {
|
|
||||||
return "foo-bar";
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const userTaskTwo = task({
|
|
||||||
id: "user/task-2",
|
|
||||||
run: async (params: { payload: { userId: string; isAdmin: boolean } }) => {
|
|
||||||
return "foo-bar";
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const zodTaskOne = task({
|
|
||||||
id: "zod/task-1",
|
|
||||||
schema: z.object({ foo: z.string() }),
|
|
||||||
run: async (params) => {},
|
|
||||||
});
|
|
||||||
|
|
||||||
const zodTaskTwo = task({
|
|
||||||
id: "zod/task-2",
|
|
||||||
schema: z.object({ foo: z.string(), isAdmin: z.boolean().default(false) }),
|
|
||||||
run: async (params) => {
|
|
||||||
console.log(params.payload.foo, params.meta.run);
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const valibotTaskOne = task({
|
|
||||||
id: "valibot/task-1",
|
|
||||||
schema: v.object({
|
|
||||||
foo: v.string(),
|
|
||||||
}),
|
|
||||||
run: async (params) => {
|
|
||||||
await zodTaskOne.trigger({ foo: "bar" });
|
|
||||||
await zodTaskTwo.trigger({ foo: "bar" });
|
|
||||||
|
|
||||||
await valibotTaskTwo.trigger({ foo: "bar" });
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const valibotTaskTwo = task({
|
|
||||||
id: "valibot/task-2",
|
|
||||||
schema: v.object({
|
|
||||||
foo: v.string(),
|
|
||||||
isAdmin: v.optional(v.boolean(), true),
|
|
||||||
}),
|
|
||||||
run: async (params) => {
|
|
||||||
await valibotTaskOne.trigger({ foo: "bar" });
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
// in trigger/lib.ts
|
|
||||||
const myTaskLibrary = taskLibrary({
|
|
||||||
myTasks: { taskOne, taskTwo },
|
|
||||||
});
|
|
||||||
|
|
||||||
const userTaskLibrary = taskLibrary({
|
|
||||||
userTaskOne,
|
|
||||||
userTaskTwo,
|
|
||||||
});
|
|
||||||
|
|
||||||
const zodTaskLibrary = taskLibrary({
|
|
||||||
zodTaskOne,
|
|
||||||
zodTaskTwo,
|
|
||||||
});
|
|
||||||
|
|
||||||
const valibotTaskLibrary = taskLibrary({
|
|
||||||
valibotTaskOne,
|
|
||||||
valibotTaskTwo,
|
|
||||||
});
|
|
||||||
|
|
||||||
export const library = taskLibrary({
|
|
||||||
foo: myTaskLibrary,
|
|
||||||
bar: userTaskLibrary,
|
|
||||||
zod: zodTaskLibrary,
|
|
||||||
valibot: valibotTaskLibrary,
|
|
||||||
});
|
|
||||||
|
|
||||||
// Export the library type
|
|
||||||
export type Library = typeof library;
|
|
||||||
|
|
||||||
// Now on the client
|
|
||||||
const client = createTriggerClient<Library>({
|
|
||||||
secretKey: "tr_dev_1234",
|
|
||||||
});
|
|
||||||
|
|
||||||
client.runs.retrieve("run_12343"); // Call regular API client calls
|
|
||||||
|
|
||||||
// Tasks are now available under lib
|
|
||||||
client.lib.foo.myTasks.taskOne.trigger("task-1", { hello: "world" });
|
|
||||||
client.lib.bar.userTaskOne.trigger("user/task-1", { userId: "user_123" });
|
|
||||||
client.lib.bar.userTaskTwo.trigger("user/task-2", { userId: "user_123", isAdmin: true });
|
|
||||||
client.lib.bar.userTaskTwo.trigger("user/task-2", { userId: "user_123", isAdmin: false });
|
|
||||||
client.lib.zod.zodTaskOne.trigger("zod/task-1", { foo: "bar" });
|
|
||||||
client.lib.zod.zodTaskTwo.trigger("zod/task-2", { foo: "bar" });
|
|
||||||
client.lib.zod.zodTaskTwo.trigger("zod/task-2", { foo: "bar", isAdmin: false });
|
|
||||||
client.lib.valibot.valibotTaskTwo.trigger("valibot/task-2", { foo: "bar" });
|
|
||||||
client.lib.valibot.valibotTaskTwo.trigger("valibot/task-2", { foo: "bar", isAdmin: false });
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
charts/
|
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
# Patterns to ignore when building packages.
|
|
||||||
# This supports shell glob matching, relative path matching, and
|
|
||||||
# negation (prefixed with !). Only one pattern per line.
|
|
||||||
.DS_Store
|
|
||||||
# Common VCS dirs
|
|
||||||
.git/
|
|
||||||
.gitignore
|
|
||||||
.bzr/
|
|
||||||
.bzrignore
|
|
||||||
.hg/
|
|
||||||
.hgignore
|
|
||||||
.svn/
|
|
||||||
# Common backup files
|
|
||||||
*.swp
|
|
||||||
*.bak
|
|
||||||
*.tmp
|
|
||||||
*.orig
|
|
||||||
*~
|
|
||||||
# Various IDEs
|
|
||||||
.project
|
|
||||||
.idea/
|
|
||||||
*.tmproj
|
|
||||||
.vscode/
|
|
||||||
node_modules/
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
dependencies:
|
|
||||||
- name: postgresql
|
|
||||||
repository: https://charts.bitnami.com/bitnami
|
|
||||||
version: 13.1.5
|
|
||||||
- name: ingress-nginx
|
|
||||||
repository: https://kubernetes.github.io/ingress-nginx
|
|
||||||
version: 4.0.13
|
|
||||||
digest: sha256:e439e4b30ba18357defec97ba080973743a4724c423b78913990409f78f1ebd8
|
|
||||||
generated: "2023-10-20T14:22:57.044126+05:30"
|
|
||||||
@@ -1,34 +0,0 @@
|
|||||||
apiVersion: v2
|
|
||||||
name: trigger
|
|
||||||
description: A Helm chart for a full Trigger application stack
|
|
||||||
|
|
||||||
# A chart can be either an 'application' or a 'library' chart.
|
|
||||||
#
|
|
||||||
# Application charts are a collection of templates that can be packaged into versioned archives
|
|
||||||
# to be deployed.
|
|
||||||
#
|
|
||||||
# Library charts provide useful utilities or functions for the chart developer. They're included as
|
|
||||||
# a dependency of application charts to inject those utilities and functions into the rendering
|
|
||||||
# pipeline. Library charts do not define any templates and therefore cannot be deployed.
|
|
||||||
type: application
|
|
||||||
|
|
||||||
# This is the chart version. This version number should be incremented each time you make changes
|
|
||||||
# to the chart and its templates, including the app version.
|
|
||||||
# Versions are expected to follow Semantic Versioning (https://semver.org/)
|
|
||||||
version: 0.1.0
|
|
||||||
|
|
||||||
# This is the version number of the application being deployed. This version number should be
|
|
||||||
# incremented each time you make changes to the application. Versions are not expected to
|
|
||||||
# follow Semantic Versioning. They should reflect the version the application is using.
|
|
||||||
# It is recommended to use it with quotes.
|
|
||||||
appVersion: "1.16.0"
|
|
||||||
|
|
||||||
dependencies:
|
|
||||||
- name: postgresql
|
|
||||||
version: "~13.1.5"
|
|
||||||
repository: https://charts.bitnami.com/bitnami
|
|
||||||
condition: postgresql.enabled
|
|
||||||
- name: ingress-nginx
|
|
||||||
version: 4.0.13
|
|
||||||
repository: https://kubernetes.github.io/ingress-nginx
|
|
||||||
condition: ingress.nginx.enabled
|
|
||||||
@@ -1,119 +0,0 @@
|
|||||||
# Trigger.dev Helm Chart
|
|
||||||
|
|
||||||
> WARNING: Kubernetes deploys are not officially supported yet, please only use these instructions as a general guide and starting point.
|
|
||||||
|
|
||||||
## Installation
|
|
||||||
|
|
||||||
As our charts aren't published for official use yet, you'll need a copy of the `helm-charts` dir and run the following commands within it:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# with access to your cluster, e.g. KUBECONFIG correctly set
|
|
||||||
helm upgrade --install --atomic --namespace trigger --create-namespace trigger .
|
|
||||||
|
|
||||||
# watch the deployment
|
|
||||||
kubectl --namespace trigger get deployments -w
|
|
||||||
```
|
|
||||||
|
|
||||||
## Parameters
|
|
||||||
|
|
||||||
### Common parameters
|
|
||||||
|
|
||||||
| Name | Description | Value |
|
|
||||||
| ------------------ | ------------------------- | ----- |
|
|
||||||
| `nameOverride` | Override release name | `""` |
|
|
||||||
| `fullnameOverride` | Override release fullname | `""` |
|
|
||||||
|
|
||||||
### Trigger.dev parameters
|
|
||||||
|
|
||||||
| Name | Description | Value |
|
|
||||||
| --------------------------------- | --------------------------------------------------------------------------------------------------------------- | ----------------------------------- |
|
|
||||||
| `trigger.name` | | `trigger` |
|
|
||||||
| `trigger.fullnameOverride` | trigger fullnameOverride | `""` |
|
|
||||||
| `trigger.podAnnotations` | trigger pod annotations | `{}` |
|
|
||||||
| `trigger.deploymentAnnotations` | trigger deployment annotations | `{}` |
|
|
||||||
| `trigger.replicaCount` | trigger replica count | `2` |
|
|
||||||
| `trigger.image.repository` | trigger image repository | `ghcr.io/triggerdotdev/trigger.dev` |
|
|
||||||
| `trigger.image.tag` | trigger image tag | `latest` |
|
|
||||||
| `trigger.image.pullPolicy` | trigger image pullPolicy | `Always` |
|
|
||||||
| `trigger.resources.limits.memory` | container memory limit [(docs)](https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/) | `800Mi` |
|
|
||||||
| `trigger.resources.requests.cpu` | container CPU requests [(docs)](https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/) | `250m` |
|
|
||||||
| `trigger.affinity` | Backend pod affinity | `{}` |
|
|
||||||
| `trigger.kubeSecretRef` | trigger secret resource reference name | `""` |
|
|
||||||
| `trigger.service.annotations` | trigger service annotations | `{}` |
|
|
||||||
| `trigger.service.type` | trigger service type | `ClusterIP` |
|
|
||||||
| `trigger.service.nodePort` | trigger service nodePort (used if above type is `NodePort`) | `""` |
|
|
||||||
|
|
||||||
### Postgres parameters
|
|
||||||
|
|
||||||
| Name | Description | Value |
|
|
||||||
| --------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------------------- |
|
|
||||||
| `postgresql.enabled` | Enable Postgres | `true` |
|
|
||||||
| `postgresql.name` | Name used to build variables (deprecated) | `postgresql` |
|
|
||||||
| `postgresql.nameOverride` | Name override | `postgresql` |
|
|
||||||
| `postgresql.fullnameOverride` | Fullname override | `postgresql` |
|
|
||||||
| `postgresql.global.postgresql.auth.postgresPassword` | Password for the "postgres" admin user (overrides `auth.postgresPassword`) | `password` |
|
|
||||||
| `postgresql.global.postgresql.auth.username` | Name for a custom user to create (overrides `auth.username`) | `postgres` |
|
|
||||||
| `postgresql.global.postgresql.auth.password` | Password for the custom user to create (overrides `auth.password`) | `password` |
|
|
||||||
| `postgresql.global.postgresql.auth.database` | Name for a custom database to create (overrides `auth.database`) | `trigger` |
|
|
||||||
| `postgresql.global.postgresql.auth.existingSecret` | Name of existing secret to use for PostgreSQL credentials (overrides `auth.existingSecret`). | `""` |
|
|
||||||
| `postgresql.global.postgresql.auth.secretKeys.adminPasswordKey` | Name of key in existing secret to use for PostgreSQL credentials (overrides `auth.secretKeys.adminPasswordKey`). Only used when `postgresql.global.postgresql.auth.existingSecret` is set. | `""` |
|
|
||||||
| `postgresql.global.postgresql.auth.secretKeys.userPasswordKey` | Name of key in existing secret to use for PostgreSQL credentials (overrides `auth.secretKeys.userPasswordKey`). Only used when `postgresql.global.postgresql.auth.existingSecret` is set. | `""` |
|
|
||||||
| `postgresql.global.postgresql.auth.secretKeys.replicationPasswordKey` | Name of key in existing secret to use for PostgreSQL credentials (overrides `auth.secretKeys.replicationPasswordKey`). Only used when `postgresql.global.postgresql.auth.existingSecret` is set. | `""` |
|
|
||||||
| `postgresql.global.postgresql.service.ports.postgresql` | PostgreSQL service port (overrides `service.ports.postgresql`) | `5432` |
|
|
||||||
| `postgresql.image.registry` | PostgreSQL image registry | `docker.io` |
|
|
||||||
| `postgresql.image.repository` | PostgreSQL image repository | `bitnami/postgresql` |
|
|
||||||
| `postgresql.image.tag` | PostgreSQL image tag (immutable tags are recommended) | `14.10.0-debian-11-r21` |
|
|
||||||
| `postgresql.image.digest` | PostgreSQL image digest in the way sha256:aa.... Please note this parameter, if set, will override the tag | `""` |
|
|
||||||
| `postgresql.image.pullPolicy` | PostgreSQL image pull policy | `IfNotPresent` |
|
|
||||||
| `postgresql.image.pullSecrets` | Specify image pull secrets | `[]` |
|
|
||||||
| `postgresql.image.debug` | Specify if debug values should be set | `false` |
|
|
||||||
| `postgresql.architecture` | PostgreSQL architecture (`standalone` or `replication`) | `standalone` |
|
|
||||||
| `postgresql.containerPorts.postgresql` | PostgreSQL container port | `5432` |
|
|
||||||
| `postgresql.postgresqlDataDir` | PostgreSQL data dir | `/bitnami/postgresql/data` |
|
|
||||||
| `postgresql.postgresqlSharedPreloadLibraries` | Shared preload libraries (comma-separated list) | `pgaudit` |
|
|
||||||
|
|
||||||
### PostgreSQL Primary parameters
|
|
||||||
|
|
||||||
| Name | Description | Value |
|
|
||||||
| ------------------------------------------------------- | ------------------------------------------------------ | ------------------- |
|
|
||||||
| `postgresql.primary.livenessProbe.enabled` | Enable livenessProbe on PostgreSQL Primary containers | `true` |
|
|
||||||
| `postgresql.primary.livenessProbe.initialDelaySeconds` | Initial delay seconds for livenessProbe | `30` |
|
|
||||||
| `postgresql.primary.livenessProbe.periodSeconds` | Period seconds for livenessProbe | `10` |
|
|
||||||
| `postgresql.primary.livenessProbe.timeoutSeconds` | Timeout seconds for livenessProbe | `5` |
|
|
||||||
| `postgresql.primary.livenessProbe.failureThreshold` | Failure threshold for livenessProbe | `6` |
|
|
||||||
| `postgresql.primary.livenessProbe.successThreshold` | Success threshold for livenessProbe | `1` |
|
|
||||||
| `postgresql.primary.readinessProbe.enabled` | Enable readinessProbe on PostgreSQL Primary containers | `true` |
|
|
||||||
| `postgresql.primary.readinessProbe.initialDelaySeconds` | Initial delay seconds for readinessProbe | `5` |
|
|
||||||
| `postgresql.primary.readinessProbe.periodSeconds` | Period seconds for readinessProbe | `10` |
|
|
||||||
| `postgresql.primary.readinessProbe.timeoutSeconds` | Timeout seconds for readinessProbe | `5` |
|
|
||||||
| `postgresql.primary.readinessProbe.failureThreshold` | Failure threshold for readinessProbe | `6` |
|
|
||||||
| `postgresql.primary.readinessProbe.successThreshold` | Success threshold for readinessProbe | `1` |
|
|
||||||
| `postgresql.primary.startupProbe.enabled` | Enable startupProbe on PostgreSQL Primary containers | `false` |
|
|
||||||
| `postgresql.primary.startupProbe.initialDelaySeconds` | Initial delay seconds for startupProbe | `30` |
|
|
||||||
| `postgresql.primary.startupProbe.periodSeconds` | Period seconds for startupProbe | `10` |
|
|
||||||
| `postgresql.primary.startupProbe.timeoutSeconds` | Timeout seconds for startupProbe | `1` |
|
|
||||||
| `postgresql.primary.startupProbe.failureThreshold` | Failure threshold for startupProbe | `15` |
|
|
||||||
| `postgresql.primary.startupProbe.successThreshold` | Success threshold for startupProbe | `1` |
|
|
||||||
| `postgresql.primary.persistence.enabled` | Enable PostgreSQL Primary data persistence using PVC | `true` |
|
|
||||||
| `postgresql.primary.persistence.existingClaim` | Name of an existing PVC to use | `""` |
|
|
||||||
| `postgresql.primary.persistence.accessModes` | PVC Access Mode for PostgreSQL volume | `["ReadWriteOnce"]` |
|
|
||||||
| `postgresql.primary.persistence.size` | PVC Storage Request for PostgreSQL volume | `8Gi` |
|
|
||||||
|
|
||||||
### Ingress parameters
|
|
||||||
|
|
||||||
| Name | Description | Value |
|
|
||||||
| -------------------------- | ------------------------------------------------------------------------ | -------- |
|
|
||||||
| `ingress.enabled` | Enable ingress | `true` |
|
|
||||||
| `ingress.ingressClassName` | Ingress class name | `nginx` |
|
|
||||||
| `ingress.nginx.enabled` | Ingress controller | `false` |
|
|
||||||
| `ingress.annotations` | Ingress annotations | `{}` |
|
|
||||||
| `ingress.hostName` | Ingress hostname (your custom domain name, e.g. `infisical.example.org`) | `""` |
|
|
||||||
| `ingress.tls` | Ingress TLS hosts (matching above hostName) | `[]` |
|
|
||||||
| `ingress.trigger.path` | Trigger.dev ingress path | `/` |
|
|
||||||
| `ingress.trigger.pathType` | Trigger.dev ingress path type | `Prefix` |
|
|
||||||
|
|
||||||
## Generating docs
|
|
||||||
|
|
||||||
This chart aims to be compliant with the [Readme Generator For Helm](https://github.com/bitnami/readme-generator-for-helm) to easily create and maintain the parameters tables above.
|
|
||||||
|
|
||||||
To update the docs, just run: `pnpm generate-docs`
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
trigger:
|
|
||||||
name: trigger
|
|
||||||
replicaCount: 2
|
|
||||||
image:
|
|
||||||
repository: ghcr.io/triggerdotdev/trigger.dev
|
|
||||||
tag: "latest"
|
|
||||||
pullPolicy: Always
|
|
||||||
env:
|
|
||||||
ENCRYPTION_KEY: "b1ebe43a6a6e24b2aa8fa0707d3890e3"
|
|
||||||
MAGIC_LINK_SECRET: "842727396bcee22da68518f959c5730b"
|
|
||||||
|
|
||||||
ingress:
|
|
||||||
nginx:
|
|
||||||
enabled: false #<-- if you would like to install nginx along with Trigger.dev
|
|
||||||
Generated
-203
@@ -1,203 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "helm-charts",
|
|
||||||
"version": "1.0.0",
|
|
||||||
"lockfileVersion": 3,
|
|
||||||
"requires": true,
|
|
||||||
"packages": {
|
|
||||||
"": {
|
|
||||||
"name": "helm-charts",
|
|
||||||
"version": "1.0.0",
|
|
||||||
"license": "ISC",
|
|
||||||
"dependencies": {
|
|
||||||
"@bitnami/readme-generator-for-helm": "^2.6.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@bitnami/readme-generator-for-helm": {
|
|
||||||
"version": "2.6.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/@bitnami/readme-generator-for-helm/-/readme-generator-for-helm-2.6.0.tgz",
|
|
||||||
"integrity": "sha512-LcByNCryaC2OJExL9rnhyFJ18+vrZu1gVoN2Z7j/HI42EjV4kLgT4G1KEPNnrKbls9HvozBqMG+sKZIDh0McFg==",
|
|
||||||
"dependencies": {
|
|
||||||
"commander": "^7.1.0",
|
|
||||||
"dot-object": "^2.1.4",
|
|
||||||
"lodash": "^4.17.21",
|
|
||||||
"markdown-table": "^2.0.0",
|
|
||||||
"yaml": "^2.0.0-3"
|
|
||||||
},
|
|
||||||
"bin": {
|
|
||||||
"readme-generator": "bin/index.js"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/balanced-match": {
|
|
||||||
"version": "1.0.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
|
|
||||||
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="
|
|
||||||
},
|
|
||||||
"node_modules/brace-expansion": {
|
|
||||||
"version": "1.1.11",
|
|
||||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
|
|
||||||
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
|
|
||||||
"dependencies": {
|
|
||||||
"balanced-match": "^1.0.0",
|
|
||||||
"concat-map": "0.0.1"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/commander": {
|
|
||||||
"version": "7.2.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz",
|
|
||||||
"integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==",
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 10"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/concat-map": {
|
|
||||||
"version": "0.0.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
|
|
||||||
"integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg=="
|
|
||||||
},
|
|
||||||
"node_modules/dot-object": {
|
|
||||||
"version": "2.1.4",
|
|
||||||
"resolved": "https://registry.npmjs.org/dot-object/-/dot-object-2.1.4.tgz",
|
|
||||||
"integrity": "sha512-7FXnyyCLFawNYJ+NhkqyP9Wd2yzuo+7n9pGiYpkmXCTYa8Ci2U0eUNDVg5OuO5Pm6aFXI2SWN8/N/w7SJWu1WA==",
|
|
||||||
"dependencies": {
|
|
||||||
"commander": "^4.0.0",
|
|
||||||
"glob": "^7.1.5"
|
|
||||||
},
|
|
||||||
"bin": {
|
|
||||||
"dot-object": "bin/dot-object"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/dot-object/node_modules/commander": {
|
|
||||||
"version": "4.1.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz",
|
|
||||||
"integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==",
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 6"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/fs.realpath": {
|
|
||||||
"version": "1.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
|
|
||||||
"integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw=="
|
|
||||||
},
|
|
||||||
"node_modules/glob": {
|
|
||||||
"version": "7.2.3",
|
|
||||||
"resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
|
|
||||||
"integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
|
|
||||||
"dependencies": {
|
|
||||||
"fs.realpath": "^1.0.0",
|
|
||||||
"inflight": "^1.0.4",
|
|
||||||
"inherits": "2",
|
|
||||||
"minimatch": "^3.1.1",
|
|
||||||
"once": "^1.3.0",
|
|
||||||
"path-is-absolute": "^1.0.0"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": "*"
|
|
||||||
},
|
|
||||||
"funding": {
|
|
||||||
"url": "https://github.com/sponsors/isaacs"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/inflight": {
|
|
||||||
"version": "1.0.6",
|
|
||||||
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
|
|
||||||
"integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
|
|
||||||
"dependencies": {
|
|
||||||
"once": "^1.3.0",
|
|
||||||
"wrappy": "1"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/inherits": {
|
|
||||||
"version": "2.0.4",
|
|
||||||
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
|
|
||||||
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
|
|
||||||
},
|
|
||||||
"node_modules/lodash": {
|
|
||||||
"version": "4.17.21",
|
|
||||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
|
|
||||||
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
|
|
||||||
},
|
|
||||||
"node_modules/markdown-table": {
|
|
||||||
"version": "2.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-2.0.0.tgz",
|
|
||||||
"integrity": "sha512-Ezda85ToJUBhM6WGaG6veasyym+Tbs3cMAw/ZhOPqXiYsr0jgocBV3j3nx+4lk47plLlIqjwuTm/ywVI+zjJ/A==",
|
|
||||||
"dependencies": {
|
|
||||||
"repeat-string": "^1.0.0"
|
|
||||||
},
|
|
||||||
"funding": {
|
|
||||||
"type": "github",
|
|
||||||
"url": "https://github.com/sponsors/wooorm"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/minimatch": {
|
|
||||||
"version": "3.1.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
|
|
||||||
"integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
|
|
||||||
"dependencies": {
|
|
||||||
"brace-expansion": "^1.1.7"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": "*"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/once": {
|
|
||||||
"version": "1.4.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
|
|
||||||
"integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
|
|
||||||
"dependencies": {
|
|
||||||
"wrappy": "1"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/path-is-absolute": {
|
|
||||||
"version": "1.0.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
|
|
||||||
"integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==",
|
|
||||||
"engines": {
|
|
||||||
"node": ">=0.10.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/repeat-string": {
|
|
||||||
"version": "1.6.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz",
|
|
||||||
"integrity": "sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==",
|
|
||||||
"engines": {
|
|
||||||
"node": ">=0.10"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/wrappy": {
|
|
||||||
"version": "1.0.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
|
|
||||||
"integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="
|
|
||||||
},
|
|
||||||
"node_modules/yaml": {
|
|
||||||
"version": "2.3.4",
|
|
||||||
"resolved": "https://registry.npmjs.org/yaml/-/yaml-2.3.4.tgz",
|
|
||||||
"integrity": "sha512-8aAvwVUSHpfEqTQ4w/KMlf3HcRdt50E5ODIQJBw1fQ5RL34xabzxtUlzTXVqc4rkZsPbvrXKWnABCD7kWSmocA==",
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 14"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"readme-generator-for-helm": {
|
|
||||||
"version": "2.6.1",
|
|
||||||
"extraneous": true,
|
|
||||||
"license": "Apache-2.0",
|
|
||||||
"dependencies": {
|
|
||||||
"commander": "^7.1.0",
|
|
||||||
"dot-object": "^2.1.4",
|
|
||||||
"lodash": "^4.17.21",
|
|
||||||
"markdown-table": "^2.0.0",
|
|
||||||
"yaml": "^2.0.0-3"
|
|
||||||
},
|
|
||||||
"bin": {
|
|
||||||
"readme-generator": "bin/index.js"
|
|
||||||
},
|
|
||||||
"devDependencies": {
|
|
||||||
"eslint": "^7.24.0",
|
|
||||||
"eslint-config-airbnb-base": "^14.2.1",
|
|
||||||
"eslint-plugin-import": "^2.22.1",
|
|
||||||
"jest": "^29.2.1",
|
|
||||||
"temp": "^0.9.4"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "helm-charts",
|
|
||||||
"version": "1.0.0",
|
|
||||||
"description": "",
|
|
||||||
"main": "index.js",
|
|
||||||
"scripts": {
|
|
||||||
"generate-docs": "readme-generator --readme README.md --values values.yaml"
|
|
||||||
},
|
|
||||||
"keywords": [],
|
|
||||||
"author": "",
|
|
||||||
"license": "ISC",
|
|
||||||
"devDependencies": {
|
|
||||||
"@bitnami/readme-generator-for-helm": "^2.6.0"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,71 +0,0 @@
|
|||||||
{{/*
|
|
||||||
Expand the name of the chart.
|
|
||||||
*/}}
|
|
||||||
{{- define "trigger.name" -}}
|
|
||||||
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
|
|
||||||
{{- end }}
|
|
||||||
|
|
||||||
{{/*
|
|
||||||
Create chart name and version as used by the chart label.
|
|
||||||
*/}}
|
|
||||||
{{- define "trigger.chart" -}}
|
|
||||||
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}}
|
|
||||||
{{- end -}}
|
|
||||||
|
|
||||||
{{/*
|
|
||||||
Create unified labels for trigger components
|
|
||||||
*/}}
|
|
||||||
{{- define "trigger.common.matchLabels" -}}
|
|
||||||
app: {{ template "trigger.name" . }}
|
|
||||||
release: {{ .Release.Name }}
|
|
||||||
{{- end -}}
|
|
||||||
|
|
||||||
{{- define "trigger.common.metaLabels" -}}
|
|
||||||
chart: {{ template "trigger.chart" . }}
|
|
||||||
heritage: {{ .Release.Service }}
|
|
||||||
{{- end -}}
|
|
||||||
|
|
||||||
{{- define "trigger.common.labels" -}}
|
|
||||||
{{ include "trigger.common.matchLabels" . }}
|
|
||||||
{{ include "trigger.common.metaLabels" . }}
|
|
||||||
{{- end -}}
|
|
||||||
|
|
||||||
{{- define "trigger.labels" -}}
|
|
||||||
{{ include "trigger.matchLabels" . }}
|
|
||||||
{{ include "trigger.common.metaLabels" . }}
|
|
||||||
{{- end -}}
|
|
||||||
|
|
||||||
{{- define "trigger.matchLabels" -}}
|
|
||||||
component: {{ .Values.trigger.name | quote }}
|
|
||||||
{{ include "trigger.common.matchLabels" . }}
|
|
||||||
{{- end -}}
|
|
||||||
|
|
||||||
{{/*
|
|
||||||
Create a fully qualified postgresql name.
|
|
||||||
We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
|
|
||||||
*/}}
|
|
||||||
{{- define "trigger.postgresql.hostname" -}}
|
|
||||||
{{- if .Values.postgresql.fullnameOverride -}}
|
|
||||||
{{- .Values.postgresql.fullnameOverride | trunc 63 | trimSuffix "-" -}}
|
|
||||||
{{- else -}}
|
|
||||||
{{- $name := default .Chart.Name .Values.nameOverride -}}
|
|
||||||
{{- if contains $name .Release.Name -}}
|
|
||||||
{{- printf "%s-%s" .Release.Name .Values.postgresql.name | trunc 63 | trimSuffix "-" -}}
|
|
||||||
{{- else -}}
|
|
||||||
{{- printf "%s-%s-%s" .Release.Name $name .Values.postgresql.name | trunc 63 | trimSuffix "-" -}}
|
|
||||||
{{- end -}}
|
|
||||||
{{- end -}}
|
|
||||||
{{- end -}}
|
|
||||||
|
|
||||||
{{/*
|
|
||||||
Create the postgresql connection string.
|
|
||||||
*/}}
|
|
||||||
{{- define "trigger.postgresql.connectionString" -}}
|
|
||||||
{{- $host := include "trigger.postgresql.hostname" . -}}
|
|
||||||
{{- $port := 5432 -}}
|
|
||||||
{{- $username := .Values.postgresql.global.postgresql.postgresqlUsername | default "postgres" -}}
|
|
||||||
{{- $password := .Values.postgresql.global.postgresql.postgresqlPassword | default "password" -}}
|
|
||||||
{{- $database := .Values.postgresql.global.postgresql.postgresqlDatabase | default "trigger" -}}
|
|
||||||
{{- $connectionString := printf "postgresql://%s:%s@%s:%d/%s" $username $password $host $port $database -}}
|
|
||||||
{{- printf "%s" $connectionString -}}
|
|
||||||
{{- end -}}
|
|
||||||
@@ -1,43 +0,0 @@
|
|||||||
{{ if .Values.ingress.enabled }}
|
|
||||||
{{- $ingress := .Values.ingress }}
|
|
||||||
{{- if and $ingress.ingressClassName (not (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion)) }}
|
|
||||||
{{- if not (hasKey $ingress.annotations "kubernetes.io/ingress.class") }}
|
|
||||||
{{- $_ := set $ingress.annotations "kubernetes.io/ingress.class" $ingress.ingressClassName}}
|
|
||||||
{{- end }}
|
|
||||||
{{- end }}
|
|
||||||
apiVersion: networking.k8s.io/v1
|
|
||||||
kind: Ingress
|
|
||||||
metadata:
|
|
||||||
name: trigger-ingress
|
|
||||||
{{- with $ingress.annotations }}
|
|
||||||
annotations:
|
|
||||||
{{- toYaml . | nindent 4 }}
|
|
||||||
{{- end }}
|
|
||||||
spec:
|
|
||||||
{{- if and $ingress.ingressClassName (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion) }}
|
|
||||||
ingressClassName: {{ $ingress.ingressClassName | default "nginx" }}
|
|
||||||
{{- end }}
|
|
||||||
{{- if $ingress.tls }}
|
|
||||||
tls:
|
|
||||||
{{- range $ingress.tls }}
|
|
||||||
- hosts:
|
|
||||||
{{- range .hosts }}
|
|
||||||
- {{ . | quote }}
|
|
||||||
{{- end }}
|
|
||||||
secretName: {{ .secretName }}
|
|
||||||
{{- end }}
|
|
||||||
{{- end }}
|
|
||||||
rules:
|
|
||||||
- http:
|
|
||||||
paths:
|
|
||||||
- path: {{ $ingress.trigger.path }}
|
|
||||||
pathType: {{ $ingress.trigger.pathType }}
|
|
||||||
backend:
|
|
||||||
service:
|
|
||||||
name: {{ include "trigger.name" . }}
|
|
||||||
port:
|
|
||||||
number: 3000
|
|
||||||
{{- if $ingress.hostName }}
|
|
||||||
host: {{ $ingress.hostName }}
|
|
||||||
{{- end }}
|
|
||||||
{{ end }}
|
|
||||||
@@ -1,98 +0,0 @@
|
|||||||
{{- $trigger := .Values.trigger -}}
|
|
||||||
apiVersion: apps/v1
|
|
||||||
kind: Deployment
|
|
||||||
metadata:
|
|
||||||
name: {{ include "trigger.name" . }}
|
|
||||||
annotations:
|
|
||||||
updatedAt: {{ now | date "2006-01-01 MST 15:04:05" | quote }}
|
|
||||||
{{- with $trigger.deploymentAnnotations }}
|
|
||||||
{{- toYaml . | nindent 4 }}
|
|
||||||
{{- end }}
|
|
||||||
labels:
|
|
||||||
{{- include "trigger.labels" . | nindent 4 }}
|
|
||||||
spec:
|
|
||||||
replicas: {{ $trigger.replicaCount }}
|
|
||||||
selector:
|
|
||||||
matchLabels:
|
|
||||||
{{- include "trigger.matchLabels" . | nindent 6 }}
|
|
||||||
template:
|
|
||||||
metadata:
|
|
||||||
labels:
|
|
||||||
{{- include "trigger.matchLabels" . | nindent 8 }}
|
|
||||||
annotations:
|
|
||||||
updatedAt: {{ now | date "2006-01-01 MST 15:04:05" | quote }}
|
|
||||||
{{- with $trigger.podAnnotations }}
|
|
||||||
{{- toYaml . | nindent 8 }}
|
|
||||||
{{- end }}
|
|
||||||
spec:
|
|
||||||
{{- with $trigger.affinity }}
|
|
||||||
affinity:
|
|
||||||
{{- toYaml . | nindent 8 }}
|
|
||||||
{{- end }}
|
|
||||||
containers:
|
|
||||||
- name: {{ $trigger.name }}
|
|
||||||
image: "{{ $trigger.image.repository }}:{{ $trigger.image.tag | default "latest" }}"
|
|
||||||
imagePullPolicy: {{ $trigger.image.pullPolicy }}
|
|
||||||
ports:
|
|
||||||
- name: http
|
|
||||||
containerPort: 3000
|
|
||||||
protocol: TCP
|
|
||||||
readinessProbe:
|
|
||||||
httpGet:
|
|
||||||
path: /
|
|
||||||
port: 3000
|
|
||||||
envFrom:
|
|
||||||
- secretRef:
|
|
||||||
name: {{ $trigger.kubeSecretRef | default (include "trigger.name" .) }}
|
|
||||||
{{- if $trigger.resources }}
|
|
||||||
resources: {{- toYaml $trigger.resources | nindent 12 }}
|
|
||||||
{{- end }}
|
|
||||||
---
|
|
||||||
|
|
||||||
apiVersion: v1
|
|
||||||
kind: Service
|
|
||||||
metadata:
|
|
||||||
name: {{ include "trigger.name" . }}
|
|
||||||
labels:
|
|
||||||
{{- include "trigger.labels" . | nindent 4 }}
|
|
||||||
{{- with $trigger.service.annotations }}
|
|
||||||
annotations:
|
|
||||||
{{- toYaml . | nindent 4 }}
|
|
||||||
{{- end }}
|
|
||||||
spec:
|
|
||||||
type: {{ $trigger.service.type }}
|
|
||||||
selector:
|
|
||||||
{{- include "trigger.matchLabels" . | nindent 8 }}
|
|
||||||
ports:
|
|
||||||
- port: 3000
|
|
||||||
targetPort: 3000
|
|
||||||
protocol: TCP
|
|
||||||
{{- if eq $trigger.service.type "NodePort" }}
|
|
||||||
nodePort: {{ $trigger.service.nodePort }}
|
|
||||||
{{- end }}
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
{{ if not $trigger.kubeSecretRef }}
|
|
||||||
apiVersion: v1
|
|
||||||
kind: Secret
|
|
||||||
metadata:
|
|
||||||
name: {{ include "trigger.name" . }}
|
|
||||||
annotations:
|
|
||||||
"helm.sh/resource-policy": "keep"
|
|
||||||
type: Opaque
|
|
||||||
stringData:
|
|
||||||
{{- $requiredVars := dict "MAGIC_LINK_SECRET" (randAlphaNum 32 | lower)
|
|
||||||
"SESSION_SECRET" (randAlphaNum 32 | lower)
|
|
||||||
"ENCRYPTION_KEY" (randAlphaNum 32 | lower)
|
|
||||||
"DIRECT_URL" (include "trigger.postgresql.connectionString" .)
|
|
||||||
"DATABASE_URL" (include "trigger.postgresql.connectionString" .) }}
|
|
||||||
{{- $secretObj := (lookup "v1" "Secret" .Release.Namespace (include "trigger.name" .)) | default dict }}
|
|
||||||
{{- $secretData := (get $secretObj "data") | default dict }}
|
|
||||||
{{ range $key, $value := .Values.trigger.env }}
|
|
||||||
{{- $default := get $requiredVars $key -}}
|
|
||||||
{{- $current := get $secretData $key | b64dec -}}
|
|
||||||
{{- $v := $value | default ($current | default $default) -}}
|
|
||||||
{{ $key }}: {{ $v | quote }}
|
|
||||||
{{ end -}}
|
|
||||||
{{- end }}
|
|
||||||
@@ -1,276 +0,0 @@
|
|||||||
# Default values for helm-charts.
|
|
||||||
# This is a YAML-formatted file.
|
|
||||||
## @section Common parameters
|
|
||||||
##
|
|
||||||
|
|
||||||
## @param nameOverride Override release name
|
|
||||||
##
|
|
||||||
nameOverride: ""
|
|
||||||
## @param fullnameOverride Override release fullname
|
|
||||||
##
|
|
||||||
fullnameOverride: ""
|
|
||||||
|
|
||||||
## @section Trigger.dev parameters
|
|
||||||
##
|
|
||||||
trigger:
|
|
||||||
## @param trigger.name
|
|
||||||
name: trigger
|
|
||||||
## @param trigger.fullnameOverride trigger fullnameOverride
|
|
||||||
##
|
|
||||||
fullnameOverride: ""
|
|
||||||
## @param trigger.podAnnotations trigger pod annotations
|
|
||||||
##
|
|
||||||
podAnnotations: {}
|
|
||||||
## @param trigger.deploymentAnnotations trigger deployment annotations
|
|
||||||
##
|
|
||||||
deploymentAnnotations: {}
|
|
||||||
## @param trigger.replicaCount trigger replica count
|
|
||||||
##
|
|
||||||
replicaCount: 2
|
|
||||||
## trigger image parameters
|
|
||||||
##
|
|
||||||
image:
|
|
||||||
## @param trigger.image.repository trigger image repository
|
|
||||||
##
|
|
||||||
repository: ghcr.io/triggerdotdev/trigger.dev
|
|
||||||
## @param trigger.image.tag trigger image tag
|
|
||||||
##
|
|
||||||
tag: "latest"
|
|
||||||
## @param trigger.image.pullPolicy trigger image pullPolicy
|
|
||||||
##
|
|
||||||
pullPolicy: Always
|
|
||||||
## @param trigger.resources.limits.memory container memory limit [(docs)](https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/)
|
|
||||||
## @param trigger.resources.requests.cpu container CPU requests [(docs)](https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/)
|
|
||||||
##
|
|
||||||
resources:
|
|
||||||
limits:
|
|
||||||
memory: 800Mi
|
|
||||||
requests:
|
|
||||||
cpu: 250m
|
|
||||||
## @param trigger.affinity Backend pod affinity
|
|
||||||
##
|
|
||||||
affinity: {}
|
|
||||||
## @param trigger.kubeSecretRef trigger secret resource reference name
|
|
||||||
##
|
|
||||||
kubeSecretRef: ""
|
|
||||||
## trigger service
|
|
||||||
##
|
|
||||||
service:
|
|
||||||
## @param trigger.service.annotations trigger service annotations
|
|
||||||
##
|
|
||||||
annotations: {}
|
|
||||||
## @param trigger.service.type trigger service type
|
|
||||||
##
|
|
||||||
type: ClusterIP
|
|
||||||
## @param trigger.service.nodePort trigger service nodePort (used if above type is `NodePort`)
|
|
||||||
##
|
|
||||||
nodePort: ""
|
|
||||||
## @skip trigger.env
|
|
||||||
##
|
|
||||||
env:
|
|
||||||
ENCRYPTION_KEY: ""
|
|
||||||
MAGIC_LINK_SECRET: ""
|
|
||||||
SESSION_SECRET: ""
|
|
||||||
LOGIN_ORIGIN: ""
|
|
||||||
APP_ORIGIN: ""
|
|
||||||
DIRECT_URL: ""
|
|
||||||
DATABASE_URL: ""
|
|
||||||
FROM_EMAIL: ""
|
|
||||||
REPLY_TO_EMAIL: ""
|
|
||||||
RESEND_API_KEY: ""
|
|
||||||
AUTH_GITHUB_CLIENT_ID: ""
|
|
||||||
AUTH_GITHUB_CLIENT_SECRET: ""
|
|
||||||
|
|
||||||
## @section Postgres parameters
|
|
||||||
## Documentation: https://github.com/bitnami/charts/tree/main/bitnami/postgresql-ha
|
|
||||||
##
|
|
||||||
postgresql:
|
|
||||||
## @param postgresql.enabled Enable Postgres
|
|
||||||
##
|
|
||||||
enabled: true
|
|
||||||
## @param postgresql.name Name used to build variables (deprecated)
|
|
||||||
##
|
|
||||||
name: "postgresql"
|
|
||||||
## @param postgresql.nameOverride Name override
|
|
||||||
##
|
|
||||||
nameOverride: "postgresql"
|
|
||||||
## @param postgresql.fullnameOverride Fullname override
|
|
||||||
##
|
|
||||||
fullnameOverride: "postgresql"
|
|
||||||
|
|
||||||
global:
|
|
||||||
postgresql:
|
|
||||||
## @param postgresql.global.postgresql.auth.postgresPassword Password for the "postgres" admin user (overrides `auth.postgresPassword`)
|
|
||||||
## @param postgresql.global.postgresql.auth.username Name for a custom user to create (overrides `auth.username`)
|
|
||||||
## @param postgresql.global.postgresql.auth.password Password for the custom user to create (overrides `auth.password`)
|
|
||||||
## @param postgresql.global.postgresql.auth.database Name for a custom database to create (overrides `auth.database`)
|
|
||||||
## @param postgresql.global.postgresql.auth.existingSecret Name of existing secret to use for PostgreSQL credentials (overrides `auth.existingSecret`).
|
|
||||||
## @param postgresql.global.postgresql.auth.secretKeys.adminPasswordKey Name of key in existing secret to use for PostgreSQL credentials (overrides `auth.secretKeys.adminPasswordKey`). Only used when `postgresql.global.postgresql.auth.existingSecret` is set.
|
|
||||||
## @param postgresql.global.postgresql.auth.secretKeys.userPasswordKey Name of key in existing secret to use for PostgreSQL credentials (overrides `auth.secretKeys.userPasswordKey`). Only used when `postgresql.global.postgresql.auth.existingSecret` is set.
|
|
||||||
## @param postgresql.global.postgresql.auth.secretKeys.replicationPasswordKey Name of key in existing secret to use for PostgreSQL credentials (overrides `auth.secretKeys.replicationPasswordKey`). Only used when `postgresql.global.postgresql.auth.existingSecret` is set.
|
|
||||||
##
|
|
||||||
auth:
|
|
||||||
postgresPassword: "password"
|
|
||||||
username: "postgres"
|
|
||||||
password: "password"
|
|
||||||
database: "trigger"
|
|
||||||
existingSecret: ""
|
|
||||||
secretKeys:
|
|
||||||
adminPasswordKey: ""
|
|
||||||
userPasswordKey: ""
|
|
||||||
replicationPasswordKey: ""
|
|
||||||
## @param postgresql.global.postgresql.service.ports.postgresql PostgreSQL service port (overrides `service.ports.postgresql`)
|
|
||||||
##
|
|
||||||
service:
|
|
||||||
ports:
|
|
||||||
postgresql: "5432"
|
|
||||||
|
|
||||||
## Bitnami PostgreSQL image version
|
|
||||||
## ref: https://hub.docker.com/r/bitnami/postgresql/tags/
|
|
||||||
## @param postgresql.image.registry PostgreSQL image registry
|
|
||||||
## @param postgresql.image.repository PostgreSQL image repository
|
|
||||||
## @param postgresql.image.tag PostgreSQL image tag (immutable tags are recommended)
|
|
||||||
## @param postgresql.image.digest PostgreSQL image digest in the way sha256:aa.... Please note this parameter, if set, will override the tag
|
|
||||||
## @param postgresql.image.pullPolicy PostgreSQL image pull policy
|
|
||||||
## @param postgresql.image.pullSecrets Specify image pull secrets
|
|
||||||
## @param postgresql.image.debug Specify if debug values should be set
|
|
||||||
##
|
|
||||||
image:
|
|
||||||
registry: docker.io
|
|
||||||
repository: bitnami/postgresql
|
|
||||||
tag: 14.10.0-debian-11-r21
|
|
||||||
digest: ""
|
|
||||||
## Specify a imagePullPolicy
|
|
||||||
## Defaults to 'Always' if image tag is 'latest', else set to 'IfNotPresent'
|
|
||||||
## ref: https://kubernetes.io/docs/user-guide/images/#pre-pulling-images
|
|
||||||
##
|
|
||||||
pullPolicy: IfNotPresent
|
|
||||||
## Optionally specify an array of imagePullSecrets.
|
|
||||||
## Secrets must be manually created in the namespace.
|
|
||||||
## ref: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/
|
|
||||||
## Example:
|
|
||||||
## pullSecrets:
|
|
||||||
## - myRegistryKeySecretName
|
|
||||||
##
|
|
||||||
pullSecrets: []
|
|
||||||
## Set to true if you would like to see extra information on logs
|
|
||||||
##
|
|
||||||
debug: false
|
|
||||||
|
|
||||||
## @param postgresql.architecture PostgreSQL architecture (`standalone` or `replication`)
|
|
||||||
##
|
|
||||||
architecture: standalone
|
|
||||||
## Replication configuration
|
|
||||||
## Ignored if `postgresql.architecture` is `standalone`
|
|
||||||
##
|
|
||||||
## @param postgresql.containerPorts.postgresql PostgreSQL container port
|
|
||||||
##
|
|
||||||
containerPorts:
|
|
||||||
postgresql: 5432
|
|
||||||
|
|
||||||
## @param postgresql.postgresqlDataDir PostgreSQL data dir
|
|
||||||
##
|
|
||||||
postgresqlDataDir: /bitnami/postgresql/data
|
|
||||||
## @param postgresql.postgresqlSharedPreloadLibraries Shared preload libraries (comma-separated list)
|
|
||||||
##
|
|
||||||
postgresqlSharedPreloadLibraries: "pgaudit"
|
|
||||||
## @section PostgreSQL Primary parameters
|
|
||||||
##
|
|
||||||
primary:
|
|
||||||
## Configure extra options for PostgreSQL Primary containers' liveness, readiness and startup probes
|
|
||||||
## ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/#configure-probes
|
|
||||||
## @param postgresql.primary.livenessProbe.enabled Enable livenessProbe on PostgreSQL Primary containers
|
|
||||||
## @param postgresql.primary.livenessProbe.initialDelaySeconds Initial delay seconds for livenessProbe
|
|
||||||
## @param postgresql.primary.livenessProbe.periodSeconds Period seconds for livenessProbe
|
|
||||||
## @param postgresql.primary.livenessProbe.timeoutSeconds Timeout seconds for livenessProbe
|
|
||||||
## @param postgresql.primary.livenessProbe.failureThreshold Failure threshold for livenessProbe
|
|
||||||
## @param postgresql.primary.livenessProbe.successThreshold Success threshold for livenessProbe
|
|
||||||
##
|
|
||||||
livenessProbe:
|
|
||||||
enabled: true
|
|
||||||
initialDelaySeconds: 30
|
|
||||||
periodSeconds: 10
|
|
||||||
timeoutSeconds: 5
|
|
||||||
failureThreshold: 6
|
|
||||||
successThreshold: 1
|
|
||||||
## @param postgresql.primary.readinessProbe.enabled Enable readinessProbe on PostgreSQL Primary containers
|
|
||||||
## @param postgresql.primary.readinessProbe.initialDelaySeconds Initial delay seconds for readinessProbe
|
|
||||||
## @param postgresql.primary.readinessProbe.periodSeconds Period seconds for readinessProbe
|
|
||||||
## @param postgresql.primary.readinessProbe.timeoutSeconds Timeout seconds for readinessProbe
|
|
||||||
## @param postgresql.primary.readinessProbe.failureThreshold Failure threshold for readinessProbe
|
|
||||||
## @param postgresql.primary.readinessProbe.successThreshold Success threshold for readinessProbe
|
|
||||||
##
|
|
||||||
readinessProbe:
|
|
||||||
enabled: true
|
|
||||||
initialDelaySeconds: 5
|
|
||||||
periodSeconds: 10
|
|
||||||
timeoutSeconds: 5
|
|
||||||
failureThreshold: 6
|
|
||||||
successThreshold: 1
|
|
||||||
## @param postgresql.primary.startupProbe.enabled Enable startupProbe on PostgreSQL Primary containers
|
|
||||||
## @param postgresql.primary.startupProbe.initialDelaySeconds Initial delay seconds for startupProbe
|
|
||||||
## @param postgresql.primary.startupProbe.periodSeconds Period seconds for startupProbe
|
|
||||||
## @param postgresql.primary.startupProbe.timeoutSeconds Timeout seconds for startupProbe
|
|
||||||
## @param postgresql.primary.startupProbe.failureThreshold Failure threshold for startupProbe
|
|
||||||
## @param postgresql.primary.startupProbe.successThreshold Success threshold for startupProbe
|
|
||||||
##
|
|
||||||
startupProbe:
|
|
||||||
enabled: false
|
|
||||||
initialDelaySeconds: 30
|
|
||||||
periodSeconds: 10
|
|
||||||
timeoutSeconds: 1
|
|
||||||
failureThreshold: 15
|
|
||||||
successThreshold: 1
|
|
||||||
persistence:
|
|
||||||
## @param postgresql.primary.persistence.enabled Enable PostgreSQL Primary data persistence using PVC
|
|
||||||
##
|
|
||||||
enabled: true
|
|
||||||
## @param postgresql.primary.persistence.existingClaim Name of an existing PVC to use
|
|
||||||
##
|
|
||||||
existingClaim: ""
|
|
||||||
## @param postgresql.primary.persistence.accessModes PVC Access Mode for PostgreSQL volume
|
|
||||||
##
|
|
||||||
accessModes:
|
|
||||||
- ReadWriteOnce
|
|
||||||
## @param postgresql.primary.persistence.size PVC Storage Request for PostgreSQL volume
|
|
||||||
##
|
|
||||||
size: 8Gi
|
|
||||||
|
|
||||||
## @section Ingress parameters
|
|
||||||
## Documentation: https://kubernetes.io/docs/concepts/services-networking/ingress/
|
|
||||||
##
|
|
||||||
ingress:
|
|
||||||
## @param ingress.enabled Enable ingress
|
|
||||||
##
|
|
||||||
enabled: true
|
|
||||||
## @param ingress.ingressClassName Ingress class name
|
|
||||||
##
|
|
||||||
ingressClassName: nginx
|
|
||||||
## @param ingress.nginx.enabled Ingress controller
|
|
||||||
##
|
|
||||||
nginx:
|
|
||||||
enabled: false
|
|
||||||
## @param ingress.annotations Ingress annotations
|
|
||||||
##
|
|
||||||
annotations:
|
|
||||||
{}
|
|
||||||
# kubernetes.io/ingress.class: "nginx"
|
|
||||||
# cert-manager.io/issuer: letsencrypt-nginx
|
|
||||||
## @param ingress.hostName Ingress hostname (your custom domain name, e.g. `infisical.example.org`)
|
|
||||||
## Replace with your own domain
|
|
||||||
##
|
|
||||||
hostName: ""
|
|
||||||
## @param ingress.tls Ingress TLS hosts (matching above hostName)
|
|
||||||
## Replace with your own domain
|
|
||||||
##
|
|
||||||
tls:
|
|
||||||
[]
|
|
||||||
# - secretName: letsencrypt-nginx
|
|
||||||
# hosts:
|
|
||||||
# - infisical.local
|
|
||||||
## @param ingress.trigger.path Trigger.dev ingress path
|
|
||||||
## @param ingress.trigger.pathType Trigger.dev ingress path type
|
|
||||||
##
|
|
||||||
trigger:
|
|
||||||
path: /
|
|
||||||
pathType: Prefix
|
|
||||||
@@ -1,790 +0,0 @@
|
|||||||
# @trigger.dev/airtable
|
|
||||||
|
|
||||||
## 3.0.0-beta.55
|
|
||||||
|
|
||||||
### Patch Changes
|
|
||||||
|
|
||||||
- Updated dependencies [0591db5f2]
|
|
||||||
- @trigger.dev/sdk@3.0.0-beta.55
|
|
||||||
- @trigger.dev/integration-kit@3.0.0-beta.55
|
|
||||||
|
|
||||||
## 3.0.0-beta.54
|
|
||||||
|
|
||||||
### Patch Changes
|
|
||||||
|
|
||||||
- Updated dependencies [728eeeff6]
|
|
||||||
- @trigger.dev/sdk@3.0.0-beta.54
|
|
||||||
- @trigger.dev/integration-kit@3.0.0-beta.54
|
|
||||||
|
|
||||||
## 3.0.0-beta.53
|
|
||||||
|
|
||||||
### Patch Changes
|
|
||||||
|
|
||||||
- @trigger.dev/integration-kit@3.0.0-beta.53
|
|
||||||
- @trigger.dev/sdk@3.0.0-beta.53
|
|
||||||
|
|
||||||
## 3.0.0-beta.52
|
|
||||||
|
|
||||||
### Patch Changes
|
|
||||||
|
|
||||||
- Updated dependencies [8cae1d087]
|
|
||||||
- @trigger.dev/sdk@3.0.0-beta.52
|
|
||||||
- @trigger.dev/integration-kit@3.0.0-beta.52
|
|
||||||
|
|
||||||
## 3.0.0-beta.51
|
|
||||||
|
|
||||||
### Patch Changes
|
|
||||||
|
|
||||||
- Updated dependencies [979bee50d]
|
|
||||||
- Updated dependencies [086a0f95c]
|
|
||||||
- Updated dependencies [55264657d]
|
|
||||||
- @trigger.dev/sdk@3.0.0-beta.51
|
|
||||||
- @trigger.dev/integration-kit@3.0.0-beta.51
|
|
||||||
|
|
||||||
## 3.0.0-beta.50
|
|
||||||
|
|
||||||
### Patch Changes
|
|
||||||
|
|
||||||
- Updated dependencies [8ba998794]
|
|
||||||
- @trigger.dev/sdk@3.0.0-beta.50
|
|
||||||
- @trigger.dev/integration-kit@3.0.0-beta.50
|
|
||||||
|
|
||||||
## 3.0.0-beta.49
|
|
||||||
|
|
||||||
### Patch Changes
|
|
||||||
|
|
||||||
- @trigger.dev/integration-kit@3.0.0-beta.49
|
|
||||||
- @trigger.dev/sdk@3.0.0-beta.49
|
|
||||||
|
|
||||||
## 3.0.0-beta.48
|
|
||||||
|
|
||||||
### Patch Changes
|
|
||||||
|
|
||||||
- Updated dependencies [ecf1110ab]
|
|
||||||
- @trigger.dev/sdk@3.0.0-beta.48
|
|
||||||
- @trigger.dev/integration-kit@3.0.0-beta.48
|
|
||||||
|
|
||||||
## 3.0.0-beta.47
|
|
||||||
|
|
||||||
### Patch Changes
|
|
||||||
|
|
||||||
- Updated dependencies [4f95c9de4]
|
|
||||||
- @trigger.dev/sdk@3.0.0-beta.47
|
|
||||||
- @trigger.dev/integration-kit@3.0.0-beta.47
|
|
||||||
|
|
||||||
## 3.0.0-beta.46
|
|
||||||
|
|
||||||
### Patch Changes
|
|
||||||
|
|
||||||
- @trigger.dev/integration-kit@3.0.0-beta.46
|
|
||||||
- @trigger.dev/sdk@3.0.0-beta.46
|
|
||||||
|
|
||||||
## 3.0.0-beta.45
|
|
||||||
|
|
||||||
### Patch Changes
|
|
||||||
|
|
||||||
- Updated dependencies [0e77e7ef7]
|
|
||||||
- @trigger.dev/sdk@3.0.0-beta.45
|
|
||||||
- @trigger.dev/integration-kit@3.0.0-beta.45
|
|
||||||
|
|
||||||
## 3.0.0-beta.44
|
|
||||||
|
|
||||||
### Patch Changes
|
|
||||||
|
|
||||||
- @trigger.dev/integration-kit@3.0.0-beta.44
|
|
||||||
- @trigger.dev/sdk@3.0.0-beta.44
|
|
||||||
|
|
||||||
## 3.0.0-beta.43
|
|
||||||
|
|
||||||
### Patch Changes
|
|
||||||
|
|
||||||
- Updated dependencies [34ca7667d]
|
|
||||||
- @trigger.dev/sdk@3.0.0-beta.43
|
|
||||||
- @trigger.dev/integration-kit@3.0.0-beta.43
|
|
||||||
|
|
||||||
## 3.0.0-beta.42
|
|
||||||
|
|
||||||
### Patch Changes
|
|
||||||
|
|
||||||
- Updated dependencies [ecef19966]
|
|
||||||
- @trigger.dev/sdk@3.0.0-beta.42
|
|
||||||
- @trigger.dev/integration-kit@3.0.0-beta.42
|
|
||||||
|
|
||||||
## 3.0.0-beta.41
|
|
||||||
|
|
||||||
### Patch Changes
|
|
||||||
|
|
||||||
- Updated dependencies [7c36a1a4b]
|
|
||||||
- @trigger.dev/sdk@3.0.0-beta.41
|
|
||||||
- @trigger.dev/integration-kit@3.0.0-beta.41
|
|
||||||
|
|
||||||
## 3.0.0-beta.40
|
|
||||||
|
|
||||||
### Patch Changes
|
|
||||||
|
|
||||||
- @trigger.dev/integration-kit@3.0.0-beta.40
|
|
||||||
- @trigger.dev/sdk@3.0.0-beta.40
|
|
||||||
|
|
||||||
## 3.0.0-beta.39
|
|
||||||
|
|
||||||
### Patch Changes
|
|
||||||
|
|
||||||
- @trigger.dev/integration-kit@3.0.0-beta.39
|
|
||||||
- @trigger.dev/sdk@3.0.0-beta.39
|
|
||||||
|
|
||||||
## 3.0.0-beta.38
|
|
||||||
|
|
||||||
### Patch Changes
|
|
||||||
|
|
||||||
- Updated dependencies [1b90ffbb8]
|
|
||||||
- Updated dependencies [c405ae711]
|
|
||||||
- @trigger.dev/sdk@3.0.0-beta.38
|
|
||||||
- @trigger.dev/integration-kit@3.0.0-beta.38
|
|
||||||
|
|
||||||
## 3.0.0-beta.37
|
|
||||||
|
|
||||||
### Patch Changes
|
|
||||||
|
|
||||||
- @trigger.dev/integration-kit@3.0.0-beta.37
|
|
||||||
- @trigger.dev/sdk@3.0.0-beta.37
|
|
||||||
|
|
||||||
## 3.0.0-beta.36
|
|
||||||
|
|
||||||
### Patch Changes
|
|
||||||
|
|
||||||
- Updated dependencies [51bb4c887]
|
|
||||||
- Updated dependencies [ba71f959e]
|
|
||||||
- @trigger.dev/sdk@3.0.0-beta.36
|
|
||||||
- @trigger.dev/integration-kit@3.0.0-beta.36
|
|
||||||
|
|
||||||
## 3.0.0-beta.35
|
|
||||||
|
|
||||||
### Patch Changes
|
|
||||||
|
|
||||||
- @trigger.dev/integration-kit@3.0.0-beta.35
|
|
||||||
- @trigger.dev/sdk@3.0.0-beta.35
|
|
||||||
|
|
||||||
## 3.0.0-beta.34
|
|
||||||
|
|
||||||
### Patch Changes
|
|
||||||
|
|
||||||
- Updated dependencies [3a1b0c486]
|
|
||||||
- Updated dependencies [3f8b6d8fc]
|
|
||||||
- Updated dependencies [1281d40e4]
|
|
||||||
- @trigger.dev/sdk@3.0.0-beta.34
|
|
||||||
- @trigger.dev/integration-kit@3.0.0-beta.34
|
|
||||||
|
|
||||||
## 3.0.0-beta.33
|
|
||||||
|
|
||||||
### Patch Changes
|
|
||||||
|
|
||||||
- @trigger.dev/integration-kit@3.0.0-beta.33
|
|
||||||
- @trigger.dev/sdk@3.0.0-beta.33
|
|
||||||
|
|
||||||
## 3.0.0-beta.32
|
|
||||||
|
|
||||||
### Patch Changes
|
|
||||||
|
|
||||||
- @trigger.dev/integration-kit@3.0.0-beta.32
|
|
||||||
- @trigger.dev/sdk@3.0.0-beta.32
|
|
||||||
|
|
||||||
## 3.0.0-beta.31
|
|
||||||
|
|
||||||
### Patch Changes
|
|
||||||
|
|
||||||
- @trigger.dev/integration-kit@3.0.0-beta.31
|
|
||||||
- @trigger.dev/sdk@3.0.0-beta.31
|
|
||||||
|
|
||||||
## 3.0.0-beta.30
|
|
||||||
|
|
||||||
### Patch Changes
|
|
||||||
|
|
||||||
- @trigger.dev/integration-kit@3.0.0-beta.30
|
|
||||||
- @trigger.dev/sdk@3.0.0-beta.30
|
|
||||||
|
|
||||||
## 3.0.0-beta.29
|
|
||||||
|
|
||||||
### Patch Changes
|
|
||||||
|
|
||||||
- @trigger.dev/integration-kit@3.0.0-beta.29
|
|
||||||
- @trigger.dev/sdk@3.0.0-beta.29
|
|
||||||
|
|
||||||
## 3.0.0-beta.28
|
|
||||||
|
|
||||||
### Patch Changes
|
|
||||||
|
|
||||||
- Updated dependencies [6d9dfbc75]
|
|
||||||
- @trigger.dev/sdk@3.0.0-beta.28
|
|
||||||
- @trigger.dev/integration-kit@3.0.0-beta.28
|
|
||||||
|
|
||||||
## 3.0.0-beta.27
|
|
||||||
|
|
||||||
### Patch Changes
|
|
||||||
|
|
||||||
- Updated dependencies [203e00208]
|
|
||||||
- @trigger.dev/sdk@3.0.0-beta.27
|
|
||||||
- @trigger.dev/integration-kit@3.0.0-beta.27
|
|
||||||
|
|
||||||
## 3.0.0-beta.26
|
|
||||||
|
|
||||||
### Patch Changes
|
|
||||||
|
|
||||||
- @trigger.dev/integration-kit@3.0.0-beta.26
|
|
||||||
- @trigger.dev/sdk@3.0.0-beta.26
|
|
||||||
|
|
||||||
## 3.0.0-beta.25
|
|
||||||
|
|
||||||
### Patch Changes
|
|
||||||
|
|
||||||
- @trigger.dev/integration-kit@3.0.0-beta.25
|
|
||||||
- @trigger.dev/sdk@3.0.0-beta.25
|
|
||||||
|
|
||||||
## 3.0.0-beta.24
|
|
||||||
|
|
||||||
### Patch Changes
|
|
||||||
|
|
||||||
- @trigger.dev/integration-kit@3.0.0-beta.24
|
|
||||||
- @trigger.dev/sdk@3.0.0-beta.24
|
|
||||||
|
|
||||||
## 3.0.0-beta.23
|
|
||||||
|
|
||||||
### Patch Changes
|
|
||||||
|
|
||||||
- @trigger.dev/integration-kit@3.0.0-beta.23
|
|
||||||
- @trigger.dev/sdk@3.0.0-beta.23
|
|
||||||
|
|
||||||
## 3.0.0-beta.22
|
|
||||||
|
|
||||||
### Patch Changes
|
|
||||||
|
|
||||||
- @trigger.dev/integration-kit@3.0.0-beta.22
|
|
||||||
- @trigger.dev/sdk@3.0.0-beta.22
|
|
||||||
|
|
||||||
## 3.0.0-beta.21
|
|
||||||
|
|
||||||
### Patch Changes
|
|
||||||
|
|
||||||
- Updated dependencies [9491a1649]
|
|
||||||
- @trigger.dev/sdk@3.0.0-beta.21
|
|
||||||
- @trigger.dev/integration-kit@3.0.0-beta.21
|
|
||||||
|
|
||||||
## 3.0.0-beta.20
|
|
||||||
|
|
||||||
### Patch Changes
|
|
||||||
|
|
||||||
- @trigger.dev/integration-kit@3.0.0-beta.20
|
|
||||||
- @trigger.dev/sdk@3.0.0-beta.20
|
|
||||||
|
|
||||||
## 3.0.0-beta.19
|
|
||||||
|
|
||||||
### Patch Changes
|
|
||||||
|
|
||||||
- Updated dependencies [e9a63a486]
|
|
||||||
- @trigger.dev/sdk@3.0.0-beta.19
|
|
||||||
- @trigger.dev/integration-kit@3.0.0-beta.19
|
|
||||||
|
|
||||||
## 3.0.0-beta.18
|
|
||||||
|
|
||||||
### Patch Changes
|
|
||||||
|
|
||||||
- Updated dependencies [b68012f81]
|
|
||||||
- Updated dependencies [b68012f81]
|
|
||||||
- Updated dependencies [b68012f81]
|
|
||||||
- @trigger.dev/sdk@3.0.0-beta.18
|
|
||||||
- @trigger.dev/integration-kit@3.0.0-beta.18
|
|
||||||
|
|
||||||
## 3.0.0-beta.17
|
|
||||||
|
|
||||||
### Patch Changes
|
|
||||||
|
|
||||||
- @trigger.dev/integration-kit@3.0.0-beta.17
|
|
||||||
- @trigger.dev/sdk@3.0.0-beta.17
|
|
||||||
|
|
||||||
## 3.0.0-beta.16
|
|
||||||
|
|
||||||
### Patch Changes
|
|
||||||
|
|
||||||
- @trigger.dev/integration-kit@3.0.0-beta.16
|
|
||||||
- @trigger.dev/sdk@3.0.0-beta.16
|
|
||||||
|
|
||||||
## 3.0.0-beta.15
|
|
||||||
|
|
||||||
### Patch Changes
|
|
||||||
|
|
||||||
- Updated dependencies [374edef02]
|
|
||||||
- Updated dependencies [26093896d]
|
|
||||||
- @trigger.dev/sdk@3.0.0-beta.15
|
|
||||||
- @trigger.dev/integration-kit@3.0.0-beta.15
|
|
||||||
|
|
||||||
## 3.0.0-beta.14
|
|
||||||
|
|
||||||
### Patch Changes
|
|
||||||
|
|
||||||
- Updated dependencies [c9e1a3e9c]
|
|
||||||
- @trigger.dev/sdk@3.0.0-beta.14
|
|
||||||
- @trigger.dev/integration-kit@3.0.0-beta.14
|
|
||||||
|
|
||||||
## 3.0.0-beta.13
|
|
||||||
|
|
||||||
### Patch Changes
|
|
||||||
|
|
||||||
- Updated dependencies [4986bfda2]
|
|
||||||
- Updated dependencies [44e1b8754]
|
|
||||||
- Updated dependencies [4986bfda2]
|
|
||||||
- Updated dependencies [4986bfda2]
|
|
||||||
- @trigger.dev/sdk@3.0.0-beta.13
|
|
||||||
- @trigger.dev/integration-kit@3.0.0-beta.13
|
|
||||||
|
|
||||||
## 3.0.0-beta.12
|
|
||||||
|
|
||||||
### Patch Changes
|
|
||||||
|
|
||||||
- @trigger.dev/integration-kit@3.0.0-beta.12
|
|
||||||
- @trigger.dev/sdk@3.0.0-beta.12
|
|
||||||
|
|
||||||
## 3.0.0-beta.11
|
|
||||||
|
|
||||||
### Patch Changes
|
|
||||||
|
|
||||||
- @trigger.dev/integration-kit@3.0.0-beta.11
|
|
||||||
- @trigger.dev/sdk@3.0.0-beta.11
|
|
||||||
|
|
||||||
## 3.0.0-beta.7
|
|
||||||
|
|
||||||
### Patch Changes
|
|
||||||
|
|
||||||
- Updated dependencies [f854cb90e]
|
|
||||||
- Updated dependencies [f854cb90e]
|
|
||||||
- @trigger.dev/sdk@3.0.0-beta.7
|
|
||||||
- @trigger.dev/integration-kit@3.0.0-beta.7
|
|
||||||
|
|
||||||
## 3.0.0-beta.6
|
|
||||||
|
|
||||||
### Patch Changes
|
|
||||||
|
|
||||||
- @trigger.dev/integration-kit@3.0.0-beta.6
|
|
||||||
- @trigger.dev/sdk@3.0.0-beta.6
|
|
||||||
|
|
||||||
## 3.0.0-beta.5
|
|
||||||
|
|
||||||
### Patch Changes
|
|
||||||
|
|
||||||
- @trigger.dev/integration-kit@3.0.0-beta.5
|
|
||||||
- @trigger.dev/sdk@3.0.0-beta.5
|
|
||||||
|
|
||||||
## 3.0.0-beta.4
|
|
||||||
|
|
||||||
### Patch Changes
|
|
||||||
|
|
||||||
- @trigger.dev/integration-kit@3.0.0-beta.4
|
|
||||||
- @trigger.dev/sdk@3.0.0-beta.4
|
|
||||||
|
|
||||||
## 3.0.0-beta.3
|
|
||||||
|
|
||||||
### Patch Changes
|
|
||||||
|
|
||||||
- Updated dependencies [b271742dc]
|
|
||||||
- @trigger.dev/sdk@3.0.0-beta.3
|
|
||||||
- @trigger.dev/integration-kit@3.0.0-beta.3
|
|
||||||
|
|
||||||
## 3.0.0-beta.2
|
|
||||||
|
|
||||||
### Patch Changes
|
|
||||||
|
|
||||||
- @trigger.dev/integration-kit@3.0.0-beta.2
|
|
||||||
- @trigger.dev/sdk@3.0.0-beta.2
|
|
||||||
|
|
||||||
## 3.0.0-beta.1
|
|
||||||
|
|
||||||
### Patch Changes
|
|
||||||
|
|
||||||
- Updated dependencies [b66d5525e]
|
|
||||||
- Updated dependencies [719c0a0b9]
|
|
||||||
- Updated dependencies [f93eae300]
|
|
||||||
- @trigger.dev/sdk@3.0.0-beta.1
|
|
||||||
- @trigger.dev/integration-kit@3.0.0-beta.1
|
|
||||||
|
|
||||||
## 3.0.0-beta.0
|
|
||||||
|
|
||||||
### Patch Changes
|
|
||||||
|
|
||||||
- Updated dependencies [395abe1b9]
|
|
||||||
- @trigger.dev/sdk@3.0.0-beta.0
|
|
||||||
- @trigger.dev/integration-kit@3.0.0-beta.0
|
|
||||||
|
|
||||||
## 2.3.18
|
|
||||||
|
|
||||||
### Patch Changes
|
|
||||||
|
|
||||||
- @trigger.dev/integration-kit@2.3.18
|
|
||||||
- @trigger.dev/sdk@2.3.18
|
|
||||||
|
|
||||||
## 2.3.17
|
|
||||||
|
|
||||||
### Patch Changes
|
|
||||||
|
|
||||||
- Updated dependencies [dd879c8e]
|
|
||||||
- @trigger.dev/sdk@2.3.17
|
|
||||||
- @trigger.dev/integration-kit@2.3.17
|
|
||||||
|
|
||||||
## 2.3.16
|
|
||||||
|
|
||||||
### Patch Changes
|
|
||||||
|
|
||||||
- @trigger.dev/integration-kit@2.3.16
|
|
||||||
- @trigger.dev/sdk@2.3.16
|
|
||||||
|
|
||||||
## 2.3.15
|
|
||||||
|
|
||||||
### Patch Changes
|
|
||||||
|
|
||||||
- Updated dependencies [6c4047cf]
|
|
||||||
- @trigger.dev/sdk@2.3.15
|
|
||||||
- @trigger.dev/integration-kit@2.3.15
|
|
||||||
|
|
||||||
## 2.3.14
|
|
||||||
|
|
||||||
### Patch Changes
|
|
||||||
|
|
||||||
- @trigger.dev/integration-kit@2.3.14
|
|
||||||
- @trigger.dev/sdk@2.3.14
|
|
||||||
|
|
||||||
## 2.3.13
|
|
||||||
|
|
||||||
### Patch Changes
|
|
||||||
|
|
||||||
- Updated dependencies [a93b554f]
|
|
||||||
- Updated dependencies [0f342cd1]
|
|
||||||
- @trigger.dev/sdk@2.3.13
|
|
||||||
- @trigger.dev/integration-kit@2.3.13
|
|
||||||
|
|
||||||
## 2.3.12
|
|
||||||
|
|
||||||
### Patch Changes
|
|
||||||
|
|
||||||
- Updated dependencies [129f023d]
|
|
||||||
- Updated dependencies [38f5a903]
|
|
||||||
- Updated dependencies [ff4ff869]
|
|
||||||
- @trigger.dev/sdk@2.3.12
|
|
||||||
- @trigger.dev/integration-kit@2.3.12
|
|
||||||
|
|
||||||
## 2.3.11
|
|
||||||
|
|
||||||
### Patch Changes
|
|
||||||
|
|
||||||
- @trigger.dev/integration-kit@2.3.11
|
|
||||||
- @trigger.dev/sdk@2.3.11
|
|
||||||
|
|
||||||
## 2.3.10
|
|
||||||
|
|
||||||
### Patch Changes
|
|
||||||
|
|
||||||
- Updated dependencies [8277f4d2]
|
|
||||||
- Updated dependencies [73cb8839]
|
|
||||||
- @trigger.dev/sdk@2.3.10
|
|
||||||
- @trigger.dev/integration-kit@2.3.10
|
|
||||||
|
|
||||||
## 2.3.9
|
|
||||||
|
|
||||||
### Patch Changes
|
|
||||||
|
|
||||||
- Updated dependencies [f7bf25f0]
|
|
||||||
- @trigger.dev/sdk@2.3.9
|
|
||||||
- @trigger.dev/integration-kit@2.3.9
|
|
||||||
|
|
||||||
## 2.3.8
|
|
||||||
|
|
||||||
### Patch Changes
|
|
||||||
|
|
||||||
- @trigger.dev/integration-kit@2.3.8
|
|
||||||
- @trigger.dev/sdk@2.3.8
|
|
||||||
|
|
||||||
## 2.3.7
|
|
||||||
|
|
||||||
### Patch Changes
|
|
||||||
|
|
||||||
- @trigger.dev/integration-kit@2.3.7
|
|
||||||
- @trigger.dev/sdk@2.3.7
|
|
||||||
|
|
||||||
## 2.3.6
|
|
||||||
|
|
||||||
### Patch Changes
|
|
||||||
|
|
||||||
- @trigger.dev/integration-kit@2.3.6
|
|
||||||
- @trigger.dev/sdk@2.3.6
|
|
||||||
|
|
||||||
## 2.3.5
|
|
||||||
|
|
||||||
### Patch Changes
|
|
||||||
|
|
||||||
- @trigger.dev/integration-kit@2.3.5
|
|
||||||
- @trigger.dev/sdk@2.3.5
|
|
||||||
|
|
||||||
## 2.3.4
|
|
||||||
|
|
||||||
### Patch Changes
|
|
||||||
|
|
||||||
- Updated dependencies [6a3c563f]
|
|
||||||
- @trigger.dev/sdk@2.3.4
|
|
||||||
- @trigger.dev/integration-kit@2.3.4
|
|
||||||
|
|
||||||
## 2.3.3
|
|
||||||
|
|
||||||
### Patch Changes
|
|
||||||
|
|
||||||
- 0f9f0102: Named exports don't work because Airtable is a CommonJS module
|
|
||||||
- @trigger.dev/integration-kit@2.3.3
|
|
||||||
- @trigger.dev/sdk@2.3.3
|
|
||||||
|
|
||||||
## 2.3.2
|
|
||||||
|
|
||||||
### Patch Changes
|
|
||||||
|
|
||||||
- 0c14e4cd: Fixed importing package subpath
|
|
||||||
- @trigger.dev/integration-kit@2.3.2
|
|
||||||
- @trigger.dev/sdk@2.3.2
|
|
||||||
|
|
||||||
## 2.3.1
|
|
||||||
|
|
||||||
### Patch Changes
|
|
||||||
|
|
||||||
- Updated dependencies [f3efcc0c]
|
|
||||||
- @trigger.dev/sdk@2.3.1
|
|
||||||
- @trigger.dev/integration-kit@2.3.1
|
|
||||||
|
|
||||||
## 2.3.0
|
|
||||||
|
|
||||||
### Minor Changes
|
|
||||||
|
|
||||||
- 17f6f29d: Support for Deno, Bun and Cloudflare workers, as well as conditionally exporting ESM versions of the package instead of just commonjs.
|
|
||||||
|
|
||||||
Cloudflare worker support requires the node compat flag turned on (https://developers.cloudflare.com/workers/runtime-apis/nodejs/)
|
|
||||||
|
|
||||||
### Patch Changes
|
|
||||||
|
|
||||||
- Updated dependencies [17f6f29d]
|
|
||||||
- @trigger.dev/integration-kit@2.3.0
|
|
||||||
- @trigger.dev/sdk@2.3.0
|
|
||||||
|
|
||||||
## 2.2.11
|
|
||||||
|
|
||||||
### Patch Changes
|
|
||||||
|
|
||||||
- de652c1d: Fix Shopify task types and KV `get()` return types
|
|
||||||
- Updated dependencies [de652c1d]
|
|
||||||
- @trigger.dev/sdk@2.2.11
|
|
||||||
- @trigger.dev/integration-kit@2.2.11
|
|
||||||
|
|
||||||
## 2.2.10
|
|
||||||
|
|
||||||
### Patch Changes
|
|
||||||
|
|
||||||
- @trigger.dev/integration-kit@2.2.10
|
|
||||||
- @trigger.dev/sdk@2.2.10
|
|
||||||
|
|
||||||
## 2.2.9
|
|
||||||
|
|
||||||
### Patch Changes
|
|
||||||
|
|
||||||
- Updated dependencies [1dcd87a2]
|
|
||||||
- Updated dependencies [6ebd435e]
|
|
||||||
- @trigger.dev/sdk@2.2.9
|
|
||||||
- @trigger.dev/integration-kit@2.2.9
|
|
||||||
|
|
||||||
## 2.2.8
|
|
||||||
|
|
||||||
### Patch Changes
|
|
||||||
|
|
||||||
- 067e19fe: - Simplify `Webhook Triggers` and use the new HTTP Endpoints
|
|
||||||
- Add a `Key-Value Store` for use in and outside of Jobs
|
|
||||||
- Add a `@trigger.dev/shopify` package
|
|
||||||
- Updated dependencies [067e19fe]
|
|
||||||
- Updated dependencies [096151c0]
|
|
||||||
- @trigger.dev/integration-kit@2.2.8
|
|
||||||
- @trigger.dev/sdk@2.2.8
|
|
||||||
|
|
||||||
## 2.2.7
|
|
||||||
|
|
||||||
### Patch Changes
|
|
||||||
|
|
||||||
- Updated dependencies [756024da]
|
|
||||||
- @trigger.dev/sdk@2.2.7
|
|
||||||
- @trigger.dev/integration-kit@2.2.7
|
|
||||||
|
|
||||||
## 2.2.6
|
|
||||||
|
|
||||||
### Patch Changes
|
|
||||||
|
|
||||||
- Updated dependencies [cb1825bf]
|
|
||||||
- Updated dependencies [cb1825bf]
|
|
||||||
- Updated dependencies [d0217344]
|
|
||||||
- Updated dependencies [cb1825bf]
|
|
||||||
- @trigger.dev/integration-kit@2.2.6
|
|
||||||
- @trigger.dev/sdk@2.2.6
|
|
||||||
|
|
||||||
## 2.2.5
|
|
||||||
|
|
||||||
### Patch Changes
|
|
||||||
|
|
||||||
- Updated dependencies [7e57f1f3]
|
|
||||||
- Updated dependencies [cf8f9946]
|
|
||||||
- Updated dependencies [a74716a1]
|
|
||||||
- Updated dependencies [620b8383]
|
|
||||||
- Updated dependencies [620b8383]
|
|
||||||
- Updated dependencies [4a0f030e]
|
|
||||||
- Updated dependencies [f4275e50]
|
|
||||||
- @trigger.dev/sdk@2.2.5
|
|
||||||
- @trigger.dev/integration-kit@2.2.5
|
|
||||||
|
|
||||||
## 2.2.4
|
|
||||||
|
|
||||||
### Patch Changes
|
|
||||||
|
|
||||||
- 9c5a7cf0: Extend the Airtable field set to accept formula errors and special values
|
|
||||||
- Updated dependencies [c1710ae7]
|
|
||||||
- Updated dependencies [9c4be40a]
|
|
||||||
- @trigger.dev/sdk@2.2.4
|
|
||||||
- @trigger.dev/integration-kit@2.2.4
|
|
||||||
|
|
||||||
## 2.2.3
|
|
||||||
|
|
||||||
### Patch Changes
|
|
||||||
|
|
||||||
- Updated dependencies [6e1b8a11]
|
|
||||||
- Updated dependencies [c4533c36]
|
|
||||||
- @trigger.dev/sdk@2.2.3
|
|
||||||
- @trigger.dev/integration-kit@2.2.3
|
|
||||||
|
|
||||||
## 2.2.2
|
|
||||||
|
|
||||||
### Patch Changes
|
|
||||||
|
|
||||||
- @trigger.dev/integration-kit@2.2.2
|
|
||||||
- @trigger.dev/sdk@2.2.2
|
|
||||||
|
|
||||||
## 2.2.1
|
|
||||||
|
|
||||||
### Patch Changes
|
|
||||||
|
|
||||||
- b9eba680: Export Base and Table
|
|
||||||
- Updated dependencies [044d38e3]
|
|
||||||
- @trigger.dev/sdk@2.2.1
|
|
||||||
- @trigger.dev/integration-kit@2.2.1
|
|
||||||
|
|
||||||
## 2.2.0
|
|
||||||
|
|
||||||
### Patch Changes
|
|
||||||
|
|
||||||
- Updated dependencies [975c5f1d]
|
|
||||||
- @trigger.dev/integration-kit@2.2.0
|
|
||||||
- @trigger.dev/sdk@2.2.0
|
|
||||||
|
|
||||||
## 2.1.9
|
|
||||||
|
|
||||||
### Patch Changes
|
|
||||||
|
|
||||||
- 9a187f9e: upgrade zod to 3.22.3
|
|
||||||
- Updated dependencies [9a187f9e]
|
|
||||||
- Updated dependencies [2e9452ab]
|
|
||||||
- @trigger.dev/sdk@2.1.9
|
|
||||||
- @trigger.dev/integration-kit@2.1.9
|
|
||||||
|
|
||||||
## 2.1.8
|
|
||||||
|
|
||||||
### Patch Changes
|
|
||||||
|
|
||||||
- 6a992a19: First release of `@trigger.dev/replicate` integration with remote callback support.
|
|
||||||
- Updated dependencies [6a992a19]
|
|
||||||
- Updated dependencies [ab9e4a98]
|
|
||||||
- Updated dependencies [ab9e4a98]
|
|
||||||
- @trigger.dev/sdk@2.1.8
|
|
||||||
- @trigger.dev/integration-kit@2.1.8
|
|
||||||
|
|
||||||
## 2.1.7
|
|
||||||
|
|
||||||
### Patch Changes
|
|
||||||
|
|
||||||
- @trigger.dev/integration-kit@2.1.7
|
|
||||||
- @trigger.dev/sdk@2.1.7
|
|
||||||
|
|
||||||
## 2.1.6
|
|
||||||
|
|
||||||
### Patch Changes
|
|
||||||
|
|
||||||
- @trigger.dev/integration-kit@2.1.6
|
|
||||||
- @trigger.dev/sdk@2.1.6
|
|
||||||
|
|
||||||
## 2.1.5
|
|
||||||
|
|
||||||
### Patch Changes
|
|
||||||
|
|
||||||
- @trigger.dev/integration-kit@2.1.5
|
|
||||||
- @trigger.dev/sdk@2.1.5
|
|
||||||
|
|
||||||
## 2.1.4
|
|
||||||
|
|
||||||
### Patch Changes
|
|
||||||
|
|
||||||
- c0dfa804: Add support for Bring Your Own Auth
|
|
||||||
- Updated dependencies [ad14983e]
|
|
||||||
- Updated dependencies [15f17d27]
|
|
||||||
- Updated dependencies [50137a6f]
|
|
||||||
- Updated dependencies [c0dfa804]
|
|
||||||
- @trigger.dev/sdk@2.1.4
|
|
||||||
- @trigger.dev/integration-kit@2.1.4
|
|
||||||
|
|
||||||
## 2.1.3
|
|
||||||
|
|
||||||
### Patch Changes
|
|
||||||
|
|
||||||
- Updated dependencies:
|
|
||||||
- `@trigger.dev/sdk@2.1.3`
|
|
||||||
- `@trigger.dev/integration-kit@2.1.3`
|
|
||||||
|
|
||||||
## 2.1.2
|
|
||||||
|
|
||||||
### Patch Changes
|
|
||||||
|
|
||||||
- Updated dependencies:
|
|
||||||
- `@trigger.dev/integration-kit@2.1.2`
|
|
||||||
- `@trigger.dev/sdk@2.1.2`
|
|
||||||
|
|
||||||
## 2.1.1
|
|
||||||
|
|
||||||
### Patch Changes
|
|
||||||
|
|
||||||
- Updated dependencies:
|
|
||||||
- `@trigger.dev/sdk@2.1.1`
|
|
||||||
- `@trigger.dev/integration-kit@2.1.1`
|
|
||||||
|
|
||||||
## 2.1.0
|
|
||||||
|
|
||||||
### Minor Changes
|
|
||||||
|
|
||||||
- Integrations are now simpler and support authentication during webhook registration ([`878da3c0`](https://github.com/triggerdotdev/trigger.dev/commit/878da3c01f0a4dfaf33a1f8943a7ad4eed8b8877))
|
|
||||||
|
|
||||||
### Patch Changes
|
|
||||||
|
|
||||||
- Updated dependencies:
|
|
||||||
- `@trigger.dev/integration-kit@2.1.0`
|
|
||||||
- `@trigger.dev/sdk@2.1.0`
|
|
||||||
|
|
||||||
## 2.1.0-beta.1
|
|
||||||
|
|
||||||
### Patch Changes
|
|
||||||
|
|
||||||
- Updated dependencies:
|
|
||||||
- `@trigger.dev/integration-kit@2.1.0-beta.1`
|
|
||||||
- `@trigger.dev/sdk@2.1.0-beta.1`
|
|
||||||
|
|
||||||
## 2.1.0-beta.0
|
|
||||||
|
|
||||||
### Minor Changes
|
|
||||||
|
|
||||||
- Integrations are now simpler and support authentication during webhook registration ([`878da3c0`](https://github.com/triggerdotdev/trigger.dev/commit/878da3c01f0a4dfaf33a1f8943a7ad4eed8b8877))
|
|
||||||
|
|
||||||
### Patch Changes
|
|
||||||
|
|
||||||
- Updated dependencies:
|
|
||||||
- `@trigger.dev/integration-kit@2.1.0-beta.0`
|
|
||||||
- `@trigger.dev/sdk@2.1.0-beta.0`
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
|
|
||||||
# @trigger.dev/airtable
|
|
||||||
|
|
||||||
@@ -1,48 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "@trigger.dev/airtable",
|
|
||||||
"version": "3.0.0-beta.55",
|
|
||||||
"description": "Trigger.dev integration for airtable",
|
|
||||||
"main": "./dist/index.js",
|
|
||||||
"types": "./dist/index.d.ts",
|
|
||||||
"publishConfig": {
|
|
||||||
"access": "public"
|
|
||||||
},
|
|
||||||
"files": [
|
|
||||||
"dist"
|
|
||||||
],
|
|
||||||
"devDependencies": {
|
|
||||||
"@trigger.dev/tsconfig": "workspace:*",
|
|
||||||
"@types/node": "16.x",
|
|
||||||
"rimraf": "^3.0.2",
|
|
||||||
"tsup": "8.0.1",
|
|
||||||
"typescript": "^5.3.0",
|
|
||||||
"@trigger.dev/tsup": "workspace:*"
|
|
||||||
},
|
|
||||||
"scripts": {
|
|
||||||
"clean": "rimraf dist",
|
|
||||||
"build": "npm run clean && npm run build:tsup",
|
|
||||||
"build:tsup": "tsup",
|
|
||||||
"typecheck": "tsc --noEmit"
|
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"@trigger.dev/integration-kit": "workspace:^3.0.0-beta.55",
|
|
||||||
"@trigger.dev/sdk": "workspace:^3.0.0-beta.55",
|
|
||||||
"airtable": "^0.12.1",
|
|
||||||
"zod": "3.22.3"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=16.8.0"
|
|
||||||
},
|
|
||||||
"exports": {
|
|
||||||
".": {
|
|
||||||
"import": {
|
|
||||||
"types": "./dist/index.d.mts",
|
|
||||||
"default": "./dist/index.mjs"
|
|
||||||
},
|
|
||||||
"require": "./dist/index.js",
|
|
||||||
"types": "./dist/index.d.ts"
|
|
||||||
},
|
|
||||||
"./package.json": "./package.json"
|
|
||||||
},
|
|
||||||
"module": "./dist/index.mjs"
|
|
||||||
}
|
|
||||||
@@ -1,164 +0,0 @@
|
|||||||
import { DisplayProperty, IntegrationTaskKey } from "@trigger.dev/sdk";
|
|
||||||
import AirtableSDK from "airtable";
|
|
||||||
import { AirtableFieldSet, AirtableRecord, AirtableRunTask } from ".";
|
|
||||||
|
|
||||||
type TableParams<Params extends Record<string, unknown>> = {
|
|
||||||
tableName: string;
|
|
||||||
} & Params;
|
|
||||||
|
|
||||||
export type AirtableRecordsParams = TableParams<{}>;
|
|
||||||
export type AirtableRecords = AirtableSDK.Records<AirtableSDK.FieldSet>;
|
|
||||||
|
|
||||||
export class Base {
|
|
||||||
constructor(
|
|
||||||
private runTask: AirtableRunTask,
|
|
||||||
public baseId: string
|
|
||||||
) {}
|
|
||||||
|
|
||||||
table<TFields extends AirtableFieldSet>(tableName: string) {
|
|
||||||
return new Table<TFields>(this.runTask, this.baseId, tableName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export class Table<TFields extends AirtableFieldSet> {
|
|
||||||
runTask: AirtableRunTask;
|
|
||||||
baseId: string;
|
|
||||||
tableName: string;
|
|
||||||
|
|
||||||
constructor(runTask: AirtableRunTask, baseId: string, tableName: string) {
|
|
||||||
this.runTask = runTask;
|
|
||||||
this.baseId = baseId;
|
|
||||||
this.tableName = tableName;
|
|
||||||
}
|
|
||||||
|
|
||||||
getRecords(key: IntegrationTaskKey, params?: AirtableSDK.SelectOptions<TFields>) {
|
|
||||||
return this.runTask(
|
|
||||||
key,
|
|
||||||
async (client) => {
|
|
||||||
const result = await client
|
|
||||||
.base(this.baseId)
|
|
||||||
// official types are wrong - we need to use our extended AirtableFieldSet here
|
|
||||||
// @ts-ignore
|
|
||||||
.table<TFields>(this.tableName)
|
|
||||||
.select(params)
|
|
||||||
.all();
|
|
||||||
return result.map((record) => toSerializableRecord<TFields>(record));
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "Get Records",
|
|
||||||
params,
|
|
||||||
properties: [...tableParams({ baseId: this.baseId, tableName: this.tableName })],
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
getRecord(key: IntegrationTaskKey, recordId: string) {
|
|
||||||
return this.runTask(
|
|
||||||
key,
|
|
||||||
async (client) => {
|
|
||||||
// official types are wrong - we need to use our extended AirtableFieldSet here
|
|
||||||
// @ts-ignore
|
|
||||||
const result = await client.base(this.baseId).table<TFields>(this.tableName).find(recordId);
|
|
||||||
return toSerializableRecord<TFields>(result);
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "Get Record",
|
|
||||||
params: { recordId },
|
|
||||||
properties: [
|
|
||||||
...tableParams({ baseId: this.baseId, tableName: this.tableName }),
|
|
||||||
{ label: "Record", text: recordId },
|
|
||||||
],
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
createRecords(key: IntegrationTaskKey, records: { fields: Partial<TFields> }[]) {
|
|
||||||
return this.runTask(
|
|
||||||
key,
|
|
||||||
async (client) => {
|
|
||||||
const result = await client
|
|
||||||
.base(this.baseId)
|
|
||||||
// official types are wrong - we need to use our extended AirtableFieldSet here
|
|
||||||
// @ts-ignore
|
|
||||||
.table<TFields>(this.tableName)
|
|
||||||
.create(records);
|
|
||||||
return result.map((record) => toSerializableRecord<TFields>(record));
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "Create Records",
|
|
||||||
params: records,
|
|
||||||
properties: [
|
|
||||||
...tableParams({ baseId: this.baseId, tableName: this.tableName }),
|
|
||||||
{ label: "Created records", text: records.length.toString() },
|
|
||||||
],
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
updateRecords(key: IntegrationTaskKey, records: { id: string; fields: Partial<TFields> }[]) {
|
|
||||||
return this.runTask(
|
|
||||||
key,
|
|
||||||
async (client) => {
|
|
||||||
const result = await client
|
|
||||||
.base(this.baseId)
|
|
||||||
// official types are wrong - we need to use our extended AirtableFieldSet here
|
|
||||||
// @ts-ignore
|
|
||||||
.table<TFields>(this.tableName)
|
|
||||||
.update(records);
|
|
||||||
return result.map((record) => toSerializableRecord<TFields>(record));
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "Update Records",
|
|
||||||
params: records,
|
|
||||||
properties: [
|
|
||||||
...tableParams({ baseId: this.baseId, tableName: this.tableName }),
|
|
||||||
{ label: "Updated records", text: records.length.toString() },
|
|
||||||
],
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
deleteRecords(key: IntegrationTaskKey, recordIds: string[]) {
|
|
||||||
return this.runTask(
|
|
||||||
key,
|
|
||||||
async (client) => {
|
|
||||||
const result = await client
|
|
||||||
.base(this.baseId)
|
|
||||||
// official types are wrong - we need to use our extended AirtableFieldSet here
|
|
||||||
// @ts-ignore
|
|
||||||
.table<TFields>(this.tableName)
|
|
||||||
.destroy(recordIds);
|
|
||||||
return result.map((record) => toSerializableRecord<TFields>(record));
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "Delete Records",
|
|
||||||
params: { recordIds },
|
|
||||||
properties: [
|
|
||||||
...tableParams({ baseId: this.baseId, tableName: this.tableName }),
|
|
||||||
{ label: "Deleted records", text: recordIds.length.toString() },
|
|
||||||
],
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function toSerializableRecord<TFields extends AirtableFieldSet>(record: AirtableRecord<TFields>) {
|
|
||||||
return {
|
|
||||||
id: record.id,
|
|
||||||
fields: record.fields,
|
|
||||||
commentCount: record.commentCount,
|
|
||||||
} as AirtableRecord<TFields>;
|
|
||||||
}
|
|
||||||
|
|
||||||
function tableParams(params: { baseId: string; tableName: string }): DisplayProperty[] {
|
|
||||||
return [
|
|
||||||
{
|
|
||||||
label: "Base",
|
|
||||||
text: params.baseId,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: "Table",
|
|
||||||
text: params.tableName,
|
|
||||||
},
|
|
||||||
];
|
|
||||||
}
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user