mirror of
https://github.com/hasura/graphql-engine.git
synced 2024-10-05 06:18:04 +03:00
feature (console): add GQL util function to generate insert mutations + tests
PR-URL: https://github.com/hasura/graphql-engine-mono/pull/7512 GitOrigin-RevId: 3e89bcd114a42c9e2fa97f1a05d5c871329c8dd9
This commit is contained in:
parent
1280ca8533
commit
0bc363de6e
@ -0,0 +1,120 @@
|
||||
import { formatSdl } from 'format-graphql';
|
||||
import { generateGraphQLInsertMutation } from './generateGraphQLInsertMutation';
|
||||
|
||||
describe('generateGraphQLInsertMutation for table with', () => {
|
||||
it('no table customization + no source customization', () => {
|
||||
const result = generateGraphQLInsertMutation({
|
||||
defaultQueryRoot: 'Album',
|
||||
objects: [
|
||||
{ AlbumId: 1, ArtistId: 1, Title: 'foo' },
|
||||
{ AlbumId: 2, ArtistId: 2, Title: 'bar' },
|
||||
],
|
||||
mutationName: 'insertAlbumRows',
|
||||
});
|
||||
const expectedGqlQuery = `
|
||||
mutation insertAlbumRows {
|
||||
insert_Album(objects: [{AlbumId: 1, ArtistId: 1, Title: "foo"},{AlbumId: 2, ArtistId: 2, Title: "bar"}]) {
|
||||
affected_rows
|
||||
}
|
||||
}
|
||||
`;
|
||||
expect(result.query).toMatch(formatSdl(expectedGqlQuery));
|
||||
});
|
||||
|
||||
it('with table customization (only custom name) + no source customization', () => {
|
||||
const result = generateGraphQLInsertMutation({
|
||||
defaultQueryRoot: 'Album',
|
||||
objects: [
|
||||
{ AlbumId: 1, ArtistId: 1, Title: 'foo' },
|
||||
{ AlbumId: 2, ArtistId: 2, Title: 'bar' },
|
||||
],
|
||||
mutationName: 'insertAlbumRows',
|
||||
tableCustomization: {
|
||||
custom_name: 'CustomTableName',
|
||||
},
|
||||
});
|
||||
const expectedGqlQuery = `
|
||||
mutation insertAlbumRows {
|
||||
insert_CustomTableName(objects: [{AlbumId: 1, ArtistId: 1, Title: "foo"},{AlbumId: 2, ArtistId: 2, Title: "bar"}]) {
|
||||
affected_rows
|
||||
}
|
||||
}
|
||||
`;
|
||||
expect(result.query).toMatch(formatSdl(expectedGqlQuery));
|
||||
});
|
||||
|
||||
it('with table customization (custom insert root) + no source customization', () => {
|
||||
const result = generateGraphQLInsertMutation({
|
||||
defaultQueryRoot: 'Album',
|
||||
objects: [
|
||||
{ AlbumId: 1, ArtistId: 1, Title: 'foo' },
|
||||
{ AlbumId: 2, ArtistId: 2, Title: 'bar' },
|
||||
],
|
||||
mutationName: 'insertAlbumRows',
|
||||
tableCustomization: {
|
||||
custom_root_fields: { insert: 'CustomInsertRoot' },
|
||||
},
|
||||
});
|
||||
const expectedGqlQuery = `
|
||||
mutation insertAlbumRows {
|
||||
CustomInsertRoot(objects: [{AlbumId: 1, ArtistId: 1, Title: "foo"},{AlbumId: 2, ArtistId: 2, Title: "bar"}]) {
|
||||
affected_rows
|
||||
}
|
||||
}
|
||||
`;
|
||||
expect(result.query).toMatch(formatSdl(expectedGqlQuery));
|
||||
});
|
||||
|
||||
it('with table customization (custom name + custom insert root) + no source customization', () => {
|
||||
const result = generateGraphQLInsertMutation({
|
||||
defaultQueryRoot: 'Album',
|
||||
objects: [
|
||||
{ AlbumId: 1, ArtistId: 1, Title: 'foo' },
|
||||
{ AlbumId: 2, ArtistId: 2, Title: 'bar' },
|
||||
],
|
||||
mutationName: 'insertAlbumRows',
|
||||
tableCustomization: {
|
||||
custom_name: 'CustomTableName',
|
||||
custom_root_fields: { insert: 'CustomInsertRoot' },
|
||||
},
|
||||
});
|
||||
const expectedGqlQuery = `
|
||||
mutation insertAlbumRows {
|
||||
CustomInsertRoot(objects: [{AlbumId: 1, ArtistId: 1, Title: "foo"},{AlbumId: 2, ArtistId: 2, Title: "bar"}]) {
|
||||
affected_rows
|
||||
}
|
||||
}
|
||||
`;
|
||||
expect(result.query).toMatch(formatSdl(expectedGqlQuery));
|
||||
});
|
||||
|
||||
it('with table customization (custom name + custom insert root) + source customization', () => {
|
||||
const result = generateGraphQLInsertMutation({
|
||||
defaultQueryRoot: 'Album',
|
||||
objects: [
|
||||
{ AlbumId: 1, ArtistId: 1, Title: 'foo' },
|
||||
{ AlbumId: 2, ArtistId: 2, Title: 'bar' },
|
||||
],
|
||||
mutationName: 'insertAlbumRows',
|
||||
tableCustomization: {
|
||||
custom_name: 'CustomTableName',
|
||||
custom_root_fields: { insert: 'CustomInsertRoot' },
|
||||
},
|
||||
sourceCustomization: {
|
||||
root_fields: {
|
||||
namespace: 'MySourceNamespace',
|
||||
},
|
||||
},
|
||||
});
|
||||
const expectedGqlQuery = `
|
||||
mutation insertAlbumRows {
|
||||
MySourceNamespace {
|
||||
CustomInsertRoot(objects: [{AlbumId: 1, ArtistId: 1, Title: "foo"},{AlbumId: 2, ArtistId: 2, Title: "bar"}]) {
|
||||
affected_rows
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
expect(result.query).toMatch(formatSdl(expectedGqlQuery));
|
||||
});
|
||||
});
|
@ -1,18 +1,19 @@
|
||||
import { MetadataTable, Source } from '@/features/hasura-metadata-types';
|
||||
import { formatSdl } from 'format-graphql';
|
||||
import { getMutationRoot } from './getMutationRoot';
|
||||
|
||||
export const generateGraphQLMutation = async ({
|
||||
export const generateGraphQLInsertMutation = ({
|
||||
defaultQueryRoot,
|
||||
tableCustomization,
|
||||
sourceCustomization,
|
||||
objects,
|
||||
operationName,
|
||||
mutationName,
|
||||
}: {
|
||||
operationName?: string;
|
||||
mutationName: string;
|
||||
defaultQueryRoot: string;
|
||||
tableCustomization: MetadataTable['configuration'];
|
||||
sourceCustomization: Source['customization'];
|
||||
objects: Record<string, string | number | boolean>;
|
||||
tableCustomization?: MetadataTable['configuration'];
|
||||
sourceCustomization?: Source['customization'];
|
||||
objects: Record<string, string | number | boolean>[];
|
||||
}) => {
|
||||
const queryRoot = getMutationRoot({
|
||||
defaultQueryRoot,
|
||||
@ -29,34 +30,38 @@ export const generateGraphQLMutation = async ({
|
||||
sourceCustomization,
|
||||
});
|
||||
|
||||
const objectToInsert = Object.entries(objects).reduce<string>((acc, x) => {
|
||||
const [column, value] = x;
|
||||
return `${column}: ${typeof value === 'string' ? `"${value}"` : value}`;
|
||||
}, '');
|
||||
const objectToInsert = objects
|
||||
.map(object => {
|
||||
return `{${Object.entries(object)
|
||||
.map(
|
||||
([column, value]) =>
|
||||
`${column}: ${typeof value === 'string' ? `"${value}"` : value}`
|
||||
)
|
||||
.join()}}`;
|
||||
})
|
||||
.join();
|
||||
|
||||
/**
|
||||
* If the source has a GQL namespace set for it, then we query for our `queryRoot` under that namespace
|
||||
*/
|
||||
if (sourceCustomization?.root_fields?.namespace)
|
||||
return {
|
||||
query: `mutation ${operationName ?? 'MyMutation'} {
|
||||
${
|
||||
sourceCustomization.root_fields.namespace
|
||||
} (objects: { ${objectToInsert} }) {
|
||||
${queryRoot} {
|
||||
query: formatSdl(`mutation ${mutationName} {
|
||||
${sourceCustomization.root_fields.namespace} {
|
||||
${queryRoot} (objects: [ ${objectToInsert} ]){
|
||||
affected_rows
|
||||
}
|
||||
}
|
||||
}`,
|
||||
}`),
|
||||
resultPath: `${sourceCustomization.root_fields?.namespace}.${queryRoot}`,
|
||||
};
|
||||
|
||||
return {
|
||||
query: `query ${operationName ?? 'MyQuery'} {
|
||||
${queryRoot} (objects: { ${objectToInsert} }) {
|
||||
query: formatSdl(`mutation ${mutationName} {
|
||||
${queryRoot} (objects: [ ${objectToInsert} ]) {
|
||||
affected_rows
|
||||
}
|
||||
}`,
|
||||
}`),
|
||||
resultPath: queryRoot,
|
||||
};
|
||||
};
|
||||
|
@ -5,6 +5,7 @@ export type AllowedMutationOperation =
|
||||
| 'insert_one'
|
||||
| 'update'
|
||||
| 'update_by_pk'
|
||||
| 'update_many'
|
||||
| 'delete'
|
||||
| 'delete_by_pk';
|
||||
|
||||
@ -52,6 +53,8 @@ export const getMutationRoot = ({
|
||||
if (operation === 'update') baseQueryRoot = `update_${baseQueryRoot}`;
|
||||
if (operation === 'update_by_pk')
|
||||
baseQueryRoot = `update_${baseQueryRoot}_by_pk`;
|
||||
if (operation === 'update_many')
|
||||
baseQueryRoot = `update_${baseQueryRoot}_many`;
|
||||
|
||||
if (operation === 'delete_by_pk')
|
||||
baseQueryRoot = `delete_${baseQueryRoot}_by_pk`;
|
||||
|
Loading…
Reference in New Issue
Block a user