Skip to content

Commit

Permalink
Fix scalar input/output object bug when given external file or module…
Browse files Browse the repository at this point in the history
… pattern (#9418)

* Use mapper to ensure path and module cases work in input/output object case

* Add test cases to capture scalars from modules

* Add test case for scalar input/output for file/module cases

* Add changeset

* Update default tests to something more practical

* Remove extraneous changeset since we haven't released feature

* Mapped scalar types are now used as input and output instead of having to be an input/output object
  • Loading branch information
eddeee888 committed May 23, 2023
1 parent ca02ad1 commit 9e8bd9d
Show file tree
Hide file tree
Showing 2 changed files with 130 additions and 29 deletions.
35 changes: 9 additions & 26 deletions packages/plugins/other/visitor-plugin-common/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -325,39 +325,22 @@ export function buildScalars(
outputMapper.type += "['output']";
}

result[name] = {
input: inputMapper,
output: outputMapper,
};
} else if (scalarsMapping && typeof scalarsMapping[name] === 'string') {
const normalizedScalar = normalizeScalarType(scalarsMapping[name]);

const inputMapper = parseMapper(normalizedScalar.input, name);
if (inputMapper.isExternal) {
inputMapper.type += "['input']";
}

const outputMapper = parseMapper(normalizedScalar.output, name);
if (outputMapper.isExternal) {
outputMapper.type += "['output']";
}

result[name] = {
input: inputMapper,
output: outputMapper,
};
} else if (scalarsMapping?.[name]) {
const mappedScalar = scalarsMapping[name];
if (typeof mappedScalar === 'object' && mappedScalar.input && mappedScalar.output) {
if (typeof mappedScalar === 'string') {
const normalizedScalar = normalizeScalarType(scalarsMapping[name]);
result[name] = {
input: {
isExternal: false,
type: mappedScalar.input,
},
output: {
isExternal: false,
type: mappedScalar.output,
},
input: parseMapper(normalizedScalar.input, name),
output: parseMapper(normalizedScalar.output, name),
};
} else if (typeof mappedScalar === 'object' && mappedScalar.input && mappedScalar.output) {
result[name] = {
input: parseMapper(mappedScalar.input, name),
output: parseMapper(mappedScalar.output, name),
};
} else {
result[name] = {
Expand Down
124 changes: 121 additions & 3 deletions packages/plugins/typescript/typescript/tests/typescript.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1961,13 +1961,19 @@ describe('TypeScript', () => {
scalar MyScalar
scalar MyOtherScalar
scalar MyAliasedScalar
scalar OrgScalar
scalar OrgOtherScalar
scalar OrgAliasedScalar
type MyType {
foo: String
bar: MyScalar!
baz: MyOtherScalar!
qux: MyAliasedScalar!
tux(in: MyScalar!): MyScalar!
ay: OrgScalar!
bee: OrgOtherScalar!
ce: OrgAliasedScalar!
}
`);
const result = (await plugin(
Expand All @@ -1978,6 +1984,9 @@ describe('TypeScript', () => {
MyScalar: '../../scalars#default',
MyOtherScalar: '../../scalars#MyOtherScalar',
MyAliasedScalar: '../../scalars#MyAliasedScalar as AliasedScalar',
OrgScalar: '@org/scalars#default',
OrgOtherScalar: '@org/scalars#OrgOtherScalar',
OrgAliasedScalar: '@org/scalars#OrgOtherScalar as OrgAliasedScalar',
},
},
{ outputFile: '' }
Expand All @@ -1987,16 +1996,122 @@ describe('TypeScript', () => {
expect(result.prepend).toContain(`import MyScalar from '../../scalars';`);
expect(result.prepend).toContain(`import { MyOtherScalar } from '../../scalars';`);
expect(result.prepend).toContain(`import { MyAliasedScalar as AliasedScalar } from '../../scalars';`);
expect(result.prepend).toContain(`import OrgScalar from '@org/scalars';`);
expect(result.prepend).toContain(`import { OrgOtherScalar } from '@org/scalars';`);
expect(result.prepend).toContain(`import { OrgOtherScalar as OrgAliasedScalar } from '@org/scalars';`);
expect(result.content).toBeSimilarStringTo(`
export type Scalars = {
ID: { input: string | number; output: string; }
String: { input: string; output: string; }
Boolean: { input: boolean; output: boolean; }
Int: { input: number; output: number; }
Float: { input: number; output: number; }
MyScalar: { input: MyScalar['input']; output: MyScalar['output']; }
MyOtherScalar: { input: MyOtherScalar['input']; output: MyOtherScalar['output']; }
MyAliasedScalar: { input: AliasedScalar['input']; output: AliasedScalar['output']; }
MyScalar: { input: MyScalar; output: MyScalar; }
MyOtherScalar: { input: MyOtherScalar; output: MyOtherScalar; }
MyAliasedScalar: { input: AliasedScalar; output: AliasedScalar; }
OrgScalar: { input: OrgScalar; output: OrgScalar; }
OrgOtherScalar: { input: OrgOtherScalar; output: OrgOtherScalar; }
OrgAliasedScalar: { input: OrgAliasedScalar; output: OrgAliasedScalar; }
};`);

expect(result.content).toBeSimilarStringTo(`
export type MyType = {
__typename?: 'MyType';
foo?: Maybe<Scalars['String']['output']>;
bar: Scalars['MyScalar']['output'];
baz: Scalars['MyOtherScalar']['output'];
qux: Scalars['MyAliasedScalar']['output'];
tux: Scalars['MyScalar']['output'];
ay: Scalars['OrgScalar']['output'];
bee: Scalars['OrgOtherScalar']['output'];
ce: Scalars['OrgAliasedScalar']['output'];
};`);
expect(result.content).toBeSimilarStringTo(`
export type MyTypeTuxArgs = {
in: Scalars['MyScalar']['input'];
}`);
validateTs(result);
});

it('Should import a type of a mapped scalar for input/output mapping', async () => {
const schema = buildSchema(/* GraphQL */ `
scalar MyScalar
scalar MyOtherScalar
scalar MyAliasedScalar
scalar OrgScalar
scalar OrgOtherScalar
scalar OrgAliasedScalar
type MyType {
foo: String
bar: MyScalar!
baz: MyOtherScalar!
qux: MyAliasedScalar!
tux(in: MyScalar!): MyScalar!
ay: OrgScalar!
bee: OrgOtherScalar!
ce: OrgAliasedScalar!
}
`);
const result = (await plugin(
schema,
[],
{
scalars: {
MyScalar: {
input: '../../scalarsInput#default as MyScalarInput',
output: '../../scalarsOutput#default as MyScalarOutput',
},
MyOtherScalar: {
input: '../../scalars#MyOtherScalarInput',
output: '../../scalars#MyOtherScalarOutput',
},
MyAliasedScalar: {
input: '../../scalars#MyAliasedScalar as AliasedScalarInput',
output: '../../scalars#MyAliasedScalar as AliasedScalarOutput',
},
OrgScalar: {
input: '@org/scalars-input#default as OrgScalarInput',
output: '@org/scalars-output#default as OrgScalarOutput',
},
OrgOtherScalar: {
input: '@org/scalars#OrgOtherScalarInput',
output: '@org/scalars#OrgOtherScalarOutput',
},
OrgAliasedScalar: {
input: '@org/scalars#OrgOtherScalar as OrgAliasedScalarInput',
output: '@org/scalars#OrgOtherScalar as OrgAliasedScalarOutput',
},
},
},
{ outputFile: '' }
)) as Types.ComplexPluginOutput;

expect(result.prepend).toContain(`import MyScalarInput from '../../scalarsInput';`);
expect(result.prepend).toContain(`import MyScalarOutput from '../../scalarsOutput';`);
expect(result.prepend).toContain(`import { MyOtherScalarInput } from '../../scalars';`);
expect(result.prepend).toContain(`import { MyOtherScalarOutput } from '../../scalars';`);
expect(result.prepend).toContain(`import { MyAliasedScalar as AliasedScalarInput } from '../../scalars';`);
expect(result.prepend).toContain(`import { MyAliasedScalar as AliasedScalarOutput } from '../../scalars';`);
expect(result.prepend).toContain(`import OrgScalarInput from '@org/scalars-input';`);
expect(result.prepend).toContain(`import OrgScalarOutput from '@org/scalars-output';`);
expect(result.prepend).toContain(`import { OrgOtherScalarInput } from '@org/scalars';`);
expect(result.prepend).toContain(`import { OrgOtherScalarOutput } from '@org/scalars';`);
expect(result.prepend).toContain(`import { OrgOtherScalar as OrgAliasedScalarInput } from '@org/scalars';`);
expect(result.prepend).toContain(`import { OrgOtherScalar as OrgAliasedScalarOutput } from '@org/scalars';`);
expect(result.content).toBeSimilarStringTo(`
export type Scalars = {
ID: { input: string | number; output: string; }
String: { input: string; output: string; }
Boolean: { input: boolean; output: boolean; }
Int: { input: number; output: number; }
Float: { input: number; output: number; }
MyScalar: { input: MyScalarInput; output: MyScalarOutput; }
MyOtherScalar: { input: MyOtherScalarInput; output: MyOtherScalarOutput; }
MyAliasedScalar: { input: AliasedScalarInput; output: AliasedScalarOutput; }
OrgScalar: { input: OrgScalarInput; output: OrgScalarOutput; }
OrgOtherScalar: { input: OrgOtherScalarInput; output: OrgOtherScalarOutput; }
OrgAliasedScalar: { input: OrgAliasedScalarInput; output: OrgAliasedScalarOutput; }
};`);

expect(result.content).toBeSimilarStringTo(`
Expand All @@ -2007,6 +2122,9 @@ describe('TypeScript', () => {
baz: Scalars['MyOtherScalar']['output'];
qux: Scalars['MyAliasedScalar']['output'];
tux: Scalars['MyScalar']['output'];
ay: Scalars['OrgScalar']['output'];
bee: Scalars['OrgOtherScalar']['output'];
ce: Scalars['OrgAliasedScalar']['output'];
};`);
expect(result.content).toBeSimilarStringTo(`
export type MyTypeTuxArgs = {
Expand Down

0 comments on commit 9e8bd9d

Please sign in to comment.