Skip to content
Merged
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
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ export const handleHttpProvider = (config: CreateHttpProviderConfig<HandleProvid
createHttpProvider<HandleProvider>({
...config,
apiVersion: config.apiVersion || apiVersion.handle,
// eslint-disable-next-line @typescript-eslint/no-explicit-any
modifyData: (method: string | number | symbol, data: any) =>
method === 'resolveHandles' ? { ...data, check_handle: true } : { ...data },
paths: handleProviderPaths,
serviceSlug: 'handle'
});
15 changes: 12 additions & 3 deletions packages/cardano-services-client/src/HttpProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@ export interface HttpProviderConfig<T extends Provider> {

/** Slug used in the URL path */
serviceSlug: string;

/** Function to modify the input data before performing the HTTP request. */
modifyData?: (method: string | number | symbol, data: any) => any;
}

/** The subset of parameters from HttpProviderConfig that must be set by the client code. */
Expand All @@ -55,6 +58,8 @@ const transformRequest: AxiosRequestTransformer = (data) => {
return JSON.stringify(toSerializableObject(data));
};

const defaultModifyData = (_method: string | number | symbol, data: any) => ({ ...data });

/**
* Creates a HTTP client for specified provider type, following some conventions:
* - All methods use POST requests
Expand All @@ -73,9 +78,12 @@ export const createHttpProvider = <T extends Provider>({
paths,
adapter,
logger,
modifyData,
serviceSlug
}: HttpProviderConfig<T>): T =>
new Proxy<T>({} as T, {
}: HttpProviderConfig<T>): T => {
const internalModifyData = modifyData || defaultModifyData;

return new Proxy<T>({} as T, {
// eslint-disable-next-line sonarjs/cognitive-complexity
get(_, prop) {
const method = prop as keyof T;
Expand All @@ -87,7 +95,7 @@ export const createHttpProvider = <T extends Provider>({
...axiosOptions,
adapter,
baseURL: `${baseUrl.replace(/\/$/, '')}/v${apiVersion}/${serviceSlug}`,
data: { ...args[0] },
data: internalModifyData(method, args[0]),
headers: {
...axiosOptions?.headers,
'Content-Type': 'application/json',
Expand Down Expand Up @@ -127,3 +135,4 @@ export const createHttpProvider = <T extends Provider>({
return prop in paths;
}
});
};
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,15 @@ describe('handleHttpProvider', () => {
axiosMock.onPost().replyOnce(200, []);
await expect(provider.resolveHandles({ handles: [] })).resolves.toEqual([]);
});

test('resolve handles has one more parameter', async () => {
const provider = handleHttpProvider(config);

axiosMock.onPost().reply((cfg) => [200, cfg.data]);

await expect(provider.resolveHandles({ handles: ['test'] })).resolves.toEqual({
check_handle: true,
handles: ['test']
});
});
});
32 changes: 30 additions & 2 deletions packages/cardano-services-client/test/HttpProvider.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,11 @@ const packageJson = require(path.join(__dirname, '..', 'package.json'));

type ComplexArg2 = { map: Map<string, Uint8Array> };
type ComplexResponse = Map<bigint, Uint8Array>[];
type OptionalParameters = { num?: number; str?: string };
interface TestProvider extends Provider {
noArgsEmptyReturn(): Promise<void>;
complexArgsAndReturn({ arg1, arg2 }: { arg1: bigint; arg2: ComplexArg2 }): Promise<ComplexResponse>;
optionalParameters(args: OptionalParameters): Promise<OptionalParameters>;
}

const apiVersion = '1.0.0';
Expand All @@ -34,7 +36,8 @@ const createStubHttpProviderServer = async (port: number, urlPath: string, handl
const stubProviderPaths = {
complexArgsAndReturn: '/complex',
healthCheck: '/health',
noArgsEmptyReturn: '/simple'
noArgsEmptyReturn: '/simple',
optionalParameters: '/optional'
};

describe('createHttpProvider', () => {
Expand All @@ -43,7 +46,7 @@ describe('createHttpProvider', () => {
let closeServer: () => Promise<unknown>;

const createTxSubmitProviderClient = (
config: Pick<HttpProviderConfig<TestProvider>, 'axiosOptions' | 'mapError'> = {}
config: Pick<HttpProviderConfig<TestProvider>, 'axiosOptions' | 'mapError' | 'modifyData'> = {}
) =>
createHttpProvider<TestProvider>({
apiVersion,
Expand Down Expand Up @@ -113,6 +116,31 @@ describe('createHttpProvider', () => {
});
});

describe('modifyData', () => {
beforeEach(
async () =>
(closeServer = await createStubHttpProviderServer(port, stubProviderPaths.optionalParameters, (req, res) =>
res.send(req.body)
))
);

it("defaultModifyData doesn't change the input data", async () => {
const provider = createTxSubmitProviderClient();
const data = { num: 23 };

const response = await provider.optionalParameters(data);
expect(response).toEqual(data);
});

it('modifyData changes the input data as expected', async () => {
const provider = createTxSubmitProviderClient({ modifyData: (_, data) => ({ ...data, added: true }) });
const data = { num: 23 };

const response = await provider.optionalParameters(data);
expect(response).toEqual({ ...data, added: true });
});
});

describe('errors', () => {
describe('connection errors', () => {
it('maps ECONNREFUSED and ENOTFOUND to ProviderError{ConnectionFailure}', async () => {
Expand Down
Loading