Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(framework): add fetchOptions parameter to Client for custom fetch configuration #7433

Open
wants to merge 1 commit into
base: next
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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>;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To provide better DX, I suggest typing this as a RequestInit.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@wh5938316 any updates on this?

};
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
Loading