chore: switch to oxfmt, oxlint - add ci checks (#3977)

This commit is contained in:
Chris Arderne
2026-06-26 12:19:29 +01:00
committed by GitHub
parent 01b8dcf03b
commit b54201f986
326 changed files with 12634 additions and 14213 deletions
-4
View File
@@ -1,4 +0,0 @@
*/**.js
*/**.d.ts
packages/*/dist
packages/*/lib
+1 -1
View File
@@ -9,4 +9,4 @@
- any: ["**/*.md"]
"📌 area: ci":
- any: [".github/**/*"]
- any: [".github/**/*"]
+38
View File
@@ -0,0 +1,38 @@
name: "🎨 Format & Lint"
on:
workflow_call:
permissions:
contents: read
jobs:
code-quality:
runs-on: ubuntu-latest
steps:
- name: ⬇️ Checkout repo
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
fetch-depth: 0
persist-credentials: false
- name: ⎔ Setup pnpm
uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # v5.0.0
with:
version: 10.33.2
- name: ⎔ Setup node
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
with:
node-version: 20.20.2
cache: "pnpm"
- name: 📥 Download deps
run: pnpm install --frozen-lockfile
- name: 💅 Check formatting
run: pnpm exec oxfmt --check .
- name: 🔎 Lint
run: pnpm exec oxlint .
@@ -2,7 +2,7 @@ name: Dependabot Critical Alerts
on:
schedule:
- cron: "0 8 * * *" # Daily 08:00 UTC
- cron: "0 8 * * *" # Daily 08:00 UTC
workflow_dispatch:
inputs:
severity:
@@ -2,7 +2,7 @@ name: Dependabot Weekly Summary
on:
schedule:
- cron: "0 8 * * 1" # Mon 08:00 UTC
- cron: "0 8 * * 1" # Mon 08:00 UTC
workflow_dispatch:
# Single-purpose monitoring workflow; serialise on workflow name only - we never
@@ -12,9 +12,9 @@ concurrency:
cancel-in-progress: false
permissions:
contents: read # gh CLI baseline
pull-requests: read # gh pr list (open dependabot PRs)
actions: read # gh run list / view (parse latest dependabot run logs)
contents: read # gh CLI baseline
pull-requests: read # gh pr list (open dependabot PRs)
actions: read # gh run list / view (parse latest dependabot run logs)
jobs:
summary:
+6
View File
@@ -102,6 +102,11 @@ jobs:
- 'pnpm-workspace.yaml'
- 'turbo.json'
code-quality:
needs: changes
if: needs.changes.outputs.code == 'true'
uses: ./.github/workflows/code-quality.yml
typecheck:
needs: changes
if: needs.changes.outputs.code == 'true' || needs.changes.outputs.typecheck_self == 'true'
@@ -155,6 +160,7 @@ jobs:
name: All PR Checks
needs:
- changes
- code-quality
- typecheck
- webapp
- e2e-webapp
+6 -6
View File
@@ -3,17 +3,17 @@ name: 🧭 Helm Chart Release
on:
push:
tags:
- 'helm-v*'
- "helm-v*"
workflow_call:
inputs:
chart_version:
description: 'Chart version to release'
description: "Chart version to release"
required: true
type: string
workflow_dispatch:
inputs:
chart_version:
description: 'Chart version to release'
description: "Chart version to release"
required: true
type: string
@@ -58,7 +58,7 @@ jobs:
- name: Validate manifests
uses: docker://ghcr.io/yannh/kubeconform:v0.7.0@sha256:85dbef6b4b312b99133decc9c6fc9495e9fc5f92293d4ff3b7e1b30f5611823c
with:
entrypoint: '/kubeconform'
entrypoint: "/kubeconform"
args: "-summary -output json ./helm-output"
release:
@@ -134,7 +134,7 @@ jobs:
run: |
VERSION="${STEPS_VERSION_OUTPUTS_VERSION}"
CHART_PACKAGE="/tmp/${{ env.CHART_NAME }}-${VERSION}.tgz"
# Push to GHCR OCI registry
helm push "$CHART_PACKAGE" "oci://${{ env.REGISTRY }}/${{ github.repository_owner }}/charts"
env:
@@ -153,7 +153,7 @@ jobs:
oci://${{ env.REGISTRY }}/${{ github.repository_owner }}/charts/${{ env.CHART_NAME }} \
--version "${{ steps.version.outputs.version }}"
```
### Changes
See commit history for detailed changes in this release.
files: |
+6 -6
View File
@@ -4,14 +4,14 @@ on:
push:
branches: [main]
paths:
- '.github/workflows/**'
- '.github/actions/**'
- '.github/zizmor.yml'
- ".github/workflows/**"
- ".github/actions/**"
- ".github/zizmor.yml"
pull_request:
paths:
- '.github/workflows/**'
- '.github/actions/**'
- '.github/zizmor.yml'
- ".github/workflows/**"
- ".github/actions/**"
- ".github/zizmor.yml"
permissions: {}
+1 -1
View File
@@ -2,4 +2,4 @@ rules:
unpinned-uses:
config:
policies:
'*': hash-pin
"*": hash-pin
+31
View File
@@ -0,0 +1,31 @@
{
"$schema": "./node_modules/oxfmt/configuration_schema.json",
"semi": true,
"singleQuote": false,
"jsxSingleQuote": false,
"trailingComma": "es5",
"bracketSpacing": true,
"bracketSameLine": false,
"printWidth": 100,
"tabWidth": 2,
"useTabs": false,
"sortPackageJson": false,
"ignorePatterns": [
"node_modules",
"apps/webapp",
".env",
".env.local",
"pnpm-lock.yaml",
"tailwind.css",
".babelrc.json",
"**/.react-email/",
"**/storybook-static/",
"**/.changeset/",
"**/dist/",
"internal-packages/tsql/src/grammar/",
// Maybe turn these on in the future
"**/*.yaml",
"**/*.mdx",
"**/*.md"
]
}
+47
View File
@@ -0,0 +1,47 @@
{
"$schema": "./node_modules/oxlint/configuration_schema.json",
"plugins": ["typescript", "import", "react"],
"ignorePatterns": [
"**/dist/**",
"**/build/**",
"**/*.d.ts",
"**/seed.js",
"**/seedCloud.ts",
"**/populate.js",
"apps/webapp/**"
],
// All rules below are disabled because they currently fire on the existing
// codebase (1748 warnings across these 20 rules as of this commit). Disabled
// to keep the lint baseline green; re-enable and fix incrementally.
"rules": {
// eslint
"no-unused-vars": "off",
"no-unused-expressions": "off",
"no-control-regex": "off",
"no-empty-pattern": "off",
"no-unused-private-class-members": "off",
"no-useless-catch": "off",
"no-unsafe-optional-chaining": "off",
"no-unreachable": "off",
"require-yield": "off",
"no-async-promise-executor": "off",
"no-unsafe-finally": "off",
"no-useless-escape": "off",
// typescript
"typescript/consistent-type-imports": "off",
"typescript/no-this-alias": "off",
"typescript/no-non-null-asserted-optional-chain": "off",
"typescript/no-unnecessary-parameter-property-assignment": "off",
// import
"import/no-duplicates": "off",
"import/namespace": "off",
// react
"react/jsx-key": "off",
"react/no-children-prop": "off",
// react-hooks
"react-hooks/exhaustive-deps": "off",
// oxlint treats any use*()/use() call as a React hook, producing false
// positives in async/test code (testcontainers, cli-v3 e2e).
"react-hooks/rules-of-hooks": "off"
}
}
-10
View File
@@ -1,10 +0,0 @@
node_modules
.env
.env.local
pnpm-lock.yaml
tailwind.css
.babelrc.json
**/.react-email/
**/storybook-static/
**/.changeset/
**/dist/
+1 -1
View File
@@ -27,4 +27,4 @@
"esbuild": "^0.19.11",
"tsx": "^4.7.0"
}
}
}
+1 -1
View File
@@ -24,4 +24,4 @@
"esbuild": "^0.19.11",
"tsx": "^4.7.0"
}
}
}
+1 -1
View File
@@ -25,4 +25,4 @@
"esbuild": "^0.19.11",
"tsx": "^4.7.0"
}
}
}
@@ -73,9 +73,9 @@ describe("K8sPodCountSignalSource", () => {
engageThreshold: 10000,
releaseThreshold: 5000,
});
expect((await source.read()).engaged).toBe(true); // engage
expect((await source.read()).engaged).toBe(true); // engage
count = 7000;
expect((await source.read()).engaged).toBe(true); // band -> still engaged
expect((await source.read()).engaged).toBe(true); // band -> still engaged
count = 4999;
expect((await source.read()).engaged).toBe(false); // below release -> off
count = 7000;
@@ -49,14 +49,17 @@ describe("RedisBackpressureSignalSource", () => {
}
});
redisTest("returns null for valid JSON of the wrong shape (fail-open)", async ({ redisOptions }) => {
const redis = new Redis(redisOptions);
try {
await redis.set(KEY, JSON.stringify({ foo: "bar" }));
const source = new RedisBackpressureSignalSource(redis, KEY);
expect(await source.read()).toBeNull();
} finally {
await redis.quit();
redisTest(
"returns null for valid JSON of the wrong shape (fail-open)",
async ({ redisOptions }) => {
const redis = new Redis(redisOptions);
try {
await redis.set(KEY, JSON.stringify({ foo: "bar" }));
const source = new RedisBackpressureSignalSource(redis, KEY);
expect(await source.read()).toBeNull();
} finally {
await redis.quit();
}
}
});
);
});
+19 -4
View File
@@ -75,9 +75,21 @@ export const Env = z
TRIGGER_DEQUEUE_BACKPRESSURE_REDIS_TLS_DISABLED: BoolEnv.default(false),
TRIGGER_DEQUEUE_BACKPRESSURE_POD_COUNT_ENABLED: BoolEnv.default(false),
TRIGGER_DEQUEUE_BACKPRESSURE_POD_COUNT_DRY_RUN: BoolEnv.default(true),
TRIGGER_DEQUEUE_BACKPRESSURE_POD_COUNT_ENGAGE: z.coerce.number().int().positive().default(10_000),
TRIGGER_DEQUEUE_BACKPRESSURE_POD_COUNT_RELEASE: z.coerce.number().int().positive().default(5_000),
TRIGGER_DEQUEUE_BACKPRESSURE_POD_COUNT_REFRESH_MS: z.coerce.number().int().positive().default(5_000),
TRIGGER_DEQUEUE_BACKPRESSURE_POD_COUNT_ENGAGE: z.coerce
.number()
.int()
.positive()
.default(10_000),
TRIGGER_DEQUEUE_BACKPRESSURE_POD_COUNT_RELEASE: z.coerce
.number()
.int()
.positive()
.default(5_000),
TRIGGER_DEQUEUE_BACKPRESSURE_POD_COUNT_REFRESH_MS: z.coerce
.number()
.int()
.positive()
.default(5_000),
// Hard timeout on the apiserver /metrics scrape. A hung request would otherwise
// never settle and freeze the monitor's refresh loop (fail-open silently).
TRIGGER_DEQUEUE_BACKPRESSURE_POD_COUNT_SCRAPE_TIMEOUT_MS: z.coerce
@@ -350,7 +362,10 @@ export const Env = z
path: ["TRIGGER_WORKLOAD_API_DOMAIN"],
});
}
if (data.TRIGGER_DEQUEUE_BACKPRESSURE_ENABLED && !data.TRIGGER_DEQUEUE_BACKPRESSURE_REDIS_HOST) {
if (
data.TRIGGER_DEQUEUE_BACKPRESSURE_ENABLED &&
!data.TRIGGER_DEQUEUE_BACKPRESSURE_REDIS_HOST
) {
ctx.addIssue({
code: z.ZodIssueCode.custom,
message:
+4 -1
View File
@@ -274,7 +274,10 @@ class ManagedSupervisor {
rampMs: env.TRIGGER_DEQUEUE_BACKPRESSURE_RAMP_MS,
dryRun: env.TRIGGER_DEQUEUE_BACKPRESSURE_POD_COUNT_DRY_RUN,
logger: this.logger,
metrics: new BackpressureMetrics({ register, prefix: "supervisor_backpressure_pod_count" }),
metrics: new BackpressureMetrics({
register,
prefix: "supervisor_backpressure_pod_count",
}),
})
);
this.logger.log("🛑 Dequeue backpressure enabled (pod-count source)", {
@@ -10,7 +10,9 @@ const DELAY_MS = 200;
const SETTLE_MS = 600;
function createService() {
const snapshot = vi.fn(async (_opts: { runnerId: string; metadata: Record<string, string> }) => true);
const snapshot = vi.fn(
async (_opts: { runnerId: string; metadata: Record<string, string> }) => true
);
const computeManager = {
snapshotDelayMs: DELAY_MS,
@@ -97,9 +99,7 @@ describe("ComputeSnapshotService", () => {
expect(service.cancel("run_1", "runner-b")).toBe(false);
await vi.waitFor(() => expect(snapshot).toHaveBeenCalledTimes(1), { timeout: 2_000 });
expect(snapshot).toHaveBeenCalledWith(
expect.objectContaining({ runnerId: "runner-a" })
);
expect(snapshot).toHaveBeenCalledWith(expect.objectContaining({ runnerId: "runner-a" }));
} finally {
service.stop();
}
@@ -31,9 +31,7 @@ describe("buildPayload", () => {
expect(triggerAttr).toEqual({ key: "$trigger", value: { boolValue: true } });
// Resource attributes
const envAttr = resourceSpan.resource.attributes.find(
(a) => a.key === "ctx.environment.id"
);
const envAttr = resourceSpan.resource.attributes.find((a) => a.key === "ctx.environment.id");
expect(envAttr).toEqual({
key: "ctx.environment.id",
value: { stringValue: "env_123" },
@@ -19,10 +19,7 @@ function makeMessage(runFriendlyId = "run_1"): DequeuedMessage {
} as unknown as DequeuedMessage;
}
function createService(opts: {
latestSnapshotId?: string;
probeError?: boolean;
}) {
function createService(opts: { latestSnapshotId?: string; probeError?: boolean }) {
const getLatestSnapshot = vi.fn(async (_runId: string) =>
opts.probeError
? { success: false as const, error: "connection refused" }
+1 -6
View File
@@ -11,12 +11,7 @@ export { type Env, isValidRequestId, newState, type NewStateOptions } from "./ne
export { emit, EmitMessage } from "./emit.js";
export { parseTraceId } from "./traceparent.js";
export { fromContext, wideEventStorage } from "./context.js";
export {
type PhaseOpt,
recordPhase,
recordPhaseSince,
timePhase,
} from "./record.js";
export { type PhaseOpt, recordPhase, recordPhaseSince, timePhase } from "./record.js";
export {
emitOneShot,
runWideEvent,
@@ -124,7 +124,8 @@ describe("runWideEvent", () => {
{
service: "supervisor",
env: {},
enabled: true, op: "test",
enabled: true,
op: "test",
setup: (state) => {
state.meta.run_id = "run_abc";
state.extras.iteration = "dequeue";
@@ -158,16 +159,13 @@ describe("runWideEvent", () => {
const lines = await captureStdout(async () => {
await Promise.all(
["a", "b", "c"].map((tag) =>
runWideEvent(
{ service: "supervisor", env: {}, enabled: true, op: "test" },
async () => {
const s = fromContext();
if (!s) throw new Error("no state");
s.meta.tag = tag;
await new Promise((r) => setTimeout(r, 5));
expect(s.meta.tag).toBe(tag);
}
)
runWideEvent({ service: "supervisor", env: {}, enabled: true, op: "test" }, async () => {
const s = fromContext();
if (!s) throw new Error("no state");
s.meta.tag = tag;
await new Promise((r) => setTimeout(r, 5));
expect(s.meta.tag).toBe(tag);
})
)
);
});
@@ -182,7 +180,8 @@ describe("emitOneShot", () => {
emitOneShot({
service: "supervisor",
env: {},
enabled: true, op: "test",
enabled: true,
op: "test",
populate: (s) => {
s.meta.run_id = "run_abc";
s.extras.event = "run:start";
@@ -15,9 +15,7 @@ describe("runnerNameForAttempt", () => {
describe("isRetryableCreateError", () => {
it("retries statuses where the create definitely did not commit", () => {
expect(isRetryableCreateError(new ComputeClientError(500, "tap busy", "http://gw"))).toBe(
true
);
expect(isRetryableCreateError(new ComputeClientError(500, "tap busy", "http://gw"))).toBe(true);
expect(isRetryableCreateError(new ComputeClientError(503, "no placement", "http://gw"))).toBe(
true
);
@@ -250,9 +250,7 @@ export class ComputeWorkloadManager implements WorkloadManager {
// name registered, so subsequent attempts use a suffixed name.
let suffixAttempts = false;
for (; attempt <= this.createMaxAttempts; attempt++) {
const attemptRunnerId = suffixAttempts
? runnerNameForAttempt(runnerId, attempt)
: runnerId;
const attemptRunnerId = suffixAttempts ? runnerNameForAttempt(runnerId, attempt) : runnerId;
[error, data] = await tryCatch(
this.compute.instances.create(
attemptRunnerId === runnerId
@@ -431,7 +431,8 @@ export class KubernetesWorkloadManager implements WorkloadManager {
// Only large machine affinity produces hard requirements (non-large runs must stay off the large pool).
// Schedule affinity is soft both ways.
const required = [
...(largeNodeAffinity?.requiredDuringSchedulingIgnoredDuringExecution?.nodeSelectorTerms ?? []),
...(largeNodeAffinity?.requiredDuringSchedulingIgnoredDuringExecution?.nodeSelectorTerms ??
[]),
];
const hasNodeAffinity = preferred.length > 0 || required.length > 0;
@@ -443,7 +444,9 @@ export class KubernetesWorkloadManager implements WorkloadManager {
return {
...(hasNodeAffinity && {
nodeAffinity: {
...(preferred.length > 0 && { preferredDuringSchedulingIgnoredDuringExecution: preferred }),
...(preferred.length > 0 && {
preferredDuringSchedulingIgnoredDuringExecution: preferred,
}),
...(required.length > 0 && {
requiredDuringSchedulingIgnoredDuringExecution: { nodeSelectorTerms: required },
}),
@@ -497,7 +500,10 @@ export class KubernetesWorkloadManager implements WorkloadManager {
}
#getScheduleNodeAffinityRules(isScheduledRun: boolean): k8s.V1NodeAffinity | undefined {
if (!env.KUBERNETES_SCHEDULED_RUN_AFFINITY_ENABLED || !env.KUBERNETES_SCHEDULED_RUN_AFFINITY_POOL_LABEL_VALUE) {
if (
!env.KUBERNETES_SCHEDULED_RUN_AFFINITY_ENABLED ||
!env.KUBERNETES_SCHEDULED_RUN_AFFINITY_POOL_LABEL_VALUE
) {
return undefined;
}
+6 -1
View File
@@ -1,4 +1,9 @@
import type { EnvironmentType, MachinePreset, PlacementTag, RunAnnotations } from "@trigger.dev/core/v3";
import type {
EnvironmentType,
MachinePreset,
PlacementTag,
RunAnnotations,
} from "@trigger.dev/core/v3";
export interface WorkloadManagerOptions {
workloadApiProtocol: "http" | "https";
+19 -13
View File
@@ -317,9 +317,7 @@ export class WorkloadServer extends EventEmitter<WorkloadServerEvents> {
return;
}
reply.json(
completeResponse.data satisfies WorkloadRunAttemptCompleteResponseBody
);
reply.json(completeResponse.data satisfies WorkloadRunAttemptCompleteResponseBody);
return;
}
),
@@ -566,7 +564,9 @@ export class WorkloadServer extends EventEmitter<WorkloadServerEvents> {
}
reply.json(
dequeueResponse.data.map(legacifyCheckpointType) satisfies WorkloadDequeueFromVersionResponseBody
dequeueResponse.data.map(
legacifyCheckpointType
) satisfies WorkloadDequeueFromVersionResponseBody
);
}
),
@@ -613,16 +613,22 @@ export class WorkloadServer extends EventEmitter<WorkloadServerEvents> {
httpServer.route("/api/v1/compute/snapshot-complete", "POST", {
bodySchema: SnapshotCallbackPayloadSchema,
handler: async (ctx) =>
this.wideRoute(ctx, "snapshot.callback", "/api/v1/compute/snapshot-complete", "POST", async () => {
const { reply, body } = ctx;
if (!this.snapshotService) {
reply.empty(404);
return;
}
this.wideRoute(
ctx,
"snapshot.callback",
"/api/v1/compute/snapshot-complete",
"POST",
async () => {
const { reply, body } = ctx;
if (!this.snapshotService) {
reply.empty(404);
return;
}
const result = await this.snapshotService.handleCallback(body);
reply.empty(result.status);
}),
const result = await this.snapshotService.handleCallback(body);
reply.empty(result.status);
}
),
});
return httpServer;
-31
View File
@@ -1,31 +0,0 @@
{
"plugins": ["react-hooks", "@typescript-eslint/eslint-plugin", "import"],
"parser": "@typescript-eslint/parser",
"overrides": [
{
"files": ["*.ts", "*.tsx"],
"rules": {
// Autofixes imports from "@trigger.dev/core" to fine grained modules
// "@trigger.dev/no-trigger-core-import": "error",
// Normalize `import type {}` and `import { type }`
"@typescript-eslint/consistent-type-imports": [
"warn",
{
// the "type" annotation can get tangled and cause syntax errors
// during some autofixes, so easier to just turn it off
"prefer": "type-imports",
"disallowTypeAnnotations": true,
"fixStyle": "inline-type-imports"
}
],
// no-trigger-core-import splits imports into multiple lines
// this one merges them back into a single line
// if they still import from the same module
"import/no-duplicates": ["warn", { "prefer-inline": true }],
// lots of undeclared vars, enable this rule if you want to clean them up
"turbo/no-undeclared-env-vars": "off"
}
}
],
"ignorePatterns": ["seed.js", "seedCloud.ts", "populate.js"]
}
-11
View File
@@ -1,11 +0,0 @@
node_modules
/build
/public/build
.env
/cypress/screenshots
/cypress/videos
/postgres-data
/app/styles/tailwind.css
+2 -18
View File
@@ -10,8 +10,8 @@
"build:sentry": "esbuild --platform=node --format=cjs --outbase=. ./sentry.server.ts ./app/utils/sentryTraceContext.server.ts --outdir=build --sourcemap",
"dev": "cross-env PORT=3030 remix dev -c \"node ./build/server.js\"",
"dev:worker": "cross-env NODE_PATH=../../node_modules/.pnpm/node_modules node ./build/server.js",
"format": "prettier --write .",
"lint": "eslint --cache --cache-location ./node_modules/.cache/eslint .",
"format": "oxfmt .",
"lint": "oxlint -c ../../.oxlintrc.json",
"start": "cross-env NODE_ENV=production node --max-old-space-size=8192 ./build/server.js",
"start:local": "cross-env node --max-old-space-size=8192 ./build/server.js",
"typecheck": "cross-env NODE_OPTIONS=\"--max-old-space-size=8192\" tsc --noEmit -p ./tsconfig.check.json",
@@ -21,11 +21,6 @@
"test": "vitest --no-file-parallelism",
"eval:dev": "evalite watch"
},
"eslintIgnore": [
"/node_modules",
"/build",
"/public/build"
],
"dependencies": {
"@ai-sdk/anthropic": "^3.0.0",
"@ai-sdk/openai": "^3.0.0",
@@ -248,7 +243,6 @@
"@internal/replication": "workspace:*",
"@internal/testcontainers": "workspace:*",
"@remix-run/dev": "2.17.4",
"@remix-run/eslint-config": "2.17.4",
"@remix-run/testing": "^2.17.4",
"@sentry/cli": "2.50.2",
"@swc/core": "^1.3.4",
@@ -259,7 +253,6 @@
"@types/bcryptjs": "^2.4.2",
"@types/compression": "^1.7.2",
"@types/cookie": "^0.6.0",
"@types/eslint": "^8.4.6",
"@types/express": "^4.17.13",
"@types/humanize-duration": "^3.27.1",
"@types/json-query": "^2.2.3",
@@ -280,25 +273,16 @@
"@types/supertest": "^6.0.2",
"@types/tar": "^6.1.4",
"@types/ws": "^8.5.3",
"@typescript-eslint/eslint-plugin": "^5.59.6",
"@typescript-eslint/parser": "^5.59.6",
"autoevals": "^0.0.130",
"autoprefixer": "^10.4.13",
"css-loader": "^6.10.0",
"datepicker": "link:@types/@react-aria/datepicker",
"engine.io": "^6.5.4",
"esbuild": "^0.15.10",
"eslint": "^8.24.0",
"eslint-config-prettier": "^8.5.0",
"eslint-plugin-import": "^2.29.1",
"eslint-plugin-react-hooks": "^4.6.2",
"eslint-plugin-turbo": "^2.0.4",
"evalite": "1.0.0-beta.16",
"npm-run-all": "^4.1.5",
"postcss-import": "^16.0.1",
"postcss-loader": "^8.1.1",
"prettier": "^2.8.8",
"prettier-plugin-tailwindcss": "^0.3.0",
"prop-types": "^15.8.1",
"rimraf": "^6.0.1",
"style-loader": "^3.3.4",
-4
View File
@@ -1,4 +0,0 @@
module.exports = {
...require("../../prettier.config.js"),
plugins: [require("prettier-plugin-tailwindcss")],
};
+1 -1
View File
@@ -1,3 +1,3 @@
{
"id": "g2k5ln95n6"
}
}
@@ -186,7 +186,12 @@
"gridPos": { "h": 8, "w": 12, "x": 0, "y": 7 },
"id": 6,
"options": {
"legend": { "calcs": ["mean", "max"], "displayMode": "table", "placement": "bottom", "showLegend": true },
"legend": {
"calcs": ["mean", "max"],
"displayMode": "table",
"placement": "bottom",
"showLegend": true
},
"tooltip": { "mode": "multi", "sort": "desc" }
},
"targets": [
@@ -238,7 +243,12 @@
"gridPos": { "h": 8, "w": 12, "x": 12, "y": 7 },
"id": 7,
"options": {
"legend": { "calcs": ["mean", "max"], "displayMode": "table", "placement": "bottom", "showLegend": true },
"legend": {
"calcs": ["mean", "max"],
"displayMode": "table",
"placement": "bottom",
"showLegend": true
},
"tooltip": { "mode": "multi", "sort": "desc" }
},
"targets": [
@@ -298,7 +308,12 @@
"gridPos": { "h": 8, "w": 12, "x": 0, "y": 16 },
"id": 9,
"options": {
"legend": { "calcs": ["mean", "max"], "displayMode": "table", "placement": "bottom", "showLegend": true },
"legend": {
"calcs": ["mean", "max"],
"displayMode": "table",
"placement": "bottom",
"showLegend": true
},
"tooltip": { "mode": "multi", "sort": "desc" }
},
"targets": [
@@ -355,7 +370,12 @@
"gridPos": { "h": 8, "w": 12, "x": 12, "y": 16 },
"id": 10,
"options": {
"legend": { "calcs": ["mean", "max"], "displayMode": "table", "placement": "bottom", "showLegend": true },
"legend": {
"calcs": ["mean", "max"],
"displayMode": "table",
"placement": "bottom",
"showLegend": true
},
"tooltip": { "mode": "multi", "sort": "desc" }
},
"targets": [
@@ -420,7 +440,12 @@
"gridPos": { "h": 8, "w": 8, "x": 0, "y": 25 },
"id": 12,
"options": {
"legend": { "calcs": ["mean", "max"], "displayMode": "table", "placement": "bottom", "showLegend": true },
"legend": {
"calcs": ["mean", "max"],
"displayMode": "table",
"placement": "bottom",
"showLegend": true
},
"tooltip": { "mode": "multi", "sort": "desc" }
},
"targets": [
@@ -467,7 +492,12 @@
"gridPos": { "h": 8, "w": 8, "x": 8, "y": 25 },
"id": 13,
"options": {
"legend": { "calcs": ["mean", "max"], "displayMode": "table", "placement": "bottom", "showLegend": true },
"legend": {
"calcs": ["mean", "max"],
"displayMode": "table",
"placement": "bottom",
"showLegend": true
},
"tooltip": { "mode": "multi", "sort": "desc" }
},
"targets": [
@@ -561,7 +591,12 @@
"gridPos": { "h": 8, "w": 12, "x": 0, "y": 34 },
"id": 16,
"options": {
"legend": { "calcs": ["mean", "max"], "displayMode": "table", "placement": "bottom", "showLegend": true },
"legend": {
"calcs": ["mean", "max"],
"displayMode": "table",
"placement": "bottom",
"showLegend": true
},
"tooltip": { "mode": "multi", "sort": "desc" }
},
"targets": [
@@ -618,7 +653,12 @@
"gridPos": { "h": 8, "w": 12, "x": 12, "y": 34 },
"id": 17,
"options": {
"legend": { "calcs": ["mean", "max"], "displayMode": "table", "placement": "bottom", "showLegend": true },
"legend": {
"calcs": ["mean", "max"],
"displayMode": "table",
"placement": "bottom",
"showLegend": true
},
"tooltip": { "mode": "multi", "sort": "desc" }
},
"targets": [
@@ -683,7 +723,12 @@
"gridPos": { "h": 8, "w": 24, "x": 0, "y": 43 },
"id": 19,
"options": {
"legend": { "calcs": ["mean", "max"], "displayMode": "table", "placement": "bottom", "showLegend": true },
"legend": {
"calcs": ["mean", "max"],
"displayMode": "table",
"placement": "bottom",
"showLegend": true
},
"tooltip": { "mode": "multi", "sort": "desc" }
},
"targets": [
@@ -14,4 +14,3 @@ providers:
allowUiUpdates: true
options:
path: /etc/grafana/provisioning/dashboards
@@ -142,9 +142,7 @@
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{ "color": "green", "value": null }
]
"steps": [{ "color": "green", "value": null }]
},
"unit": "short"
},
@@ -207,7 +205,12 @@
"gridPos": { "h": 8, "w": 12, "x": 0, "y": 7 },
"id": 6,
"options": {
"legend": { "calcs": ["mean", "max"], "displayMode": "table", "placement": "bottom", "showLegend": true },
"legend": {
"calcs": ["mean", "max"],
"displayMode": "table",
"placement": "bottom",
"showLegend": true
},
"tooltip": { "mode": "multi", "sort": "desc" }
},
"targets": [
@@ -254,7 +257,12 @@
"gridPos": { "h": 8, "w": 12, "x": 12, "y": 7 },
"id": 7,
"options": {
"legend": { "calcs": ["mean", "max"], "displayMode": "table", "placement": "bottom", "showLegend": true },
"legend": {
"calcs": ["mean", "max"],
"displayMode": "table",
"placement": "bottom",
"showLegend": true
},
"tooltip": { "mode": "multi", "sort": "desc" }
},
"targets": [
@@ -324,7 +332,12 @@
"gridPos": { "h": 8, "w": 12, "x": 0, "y": 16 },
"id": 9,
"options": {
"legend": { "calcs": ["mean", "max"], "displayMode": "table", "placement": "bottom", "showLegend": true },
"legend": {
"calcs": ["mean", "max"],
"displayMode": "table",
"placement": "bottom",
"showLegend": true
},
"tooltip": { "mode": "multi", "sort": "desc" }
},
"targets": [
@@ -371,7 +384,12 @@
"gridPos": { "h": 8, "w": 12, "x": 12, "y": 16 },
"id": 10,
"options": {
"legend": { "calcs": ["mean", "max"], "displayMode": "table", "placement": "bottom", "showLegend": true },
"legend": {
"calcs": ["mean", "max"],
"displayMode": "table",
"placement": "bottom",
"showLegend": true
},
"tooltip": { "mode": "multi", "sort": "desc" }
},
"targets": [
@@ -418,7 +436,12 @@
"gridPos": { "h": 8, "w": 24, "x": 0, "y": 24 },
"id": 11,
"options": {
"legend": { "calcs": ["mean", "max"], "displayMode": "table", "placement": "right", "showLegend": true },
"legend": {
"calcs": ["mean", "max"],
"displayMode": "table",
"placement": "right",
"showLegend": true
},
"tooltip": { "mode": "multi", "sort": "desc" }
},
"targets": [
@@ -443,4 +466,3 @@
"uid": "nodejs-runtime",
"version": 1
}
@@ -1,10 +1,7 @@
{
"title": "Realtime Native Backend",
"uid": "realtime-native",
"tags": [
"trigger.dev",
"realtime"
],
"tags": ["trigger.dev", "realtime"],
"timezone": "browser",
"schemaVersion": 39,
"refresh": "10s",
@@ -174,9 +171,7 @@
"colorMode": "background",
"graphMode": "area",
"reduceOptions": {
"calcs": [
"lastNotNull"
]
"calcs": ["lastNotNull"]
}
},
"description": "A backstop that finds missed changes means the notify/replay path is leaking. Alert on sustained non-zero."
@@ -500,4 +495,4 @@
"description": "hit/coalesced vs miss = the single-flight cache collapsing same-filter herds. Gate in use near the limit = reconnect stampedes queueing."
}
]
}
}
@@ -186,7 +186,12 @@
"gridPos": { "h": 8, "w": 12, "x": 0, "y": 7 },
"id": 6,
"options": {
"legend": { "calcs": ["mean", "max"], "displayMode": "table", "placement": "bottom", "showLegend": true },
"legend": {
"calcs": ["mean", "max"],
"displayMode": "table",
"placement": "bottom",
"showLegend": true
},
"tooltip": { "mode": "multi", "sort": "desc" }
},
"targets": [
@@ -233,7 +238,12 @@
"gridPos": { "h": 8, "w": 12, "x": 12, "y": 7 },
"id": 7,
"options": {
"legend": { "calcs": ["mean", "max"], "displayMode": "table", "placement": "bottom", "showLegend": true },
"legend": {
"calcs": ["mean", "max"],
"displayMode": "table",
"placement": "bottom",
"showLegend": true
},
"tooltip": { "mode": "multi", "sort": "desc" }
},
"targets": [
@@ -293,7 +303,12 @@
"gridPos": { "h": 8, "w": 12, "x": 0, "y": 16 },
"id": 9,
"options": {
"legend": { "calcs": ["mean", "max"], "displayMode": "table", "placement": "bottom", "showLegend": true },
"legend": {
"calcs": ["mean", "max"],
"displayMode": "table",
"placement": "bottom",
"showLegend": true
},
"tooltip": { "mode": "multi", "sort": "desc" }
},
"targets": [
@@ -350,7 +365,12 @@
"gridPos": { "h": 8, "w": 12, "x": 12, "y": 16 },
"id": 10,
"options": {
"legend": { "calcs": ["mean", "max"], "displayMode": "table", "placement": "bottom", "showLegend": true },
"legend": {
"calcs": ["mean", "max"],
"displayMode": "table",
"placement": "bottom",
"showLegend": true
},
"tooltip": { "mode": "multi", "sort": "desc" }
},
"targets": [
@@ -415,7 +435,12 @@
"gridPos": { "h": 8, "w": 12, "x": 0, "y": 25 },
"id": 13,
"options": {
"legend": { "calcs": ["mean", "max"], "displayMode": "table", "placement": "bottom", "showLegend": true },
"legend": {
"calcs": ["mean", "max"],
"displayMode": "table",
"placement": "bottom",
"showLegend": true
},
"tooltip": { "mode": "multi", "sort": "desc" }
},
"targets": [
@@ -519,7 +544,12 @@
"gridPos": { "h": 8, "w": 24, "x": 0, "y": 34 },
"id": 16,
"options": {
"legend": { "calcs": ["mean", "max"], "displayMode": "table", "placement": "bottom", "showLegend": true },
"legend": {
"calcs": ["mean", "max"],
"displayMode": "table",
"placement": "bottom",
"showLegend": true
},
"tooltip": { "mode": "multi", "sort": "desc" }
},
"targets": [
@@ -15,4 +15,3 @@ datasources:
httpMethod: POST
manageAlerts: true
prometheusType: Prometheus
-1
View File
@@ -30,4 +30,3 @@ scrape_configs:
- job_name: "prometheus"
static_configs:
- targets: ["localhost:9090"]
+1 -1
View File
@@ -5,4 +5,4 @@
"upstream": "host.docker.internal:3030",
"enabled": true
}
]
]
+13 -60
View File
@@ -10,11 +10,7 @@
},
"favicon": "/images/favicon.png",
"contextual": {
"options": [
"copy",
"view",
"claude"
]
"options": ["copy", "view", "claude"]
},
"navigation": {
"dropdowns": [
@@ -40,11 +36,7 @@
"pages": [
{
"group": "Tasks",
"pages": [
"tasks/overview",
"tasks/schemaTask",
"tasks/scheduled"
]
"pages": ["tasks/overview", "tasks/schemaTask", "tasks/scheduled"]
},
"triggering",
"runs",
@@ -57,10 +49,7 @@
"building-with-ai",
{
"group": "MCP Server",
"pages": [
"mcp-introduction",
"mcp-tools"
]
"pages": ["mcp-introduction", "mcp-tools"]
},
"skills",
"mcp-agent-rules"
@@ -74,12 +63,7 @@
"errors-retrying",
{
"group": "Wait",
"pages": [
"wait",
"wait-for",
"wait-until",
"wait-for-token"
]
"pages": ["wait", "wait-for", "wait-until", "wait-for-token"]
},
"queue-concurrency",
"versioning",
@@ -203,10 +187,7 @@
"deployment/atomic-deployment",
{
"group": "Deployment integrations",
"pages": [
"github-integration",
"vercel-integration"
]
"pages": ["github-integration", "vercel-integration"]
}
]
},
@@ -270,19 +251,11 @@
},
{
"group": "Observability",
"pages": [
"observability/query",
"observability/dashboards"
]
"pages": ["observability/query", "observability/dashboards"]
},
{
"group": "Using the Dashboard",
"pages": [
"run-tests",
"troubleshooting-alerts",
"replaying",
"bulk-actions"
]
"pages": ["run-tests", "troubleshooting-alerts", "replaying", "bulk-actions"]
},
{
"group": "Troubleshooting",
@@ -305,30 +278,18 @@
"self-hosting/kubernetes",
{
"group": "Environment variables",
"pages": [
"self-hosting/env/webapp",
"self-hosting/env/supervisor"
]
"pages": ["self-hosting/env/webapp", "self-hosting/env/supervisor"]
},
"open-source-self-hosting"
]
},
{
"group": "Open source",
"pages": [
"open-source-contributing",
"github-repo",
"changelog",
"roadmap"
]
"pages": ["open-source-contributing", "github-repo", "changelog", "roadmap"]
},
{
"group": "Help",
"pages": [
"community",
"help-slack",
"help-email"
]
"pages": ["community", "help-slack", "help-email"]
}
]
},
@@ -471,9 +432,7 @@
"groups": [
{
"group": "Introduction",
"pages": [
"guides/introduction"
]
"pages": ["guides/introduction"]
},
{
"group": "Frameworks",
@@ -539,10 +498,7 @@
},
{
"group": "Migration guides",
"pages": [
"migration-mergent",
"migration-n8n"
]
"pages": ["migration-mergent", "migration-n8n"]
},
{
"group": "Use cases",
@@ -633,10 +589,7 @@
"href": "https://trigger.dev"
},
"api": {
"openapi": [
"openapi.yml",
"v3-openapi.yaml"
],
"openapi": ["openapi.yml", "v3-openapi.yaml"],
"playground": {
"display": "simple"
}
+26 -26
View File
@@ -1,31 +1,31 @@
button~.absolute.peer-hover\:opacity-100 {
color: #000
button ~ .absolute.peer-hover\:opacity-100 {
color: #000;
}
:root {
/* Code block colors - Trigger.dark theme */
--mint-color-background: #121317;
--mint-color-text: #D4D4D4;
--mint-token-constant: #9B99FF;
--mint-token-string: #AFEC73;
--mint-token-comment: #5F6570;
--mint-token-keyword: #E888F8;
--mint-token-parameter: #CCCBFF;
--mint-token-function: #D9F07C;
--mint-token-string-expression: #AFEC73;
--mint-token-punctuation: #878C99;
--mint-token-link: #826DFF;
/* Code block colors - Trigger.dark theme */
--mint-color-background: #121317;
--mint-color-text: #d4d4d4;
--mint-token-constant: #9b99ff;
--mint-token-string: #afec73;
--mint-token-comment: #5f6570;
--mint-token-keyword: #e888f8;
--mint-token-parameter: #cccbff;
--mint-token-function: #d9f07c;
--mint-token-string-expression: #afec73;
--mint-token-punctuation: #878c99;
--mint-token-link: #826dff;
/* Shiki css-variables fallbacks */
--shiki-foreground: #D4D4D4;
--shiki-background: #121317;
--shiki-token-constant: #9B99FF;
--shiki-token-string: #AFEC73;
--shiki-token-comment: #5F6570;
--shiki-token-keyword: #E888F8;
--shiki-token-parameter: #CCCBFF;
--shiki-token-function: #D9F07C;
--shiki-token-string-expression: #AFEC73;
--shiki-token-punctuation: #878C99;
--shiki-token-link: #826DFF;
/* Shiki css-variables fallbacks */
--shiki-foreground: #d4d4d4;
--shiki-background: #121317;
--shiki-token-constant: #9b99ff;
--shiki-token-string: #afec73;
--shiki-token-comment: #5f6570;
--shiki-token-keyword: #e888f8;
--shiki-token-parameter: #cccbff;
--shiki-token-function: #d9f07c;
--shiki-token-string-expression: #afec73;
--shiki-token-punctuation: #878c99;
--shiki-token-link: #826dff;
}
+1 -1
View File
@@ -238,4 +238,4 @@ networks:
supervisor:
name: supervisor
webapp:
name: webapp
name: webapp
+7 -1
View File
@@ -45,7 +45,13 @@ services:
DOCKER_REGISTRY_PASSWORD: ${DOCKER_REGISTRY_PASSWORD:-}
DOCKER_AUTOREMOVE_EXITED_CONTAINERS: 0
healthcheck:
test: ["CMD", "node", "-e", "http.get('http://localhost:8020/health', res => process.exit(res.statusCode === 200 ? 0 : 1)).on('error', () => process.exit(1))"]
test:
[
"CMD",
"node",
"-e",
"http.get('http://localhost:8020/health', res => process.exit(res.statusCode === 200 ? 0 : 1)).on('error', () => process.exit(1))",
]
interval: 30s
timeout: 10s
retries: 5
+1 -1
View File
@@ -18,4 +18,4 @@
"test": "vitest",
"test:watch": "vitest"
}
}
}
+5 -7
View File
@@ -28,9 +28,10 @@ export type LRUMemoryStoreConfig = {
* but will be evicted by LRU when the cache is full.
*/
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export class LRUMemoryStore<TNamespace extends string, TValue = any>
implements Store<TNamespace, TValue>
{
export class LRUMemoryStore<TNamespace extends string, TValue = any> implements Store<
TNamespace,
TValue
> {
readonly name: string;
private readonly cache: LRUCache<string, Entry<TValue>>;
@@ -110,10 +111,7 @@ export class LRUMemoryStore<TNamespace extends string, TValue = any>
}
}
async remove(
namespace: TNamespace,
keys: string | string[]
): Promise<Result<void, CacheError>> {
async remove(namespace: TNamespace, keys: string | string[]): Promise<Result<void, CacheError>> {
try {
const keyArray = Array.isArray(keys) ? keys : [keys];
+4 -3
View File
@@ -9,9 +9,10 @@ export type RedisCacheStoreConfig = {
useModernCacheKeyBuilder?: boolean;
};
export class RedisCacheStore<TNamespace extends string, TValue = any>
implements Store<TNamespace, TValue>
{
export class RedisCacheStore<TNamespace extends string, TValue = any> implements Store<
TNamespace,
TValue
> {
public readonly name = "redis";
private readonly redis: Redis;
@@ -518,7 +518,10 @@ export class ClickhouseClient implements ClickhouseReader, ClickhouseWriter {
};
}
public queryFastStream<TOut extends Record<string, any>, TParams extends Record<string, any>>(req: {
public queryFastStream<
TOut extends Record<string, any>,
TParams extends Record<string, any>,
>(req: {
name: string;
query: string;
columns: Array<string | ColumnExpression>;
@@ -95,7 +95,10 @@ export class NoopClient implements ClickhouseReader, ClickhouseWriter {
};
}
public queryFastStream<TOut extends Record<string, any>, TParams extends Record<string, any>>(req: {
public queryFastStream<
TOut extends Record<string, any>,
TParams extends Record<string, any>,
>(req: {
name: string;
query: string;
columns: string[];
@@ -15,7 +15,7 @@ import {
type QuerySettings,
type FieldMappings,
type TimeRange,
type WhereClauseCondition
type WhereClauseCondition,
} from "@internal/tsql";
import type { ClickhouseReader, QueryStats } from "./types.js";
import { QueryError } from "./errors.js";
@@ -180,9 +180,10 @@ export async function executeTSQL<TOut extends z.ZodSchema>(
try {
// 1. Compile the TSQL query to ClickHouse SQL
// Pass maxRows + 1 to fetch one extra row for overflow detection
const compiledSettings = maxRows !== undefined
? { ...options.querySettings, maxRows: maxRows + 1 }
: options.querySettings;
const compiledSettings =
maxRows !== undefined
? { ...options.querySettings, maxRows: maxRows + 1 }
: options.querySettings;
const { sql, params, columns, hiddenColumns } = compileTSQL(options.query, {
tableSchema: options.tableSchema,
+2 -8
View File
@@ -157,10 +157,7 @@ export function getSessionsQueryBuilder(ch: ClickhouseReader, settings?: ClickHo
});
}
export function getSessionsCountQueryBuilder(
ch: ClickhouseReader,
settings?: ClickHouseSettings
) {
export function getSessionsCountQueryBuilder(ch: ClickhouseReader, settings?: ClickHouseSettings) {
return ch.queryBuilder({
name: "getSessionsCount",
baseQuery: "SELECT count() as count FROM trigger_dev.sessions_v1 FINAL",
@@ -175,10 +172,7 @@ export const SessionTagsQueryResult = z.object({
export type SessionTagsQueryResult = z.infer<typeof SessionTagsQueryResult>;
export function getSessionTagsQueryBuilder(
ch: ClickhouseReader,
settings?: ClickHouseSettings
) {
export function getSessionTagsQueryBuilder(ch: ClickhouseReader, settings?: ClickHouseSettings) {
return ch.queryBuilder({
name: "getSessionTags",
baseQuery: "SELECT DISTINCT arrayJoin(tags) as tag FROM trigger_dev.sessions_v1",
+4 -11
View File
@@ -213,10 +213,7 @@ export function insertTaskEventsV2(ch: ClickhouseWriter, settings?: ClickHouseSe
});
}
export function getTraceSummaryQueryBuilderV2(
ch: ClickhouseReader,
settings?: ClickHouseSettings
) {
export function getTraceSummaryQueryBuilderV2(ch: ClickhouseReader, settings?: ClickHouseSettings) {
return ch.queryBuilderFast<TaskEventSummaryV1Result>({
name: "getTraceEventsV2",
table: "trigger_dev.task_events_v2",
@@ -258,10 +255,7 @@ export function getTraceDetailedSummaryQueryBuilderV2(
});
}
export function getSpanDetailsQueryBuilderV2(
ch: ClickhouseReader,
settings?: ClickHouseSettings
) {
export function getSpanDetailsQueryBuilderV2(ch: ClickhouseReader, settings?: ClickHouseSettings) {
return ch.queryBuilder({
name: "getSpanDetailsV2",
baseQuery:
@@ -283,7 +277,6 @@ export function getTraceEventsForExportQueryBuilderV2(
});
}
// ============================================================================
// Search Table Query Builders (for logs page, using task_events_search_v1)
// ============================================================================
@@ -350,7 +343,7 @@ export const LogDetailV2Result = z.object({
kind: z.string(),
status: z.string(),
duration: z.number().or(z.string()),
attributes_text: z.string()
attributes_text: z.string(),
});
export type LogDetailV2Result = z.output<typeof LogDetailV2Result>;
@@ -376,4 +369,4 @@ export function getLogDetailQueryBuilderV2(ch: ClickhouseReader) {
"attributes_text",
],
});
}
}
@@ -556,9 +556,7 @@ describe("Task Runs V2", () => {
null,
];
const childA_v2: TaskRunInsertArray = [
...childA_v1,
];
const childA_v2: TaskRunInsertArray = [...childA_v1];
childA_v2[TASK_RUN_INDEX.status] = "COMPLETED_SUCCESSFULLY";
childA_v2[TASK_RUN_INDEX._version] = "2";
@@ -676,24 +674,18 @@ describe("Task Runs V2", () => {
null,
];
const childDeleted_v2: TaskRunInsertArray = [
...childDeleted_v1,
];
const childDeleted_v2: TaskRunInsertArray = [...childDeleted_v1];
childDeleted_v2[TASK_RUN_INDEX._version] = "2";
childDeleted_v2[TASK_RUN_INDEX._is_deleted] = 1;
const childWrongRoot: TaskRunInsertArray = [
...childB,
];
const childWrongRoot: TaskRunInsertArray = [...childB];
childWrongRoot[TASK_RUN_INDEX.run_id] = "child_wrong_root";
childWrongRoot[TASK_RUN_INDEX.friendly_id] = "run_child_wrong_root";
childWrongRoot[TASK_RUN_INDEX.root_run_id] = "other_root";
childWrongRoot[TASK_RUN_INDEX.parent_run_id] = "other_root";
childWrongRoot[TASK_RUN_INDEX.span_id] = "span_child_wrong_root";
const childOld: TaskRunInsertArray = [
...childB,
];
const childOld: TaskRunInsertArray = [...childB];
childOld[TASK_RUN_INDEX.run_id] = "child_old";
childOld[TASK_RUN_INDEX.created_at] = oldCreatedAt;
childOld[TASK_RUN_INDEX.updated_at] = oldCreatedAt;
+40 -43
View File
@@ -1563,52 +1563,49 @@ describe("Field Mapping Tests", () => {
}
);
clickhouseTest(
"should handle field mapping with IN clause",
async ({ clickhouseContainer }) => {
const client = new ClickhouseClient({
name: "test",
url: clickhouseContainer.getConnectionUrl(),
});
clickhouseTest("should handle field mapping with IN clause", async ({ clickhouseContainer }) => {
const client = new ClickhouseClient({
name: "test",
url: clickhouseContainer.getConnectionUrl(),
});
const insert = insertTaskRuns(client, { async_insert: 0 });
const insert = insertTaskRuns(client, { async_insert: 0 });
// Insert test runs with different projects
await insert([
createTaskRun({
run_id: "run_fm_in1",
project_id: "proj_tenant1",
status: "COMPLETED_SUCCESSFULLY",
}),
createTaskRun({
run_id: "run_fm_in2",
project_id: "proj_other",
organization_id: "org_tenant1",
status: "PENDING",
}),
]);
// Insert test runs with different projects
await insert([
createTaskRun({
run_id: "run_fm_in1",
project_id: "proj_tenant1",
status: "COMPLETED_SUCCESSFULLY",
}),
createTaskRun({
run_id: "run_fm_in2",
project_id: "proj_other",
organization_id: "org_tenant1",
status: "PENDING",
}),
]);
// Query using IN clause with external project_ref values
const [error, result] = await executeTSQL(client, {
name: "test-field-mapping-in",
query:
"SELECT run_id FROM task_runs WHERE project_ref IN ('my-project-ref', 'other-project')",
schema: z.object({ run_id: z.string() }),
enforcedWhereClause: {
organization_id: { op: "eq", value: "org_tenant1" },
// Query using IN clause with external project_ref values
const [error, result] = await executeTSQL(client, {
name: "test-field-mapping-in",
query:
"SELECT run_id FROM task_runs WHERE project_ref IN ('my-project-ref', 'other-project')",
schema: z.object({ run_id: z.string() }),
enforcedWhereClause: {
organization_id: { op: "eq", value: "org_tenant1" },
},
tableSchema: [fieldMappingSchema],
fieldMappings: {
project: {
proj_tenant1: "my-project-ref",
proj_other: "other-project",
},
tableSchema: [fieldMappingSchema],
fieldMappings: {
project: {
proj_tenant1: "my-project-ref",
proj_other: "other-project",
},
},
});
},
});
expect(error).toBeNull();
expect(result?.rows).toHaveLength(2);
expect(result?.rows?.map((r) => r.run_id).sort()).toEqual(["run_fm_in1", "run_fm_in2"]);
}
);
expect(error).toBeNull();
expect(result?.rows).toHaveLength(2);
expect(result?.rows?.map((r) => r.run_id).sort()).toEqual(["run_fm_in1", "run_fm_in2"]);
});
});
+5 -1
View File
@@ -62,7 +62,11 @@ class HttpTransport {
return options?.signal ?? AbortSignal.timeout(this.opts.timeoutMs);
}
async post<T = unknown>(path: string, body: unknown, options?: RequestOptions): Promise<T | undefined> {
async post<T = unknown>(
path: string,
body: unknown,
options?: RequestOptions
): Promise<T | undefined> {
const url = `${this.opts.gatewayUrl}${path}`;
const response = await fetch(url, {
@@ -175,4 +175,4 @@
"schemas": {},
"tables": {}
}
}
}
@@ -303,10 +303,7 @@
"compositePrimaryKeys": {
"chat_turn_evals_chat_id_turn_pk": {
"name": "chat_turn_evals_chat_id_turn_pk",
"columns": [
"chat_id",
"turn"
]
"columns": ["chat_id", "turn"]
}
},
"uniqueConstraints": {},
@@ -441,4 +438,4 @@
"schemas": {},
"tables": {}
}
}
}
@@ -17,4 +17,4 @@
"breakpoints": true
}
]
}
}
@@ -33,10 +33,7 @@ function normalizeConnectionString(value) {
}
}
const journalPath = join(
dirname(fileURLToPath(import.meta.url)),
"drizzle/meta/_journal.json"
);
const journalPath = join(dirname(fileURLToPath(import.meta.url)), "drizzle/meta/_journal.json");
const sql = postgres(normalizeConnectionString(connectionString), {
max: 1,
prepare: false,
@@ -59,9 +56,7 @@ async function main() {
}
const pending = entries.filter((e) => e.when > lastAppliedAt);
console.log(
`${entries.length} migration(s) found, ${entries.length - pending.length} applied`
);
console.log(`${entries.length} migration(s) found, ${entries.length - pending.length} applied`);
if (pending.length > 0) {
console.log(`${pending.length} pending migration(s):`);
@@ -1,6 +1,12 @@
import { and, desc, eq, isNull, sql } from "drizzle-orm";
import type { DashboardAgentDb } from "./client.js";
import { chats, chatSessions, chatTurnEvals, type ChatSession, type NewChatTurnEval } from "./schema.js";
import {
chats,
chatSessions,
chatTurnEvals,
type ChatSession,
type NewChatTurnEval,
} from "./schema.js";
/**
* The access-pattern layer. Every query that touches user data is scoped by
@@ -64,11 +70,7 @@ export async function getChatMessages(
.select({ messages: chats.messages })
.from(chats)
.where(
and(
eq(chats.id, params.chatId),
eq(chats.userId, params.userId),
isNull(chats.deletedAt)
)
and(eq(chats.id, params.chatId), eq(chats.userId, params.userId), isNull(chats.deletedAt))
)
.limit(1);
return rows[0]?.messages ?? null;
@@ -175,11 +177,7 @@ export async function setChatTitleIfDefault(
.update(chats)
.set({ title: params.title, updatedAt: sql`now()` })
.where(
and(
eq(chats.id, params.chatId),
eq(chats.title, DEFAULT_CHAT_TITLE),
isNull(chats.deletedAt)
)
and(eq(chats.id, params.chatId), eq(chats.title, DEFAULT_CHAT_TITLE), isNull(chats.deletedAt))
);
}
@@ -195,7 +195,12 @@ const Verdict = z.object({
.min(1)
.max(5)
.describe("Does the answer directly address the user's question? 5 = fully, 1 = not at all."),
concise: z.number().int().min(1).max(5).describe("Direct and free of padding. Do not reward length."),
concise: z
.number()
.int()
.min(1)
.max(5)
.describe("Direct and free of padding. Do not reward length."),
});
const JUDGE_SYSTEM = [
@@ -246,48 +251,43 @@ const TOOL_CASES: Array<{ question: string; expect: string }> = [
const TOOL_SELECTION_THRESHOLD = 0.83; // tolerate ~2/12 misses; a trend reds the suite
describe.skipIf(!HAS_KEY)("dashboardAgent evals (real model)", () => {
it(
"tool selection: picks the right tool for the question",
async () => {
const results: Array<{ question: string; expected: string; got: string; ok: boolean }> = [];
for (const c of TOOL_CASES) {
const { calls } = await runCase(c.question);
const got = calls[0]?.tool ?? "(none)";
results.push({ question: c.question, expected: c.expect, got, ok: got === c.expect });
}
it("tool selection: picks the right tool for the question", async () => {
const results: Array<{ question: string; expected: string; got: string; ok: boolean }> = [];
for (const c of TOOL_CASES) {
const { calls } = await runCase(c.question);
const got = calls[0]?.tool ?? "(none)";
results.push({ question: c.question, expected: c.expect, got, ok: got === c.expect });
}
const passed = results.filter((r) => r.ok).length;
const rate = passed / results.length;
// Surface the full table so a failing case is diagnosable, not just a number.
// process.stdout.write (not console.log) so it survives vitest's console intercept.
process.stdout.write(
`\ntool selection: ${passed}/${results.length} (${(rate * 100).toFixed(0)}%)\n` +
results
.map((r) => ` ${r.ok ? "PASS" : "FAIL"} ${r.got.padEnd(18)} (want ${r.expected}) ${r.question}`)
.join("\n") +
"\n"
);
const passed = results.filter((r) => r.ok).length;
const rate = passed / results.length;
// Surface the full table so a failing case is diagnosable, not just a number.
// process.stdout.write (not console.log) so it survives vitest's console intercept.
process.stdout.write(
`\ntool selection: ${passed}/${results.length} (${(rate * 100).toFixed(0)}%)\n` +
results
.map(
(r) =>
` ${r.ok ? "PASS" : "FAIL"} ${r.got.padEnd(18)} (want ${r.expected}) ${r.question}`
)
.join("\n") +
"\n"
);
expect(rate).toBeGreaterThanOrEqual(TOOL_SELECTION_THRESHOLD);
},
180_000
);
expect(rate).toBeGreaterThanOrEqual(TOOL_SELECTION_THRESHOLD);
}, 180_000);
it(
"answer quality: grounded and on-question (LLM judge)",
async () => {
const question = "What errors are happening in this environment? Summarize the top ones.";
const { calls, answer } = await runCase(question);
it("answer quality: grounded and on-question (LLM judge)", async () => {
const question = "What errors are happening in this environment? Summarize the top ones.";
const { calls, answer } = await runCase(question);
expect(calls[0]?.tool).toBe("list_errors");
expect(answer.length).toBeGreaterThan(0);
expect(calls[0]?.tool).toBe("list_errors");
expect(answer.length).toBeGreaterThan(0);
const verdict = await judge({ question, toolData: FIXTURES.list_errors, answer });
process.stdout.write(`\nanswer:\n${answer}\n\njudge: ${JSON.stringify(verdict)}\n`);
const verdict = await judge({ question, toolData: FIXTURES.list_errors, answer });
process.stdout.write(`\nanswer:\n${answer}\n\njudge: ${JSON.stringify(verdict)}\n`);
expect(verdict.grounded).toBeGreaterThanOrEqual(4);
expect(verdict.answersQuestion).toBeGreaterThanOrEqual(4);
},
120_000
);
expect(verdict.grounded).toBeGreaterThanOrEqual(4);
expect(verdict.answersQuestion).toBeGreaterThanOrEqual(4);
}, 120_000);
});
@@ -302,7 +302,9 @@ describe("buildDashboardAgentTools", () => {
category: "user_code_error",
likelyCause: "processOrder throws when items is empty.",
confidence: "high",
evidence: [{ type: "error", detail: "Error: order has no items", reference: "run_abc123" }],
evidence: [
{ type: "error", detail: "Error: order has no items", reference: "run_abc123" },
],
nextSteps: ["Validate the payload before triggering."],
},
],
@@ -45,8 +45,7 @@ let dbClient: DashboardAgentDbClient | undefined;
function getDb(): DashboardAgentDbClient {
if (!dbClient) {
const connectionString =
process.env.DASHBOARD_AGENT_DATABASE_URL ?? process.env.DATABASE_URL;
const connectionString = process.env.DASHBOARD_AGENT_DATABASE_URL ?? process.env.DATABASE_URL;
if (!connectionString) {
throw new Error(
"DASHBOARD_AGENT_DATABASE_URL (or DATABASE_URL) must be set for the dashboard agent"
@@ -182,7 +181,9 @@ async function generateAndSaveTitle(
const { text } = await generateText({
model:
locals.get(dashboardAgentModelKey) ??
registry.languageModel((resolved.model ?? "anthropic:claude-haiku-4-5") as `anthropic:${string}`),
registry.languageModel(
(resolved.model ?? "anthropic:claude-haiku-4-5") as `anthropic:${string}`
),
system: resolved.text,
prompt: userText,
...resolved.toAISDKTelemetry(),
@@ -373,7 +374,9 @@ export const dashboardAgent = chat.agent({
// prompt's model through the provider registry.
model:
locals.get(dashboardAgentModelKey) ??
registry.languageModel((resolved.model ?? "anthropic:claude-sonnet-4-6") as `anthropic:${string}`),
registry.languageModel(
(resolved.model ?? "anthropic:claude-sonnet-4-6") as `anthropic:${string}`
),
messages,
abortSignal: signal,
// toStreamTextOptions() defaults to a single step; override so the model
@@ -25,10 +25,11 @@ const JUDGE_MODEL = "claude-sonnet-4-6";
let dbClient: DashboardAgentDbClient | undefined;
function getEvalDb(): DashboardAgentDbClient {
if (!dbClient) {
const connectionString =
process.env.DASHBOARD_AGENT_DATABASE_URL ?? process.env.DATABASE_URL;
const connectionString = process.env.DASHBOARD_AGENT_DATABASE_URL ?? process.env.DATABASE_URL;
if (!connectionString) {
throw new Error("DASHBOARD_AGENT_DATABASE_URL (or DATABASE_URL) must be set for the eval task");
throw new Error(
"DASHBOARD_AGENT_DATABASE_URL (or DATABASE_URL) must be set for the eval task"
);
}
dbClient = createDashboardAgentDb(connectionString, { max: 2 });
}
@@ -77,8 +78,15 @@ const TurnEval = z.object({
.int()
.min(1)
.max(5)
.describe("Does the answer use only facts from the tool results? Penalize invented ids/counts/status. 5 = fully grounded."),
answered: z.number().int().min(1).max(5).describe("Does it directly answer the question? 5 = fully."),
.describe(
"Does the answer use only facts from the tool results? Penalize invented ids/counts/status. 5 = fully grounded."
),
answered: z
.number()
.int()
.min(1)
.max(5)
.describe("Does it directly answer the question? 5 = fully."),
concise: z.number().int().min(1).max(5).describe("Direct, no padding. Do not reward length."),
// Insight classification.
intentCategory: z
@@ -86,17 +94,25 @@ const TurnEval = z.object({
.describe("What the user was trying to do."),
outcome: z
.enum(["resolved", "partial", "unresolved", "deflected"])
.describe("Did the agent actually help? deflected = sent the user elsewhere without answering."),
.describe(
"Did the agent actually help? deflected = sent the user elsewhere without answering."
),
sentiment: z.enum(["positive", "neutral", "negative", "frustrated"]),
capabilityGap: z
.boolean()
.describe("The agent lacked a tool, data, or permission needed to fully help."),
docsGap: z.boolean().describe("A how-to the agent answered weakly or that better docs would solve."),
docsGap: z
.boolean()
.describe("A how-to the agent answered weakly or that better docs would solve."),
supportOpportunity: z
.boolean()
.describe("The user seems stuck, blocked, or frustrated and would benefit from a human follow-up."),
.describe(
"The user seems stuck, blocked, or frustrated and would benefit from a human follow-up."
),
featureRequest: z.boolean().describe("The user wants something the product does not do."),
topics: z.array(z.string()).describe("1-3 short topic tags, e.g. 'concurrency', 'failed deploys'."),
topics: z
.array(z.string())
.describe("1-3 short topic tags, e.g. 'concurrency', 'failed deploys'."),
signals: z
.array(
z.object({
@@ -28,7 +28,8 @@ export const systemPrompt = prompts.define({
// repo, so the agent has the source-reading tools too.
export const codeSystemPrompt = prompts.define({
id: "dashboard-agent-system-code",
description: "System prompt for the in-dashboard agent when the project's GitHub repo is connected.",
description:
"System prompt for the in-dashboard agent when the project's GitHub repo is connected.",
model: `anthropic:${DASHBOARD_AGENT_MODEL}`,
content: DASHBOARD_AGENT_CODE_SYSTEM_PROMPT,
});
@@ -67,7 +67,12 @@ afterAll(async () => {
describe("repo-tools", () => {
it("get_repo_info returns the connected repo and pinned commit", async () => {
const res = await call(tools.get_repo_info, {});
expect(res).toEqual({ owner: "acme", repo: "demo", sha: "deadbeefdeadbeef", defaultBranch: "main" });
expect(res).toEqual({
owner: "acme",
repo: "demo",
sha: "deadbeefdeadbeef",
defaultBranch: "main",
});
});
it("read_file reads a file from the workspace", async () => {
@@ -78,7 +83,11 @@ describe("repo-tools", () => {
});
it("read_file honors a line range", async () => {
const res: any = await call(tools.read_file, { path: "src/trigger/order.ts", startLine: 2, endLine: 2 });
const res: any = await call(tools.read_file, {
path: "src/trigger/order.ts",
startLine: 2,
endLine: 2,
});
expect(res.content).toBe("const LIMIT = 10000;");
expect(res.startLine).toBe(2);
expect(res.endLine).toBe(2);
@@ -99,7 +108,10 @@ describe("repo-tools", () => {
it("read_file with runId reads the run's pinned commit", async () => {
const def: any = await call(tools.read_file, { path: "src/trigger/order.ts" });
expect(def.content).toContain("const LIMIT = 10000;");
const pinned: any = await call(tools.read_file, { path: "src/trigger/order.ts", runId: "run_pinned" });
const pinned: any = await call(tools.read_file, {
path: "src/trigger/order.ts",
runId: "run_pinned",
});
expect(pinned.error).toBeUndefined();
expect(pinned.content).toContain("const LIMIT = 5000;");
});
@@ -110,14 +122,19 @@ describe("repo-tools", () => {
});
it("read_file with an unresolvable runId errors instead of falling back", async () => {
const res: any = await call(tools.read_file, { path: "src/trigger/order.ts", runId: "run_unknown" });
const res: any = await call(tools.read_file, {
path: "src/trigger/order.ts",
runId: "run_unknown",
});
expect(res.error).toMatch(/Couldn't resolve the source/);
});
it.runIf(hasRg)("search_code finds a match (and does not hang on stdin)", async () => {
const res: any = await call(tools.search_code, { query: "const LIMIT" });
expect(res.error).toBeUndefined();
expect(res.matches.some((m: any) => String(m.file).includes("order.ts") && /LIMIT/.test(m.text))).toBe(true);
expect(
res.matches.some((m: any) => String(m.file).includes("order.ts") && /LIMIT/.test(m.text))
).toBe(true);
});
it.runIf(hasRg)("list_files lists workspace files", async () => {
@@ -86,7 +86,8 @@ async function ensureWorkspace(snapshot: RepoSnapshot): Promise<string> {
const length = Number(res.headers.get("content-length") ?? 0);
if (length > MAX_ARCHIVE_BYTES) throw new Error(`archive too large (${length} bytes)`);
const bytes = new Uint8Array(await res.arrayBuffer());
if (bytes.length > MAX_ARCHIVE_BYTES) throw new Error(`archive too large (${bytes.length} bytes)`);
if (bytes.length > MAX_ARCHIVE_BYTES)
throw new Error(`archive too large (${bytes.length} bytes)`);
const scratch = await mkdtemp(join(tmpdir(), "dashboard-agent-tar-"));
tarPath = join(scratch, "repo.tar.gz");
@@ -149,7 +150,8 @@ export function buildRepoTools(
// (resolved server-side), otherwise the default tracked-branch snapshot.
async function snapshotFor(runId?: string): Promise<RepoSnapshot | { error: string }> {
if (!runId) return defaultSnapshot;
if (!resolveRunSnapshot) return { error: "Reading a specific run's source isn't available here." };
if (!resolveRunSnapshot)
return { error: "Reading a specific run's source isn't available here." };
const snap = await resolveRunSnapshot(runId);
return (
snap ?? {
@@ -177,7 +179,12 @@ export function buildRepoTools(
execute: async ({ runId }) => {
const snap = await snapshotFor(runId);
if ("error" in snap) return snap;
return { owner: snap.owner, repo: snap.repo, sha: snap.sha, defaultBranch: snap.defaultBranch };
return {
owner: snap.owner,
repo: snap.repo,
sha: snap.sha,
defaultBranch: snap.defaultBranch,
};
},
}),
@@ -199,8 +206,14 @@ export function buildRepoTools(
const cwd = realSub ?? sub;
try {
const { stdout } = await execFileAsync("rg", args, { cwd, maxBuffer: 16 * 1024 * 1024 });
const files = stdout.split("\n").filter(Boolean).map((f) => relative(workdir, resolve(cwd, f)));
return { files: files.slice(0, MAX_LIST_FILES), truncated: files.length > MAX_LIST_FILES };
const files = stdout
.split("\n")
.filter(Boolean)
.map((f) => relative(workdir, resolve(cwd, f)));
return {
files: files.slice(0, MAX_LIST_FILES),
truncated: files.length > MAX_LIST_FILES,
};
} catch (error) {
// rg exits 1 when there are no matches; treat as empty, not an error.
if ((error as { code?: number }).code === 1) return { files: [], truncated: false };
@@ -256,14 +269,19 @@ export function buildRepoTools(
// in a spawned process) and blocks forever. The "." makes it search files.
args.push("-e", query, ".");
try {
const { stdout } = await execFileAsync("rg", args, { cwd: workdir, maxBuffer: 16 * 1024 * 1024 });
const { stdout } = await execFileAsync("rg", args, {
cwd: workdir,
maxBuffer: 16 * 1024 * 1024,
});
const matches = stdout
.split("\n")
.filter(Boolean)
.slice(0, cap)
.map((line) => {
const m = line.match(/^([^:]+):(\d+):(.*)$/);
return m ? { file: m[1], line: Number(m[2]), text: m[3].slice(0, 300) } : { text: line };
return m
? { file: m[1], line: Number(m[2]), text: m[3].slice(0, 300) }
: { text: line };
});
return { matches, truncated: matches.length >= cap };
} catch (error) {
@@ -48,12 +48,20 @@ export const listRunsSchema = tool({
errorId: z
.string()
.optional()
.describe("Only runs that hit this error group (an error_... id from list_errors/get_error)."),
.describe(
"Only runs that hit this error group (an error_... id from list_errors/get_error)."
),
period: z
.string()
.optional()
.describe("Relative window, e.g. 1h, 24h, 7d. Max 30d; larger values are capped at 30d."),
limit: z.number().int().positive().max(50).optional().describe("Max runs to return (default 10)."),
limit: z
.number()
.int()
.positive()
.max(50)
.optional()
.describe("Max runs to return (default 10)."),
}),
});
@@ -119,7 +127,9 @@ export const getQuerySchemaSchema = tool({
table: z
.string()
.optional()
.describe("A table name (e.g. 'runs') to get its columns. Omit to list the available tables."),
.describe(
"A table name (e.g. 'runs') to get its columns. Omit to list the available tables."
),
}),
});
@@ -129,11 +139,15 @@ export const runQuerySchema = tool({
inputSchema: z.object({
query: z
.string()
.describe("The TRQL query. A read-only SELECT over runs / metrics / llm_metrics / llm_models."),
.describe(
"The TRQL query. A read-only SELECT over runs / metrics / llm_metrics / llm_models."
),
period: z
.string()
.optional()
.describe("Time window shorthand like '24h', '7d', '30d' (max 30d), applied to the table's time column."),
.describe(
"Time window shorthand like '24h', '7d', '30d' (max 30d), applied to the table's time column."
),
}),
});
@@ -141,7 +155,9 @@ export const askSupportSchema = tool({
description:
"Ask the Trigger.dev support assistant a question about how Trigger.dev works: docs, concepts, features, configuration, best practices, and troubleshooting how-tos (e.g. 'how do retries work?', 'how do I set a concurrency limit?', 'does Trigger.dev support cron schedules?'). Use this for product/knowledge questions, NOT for the user's own runs, errors, or data (use the read and query tools for those). Returns a composed answer.",
inputSchema: z.object({
question: z.string().describe("The user's question about how Trigger.dev works, in natural language."),
question: z
.string()
.describe("The user's question about how Trigger.dev works, in natural language."),
}),
});
@@ -183,7 +199,9 @@ export const diagnosisBlockSchema = z.object({
.describe("Your classification of the root cause."),
likelyCause: z
.string()
.describe("The most probable root cause, in specific terms — name the code, config, or dependency."),
.describe(
"The most probable root cause, in specific terms — name the code, config, or dependency."
),
confidence: z
.enum(["high", "medium", "low"])
.describe("How confident you are in this diagnosis given the evidence. Be honest."),
@@ -208,7 +226,9 @@ export const diagnosisBlockSchema = z.object({
),
})
)
.describe("The concrete signals behind the diagnosis. Cite real ids, spans, versions, or file:line."),
.describe(
"The concrete signals behind the diagnosis. Cite real ids, spans, versions, or file:line."
),
impact: z
.string()
.optional()
@@ -220,7 +240,9 @@ export const diagnosisBlockSchema = z.object({
label: z.string().describe("Button text, e.g. 'View run' or 'Read the retries docs'."),
kind: z
.enum(["view_run", "docs"])
.describe("view_run links to a run page in this environment; docs opens an external URL."),
.describe(
"view_run links to a run page in this environment; docs opens an external URL."
),
target: z.string().describe("For view_run: a run id (run_...). For docs: an https URL."),
})
)
@@ -244,13 +266,19 @@ export const chartBlockSchema = z.object({
period: z
.string()
.optional()
.describe("Time window shorthand like '24h', '7d', '30d' (max 30d), applied to the table's time column."),
.describe(
"Time window shorthand like '24h', '7d', '30d' (max 30d), applied to the table's time column."
),
chartType: z
.enum(["line", "bar"])
.describe("line for trends over time, bar for comparing categories. Stack with `stacked` for composition."),
.describe(
"line for trends over time, bar for comparing categories. Stack with `stacked` for composition."
),
xAxisColumn: z
.string()
.describe("The result column for the x-axis: a time bucket (for line) or a category (for bar)."),
.describe(
"The result column for the x-axis: a time bucket (for line) or a category (for bar)."
),
yAxisColumns: z
.array(z.string())
.min(1)
@@ -258,15 +286,23 @@ export const chartBlockSchema = z.object({
groupByColumn: z
.string()
.nullish()
.describe("Optional result column to split a single yAxisColumn into one series per distinct value."),
stacked: z.boolean().optional().describe("Stack the series (cumulative/composition). Default false."),
.describe(
"Optional result column to split a single yAxisColumn into one series per distinct value."
),
stacked: z
.boolean()
.optional()
.describe("Stack the series (cumulative/composition). Default false."),
aggregation: z
.enum(["sum", "avg", "count", "min", "max"])
.optional()
.describe("How to combine values that share an x point. Default sum."),
});
export const viewBlockSchema = z.discriminatedUnion("type", [diagnosisBlockSchema, chartBlockSchema]);
export const viewBlockSchema = z.discriminatedUnion("type", [
diagnosisBlockSchema,
chartBlockSchema,
]);
export type DiagnosisBlock = z.infer<typeof diagnosisBlockSchema>;
export type ChartBlock = z.infer<typeof chartBlockSchema>;
@@ -303,7 +339,10 @@ export const listFilesSchema = tool({
"List source files in the connected repository (respecting .gitignore). Optionally filter by a glob like '**/*.ts' or scope to a subdirectory. Use this to find where something lives before reading it.",
inputSchema: z.object({
glob: z.string().optional().describe("Glob filter, e.g. 'src/**/*.ts' or '*.json'."),
path: z.string().optional().describe("Subdirectory (relative to repo root) to scope the listing to."),
path: z
.string()
.optional()
.describe("Subdirectory (relative to repo root) to scope the listing to."),
runId: runIdField,
}),
});
@@ -312,7 +351,9 @@ export const readFileSchema = tool({
description:
"Read a file from the connected repository by its path relative to the repo root. Optionally restrict to a line range. Use this to read the actual task source behind a run or error.",
inputSchema: z.object({
path: z.string().describe("File path relative to the repo root, e.g. src/trigger/processOrder.ts."),
path: z
.string()
.describe("File path relative to the repo root, e.g. src/trigger/processOrder.ts."),
startLine: z.number().int().positive().optional().describe("First line to include (1-based)."),
endLine: z.number().int().positive().optional().describe("Last line to include (1-based)."),
runId: runIdField,
@@ -325,7 +366,13 @@ export const searchCodeSchema = tool({
inputSchema: z.object({
query: z.string().describe("The ripgrep pattern to search for."),
glob: z.string().optional().describe("Restrict the search to files matching this glob."),
maxResults: z.number().int().positive().max(80).optional().describe("Max matches to return (default 40)."),
maxResults: z
.number()
.int()
.positive()
.max(80)
.optional()
.describe("Max matches to return (default 40)."),
runId: runIdField,
}),
});
+35 -11
View File
@@ -174,7 +174,11 @@ function curateTrace(data: unknown) {
for (const child of span.children ?? []) walk(child, depth + 1);
};
walk(root, 0);
return { traceId: (data as any)?.trace?.traceId, spans, truncated: spans.length >= MAX_TRACE_SPANS };
return {
traceId: (data as any)?.trace?.traceId,
spans,
truncated: spans.length >= MAX_TRACE_SPANS,
};
}
function curateErrors(data: unknown) {
@@ -260,7 +264,13 @@ export function buildDashboardAgentTools(ctx: DashboardAgentToolContext): ToolSe
if (!result.ok) return null;
const d = result.data as Partial<RepoSnapshot> | undefined;
if (!d?.tarballUrl || !d.owner || !d.repo || !d.sha) return null;
return { tarballUrl: d.tarballUrl, owner: d.owner, repo: d.repo, sha: d.sha, defaultBranch: d.defaultBranch };
return {
tarballUrl: d.tarballUrl,
owner: d.owner,
repo: d.repo,
sha: d.sha,
defaultBranch: d.defaultBranch,
};
};
const apiTools: ToolSet = {
@@ -280,7 +290,11 @@ export function buildDashboardAgentTools(ctx: DashboardAgentToolContext): ToolSe
if (!hasAuth) return NO_AUTH;
const ref = inputRef ?? projectRef;
if (!ref) return { error: "No project ref available. Ask the user which project." };
const result = await apiGet(origin, `/api/v1/projects/${ref}/environments`, userActorToken!);
const result = await apiGet(
origin,
`/api/v1/projects/${ref}/environments`,
userActorToken!
);
if (!result.ok) return { error: `Couldn't list environments (status ${result.status}).` };
return curateEnvironments(result.data);
},
@@ -340,7 +354,8 @@ export function buildDashboardAgentTools(ctx: DashboardAgentToolContext): ToolSe
const envJwt = await getEnvJwt();
if (!envJwt) return { error: "No current environment is available to read runs from." };
const result = await apiGet(origin, `/api/v1/runs/${runId}/trace`, envJwt);
if (!result.ok) return { error: `Couldn't get the trace for ${runId} (status ${result.status}).` };
if (!result.ok)
return { error: `Couldn't get the trace for ${runId} (status ${result.status}).` };
return curateTrace(result.data);
},
}),
@@ -368,7 +383,8 @@ export function buildDashboardAgentTools(ctx: DashboardAgentToolContext): ToolSe
const envJwt = await getEnvJwt();
if (!envJwt) return { error: "No current environment is available to read errors from." };
const result = await apiGet(origin, `/api/v1/errors/${errorId}`, envJwt);
if (!result.ok) return { error: `Couldn't get error ${errorId} (status ${result.status}).` };
if (!result.ok)
return { error: `Couldn't get error ${errorId} (status ${result.status}).` };
return curateError(result.data);
},
}),
@@ -379,7 +395,8 @@ export function buildDashboardAgentTools(ctx: DashboardAgentToolContext): ToolSe
const envJwt = await getEnvJwt();
if (!envJwt) return { error: "No current environment is available to query." };
const result = await apiGet(origin, "/api/v1/query/schema", envJwt);
if (!result.ok) return { error: `Couldn't load the query schema (status ${result.status}).` };
if (!result.ok)
return { error: `Couldn't load the query schema (status ${result.status}).` };
const tables = ((result.data as { tables?: any[] })?.tables ?? []) as any[];
// No table → list what's queryable; a table → its columns.
if (!table) {
@@ -393,7 +410,9 @@ export function buildDashboardAgentTools(ctx: DashboardAgentToolContext): ToolSe
}
const match = tables.find((t) => t.name === table);
if (!match) {
return { error: `Unknown table "${table}". Available: ${tables.map((t) => t.name).join(", ")}.` };
return {
error: `Unknown table "${table}". Available: ${tables.map((t) => t.name).join(", ")}.`,
};
}
return {
name: match.name,
@@ -433,7 +452,9 @@ export function buildDashboardAgentTools(ctx: DashboardAgentToolContext): ToolSe
// the model can fix the query rather than the turn dying.
const data = (await res.json().catch(() => ({}))) as { results?: unknown; error?: string };
if (!res.ok) return { error: data.error ?? `Query failed (status ${res.status}).` };
const rows = Array.isArray(data.results) ? (data.results as Array<Record<string, unknown>>) : [];
const rows = Array.isArray(data.results)
? (data.results as Array<Record<string, unknown>>)
: [];
const cap = 200;
return { rows: rows.slice(0, cap), rowCount: rows.length, truncated: rows.length > cap };
},
@@ -448,7 +469,8 @@ export function buildDashboardAgentTools(ctx: DashboardAgentToolContext): ToolSe
execute: async ({ question }) => {
const url = process.env.SUPPORT_ASK_URL ?? "http://localhost:3939/api/ask";
const secret = process.env.SUPPORT_ASK_SECRET;
if (!secret) return { error: "The support assistant isn't configured in this environment." };
if (!secret)
return { error: "The support assistant isn't configured in this environment." };
const controller = new AbortController();
const timer = setTimeout(() => controller.abort(), 60_000);
try {
@@ -461,7 +483,8 @@ export function buildDashboardAgentTools(ctx: DashboardAgentToolContext): ToolSe
}),
signal: controller.signal,
});
if (!res.ok) return { error: `The support assistant request failed (status ${res.status}).` };
if (!res.ok)
return { error: `The support assistant request failed (status ${res.status}).` };
// The endpoint streams a UI-message SSE; accumulate the text-delta
// chunks into the final answer (tool-output-error chunks are noise).
const body = await res.text();
@@ -472,7 +495,8 @@ export function buildDashboardAgentTools(ctx: DashboardAgentToolContext): ToolSe
if (!payload || payload === "[DONE]") continue;
try {
const chunk = JSON.parse(payload) as { type?: string; delta?: string };
if (chunk.type === "text-delta" && typeof chunk.delta === "string") answer += chunk.delta;
if (chunk.type === "text-delta" && typeof chunk.delta === "string")
answer += chunk.delta;
} catch {
// Skip keepalives / non-JSON lines.
}
+1 -1
View File
@@ -25,4 +25,4 @@
"build": "pnpm run clean && tsc --noEmit false --outDir dist --declaration",
"dev": "tsc --noEmit false --outDir dist --declaration --watch"
}
}
}
@@ -39,8 +39,7 @@ export default function Email(props: MfaEnabledEmailProps) {
</Text>
<Text style={paragraphLight}>
Keep your authenticator app safe and secured
<br />
Never share your MFA codes with anyone
<br /> Never share your MFA codes with anyone
<br /> Store your recovery codes in a secure location
</Text>
<Text
+1 -3
View File
@@ -2,9 +2,7 @@ import { ReactElement } from "react";
import { z } from "zod";
import AlertAttemptFailureEmail, { AlertAttemptEmailSchema } from "../emails/alert-attempt-failure";
import AlertErrorGroupEmail, {
AlertErrorGroupEmailSchema,
} from "../emails/alert-error-group";
import AlertErrorGroupEmail, { AlertErrorGroupEmailSchema } from "../emails/alert-error-group";
import AlertRunFailureEmail, { AlertRunEmailSchema } from "../emails/alert-run-failure";
import { setGlobalBasePath } from "../emails/components/BasePath";
import AlertDeploymentFailureEmail, {
@@ -1,24 +1,24 @@
import { render } from "@react-email/render";
import { EmailError, MailMessage, MailTransport, PlainTextMailMessage } from "./index";
import nodemailer from "nodemailer"
import { SESv2Client, SendEmailCommand } from "@aws-sdk/client-sesv2"
import nodemailer from "nodemailer";
import { SESv2Client, SendEmailCommand } from "@aws-sdk/client-sesv2";
export type AwsSesMailTransportOptions = {
type: 'aws-ses',
}
type: "aws-ses";
};
export class AwsSesMailTransport implements MailTransport {
#client: nodemailer.Transporter;
constructor(options: AwsSesMailTransportOptions) {
const sesClient = new SESv2Client()
const sesClient = new SESv2Client();
this.#client = nodemailer.createTransport({
SES: { sesClient, SendEmailCommand }
})
SES: { sesClient, SendEmailCommand },
});
}
async send({to, from, replyTo, subject, react}: MailMessage): Promise<void> {
async send({ to, from, replyTo, subject, react }: MailMessage): Promise<void> {
try {
await this.#client.sendMail({
from: from,
@@ -27,8 +27,7 @@ export class AwsSesMailTransport implements MailTransport {
subject,
html: await render(react),
});
}
catch (error) {
} catch (error) {
if (error instanceof Error) {
console.error(
`Failed to send email to ${to}, ${subject}. Error ${error.name}: ${error.message}`
@@ -40,7 +39,7 @@ export class AwsSesMailTransport implements MailTransport {
}
}
async sendPlainText({to, from, replyTo, subject, text}: PlainTextMailMessage): Promise<void> {
async sendPlainText({ to, from, replyTo, subject, text }: PlainTextMailMessage): Promise<void> {
try {
await this.#client.sendMail({
from: from,
@@ -49,8 +48,7 @@ export class AwsSesMailTransport implements MailTransport {
subject,
text: text,
});
}
catch (error) {
} catch (error) {
if (error instanceof Error) {
console.error(
`Failed to send email to ${to}, ${subject}. Error ${error.name}: ${error.message}`
@@ -18,7 +18,7 @@ export type PlainTextMailMessage = {
replyTo: string;
subject: string;
text: string;
}
};
export interface MailTransport {
send(message: MailMessage): Promise<void>;
@@ -33,13 +33,13 @@ export class EmailError extends Error {
}
export type MailTransportOptions =
AwsSesMailTransportOptions |
ResendMailTransportOptions |
NullMailTransportOptions |
SmtpMailTransportOptions
| AwsSesMailTransportOptions
| ResendMailTransportOptions
| NullMailTransportOptions
| SmtpMailTransportOptions;
export function constructMailTransport(options: MailTransportOptions): MailTransport {
switch(options.type) {
switch (options.type) {
case "aws-ses":
return new AwsSesMailTransport(options);
case "resend":
@@ -2,14 +2,13 @@ import { render } from "@react-email/render";
import { MailMessage, MailTransport, PlainTextMailMessage } from "./index";
export type NullMailTransportOptions = {
type: undefined,
}
type: undefined;
};
export class NullMailTransport implements MailTransport {
constructor(options: NullMailTransportOptions) {
}
constructor(options: NullMailTransportOptions) {}
async send({to, subject, react}: MailMessage): Promise<void> {
async send({ to, subject, react }: MailMessage): Promise<void> {
const plainText = await render(react, {
plainText: true,
});
@@ -21,7 +20,7 @@ ${plainText}
`);
}
async sendPlainText({to, subject, text}: PlainTextMailMessage): Promise<void> {
async sendPlainText({ to, subject, text }: PlainTextMailMessage): Promise<void> {
console.log(`
##### sendEmail to ${to}, subject: ${subject}
@@ -2,20 +2,20 @@ import { EmailError, MailMessage, MailTransport, PlainTextMailMessage } from "./
import { Resend } from "resend";
export type ResendMailTransportOptions = {
type: 'resend',
type: "resend";
config: {
apiKey?: string
}
}
apiKey?: string;
};
};
export class ResendMailTransport implements MailTransport {
#client: Resend;
constructor(options: ResendMailTransportOptions) {
this.#client = new Resend(options.config.apiKey)
this.#client = new Resend(options.config.apiKey);
}
async send({to, from, replyTo, subject, react}: MailMessage): Promise<void> {
async send({ to, from, replyTo, subject, react }: MailMessage): Promise<void> {
const result = await this.#client.emails.send({
from: from,
to,
@@ -32,7 +32,7 @@ export class ResendMailTransport implements MailTransport {
}
}
async sendPlainText({to, from, replyTo, subject, text}: PlainTextMailMessage): Promise<void> {
async sendPlainText({ to, from, replyTo, subject, text }: PlainTextMailMessage): Promise<void> {
const result = await this.#client.emails.send({
from: from,
to,
+1 -1
View File
@@ -13,7 +13,7 @@
"resolveJsonModule": true,
"isolatedModules": true,
"jsx": "preserve",
"target": "ES2015",
"target": "ES2015"
},
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"],
"exclude": ["node_modules"]
@@ -43,7 +43,8 @@ if (existsSync(pricesJsonPath)) {
let out = 'import type { DefaultModelDefinition } from "./types.js";\n\n';
out += "// Auto-generated from default-model-prices.json — do not edit manually.\n";
out += "// Run `pnpm run sync-prices` to update the JSON, then `pnpm run generate` to regenerate.\n";
out +=
"// Run `pnpm run sync-prices` to update the JSON, then `pnpm run generate` to regenerate.\n";
out += "// Source: https://github.com/langfuse/langfuse\n\n";
out += "export const defaultModelPrices: DefaultModelDefinition[] = ";
out += JSON.stringify(stripped, null, 2) + ";\n";
@@ -65,9 +66,12 @@ if (existsSync(catalogJsonPath)) {
for (const key of Object.keys(data)) {
if (data[key].releaseDate === undefined) data[key].releaseDate = null;
if (data[key].isHidden === undefined) data[key].isHidden = false;
if (data[key].supportsStructuredOutput === undefined) data[key].supportsStructuredOutput = false;
if (data[key].supportsParallelToolCalls === undefined) data[key].supportsParallelToolCalls = false;
if (data[key].supportsStreamingToolCalls === undefined) data[key].supportsStreamingToolCalls = false;
if (data[key].supportsStructuredOutput === undefined)
data[key].supportsStructuredOutput = false;
if (data[key].supportsParallelToolCalls === undefined)
data[key].supportsParallelToolCalls = false;
if (data[key].supportsStreamingToolCalls === undefined)
data[key].supportsStreamingToolCalls = false;
if (data[key].deprecationDate === undefined) data[key].deprecationDate = null;
if (data[key].knowledgeCutoff === undefined) data[key].knowledgeCutoff = null;
if (data[key].resolvedAt === undefined) data[key].resolvedAt = new Date().toISOString();
@@ -82,7 +86,8 @@ if (existsSync(catalogJsonPath)) {
let out = 'import type { ModelCatalogEntry } from "./types.js";\n\n';
out += "// Auto-generated from model-catalog.json — do not edit manually.\n";
out += "// Run `pnpm run generate-catalog` to update the JSON, then `pnpm run generate` to regenerate.\n\n";
out +=
"// Run `pnpm run generate-catalog` to update the JSON, then `pnpm run generate` to regenerate.\n\n";
out += "export const modelCatalog: Record<string, ModelCatalogEntry> = ";
out += JSON.stringify(data, null, 2) + ";\n";
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -303,9 +303,7 @@ describe("ModelPricingRegistry", () => {
name: "Large Context",
isDefault: false,
priority: 0,
conditions: [
{ usageDetailPattern: "input", operator: "gt" as const, value: 200000 },
],
conditions: [{ usageDetailPattern: "input", operator: "gt" as const, value: 200000 }],
prices: [
{ usageType: "input", price: 0.0000025 },
{ usageType: "output", price: 0.00001 },
@@ -371,9 +369,7 @@ describe("ModelPricingRegistry", () => {
name: "Conditional",
isDefault: false,
priority: 1,
conditions: [
{ usageDetailPattern: "input", operator: "gt" as const, value: 100 },
],
conditions: [{ usageDetailPattern: "input", operator: "gt" as const, value: 100 }],
prices: [{ usageType: "input", price: 0.0001 }],
},
{
@@ -405,9 +401,7 @@ describe("ModelPricingRegistry", () => {
name: "Conditional",
isDefault: false,
priority: 0,
conditions: [
{ usageDetailPattern: "input", operator: "gt" as const, value: 999999 },
],
conditions: [{ usageDetailPattern: "input", operator: "gt" as const, value: 999999 }],
prices: [{ usageType: "input", price: 0.001 }],
},
{
@@ -134,10 +134,7 @@ export class ModelPricingRegistry {
return null;
}
calculateCost(
responseModel: string,
usageDetails: Record<string, number>
): LlmCostResult | null {
calculateCost(responseModel: string, usageDetails: Record<string, number>): LlmCostResult | null {
const model = this.match(responseModel);
if (!model) return null;
@@ -32,10 +32,7 @@ const STALE_BASE_MODEL_NAME = "wrong-base-model-sentinel";
const STALE_INPUT_PRICE = 0.099;
const STALE_OUTPUT_PRICE = 0.088;
async function createGpt4oWithStalePricing(
prisma: PrismaClient,
source: "default" | "admin"
) {
async function createGpt4oWithStalePricing(prisma: PrismaClient, source: "default" | "admin") {
const model = await prisma.llmModel.create({
data: {
friendlyId: generateFriendlyId("llm_model"),
@@ -129,7 +126,9 @@ async function loadGpt4oWithTiers(prisma: PrismaClient) {
});
}
function expectBundledGpt4oPricing(model: NonNullable<Awaited<ReturnType<typeof loadGpt4oWithTiers>>>) {
function expectBundledGpt4oPricing(
model: NonNullable<Awaited<ReturnType<typeof loadGpt4oWithTiers>>>
) {
expect(model.matchPattern).toBe(gpt4oDef.matchPattern);
expect(model.pricingTiers).toHaveLength(gpt4oDef.pricingTiers.length);
@@ -71,9 +71,7 @@ export async function syncLlmCatalog(prisma: PrismaClient): Promise<{
capabilities: catalog?.capabilities ?? existing.capabilities,
isHidden: catalog?.isHidden ?? existing.isHidden,
baseModelName:
catalog?.baseModelName === undefined
? existing.baseModelName
: catalog.baseModelName,
catalog?.baseModelName === undefined ? existing.baseModelName : catalog.baseModelName,
pricingUnit: existing.pricingUnit ?? "tokens",
},
});
+1 -1
View File
@@ -38,4 +38,4 @@
"long": "^5.2.3",
"protobufjs": "^7.2.6"
}
}
}
@@ -108,10 +108,14 @@ export const ExportLogsServiceRequest = {
return obj;
},
create<I extends Exact<DeepPartial<ExportLogsServiceRequest>, I>>(base?: I): ExportLogsServiceRequest {
create<I extends Exact<DeepPartial<ExportLogsServiceRequest>, I>>(
base?: I
): ExportLogsServiceRequest {
return ExportLogsServiceRequest.fromPartial(base ?? ({} as any));
},
fromPartial<I extends Exact<DeepPartial<ExportLogsServiceRequest>, I>>(object: I): ExportLogsServiceRequest {
fromPartial<I extends Exact<DeepPartial<ExportLogsServiceRequest>, I>>(
object: I
): ExportLogsServiceRequest {
const message = createBaseExportLogsServiceRequest();
message.resourceLogs = object.resourceLogs?.map((e) => ResourceLogs.fromPartial(e)) || [];
return message;
@@ -169,14 +173,19 @@ export const ExportLogsServiceResponse = {
return obj;
},
create<I extends Exact<DeepPartial<ExportLogsServiceResponse>, I>>(base?: I): ExportLogsServiceResponse {
create<I extends Exact<DeepPartial<ExportLogsServiceResponse>, I>>(
base?: I
): ExportLogsServiceResponse {
return ExportLogsServiceResponse.fromPartial(base ?? ({} as any));
},
fromPartial<I extends Exact<DeepPartial<ExportLogsServiceResponse>, I>>(object: I): ExportLogsServiceResponse {
fromPartial<I extends Exact<DeepPartial<ExportLogsServiceResponse>, I>>(
object: I
): ExportLogsServiceResponse {
const message = createBaseExportLogsServiceResponse();
message.partialSuccess = (object.partialSuccess !== undefined && object.partialSuccess !== null)
? ExportLogsPartialSuccess.fromPartial(object.partialSuccess)
: undefined;
message.partialSuccess =
object.partialSuccess !== undefined && object.partialSuccess !== null
? ExportLogsPartialSuccess.fromPartial(object.partialSuccess)
: undefined;
return message;
},
};
@@ -189,7 +198,9 @@ export const ExportLogsPartialSuccess = {
encode(message: ExportLogsPartialSuccess, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer {
if (message.rejectedLogRecords !== BigInt("0")) {
if (BigInt.asIntN(64, message.rejectedLogRecords) !== message.rejectedLogRecords) {
throw new globalThis.Error("value provided for field message.rejectedLogRecords of type int64 too large");
throw new globalThis.Error(
"value provided for field message.rejectedLogRecords of type int64 too large"
);
}
writer.uint32(8).int64(message.rejectedLogRecords.toString());
}
@@ -231,7 +242,9 @@ export const ExportLogsPartialSuccess = {
fromJSON(object: any): ExportLogsPartialSuccess {
return {
rejectedLogRecords: isSet(object.rejectedLogRecords) ? BigInt(object.rejectedLogRecords) : BigInt("0"),
rejectedLogRecords: isSet(object.rejectedLogRecords)
? BigInt(object.rejectedLogRecords)
: BigInt("0"),
errorMessage: isSet(object.errorMessage) ? globalThis.String(object.errorMessage) : "",
};
},
@@ -247,10 +260,14 @@ export const ExportLogsPartialSuccess = {
return obj;
},
create<I extends Exact<DeepPartial<ExportLogsPartialSuccess>, I>>(base?: I): ExportLogsPartialSuccess {
create<I extends Exact<DeepPartial<ExportLogsPartialSuccess>, I>>(
base?: I
): ExportLogsPartialSuccess {
return ExportLogsPartialSuccess.fromPartial(base ?? ({} as any));
},
fromPartial<I extends Exact<DeepPartial<ExportLogsPartialSuccess>, I>>(object: I): ExportLogsPartialSuccess {
fromPartial<I extends Exact<DeepPartial<ExportLogsPartialSuccess>, I>>(
object: I
): ExportLogsPartialSuccess {
const message = createBaseExportLogsPartialSuccess();
message.rejectedLogRecords = object.rejectedLogRecords ?? BigInt("0");
message.errorMessage = object.errorMessage ?? "";
@@ -293,14 +310,19 @@ interface Rpc {
type Builtin = Date | Function | Uint8Array | string | number | boolean | bigint | undefined;
export type DeepPartial<T> = T extends Builtin ? T
: T extends globalThis.Array<infer U> ? globalThis.Array<DeepPartial<U>>
: T extends ReadonlyArray<infer U> ? ReadonlyArray<DeepPartial<U>>
: T extends {} ? { [K in keyof T]?: DeepPartial<T[K]> }
: Partial<T>;
export type DeepPartial<T> = T extends Builtin
? T
: T extends globalThis.Array<infer U>
? globalThis.Array<DeepPartial<U>>
: T extends ReadonlyArray<infer U>
? ReadonlyArray<DeepPartial<U>>
: T extends {}
? { [K in keyof T]?: DeepPartial<T[K]> }
: Partial<T>;
type KeysOfUnion<T> = T extends T ? keyof T : never;
export type Exact<P, I extends P> = P extends Builtin ? P
export type Exact<P, I extends P> = P extends Builtin
? P
: P & { [K in keyof P]: Exact<P[K], I[K]> } & { [K in Exclude<keyof I, KeysOfUnion<P>>]: never };
function longToBigint(long: Long) {
@@ -62,7 +62,10 @@ function createBaseExportMetricsServiceRequest(): ExportMetricsServiceRequest {
}
export const ExportMetricsServiceRequest = {
encode(message: ExportMetricsServiceRequest, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer {
encode(
message: ExportMetricsServiceRequest,
writer: _m0.Writer = _m0.Writer.create()
): _m0.Writer {
for (const v of message.resourceMetrics) {
ResourceMetrics.encode(v!, writer.uint32(10).fork()).ldelim();
}
@@ -108,12 +111,17 @@ export const ExportMetricsServiceRequest = {
return obj;
},
create<I extends Exact<DeepPartial<ExportMetricsServiceRequest>, I>>(base?: I): ExportMetricsServiceRequest {
create<I extends Exact<DeepPartial<ExportMetricsServiceRequest>, I>>(
base?: I
): ExportMetricsServiceRequest {
return ExportMetricsServiceRequest.fromPartial(base ?? ({} as any));
},
fromPartial<I extends Exact<DeepPartial<ExportMetricsServiceRequest>, I>>(object: I): ExportMetricsServiceRequest {
fromPartial<I extends Exact<DeepPartial<ExportMetricsServiceRequest>, I>>(
object: I
): ExportMetricsServiceRequest {
const message = createBaseExportMetricsServiceRequest();
message.resourceMetrics = object.resourceMetrics?.map((e) => ResourceMetrics.fromPartial(e)) || [];
message.resourceMetrics =
object.resourceMetrics?.map((e) => ResourceMetrics.fromPartial(e)) || [];
return message;
},
};
@@ -123,7 +131,10 @@ function createBaseExportMetricsServiceResponse(): ExportMetricsServiceResponse
}
export const ExportMetricsServiceResponse = {
encode(message: ExportMetricsServiceResponse, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer {
encode(
message: ExportMetricsServiceResponse,
writer: _m0.Writer = _m0.Writer.create()
): _m0.Writer {
if (message.partialSuccess !== undefined) {
ExportMetricsPartialSuccess.encode(message.partialSuccess, writer.uint32(10).fork()).ldelim();
}
@@ -169,14 +180,19 @@ export const ExportMetricsServiceResponse = {
return obj;
},
create<I extends Exact<DeepPartial<ExportMetricsServiceResponse>, I>>(base?: I): ExportMetricsServiceResponse {
create<I extends Exact<DeepPartial<ExportMetricsServiceResponse>, I>>(
base?: I
): ExportMetricsServiceResponse {
return ExportMetricsServiceResponse.fromPartial(base ?? ({} as any));
},
fromPartial<I extends Exact<DeepPartial<ExportMetricsServiceResponse>, I>>(object: I): ExportMetricsServiceResponse {
fromPartial<I extends Exact<DeepPartial<ExportMetricsServiceResponse>, I>>(
object: I
): ExportMetricsServiceResponse {
const message = createBaseExportMetricsServiceResponse();
message.partialSuccess = (object.partialSuccess !== undefined && object.partialSuccess !== null)
? ExportMetricsPartialSuccess.fromPartial(object.partialSuccess)
: undefined;
message.partialSuccess =
object.partialSuccess !== undefined && object.partialSuccess !== null
? ExportMetricsPartialSuccess.fromPartial(object.partialSuccess)
: undefined;
return message;
},
};
@@ -186,10 +202,15 @@ function createBaseExportMetricsPartialSuccess(): ExportMetricsPartialSuccess {
}
export const ExportMetricsPartialSuccess = {
encode(message: ExportMetricsPartialSuccess, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer {
encode(
message: ExportMetricsPartialSuccess,
writer: _m0.Writer = _m0.Writer.create()
): _m0.Writer {
if (message.rejectedDataPoints !== BigInt("0")) {
if (BigInt.asIntN(64, message.rejectedDataPoints) !== message.rejectedDataPoints) {
throw new globalThis.Error("value provided for field message.rejectedDataPoints of type int64 too large");
throw new globalThis.Error(
"value provided for field message.rejectedDataPoints of type int64 too large"
);
}
writer.uint32(8).int64(message.rejectedDataPoints.toString());
}
@@ -231,7 +252,9 @@ export const ExportMetricsPartialSuccess = {
fromJSON(object: any): ExportMetricsPartialSuccess {
return {
rejectedDataPoints: isSet(object.rejectedDataPoints) ? BigInt(object.rejectedDataPoints) : BigInt("0"),
rejectedDataPoints: isSet(object.rejectedDataPoints)
? BigInt(object.rejectedDataPoints)
: BigInt("0"),
errorMessage: isSet(object.errorMessage) ? globalThis.String(object.errorMessage) : "",
};
},
@@ -247,10 +270,14 @@ export const ExportMetricsPartialSuccess = {
return obj;
},
create<I extends Exact<DeepPartial<ExportMetricsPartialSuccess>, I>>(base?: I): ExportMetricsPartialSuccess {
create<I extends Exact<DeepPartial<ExportMetricsPartialSuccess>, I>>(
base?: I
): ExportMetricsPartialSuccess {
return ExportMetricsPartialSuccess.fromPartial(base ?? ({} as any));
},
fromPartial<I extends Exact<DeepPartial<ExportMetricsPartialSuccess>, I>>(object: I): ExportMetricsPartialSuccess {
fromPartial<I extends Exact<DeepPartial<ExportMetricsPartialSuccess>, I>>(
object: I
): ExportMetricsPartialSuccess {
const message = createBaseExportMetricsPartialSuccess();
message.rejectedDataPoints = object.rejectedDataPoints ?? BigInt("0");
message.errorMessage = object.errorMessage ?? "";
@@ -293,14 +320,19 @@ interface Rpc {
type Builtin = Date | Function | Uint8Array | string | number | boolean | bigint | undefined;
export type DeepPartial<T> = T extends Builtin ? T
: T extends globalThis.Array<infer U> ? globalThis.Array<DeepPartial<U>>
: T extends ReadonlyArray<infer U> ? ReadonlyArray<DeepPartial<U>>
: T extends {} ? { [K in keyof T]?: DeepPartial<T[K]> }
: Partial<T>;
export type DeepPartial<T> = T extends Builtin
? T
: T extends globalThis.Array<infer U>
? globalThis.Array<DeepPartial<U>>
: T extends ReadonlyArray<infer U>
? ReadonlyArray<DeepPartial<U>>
: T extends {}
? { [K in keyof T]?: DeepPartial<T[K]> }
: Partial<T>;
type KeysOfUnion<T> = T extends T ? keyof T : never;
export type Exact<P, I extends P> = P extends Builtin ? P
export type Exact<P, I extends P> = P extends Builtin
? P
: P & { [K in keyof P]: Exact<P[K], I[K]> } & { [K in Exclude<keyof I, KeysOfUnion<P>>]: never };
function longToBigint(long: Long) {
@@ -108,10 +108,14 @@ export const ExportTraceServiceRequest = {
return obj;
},
create<I extends Exact<DeepPartial<ExportTraceServiceRequest>, I>>(base?: I): ExportTraceServiceRequest {
create<I extends Exact<DeepPartial<ExportTraceServiceRequest>, I>>(
base?: I
): ExportTraceServiceRequest {
return ExportTraceServiceRequest.fromPartial(base ?? ({} as any));
},
fromPartial<I extends Exact<DeepPartial<ExportTraceServiceRequest>, I>>(object: I): ExportTraceServiceRequest {
fromPartial<I extends Exact<DeepPartial<ExportTraceServiceRequest>, I>>(
object: I
): ExportTraceServiceRequest {
const message = createBaseExportTraceServiceRequest();
message.resourceSpans = object.resourceSpans?.map((e) => ResourceSpans.fromPartial(e)) || [];
return message;
@@ -123,7 +127,10 @@ function createBaseExportTraceServiceResponse(): ExportTraceServiceResponse {
}
export const ExportTraceServiceResponse = {
encode(message: ExportTraceServiceResponse, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer {
encode(
message: ExportTraceServiceResponse,
writer: _m0.Writer = _m0.Writer.create()
): _m0.Writer {
if (message.partialSuccess !== undefined) {
ExportTracePartialSuccess.encode(message.partialSuccess, writer.uint32(10).fork()).ldelim();
}
@@ -169,14 +176,19 @@ export const ExportTraceServiceResponse = {
return obj;
},
create<I extends Exact<DeepPartial<ExportTraceServiceResponse>, I>>(base?: I): ExportTraceServiceResponse {
create<I extends Exact<DeepPartial<ExportTraceServiceResponse>, I>>(
base?: I
): ExportTraceServiceResponse {
return ExportTraceServiceResponse.fromPartial(base ?? ({} as any));
},
fromPartial<I extends Exact<DeepPartial<ExportTraceServiceResponse>, I>>(object: I): ExportTraceServiceResponse {
fromPartial<I extends Exact<DeepPartial<ExportTraceServiceResponse>, I>>(
object: I
): ExportTraceServiceResponse {
const message = createBaseExportTraceServiceResponse();
message.partialSuccess = (object.partialSuccess !== undefined && object.partialSuccess !== null)
? ExportTracePartialSuccess.fromPartial(object.partialSuccess)
: undefined;
message.partialSuccess =
object.partialSuccess !== undefined && object.partialSuccess !== null
? ExportTracePartialSuccess.fromPartial(object.partialSuccess)
: undefined;
return message;
},
};
@@ -189,7 +201,9 @@ export const ExportTracePartialSuccess = {
encode(message: ExportTracePartialSuccess, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer {
if (message.rejectedSpans !== BigInt("0")) {
if (BigInt.asIntN(64, message.rejectedSpans) !== message.rejectedSpans) {
throw new globalThis.Error("value provided for field message.rejectedSpans of type int64 too large");
throw new globalThis.Error(
"value provided for field message.rejectedSpans of type int64 too large"
);
}
writer.uint32(8).int64(message.rejectedSpans.toString());
}
@@ -247,10 +261,14 @@ export const ExportTracePartialSuccess = {
return obj;
},
create<I extends Exact<DeepPartial<ExportTracePartialSuccess>, I>>(base?: I): ExportTracePartialSuccess {
create<I extends Exact<DeepPartial<ExportTracePartialSuccess>, I>>(
base?: I
): ExportTracePartialSuccess {
return ExportTracePartialSuccess.fromPartial(base ?? ({} as any));
},
fromPartial<I extends Exact<DeepPartial<ExportTracePartialSuccess>, I>>(object: I): ExportTracePartialSuccess {
fromPartial<I extends Exact<DeepPartial<ExportTracePartialSuccess>, I>>(
object: I
): ExportTracePartialSuccess {
const message = createBaseExportTracePartialSuccess();
message.rejectedSpans = object.rejectedSpans ?? BigInt("0");
message.errorMessage = object.errorMessage ?? "";
@@ -293,14 +311,19 @@ interface Rpc {
type Builtin = Date | Function | Uint8Array | string | number | boolean | bigint | undefined;
export type DeepPartial<T> = T extends Builtin ? T
: T extends globalThis.Array<infer U> ? globalThis.Array<DeepPartial<U>>
: T extends ReadonlyArray<infer U> ? ReadonlyArray<DeepPartial<U>>
: T extends {} ? { [K in keyof T]?: DeepPartial<T[K]> }
: Partial<T>;
export type DeepPartial<T> = T extends Builtin
? T
: T extends globalThis.Array<infer U>
? globalThis.Array<DeepPartial<U>>
: T extends ReadonlyArray<infer U>
? ReadonlyArray<DeepPartial<U>>
: T extends {}
? { [K in keyof T]?: DeepPartial<T[K]> }
: Partial<T>;
type KeysOfUnion<T> = T extends T ? keyof T : never;
export type Exact<P, I extends P> = P extends Builtin ? P
export type Exact<P, I extends P> = P extends Builtin
? P
: P & { [K in keyof P]: Exact<P[K], I[K]> } & { [K in Exclude<keyof I, KeysOfUnion<P>>]: never };
function longToBigint(long: Long) {
@@ -93,7 +93,9 @@ export const AnyValue = {
}
if (message.intValue !== undefined) {
if (BigInt.asIntN(64, message.intValue) !== message.intValue) {
throw new globalThis.Error("value provided for field message.intValue of type int64 too large");
throw new globalThis.Error(
"value provided for field message.intValue of type int64 too large"
);
}
writer.uint32(24).int64(message.intValue.toString());
}
@@ -184,8 +186,12 @@ export const AnyValue = {
intValue: isSet(object.intValue) ? BigInt(object.intValue) : undefined,
doubleValue: isSet(object.doubleValue) ? globalThis.Number(object.doubleValue) : undefined,
arrayValue: isSet(object.arrayValue) ? ArrayValue.fromJSON(object.arrayValue) : undefined,
kvlistValue: isSet(object.kvlistValue) ? KeyValueList.fromJSON(object.kvlistValue) : undefined,
bytesValue: isSet(object.bytesValue) ? Buffer.from(bytesFromBase64(object.bytesValue)) : undefined,
kvlistValue: isSet(object.kvlistValue)
? KeyValueList.fromJSON(object.kvlistValue)
: undefined,
bytesValue: isSet(object.bytesValue)
? Buffer.from(bytesFromBase64(object.bytesValue))
: undefined,
};
},
@@ -224,12 +230,14 @@ export const AnyValue = {
message.boolValue = object.boolValue ?? undefined;
message.intValue = object.intValue ?? undefined;
message.doubleValue = object.doubleValue ?? undefined;
message.arrayValue = (object.arrayValue !== undefined && object.arrayValue !== null)
? ArrayValue.fromPartial(object.arrayValue)
: undefined;
message.kvlistValue = (object.kvlistValue !== undefined && object.kvlistValue !== null)
? KeyValueList.fromPartial(object.kvlistValue)
: undefined;
message.arrayValue =
object.arrayValue !== undefined && object.arrayValue !== null
? ArrayValue.fromPartial(object.arrayValue)
: undefined;
message.kvlistValue =
object.kvlistValue !== undefined && object.kvlistValue !== null
? KeyValueList.fromPartial(object.kvlistValue)
: undefined;
message.bytesValue = object.bytesValue ?? undefined;
return message;
},
@@ -272,7 +280,9 @@ export const ArrayValue = {
fromJSON(object: any): ArrayValue {
return {
values: globalThis.Array.isArray(object?.values) ? object.values.map((e: any) => AnyValue.fromJSON(e)) : [],
values: globalThis.Array.isArray(object?.values)
? object.values.map((e: any) => AnyValue.fromJSON(e))
: [],
};
},
@@ -331,7 +341,9 @@ export const KeyValueList = {
fromJSON(object: any): KeyValueList {
return {
values: globalThis.Array.isArray(object?.values) ? object.values.map((e: any) => KeyValue.fromJSON(e)) : [],
values: globalThis.Array.isArray(object?.values)
? object.values.map((e: any) => KeyValue.fromJSON(e))
: [],
};
},
@@ -422,9 +434,10 @@ export const KeyValue = {
fromPartial<I extends Exact<DeepPartial<KeyValue>, I>>(object: I): KeyValue {
const message = createBaseKeyValue();
message.key = object.key ?? "";
message.value = (object.value !== undefined && object.value !== null)
? AnyValue.fromPartial(object.value)
: undefined;
message.value =
object.value !== undefined && object.value !== null
? AnyValue.fromPartial(object.value)
: undefined;
return message;
},
};
@@ -527,7 +540,9 @@ export const InstrumentationScope = {
create<I extends Exact<DeepPartial<InstrumentationScope>, I>>(base?: I): InstrumentationScope {
return InstrumentationScope.fromPartial(base ?? ({} as any));
},
fromPartial<I extends Exact<DeepPartial<InstrumentationScope>, I>>(object: I): InstrumentationScope {
fromPartial<I extends Exact<DeepPartial<InstrumentationScope>, I>>(
object: I
): InstrumentationScope {
const message = createBaseInstrumentationScope();
message.name = object.name ?? "";
message.version = object.version ?? "";
@@ -564,14 +579,19 @@ function base64FromBytes(arr: Uint8Array): string {
type Builtin = Date | Function | Uint8Array | string | number | boolean | bigint | undefined;
export type DeepPartial<T> = T extends Builtin ? T
: T extends globalThis.Array<infer U> ? globalThis.Array<DeepPartial<U>>
: T extends ReadonlyArray<infer U> ? ReadonlyArray<DeepPartial<U>>
: T extends {} ? { [K in keyof T]?: DeepPartial<T[K]> }
: Partial<T>;
export type DeepPartial<T> = T extends Builtin
? T
: T extends globalThis.Array<infer U>
? globalThis.Array<DeepPartial<U>>
: T extends ReadonlyArray<infer U>
? ReadonlyArray<DeepPartial<U>>
: T extends {}
? { [K in keyof T]?: DeepPartial<T[K]> }
: Partial<T>;
type KeysOfUnion<T> = T extends T ? keyof T : never;
export type Exact<P, I extends P> = P extends Builtin ? P
export type Exact<P, I extends P> = P extends Builtin
? P
: P & { [K in keyof P]: Exact<P[K], I[K]> } & { [K in Exclude<keyof I, KeysOfUnion<P>>]: never };
function longToBigint(long: Long) {
@@ -255,9 +255,7 @@ export interface ResourceLogs {
* The resource for the logs in this message.
* If this field is not set then resource info is unknown.
*/
resource:
| Resource
| undefined;
resource: Resource | undefined;
/** A list of ScopeLogs that originate from a resource. */
scopeLogs: ScopeLogs[];
/**
@@ -277,9 +275,7 @@ export interface ScopeLogs {
* Semantically when InstrumentationScope isn't set, it is equivalent with
* an empty instrumentation scope name (unknown).
*/
scope:
| InstrumentationScope
| undefined;
scope: InstrumentationScope | undefined;
/** A list of log records. */
logRecords: LogRecord[];
/**
@@ -335,9 +331,7 @@ export interface LogRecord {
* string message (including multi-line) describing the event in a free form or it can
* be a structured data composed of arrays and maps of other values. [Optional].
*/
body:
| AnyValue
| undefined;
body: AnyValue | undefined;
/**
* Additional attributes that describe the specific event occurrence. [Optional].
* Attribute keys MUST be unique (it is not allowed to have more than one
@@ -529,9 +523,10 @@ export const ResourceLogs = {
},
fromPartial<I extends Exact<DeepPartial<ResourceLogs>, I>>(object: I): ResourceLogs {
const message = createBaseResourceLogs();
message.resource = (object.resource !== undefined && object.resource !== null)
? Resource.fromPartial(object.resource)
: undefined;
message.resource =
object.resource !== undefined && object.resource !== null
? Resource.fromPartial(object.resource)
: undefined;
message.scopeLogs = object.scopeLogs?.map((e) => ScopeLogs.fromPartial(e)) || [];
message.schemaUrl = object.schemaUrl ?? "";
return message;
@@ -622,9 +617,10 @@ export const ScopeLogs = {
},
fromPartial<I extends Exact<DeepPartial<ScopeLogs>, I>>(object: I): ScopeLogs {
const message = createBaseScopeLogs();
message.scope = (object.scope !== undefined && object.scope !== null)
? InstrumentationScope.fromPartial(object.scope)
: undefined;
message.scope =
object.scope !== undefined && object.scope !== null
? InstrumentationScope.fromPartial(object.scope)
: undefined;
message.logRecords = object.logRecords?.map((e) => LogRecord.fromPartial(e)) || [];
message.schemaUrl = object.schemaUrl ?? "";
return message;
@@ -650,13 +646,17 @@ export const LogRecord = {
encode(message: LogRecord, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer {
if (message.timeUnixNano !== BigInt("0")) {
if (BigInt.asUintN(64, message.timeUnixNano) !== message.timeUnixNano) {
throw new globalThis.Error("value provided for field message.timeUnixNano of type fixed64 too large");
throw new globalThis.Error(
"value provided for field message.timeUnixNano of type fixed64 too large"
);
}
writer.uint32(9).fixed64(message.timeUnixNano.toString());
}
if (message.observedTimeUnixNano !== BigInt("0")) {
if (BigInt.asUintN(64, message.observedTimeUnixNano) !== message.observedTimeUnixNano) {
throw new globalThis.Error("value provided for field message.observedTimeUnixNano of type fixed64 too large");
throw new globalThis.Error(
"value provided for field message.observedTimeUnixNano of type fixed64 too large"
);
}
writer.uint32(89).fixed64(message.observedTimeUnixNano.toString());
}
@@ -776,8 +776,12 @@ export const LogRecord = {
fromJSON(object: any): LogRecord {
return {
timeUnixNano: isSet(object.timeUnixNano) ? BigInt(object.timeUnixNano) : BigInt("0"),
observedTimeUnixNano: isSet(object.observedTimeUnixNano) ? BigInt(object.observedTimeUnixNano) : BigInt("0"),
severityNumber: isSet(object.severityNumber) ? severityNumberFromJSON(object.severityNumber) : 0,
observedTimeUnixNano: isSet(object.observedTimeUnixNano)
? BigInt(object.observedTimeUnixNano)
: BigInt("0"),
severityNumber: isSet(object.severityNumber)
? severityNumberFromJSON(object.severityNumber)
: 0,
severityText: isSet(object.severityText) ? globalThis.String(object.severityText) : "",
body: isSet(object.body) ? AnyValue.fromJSON(object.body) : undefined,
attributes: globalThis.Array.isArray(object?.attributes)
@@ -787,7 +791,9 @@ export const LogRecord = {
? globalThis.Number(object.droppedAttributesCount)
: 0,
flags: isSet(object.flags) ? globalThis.Number(object.flags) : 0,
traceId: isSet(object.traceId) ? Buffer.from(bytesFromBase64(object.traceId)) : Buffer.alloc(0),
traceId: isSet(object.traceId)
? Buffer.from(bytesFromBase64(object.traceId))
: Buffer.alloc(0),
spanId: isSet(object.spanId) ? Buffer.from(bytesFromBase64(object.spanId)) : Buffer.alloc(0),
};
},
@@ -836,7 +842,10 @@ export const LogRecord = {
message.observedTimeUnixNano = object.observedTimeUnixNano ?? BigInt("0");
message.severityNumber = object.severityNumber ?? 0;
message.severityText = object.severityText ?? "";
message.body = (object.body !== undefined && object.body !== null) ? AnyValue.fromPartial(object.body) : undefined;
message.body =
object.body !== undefined && object.body !== null
? AnyValue.fromPartial(object.body)
: undefined;
message.attributes = object.attributes?.map((e) => KeyValue.fromPartial(e)) || [];
message.droppedAttributesCount = object.droppedAttributesCount ?? 0;
message.flags = object.flags ?? 0;
@@ -873,14 +882,19 @@ function base64FromBytes(arr: Uint8Array): string {
type Builtin = Date | Function | Uint8Array | string | number | boolean | bigint | undefined;
export type DeepPartial<T> = T extends Builtin ? T
: T extends globalThis.Array<infer U> ? globalThis.Array<DeepPartial<U>>
: T extends ReadonlyArray<infer U> ? ReadonlyArray<DeepPartial<U>>
: T extends {} ? { [K in keyof T]?: DeepPartial<T[K]> }
: Partial<T>;
export type DeepPartial<T> = T extends Builtin
? T
: T extends globalThis.Array<infer U>
? globalThis.Array<DeepPartial<U>>
: T extends ReadonlyArray<infer U>
? ReadonlyArray<DeepPartial<U>>
: T extends {}
? { [K in keyof T]?: DeepPartial<T[K]> }
: Partial<T>;
type KeysOfUnion<T> = T extends T ? keyof T : never;
export type Exact<P, I extends P> = P extends Builtin ? P
export type Exact<P, I extends P> = P extends Builtin
? P
: P & { [K in keyof P]: Exact<P[K], I[K]> } & { [K in Exclude<keyof I, KeysOfUnion<P>>]: never };
function longToBigint(long: Long) {
@@ -193,9 +193,7 @@ export interface ResourceMetrics {
* The resource for the metrics in this message.
* If this field is not set then no resource info is known.
*/
resource:
| Resource
| undefined;
resource: Resource | undefined;
/** A list of metrics that originate from a resource. */
scopeMetrics: ScopeMetrics[];
/**
@@ -215,9 +213,7 @@ export interface ScopeMetrics {
* Semantically when InstrumentationScope isn't set, it is equivalent with
* an empty instrumentation scope name (unknown).
*/
scope:
| InstrumentationScope
| undefined;
scope: InstrumentationScope | undefined;
/** A list of metrics that originate from an instrumentation library. */
metrics: Metric[];
/**
@@ -329,9 +325,7 @@ export interface Metric {
sum?: Sum | undefined;
histogram?: Histogram | undefined;
exponentialHistogram?: ExponentialHistogram | undefined;
summary?:
| Summary
| undefined;
summary?: Summary | undefined;
/**
* Additional metadata attributes that describe the metric. [Optional].
* Attributes are non-identifying.
@@ -440,9 +434,7 @@ export interface NumberDataPoint {
*/
timeUnixNano: bigint;
asDouble?: number | undefined;
asInt?:
| bigint
| undefined;
asInt?: bigint | undefined;
/**
* (Optional) List of exemplars collected from
* measurements that were used to form the data point
@@ -506,9 +498,7 @@ export interface HistogramDataPoint {
* doing so. This is specifically to enforce compatibility w/ OpenMetrics,
* see: https://github.com/OpenObservability/OpenMetrics/blob/main/specification/OpenMetrics.md#histogram
*/
sum?:
| number
| undefined;
sum?: number | undefined;
/**
* bucket_counts is an optional field contains the count values of histogram
* for each bucket.
@@ -546,9 +536,7 @@ export interface HistogramDataPoint {
*/
flags: number;
/** min is the minimum value over (start_time, end_time]. */
min?:
| number
| undefined;
min?: number | undefined;
/** max is the maximum value over (start_time, end_time]. */
max?: number | undefined;
}
@@ -598,9 +586,7 @@ export interface ExponentialHistogramDataPoint {
* doing so. This is specifically to enforce compatibility w/ OpenMetrics,
* see: https://github.com/OpenObservability/OpenMetrics/blob/main/specification/OpenMetrics.md#histogram
*/
sum?:
| number
| undefined;
sum?: number | undefined;
/**
* scale describes the resolution of the histogram. Boundaries are
* located at powers of the base, where:
@@ -631,13 +617,9 @@ export interface ExponentialHistogramDataPoint {
*/
zeroCount: bigint;
/** positive carries the positive range of exponential bucket counts. */
positive:
| ExponentialHistogramDataPoint_Buckets
| undefined;
positive: ExponentialHistogramDataPoint_Buckets | undefined;
/** negative carries the negative range of exponential bucket counts. */
negative:
| ExponentialHistogramDataPoint_Buckets
| undefined;
negative: ExponentialHistogramDataPoint_Buckets | undefined;
/**
* Flags that apply to this specific data point. See DataPointFlags
* for the available flags and their meaning.
@@ -649,13 +631,9 @@ export interface ExponentialHistogramDataPoint {
*/
exemplars: Exemplar[];
/** min is the minimum value over (start_time, end_time]. */
min?:
| number
| undefined;
min?: number | undefined;
/** max is the maximum value over (start_time, end_time]. */
max?:
| number
| undefined;
max?: number | undefined;
/**
* ZeroThreshold may be optionally set to convey the width of the zero
* region. Where the zero region is defined as the closed interval
@@ -789,9 +767,7 @@ export interface Exemplar {
*/
timeUnixNano: bigint;
asDouble?: number | undefined;
asInt?:
| bigint
| undefined;
asInt?: bigint | undefined;
/**
* (Optional) Span ID of the exemplar trace.
* span_id may be missing if the measurement is not recorded inside a trace
@@ -862,7 +838,8 @@ export const MetricsData = {
},
fromPartial<I extends Exact<DeepPartial<MetricsData>, I>>(object: I): MetricsData {
const message = createBaseMetricsData();
message.resourceMetrics = object.resourceMetrics?.map((e) => ResourceMetrics.fromPartial(e)) || [];
message.resourceMetrics =
object.resourceMetrics?.map((e) => ResourceMetrics.fromPartial(e)) || [];
return message;
},
};
@@ -951,9 +928,10 @@ export const ResourceMetrics = {
},
fromPartial<I extends Exact<DeepPartial<ResourceMetrics>, I>>(object: I): ResourceMetrics {
const message = createBaseResourceMetrics();
message.resource = (object.resource !== undefined && object.resource !== null)
? Resource.fromPartial(object.resource)
: undefined;
message.resource =
object.resource !== undefined && object.resource !== null
? Resource.fromPartial(object.resource)
: undefined;
message.scopeMetrics = object.scopeMetrics?.map((e) => ScopeMetrics.fromPartial(e)) || [];
message.schemaUrl = object.schemaUrl ?? "";
return message;
@@ -1018,7 +996,9 @@ export const ScopeMetrics = {
fromJSON(object: any): ScopeMetrics {
return {
scope: isSet(object.scope) ? InstrumentationScope.fromJSON(object.scope) : undefined,
metrics: globalThis.Array.isArray(object?.metrics) ? object.metrics.map((e: any) => Metric.fromJSON(e)) : [],
metrics: globalThis.Array.isArray(object?.metrics)
? object.metrics.map((e: any) => Metric.fromJSON(e))
: [],
schemaUrl: isSet(object.schemaUrl) ? globalThis.String(object.schemaUrl) : "",
};
},
@@ -1042,9 +1022,10 @@ export const ScopeMetrics = {
},
fromPartial<I extends Exact<DeepPartial<ScopeMetrics>, I>>(object: I): ScopeMetrics {
const message = createBaseScopeMetrics();
message.scope = (object.scope !== undefined && object.scope !== null)
? InstrumentationScope.fromPartial(object.scope)
: undefined;
message.scope =
object.scope !== undefined && object.scope !== null
? InstrumentationScope.fromPartial(object.scope)
: undefined;
message.metrics = object.metrics?.map((e) => Metric.fromPartial(e)) || [];
message.schemaUrl = object.schemaUrl ?? "";
return message;
@@ -1188,7 +1169,9 @@ export const Metric = {
? ExponentialHistogram.fromJSON(object.exponentialHistogram)
: undefined,
summary: isSet(object.summary) ? Summary.fromJSON(object.summary) : undefined,
metadata: globalThis.Array.isArray(object?.metadata) ? object.metadata.map((e: any) => KeyValue.fromJSON(e)) : [],
metadata: globalThis.Array.isArray(object?.metadata)
? object.metadata.map((e: any) => KeyValue.fromJSON(e))
: [],
};
},
@@ -1232,17 +1215,24 @@ export const Metric = {
message.name = object.name ?? "";
message.description = object.description ?? "";
message.unit = object.unit ?? "";
message.gauge = (object.gauge !== undefined && object.gauge !== null) ? Gauge.fromPartial(object.gauge) : undefined;
message.sum = (object.sum !== undefined && object.sum !== null) ? Sum.fromPartial(object.sum) : undefined;
message.histogram = (object.histogram !== undefined && object.histogram !== null)
? Histogram.fromPartial(object.histogram)
: undefined;
message.exponentialHistogram = (object.exponentialHistogram !== undefined && object.exponentialHistogram !== null)
? ExponentialHistogram.fromPartial(object.exponentialHistogram)
: undefined;
message.summary = (object.summary !== undefined && object.summary !== null)
? Summary.fromPartial(object.summary)
: undefined;
message.gauge =
object.gauge !== undefined && object.gauge !== null
? Gauge.fromPartial(object.gauge)
: undefined;
message.sum =
object.sum !== undefined && object.sum !== null ? Sum.fromPartial(object.sum) : undefined;
message.histogram =
object.histogram !== undefined && object.histogram !== null
? Histogram.fromPartial(object.histogram)
: undefined;
message.exponentialHistogram =
object.exponentialHistogram !== undefined && object.exponentialHistogram !== null
? ExponentialHistogram.fromPartial(object.exponentialHistogram)
: undefined;
message.summary =
object.summary !== undefined && object.summary !== null
? Summary.fromPartial(object.summary)
: undefined;
message.metadata = object.metadata?.map((e) => KeyValue.fromPartial(e)) || [];
return message;
},
@@ -1550,9 +1540,12 @@ export const ExponentialHistogram = {
create<I extends Exact<DeepPartial<ExponentialHistogram>, I>>(base?: I): ExponentialHistogram {
return ExponentialHistogram.fromPartial(base ?? ({} as any));
},
fromPartial<I extends Exact<DeepPartial<ExponentialHistogram>, I>>(object: I): ExponentialHistogram {
fromPartial<I extends Exact<DeepPartial<ExponentialHistogram>, I>>(
object: I
): ExponentialHistogram {
const message = createBaseExponentialHistogram();
message.dataPoints = object.dataPoints?.map((e) => ExponentialHistogramDataPoint.fromPartial(e)) || [];
message.dataPoints =
object.dataPoints?.map((e) => ExponentialHistogramDataPoint.fromPartial(e)) || [];
message.aggregationTemporality = object.aggregationTemporality ?? 0;
return message;
},
@@ -1638,13 +1631,17 @@ export const NumberDataPoint = {
}
if (message.startTimeUnixNano !== BigInt("0")) {
if (BigInt.asUintN(64, message.startTimeUnixNano) !== message.startTimeUnixNano) {
throw new globalThis.Error("value provided for field message.startTimeUnixNano of type fixed64 too large");
throw new globalThis.Error(
"value provided for field message.startTimeUnixNano of type fixed64 too large"
);
}
writer.uint32(17).fixed64(message.startTimeUnixNano.toString());
}
if (message.timeUnixNano !== BigInt("0")) {
if (BigInt.asUintN(64, message.timeUnixNano) !== message.timeUnixNano) {
throw new globalThis.Error("value provided for field message.timeUnixNano of type fixed64 too large");
throw new globalThis.Error(
"value provided for field message.timeUnixNano of type fixed64 too large"
);
}
writer.uint32(25).fixed64(message.timeUnixNano.toString());
}
@@ -1653,7 +1650,9 @@ export const NumberDataPoint = {
}
if (message.asInt !== undefined) {
if (BigInt.asIntN(64, message.asInt) !== message.asInt) {
throw new globalThis.Error("value provided for field message.asInt of type sfixed64 too large");
throw new globalThis.Error(
"value provided for field message.asInt of type sfixed64 too large"
);
}
writer.uint32(49).sfixed64(message.asInt.toString());
}
@@ -1736,7 +1735,9 @@ export const NumberDataPoint = {
attributes: globalThis.Array.isArray(object?.attributes)
? object.attributes.map((e: any) => KeyValue.fromJSON(e))
: [],
startTimeUnixNano: isSet(object.startTimeUnixNano) ? BigInt(object.startTimeUnixNano) : BigInt("0"),
startTimeUnixNano: isSet(object.startTimeUnixNano)
? BigInt(object.startTimeUnixNano)
: BigInt("0"),
timeUnixNano: isSet(object.timeUnixNano) ? BigInt(object.timeUnixNano) : BigInt("0"),
asDouble: isSet(object.asDouble) ? globalThis.Number(object.asDouble) : undefined,
asInt: isSet(object.asInt) ? BigInt(object.asInt) : undefined,
@@ -1812,19 +1813,25 @@ export const HistogramDataPoint = {
}
if (message.startTimeUnixNano !== BigInt("0")) {
if (BigInt.asUintN(64, message.startTimeUnixNano) !== message.startTimeUnixNano) {
throw new globalThis.Error("value provided for field message.startTimeUnixNano of type fixed64 too large");
throw new globalThis.Error(
"value provided for field message.startTimeUnixNano of type fixed64 too large"
);
}
writer.uint32(17).fixed64(message.startTimeUnixNano.toString());
}
if (message.timeUnixNano !== BigInt("0")) {
if (BigInt.asUintN(64, message.timeUnixNano) !== message.timeUnixNano) {
throw new globalThis.Error("value provided for field message.timeUnixNano of type fixed64 too large");
throw new globalThis.Error(
"value provided for field message.timeUnixNano of type fixed64 too large"
);
}
writer.uint32(25).fixed64(message.timeUnixNano.toString());
}
if (message.count !== BigInt("0")) {
if (BigInt.asUintN(64, message.count) !== message.count) {
throw new globalThis.Error("value provided for field message.count of type fixed64 too large");
throw new globalThis.Error(
"value provided for field message.count of type fixed64 too large"
);
}
writer.uint32(33).fixed64(message.count.toString());
}
@@ -1834,7 +1841,9 @@ export const HistogramDataPoint = {
writer.uint32(50).fork();
for (const v of message.bucketCounts) {
if (BigInt.asUintN(64, v) !== v) {
throw new globalThis.Error("a value provided in array field bucketCounts of type fixed64 is too large");
throw new globalThis.Error(
"a value provided in array field bucketCounts of type fixed64 is too large"
);
}
writer.fixed64(v.toString());
}
@@ -1977,7 +1986,9 @@ export const HistogramDataPoint = {
attributes: globalThis.Array.isArray(object?.attributes)
? object.attributes.map((e: any) => KeyValue.fromJSON(e))
: [],
startTimeUnixNano: isSet(object.startTimeUnixNano) ? BigInt(object.startTimeUnixNano) : BigInt("0"),
startTimeUnixNano: isSet(object.startTimeUnixNano)
? BigInt(object.startTimeUnixNano)
: BigInt("0"),
timeUnixNano: isSet(object.timeUnixNano) ? BigInt(object.timeUnixNano) : BigInt("0"),
count: isSet(object.count) ? BigInt(object.count) : BigInt("0"),
sum: isSet(object.sum) ? globalThis.Number(object.sum) : undefined,
@@ -2074,25 +2085,34 @@ function createBaseExponentialHistogramDataPoint(): ExponentialHistogramDataPoin
}
export const ExponentialHistogramDataPoint = {
encode(message: ExponentialHistogramDataPoint, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer {
encode(
message: ExponentialHistogramDataPoint,
writer: _m0.Writer = _m0.Writer.create()
): _m0.Writer {
for (const v of message.attributes) {
KeyValue.encode(v!, writer.uint32(10).fork()).ldelim();
}
if (message.startTimeUnixNano !== BigInt("0")) {
if (BigInt.asUintN(64, message.startTimeUnixNano) !== message.startTimeUnixNano) {
throw new globalThis.Error("value provided for field message.startTimeUnixNano of type fixed64 too large");
throw new globalThis.Error(
"value provided for field message.startTimeUnixNano of type fixed64 too large"
);
}
writer.uint32(17).fixed64(message.startTimeUnixNano.toString());
}
if (message.timeUnixNano !== BigInt("0")) {
if (BigInt.asUintN(64, message.timeUnixNano) !== message.timeUnixNano) {
throw new globalThis.Error("value provided for field message.timeUnixNano of type fixed64 too large");
throw new globalThis.Error(
"value provided for field message.timeUnixNano of type fixed64 too large"
);
}
writer.uint32(25).fixed64(message.timeUnixNano.toString());
}
if (message.count !== BigInt("0")) {
if (BigInt.asUintN(64, message.count) !== message.count) {
throw new globalThis.Error("value provided for field message.count of type fixed64 too large");
throw new globalThis.Error(
"value provided for field message.count of type fixed64 too large"
);
}
writer.uint32(33).fixed64(message.count.toString());
}
@@ -2104,15 +2124,23 @@ export const ExponentialHistogramDataPoint = {
}
if (message.zeroCount !== BigInt("0")) {
if (BigInt.asUintN(64, message.zeroCount) !== message.zeroCount) {
throw new globalThis.Error("value provided for field message.zeroCount of type fixed64 too large");
throw new globalThis.Error(
"value provided for field message.zeroCount of type fixed64 too large"
);
}
writer.uint32(57).fixed64(message.zeroCount.toString());
}
if (message.positive !== undefined) {
ExponentialHistogramDataPoint_Buckets.encode(message.positive, writer.uint32(66).fork()).ldelim();
ExponentialHistogramDataPoint_Buckets.encode(
message.positive,
writer.uint32(66).fork()
).ldelim();
}
if (message.negative !== undefined) {
ExponentialHistogramDataPoint_Buckets.encode(message.negative, writer.uint32(74).fork()).ldelim();
ExponentialHistogramDataPoint_Buckets.encode(
message.negative,
writer.uint32(74).fork()
).ldelim();
}
if (message.flags !== 0) {
writer.uint32(80).uint32(message.flags);
@@ -2251,14 +2279,20 @@ export const ExponentialHistogramDataPoint = {
attributes: globalThis.Array.isArray(object?.attributes)
? object.attributes.map((e: any) => KeyValue.fromJSON(e))
: [],
startTimeUnixNano: isSet(object.startTimeUnixNano) ? BigInt(object.startTimeUnixNano) : BigInt("0"),
startTimeUnixNano: isSet(object.startTimeUnixNano)
? BigInt(object.startTimeUnixNano)
: BigInt("0"),
timeUnixNano: isSet(object.timeUnixNano) ? BigInt(object.timeUnixNano) : BigInt("0"),
count: isSet(object.count) ? BigInt(object.count) : BigInt("0"),
sum: isSet(object.sum) ? globalThis.Number(object.sum) : undefined,
scale: isSet(object.scale) ? globalThis.Number(object.scale) : 0,
zeroCount: isSet(object.zeroCount) ? BigInt(object.zeroCount) : BigInt("0"),
positive: isSet(object.positive) ? ExponentialHistogramDataPoint_Buckets.fromJSON(object.positive) : undefined,
negative: isSet(object.negative) ? ExponentialHistogramDataPoint_Buckets.fromJSON(object.negative) : undefined,
positive: isSet(object.positive)
? ExponentialHistogramDataPoint_Buckets.fromJSON(object.positive)
: undefined,
negative: isSet(object.negative)
? ExponentialHistogramDataPoint_Buckets.fromJSON(object.negative)
: undefined,
flags: isSet(object.flags) ? globalThis.Number(object.flags) : 0,
exemplars: globalThis.Array.isArray(object?.exemplars)
? object.exemplars.map((e: any) => Exemplar.fromJSON(e))
@@ -2316,11 +2350,13 @@ export const ExponentialHistogramDataPoint = {
return obj;
},
create<I extends Exact<DeepPartial<ExponentialHistogramDataPoint>, I>>(base?: I): ExponentialHistogramDataPoint {
create<I extends Exact<DeepPartial<ExponentialHistogramDataPoint>, I>>(
base?: I
): ExponentialHistogramDataPoint {
return ExponentialHistogramDataPoint.fromPartial(base ?? ({} as any));
},
fromPartial<I extends Exact<DeepPartial<ExponentialHistogramDataPoint>, I>>(
object: I,
object: I
): ExponentialHistogramDataPoint {
const message = createBaseExponentialHistogramDataPoint();
message.attributes = object.attributes?.map((e) => KeyValue.fromPartial(e)) || [];
@@ -2330,12 +2366,14 @@ export const ExponentialHistogramDataPoint = {
message.sum = object.sum ?? undefined;
message.scale = object.scale ?? 0;
message.zeroCount = object.zeroCount ?? BigInt("0");
message.positive = (object.positive !== undefined && object.positive !== null)
? ExponentialHistogramDataPoint_Buckets.fromPartial(object.positive)
: undefined;
message.negative = (object.negative !== undefined && object.negative !== null)
? ExponentialHistogramDataPoint_Buckets.fromPartial(object.negative)
: undefined;
message.positive =
object.positive !== undefined && object.positive !== null
? ExponentialHistogramDataPoint_Buckets.fromPartial(object.positive)
: undefined;
message.negative =
object.negative !== undefined && object.negative !== null
? ExponentialHistogramDataPoint_Buckets.fromPartial(object.negative)
: undefined;
message.flags = object.flags ?? 0;
message.exemplars = object.exemplars?.map((e) => Exemplar.fromPartial(e)) || [];
message.min = object.min ?? undefined;
@@ -2350,14 +2388,19 @@ function createBaseExponentialHistogramDataPoint_Buckets(): ExponentialHistogram
}
export const ExponentialHistogramDataPoint_Buckets = {
encode(message: ExponentialHistogramDataPoint_Buckets, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer {
encode(
message: ExponentialHistogramDataPoint_Buckets,
writer: _m0.Writer = _m0.Writer.create()
): _m0.Writer {
if (message.offset !== 0) {
writer.uint32(8).sint32(message.offset);
}
writer.uint32(18).fork();
for (const v of message.bucketCounts) {
if (BigInt.asUintN(64, v) !== v) {
throw new globalThis.Error("a value provided in array field bucketCounts of type uint64 is too large");
throw new globalThis.Error(
"a value provided in array field bucketCounts of type uint64 is too large"
);
}
writer.uint64(v.toString());
}
@@ -2426,12 +2469,12 @@ export const ExponentialHistogramDataPoint_Buckets = {
},
create<I extends Exact<DeepPartial<ExponentialHistogramDataPoint_Buckets>, I>>(
base?: I,
base?: I
): ExponentialHistogramDataPoint_Buckets {
return ExponentialHistogramDataPoint_Buckets.fromPartial(base ?? ({} as any));
},
fromPartial<I extends Exact<DeepPartial<ExponentialHistogramDataPoint_Buckets>, I>>(
object: I,
object: I
): ExponentialHistogramDataPoint_Buckets {
const message = createBaseExponentialHistogramDataPoint_Buckets();
message.offset = object.offset ?? 0;
@@ -2459,19 +2502,25 @@ export const SummaryDataPoint = {
}
if (message.startTimeUnixNano !== BigInt("0")) {
if (BigInt.asUintN(64, message.startTimeUnixNano) !== message.startTimeUnixNano) {
throw new globalThis.Error("value provided for field message.startTimeUnixNano of type fixed64 too large");
throw new globalThis.Error(
"value provided for field message.startTimeUnixNano of type fixed64 too large"
);
}
writer.uint32(17).fixed64(message.startTimeUnixNano.toString());
}
if (message.timeUnixNano !== BigInt("0")) {
if (BigInt.asUintN(64, message.timeUnixNano) !== message.timeUnixNano) {
throw new globalThis.Error("value provided for field message.timeUnixNano of type fixed64 too large");
throw new globalThis.Error(
"value provided for field message.timeUnixNano of type fixed64 too large"
);
}
writer.uint32(25).fixed64(message.timeUnixNano.toString());
}
if (message.count !== BigInt("0")) {
if (BigInt.asUintN(64, message.count) !== message.count) {
throw new globalThis.Error("value provided for field message.count of type fixed64 too large");
throw new globalThis.Error(
"value provided for field message.count of type fixed64 too large"
);
}
writer.uint32(33).fixed64(message.count.toString());
}
@@ -2534,7 +2583,9 @@ export const SummaryDataPoint = {
break;
}
message.quantileValues.push(SummaryDataPoint_ValueAtQuantile.decode(reader, reader.uint32()));
message.quantileValues.push(
SummaryDataPoint_ValueAtQuantile.decode(reader, reader.uint32())
);
continue;
case 8:
if (tag !== 64) {
@@ -2557,7 +2608,9 @@ export const SummaryDataPoint = {
attributes: globalThis.Array.isArray(object?.attributes)
? object.attributes.map((e: any) => KeyValue.fromJSON(e))
: [],
startTimeUnixNano: isSet(object.startTimeUnixNano) ? BigInt(object.startTimeUnixNano) : BigInt("0"),
startTimeUnixNano: isSet(object.startTimeUnixNano)
? BigInt(object.startTimeUnixNano)
: BigInt("0"),
timeUnixNano: isSet(object.timeUnixNano) ? BigInt(object.timeUnixNano) : BigInt("0"),
count: isSet(object.count) ? BigInt(object.count) : BigInt("0"),
sum: isSet(object.sum) ? globalThis.Number(object.sum) : 0,
@@ -2586,7 +2639,9 @@ export const SummaryDataPoint = {
obj.sum = message.sum;
}
if (message.quantileValues?.length) {
obj.quantileValues = message.quantileValues.map((e) => SummaryDataPoint_ValueAtQuantile.toJSON(e));
obj.quantileValues = message.quantileValues.map((e) =>
SummaryDataPoint_ValueAtQuantile.toJSON(e)
);
}
if (message.flags !== 0) {
obj.flags = Math.round(message.flags);
@@ -2604,7 +2659,8 @@ export const SummaryDataPoint = {
message.timeUnixNano = object.timeUnixNano ?? BigInt("0");
message.count = object.count ?? BigInt("0");
message.sum = object.sum ?? 0;
message.quantileValues = object.quantileValues?.map((e) => SummaryDataPoint_ValueAtQuantile.fromPartial(e)) || [];
message.quantileValues =
object.quantileValues?.map((e) => SummaryDataPoint_ValueAtQuantile.fromPartial(e)) || [];
message.flags = object.flags ?? 0;
return message;
},
@@ -2615,7 +2671,10 @@ function createBaseSummaryDataPoint_ValueAtQuantile(): SummaryDataPoint_ValueAtQ
}
export const SummaryDataPoint_ValueAtQuantile = {
encode(message: SummaryDataPoint_ValueAtQuantile, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer {
encode(
message: SummaryDataPoint_ValueAtQuantile,
writer: _m0.Writer = _m0.Writer.create()
): _m0.Writer {
if (message.quantile !== 0) {
writer.uint32(9).double(message.quantile);
}
@@ -2674,12 +2733,12 @@ export const SummaryDataPoint_ValueAtQuantile = {
},
create<I extends Exact<DeepPartial<SummaryDataPoint_ValueAtQuantile>, I>>(
base?: I,
base?: I
): SummaryDataPoint_ValueAtQuantile {
return SummaryDataPoint_ValueAtQuantile.fromPartial(base ?? ({} as any));
},
fromPartial<I extends Exact<DeepPartial<SummaryDataPoint_ValueAtQuantile>, I>>(
object: I,
object: I
): SummaryDataPoint_ValueAtQuantile {
const message = createBaseSummaryDataPoint_ValueAtQuantile();
message.quantile = object.quantile ?? 0;
@@ -2706,7 +2765,9 @@ export const Exemplar = {
}
if (message.timeUnixNano !== BigInt("0")) {
if (BigInt.asUintN(64, message.timeUnixNano) !== message.timeUnixNano) {
throw new globalThis.Error("value provided for field message.timeUnixNano of type fixed64 too large");
throw new globalThis.Error(
"value provided for field message.timeUnixNano of type fixed64 too large"
);
}
writer.uint32(17).fixed64(message.timeUnixNano.toString());
}
@@ -2715,7 +2776,9 @@ export const Exemplar = {
}
if (message.asInt !== undefined) {
if (BigInt.asIntN(64, message.asInt) !== message.asInt) {
throw new globalThis.Error("value provided for field message.asInt of type sfixed64 too large");
throw new globalThis.Error(
"value provided for field message.asInt of type sfixed64 too large"
);
}
writer.uint32(49).sfixed64(message.asInt.toString());
}
@@ -2795,7 +2858,9 @@ export const Exemplar = {
asDouble: isSet(object.asDouble) ? globalThis.Number(object.asDouble) : undefined,
asInt: isSet(object.asInt) ? BigInt(object.asInt) : undefined,
spanId: isSet(object.spanId) ? Buffer.from(bytesFromBase64(object.spanId)) : Buffer.alloc(0),
traceId: isSet(object.traceId) ? Buffer.from(bytesFromBase64(object.traceId)) : Buffer.alloc(0),
traceId: isSet(object.traceId)
? Buffer.from(bytesFromBase64(object.traceId))
: Buffer.alloc(0),
};
},
@@ -2827,7 +2892,8 @@ export const Exemplar = {
},
fromPartial<I extends Exact<DeepPartial<Exemplar>, I>>(object: I): Exemplar {
const message = createBaseExemplar();
message.filteredAttributes = object.filteredAttributes?.map((e) => KeyValue.fromPartial(e)) || [];
message.filteredAttributes =
object.filteredAttributes?.map((e) => KeyValue.fromPartial(e)) || [];
message.timeUnixNano = object.timeUnixNano ?? BigInt("0");
message.asDouble = object.asDouble ?? undefined;
message.asInt = object.asInt ?? undefined;
@@ -2864,14 +2930,19 @@ function base64FromBytes(arr: Uint8Array): string {
type Builtin = Date | Function | Uint8Array | string | number | boolean | bigint | undefined;
export type DeepPartial<T> = T extends Builtin ? T
: T extends globalThis.Array<infer U> ? globalThis.Array<DeepPartial<U>>
: T extends ReadonlyArray<infer U> ? ReadonlyArray<DeepPartial<U>>
: T extends {} ? { [K in keyof T]?: DeepPartial<T[K]> }
: Partial<T>;
export type DeepPartial<T> = T extends Builtin
? T
: T extends globalThis.Array<infer U>
? globalThis.Array<DeepPartial<U>>
: T extends ReadonlyArray<infer U>
? ReadonlyArray<DeepPartial<U>>
: T extends {}
? { [K in keyof T]?: DeepPartial<T[K]> }
: Partial<T>;
type KeysOfUnion<T> = T extends T ? keyof T : never;
export type Exact<P, I extends P> = P extends Builtin ? P
export type Exact<P, I extends P> = P extends Builtin
? P
: P & { [K in keyof P]: Exact<P[K], I[K]> } & { [K in Exclude<keyof I, KeysOfUnion<P>>]: never };
function longToBigint(long: Long) {
@@ -99,14 +99,19 @@ export const Resource = {
type Builtin = Date | Function | Uint8Array | string | number | boolean | bigint | undefined;
export type DeepPartial<T> = T extends Builtin ? T
: T extends globalThis.Array<infer U> ? globalThis.Array<DeepPartial<U>>
: T extends ReadonlyArray<infer U> ? ReadonlyArray<DeepPartial<U>>
: T extends {} ? { [K in keyof T]?: DeepPartial<T[K]> }
: Partial<T>;
export type DeepPartial<T> = T extends Builtin
? T
: T extends globalThis.Array<infer U>
? globalThis.Array<DeepPartial<U>>
: T extends ReadonlyArray<infer U>
? ReadonlyArray<DeepPartial<U>>
: T extends {}
? { [K in keyof T]?: DeepPartial<T[K]> }
: Partial<T>;
type KeysOfUnion<T> = T extends T ? keyof T : never;
export type Exact<P, I extends P> = P extends Builtin ? P
export type Exact<P, I extends P> = P extends Builtin
? P
: P & { [K in keyof P]: Exact<P[K], I[K]> } & { [K in Exclude<keyof I, KeysOfUnion<P>>]: never };
function isSet(value: any): boolean {
@@ -106,9 +106,7 @@ export interface ResourceSpans {
* The resource for the spans in this message.
* If this field is not set then no resource info is known.
*/
resource:
| Resource
| undefined;
resource: Resource | undefined;
/** A list of ScopeSpans that originate from a resource. */
scopeSpans: ScopeSpans[];
/**
@@ -128,9 +126,7 @@ export interface ScopeSpans {
* Semantically when InstrumentationScope isn't set, it is equivalent with
* an empty instrumentation scope name (unknown).
*/
scope:
| InstrumentationScope
| undefined;
scope: InstrumentationScope | undefined;
/** A list of Spans that originate from an instrumentation scope. */
spans: Span[];
/**
@@ -648,9 +644,10 @@ export const ResourceSpans = {
},
fromPartial<I extends Exact<DeepPartial<ResourceSpans>, I>>(object: I): ResourceSpans {
const message = createBaseResourceSpans();
message.resource = (object.resource !== undefined && object.resource !== null)
? Resource.fromPartial(object.resource)
: undefined;
message.resource =
object.resource !== undefined && object.resource !== null
? Resource.fromPartial(object.resource)
: undefined;
message.scopeSpans = object.scopeSpans?.map((e) => ScopeSpans.fromPartial(e)) || [];
message.schemaUrl = object.schemaUrl ?? "";
return message;
@@ -715,7 +712,9 @@ export const ScopeSpans = {
fromJSON(object: any): ScopeSpans {
return {
scope: isSet(object.scope) ? InstrumentationScope.fromJSON(object.scope) : undefined,
spans: globalThis.Array.isArray(object?.spans) ? object.spans.map((e: any) => Span.fromJSON(e)) : [],
spans: globalThis.Array.isArray(object?.spans)
? object.spans.map((e: any) => Span.fromJSON(e))
: [],
schemaUrl: isSet(object.schemaUrl) ? globalThis.String(object.schemaUrl) : "",
};
},
@@ -739,9 +738,10 @@ export const ScopeSpans = {
},
fromPartial<I extends Exact<DeepPartial<ScopeSpans>, I>>(object: I): ScopeSpans {
const message = createBaseScopeSpans();
message.scope = (object.scope !== undefined && object.scope !== null)
? InstrumentationScope.fromPartial(object.scope)
: undefined;
message.scope =
object.scope !== undefined && object.scope !== null
? InstrumentationScope.fromPartial(object.scope)
: undefined;
message.spans = object.spans?.map((e) => Span.fromPartial(e)) || [];
message.schemaUrl = object.schemaUrl ?? "";
return message;
@@ -794,13 +794,17 @@ export const Span = {
}
if (message.startTimeUnixNano !== BigInt("0")) {
if (BigInt.asUintN(64, message.startTimeUnixNano) !== message.startTimeUnixNano) {
throw new globalThis.Error("value provided for field message.startTimeUnixNano of type fixed64 too large");
throw new globalThis.Error(
"value provided for field message.startTimeUnixNano of type fixed64 too large"
);
}
writer.uint32(57).fixed64(message.startTimeUnixNano.toString());
}
if (message.endTimeUnixNano !== BigInt("0")) {
if (BigInt.asUintN(64, message.endTimeUnixNano) !== message.endTimeUnixNano) {
throw new globalThis.Error("value provided for field message.endTimeUnixNano of type fixed64 too large");
throw new globalThis.Error(
"value provided for field message.endTimeUnixNano of type fixed64 too large"
);
}
writer.uint32(65).fixed64(message.endTimeUnixNano.toString());
}
@@ -958,14 +962,20 @@ export const Span = {
fromJSON(object: any): Span {
return {
traceId: isSet(object.traceId) ? Buffer.from(bytesFromBase64(object.traceId)) : Buffer.alloc(0),
traceId: isSet(object.traceId)
? Buffer.from(bytesFromBase64(object.traceId))
: Buffer.alloc(0),
spanId: isSet(object.spanId) ? Buffer.from(bytesFromBase64(object.spanId)) : Buffer.alloc(0),
traceState: isSet(object.traceState) ? globalThis.String(object.traceState) : "",
parentSpanId: isSet(object.parentSpanId) ? Buffer.from(bytesFromBase64(object.parentSpanId)) : Buffer.alloc(0),
parentSpanId: isSet(object.parentSpanId)
? Buffer.from(bytesFromBase64(object.parentSpanId))
: Buffer.alloc(0),
flags: isSet(object.flags) ? globalThis.Number(object.flags) : 0,
name: isSet(object.name) ? globalThis.String(object.name) : "",
kind: isSet(object.kind) ? span_SpanKindFromJSON(object.kind) : 0,
startTimeUnixNano: isSet(object.startTimeUnixNano) ? BigInt(object.startTimeUnixNano) : BigInt("0"),
startTimeUnixNano: isSet(object.startTimeUnixNano)
? BigInt(object.startTimeUnixNano)
: BigInt("0"),
endTimeUnixNano: isSet(object.endTimeUnixNano) ? BigInt(object.endTimeUnixNano) : BigInt("0"),
attributes: globalThis.Array.isArray(object?.attributes)
? object.attributes.map((e: any) => KeyValue.fromJSON(e))
@@ -973,10 +983,18 @@ export const Span = {
droppedAttributesCount: isSet(object.droppedAttributesCount)
? globalThis.Number(object.droppedAttributesCount)
: 0,
events: globalThis.Array.isArray(object?.events) ? object.events.map((e: any) => Span_Event.fromJSON(e)) : [],
droppedEventsCount: isSet(object.droppedEventsCount) ? globalThis.Number(object.droppedEventsCount) : 0,
links: globalThis.Array.isArray(object?.links) ? object.links.map((e: any) => Span_Link.fromJSON(e)) : [],
droppedLinksCount: isSet(object.droppedLinksCount) ? globalThis.Number(object.droppedLinksCount) : 0,
events: globalThis.Array.isArray(object?.events)
? object.events.map((e: any) => Span_Event.fromJSON(e))
: [],
droppedEventsCount: isSet(object.droppedEventsCount)
? globalThis.Number(object.droppedEventsCount)
: 0,
links: globalThis.Array.isArray(object?.links)
? object.links.map((e: any) => Span_Link.fromJSON(e))
: [],
droppedLinksCount: isSet(object.droppedLinksCount)
? globalThis.Number(object.droppedLinksCount)
: 0,
status: isSet(object.status) ? Status.fromJSON(object.status) : undefined,
};
},
@@ -1054,9 +1072,10 @@ export const Span = {
message.droppedEventsCount = object.droppedEventsCount ?? 0;
message.links = object.links?.map((e) => Span_Link.fromPartial(e)) || [];
message.droppedLinksCount = object.droppedLinksCount ?? 0;
message.status = (object.status !== undefined && object.status !== null)
? Status.fromPartial(object.status)
: undefined;
message.status =
object.status !== undefined && object.status !== null
? Status.fromPartial(object.status)
: undefined;
return message;
},
};
@@ -1069,7 +1088,9 @@ export const Span_Event = {
encode(message: Span_Event, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer {
if (message.timeUnixNano !== BigInt("0")) {
if (BigInt.asUintN(64, message.timeUnixNano) !== message.timeUnixNano) {
throw new globalThis.Error("value provided for field message.timeUnixNano of type fixed64 too large");
throw new globalThis.Error(
"value provided for field message.timeUnixNano of type fixed64 too large"
);
}
writer.uint32(9).fixed64(message.timeUnixNano.toString());
}
@@ -1266,7 +1287,9 @@ export const Span_Link = {
fromJSON(object: any): Span_Link {
return {
traceId: isSet(object.traceId) ? Buffer.from(bytesFromBase64(object.traceId)) : Buffer.alloc(0),
traceId: isSet(object.traceId)
? Buffer.from(bytesFromBase64(object.traceId))
: Buffer.alloc(0),
spanId: isSet(object.spanId) ? Buffer.from(bytesFromBase64(object.spanId)) : Buffer.alloc(0),
traceState: isSet(object.traceState) ? globalThis.String(object.traceState) : "",
attributes: globalThis.Array.isArray(object?.attributes)
@@ -1418,14 +1441,19 @@ function base64FromBytes(arr: Uint8Array): string {
type Builtin = Date | Function | Uint8Array | string | number | boolean | bigint | undefined;
export type DeepPartial<T> = T extends Builtin ? T
: T extends globalThis.Array<infer U> ? globalThis.Array<DeepPartial<U>>
: T extends ReadonlyArray<infer U> ? ReadonlyArray<DeepPartial<U>>
: T extends {} ? { [K in keyof T]?: DeepPartial<T[K]> }
: Partial<T>;
export type DeepPartial<T> = T extends Builtin
? T
: T extends globalThis.Array<infer U>
? globalThis.Array<DeepPartial<U>>
: T extends ReadonlyArray<infer U>
? ReadonlyArray<DeepPartial<U>>
: T extends {}
? { [K in keyof T]?: DeepPartial<T[K]> }
: Partial<T>;
type KeysOfUnion<T> = T extends T ? keyof T : never;
export type Exact<P, I extends P> = P extends Builtin ? P
export type Exact<P, I extends P> = P extends Builtin
? P
: P & { [K in keyof P]: Exact<P[K], I[K]> } & { [K in Exclude<keyof I, KeysOfUnion<P>>]: never };
function longToBigint(long: Long) {
+7 -1
View File
@@ -1,5 +1,11 @@
import { describe, it, expect } from "vitest";
import { permissiveAbility, superAbility, denyAbility, buildFallbackAbility, buildJwtAbility } from "./ability.js";
import {
permissiveAbility,
superAbility,
denyAbility,
buildFallbackAbility,
buildJwtAbility,
} from "./ability.js";
describe("permissiveAbility", () => {
it("allows any action on any resource type", () => {
+15 -7
View File
@@ -91,7 +91,10 @@ class RoleBaseAccessFallbackController implements RoleBaseAccessController {
// pre-RBAC routes that haven't been migrated, but it's a dead
// code path for any route that uses `createLoaderApiRoute` /
// `createActionApiRoute`.
const rawToken = request.headers.get("Authorization")?.replace(/^Bearer /, "").trim();
const rawToken = request.headers
.get("Authorization")
?.replace(/^Bearer /, "")
.trim();
if (!rawToken) return { ok: false, status: 401, error: "Invalid or Missing API key" };
if (options?.allowJWT && isPublicJWT(rawToken)) {
@@ -165,9 +168,7 @@ class RoleBaseAccessFallbackController implements RoleBaseAccessController {
},
},
parentEnvironment: { select: { id: true, apiKey: true } },
childEnvironments: branchName
? { where: { branchName, archivedAt: null } }
: undefined,
childEnvironments: branchName ? { where: { branchName, archivedAt: null } } : undefined,
} as const;
let env = await this.replica.runtimeEnvironment.findFirst({
where: { apiKey: rawToken },
@@ -338,7 +339,10 @@ class RoleBaseAccessFallbackController implements RoleBaseAccessController {
request: Request,
context: { organizationId?: string; projectId?: string }
): Promise<UserActorAuthResult> {
const rawToken = request.headers.get("Authorization")?.replace(/^Bearer /, "").trim();
const rawToken = request.headers
.get("Authorization")
?.replace(/^Bearer /, "")
.trim();
if (!rawToken || !isUserActorToken(rawToken)) {
return { ok: false, status: 401, error: "Invalid or Missing user-actor token" };
}
@@ -431,7 +435,9 @@ function isPublicJWT(token: string): boolean {
const parts = token.split(".");
if (parts.length !== 3) return false;
try {
const payload = JSON.parse(Buffer.from(parts[1].replace(/-/g, "+").replace(/_/g, "/"), "base64").toString("utf8"));
const payload = JSON.parse(
Buffer.from(parts[1].replace(/-/g, "+").replace(/_/g, "/"), "base64").toString("utf8")
);
return payload !== null && typeof payload === "object" && payload.pub === true;
} catch {
return false;
@@ -442,7 +448,9 @@ function extractJWTSub(token: string): string | undefined {
const parts = token.split(".");
if (parts.length !== 3) return undefined;
try {
const payload = JSON.parse(Buffer.from(parts[1].replace(/-/g, "+").replace(/_/g, "/"), "base64").toString("utf8"));
const payload = JSON.parse(
Buffer.from(parts[1].replace(/-/g, "+").replace(/_/g, "/"), "base64").toString("utf8")
);
return payload !== null && typeof payload === "object" && typeof payload.sub === "string"
? payload.sub
: undefined;
+5 -14
View File
@@ -108,10 +108,8 @@ class LazyController implements RoleBaseAccessController {
// specifier in the error message is the plugin's own moduleName.
const code = (err as NodeJS.ErrnoException | undefined)?.code;
const message = err instanceof Error ? err.message : String(err);
const isModuleNotFound =
code === "ERR_MODULE_NOT_FOUND" || code === "MODULE_NOT_FOUND";
const isPluginItselfMissing =
isModuleNotFound && message.includes(moduleName);
const isModuleNotFound = code === "ERR_MODULE_NOT_FOUND" || code === "MODULE_NOT_FOUND";
const isPluginItselfMissing = isModuleNotFound && message.includes(moduleName);
if (!isPluginItselfMissing) {
// Either the error wasn't a missing-module error at all, or the
@@ -122,9 +120,7 @@ class LazyController implements RoleBaseAccessController {
err
);
} else if (process.env.RBAC_LOG_FALLBACK === "1") {
console.log(
"RBAC: no plugin installed (ERR_MODULE_NOT_FOUND); using fallback"
);
console.log("RBAC: no plugin installed (ERR_MODULE_NOT_FOUND); using fallback");
}
// Fail-fast for deployments that require plugins to be present. Set
@@ -135,9 +131,7 @@ class LazyController implements RoleBaseAccessController {
// rolled back. Self-hosters leave REQUIRE_PLUGINS unset and continue
// to use the fallback when no plugin is installed.
if (process.env.REQUIRE_PLUGINS === "1") {
throw new Error(
`REQUIRE_PLUGINS=1 but plugin "${moduleName}" did not load: ${message}`
);
throw new Error(`REQUIRE_PLUGINS=1 but plugin "${moduleName}" did not load: ${message}`);
}
return new RoleBaseAccessFallback(prisma, {
@@ -289,10 +283,7 @@ class LazyController implements RoleBaseAccessController {
class RoleBaseAccess {
// Synchronous — returns a lazy controller that resolves any installed
// plugin on first call.
create(
prisma: RbacPrismaInput,
options?: RbacCreateOptions
): RoleBaseAccessController {
create(prisma: RbacPrismaInput, options?: RbacCreateOptions): RoleBaseAccessController {
return new LazyController(prisma, options);
}
}
+1 -1
View File
@@ -12,4 +12,4 @@
"scripts": {
"typecheck": "tsc --noEmit"
}
}
}

Some files were not shown because too many files have changed in this diff Show More