Skip to content

Commit

Permalink
feat(graphql): cleaning up a few functions and handling more graphql …
Browse files Browse the repository at this point in the history
…scenarios
  • Loading branch information
lpsmit committed Aug 15, 2024
1 parent 31bfe2a commit c3be8c7
Show file tree
Hide file tree
Showing 7 changed files with 83 additions and 83 deletions.
7 changes: 0 additions & 7 deletions packages/fetchye-core/__tests__/defaultFetcher.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@ describe('defaultFetcher', () => {
'Content-Type': 'application/json',
}),
}));
// write a mock for jsonToGraphQLQuery
jsonToGraphQLQuery.mockImplementationOnce(() => 'jsonToGraphQLQueryMock');
trimQueryBody.mockImplementationOnce(() => 'trimQueryBodyMock');
const data = await defaultFetcher(fetchClient, 'http://example.com', {
Expand Down Expand Up @@ -75,7 +74,6 @@ describe('defaultFetcher', () => {
'Content-Type': 'application/json',
}),
}));
// write a mock for jsonToGraphQLQuery
jsonToGraphQLQuery.mockImplementationOnce(() => 'jsonToGraphQLQueryMock');
trimQueryBody.mockImplementationOnce(() => 'trimQueryBodyMock');
const data = await defaultFetcher(fetchClient, 'http://example.com', {
Expand All @@ -97,7 +95,6 @@ describe('defaultFetcher', () => {
},
}
`);
expect(jsonToGraphQLQuery).toHaveBeenCalledWith(undefined, { pretty: true });
});
it('should handle graphql query with existing query', async () => {
const fetchClient = jest.fn(async () => ({
Expand All @@ -108,7 +105,6 @@ describe('defaultFetcher', () => {
'Content-Type': 'application/json',
}),
}));
// write a mock for jsonToGraphQLQuery
jsonToGraphQLQuery.mockImplementationOnce(() => 'jsonToGraphQLQueryMock');
trimQueryBody.mockImplementationOnce(() => 'trimQueryBodyMock');
const data = await defaultFetcher(fetchClient, 'http://example.com', {
Expand Down Expand Up @@ -146,7 +142,6 @@ describe('defaultFetcher', () => {
'Content-Type': 'application/json',
}),
}));
// write a mock for jsonToGraphQLQuery
jsonToGraphQLQuery.mockImplementationOnce(() => 'jsonToGraphQLQueryMock');
trimQueryBody.mockImplementationOnce(() => 'trimQueryBodyMock');
const data = await defaultFetcher(fetchClient, 'http://example.com', {
Expand All @@ -169,8 +164,6 @@ describe('defaultFetcher', () => {
},
}
`);
expect(jsonToGraphQLQuery).toHaveBeenCalledWith('trimQueryBodyMock', { pretty: true });
expect(trimQueryBody).toHaveBeenCalledWith(undefined, 'existingQueryMock');
});

it('should return payload and undefined error when status 200', async () => {
Expand Down
38 changes: 38 additions & 0 deletions packages/fetchye-core/__tests__/trimOptions.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { jsonToGraphQLQuery } from 'json-to-graphql-query';
import { trimOptions } from '../src/trimOptions';
import { trimQueryBody } from '../src/trimQueryBody';

jest.mock('json-to-graphql-query', () => ({
jsonToGraphQLQuery: jest.fn(),
}));
jest.mock('../src/trimQueryBody', () => ({
trimQueryBody: jest.fn(),
}));

describe('trimOptions', () => {
it('should return options if isGraphQL is false', () => {
const options = { isGraphQL: false };
expect(trimOptions(options)).toEqual(options);
});
it('should return options if isGraphQL is true and existingQuery is not provided', () => {
const options = { isGraphQL: true, body: { query: 'query' } };
jsonToGraphQLQuery.mockImplementation((value) => value);
const expectedBody = JSON.stringify({
query: 'query',
});
expect(trimOptions(options)).toEqual({ ...options, body: expectedBody });
});
it('should return options with trimmed query if isGraphQL is true and existingQuery is provided', () => {
const options = { isGraphQL: true, existingQuery: 'existingQuery', body: { query: 'query' } };
const trimmedQuery = 'trimmedQuery';
trimQueryBody.mockReturnValue(trimmedQuery);
jsonToGraphQLQuery.mockImplementation((value) => value);
const expectedBody = JSON.stringify({
query: 'trimmedQuery',
});
expect(trimOptions(options)).toEqual({ ...options, body: expectedBody });
});
it('should handle if options is not provided', () => {
expect(trimOptions()).toEqual(undefined);
});
});
23 changes: 1 addition & 22 deletions packages/fetchye-core/__tests__/trimQueryBody.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,28 +7,6 @@ describe('trimQueryBody', () => {
beforeEach(() => {
jest.resetAllMocks();
});
it('should return empty object if __args are different', () => {
deepEqual.mockImplementationOnce(() => false);
const newQuery = {
__args: { a: 1 },
};
const existingQuery = {
__args: { a: 2 },
};
const result = trimQueryBody(newQuery, existingQuery);
expect(result).toEqual({});
});
it('should return empty object if __name are different', () => {
deepEqual.mockImplementationOnce(() => false);
const newQuery = {
__name: 'a',
};
const existingQuery = {
__name: 'b',
};
const result = trimQueryBody(newQuery, existingQuery);
expect(result).toEqual({});
});
it('should return empty object if key is not in existingQuery', () => {
deepEqual.mockImplementationOnce(() => true);
const newQuery = {
Expand Down Expand Up @@ -180,6 +158,7 @@ describe('trimQueryBody', () => {
const newQuery = {
a: {
b: {
c: 1,
},
},
};
Expand Down
44 changes: 4 additions & 40 deletions packages/fetchye-core/src/defaultFetcher.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,7 @@
* permissions and limitations under the License.
*/

import { jsonToGraphQLQuery } from 'json-to-graphql-query';
import { trimQueryBody } from './trimQueryBody';
import { trimOptions } from './trimOptions';

// Object.fromEntries is not compatible with Node v10
// provide our own lightweight solution
Expand All @@ -24,48 +23,13 @@ export const headersToObject = (headers = []) => [...headers]
acc[key] = value;
return acc;
}, {});
export const defaultFetcher = async (fetchClient, key, options) => {
let trimmedOptions;
export const defaultFetcher = async (fetchClient, key, initialOptions) => {
let res;
let payload;
let error;
const { existingQuery, isGraphQL } = options || {};

if (existingQuery && isGraphQL) {
const {
body,
...restOfOptions
} = options;
const {
query,
...restOfBody
} = body || {};
trimmedOptions = {
...restOfOptions,
body: JSON.stringify({
query: jsonToGraphQLQuery(trimQueryBody(query, existingQuery), { pretty: true }),
...restOfBody,
}),
};
} else if (isGraphQL) {
const {
body,
...restOfOptions
} = options;
const {
query,
...restOfBody
} = body || {};
trimmedOptions = {
...restOfOptions,
body: JSON.stringify({
query: jsonToGraphQLQuery(query, { pretty: true }),
...restOfBody,
}),
};
}
const options = trimOptions(initialOptions);
try {
res = await fetchClient(key, trimmedOptions || options);
res = await fetchClient(key, options);
let body = await res.text();
try {
body = JSON.parse(body);
Expand Down
34 changes: 34 additions & 0 deletions packages/fetchye-core/src/trimOptions.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { jsonToGraphQLQuery } from 'json-to-graphql-query';
import { trimQueryBody } from './trimQueryBody';

export const trimOptions = (options) => {
const { existingQuery, isGraphQL } = options || {};
const {
body: requestBody,
...restOfOptions
} = options || {};
const {
query,
...restOfBody
} = requestBody || {};

if (isGraphQL && query && existingQuery) {
return {
...restOfOptions,
body: JSON.stringify({
query: jsonToGraphQLQuery(trimQueryBody(query, existingQuery), { pretty: true }),
...restOfBody,
}),
};
}
if (isGraphQL && query) {
return {
...restOfOptions,
body: JSON.stringify({
query: jsonToGraphQLQuery(query, { pretty: true }),
...restOfBody,
}),
};
}
return options;
};
16 changes: 3 additions & 13 deletions packages/fetchye-core/src/trimQueryBody.js
Original file line number Diff line number Diff line change
@@ -1,23 +1,13 @@
import deepEqual from 'deep-equal';
const graphQLTerms = ['__args', '__name', '__aliasFor', '__variables', '__directives', '__all_on', '__on', '__typeName', 'mutation'];

export const trimQueryBody = (newQuery, existingQuery) => {
const trimmedQuery = {};
// eslint-disable-next-line dot-notation -- __args and __name are special keys
if (newQuery['__args'] && existingQuery['__args'] && !deepEqual(newQuery['__args'], existingQuery['__args'])) {
return trimmedQuery;
}
// eslint-disable-next-line dot-notation -- __args and __name are special keys
if (newQuery['__name'] && existingQuery['__name'] && !deepEqual(newQuery['__name'], existingQuery['__name'])) {
return trimmedQuery;
}
Object.keys(newQuery).forEach((key) => {
if (newQuery[key] && !existingQuery[key]) {
trimmedQuery[key] = newQuery[key];
}
if (key === '__args' || key === '__name') {
} else if (graphQLTerms.indexOf(key) > -1) {
trimmedQuery[key] = newQuery[key];
}
if (typeof newQuery[key] === 'object' && !Array.isArray(newQuery[key]) && newQuery[key] !== null) {
} else if (typeof newQuery[key] === 'object' && !Array.isArray(newQuery[key]) && newQuery[key] !== null) {
const cutQueryObject = trimQueryBody(newQuery[key], existingQuery[key]);
const {
__args, __name, ...rest
Expand Down
4 changes: 3 additions & 1 deletion packages/fetchye/src/getGraphQLArgs.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
const graphQLTerms = ['__args', '__name', '__aliasFor', '__variables', '__directives', '__all_on', '__on', '__typeName', 'mutation'];

export const getGraphQLArgs = (query, args = []) => {
let argsList = [...args];
Object.keys(query).forEach((key) => {
if (key === '__args' || key === '__name') {
if (graphQLTerms.indexOf(key) > -1) {
argsList.push({ [key]: query[key] });
}
if (typeof query[key] === 'object' && !Array.isArray(query[key]) && query[key] !== null) {
Expand Down

0 comments on commit c3be8c7

Please sign in to comment.