Skip to main content

Migrating from v7 to v8

First, execute npx @comet/upgrade@latest v8 in the root of your project. It automatically installs the new versions of all @comet libraries, runs an ESLint autofix and handles some of the necessary renames.

Changes handled by @comet/upgrade
  • Upgrade MUI packages to v6
  • Run MUI codemods
  • Upgrade MUI X packages to v6
  • Upgrade NestJS packages to v10
  • Upgrade Prettier to v3

API

Upgrade peer dependencies

NestJS

The NestJS peer dependency has been bumped to v10.

  1. Upgrade all your dependencies to support NestJS v10:

    {
    "dependencies": {
    + "@apollo/server": "^4.0.0",
    - "@nestjs/apollo": "^10.0.0",
    - "@nestjs/common": "^9.0.0",
    - "@nestjs/config": "^2.0.0",
    - "@nestjs/core": "^9.0.0",
    - "@nestjs/graphql": "^10.0.0",
    - "@nestjs/passport": "^9.0.0",
    - "@nestjs/platform-express": "^9.0.0",
    + "@nestjs/apollo": "^12.0.0",
    + "@nestjs/common": "^10.0.0",
    + "@nestjs/core": "^10.0.0",
    + "@nestjs/graphql": "^12.0.0",
    + "@nestjs/passport": "^10.0.0",
    + "@nestjs/platform-express": "^10.0.0",
    - "apollo-server-core": "^3.0.0",
    - "apollo-server-express": "^3.0.0",
    - "graphql": "^15.0.0",
    + "graphql": "^16.6.0",
    - "nestjs-console": "^8.0.0",
    + "nestjs-console": "^9.0.0"
    },
    "devDependencies": {
    - "@nestjs/cli": "^9.0.0",
    - "@nestjs/schematics": "^9.0.0",
    - "@nestjs/testing": "^9.0.0",
    + "@nestjs/cli": "^10.0.0",
    + "@nestjs/schematics": "^10.0.0",
    + "@nestjs/testing": "^10.0.0"
    }
    }
    Codemod available
    npx @comet/upgrade v8/update-nest-dependencies.ts
  2. Update the custom formatError function to hide GraphQL field suggestions:

    - import { ValidationError } from "apollo-server-express";
    + import { ValidationError } from "@nestjs/apollo";

    /* ... */

    GraphQLModule.forRootAsync<ApolloDriverConfig>({
    /* ... */
    useFactory: (moduleRef: ModuleRef) => ({
    /* ... */,
    formatError: (error) => {
    // Disable GraphQL field suggestions in production
    if (process.env.NODE_ENV !== "development") {
    - if (error instanceof ValidationError) {
    + if (error.extensions?.code === "GRAPHQL_VALIDATION_FAILED") {
    return new ValidationError("Invalid request.");
    }
    }
    return error;
    },

    }),
    }),
    Codemod available
    npx @comet/upgrade v8/update-graphql-format-error.ts

MikroORM

The MikroORM peer dependency has been bumped to v6.

  1. Upgrade all your dependencies:

    {
    "dependencies": {
    - "@mikro-orm/cli": "^5.9.8",
    - "@mikro-orm/core": "^5.9.8",
    - "@mikro-orm/migrations": "^5.9.8",
    - "@mikro-orm/nestjs": "^5.2.3",
    - "@mikro-orm/postgresql": "^5.9.8",
    + "@mikro-orm/cli": "^6.4.0",
    + "@mikro-orm/core": "^6.4.0",
    + "@mikro-orm/migrations": "^6.4.0",
    + "@mikro-orm/nestjs": "^6.0.2",
    + "@mikro-orm/postgresql": "^6.4.0",
    },
    }
    Codemod available
    npx @comet/upgrade v8/update-mikro-orm-dependencies.ts
  2. Follow the official migration guide to upgrade.

    Codemods available

    We provide upgrade scripts for basic migrations. Please note that these scripts might not cover all necessary migrations.

    Remove generic from BaseEntity:

    npx @comet/upgrade v8/mikro-orm-base-entity-generic.ts

    Rename customType to type:

    npx @comet/upgrade v8/mikro-orm-custom-type.ts

    Rename onDelete to deleteRule:

    npx @comet/upgrade v8/mikro-orm-delete-rule.ts

    Add a mikro-orm script with a dotenv call to package.json:

    npx @comet/upgrade v8/mikro-orm-dotenv.ts

    Change all imports from @mikro-orm/core to @mikro-orm/postgresql:

    npx @comet/upgrade v8/mikro-orm-imports.ts

    Wrap config in defineConfig:

    npx @comet/upgrade v8/mikro-orm-ormconfig.ts

class-validator

The class-validator peer dependency has been bumped to v0.14.0:

{
"dependencies": {
- "class-validator": "0.13.2",
+ "class-validator": "^0.14.0",
}
}
Codemod available
npx @comet/upgrade v8/update-class-validator.ts

Sentry

  1. Upgrade the "@sentry/node" dependency in your package.json file:
{
"dependencies": {
- "@sentry/node": "^7.0.0",
+ "@sentry/node": "^8.0.0",
},
}
  1. Update your main.ts file to remove all Sentry.Handlers and add Sentry.setupExpressErrorHandler(app):
-   app.use(Sentry.Handlers.requestHandler());
- app.use(Sentry.Handlers.tracingHandler());
- app.use(Sentry.Handlers.errorHandler());
+ Sentry.setupExpressErrorHandler(app);

NestJS peer dependencies

Peer dependencies defined by NestJS have been added as peer dependencies to @comet/cms-api. To upgrade, install the dependencies in your project:

{
"dependencies": {
+ "class-transformer": "^0.5.1",
- "reflect-metadata": "^0.1.13",
+ "reflect-metadata": "^0.2.2",
- "rxjs": "^7.0.0",
+ "rxjs": "^7.8.1",
}
}
Codemod available
npx @comet/upgrade v8/nest-peer-dependencies.ts

Remove @comet/blocks-api

The @comet/blocks-api package has been merged into the @comet/cms-api package. To upgrade, perform the following steps:

  1. Remove the package:

    api/package.json
    - "@comet/blocks-api": "^7.x.x",
    Codemod available
    npx @comet/upgrade v8/remove-blocks-packages.ts
  2. Update all your imports from @comet/blocks-api to @comet/cms-api

    Codemod available
    npx @comet/upgrade v8/merge-blocks-api-into-cms-api.ts
  3. Update imports that have been renamed

    Codemod available
    npx @comet/upgrade v8/merge-blocks-api-into-cms-api.ts
  4. Remove usages of removed export getFieldKeys (probably none)

Admin

Upgrade peer dependencies

Support for React 18 has been added. While optional, it is recommended to upgrade to React 18 in the project.

  1. Upgrade all your dependencies:

    {
    "dependencies": {
    - "react": "^17.0.2",
    - "react-dom": "^17.0.2",
    + "react": "^18.3.1",
    + "react-dom": "^18.3.1"
    },
    "devDependencies": {
    - "@types/react": "^17.0.83",
    - "@types/react-dom": "^17.0.26",
    + "@types/react": "^18.3.18",
    + "@types/react-dom": "^18.3.5"
    }
    }
    Codemod available
    npx @comet/upgrade v8/update-react-dependencies.ts
  2. Follow the official migration guide to upgrade.

    tip

    Use types-react-codemod to fix potential TypeScript compile errors when upgrading to @types/react@^18.0.0.

Stay on same page after changing scope

The Admin now stays on the same page per default when changing scopes. Perform the following changes:

  1. Remove the path prop from the PagesPage component

    admin/src/common/MasterMenu.tsx
    <PagesPage
    - path="/pages/pagetree/main-navigation"
    allCategories={pageTreeCategories}
    documentTypes={pageTreeDocumentTypes}
    category="MainNavigation"
    renderContentScopeIndicator={(scope) => <ContentScopeIndicator scope={scope} />}
    />
  2. Remove the redirectPathAfterChange prop from the RedirectsPage component

    admin/src/common/MasterMenu.tsx
    {
    type: "route",
    primary: <FormattedMessage id="menu.redirects" defaultMessage="Redirects" />,
    route: {
    path: "/system/redirects",
    - render: () => <RedirectsPage redirectPathAfterChange="/system/redirects" />,
    + component: RedirectsPage
    },
    requiredPermission: "pageTree",
    },
  3. Optional: Remove unnecessary usages of the useContentScopeConfig hook

    export function ProductsPage() {
    const intl = useIntl();

    - useContentScopeConfig({ redirectPathAfterChange: "/structured-content/products" });
    }

Import Tooltip from @comet/admin package

- import { Tooltip } from "@mui/material";
+ import { Tooltip } from "@comet/admin";

Remove trigger prop from Tooltip

The trigger prop has been removed. The combined hover/focus trigger is now the only supported behavior.

Example:

<Tooltip
- trigger="hover"
></Tooltip>

Import Dialog from @comet/admin package

- import { Dialog } from "@mui/material";
+ import { Dialog } from "@comet/admin";

Update MUI - X Packages

In package.json update the version of the MUI X packages to ^7.22.3.

- "@mui/x-data-grid": "^5.x.x",
- "@mui/x-data-grid-pro": "^5.x.x",
- "@mui/x-data-grid-premium": "^5.x.x",

+ "@mui/x-data-grid": "^7.22.3",
+ "@mui/x-data-grid-pro": "^7.22.3",
+ "@mui/x-data-grid-premium": "^7.22.3",
Codemod
npx @comet/upgrade v8/mui-x-upgrade.ts

A lots of props have been renamed from MUI, for a detailed look, see the official migration guide v5 -> v6 and migration guide v6 -> v7. There is also a codemod from MUI which handles most of the changes:

! As well, be aware if you have a date in the data grid, you will need to add a valueGetter

    <DataGrid
//other props
columns=[
{
field: "updatedAt",
type: "dateTime",
+ valueGetter: (params, row) => row.updatedAt && new Date(row.updatedAt)
}]
/>

Also, be aware if you have a valueGetter or valueFormatter in the data grid, you will need to change the arguments passing to the functions. Previously, arguments were passed as an object. Now, they are passed directly as individual parameters

    <DataGrid
//other props
columns=[
{
field: "updatedAt",
type: "dateTime",
- valueGetter: ({params, row}) => row.updatedAt && new Date(row.updatedAt)
+ valueGetter: (params, row) => row.updatedAt && new Date(row.updatedAt)
- valueFormatter: ({value}) => (value ? intl.formatDate(value, { dateStyle: "medium", timeStyle: "short" }) : ""),
+ valueFormatter: (value) => (value ? intl.formatDate(value, { dateStyle: "medium", timeStyle: "short" }) : ""),
}]
/>
npx @mui/x-codemod@latest v6.0.0/data-grid/preset-safe <path>

useDataGridRemote Hook - Return Value

The useDataGridRemote hook has been changed to match the updated DataGrid props:

- const { pageSize, page, onPageSizeChange } = useDataGridRemote();
+ const { paginationModel, onPaginationModelChange } = useDataGridRemote();

muiGridSortToGql Function

The muiGridSortToGql helper now expects the columns instead of the apiRef:

const columns : GridColDef[] = [/* column definitions*/];
const dataGridRemote = useDataGridRemote();
const persistentColumnState = usePersistentColumnState("persistent_column_state");

- muiGridSortToGql(dataGridRemote.sortModel, persistentColumnState.apiRef);
+ muiGridSortToGql(dataGridRemote.sortModel, columns);
Codemod
npx @comet/upgrade v8/mui-grid-sort-to-gql.ts

Note: Be aware, this will naively change the second argument of muiGridSortToGql function to columns variable, attempting that this variable is available in the current scope.

MUI removed error prop on DataGrid

The error and onError props were removed - the grid no longer catches errors during rendering. To catch errors that happen during rendering use the error boundary. The components.ErrorOverlay slot was also removed.

MUI migration guide

Codemod
npx @comet/upgrade v8/mui-data-grid-remove-error-prop.ts

Note: error handling must be implemented manually, the codemod simple removes all usages of the error prop on DataGrids and adds a TODO: comment.

The recommended way to handle errors is to use the ErrorBoundary in the parent component and throw errors where the query error happens.

- const { loading, data, error } = useQuery(/* query parameters */)
- <DataGrid error={error} /* other props */ >

+ const { loading, data, error } = useQuery(/* query parameters */)
+ if (error) {
+ throw error
+ }
+ <DataGrid /* other props */ >

Remove @comet/admin-react-select

- "@comet/admin-react-select": "^7.x.x",

It is recommended to use the AutocompleteField or the SelectField components from @comet/admin instead:

- import { FinalFormReactSelectStaticOptions } from "@comet/admin-react-select";
- <Field name="color" type="text" component={FinalFormReactSelectStaticOptions} fullWidth options={options} />;
+ import { AutocompleteField } from "@comet/admin";
+ <AutocompleteField name="color" label="Color" options={options} fullWidth />;

ESLint

ESLint upgrade from v8 to v9 with ESM

Update ESLint to v9

package.json

- "eslint": "^8.0.0",
+ "eslint": "^9.0.0",

An ESM compatible ESLint config is required. Delete the related .eslintrc.json and move the configured rules to the new ESLint flat configuration eslint.config.mjs.

Migration Guide of ESLint 9.0 can be found here: Migration Guide

admin/eslint.config.mjs

import cometConfig from "@comet/eslint-config/react.js";

/** @type {import('eslint')} */
const config = [
{
ignores: ["schema.json", "src/fragmentTypes.json", "dist/**", "src/**/*.generated.ts"],
},
...cometConfig
];

export default config;

api/eslint.config.mjs

import cometConfig from "@comet/eslint-config/react.js";

/** @type {import('eslint')} */
import cometConfig from "@comet/eslint-config/nestjs.js";

/** @type {import('eslint')} */
const config = [
{
ignores: ["src/db/migrations/**", "dist/**", "src/**/*.generated.ts"],
},
...cometConfig,
];

export default config;

site/eslint.config.mjs

import cometConfig from "@comet/eslint-config/react.js";

/** @type {import('eslint')} */
import cometConfig from "@comet/eslint-config/nextjs.js";

/** @type {import('eslint')} */
const config = [
{
ignores: ["**/**/*.generated.ts", "dist/**", "lang/**", "lang-compiled/**", "lang-extracted/**", ".next/**", "public/**"],
},
...cometConfig,
];

export default config;

Remove React barrel imports

Importing React is no longer necessary due to the new JSX transform, which automatically imports the necessary react/jsx-runtime functions. Use individual named imports instead, e.g, import { useState } from "react".

It is recommended to perform the following steps separately in the admin/ and site/ directories:

  1. Replace import * as React from "react"; with import React from "react"; in your codebase (This step is optional but improves the results of the codemod).

  2. Run the codemod to update React imports (option --force is required to because of changes of step one above):

    npx react-codemod update-react-imports --force
  3. Run ESLint with the --fix option to automatically fix issues:

    npm run lint:eslint --fix

These steps will help automate the process of updating React imports and fixing linting issues, making the migration smoother. The codemod does not handle all cases, so manual adjustments may still be necessary.

Consistent type imports

To improve code consistency and readability, we now enforce the ESLint rule @typescript-eslint/consistent-type-imports with the following configuration:

"@typescript-eslint/consistent-type-imports": [
"error",
{
"prefer": "type-imports",
"disallowTypeAnnotations": false,
"fixStyle": "inline-type-imports"
}
]

Why this change?

This rule ensures that TypeScript type-only imports are explicitly marked with import type, leading to multiple benefits:

  • Improved Code Clarity It is immediately clear that the imported symbol is used only for TypeScript type checking and not at runtime. Avoids confusion between runtime imports and purely static type definitions.
  • Performance & Tree-Shaking TypeScript can optimize build performance since it knows which imports are needed only at compile time. Some bundlers can more effectively remove unused type imports, reducing bundle size.
  • Reduced Circular Dependency Issues Circular dependencies can cause hard-to-debug issues in TypeScript projects. Using import type ensures that types do not introduce unintended runtime dependencies.

Migration Steps

Run ESLint with the --fix option to automatically update imports:

npm run lint:eslint --fix