MrHertal / react-admin-amplify

AWS Amplify data provider for react-admin.
MIT License
159 stars 42 forks source link

How to alter `getQueryName` and `getQueryNameMany`? #83

Open Carduelis opened 1 year ago

Carduelis commented 1 year ago

Hi @MrHertal !

I realized in latest amplify it generates queries like: dataPointsByMetricID instead of listDatapointsByMetricId which is generated via getQueryName and getQueryNameMany functions.

Although, there is no way to alter those functions, and DataProvider is not exported nor its parts.

There are two options, which might be helpful:

  1. Make DataProvider customizable including getQueryName
  2. Update getQueryName according to recent updates

Also, I would suggest not using getQueryName and similar functions as class methods preferring simple functions.

Carduelis commented 1 year ago

After some digging, I realized the following issues with the current approach to query name generation.

First, of all, I do believe the assumption of capitalizing and joining targets, sources, and resources is error-prone.

Since, the idea of generation hundreds of GraphQL queries, provided by amplify-cli is great and it is a subject of constant change, we need to have the ability to override behavior in this library. Otherwise, we had to copy the code of providers folder (thanks it's in TS) and modify it.

Also, the method getQueryNameMany trims the last two letters, and adds Id at the end. Which is, probably, was right in your case, but is wrong in mine. I have a query, ended with ID (both letters uppercased)

Carduelis commented 1 year ago

So, I came up with the following solution:

  1. I copied the providers folder, kept only buildDataProvider and AdminQueries.ts, Filter.ts, Pagination.ts;
  2. Created utils.ts file;
  3. Modified getQueryName and getQueryNameMany public methods;
// DataProvider.ts

  public getQueryName(operation: string, resource: string): string {
    const pluralOperations = ["list"];

    if (pluralOperations.includes(operation)) {
      return `${operation}${capitalize(resource)}`;
    }
    // else singular operations ["create", "delete", "get", "update"]
    const singularResource = depluralize(resource);
    return `${operation}${capitalize(singularResource)}`;
  }

  public getQueryNameMany(
    operation: string,
    resource: string,
    target: string
  ): string {
    return `${capitalize(resource)}By${capitalize(target)}`;
  }
export const capitalize = (string: string): string => {
  return `${string[0].toUpperCase()}${string.slice(1)}`;
};

export const depluralize = (string: string): string => {
  if (string.slice(-1) === "s") {
    return string.slice(0, -1);
  }
  return string;
};