Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixes #30, Fixes #34, Fixes #36, #35

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Changes from 2 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
226 changes: 145 additions & 81 deletions src/buildVariables.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ import { computeFieldsToAddRemoveUpdate } from './utils/computeAddRemoveUpdate';
import {
PRISMA_CONNECT,
PRISMA_DISCONNECT,
PRISMA_UPDATE
PRISMA_UPDATE,
PRISMA_CREATE
} from './constants/mutations';
import {
IntrospectionInputObjectType,
Expand Down Expand Up @@ -143,6 +144,35 @@ const inputFieldExistsForType = (
return !!findInputFieldForType(introspectionResults, typeName, field);
};

const findMutationInputType = (
introspectionResults: IntrospectionResult,
typeName: string,
field: string,
mutationType: string
) => {
const inputType = findInputFieldForType(
introspectionResults,
typeName,
field
);
return findInputFieldForType(
introspectionResults,
inputType!.name,
mutationType
);
};

const hasMutationInputType = (
introspectionResults: IntrospectionResult,
typeName: string,
field: string,
mutationType: string
) => {
return Boolean(
findMutationInputType(introspectionResults, typeName, field, mutationType)
);
};

const buildReferenceField = ({
inputArg,
introspectionResults,
Expand All @@ -156,14 +186,10 @@ const buildReferenceField = ({
field: string;
mutationType: string;
}) => {
const inputType = findInputFieldForType(
const mutationInputType = findMutationInputType(
introspectionResults,
typeName,
field
);
const mutationInputType = findInputFieldForType(
introspectionResults,
inputType!.name,
field,
mutationType
);

Expand All @@ -178,6 +204,45 @@ const buildReferenceField = ({
}, {});
};

const buildObjectMutationData = ({
inputArg,
introspectionResults,
typeName,
key
}: {
inputArg: { [key: string]: any };
introspectionResults: IntrospectionResult;
typeName: string;
key: string;
}) => {
const hasConnect = hasMutationInputType(
introspectionResults,
typeName,
key,
PRISMA_CONNECT
);

const mutationType = hasConnect ? PRISMA_CONNECT : PRISMA_CREATE;

const fields = buildReferenceField({
inputArg,
introspectionResults,
typeName,
field: key,
mutationType
});

// If no fields in the object are valid, continue
if (Object.keys(fields).length === 0) {
return {};
}

// Else, connect the nodes
return {
[key]: { [mutationType]: { ...fields } }
};
};

interface UpdateParams {
id: string;
data: { [key: string]: any };
Expand All @@ -191,17 +256,26 @@ const buildUpdateVariables = (introspectionResults: IntrospectionResult) => (
) => {
return Object.keys(params.data).reduce(
(acc, key) => {
if (Array.isArray(params.data[key])) {
const inputType = findInputFieldForType(
introspectionResults,
`${resource.type.name}UpdateInput`,
key
);
// Put id field in a where object
if (key === 'id' && params.data[key]) {
return {
...acc,
where: {
id: params.data[key]
}
};
}
const inputType = findInputFieldForType(
introspectionResults,
`${resource.type.name}UpdateInput`,
key
);

if (!inputType) {
return acc;
}
if (!inputType) {
return acc;
}
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i am not sure if there are some cases where we should add the property despite there is no input type.

when key is id is one exception, that's why i moved it on top of the function. But maybe there are other cases?


if (Array.isArray(params.data[key])) {
//TODO: Make connect, disconnect and update overridable
//TODO: Make updates working
const {
Expand All @@ -226,37 +300,23 @@ const buildUpdateVariables = (introspectionResults: IntrospectionResult) => (
}

if (isObject(params.data[key])) {
const fieldsToUpdate = buildReferenceField({
inputArg: params.data[key],
introspectionResults,
typeName: `${resource.type.name}UpdateInput`,
field: key,
mutationType: PRISMA_CONNECT
});
if (inputType.kind !== 'SCALAR') {
const typeName = `${resource.type.name}UpdateInput`;

// If no fields in the object are valid, continue
if (Object.keys(fieldsToUpdate).length === 0) {
return acc;
const data = buildObjectMutationData({
inputArg: params.data[key],
introspectionResults,
typeName,
key
});
return {
...acc,
data: {
...acc.data,
...data
}
};
}

// Else, connect the nodes
return {
...acc,
data: {
...acc.data,
[key]: { [PRISMA_CONNECT]: { ...fieldsToUpdate } }
}
};
}

// Put id field in a where object
if (key === 'id' && params.data[key]) {
return {
...acc,
where: {
id: params.data[key]
}
};
}

const type = introspectionResults.types.find(
Expand Down Expand Up @@ -291,17 +351,26 @@ const buildCreateVariables = (introspectionResults: IntrospectionResult) => (
) =>
Object.keys(params.data).reduce(
(acc, key) => {
if (Array.isArray(params.data[key])) {
if (
!inputFieldExistsForType(
introspectionResults,
`${resource.type.name}CreateInput`,
key
)
) {
return acc;
}
// Put id field in a where object
if (key === 'id' && params.data[key]) {
return {
...acc,
where: {
id: params.data[key]
}
};
}

const inputType = findInputFieldForType(
introspectionResults,
`${resource.type.name}UpdateInput`,
key
);

if (!inputType) {
return acc;
}
if (Array.isArray(params.data[key])) {
return {
...acc,
data: {
Expand All @@ -316,37 +385,32 @@ const buildCreateVariables = (introspectionResults: IntrospectionResult) => (
}

if (isObject(params.data[key])) {
const fieldsToConnect = buildReferenceField({
inputArg: params.data[key],
const inputType = findInputFieldForType(
introspectionResults,
typeName: `${resource.type.name}CreateInput`,
field: key,
mutationType: PRISMA_CONNECT
});
`${resource.type.name}UpdateInput`,
key
);

// If no fields in the object are valid, continue
if (Object.keys(fieldsToConnect).length === 0) {
if (!inputType) {
return acc;
}

// Else, connect the nodes
return {
...acc,
data: {
...acc.data,
[key]: { [PRISMA_CONNECT]: { ...fieldsToConnect } }
}
};
}

// Put id field in a where object
if (key === 'id' && params.data[key]) {
return {
...acc,
where: {
id: params.data[key]
}
};
if (inputType.kind !== 'SCALAR') {
const typeName = `${resource.type.name}CreateInput`;
const data = buildObjectMutationData({
inputArg: params.data[key],
introspectionResults,
typeName,
key
});
return {
...acc,
data: {
...acc.data,
...data
}
};
}
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this part is mostly duplicated from buildUpdateVariables, we should generalize that later

}

const type = introspectionResults.types.find(
Expand Down