Skip to content

Commit

Permalink
feat(framework): add fetchOptions parameter to Client for custom …
Browse files Browse the repository at this point in the history
…fetch configuration

close novuhq#7432
  • Loading branch information
wh5938316 committed Jan 5, 2025
1 parent ae0c2b0 commit 772a66e
Show file tree
Hide file tree
Showing 6 changed files with 23 additions and 3 deletions.
4 changes: 4 additions & 0 deletions packages/framework/src/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,8 @@ export class Client {

public apiUrl: string;

public fetchOptions?: Record<string, any>;

public version: string = SDK_VERSION;

public strictAuthentication: boolean;
Expand All @@ -75,6 +77,7 @@ export class Client {
const builtOpts = this.buildOptions(options);
this.apiUrl = builtOpts.apiUrl;
this.secretKey = builtOpts.secretKey;
this.fetchOptions = builtOpts.fetchOptions;
this.strictAuthentication = builtOpts.strictAuthentication;
this.templateEngine.registerFilter('json', (value, spaces) =>
stringifyDataStructureWithSingleQuotes(value, spaces)
Expand All @@ -85,6 +88,7 @@ export class Client {
const builtConfiguration: Required<ClientOptions> = {
apiUrl: resolveApiUrl(providedOptions?.apiUrl),
secretKey: resolveSecretKey(providedOptions?.secretKey),
fetchOptions: providedOptions?.fetchOptions ?? {},
strictAuthentication: !isRuntimeInDevelopment(),
};

Expand Down
2 changes: 1 addition & 1 deletion packages/framework/src/handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ export class NovuRequestHandler<Input extends any[] = any[], Output = any> {
this.handler = options.handler;
this.client = options.client ? options.client : new Client();
this.workflows = options.workflows;
this.http = initApiClient(this.client.secretKey, this.client.apiUrl);
this.http = initApiClient(this.client.secretKey, this.client.apiUrl, this.client.fetchOptions);
this.frameworkName = options.frameworkName;
this.hmacEnabled = this.client.strictAuthentication;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ export function workflow<
const options = workflowOptions || {};

const trigger: Workflow<T_PayloadUnvalidated>['trigger'] = async (event) => {
const apiClient = initApiClient(resolveSecretKey(event.secretKey), resolveApiUrl(event.apiUrl));
const apiClient = initApiClient(resolveSecretKey(event.secretKey), resolveApiUrl(event.apiUrl), event.fetchOptions);

const unvalidatedData = (event.payload || {}) as T_PayloadUnvalidated;
let validatedData: T_PayloadValidated;
Expand Down
6 changes: 6 additions & 0 deletions packages/framework/src/types/config.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,10 @@ export type ClientOptions = {
* Defaults to true.
*/
strictAuthentication?: boolean;

/**
* Additional fetch options to be passed to the fetch API.
* This can be used to set custom agent, headers, etc.
*/
fetchOptions?: Record<string, any>;
};
4 changes: 4 additions & 0 deletions packages/framework/src/types/event.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,10 @@ export type EventTriggerParams<T_Payload = EventPayload> = {
* Override secret key for the trigger
*/
secretKey?: string;
/**
* Additional fetch options to be passed to the fetch API.
*/
fetchOptions?: Record<string, any>;
} & ConditionalPartial<
{
/**
Expand Down
8 changes: 7 additions & 1 deletion packages/framework/src/utils/http.utils.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,20 @@
import { checkIsResponseError } from '../shared';
import { BridgeError, MissingSecretKeyError, PlatformError } from '../errors';

export const initApiClient = (secretKey: string, apiUrl: string) => {
export const initApiClient = (secretKey: string, apiUrl: string, fetchOptions?: Record<string, any>) => {
const { headers: additionalHeaders, ...restFetchOptions } = fetchOptions || {};

if (!secretKey) {
throw new MissingSecretKeyError();
}

return {
post: async <T = unknown>(route: string, data: Record<string, unknown>): Promise<T> => {
const response = await fetch(`${apiUrl}/v1${route}`, {
...restFetchOptions,
method: 'POST',
headers: {
...additionalHeaders,
'Content-Type': 'application/json',
Authorization: `ApiKey ${secretKey}`,
},
Expand All @@ -30,8 +34,10 @@ export const initApiClient = (secretKey: string, apiUrl: string) => {
delete: async <T = unknown>(route: string): Promise<T> => {
return (
await fetch(`${apiUrl}/v1${route}`, {
...restFetchOptions,
method: 'DELETE',
headers: {
...additionalHeaders,
'Content-Type': 'application/json',
Authorization: `ApiKey ${secretKey}`,
},
Expand Down

0 comments on commit 772a66e

Please sign in to comment.