feat!: @rudder/sdk 0.1.0: createClient, idempotent modules.call retries, storage save(type, data), drop resources and projectStorage
This commit is contained in:
@@ -1,11 +1,59 @@
|
||||
import type { RudderContext } from '../core/context.js';
|
||||
import { api } from '../generated/api.js';
|
||||
import type { CallModuleFunctionClientResponse } from '../generated/modules.js';
|
||||
import { uuidv4 } from '../core/uuid.js';
|
||||
import { RudderHttpError, RudderModuleError } from '../client/RudderError.js';
|
||||
import type {
|
||||
CallModuleFunctionClientResponse,
|
||||
CallModuleFunctionRequest,
|
||||
ModuleErrorResponse,
|
||||
} from '../generated/modules.js';
|
||||
|
||||
export interface ModuleCallOptions {
|
||||
/** Version the caller was built against; sent as `X-Rudder-Module-Version: <module>@<version>`. */
|
||||
moduleVersion?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* ModulesDomain — calls module functions. Usually reached through a client
|
||||
* generated by `rudder client generate`, not directly.
|
||||
*/
|
||||
export class ModulesDomain {
|
||||
constructor(private readonly ctx: RudderContext) {}
|
||||
|
||||
call(module: string, fn: string, args?: unknown): Promise<CallModuleFunctionClientResponse> {
|
||||
return api.callModuleFunction(this.ctx, { module, fn }, { args });
|
||||
/**
|
||||
* Calls `module.fn` and returns its `result`. Each call gets one
|
||||
* Idempotency-Key reused across retries (network errors, 5xx, 409 `conflict`).
|
||||
* Rejects with {@link RudderModuleError} on 422.
|
||||
*/
|
||||
async call<T = unknown>(
|
||||
module: string,
|
||||
fn: string,
|
||||
args?: unknown,
|
||||
options?: ModuleCallOptions,
|
||||
): Promise<T> {
|
||||
const headers: Record<string, string> = { 'Idempotency-Key': uuidv4() };
|
||||
if (options?.moduleVersion) {
|
||||
headers['X-Rudder-Module-Version'] = `${module}@${options.moduleVersion}`;
|
||||
}
|
||||
const path = `/sdk/v1/modules/${encodeURIComponent(module)}/${encodeURIComponent(fn)}`;
|
||||
try {
|
||||
const response = await this.ctx.request<CallModuleFunctionClientResponse>(
|
||||
'POST',
|
||||
path,
|
||||
{ args: args ?? {} } satisfies CallModuleFunctionRequest,
|
||||
{ headers, retry: true },
|
||||
);
|
||||
return response?.result as T;
|
||||
} catch (err) {
|
||||
if (err instanceof RudderHttpError && err.status === 422 && err.code) {
|
||||
let payload: Partial<ModuleErrorResponse> = {};
|
||||
try {
|
||||
payload = JSON.parse(err.body);
|
||||
} catch {
|
||||
// err.code came from this body, so it is JSON; keep the fallback anyway.
|
||||
}
|
||||
throw new RudderModuleError(err.statusText, err.body, { ...payload, code: err.code });
|
||||
}
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user