Skip to content
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
6616585
integration test
Jan 7, 2026
7e204c1
cleanups
ikusakov Jan 7, 2026
2fc4571
cleanups2
ikusakov Jan 7, 2026
056dbd0
Merge remote-tracking branch 'upstream/master-next' into feature/add-…
ikusakov Jan 7, 2026
ba85977
fixed a bug with external fragments
ikusakov Jan 7, 2026
6fd5428
cleanup
ikusakov Jan 7, 2026
790b876
keep generated files, refactored visitorwq
ikusakov Jan 8, 2026
e73b9ba
cleanup
ikusakov Jan 8, 2026
1f54f42
changeset
ikusakov Jan 9, 2026
900aa10
adding missing dependency
ikusakov Jan 9, 2026
10a2774
delete temporary files
ikusakov Jan 12, 2026
10d3b85
cleanup
ikusakov Jan 12, 2026
9b3dbf8
cleanups
ikusakov Jan 12, 2026
64b7834
Adding back the integration tests + fix them
ikusakov Jan 12, 2026
17c9614
Merge remote-tracking branch 'upstream/master-next' into feature/add-…
ikusakov Jan 12, 2026
ab0ab18
merged + fixes
ikusakov Jan 12, 2026
1498d8f
cleanup
ikusakov Jan 12, 2026
3839b02
cleanup
ikusakov Jan 12, 2026
ad44930
patching near-operation-file preset
ikusakov Jan 15, 2026
c2c6ea0
cleanup
ikusakov Jan 15, 2026
4d86e60
adding duplicates case to integration tests
ikusakov Jan 15, 2026
85fd378
Fixing bug with duplicates generated when using extractAllFieldsToTyp…
ikusakov Jan 15, 2026
d7e75e3
cleanup
ikusakov Jan 15, 2026
28e61b0
Merge remote-tracking branch 'upstream/master-next' into feature/add-…
ikusakov Jan 15, 2026
b474a3f
prevent running prettier on generated code
ikusakov Jan 16, 2026
5f4666c
cleanups
ikusakov Jan 16, 2026
da8f02a
cleanup
ikusakov Jan 16, 2026
899fd58
adding unit tests
ikusakov Jan 16, 2026
4789809
update changeset
ikusakov Jan 16, 2026
15b4278
cleanups
ikusakov Jan 18, 2026
24f7aec
try resolving graphql 16 error
ikusakov Jan 18, 2026
ed99011
remove unused deps
ikusakov Jan 18, 2026
2740719
remove unused deps
ikusakov Jan 18, 2026
65d158a
cleanups
ikusakov Jan 18, 2026
eec25ef
Revert and apply minimal yarn.lock changes
eddeee888 Jan 19, 2026
180a80a
Merge branch 'master-next' into feature/add-config-extractAllFieldsTo…
eddeee888 Jan 19, 2026
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
2 changes: 2 additions & 0 deletions dev-test-alpha/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
**/__generated__/**
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I feel we should unignore the generation 🙂
This could be a good test that can be kept as snapshot test, and an advanced use case of codegen

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

OK, generated files added!


106 changes: 106 additions & 0 deletions dev-test-alpha/cli/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
#!/usr/bin/env ts-node
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I created the dev-test-alpha just as a temporary package to demonstrate our company issues.
Do you think it would be worth keeping it?
Then:

  • I'll need to add some tests which would get invoked when global tests are running.
  • We need to come up with some better name than dev-test-alpha

Copy link
Copy Markdown
Collaborator

@eddeee888 eddeee888 Jan 11, 2026

Choose a reason for hiding this comment

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

Yes, I think so! I find this test is very valuable, as it can be used to catch unexpected bugs, at least in the initial stage after rolling out.

I feel we might be able to simplify a few things in the setup. And worst case, if its usefulness is overshadowed by maintenance, we can decide to drop it (or further simplify) later 🙂

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

OK, I renamed dev-test-alpha to dev-test-apollo-tooling - to give a more descriptive name to what this integration test it about. I also added another (hopefully last) fix - so you can run yarn install && yarn build from the root directory: graphql-code-generator and - it should work.


import path from 'path';
import { isEmpty, uniq } from 'lodash-es';
import { generate } from '@graphql-codegen/cli';
import type { Types } from '@graphql-codegen/plugin-helpers';
import deleteAsync from 'del';

export const GENERATED = '__generated__';
export const GLOBAL_TYPES_FILE = 'globalTypes.ts';
export const TS_GENERATED_FILE_HEADER = `\
/* tslint:disable */
/* eslint-disable */
// @generated
// This file was automatically generated and should not be edited.
`;

/**
* The following GraphQL Codegen config matches as closely as possible
* to the old apollo-tooling codegen
* @see https://github.com/apollographql/apollo-tooling/issues/2053
* */
const GRAPHQL_CODEGEN_CONFIG = {
skipTypename: false,
useTypeImports: true,
preResolveTypes: true, // Simplifies the generated types
namingConvention: 'keep', // Keeps naming as-is
avoidOptionals: false, // Allow '?' on variables fields
nonOptionalTypename: true, // Forces `__typename` on all selection sets
skipTypeNameForRoot: true, // Don't generate __typename for root types
omitOperationSuffix: true, // Don't add 'Query', 'Mutation' or 'Subscription' suffixes to operation result types
fragmentSuffix: '', // Don't add 'Fragment' suffix to fragment result types
extractAllFieldsToTypes: true, // Extracts all fields to separate types (similar to apollo-codegen behavior)
printFieldsOnNewLines: true, // Prints each field on a new line (similar to apollo-codegen behavior)
namespacedImportName: '',
importTypesNamespace: '',
enumType: 'native',
generatesOperationTypes: true,
importSchemaTypesFrom: false,
};

export const main = async () => {
const cwd = process.cwd();

await deleteAsync([`src/**/${GENERATED}`], { cwd });

const localSchemaFilePath = `${cwd}/schema.graphql`;

const { internalIncludes, externalIncludes } = { internalIncludes: [`${cwd}/src/**/*.ts`], externalIncludes: [] };

const generateFiles: { [scanPath: string]: Types.ConfiguredOutput } = {};

const includesForCodegen = uniq(internalIncludes.map((includes: string) => includes.replace(/\/\*\*\/.+$/, '')));

const globalTypesPath = `${cwd}/src/${GENERATED}/${GLOBAL_TYPES_FILE}`;

const monorepoRoot = path.resolve(cwd, '..');

if (!isEmpty(includesForCodegen)) {
// Prepare the required structure for GraphQL Codegen
includesForCodegen.forEach((includes: string) => {
const relativeIncludes = path.relative(monorepoRoot, includes);

generateFiles[relativeIncludes] = {
preset: 'near-operation-file', // This preset tells the codegen to generate multiple files instead of one
presetConfig: {
extension: '.ts', // Matches the existing Apollo-Codegen file naming
baseTypesPath: `../${path.relative(cwd, globalTypesPath)}`, // Relative (to repo root) path to the global types file to include
folder: GENERATED, // Output folder for generated files
},
plugins: [
'typescript-operations',
{
add: {
content: TS_GENERATED_FILE_HEADER,
},
},
],
};
});

await generate(
{
schema: localSchemaFilePath,
documents: [
// matching js extensins as well - there are cases where js files are not converted to typescript yet
// (but the package is typescript)
...includesForCodegen.map(include => `${include}/**/*.{js,jsx,ts,tsx}`),
...externalIncludes,
`!**/${GENERATED}/**`,
],
config: GRAPHQL_CODEGEN_CONFIG,
generates: generateFiles,
silent: true,
},
true // overwrite existing files
);
}
};

if (import.meta.url === process.argv[1] || import.meta.url === `file://${process.argv[1]}`) {
main().catch(e => {
console.error(e);
process.exit(1);
});
}
28 changes: 28 additions & 0 deletions dev-test-alpha/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
{
"name": "dev-test-alpha",
"description": "dev-test-alpha",
"version": "0.0.1",
"type": "module",
"dependencies": {
"@apollo/client": "3.13.8",
"@graphql-codegen/cli": "workspace:../packages/graphql-codegen-cli",
"@graphql-codegen/near-operation-file-preset": "4.0.0",
"@graphql-codegen/plugin-helpers": "workspace:../packages/utils/plugins-helpers",
"@graphql-codegen/typescript-operations": "workspace:../packages/plugins/typescript/operations",
"del": "^6.1.1",
"graphql": "^16.9.0",
"lodash-es": "^4.17.15"
},
"devDependencies": {
"@types/lodash-es": "^4.17.6",
"@types/node": "^25.0.3",
"typescript": "^5.9.3"
},
"files": [
"cli"
],
"scripts": {
"start": "npx tsx cli/index.ts"
},
"sideEffects": false
}
106 changes: 106 additions & 0 deletions dev-test-alpha/schema.graphql
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
schema
@link(url: "https://specs.apollo.dev/link/v1.0")
@link(url: "https://specs.apollo.dev/join/v0.4", for: EXECUTION)
@link(url: "https://specs.apollo.dev/tag/v0.3") {
query: Query
}

directive @join__graph(name: String!, url: String!) on ENUM_VALUE

directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE

directive @join__field(
graph: join__Graph
requires: join__FieldSet
provides: join__FieldSet
type: String
external: Boolean
override: String
usedOverridden: Boolean
overrideLabel: String
) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION

directive @join__implements(graph: join__Graph!, interface: String!) repeatable on OBJECT | INTERFACE

directive @join__type(
graph: join__Graph!
key: join__FieldSet
extension: Boolean! = false
resolvable: Boolean! = true
isInterfaceObject: Boolean! = false
) repeatable on OBJECT | INTERFACE | UNION | ENUM | INPUT_OBJECT | SCALAR

directive @join__unionMember(graph: join__Graph!, member: String!) repeatable on UNION

directive @link(url: String, as: String, for: link__Purpose, import: [link__Import]) repeatable on SCHEMA

directive @tag(
name: String!
) repeatable on FIELD_DEFINITION | OBJECT | INTERFACE | UNION | ARGUMENT_DEFINITION | SCALAR | ENUM | ENUM_VALUE | INPUT_OBJECT | INPUT_FIELD_DEFINITION | SCHEMA

scalar join__FieldSet

scalar link__Import

enum link__Purpose {
EXECUTION
}

enum join__Graph {
SUPER_USER_MANAGER @join__graph(name: "super_user_management", url: "http://i.am.not.used.example.com")
GRAPHQL_MAIN__SHARD__BASE @join__graph(name: "graphql_main__shard__base", url: "http://i.am.not.used.example.com")
GRAPHQL_MAIN__SHARD__INTERNAL_TESTING
@join__graph(name: "graphql_main__shard__internal_testing", url: "http://i.am.not.used.example.com")
}

type Query {
superUser: SuperUser! @join__field(graph: GRAPHQL_MAIN__SHARD__BASE)
}

enum UserManagerRoleType @join__type(graph: SUPER_USER_MANAGER) {
ROLE_TYPE_1 @join__enumValue(graph: SUPER_USER_MANAGER)

ROLE_TYPE_2 @join__enumValue(graph: SUPER_USER_MANAGER)

ROLE_TYPE_3 @join__enumValue(graph: SUPER_USER_MANAGER)
}

type UserManager @join__type(graph: SUPER_USER_MANAGER) {
fooUser: User!

roleType: UserManagerRoleType!
}

type User {
id: ID!
profilePhoto: UserProfilePhoto @join__field(graph: GRAPHQL_MAIN__SHARD__BASE)
}

type UserProfilePhoto @join__type(graph: GRAPHQL_MAIN__SHARD__BASE) {
id: ID!
photoUrl: UserPhotoUrl
}

type UserPhotoUrl @join__type(graph: GRAPHQL_MAIN__SHARD__BASE) {
url(size: UserPhotoSize!): String
}

enum UserPhotoSize
@join__type(graph: GRAPHQL_MAIN__SHARD__BASE)
@join__type(graph: GRAPHQL_MAIN__SHARD__INTERNAL_TESTING) {
SQUARE_300
@join__enumValue(graph: GRAPHQL_MAIN__SHARD__BASE)
@join__enumValue(graph: GRAPHQL_MAIN__SHARD__INTERNAL_TESTING)
}

type SuperUser @join__type(graph: GRAPHQL_MAIN__SHARD__BASE) {
groupFromAlias(alias: String!): SuperUserGroup!
}

type SuperUserGroup
@join__type(graph: SUPER_USER_MANAGER, key: "id")
@join__type(graph: GRAPHQL_MAIN__SHARD__BASE, key: "id") {
id: ID!

managers(onlyPublic: Boolean! = false): [UserManager!] @join__field(graph: SUPER_USER_MANAGER)
}
21 changes: 21 additions & 0 deletions dev-test-alpha/src/Component.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { useQuery, gql } from '@apollo/client';
import Helper from './Helper';

export const getFooQuery = gql`
${Helper.fragments.query}
query GetFoo($alias: String!, $collectionId: String!) {
superUser {
groupFromAlias(alias: $alias) {
managers(onlyPublic: true) {
...HelperFields
}
}
}
}
`;

const Component = () => {
useQuery(getFooQuery, {});
};

export default Component;
27 changes: 27 additions & 0 deletions dev-test-alpha/src/Helper.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { gql } from '@apollo/client';

const getHelperFieldsFragment = gql`
fragment HelperFields on UserManager {
roleType
fooUser {
profilePhoto {
photoUrl {
url(size: SQUARE_300)
}
}
}
}
`;

export const helperPropsFromFragment = (fragment: any) => ({
profilePhotoUrl: fragment.fooUser.profilePhoto?.photoUrl.url,
roleType: fragment.roleType,
});

const Helper = { fragments: { query: {} } };

Helper.fragments = {
query: getHelperFieldsFragment,
};

export default Helper;
11 changes: 11 additions & 0 deletions dev-test-alpha/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"compilerOptions": {
"target": "ES2020",
"module": "NodeNext",
"moduleResolution": "NodeNext",
"verbatimModuleSyntax": true,
"esModuleInterop": true,
"resolveJsonModule": true,
"strict": true
}
}
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,8 @@
"packages/plugins/other/*",
"packages/presets/*",
"website",
"examples/**/*"
"examples/**/*",
"dev-test-alpha"
],
"devDependencies": {
"@babel/core": "7.25.2",
Expand Down
8 changes: 7 additions & 1 deletion packages/plugins/typescript/operations/src/visitor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,13 @@ export class TypeScriptDocumentsVisitor extends BaseDocumentsVisitor<
...(config.externalFragments || []),
];

this._usedNamedInputTypes = this.collectUsedInputTypes({ schema, documentNode });
// Create a combined document that includes external fragments for enum collection
const documentWithExternalFragments: DocumentNode = {
...documentNode,
definitions: [...documentNode.definitions, ...(config.externalFragments || []).map(f => f.node)],
};
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I wonder if the functionality in the above statement used to create allFragments could be used for our fragments here somehow? 🤔
It seems to do a similar function of collecting fragments, either from documents or from config.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Good call!
Check the new code - I combined it with allFragments.


this._usedNamedInputTypes = this.collectUsedInputTypes({ schema, documentNode: documentWithExternalFragments });

const processorConfig: SelectionSetProcessorConfig = {
namespacedImportName: this.config.namespacedImportName,
Expand Down
Loading
Loading