Skip to content

Commit

Permalink
Add variables mapper
Browse files Browse the repository at this point in the history
  • Loading branch information
louiszawadzki committed Sep 21, 2023
1 parent b45680a commit f01e058
Show file tree
Hide file tree
Showing 3 changed files with 111 additions and 4 deletions.
16 changes: 12 additions & 4 deletions packages/react-native-apollo-client/src/DatadogLink.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,20 @@ import {
} from '@datadog/mobile-react-native';

import { getOperationName, getVariables, getOperationType } from './helpers';
import type { VariablesMapper } from './mappers';
import { mapVariables } from './mappers';

export class DatadogLink extends ApolloLink {
constructor() {
private variablesMapper: undefined | VariablesMapper;

constructor({ variablesMapper }: { variablesMapper?: VariablesMapper }) {
super((operation, forward) => {
const operationName = getOperationName(operation);
const formattedVariables = getVariables(operation);
const mappedVariables = mapVariables(
formattedVariables,
this.variablesMapper
);
const operationType = getOperationType(operation);

operation.setContext(({ headers = {} }) => {
Expand All @@ -31,9 +39,7 @@ export class DatadogLink extends ApolloLink {
newHeaders[
DATADOG_GRAPH_QL_OPERATION_NAME_HEADER
] = operationName;
newHeaders[
DATADOG_GRAPH_QL_VARIABLES_HEADER
] = formattedVariables;
newHeaders[DATADOG_GRAPH_QL_VARIABLES_HEADER] = mappedVariables;

return {
headers: newHeaders
Expand All @@ -42,5 +48,7 @@ export class DatadogLink extends ApolloLink {

return forward(operation);
});

this.variablesMapper = variablesMapper;
}
}
77 changes: 77 additions & 0 deletions packages/react-native-apollo-client/src/__tests__/mappers.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import { mapVariables } from '../mappers';

describe('mappers', () => {
describe('mapVariables', () => {
it('executes the provided mapper on the variables as JSON', () => {
const originalVariables = JSON.stringify({
user: {
email: 'user@email.com',
password: 'pass',
type: 'admin'
}
});
const mapper = (variables: Record<string, any> | null) => {
if (variables && variables.user?.email) {
delete variables.user.email;
}
if (variables && variables.user?.password) {
delete variables.user.password;
}
return variables;
};

expect(mapVariables(originalVariables, mapper)).toBe(
'{"user":{"type":"admin"}}'
);
});
it('returns the original variables if they are not well formatted as JSON', () => {
const originalVariables = '{user: [Object object]}';
const mapper = (variables: Record<string, any> | null) => {
if (variables && variables.user?.email) {
delete variables.user.email;
}
if (variables && variables.user?.password) {
delete variables.user.password;
}
return variables;
};

expect(mapVariables(originalVariables, mapper)).toBe(
originalVariables
);
});
it('returns the original variables if the mapper errors', () => {
const originalVariables = JSON.stringify({
user: {
email: 'user@email.com',
password: 'pass',
type: 'admin'
}
});
const mapper = (variables: Record<string, any> | null) => {
if (variables && variables.user?.email) {
delete variables.user.email;
}
if (variables && variables.user?.password) {
delete variables.user.password;
}
throw new Error('mapper error');
};

expect(mapVariables(originalVariables, mapper)).toBe(
originalVariables
);
});
it('returns the original variables if no mapper was provided', () => {
const originalVariables = JSON.stringify({
user: {
email: 'user@email.com',
password: 'pass',
type: 'admin'
}
});

expect(mapVariables(originalVariables)).toBe(originalVariables);
});
});
});
22 changes: 22 additions & 0 deletions packages/react-native-apollo-client/src/mappers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
export type VariablesMapper = (
variables: Record<string, unknown> | null
) => Record<string, unknown> | null;

export const mapVariables = (
originalVariables: string | null,
mapper?: VariablesMapper
): string | null => {
if (!mapper) {
return originalVariables;
}
try {
const mappedVariables = mapper(
originalVariables === null ? null : JSON.parse(originalVariables)
);

return JSON.stringify(mappedVariables);
} catch (e) {
// TODO: telemetry
return originalVariables;
}
};

0 comments on commit f01e058

Please sign in to comment.