Repository: sequelize/sequelize
File: packages/core/src/model.js (JavaScript)

Code before:
  static async count(options) {
    options = cloneDeep(options) ?? {};
    options = defaultsLodash(options, { hooks: true });

    setTransactionFromCls(options, this.sequelize);

    options.raw = true;
    if (options.hooks) {
      await this.hooks.runAsync('beforeCount', options);
    }

    options.plain = !options.group;
    options.dataType = new DataTypes.INTEGER();
    options.includeIgnoreAttributes = false;

    // No limit, offset or order for the options max be given to count()
    // Set them to null to prevent scopes setting those values
    options.limit = null;
    options.offset = null;
    options.order = null;

    // counting grouped rows is not possible with `this.aggregate`
    // use a subquery to get the count
    if (options.group && options.countGroupedRows) {
      // remove trailing semicolon for wrap query
      const query = this.queryGenerator.selectQuery(this.getTableName(), options).slice(0, -1);

      const queryCountAll = `Select COUNT(*) AS count FROM (${query}) AS Z`;

      const result = await this.sequelize.query(queryCountAll);

      const count = Number(result[0][0].count || result[0][0].COUNT);

      return count;
    }

    let col = options.col || '*';
    if (options.include) {
      col = `${this.name}.${options.col || this.primaryKeyField}`;
    }

    if (options.distinct && col === '*') {
      col = this.primaryKeyField;
    }

    const result = await this.aggregate(col, 'count', options);

    // When grouping is used, some dialects such as PG are returning the count as string
    // --> Manually convert it to number
    if (Array.isArray(result)) {
      return result.map(item => ({

Review comment (suggestion):
```suggestion
      const query = removeTrailingSemicolon(this.queryGenerator.selectQuery(this.table, options));
```

You'll need to import `removeTrailingSemicolon`;
https://github.com/sequelize/sequelize/blob/89fc0ff0dec093d17cd37d2f0260e404926faeb0/packages/core/src/utils/string.ts#L109-L115

`getTableName()` is deprecated as per;
https://github.com/sequelize/sequelize/blob/89fc0ff0dec093d17cd37d2f0260e404926faeb0/packages/core/src/model-typescript.ts#L413-L433

Code after:
   */
  static async count(options) {
    options = cloneDeep(options) ?? {};
    options = defaultsLodash(options, { hooks: true });

    setTransactionFromCls(options, this.sequelize);

    options.raw = true;
    if (options.hooks) {
      await this.hooks.runAsync('beforeCount', options);
    }

    options.plain = !options.group;
    options.dataType = new DataTypes.INTEGER();
    options.includeIgnoreAttributes = false;

    // No limit, offset or order for the options max be given to count()
    // Set them to null to prevent scopes setting those values
    options.limit = null;
    options.offset = null;
    options.order = null;

    // counting grouped rows is not possible with `this.aggregate`
    // use a subquery to get the count
    if (options.group && options.countGroupedRows) {
      const query = removeTrailingSemicolon(this.queryGenerator.selectQuery(this.table, options));

      const queryCountAll = `Select COUNT(*) AS count FROM (${query}) AS Z`;

      const result = await this.sequelize.query(queryCountAll);

      const count = Number(result[0][0].count || result[0][0].COUNT);

      return count;
    }

    let col = options.col || '*';
    if (options.include) {
      col = `${this.name}.${options.col || this.primaryKeyField}`;
    }

    if (options.distinct && col === '*') {
      col = this.primaryKeyField;
    }

    const result = await this.aggregate(col, 'count', options);

    // When grouping is used, some dialects such as PG are returning the count as string
    // --> Manually convert it to number
    if (Array.isArray(result)) {
      return result.map(item => ({