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) {
|
||||
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") {
|
||||
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) => {
|
||||
|
||||
@@ -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:
|
||||
|
||||

|
||||
|
||||
### 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;
|
||||
}
|
||||
}
|
||||
|
||||
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 "./runtime-api";
|
||||
export * from "./task-context-api";
|
||||
export * from "./apiClientManager-api";
|
||||
export * from "./schemas";
|
||||
export { SemanticInternalAttributes } from "./semanticInternalAttributes";
|
||||
export * from "./task-catalog-api";
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { ApiClientConfiguration } from "../apiClientManager/types";
|
||||
import { Clock } from "../clock/clock";
|
||||
import type { RuntimeManager } from "../runtime/manager";
|
||||
import { TaskCatalog } from "../task-catalog/catalog";
|
||||
@@ -50,4 +51,5 @@ type TriggerDotDevGlobalAPI = {
|
||||
clock?: Clock;
|
||||
["task-catalog"]?: TaskCatalog;
|
||||
["task-context"]?: TaskContext;
|
||||
["api-client"]?: ApiClientConfiguration;
|
||||
};
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import { Attributes, Span } from "@opentelemetry/api";
|
||||
import { apiClientManager } from "../apiClient";
|
||||
import { OFFLOAD_IO_PACKET_LENGTH_LIMIT, imposeAttributeLimits } from "../limits";
|
||||
import { SemanticInternalAttributes } from "../semanticInternalAttributes";
|
||||
import { TriggerTracer } from "../tracer";
|
||||
import { flattenAttributes } from "./flattenAttributes";
|
||||
import { apiClientManager } from "../apiClientManager-api";
|
||||
|
||||
export type IOPacket = {
|
||||
data?: string | undefined;
|
||||
|
||||
@@ -1,26 +1,52 @@
|
||||
export * from "./tasks";
|
||||
export * from "./config";
|
||||
export * from "./wait";
|
||||
export * from "./cache";
|
||||
export * from "./config";
|
||||
export { retry, type RetryOptions } from "./retry";
|
||||
export { queue } from "./shared";
|
||||
|
||||
import type { Context } from "./shared";
|
||||
export * from "./tasks";
|
||||
export * from "./wait";
|
||||
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 {
|
||||
APIError,
|
||||
AuthenticationError,
|
||||
BadRequestError,
|
||||
ConflictError,
|
||||
InternalServerError,
|
||||
NotFoundError,
|
||||
PermissionDeniedError,
|
||||
RateLimitError,
|
||||
UnprocessableEntityError,
|
||||
logger,
|
||||
type LogLevel,
|
||||
APIError,
|
||||
BadRequestError,
|
||||
AuthenticationError,
|
||||
PermissionDeniedError,
|
||||
NotFoundError,
|
||||
ConflictError,
|
||||
UnprocessableEntityError,
|
||||
RateLimitError,
|
||||
InternalServerError,
|
||||
} from "@trigger.dev/core/v3";
|
||||
|
||||
export { runs } from "./management";
|
||||
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 dotenv from "dotenv";
|
||||
import { firstScheduledTask } from "./trigger/scheduled";
|
||||
|
||||
Reference in New Issue
Block a user