Skip to main content

Migrating from v5 to v6

First, execute npx @comet/upgrade@latest v6 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.

Renames handled by @comet/upgrade
  • JobStatus -> KubernetesJobStatus in API
  • @SubjectEntity -> @AffectedEntity in API
  • BuildRuntime -> JobRuntime in Admin

API

User Permissions

  1. Prerequisites: Manage or sync allowed users in project (not covered here)

  2. Remove custom CurrentUser and CurrentUserLoader

    - declare module "@comet/cms-api" {
    - interface CurrentUserInterface {
    - ...
    - }
    - }

    - @ObjectType()
    - export class CurrentUser implements CurrentUserInterface {
    - ...
    - }

    - export class CurrentUserLoader implements CurrentUserLoaderInterface {
    - ...
    - }

    Also remove usage

      createAuthProxyJwtStrategy({
    jwksUri: config.auth.idpJwksUri,
    - currentUserLoader: new CurrentUserLoader(),
    }),

    Furthermore, it's not necessary anymore to provide the CurrentUser

      createAuthResolver({
    - currentUser: CurrentUser,

    Change imports of removed classes

    - import { CurrentUser, CurrentUserLoader } from "@src/auth/current-user";
    + import { CurrentUser } from "@comet/cms-api";

    Replace occurrences of CurrentUserInterface

    - @GetCurrentUser() user: CurrentUserInterface;
    + @GetCurrentUser() user: CurrentUser;

    It is not possible anymore to use a custom CurrentUserLoader neither to augment/use the CurrentUserInterface.

  3. Create the AccessControlService for the UserPermissionsModule (either in a new module or where it fits best)

    @Injectable()
    export class AccessControlService extends AbstractAccessControlService {
    getPermissionsForUser(user: User): PermissionsForUser {
    // e.g. return `UserPermissions.allPermissions;` for certain users
    }
    getContentScopesForUser(user: User): ContentScopesForUser {
    // e.g. return `UserPermissions.allContentScopes;` for certain users
    }
    }
  4. Replace ContentScopeModule with UserPermissionsModule

    Remove ContentScopeModule:

    - ContentScopeModule.forRoot({
    - ...
    - }),

    Add UserPermissionsModule:

    UserPermissionsModule.forRootAsync({
    useFactory: (accessControlService: AccessControlService) => ({
    availableContentScopes: [/* Array of content Scopes */],
    accessControlService,
    }),
    inject: [AccessControlService],
    imports: [/* Modules which provide the services injected in useFactory */],
    }),
  5. Adapt decorators

    Add @RequiredPermission to resolvers and controllers

    + @RequiredPermission(["pageTree"])
    export class PagesResolver {

    Remove @AllowForRole (replaced by @RequiredPermission)

    - @AllowForRole(...)
  6. Optional: Add the UserService (required for Administration Panel, see Admin)

    Create a UserService:

    // Attention: might already being provided by the library which syncs the users
    @Injectable()
    export class UserService implements UserPermissionsUserServiceInterface {
    getUser(id: string): User {
    ...
    }
    findUsers(args: FindUsersArgs): Users {
    ...
    }
    }

    Add it to the UserPermissionsModule:

      UserPermissionsModule.forRootAsync({
    + useFactory: (accessControlService: AccessControlService, userService: UserService) => ({
    - useFactory: (accessControlService: AccessControlService) => ({
    availableContentScopes: [/* Array of content Scopes */],
    + userService,
    accessControlService,
    }),
    + inject: [AccessControlService, UserService],
    - inject: [AccessControlService],
    imports: [/* Modules which provide the services injected in useFactory */],
    }),

Admin

User Permissions

  1. Add <CurrentUserProvider> to App.tsx

    <ApolloProvider client={apolloClient}>
    + <CurrentUserProvider>
  2. Use useCurrentUser() hook instead requesting the current user from the API

    - const { loading, data } = useQuery(gql`
    - query CurrentUser {
    - currentUser {
    - ...
    - }
    - }
    - `);
    + const user = useCurrentUser();

    Also access allowedContentScopes where necessary (e.g. in ContentScopeProvider):

    - const allowedUserDomains = data.currentUser.domains;
    + const allowedUserDomains = user.allowedContentScopes.map((contentScope) => contentScope.domain);
  3. Optional: Add the Adminstration Panel

    <MenuItemRouterLink
    primary={intl.formatMessage({
    id: "menu.userPermissions",
    defaultMessage: "User Permissions",
    })}
    icon={<Snips />}
    to={`${match.url}/user-permissions`}
    />
    <RouteWithErrorBoundary
    path={`${match.path}/user-permissions`}
    component={UserPermissionsPage}
    />

Sites Config

The SitesConfigProvider and useSitesConfig were made generic.

You must make following changes in the application:

  1. Define the type of your sites config

    Preferably this should be done in config.ts:

    export function createConfig() {
    // ...

    return {
    ...cometConfig,
    apiUrl: environmentVariables.API_URL,
    adminUrl: environmentVariables.ADMIN_URL,
    + sitesConfig: JSON.parse(environmentVariables.SITES_CONFIG) as SitesConfig,
    };
    }

    + export type SitesConfig = Record<string, SiteConfig>;
  2. Use the type when using useSitesConfig

    - const sitesConfig = useSitesConfig();
    + const sitesConfig = useSitesConfig<SitesConfig>();
  3. Optional: Remove type annotation from ContentScopeProvider#resolveSiteConfigForScope (as it's now inferred)

    - resolveSiteConfigForScope: (configs: Record<string, SiteConfig>, scope: ContentScope) => configs[scope.domain],
    + resolveSiteConfigForScope: (configs, scope: ContentScope) => configs[scope.domain],

@comet/admin

FinalForm

Previously, FinalForm#onAfterSubmit() automatically executed

stackApi?.goBack();
editDialog?.closeDialog({ delay: true });

This was removed because it was often unwanted and overridden.

You need to:

  1. Add following code if you still want the old behavior:

    const stackApi = React.useContext(StackApiContext);
    const editDialog = React.useContext(EditDialogApiContext);

    // ...

    <FinalForm
    onAfterSubmit={() => {
    stackApi?.goBack();
    editDialog?.closeDialog({ delay: true });
    }}
    >
  2. You can remove workarounds like

    - onAfterSubmit={() => {
    - //don't go back automatically
    - }}

@comet/admin-icons

The icons Betrieb, LogischeFilter, Pool, Pool2, Vignette1, Vignette2, StateGreen, StateGreenRing, StateOrange, StateOrangeRing, StateRed and StateRedRing were removed.

If you used any of these icons in your app, you must add them to your project. You can download them here.