Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Lack of the type of ‘total’ property in GraphQLResult if using searchXxx query #13766

Open
3 tasks done
HikaruTakakura opened this issue Aug 29, 2024 · 8 comments
Open
3 tasks done
Assignees
Labels
feature-request Request a new feature GraphQL Related to GraphQL API issues pending-community-response Issue is pending a response from the author or community.

Comments

@HikaruTakakura
Copy link

HikaruTakakura commented Aug 29, 2024

Before opening, please confirm:

JavaScript Framework

Next.js

Amplify APIs

GraphQL API

Amplify Version

v6

Amplify Categories

api

Backend

Amplify CLI

Environment information

# Put output below this line
  System:
    OS: macOS 14.4
    CPU: (8) arm64 Apple M2
    Memory: 62.75 MB / 16.00 GB
    Shell: 5.9 - /bin/zsh
  Binaries:
    Node: 20.6.1 - ~/.anyenv/envs/nodenv/versions/20.6.1/bin/node
    npm: 9.8.1 - ~/.anyenv/envs/nodenv/versions/20.6.1/bin/npm
    bun: 1.0.29 - ~/.bun/bin/bun
  Browsers:
    Chrome: 128.0.6613.86
    Safari: 17.4
  npmPackages:
    @ampproject/toolbox-optimizer:  undefined ()
    @aws-amplify/adapter-nextjs: ^1.0.30 => 1.2.10 
    @aws-amplify/adapter-nextjs/api:  undefined ()
    @aws-amplify/adapter-nextjs/data:  undefined ()
    @babel/core:  undefined ()
    @babel/runtime:  7.22.5 
    @edge-runtime/cookies:  4.1.0 
    @edge-runtime/ponyfill:  2.4.2 
    @edge-runtime/primitives:  4.1.0 
    @hapi/accept:  undefined ()
    @mswjs/interceptors:  undefined ()
    @napi-rs/triples:  undefined ()
    @next/font:  undefined ()
    @next/react-dev-overlay:  undefined ()
    @next/third-parties: ^14.1.4 => 14.1.4 
    @opentelemetry/api:  undefined ()
    @remixicon/react: ^4.2.0 => 4.2.0 
    @stripe/react-stripe-js: ^2.6.2 => 2.7.0 
    @stripe/stripe-js: ^3.2.0 => 3.3.0 
    @types/node: ^20 => 20.12.7 
    @types/react: ^18 => 18.2.75 
    @types/react-burger-menu: ^2.8.7 => 2.8.7 
    @types/react-dom: ^18 => 18.2.24 
    @types/react-modal: ^3.16.3 => 3.16.3 
    @vercel/nft:  undefined ()
    @vercel/og:  0.6.2 
    acorn:  undefined ()
    amphtml-validator:  undefined ()
    amplify: ^0.0.11 => 0.0.11 
    anser:  undefined ()
    arg:  undefined ()
    assert:  undefined ()
    async-retry:  undefined ()
    async-sema:  undefined ()
    autoprefixer: ^10.0.1 => 10.4.19 
    aws-amplify: ^6.0.30 => 6.4.3 
    aws-amplify/adapter-core:  undefined ()
    aws-amplify/analytics:  undefined ()
    aws-amplify/analytics/kinesis:  undefined ()
    aws-amplify/analytics/kinesis-firehose:  undefined ()
    aws-amplify/analytics/personalize:  undefined ()
    aws-amplify/analytics/pinpoint:  undefined ()
    aws-amplify/api:  undefined ()
    aws-amplify/api/server:  undefined ()
    aws-amplify/auth:  undefined ()
    aws-amplify/auth/cognito:  undefined ()
    aws-amplify/auth/cognito/server:  undefined ()
    aws-amplify/auth/enable-oauth-listener:  undefined ()
    aws-amplify/auth/server:  undefined ()
    aws-amplify/data:  undefined ()
    aws-amplify/data/server:  undefined ()
    aws-amplify/datastore:  undefined ()
    aws-amplify/in-app-messaging:  undefined ()
    aws-amplify/in-app-messaging/pinpoint:  undefined ()
    aws-amplify/push-notifications:  undefined ()
    aws-amplify/push-notifications/pinpoint:  undefined ()
    aws-amplify/storage:  undefined ()
    aws-amplify/storage/s3:  undefined ()
    aws-amplify/storage/s3/server:  undefined ()
    aws-amplify/storage/server:  undefined ()
    aws-amplify/utils:  undefined ()
    aws-sdk: ^2.1655.0 => 2.1655.0 
    axios: ^1.6.8 => 1.6.8 
    babel-packages:  undefined ()
    browser-image-compression: ^2.0.2 => 2.0.2 
    browserify-zlib:  undefined ()
    browserslist:  undefined ()
    buffer:  undefined ()
    bytes:  undefined ()
    ci-info:  undefined ()
    cli-select:  undefined ()
    client-only:  0.0.1 
    comment-json:  undefined ()
    compression:  undefined ()
    conf:  undefined ()
    constants-browserify:  undefined ()
    content-disposition:  undefined ()
    content-type:  undefined ()
    cookie:  undefined ()
    cross-spawn:  undefined ()
    crypto-browserify:  undefined ()
    css.escape:  undefined ()
    data-uri-to-buffer:  undefined ()
    date-fns: ^3.6.0 => 3.6.0 
    date-fns-tz: ^3.1.3 => 3.1.3 
    dayjs: ^1.11.10 => 1.11.10 
    debug:  undefined ()
    devalue:  undefined ()
    domain-browser:  undefined ()
    edge-runtime:  undefined ()
    eslint: ^8 => 8.57.0 
    eslint-config-next: 14.1.3 => 14.1.3 
    events:  undefined ()
    find-cache-dir:  undefined ()
    find-up:  undefined ()
    fresh:  undefined ()
    get-orientation:  undefined ()
    glob:  undefined ()
    gzip-size:  undefined ()
    http-proxy:  undefined ()
    http-proxy-agent:  undefined ()
    https-browserify:  undefined ()
    https-proxy-agent:  undefined ()
    icss-utils:  undefined ()
    ignore-loader:  undefined ()
    image-size:  undefined ()
    is-animated:  undefined ()
    is-docker:  undefined ()
    is-wsl:  undefined ()
    jest-worker:  undefined ()
    jotai: ^2.7.0 => 2.8.0 
    jotai-devtools: ^0.10.0 => 0.10.0 
    json5:  undefined ()
    jsonwebtoken:  undefined ()
    loader-runner:  undefined ()
    loader-utils:  undefined ()
    lodash.curry:  undefined ()
    lru-cache:  undefined ()
    micromatch:  undefined ()
    mini-css-extract-plugin:  undefined ()
    nanoid:  undefined ()
    native-url:  undefined ()
    neo-async:  undefined ()
    next: 14.1.3 => 14.1.3 
    node-fetch:  undefined ()
    node-html-parser:  undefined ()
    nookies: ^2.5.2 => 2.5.2 
    ora:  undefined ()
    os-browserify:  undefined ()
    p-limit:  undefined ()
    path-browserify:  undefined ()
    platform:  undefined ()
    postcss: ^8 => 8.4.38 (8.4.31)
    postcss-flexbugs-fixes:  undefined ()
    postcss-modules-extract-imports:  undefined ()
    postcss-modules-local-by-default:  undefined ()
    postcss-modules-scope:  undefined ()
    postcss-modules-values:  undefined ()
    postcss-preset-env:  undefined ()
    postcss-safe-parser:  undefined ()
    postcss-scss:  undefined ()
    postcss-value-parser:  undefined ()
    prettier: ^3.2.5 => 3.2.5 
    process:  undefined ()
    punycode:  undefined ()
    querystring-es3:  undefined ()
    raw-body:  undefined ()
    react: ^18 => 18.2.0 
    react-builtin:  undefined ()
    react-burger-menu: ^3.0.9 => 3.0.9 
    react-cropper: ^2.3.3 => 2.3.3 
    react-dom: ^18 => 18.2.0 (17.0.2)
    react-dom-builtin:  undefined ()
    react-dom-experimental-builtin:  undefined ()
    react-experimental-builtin:  undefined ()
    react-form-stepper: ^2.0.3 => 2.0.3 
    react-hook-form: ^7.51.0 => 7.51.2 
    react-hot-toast: ^2.4.1 => 2.4.1 
    react-is:  18.2.0 
    react-modal: ^3.16.1 => 3.16.1 
    react-refresh:  0.12.0 
    react-server-dom-turbopack-builtin:  undefined ()
    react-server-dom-turbopack-experimental-builtin:  undefined ()
    react-server-dom-webpack-builtin:  undefined ()
    react-server-dom-webpack-experimental-builtin:  undefined ()
    react-spring-bottom-sheet: ^3.4.1 => 3.4.1 
    regenerator-runtime:  0.13.4 
    sass: ^1.71.1 => 1.74.1 
    sass-loader:  undefined ()
    scheduler-builtin:  undefined ()
    scheduler-experimental-builtin:  undefined ()
    schema-utils:  undefined ()
    semver:  undefined ()
    send:  undefined ()
    server-only:  0.0.1 
    setimmediate:  undefined ()
    shell-quote:  undefined ()
    shortid: ^2.2.16 => 2.2.16 
    source-map:  undefined ()
    stacktrace-parser:  undefined ()
    stream-browserify:  undefined ()
    stream-http:  undefined ()
    string-hash:  undefined ()
    string_decoder:  undefined ()
    strip-ansi:  undefined ()
    superstruct:  undefined ()
    swiper: ^11.0.7 => 11.1.1 
    swr: ^2.2.5 => 2.2.5 
    tailwindcss: ^3.3.0 => 3.4.3 
    tar:  undefined ()
    terser:  undefined ()
    text-table:  undefined ()
    timers-browserify:  undefined ()
    tty-browserify:  undefined ()
    typescript: ^5 => 5.4.5 
    ua-parser-js:  undefined ()
    unistore:  undefined ()
    util:  undefined ()
    vm-browserify:  undefined ()
    watchpack:  undefined ()
    web-vitals:  undefined ()
    webpack:  undefined ()
    webpack-sources:  undefined ()
    ws:  undefined ()
    zod:  undefined ()
  npmGlobalPackages:
    @squoosh/cli: 0.7.3
    corepack: 0.19.0
    npm: 9.8.1
    react-devtools: 5.0.0

Describe the bug

Property total does not exist on type 'PagedList<{ __typename: "Cat"; ...'.

const response = await client.graphql({
  query: searchCats,
  variables: {
    // ...
  } satisfies SearchCatsQueryVariables,
})

response.data.searchCats?.total // Property total does not exist on type 'PagedList<{ __typename: "Cat"; ...'.

The reason is that WithListsFixed<T> removes properties that exist in T but are not included in PagedList.

? PagedList<Exclude<IT, null | undefined>, NAME>

In fact, the error disappeared after making the following changes

type WithListsFixed<T> =
  T extends PagedList<infer IT, infer NAME>
    ? PagedList<Exclude<IT, null | undefined>, NAME> &
        Exclude<T, keyof PagedList<any, any>>
    : T extends Record<string, unknown>
      ? {
          [K in keyof T]: WithListsFixed<T[K]>
        }
      : T

Expected behavior

The total property exists, so there should not be an error

Reproduction steps

  1. Generate search query (searchCats) using @searchable.
  2. Run query like const response = await client.graphql({ query: searchCats })
  3. Try to get total property on response.data.searchCats

Code Snippet

No response

Log output

No response

aws-exports.js

No response

Manual configuration

No response

Additional configuration

No response

Mobile Device

No response

Mobile Operating System

No response

Mobile Browser

No response

Mobile Browser Version

No response

Additional information and screenshots

No response

@HikaruTakakura HikaruTakakura added the pending-triage Issue is pending triage label Aug 29, 2024
@cwomack cwomack added the GraphQL Related to GraphQL API issues label Aug 29, 2024
@chrisbonifacio
Copy link
Member

Hi @HikaruTakakura can you share your schema?

@chrisbonifacio chrisbonifacio self-assigned this Aug 29, 2024
@chrisbonifacio chrisbonifacio added pending-response question General question and removed pending-triage Issue is pending triage labels Aug 29, 2024
@HikaruTakakura
Copy link
Author

@chrisbonifacio

Thank you for your prompt reply. This is my schema.

type Cat
  @model
  @searchable
  @auth(
    rules: [
      { allow: public, operations: [read, create, update, delete] }
    ]
  ) {
  id: ID!
  name: String
  about: String
  deletedAt: AWSDateTime
  updatedAt: AWSDateTime!
  createdAt: AWSDateTime!
}

@chrisbonifacio
Copy link
Member

chrisbonifacio commented Aug 30, 2024

@HikaruTakakura hmm, I don't think that we support a total field from openSearch out of the box. You may have to edit the VTL template for the resolver to set a track_total_hits parameter to true as mentioned in this feature request:

aws-amplify/amplify-category-api#1079

@HikaruTakakura
Copy link
Author

@chrisbonifacio Thanks for the information. However, the issue I am raising is not the implementation of the total field but its type.

Here is the query and its type generated by the schema shown above.

// queries.ts
export const searchCats = /* GraphQL */ `query SearchCats(
  $filter: SearchableCatFilterInput
  $sort: SearchableCatSortInput
  $limit: Int
  $nextToken: String
  $from: Int
) {
  searchCats(
    filter: $filter
    sort: $sort
    limit: $limit
    nextToken: $nextToken
    from: $from
  ) {
    items {
      // ...
    }
    nextToken
    total
    __typename
  }
}
` as GeneratedQuery<
  APITypes.SearchCatsQueryVariables,
  APITypes.SearchCatsQuery
>;
// API.ts
export type SearchCatsQuery = {
  searchCats?:  {
    __typename: "SearchableCatConnection",
    items:  Array< {
      __typename: "Cat",
      // ...
    } | null >,
    nextToken?: string | null,
    total?: number | null,
  } | null,
};

It is clear that the response to the query should contain a total field, and in fact it does return a value for that field, but it gives a type error.
As you can see in the screenshot below, it does not appear in the predictive text.

スクリーンショット 2024-08-31 17 45 29

So now we use @ts-ignore to suppress that error.

@chrisbonifacio chrisbonifacio added to-be-reproduced Used in order for Amplify to reproduce said issue and removed pending-response labels Sep 4, 2024
@chrisbonifacio
Copy link
Member

Hi @HikaruTakakura 👋 thanks for raising this issue!

I was able to get total from the return type by using the SearchCatsQuery type from API.ts like this:

import { SearchCatsQuery } from "@/src/API";
import { searchCats } from "@/src/graphql/queries";
import { GraphQLQuery } from "aws-amplify/api";

// ...
const searchCatsQuery = async () => {
  const result = await client.graphql<GraphQLQuery<SearchCatsQuery>>({
    query: searchCats,
  })

CleanShot 2024-09-06 at 12 32 17@2x

@chrisbonifacio chrisbonifacio removed the to-be-reproduced Used in order for Amplify to reproduce said issue label Sep 6, 2024
@HikaruTakakura
Copy link
Author

Hi @chrisbonifacio thank you very much.
In this case, however, the presence of the total field should be inferred without type annotation. And that can be done by the modification of WithListsFixed I first showed.
What are the problems with this modification approach?

@github-actions github-actions bot added the pending-maintainer-response Issue is pending a response from the Amplify team. label Sep 6, 2024
@chrisbonifacio
Copy link
Member

chrisbonifacio commented Sep 18, 2024

@HikaruTakakura re-opened this issue and will discuss with the team!

In the meantime, please submit a Pull Request with the proposed fix for the team to review

@github-actions github-actions bot removed the pending-maintainer-response Issue is pending a response from the Amplify team. label Sep 18, 2024
@chrisbonifacio chrisbonifacio added the pending-community-response Issue is pending a response from the author or community. label Sep 18, 2024
@chrisbonifacio
Copy link
Member

Hi @HikaruTakakura, just wanted to follow up on this.

Would you still like to submit a pull request for this?

In the meantime, I'm going to mark this as a feature request

@chrisbonifacio chrisbonifacio added feature-request Request a new feature and removed question General question labels Oct 21, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature-request Request a new feature GraphQL Related to GraphQL API issues pending-community-response Issue is pending a response from the author or community.
Projects
None yet
Development

No branches or pull requests

3 participants