Add configure function to be able to configure the SDK manually
And move the ApiClient configuration away from AsyncLocalStorage and use our globals system instead
This commit is contained in:
@@ -0,0 +1,6 @@
|
|||||||
|
---
|
||||||
|
"@trigger.dev/sdk": patch
|
||||||
|
"@trigger.dev/core": patch
|
||||||
|
---
|
||||||
|
|
||||||
|
Add configure function to be able to configure the SDK manually
|
||||||
@@ -51,11 +51,15 @@ export class UpsertTaskScheduleService extends BaseService {
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (!task) {
|
if (!task) {
|
||||||
throw new Error(`Task with identifier ${schedule.taskIdentifier} not found in project.`);
|
throw new ServiceValidationError(
|
||||||
|
`Task with identifier ${schedule.taskIdentifier} not found in project.`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (task.triggerSource !== "SCHEDULED") {
|
if (task.triggerSource !== "SCHEDULED") {
|
||||||
throw new Error(`Task with identifier ${schedule.taskIdentifier} is not a scheduled task.`);
|
throw new ServiceValidationError(
|
||||||
|
`Task with identifier ${schedule.taskIdentifier} is not a scheduled task.`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const result = await $transaction(this._prisma, async (tx) => {
|
const result = await $transaction(this._prisma, async (tx) => {
|
||||||
|
|||||||
@@ -10,3 +10,37 @@ When you [trigger a task](/v3/triggering) from your backend code, you need to se
|
|||||||
Each environment has its own secret key. You can find the value on the API keys page in the Trigger.dev dashboard:
|
Each environment has its own secret key. You can find the value on the API keys page in the Trigger.dev dashboard:
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
|
### Automatically Configuring the SDK
|
||||||
|
|
||||||
|
To automatically configure the SDK with your secret key, you can set the `TRIGGER_SECRET_KEY` environment variable. The SDK will automatically use this value when calling API methods (like `trigger`).
|
||||||
|
|
||||||
|
```bash
|
||||||
|
export TRIGGER_SECRET_KEY=tr_dev_…
|
||||||
|
```
|
||||||
|
|
||||||
|
You can do the same if you are self-hosting and need to change the default URL by using `TRIGGER_API_URL`.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
export TRIGGER_API_URL=https://trigger.example.com
|
||||||
|
```
|
||||||
|
|
||||||
|
The default URL is `https://api.trigger.dev`.
|
||||||
|
|
||||||
|
### Manually Configuring the SDK
|
||||||
|
|
||||||
|
If you prefer to manually configure the SDK, you can call the `configure` method:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
import { configure } from "@trigger.dev/sdk/v3";
|
||||||
|
import { myTask } from "./trigger/myTasks";
|
||||||
|
|
||||||
|
configure({
|
||||||
|
secretKey: "tr_dev_1234", // WARNING: Never actually hardcode your secret key like this
|
||||||
|
baseURL: "https://mytrigger.example.com", // Optional
|
||||||
|
});
|
||||||
|
|
||||||
|
async function triggerTask() {
|
||||||
|
await myTask.trigger({ userId: "1234" }); // This will use the secret key and base URL you configured
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|||||||
@@ -253,44 +253,3 @@ export class ApiClient {
|
|||||||
return headers;
|
return headers;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type ApiClientContext = {
|
|
||||||
baseURL: string;
|
|
||||||
accessToken: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
export class ApiClientManager {
|
|
||||||
private _storage: SafeAsyncLocalStorage<ApiClientContext> =
|
|
||||||
new SafeAsyncLocalStorage<ApiClientContext>();
|
|
||||||
|
|
||||||
get baseURL(): string | undefined {
|
|
||||||
const store = this.#getStore();
|
|
||||||
return store?.baseURL ?? getEnvVar("TRIGGER_API_URL") ?? "https://api.trigger.dev";
|
|
||||||
}
|
|
||||||
|
|
||||||
get accessToken(): string | undefined {
|
|
||||||
const store = this.#getStore();
|
|
||||||
return store?.accessToken ?? getEnvVar("TRIGGER_SECRET_KEY");
|
|
||||||
}
|
|
||||||
|
|
||||||
get client(): ApiClient | undefined {
|
|
||||||
if (!this.baseURL || !this.accessToken) {
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
return new ApiClient(this.baseURL, this.accessToken);
|
|
||||||
}
|
|
||||||
|
|
||||||
runWith<R extends (...args: any[]) => Promise<any>>(
|
|
||||||
context: ApiClientContext,
|
|
||||||
fn: R
|
|
||||||
): Promise<ReturnType<R>> {
|
|
||||||
return this._storage.runWith(context, fn);
|
|
||||||
}
|
|
||||||
|
|
||||||
#getStore(): ApiClientContext | undefined {
|
|
||||||
return this._storage.getStore();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export const apiClientManager = new ApiClientManager();
|
|
||||||
|
|||||||
@@ -0,0 +1,7 @@
|
|||||||
|
// Split module-level variable definition into separate files to allow
|
||||||
|
// tree-shaking on each api instance.
|
||||||
|
import { APIClientManagerAPI } from "./apiClientManager";
|
||||||
|
/** Entrypoint for logger API */
|
||||||
|
export const apiClientManager = APIClientManagerAPI.getInstance();
|
||||||
|
|
||||||
|
export type { ApiClientConfiguration } from "./apiClientManager/types";
|
||||||
@@ -0,0 +1,50 @@
|
|||||||
|
import { ApiClient } from "../apiClient";
|
||||||
|
import { getGlobal, registerGlobal, unregisterGlobal } from "../utils/globals";
|
||||||
|
import { getEnvVar } from "../utils/getEnv";
|
||||||
|
import { ApiClientConfiguration } from "./types";
|
||||||
|
|
||||||
|
const API_NAME = "api-client";
|
||||||
|
|
||||||
|
export class APIClientManagerAPI {
|
||||||
|
private static _instance?: APIClientManagerAPI;
|
||||||
|
|
||||||
|
private constructor() {}
|
||||||
|
|
||||||
|
public static getInstance(): APIClientManagerAPI {
|
||||||
|
if (!this._instance) {
|
||||||
|
this._instance = new APIClientManagerAPI();
|
||||||
|
}
|
||||||
|
|
||||||
|
return this._instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
public disable() {
|
||||||
|
unregisterGlobal(API_NAME);
|
||||||
|
}
|
||||||
|
|
||||||
|
public setGlobalAPIClientConfiguration(config: ApiClientConfiguration): boolean {
|
||||||
|
return registerGlobal(API_NAME, config);
|
||||||
|
}
|
||||||
|
|
||||||
|
get baseURL(): string | undefined {
|
||||||
|
const store = this.#getConfig();
|
||||||
|
return store?.baseURL ?? getEnvVar("TRIGGER_API_URL") ?? "https://api.trigger.dev";
|
||||||
|
}
|
||||||
|
|
||||||
|
get accessToken(): string | undefined {
|
||||||
|
const store = this.#getConfig();
|
||||||
|
return store?.secretKey ?? getEnvVar("TRIGGER_SECRET_KEY");
|
||||||
|
}
|
||||||
|
|
||||||
|
get client(): ApiClient | undefined {
|
||||||
|
if (!this.baseURL || !this.accessToken) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new ApiClient(this.baseURL, this.accessToken);
|
||||||
|
}
|
||||||
|
|
||||||
|
#getConfig(): ApiClientConfiguration | undefined {
|
||||||
|
return getGlobal(API_NAME);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
export type ApiClientConfiguration = {
|
||||||
|
baseURL?: string;
|
||||||
|
secretKey?: string;
|
||||||
|
};
|
||||||
@@ -6,6 +6,7 @@ export * from "./limits";
|
|||||||
export * from "./logger-api";
|
export * from "./logger-api";
|
||||||
export * from "./runtime-api";
|
export * from "./runtime-api";
|
||||||
export * from "./task-context-api";
|
export * from "./task-context-api";
|
||||||
|
export * from "./apiClientManager-api";
|
||||||
export * from "./schemas";
|
export * from "./schemas";
|
||||||
export { SemanticInternalAttributes } from "./semanticInternalAttributes";
|
export { SemanticInternalAttributes } from "./semanticInternalAttributes";
|
||||||
export * from "./task-catalog-api";
|
export * from "./task-catalog-api";
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import { ApiClientConfiguration } from "../apiClientManager/types";
|
||||||
import { Clock } from "../clock/clock";
|
import { Clock } from "../clock/clock";
|
||||||
import type { RuntimeManager } from "../runtime/manager";
|
import type { RuntimeManager } from "../runtime/manager";
|
||||||
import { TaskCatalog } from "../task-catalog/catalog";
|
import { TaskCatalog } from "../task-catalog/catalog";
|
||||||
@@ -50,4 +51,5 @@ type TriggerDotDevGlobalAPI = {
|
|||||||
clock?: Clock;
|
clock?: Clock;
|
||||||
["task-catalog"]?: TaskCatalog;
|
["task-catalog"]?: TaskCatalog;
|
||||||
["task-context"]?: TaskContext;
|
["task-context"]?: TaskContext;
|
||||||
|
["api-client"]?: ApiClientConfiguration;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
import { Attributes, Span } from "@opentelemetry/api";
|
import { Attributes, Span } from "@opentelemetry/api";
|
||||||
import { apiClientManager } from "../apiClient";
|
|
||||||
import { OFFLOAD_IO_PACKET_LENGTH_LIMIT, imposeAttributeLimits } from "../limits";
|
import { OFFLOAD_IO_PACKET_LENGTH_LIMIT, imposeAttributeLimits } from "../limits";
|
||||||
import { SemanticInternalAttributes } from "../semanticInternalAttributes";
|
import { SemanticInternalAttributes } from "../semanticInternalAttributes";
|
||||||
import { TriggerTracer } from "../tracer";
|
import { TriggerTracer } from "../tracer";
|
||||||
import { flattenAttributes } from "./flattenAttributes";
|
import { flattenAttributes } from "./flattenAttributes";
|
||||||
|
import { apiClientManager } from "../apiClientManager-api";
|
||||||
|
|
||||||
export type IOPacket = {
|
export type IOPacket = {
|
||||||
data?: string | undefined;
|
data?: string | undefined;
|
||||||
|
|||||||
@@ -1,26 +1,52 @@
|
|||||||
export * from "./tasks";
|
|
||||||
export * from "./config";
|
|
||||||
export * from "./wait";
|
|
||||||
export * from "./cache";
|
export * from "./cache";
|
||||||
|
export * from "./config";
|
||||||
export { retry, type RetryOptions } from "./retry";
|
export { retry, type RetryOptions } from "./retry";
|
||||||
export { queue } from "./shared";
|
export { queue } from "./shared";
|
||||||
|
export * from "./tasks";
|
||||||
import type { Context } from "./shared";
|
export * from "./wait";
|
||||||
export type { Context };
|
export type { Context };
|
||||||
|
|
||||||
|
import type { Context } from "./shared";
|
||||||
|
|
||||||
|
import type { ApiClientConfiguration } from "@trigger.dev/core/v3";
|
||||||
|
import { apiClientManager } from "@trigger.dev/core/v3";
|
||||||
|
|
||||||
|
export type { ApiClientConfiguration };
|
||||||
|
|
||||||
export {
|
export {
|
||||||
|
APIError,
|
||||||
|
AuthenticationError,
|
||||||
|
BadRequestError,
|
||||||
|
ConflictError,
|
||||||
|
InternalServerError,
|
||||||
|
NotFoundError,
|
||||||
|
PermissionDeniedError,
|
||||||
|
RateLimitError,
|
||||||
|
UnprocessableEntityError,
|
||||||
logger,
|
logger,
|
||||||
type LogLevel,
|
type LogLevel,
|
||||||
APIError,
|
|
||||||
BadRequestError,
|
|
||||||
AuthenticationError,
|
|
||||||
PermissionDeniedError,
|
|
||||||
NotFoundError,
|
|
||||||
ConflictError,
|
|
||||||
UnprocessableEntityError,
|
|
||||||
RateLimitError,
|
|
||||||
InternalServerError,
|
|
||||||
} from "@trigger.dev/core/v3";
|
} from "@trigger.dev/core/v3";
|
||||||
|
|
||||||
export { runs } from "./management";
|
export { runs } from "./management";
|
||||||
export * as schedules from "./schedules";
|
export * as schedules from "./schedules";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register the global API client configuration. Alternatively, you can set the `TRIGGER_SECRET_KEY` and `TRIGGER_API_URL` environment variables.
|
||||||
|
* @param options The API client configuration.
|
||||||
|
* @param options.baseURL The base URL of the Trigger API. (default: `https://api.trigger.dev`)
|
||||||
|
* @param options.secretKey The secret key to authenticate with the Trigger API. (default: `process.env.TRIGGER_SECRET_KEY`) This can be found in your Trigger.dev project "API Keys" settings.
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
*
|
||||||
|
* ```typescript
|
||||||
|
* import { configure } from "@trigger.dev/sdk/v3";
|
||||||
|
*
|
||||||
|
* configure({
|
||||||
|
* baseURL: "https://api.trigger.dev",
|
||||||
|
* secretKey: "tr_dev_1234567890"
|
||||||
|
* });
|
||||||
|
* ```
|
||||||
|
*/
|
||||||
|
export function configure(options: ApiClientConfiguration) {
|
||||||
|
apiClientManager.setGlobalAPIClientConfiguration(options);
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { APIError, runs, schedules } from "@trigger.dev/sdk/v3";
|
import { APIError, configure, runs, schedules } from "@trigger.dev/sdk/v3";
|
||||||
import { simpleChildTask } from "./trigger/subtasks";
|
import { simpleChildTask } from "./trigger/subtasks";
|
||||||
import dotenv from "dotenv";
|
import dotenv from "dotenv";
|
||||||
import { firstScheduledTask } from "./trigger/scheduled";
|
import { firstScheduledTask } from "./trigger/scheduled";
|
||||||
|
|||||||
Reference in New Issue
Block a user