<aside> ⚠️ The guide is written to upgrade:

Starting from earlier versions might work, but it’s not guaranteed (it will probably need extra work). Read more in the previous upgrade guide.

</aside>

<aside> 🎏 References:

Step by step guide

<aside> 🆚 Before to start, make sure your developer tools are updated to the versions stated in our Development basics guide.

</aside>

Back-end

  1. First, let’s ignore a new temporary file generated during builds.

    1. Add to the .gitignore file in the root folder the following line:

      // ...
      @idea custom
      back-end/tsconfig.tsbuildinfo # new line here just below @idea custom
      // ...
      
    2. Add to the .vscode/settings.json file the following line:

      // ...
      # new line after "back-end/**/node_modules": true
      "back-end/**/tsconfig.tsbuildinfo": true,
      // ...
      
  2. Locate the back-end folder.

  3. ESLint v9 requires different configuration file and commands.

    1. Delete the .eslintrc.js file.

    2. In the deploy.sh script:

      # change the following line (before)...
      npm run lint ${SRC_FOLDER} 1>/dev/null
      # ...to (after)
      npm run lint 1>/dev/null
      
      # remove the following line (it should be unused after previous change)
      SRC_FOLDER='src/'
      
    3. Add the following new file:

      • eslint.config.js
    4. In the package.json file:

      // change the following line (before)...
      "lint": "eslint --ext .ts",
      // ...with (after)
      "lint": "eslint 'src/**/*.{ts,tsx}'",
      
  4. Run npm i PACKAGE@latest, for each of the following packages:

    1. idea-toolbox.
    2. idea-aws.
    3. any IDEA’s other package.
  5. Remove the package-lock.json file and the node_modules folder.

  6. In the package.json file, refer to to the following versions for devDependencies and manually fix the packages versions so that all of IDEA’s projects are aligned to the very same state. Note: you don’t have to add packages that your codebase don’t need; also: there could be some packages missing from the list.

  7. In the tsconfig.json file, change the following line:

    // before
    "extends": "./node_modules/@tsconfig/node20/tsconfig.json",
    // after
    "extends": "./node_modules/@tsconfig/node22/tsconfig.json",
    
  8. Run a npm i to reinstall everything from a clean state. At this point, it shouldn’t throw any errors or vulnerability.

  9. Change the Lambda functions configuration to v22 (in all the stacks):

    1. In CDK, in the stacks, substitute any occurrence of NODEJS_20_X with NODEJS_22_X.
    2. In SAM, in yaml templates, substitute any occurrence of nodejs20.x with nodejs22.x.
    3. In non-IAC projects: update manually from the UI console of Lambda.
  10. CDK only. The use of the attribute logRetention for Lambda functions is deprecated. Therefore, we need to implement an explicit creation of a logGroup for each of our Lambda functions. You can copy (the more similar, the better) the behaviour from THIS commit to the cloud-app-starter project.

  11. We want to automatically get the updated code from support functions loaded from our S3 buckets (i.e. idea-lambda-functions) each time the version of Node.js changes.

    1. With CDK, replace this file’s content — but keep any project-specific changes already in place. Note that, for CDK only, the change also implements for the media-stack the same behaviour to the log groups explained earlier for the api-stack.
      • deploy/media-stack.ts of cloud-app-starter project.
    2. With SAM, you need to run these commands (if not already done by @Matteo Carbone), depending whether the project uses the thumbnailer and/or html2pdf.
      • thumbnailer — replace the correct AWS profile.
      • html2pdf — replace the correct AWS profile.
    3. With non-IAC projects: the update is manual; for the services of the suite ITER, it has already been done. For other projects, contact @Matteo Carbone for help.
  12. CDK only. With the objective of optimising the size of the generated IaC template for api-stack.ts (hence achieving faster deploys), we want to refactor the permissions creation from direct IAM policies for each Lambda function, to one IAM role shared among all Lambda functions. You can copy (the more similar, the better) the behaviour from THIS commit to the cloud-app-starter project.

  13. Following the release notes of IDEA-AWS, we need to update all the Controllers so that they don’t use callbacks (deprecated). Short examples:

    // before
    export const handler = (ev: any, _: any, cb: any) => new MyRC(ev, cb).handleRequest();
    // after
    export const handler = (event: any): Promise<any> => new MyRC(event).handleRequest();
    
    // ...
    class MyRC extends ResourceController {
      // before
      constructor(event: any, callback: any) {
        super(event, callback);
      // after
      constructor(event: any) {
        super(event);
        // ...
      }
      // ...
    }
    
    // before
    export const handler = (ev: any, _: any, cb: any): void => {
      if (ev.Records) new WebSocketStreamController(ev, cb).handleRequest();
      else new WebSocketApiController(ev, cb).handleRequest();
    };
    // after
    export const handler = async (ev: any): Promise<any> => {
      if (ev.Records) return new WebSocketStreamController(ev, cb).handleRequest();
      else return new WebSocketApiController(ev, cb).handleRequest();
    };
    
    // ...
    // before
    async handleRequest(): Promise<void> {
      try {
        // ...
        this.callback(null, { statusCode: 200 });
      } catch (error) {
        // ...
        this.callback(null, { statusCode: 400 });
      }
    }
    // ...
    // after
    async handleRequest(): Promise<any> {
      try {
        // ...
        return { statusCode: 200 };
      } catch (error) {
        // ...
        return { statusCode: 400 };
      }
    }
    // ...
    
  14. Following the new default recommendations of the Linter, if we have cases of try/catch in which we don’t use the variable of catch, we need to substitute it with _:

    // before
    } catch (unusedVar) {
    // after
    } catch (_) {
    

    <aside> 💬

    If any other Linter warning/error appears, consult with @Matteo Carbone.

    </aside>