aws-amplify / amplify-category-api

The AWS Amplify CLI is a toolchain for simplifying serverless web and mobile development. This plugin provides functionality for the API category, allowing for the creation and management of GraphQL and REST based backends for your amplify project.
https://docs.amplify.aws/
Apache License 2.0
89 stars 77 forks source link

Impossible to create a custom schema array #2979

Open philippeauriach opened 3 hours ago

philippeauriach commented 3 hours ago

Environment information

System:
  OS: macOS 15.0.1
  CPU: (16) arm64 Apple M3 Max
  Memory: 53.61 GB / 128.00 GB
  Shell: /bin/zsh
Binaries:
  Node: 20.17.0 - ~/.asdf/installs/nodejs/20.17.0/bin/node
  Yarn: undefined - undefined
  npm: 10.9.0 - ~/.asdf/plugins/nodejs/shims/npm
  pnpm: 9.0.6 - ~/.asdf/installs/nodejs/20.17.0/bin/pnpm
NPM Packages:
  @aws-amplify/auth-construct: 1.3.1
  @aws-amplify/backend: 1.5.1
  @aws-amplify/backend-auth: 1.2.0
  @aws-amplify/backend-cli: 1.3.0
  @aws-amplify/backend-data: 1.1.5
  @aws-amplify/backend-deployer: 1.1.5
  @aws-amplify/backend-function: 1.7.1
  @aws-amplify/backend-output-schemas: 1.4.0
  @aws-amplify/backend-output-storage: 1.1.2
  @aws-amplify/backend-secret: 1.1.4
  @aws-amplify/backend-storage: 1.2.1
  @aws-amplify/cli-core: 1.1.3
  @aws-amplify/client-config: 1.5.0
  @aws-amplify/deployed-backend-client: 1.4.1
  @aws-amplify/form-generator: 1.0.3
  @aws-amplify/model-generator: 1.0.8
  @aws-amplify/platform-core: 1.1.0
  @aws-amplify/plugin-types: 1.3.0
  @aws-amplify/sandbox: 1.2.3
  @aws-amplify/schema-generator: 1.2.4
  aws-amplify: 6.6.6
  aws-cdk: 2.162.1
  aws-cdk-lib: 2.162.1
  typescript: 5.6.3
AWS environment variables:
  AWS_STS_REGIONAL_ENDPOINTS = regional
  AWS_NODEJS_CONNECTION_REUSE_ENABLED = 1
No CDK environment variables

Describe the bug

Our goal is to have a custom query returning complex typings, and to have it generated client side. From what we understood, we have no choice but to declare the return type in the data/resources/schema.ts.

How could we declare our custom return type so that the client response is typed ? We don't need to create a model that will be stored, just a custom schema for the client to have the typings.

For now we are using

.returns(
      a.customType({
        commits: a.json().array().required(),
      }),
    )

But this leads to the response being a string, and no types, which looses the benefits of using amplify on this query.

In an ideal world we could something like

type OurCommitTypescriptType = {
    title?: string
    message: string
}

.returns(
      a.customTypescriptType<OurCommitTypescriptType>().array(),
    )

Reproduction steps

1. Non working array version

listCommits: a
    .query()
    .returns(
      a.customType({
        commits: a.customType({
            author: a.string(),
            message: a.string()
        }).array(), // <--- here .array() does not exists
      }),
    )
    .handler(a.handler.function(listCommits))

And we get

Property 'array' does not exist on type 'CustomType<{ fields: { author: ModelField<Nullable<string>, never, undefined>; message: ModelField<Nullable<string>, never, undefined>; }; }>'.ts(2339)

2. Non working .ref version

  Commit: a.customType({
    author: a.string(),
    message: a.string(),
  }),

  listCommitDiff: a
    .query()
    .returns(
      a.customType({
        commits: a.ref("Commit").array().required(),
      }),
    )

But now, in our handler we get another typescript error telling us that we can not return what we return, missing properties:

const functionHandler: Schema["listCommitDiff"]["functionHandler"] = async (
  event,
) => {
    // logic omitted for brevity
      return { commits: [{ author: "author", message: "message" }] };
}

It seems that our handler is now expecting some complex type from aws-amplify

        Types of property 'commits' are incompatible.
          Type '{ author: string; message: string; }[]' is not assignable to type 'RefType<SetTypeSubArg<SetTypeSubArg<RefTypeArgFactory<"Commit">, "array", true>, "arrayRequired", true>, "required" | "array", undefined>'.
            Type '{ author: string; message: string; }[]' is missing the following properties from type 'Omit<{ required(): RefType<SetTypeSubArg<SetTypeSubArg<SetTypeSubArg<RefTypeArgFactory<"Commit">, "array", true>, "arrayRequired", true>, "arrayRequired", true>, "required" | "array", undefined>; array(): RefType<...>; authorization<AuthRuleType extends Authorization<any, any, any>>(callback: (allow: { ...; }) => Au...': authorization, mutations
ykethan commented 3 hours ago

Hey,👋 thanks for raising this! I'm going to transfer this over to our API repository for better assistance 🙂