Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
427 changes: 427 additions & 0 deletions .api-reports/api-report-v4-migration.api.md

Large diffs are not rendered by default.

427 changes: 427 additions & 0 deletions .api-reports/api-report-zz_removals.api.md

Large diffs are not rendered by default.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,8 @@
"production": "./src/utilities/environment/index.production.ts",
"development": "./src/utilities/environment/index.development.ts",
"default": "./src/utilities/environment/index.ts"
}
},
"./v4-migration": "./src/v4-migration.ts"
},
"scripts": {
"prebuild": "npm run clean",
Expand Down
1 change: 1 addition & 0 deletions scripts/codemods/ac3-to-ac4/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ npx @apollo/client-codemod-migrate-3-to-4 --parser ts file1.ts file2.ts --codem
- `imports`: Moves imports that have been moved or renamed in Apollo Client 4. Also moves types into namespace imports where applicable.
- `links`: Moves `split`, `from`, `concat` and `empty` onto the `ApolloLink` namespace, changes funtion link invocations like `createHttpLink(...)` to their class equivalents like (`new HttpLink(...)`).
Does not change `setContext((operation, prevContext) => {})` to `new ContextLink((prevContext, operation) => {})` - this requires manual intervention, as the order of callback arguments is flipped and this is not reliable codemoddable.
- `removals`: Points all imports of values or types that have been removed in Apollo Client 4 to the `@apollo/client/v4-migration` entry point. That entry point contains context for each removal, oftentimes with migration instructions.

### Usage against TypeScript/TSX

Expand Down

Large diffs are not rendered by default.

30 changes: 30 additions & 0 deletions scripts/codemods/ac3-to-ac4/src/__tests__/removals.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { describe, expect, test } from "vitest";

import removals from "../removals.js";

import { createDiff } from "./diffTransform.js";
import allExports from "./exports.json" with { type: "json" };
const diff = createDiff(removals);

test("all exports", () => {
const source = Object.entries(allExports)
.map(([entryPoint, exports]) =>
`
import {
${exports
.map(
(info) =>
`${info.name} as ${entryPoint
.replace(/@apollo\/client\/?/, "")
.replace(/[/-]/g, "_")}_${info.name}`
)
.join(",\n ")},
} from "${entryPoint}";
`.trim()
)
.join("\n\n");

//console.log(source);

expect(diff(source)).toMatchSnapshot();
});
6 changes: 5 additions & 1 deletion scripts/codemods/ac3-to-ac4/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,13 @@ import type { API, FileInfo, Options, Transform } from "jscodeshift";

import imports from "./imports.js";
import links from "./links.js";
import removals from "./removals.js";
import { monkeyPatchAstTypes } from "./util/monkeyPatchAstTypes.js";

export const codemods = { imports, links } satisfies Record<string, Transform>;
export const codemods = { imports, links, removals } satisfies Record<
string,
Transform
>;

export default async function transform(
file: FileInfo,
Expand Down
195 changes: 195 additions & 0 deletions scripts/codemods/ac3-to-ac4/src/removals.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,195 @@
import type { Transform } from "jscodeshift";

import type { IdentifierRename } from "./renames.js";
import { handleIdentiferRename } from "./util/handleIdentiferRename.js";

// prettier-ignore
const removals = [
{ importType: "type", module: "@apollo/client", identifier: "ClientParseError" },
{ importType: "type", module: "@apollo/client", identifier: "FetchMoreQueryOptions" },
{ importType: "type", module: "@apollo/client", identifier: "FragmentMatcher" },
{ importType: "type", module: "@apollo/client", identifier: "MethodKeys" },
{ importType: "type", module: "@apollo/client", identifier: "MutationUpdaterFn" },
{ importType: "type", module: "@apollo/client", identifier: "PureQueryOptions" },
{ importType: "type", module: "@apollo/client", identifier: "Resolver" },
{ importType: "type", module: "@apollo/client", identifier: "Resolvers" },
{ importType: "type", module: "@apollo/client/errors", identifier: "ApolloErrorOptions" },
{ importType: "type", module: "@apollo/client/errors", identifier: "GraphQLErrors" },
{ importType: "type", module: "@apollo/client/errors", identifier: "NetworkError" },
{ importType: "type", module: "@apollo/client/link/batch", identifier: "BatchableRequest" },
{ importType: "type", module: "@apollo/client/link/http", identifier: "ClientParseError" },
{ importType: "type", module: "@apollo/client/react", identifier: "BaseMutationOptions" },
{ importType: "type", module: "@apollo/client/react", identifier: "BaseQueryOptions" },
{ importType: "type", module: "@apollo/client/react", identifier: "CommonOptions" },
{ importType: "type", module: "@apollo/client/react", identifier: "IDocumentDefinition" },
{ importType: "type", module: "@apollo/client/react", identifier: "MutationDataOptions" },
{ importType: "type", module: "@apollo/client/react", identifier: "ObservableQueryFields" },
{ importType: "type", module: "@apollo/client/react", identifier: "QueryDataOptions" },
{ importType: "type", module: "@apollo/client/react", identifier: "QueryLazyOptions" },
{ importType: "type", module: "@apollo/client/react", identifier: "RefetchQueriesFunction" },
{ importType: "type", module: "@apollo/client/react", identifier: "SubscriptionCurrentObservable" },
{ importType: "type", module: "@apollo/client/react/components", identifier: "MutationComponentOptions" },
{ importType: "type", module: "@apollo/client/react/components", identifier: "QueryComponentOptions" },
{ importType: "type", module: "@apollo/client/react/components", identifier: "SubscriptionComponentOptions" },
{ importType: "type", module: "@apollo/client/react/context", identifier: "ApolloConsumerProps" },
{ importType: "type", module: "@apollo/client/react/hoc", identifier: "ChildDataProps" },
{ importType: "type", module: "@apollo/client/react/hoc", identifier: "ChildMutateProps" },
{ importType: "type", module: "@apollo/client/react/hoc", identifier: "ChildProps" },
{ importType: "type", module: "@apollo/client/react/hoc", identifier: "DataProps" },
{ importType: "type", module: "@apollo/client/react/hoc", identifier: "DataValue" },
{ importType: "type", module: "@apollo/client/react/hoc", identifier: "MutateProps" },
{ importType: "type", module: "@apollo/client/react/hoc", identifier: "OperationOption" },
{ importType: "type", module: "@apollo/client/react/hoc", identifier: "OptionProps" },
{ importType: "type", module: "@apollo/client/react/hoc", identifier: "QueryControls" },
{ importType: "type", module: "@apollo/client/react/hoc", identifier: "WithApolloClient" },
{ importType: "type", module: "@apollo/client/react/parser", identifier: "IDocumentDefinition" },
{ importType: "type", module: "@apollo/client/utilities", identifier: "ConcastSourcesArray" },
{ importType: "type", module: "@apollo/client/utilities", identifier: "ConcastSourcesIterable" },
{ importType: "type", module: "@apollo/client/utilities", identifier: "DirectiveInfo" },
{ importType: "type", module: "@apollo/client/utilities", identifier: "Directives" },
{ importType: "type", module: "@apollo/client/utilities", identifier: "GetDirectiveConfig" },
{ importType: "type", module: "@apollo/client/utilities", identifier: "GetFragmentSpreadConfig" },
{ importType: "type", module: "@apollo/client/utilities", identifier: "GetNodeConfig" },
{ importType: "type", module: "@apollo/client/utilities", identifier: "InclusionDirectives" },
{ importType: "type", module: "@apollo/client/utilities", identifier: "IsStrictlyAny" },
{ importType: "type", module: "@apollo/client/utilities", identifier: "OnlyRequiredProperties" },
{ importType: "type", module: "@apollo/client/utilities", identifier: "PromiseWithState" },
{ importType: "type", module: "@apollo/client/utilities", identifier: "ReconcilerFunction" },
{ importType: "type", module: "@apollo/client/utilities", identifier: "RemoveArgumentsConfig" },
{ importType: "type", module: "@apollo/client/utilities", identifier: "RemoveDirectiveConfig" },
{ importType: "type", module: "@apollo/client/utilities", identifier: "RemoveFragmentDefinitionConfig" },
{ importType: "type", module: "@apollo/client/utilities", identifier: "RemoveFragmentSpreadConfig" },
{ importType: "type", module: "@apollo/client/utilities", identifier: "RemoveNodeConfig" },
{ importType: "type", module: "@apollo/client/utilities", identifier: "RemoveVariableDefinitionConfig" },
{ importType: "type", module: "@apollo/client/utilities", identifier: "TupleToIntersection" },
{ importType: "type", module: "@apollo/client/utilities", identifier: "UnionToIntersection" },
{ importType: "type", module: "@apollo/client/utilities", identifier: "VariableValue" },
{ importType: "value", module: "@apollo/client", identifier: "ApolloError" },
{ importType: "value", module: "@apollo/client", identifier: "DataProxy" },
{ importType: "value", module: "@apollo/client", identifier: "fromError" },
{ importType: "value", module: "@apollo/client", identifier: "fromPromise" },
{ importType: "value", module: "@apollo/client", identifier: "isApolloError" },
{ importType: "value", module: "@apollo/client", identifier: "ObservableSubscription" },
{ importType: "value", module: "@apollo/client", identifier: "Observer" },
{ importType: "value", module: "@apollo/client", identifier: "serializeFetchParameter" },
{ importType: "value", module: "@apollo/client", identifier: "throwServerError" },
{ importType: "value", module: "@apollo/client", identifier: "toPromise" },
{ importType: "value", module: "@apollo/client/cache", identifier: "DataProxy" },
{ importType: "value", module: "@apollo/client/errors", identifier: "ApolloError" },
{ importType: "value", module: "@apollo/client/errors", identifier: "isApolloError" },
{ importType: "value", module: "@apollo/client/link/batch", identifier: "OperationBatcher" },
{ importType: "value", module: "@apollo/client/link/http", identifier: "serializeFetchParameter" },
{ importType: "value", module: "@apollo/client/link/utils", identifier: "fromError" },
{ importType: "value", module: "@apollo/client/link/utils", identifier: "fromPromise" },
{ importType: "value", module: "@apollo/client/link/utils", identifier: "throwServerError" },
{ importType: "value", module: "@apollo/client/link/utils", identifier: "toPromise" },
{ importType: "value", module: "@apollo/client/link/utils", identifier: "transformOperation" },
{ importType: "value", module: "@apollo/client/link/utils", identifier: "validateOperation" },
{ importType: "value", module: "@apollo/client/react", identifier: "ApolloConsumer" },
{ importType: "value", module: "@apollo/client/react", identifier: "DocumentType" },
{ importType: "value", module: "@apollo/client/react", identifier: "operationName" },
{ importType: "value", module: "@apollo/client/react", identifier: "parser" },
{ importType: "value", module: "@apollo/client/react", identifier: "resetApolloContext" },
{ importType: "value", module: "@apollo/client/react/components", identifier: "Mutation" },
{ importType: "value", module: "@apollo/client/react/components", identifier: "Query" },
{ importType: "value", module: "@apollo/client/react/components", identifier: "Subscription" },
{ importType: "value", module: "@apollo/client/react/context", identifier: "ApolloConsumer" },
{ importType: "value", module: "@apollo/client/react/context", identifier: "resetApolloContext" },
{ importType: "value", module: "@apollo/client/react/hoc", identifier: "graphql" },
{ importType: "value", module: "@apollo/client/react/hoc", identifier: "withApollo" },
{ importType: "value", module: "@apollo/client/react/hoc", identifier: "withMutation" },
{ importType: "value", module: "@apollo/client/react/hoc", identifier: "withQuery" },
{ importType: "value", module: "@apollo/client/react/hoc", identifier: "withSubscription" },
{ importType: "value", module: "@apollo/client/react/parser", identifier: "DocumentType" },
{ importType: "value", module: "@apollo/client/react/parser", identifier: "operationName" },
{ importType: "value", module: "@apollo/client/react/parser", identifier: "parser" },
{ importType: "value", module: "@apollo/client/react/parser", identifier: "verifyDocumentType" },
{ importType: "value", module: "@apollo/client/react/ssr", identifier: "RenderPromises" },
{ importType: "value", module: "@apollo/client/testing", identifier: "createMockClient" },
{ importType: "value", module: "@apollo/client/testing", identifier: "itAsync" },
{ importType: "value", module: "@apollo/client/testing", identifier: "mockObservableLink" },
{ importType: "value", module: "@apollo/client/testing", identifier: "mockSingleLink" },
{ importType: "value", module: "@apollo/client/testing", identifier: "subscribeAndCount" },
{ importType: "value", module: "@apollo/client/testing", identifier: "tick" },
{ importType: "value", module: "@apollo/client/testing", identifier: "wait" },
{ importType: "value", module: "@apollo/client/testing", identifier: "withErrorSpy" },
{ importType: "value", module: "@apollo/client/testing", identifier: "withLogSpy" },
{ importType: "value", module: "@apollo/client/testing", identifier: "withWarningSpy" },
{ importType: "value", module: "@apollo/client/testing/core", identifier: "createMockClient" },
{ importType: "value", module: "@apollo/client/testing/core", identifier: "itAsync" },
{ importType: "value", module: "@apollo/client/testing/core", identifier: "mockObservableLink" },
{ importType: "value", module: "@apollo/client/testing/core", identifier: "mockSingleLink" },
{ importType: "value", module: "@apollo/client/testing/core", identifier: "subscribeAndCount" },
{ importType: "value", module: "@apollo/client/testing/core", identifier: "tick" },
{ importType: "value", module: "@apollo/client/testing/core", identifier: "withErrorSpy" },
{ importType: "value", module: "@apollo/client/testing/core", identifier: "withLogSpy" },
{ importType: "value", module: "@apollo/client/testing/core", identifier: "withWarningSpy" },
{ importType: "value", module: "@apollo/client/testing/experimental", identifier: "createSchemaFetch" },
{ importType: "value", module: "@apollo/client/testing/experimental", identifier: "createTestSchema" },
{ importType: "value", module: "@apollo/client/utilities", identifier: "addNonReactiveToNamedFragments" },
{ importType: "value", module: "@apollo/client/utilities", identifier: "asyncMap" },
{ importType: "value", module: "@apollo/client/utilities", identifier: "buildQueryFromSelectionSet" },
{ importType: "value", module: "@apollo/client/utilities", identifier: "canUseAsyncIteratorSymbol" },
{ importType: "value", module: "@apollo/client/utilities", identifier: "canUseLayoutEffect" },
{ importType: "value", module: "@apollo/client/utilities", identifier: "canUseSymbol" },
{ importType: "value", module: "@apollo/client/utilities", identifier: "canUseWeakMap" },
{ importType: "value", module: "@apollo/client/utilities", identifier: "canUseWeakSet" },
{ importType: "value", module: "@apollo/client/utilities", identifier: "Concast" },
{ importType: "value", module: "@apollo/client/utilities", identifier: "defaultCacheSizes" },
{ importType: "value", module: "@apollo/client/utilities", identifier: "fixObservableSubclass" },
{ importType: "value", module: "@apollo/client/utilities", identifier: "getDirectiveNames" },
{ importType: "value", module: "@apollo/client/utilities", identifier: "getFragmentMaskMode" },
{ importType: "value", module: "@apollo/client/utilities", identifier: "getInclusionDirectives" },
{ importType: "value", module: "@apollo/client/utilities", identifier: "getTypenameFromResult" },
{ importType: "value", module: "@apollo/client/utilities", identifier: "hasAllDirectives" },
{ importType: "value", module: "@apollo/client/utilities", identifier: "hasAnyDirectives" },
{ importType: "value", module: "@apollo/client/utilities", identifier: "hasClientExports" },
{ importType: "value", module: "@apollo/client/utilities", identifier: "isApolloPayloadResult" },
{ importType: "value", module: "@apollo/client/utilities", identifier: "isExecutionPatchIncrementalResult" },
{ importType: "value", module: "@apollo/client/utilities", identifier: "isExecutionPatchInitialResult" },
{ importType: "value", module: "@apollo/client/utilities", identifier: "isExecutionPatchResult" },
{ importType: "value", module: "@apollo/client/utilities", identifier: "isFullyUnmaskedOperation" },
{ importType: "value", module: "@apollo/client/utilities", identifier: "isInlineFragment" },
{ importType: "value", module: "@apollo/client/utilities", identifier: "isStatefulPromise" },
{ importType: "value", module: "@apollo/client/utilities", identifier: "iterateObserversSafely" },
{ importType: "value", module: "@apollo/client/utilities", identifier: "mergeIncrementalData" },
{ importType: "value", module: "@apollo/client/utilities", identifier: "ObservableSubscription" },
{ importType: "value", module: "@apollo/client/utilities", identifier: "Observer" },
{ importType: "value", module: "@apollo/client/utilities", identifier: "removeArgumentsFromDocument" },
{ importType: "value", module: "@apollo/client/utilities", identifier: "removeClientSetsFromDocument" },
{ importType: "value", module: "@apollo/client/utilities", identifier: "removeConnectionDirectiveFromDocument" },
{ importType: "value", module: "@apollo/client/utilities", identifier: "removeFragmentSpreadFromDocument" },
{ importType: "value", module: "@apollo/client/utilities", identifier: "valueToObjectRepresentation" },
] satisfies Array<{
module: string;
identifier: string;
importType: "type" | "value";
}>;

const removalsTransform: Transform = function transform(file, api) {
const j = api.jscodeshift;
const source = j(file.source);
const context = { j, source };

let modified = false;
for (const removal of removals) {
const rename: IdentifierRename = {
from: {
module: removal.module,
identifier: removal.identifier,
alternativeModules: ["@apollo/client", "@apollo/client/core"],
},
to: { module: "@apollo/client/v4-migration", alternativeModules: [] },
importType: removal.importType,
};
handleIdentiferRename({
rename,
context,
onModify: () => {
modified = true;
},
});
}
return modified ? source.toSource() : undefined;
};
export default removalsTransform;
2 changes: 2 additions & 0 deletions src/__tests__/__snapshots__/exports.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -487,3 +487,5 @@ Array [
"setVerbosity",
]
`;

exports[`exports of public entry points @apollo/client/v4-migration 1`] = `Array []`;
2 changes: 2 additions & 0 deletions src/__tests__/exports.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ import * as utilitiesEnvironment from "@apollo/client/utilities/environment";
import * as utilitiesInternal from "@apollo/client/utilities/internal";
import * as utilitiesInternalGlobals from "@apollo/client/utilities/internal/globals";
import * as utilitiesInvariant from "@apollo/client/utilities/invariant";
import * as v4_migration from "@apollo/client/v4-migration";

// eslint-disable-next-line local-rules/no-relative-imports
import { entryPoints } from "../../config/entryPoints.js";
Expand Down Expand Up @@ -105,6 +106,7 @@ describe("exports of public entry points", () => {
check("@apollo/client/utilities/internal/globals", utilitiesInternalGlobals);
check("@apollo/client/utilities/invariant", utilitiesInvariant);
check("@apollo/client/utilities/environment", utilitiesEnvironment);
check("@apollo/client/v4-migration", v4_migration);

checkWithConditions("@apollo/client/react", ["react-server"]);

Expand Down
Loading