Skip to content

Commit

Permalink
fix: No atomic operations for scalar input list
Browse files Browse the repository at this point in the history
  • Loading branch information
unlight committed May 22, 2022
1 parent f692ebd commit d32b03c
Show file tree
Hide file tree
Showing 13 changed files with 125 additions and 30 deletions.
2 changes: 1 addition & 1 deletion @generated/dummy/dummy-create-many.input.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { Int } from '@nestjs/graphql';
import { Decimal } from '@prisma/client/runtime';
import { GraphQLDecimal } from 'prisma-graphql-type-decimal';
import { GraphQLJSON } from 'graphql-type-json';
import { DummyCreatefriendsInput } from '../prisma/dummy-createfriends.input';
import { DummyCreatefriendsInput } from './dummy-createfriends.input';

@InputType()
export class DummyCreateManyInput {
Expand Down
2 changes: 1 addition & 1 deletion @generated/dummy/dummy-create.input.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { Int } from '@nestjs/graphql';
import { Decimal } from '@prisma/client/runtime';
import { GraphQLDecimal } from 'prisma-graphql-type-decimal';
import { GraphQLJSON } from 'graphql-type-json';
import { DummyCreatefriendsInput } from '../prisma/dummy-createfriends.input';
import { DummyCreatefriendsInput } from './dummy-createfriends.input';

@InputType()
export class DummyCreateInput {
Expand Down
2 changes: 1 addition & 1 deletion @generated/dummy/dummy-unchecked-create.input.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { Int } from '@nestjs/graphql';
import { Decimal } from '@prisma/client/runtime';
import { GraphQLDecimal } from 'prisma-graphql-type-decimal';
import { GraphQLJSON } from 'graphql-type-json';
import { DummyCreatefriendsInput } from '../prisma/dummy-createfriends.input';
import { DummyCreatefriendsInput } from './dummy-createfriends.input';

@InputType()
export class DummyUncheckedCreateInput {
Expand Down
2 changes: 1 addition & 1 deletion @generated/dummy/dummy-unchecked-update-many.input.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { NullableBytesFieldUpdateOperationsInput } from '../prisma/nullable-byte
import { NullableDecimalFieldUpdateOperationsInput } from '../prisma/nullable-decimal-field-update-operations.input';
import { NullableBigIntFieldUpdateOperationsInput } from '../prisma/nullable-big-int-field-update-operations.input';
import { GraphQLJSON } from 'graphql-type-json';
import { DummyUpdatefriendsInput } from '../prisma/dummy-updatefriends.input';
import { DummyUpdatefriendsInput } from './dummy-updatefriends.input';

@InputType()
export class DummyUncheckedUpdateManyInput {
Expand Down
2 changes: 1 addition & 1 deletion @generated/dummy/dummy-unchecked-update.input.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { NullableBytesFieldUpdateOperationsInput } from '../prisma/nullable-byte
import { NullableDecimalFieldUpdateOperationsInput } from '../prisma/nullable-decimal-field-update-operations.input';
import { NullableBigIntFieldUpdateOperationsInput } from '../prisma/nullable-big-int-field-update-operations.input';
import { GraphQLJSON } from 'graphql-type-json';
import { DummyUpdatefriendsInput } from '../prisma/dummy-updatefriends.input';
import { DummyUpdatefriendsInput } from './dummy-updatefriends.input';

@InputType()
export class DummyUncheckedUpdateInput {
Expand Down
2 changes: 1 addition & 1 deletion @generated/dummy/dummy-update-many-mutation.input.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { NullableBytesFieldUpdateOperationsInput } from '../prisma/nullable-byte
import { NullableDecimalFieldUpdateOperationsInput } from '../prisma/nullable-decimal-field-update-operations.input';
import { NullableBigIntFieldUpdateOperationsInput } from '../prisma/nullable-big-int-field-update-operations.input';
import { GraphQLJSON } from 'graphql-type-json';
import { DummyUpdatefriendsInput } from '../prisma/dummy-updatefriends.input';
import { DummyUpdatefriendsInput } from './dummy-updatefriends.input';

@InputType()
export class DummyUpdateManyMutationInput {
Expand Down
2 changes: 1 addition & 1 deletion @generated/dummy/dummy-update.input.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { NullableBytesFieldUpdateOperationsInput } from '../prisma/nullable-byte
import { NullableDecimalFieldUpdateOperationsInput } from '../prisma/nullable-decimal-field-update-operations.input';
import { NullableBigIntFieldUpdateOperationsInput } from '../prisma/nullable-big-int-field-update-operations.input';
import { GraphQLJSON } from 'graphql-type-json';
import { DummyUpdatefriendsInput } from '../prisma/dummy-updatefriends.input';
import { DummyUpdatefriendsInput } from './dummy-updatefriends.input';

@InputType()
export class DummyUpdateInput {
Expand Down
18 changes: 14 additions & 4 deletions src/handlers/no-atomic-operations.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import AwaitEventEmitter from 'await-event-emitter';

import { isListInput } from '../helpers/is-list-input';
import { EventArguments, InputType } from '../types';

export function noAtomicOperations(eventEmitter: AwaitEventEmitter) {
Expand All @@ -8,11 +9,16 @@ export function noAtomicOperations(eventEmitter: AwaitEventEmitter) {
}

function beforeInputType(args: EventArguments & { inputType: InputType }) {
const { inputType } = args;
const { inputType, getModelName } = args;

for (const field of inputType.fields) {
field.inputTypes = field.inputTypes.filter(inputType => {
if (isAtomicOperation(String(inputType.type))) {
const inputTypeName = String(inputType.type);
const modelName = getModelName(inputTypeName);
if (
isAtomicOperation(inputTypeName) ||
(modelName && isListInput(inputTypeName, modelName))
) {
return false;
}
return true;
Expand All @@ -25,12 +31,16 @@ function beforeGenerateFiles(args: EventArguments) {

for (const sourceFile of project.getSourceFiles()) {
const className = sourceFile.getClass(() => true)?.getName();

if (className && isAtomicOperation(className)) {
project.removeSourceFile(sourceFile);
}
}
}

function isAtomicOperation(name: string) {
return name.endsWith('FieldUpdateOperationsInput');
function isAtomicOperation(typeName: string) {
if (typeName.endsWith('FieldUpdateOperationsInput')) {
return true;
}
return false;
}
11 changes: 11 additions & 0 deletions src/helpers/get-model-name.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { first, memoize } from 'lodash';

import { isListInput } from './is-list-input';

export function createGetModelName(modelNames: string[]) {
return memoize(tryGetName);

Expand Down Expand Up @@ -52,6 +54,15 @@ function getModelName(args: {
return test;
}
}

if (name.slice(-5) === 'Input') {
for (const model of modelNames) {
if (isListInput(name, model)) {
return model;
}
}
}

// eslint-disable-next-line consistent-return, unicorn/no-useless-undefined
return undefined;
}
Expand Down
3 changes: 3 additions & 0 deletions src/helpers/is-list-input.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export function isListInput(typeName: string, model: string) {
return typeName.startsWith(`${model}Create`) || typeName.startsWith(`${model}Update`);
}
109 changes: 90 additions & 19 deletions src/test/generate.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ let sourceFiles: SourceFile[];
let importDeclarations: ImportDeclarationStructure[] = [];

const p = (name: string) => getPropertyStructure(sourceFile, name);
const d = (name: string) => getPropertyStructure(sourceFile, name)?.decorators?.[0];
const f = (name: string) =>
getPropertyStructure(sourceFile, name)?.decorators?.find(d => d.name === 'Field')
?.arguments;
Expand Down Expand Up @@ -1148,7 +1147,12 @@ describe('get rid of atomic number operations', () => {
friends String[]
}
`,
options: [`outputFilePattern = "{name}.{type}.ts"`, `noAtomicOperations = true`],
options: [
`
outputFilePattern = "{name}.{type}.ts"
noAtomicOperations = true
`,
],
}));
});

Expand All @@ -1165,48 +1169,82 @@ describe('get rid of atomic number operations', () => {
});

it('id should be regular string', () => {
expect(getPropertyStructure(sourceFile, 'id')?.type).toEqual('string');
it('rating should be regular string', () => {
const s = testSourceFile({
project,
class: 'UserUpdateInput',
property: 'id',
});
expect(s.property?.type).toEqual('string');
});
});

it('id field type should be string', () => {
expect(t('id')).toEqual('() => String');
const s = testSourceFile({
project,
class: 'UserUpdateInput',
property: 'id',
});
expect(s.fieldDecoratorType).toEqual('() => String');
});

it('age should be regular string', () => {
expect(getPropertyStructure(sourceFile, 'age')?.type).toEqual('number');
it('rating should be regular string', () => {
const s = testSourceFile({
project,
class: 'UserUpdateInput',
property: 'age',
});
expect(s.property?.type).toEqual('number');
});
});

it('age field type should be string', () => {
expect(t('age')).toEqual('() => Int');
const s = testSourceFile({
project,
class: 'UserUpdateInput',
property: 'age',
});
expect(s.fieldDecoratorType).toEqual('() => Int');
});

it('rating should be regular string', () => {
expect(getPropertyStructure(sourceFile, 'rating')?.type).toEqual('number');
const s = testSourceFile({
project,
class: 'UserUpdateInput',
property: 'rating',
});
expect(s.property?.type).toEqual('number');
});

it('rating field type should be string', () => {
expect(t('rating')).toEqual('() => Float');
const s = testSourceFile({
project,
class: 'UserUpdateInput',
property: 'rating',
});
expect(s.fieldDecoratorType).toEqual('() => Float');
});

it('scalar array', () => {
expect(t('friends')).toEqual('() => UserUpdatefriendsInput');
});
});

describe('UserUpdatefriendsInput', () => {
before(() => {
setSourceFile('user-updatefriends.input.ts');
const s = testSourceFile({
project,
class: 'UserUpdateInput',
property: 'friends',
});
expect(s.fieldDecoratorType).toEqual('() => [String]');
});
});

describe('date field files', () => {
const dateFieldFiles = ['user-create.input.ts', 'user-unchecked-update.input.ts'];

for (const file of dateFieldFiles) {
it(`date field files ${file}`, () => {
setSourceFile(file);
expect(p('born')?.type).toEqual('Date | string');
expect(t('born')).toEqual('() => Date');
it(`date field files [${file}]`, () => {
const s = testSourceFile({ project, file, property: 'born' });

expect(s.fieldDecoratorType).toEqual('() => Date');
expect(s.property?.type).toEqual('Date | string');
});
}
});
Expand Down Expand Up @@ -1241,6 +1279,39 @@ describe('noAtomicOperations with emitSingle and combineScalarFilters', () => {
});
});

describe('scalar arrays with noAtomicOperations', () => {
let project: Project;
before(async () => {
({ project } = await testGenerate({
schema: `
model Dummy {
id String @id
ints Int[]
}
`,
options: [
`
noAtomicOperations = true
`,
],
}));
});

describe('ints should be array', () => {
for (const className of ['DummyCreateInput']) {
it(className, () => {
const s = testSourceFile({
project,
class: className,
property: 'ints',
});

expect(s.fieldDecoratorType).toEqual('() => [Int]');
});
}
});
});

describe('combine scalar filters', () => {
before(async () => {
({ project, sourceFiles } = await testGenerate({
Expand Down

0 comments on commit d32b03c

Please sign in to comment.