Skip to content

Commit 58fd694

Browse files
authored
Merge branch 'master' into federation-fixes
2 parents b446e84 + 157c823 commit 58fd694

File tree

11 files changed

+699
-250
lines changed

11 files changed

+699
-250
lines changed

.changeset/tidy-cows-knock.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@graphql-codegen/cli': patch
3+
---
4+
5+
Remove extraneous error stacktrace if fails to load `@parcel/watcher`

packages/graphql-codegen-cli/src/utils/watcher.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,9 +64,9 @@ export const createWatcher = (
6464
let parcelWatcher: typeof import('@parcel/watcher');
6565
try {
6666
parcelWatcher = await import('@parcel/watcher');
67-
} catch (err) {
67+
} catch {
6868
log(
69-
`Failed to import @parcel/watcher due to the following error (to use watch mode, install https://www.npmjs.com/package/@parcel/watcher):\n${err}`
69+
'Failed to import @parcel/watcher.\n To use watch mode, install https://www.npmjs.com/package/@parcel/watcher.'
7070
);
7171
return;
7272
}

packages/plugins/other/visitor-plugin-common/src/base-resolvers-visitor.ts

Lines changed: 46 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1128,54 +1128,58 @@ export class BaseResolversVisitor<
11281128
memberTypes: readonly GraphQLObjectType[] | GraphQLObjectType[];
11291129
isTypenameNonOptional: boolean;
11301130
}): string {
1131-
const result =
1132-
memberTypes
1133-
.map(type => {
1134-
const isTypeMapped = this.config.mappers[type.name];
1135-
// 1. If mapped without placehoder, just use it without doing extra checks
1136-
if (isTypeMapped && !hasPlaceholder(isTypeMapped.type)) {
1137-
return { typename: type.name, typeValue: isTypeMapped.type };
1138-
}
1131+
const members = memberTypes
1132+
.map(type => {
1133+
const isTypeMapped = this.config.mappers[type.name];
1134+
// 1. If mapped without placehoder, just use it without doing extra checks
1135+
if (isTypeMapped && !hasPlaceholder(isTypeMapped.type)) {
1136+
return { typename: type.name, typeValue: isTypeMapped.type };
1137+
}
11391138

1140-
// 2. Work out value for type
1141-
// 2a. By default, use the typescript type
1142-
let typeValue = this.convertName(type.name, {}, true);
1139+
// 2. Work out value for type
1140+
// 2a. By default, use the typescript type
1141+
let typeValue = this.convertName(type.name, {}, true);
11431142

1144-
// 2b. Find fields to Omit if needed.
1145-
// - If no field to Omit, "type with maybe Omit" is typescript type i.e. no Omit
1146-
// - If there are fields to Omit, keep track of these "type with maybe Omit" to replace in original unionMemberValue
1147-
const fieldsToOmit = this.getRelevantFieldsToOmit({
1148-
schemaType: type,
1149-
getTypeToUse: baseType => `_RefType['${baseType}']`,
1150-
});
1151-
if (fieldsToOmit.length > 0) {
1152-
typeValue = this.replaceFieldsInType(typeValue, fieldsToOmit);
1153-
}
1143+
// 2b. Find fields to Omit if needed.
1144+
// - If no field to Omit, "type with maybe Omit" is typescript type i.e. no Omit
1145+
// - If there are fields to Omit, keep track of these "type with maybe Omit" to replace in original unionMemberValue
1146+
const fieldsToOmit = this.getRelevantFieldsToOmit({
1147+
schemaType: type,
1148+
getTypeToUse: baseType => `_RefType['${baseType}']`,
1149+
});
1150+
if (fieldsToOmit.length > 0) {
1151+
typeValue = this.replaceFieldsInType(typeValue, fieldsToOmit);
1152+
}
11541153

1155-
// 2c. If type is mapped with placeholder, use the "type with maybe Omit" as {T}
1156-
if (isTypeMapped && hasPlaceholder(isTypeMapped.type)) {
1157-
return { typename: type.name, typeValue: replacePlaceholder(isTypeMapped.type, typeValue) };
1158-
}
1154+
// 2c. If type is mapped with placeholder, use the "type with maybe Omit" as {T}
1155+
if (isTypeMapped && hasPlaceholder(isTypeMapped.type)) {
1156+
return { typename: type.name, typeValue: replacePlaceholder(isTypeMapped.type, typeValue) };
1157+
}
11591158

1160-
// 2d. If has default mapper with placeholder, use the "type with maybe Omit" as {T}
1161-
const hasDefaultMapper = !!this.config.defaultMapper?.type;
1162-
const isScalar = this.config.scalars[typeName];
1163-
if (hasDefaultMapper && hasPlaceholder(this.config.defaultMapper.type)) {
1164-
const finalTypename = isScalar ? this._getScalar(typeName) : typeValue;
1165-
return {
1166-
typename: type.name,
1167-
typeValue: replacePlaceholder(this.config.defaultMapper.type, finalTypename),
1168-
};
1169-
}
1159+
// 2d. If has default mapper with placeholder, use the "type with maybe Omit" as {T}
1160+
const hasDefaultMapper = !!this.config.defaultMapper?.type;
1161+
const isScalar = this.config.scalars[typeName];
1162+
if (hasDefaultMapper && hasPlaceholder(this.config.defaultMapper.type)) {
1163+
const finalTypename = isScalar ? this._getScalar(typeName) : typeValue;
1164+
return {
1165+
typename: type.name,
1166+
typeValue: replacePlaceholder(this.config.defaultMapper.type, finalTypename),
1167+
};
1168+
}
11701169

1171-
return { typename: type.name, typeValue };
1172-
})
1173-
.map(({ typename, typeValue }) => {
1174-
const nonOptionalTypenameModifier = isTypenameNonOptional ? ` & { __typename: '${typename}' }` : '';
1170+
return { typename: type.name, typeValue };
1171+
})
1172+
.map(({ typename, typeValue }) => {
1173+
const nonOptionalTypenameModifier = isTypenameNonOptional ? ` & { __typename: '${typename}' }` : '';
11751174

1176-
return `( ${typeValue}${nonOptionalTypenameModifier} )`; // Must wrap every type in explicit "( )" to separate them
1177-
})
1178-
.join(' | ') || 'never';
1175+
return `( ${typeValue}${nonOptionalTypenameModifier} )`; // Must wrap every type in explicit "( )" to separate them
1176+
});
1177+
const result =
1178+
members.length === 0
1179+
? 'never'
1180+
: members.length > 1
1181+
? `\n | ${members.map(m => m.replace(/\n/g, '\n ')).join('\n | ')}\n `
1182+
: members.join(' | ');
11791183
return result;
11801184
}
11811185

packages/plugins/other/visitor-plugin-common/src/selection-set-to-object.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -844,7 +844,7 @@ export class SelectionSetToObject<Config extends ParsedDocumentsConfig = ParsedD
844844
this.getEmptyObjectTypeString(mustAddEmptyObject),
845845
].filter(Boolean);
846846

847-
const content = typeParts.join(' | ');
847+
const content = formatUnion(typeParts);
848848

849849
if (typeParts.length > 1 && this._config.extractAllFieldsToTypes) {
850850
return {
@@ -944,7 +944,7 @@ export class SelectionSetToObject<Config extends ParsedDocumentsConfig = ParsedD
944944
.export()
945945
.asKind('type')
946946
.withName(mergedTypeString)
947-
.withContent(subTypes.map(t => t.name).join(' | ')).string,
947+
.withContent(formatUnion(subTypes.map(t => t.name))).string,
948948
].join('\n');
949949
}
950950

@@ -961,3 +961,10 @@ export class SelectionSetToObject<Config extends ParsedDocumentsConfig = ParsedD
961961
return operationTypes.includes(typeName) ? parentName : `${parentName}_${typeName}`;
962962
}
963963
}
964+
965+
function formatUnion(members: string[]): string {
966+
if (members.length > 1) {
967+
return `\n | ${members.map(m => m.replace(/\n/g, '\n ')).join('\n | ')}\n`;
968+
}
969+
return members.join(' | ');
970+
}

packages/plugins/typescript/operations/src/ts-selection-set-processor.ts

Lines changed: 38 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -25,20 +25,20 @@ export class TypeScriptSelectionSetProcessor extends BaseSelectionSetProcessor<S
2525
});
2626

2727
if (unsetTypes) {
28-
return [`MakeEmpty<${parentName}, ${fields.map(field => `'${field.fieldName}'`).join(' | ')}>`];
28+
const escapedFieldNames = fields.map(field => `'${field.fieldName}'`);
29+
return [formattedUnionTransform('MakeEmpty', parentName, escapedFieldNames)];
2930
}
3031

3132
let hasConditionals = false;
32-
const conditilnalsList: string[] = [];
33-
let resString = `Pick<${parentName}, ${fields
34-
.map(field => {
35-
if (field.isConditional) {
36-
hasConditionals = true;
37-
conditilnalsList.push(field.fieldName);
38-
}
39-
return `'${field.fieldName}'`;
40-
})
41-
.join(' | ')}>`;
33+
const escapedConditionalsList: string[] = [];
34+
const escapedFieldNames = fields.map(field => {
35+
if (field.isConditional) {
36+
hasConditionals = true;
37+
escapedConditionalsList.push(`'${field.fieldName}'`);
38+
}
39+
return `'${field.fieldName}'`;
40+
});
41+
let resString = formattedUnionTransform('Pick', parentName, escapedFieldNames);
4242

4343
if (hasConditionals) {
4444
const avoidOptional =
@@ -52,7 +52,7 @@ export class TypeScriptSelectionSetProcessor extends BaseSelectionSetProcessor<S
5252
const transform = avoidOptional ? 'MakeMaybe' : 'MakeOptional';
5353
resString = `${
5454
this.config.namespacedImportName ? `${this.config.namespacedImportName}.` : ''
55-
}${transform}<${resString}, ${conditilnalsList.map(field => `'${field}'`).join(' | ')}>`;
55+
}${formattedUnionTransform(transform, resString, escapedConditionalsList)}`;
5656
}
5757
return [resString];
5858
}
@@ -75,25 +75,38 @@ export class TypeScriptSelectionSetProcessor extends BaseSelectionSetProcessor<S
7575
useTypesPrefix: true,
7676
});
7777

78-
return [
79-
`{ ${fields
80-
.map(aliasedField => {
81-
const value =
82-
aliasedField.fieldName === '__typename'
83-
? `'${schemaType.name}'`
84-
: `${parentName}['${aliasedField.fieldName}']`;
85-
86-
return `${aliasedField.alias}: ${value}`;
87-
})
88-
.join(', ')} }`,
89-
];
78+
const selections = fields.map(aliasedField => {
79+
const value =
80+
aliasedField.fieldName === '__typename' ? `'${schemaType.name}'` : `${parentName}['${aliasedField.fieldName}']`;
81+
82+
return `${aliasedField.alias}: ${value}`;
83+
});
84+
return [formatSelections(selections)];
9085
}
9186

9287
transformLinkFields(fields: LinkField[]): ProcessResult {
9388
if (fields.length === 0) {
9489
return [];
9590
}
9691

97-
return [`{ ${fields.map(field => `${field.alias || field.name}: ${field.selectionSet}`).join(', ')} }`];
92+
const selections = fields.map(field => `${field.alias || field.name}: ${field.selectionSet}`);
93+
94+
return [formatSelections(selections)];
95+
}
96+
}
97+
98+
/** Equivalent to `${transformName}<${target}, ${unionElements.join(' | ')}>`, but with line feeds if necessary */
99+
function formattedUnionTransform(transformName: string, target: string, unionElements: string[]): string {
100+
if (unionElements.length > 3) {
101+
return `${transformName}<\n ${target},\n | ${unionElements.join('\n | ')}\n >`;
102+
}
103+
return `${transformName}<${target}, ${unionElements.join(' | ')}>`;
104+
}
105+
106+
/** Equivalent to `{ ${selections.join(', ')} }`, but with line feeds if necessary */
107+
function formatSelections(selections: string[]): string {
108+
if (selections.length > 1) {
109+
return `{\n ${selections.map(s => s.replace(/\n/g, '\n ')).join(',\n ')},\n }`;
98110
}
111+
return `{ ${selections.join(', ')} }`;
99112
}

0 commit comments

Comments
 (0)