amplify-codegen icon indicating copy to clipboard operation
amplify-codegen copied to clipboard

Generated queries in TypeScript do not compile with ESM

Open dpilch opened this issue 1 year ago • 2 comments

Before opening, please confirm:

  • [X] I have installed the latest version of the Amplify CLI (see above), and confirmed that the issue still persists.
  • [X] I have searched for duplicate or closed issues.
  • [X] I have read the guide for submitting bug reports.
  • [X] I have done my best to include a minimal, self-contained set of instructions for consistently reproducing the issue.

How did you install the Amplify CLI?

npm

If applicable, what version of Node.js are you using?

v18.8.0

Amplify CLI Version

12.6.0

What operating system are you using?

Mac

Amplify Codegen Command

codegen statements

Describe the bug

When generating GraphQL queries with TypeScript the types import does not use correct module resolution for ESM.

src/graphql/mutations.ts:5:27 - error TS2835: Relative import paths need explicit file extensions in EcmaScript imports when '--moduleResolution' is 'node16' or 'nodenext'. Did you mean '../API.js'?

5 import * as APITypes from "../API";
                            ~~~~~~~~

src/graphql/queries.ts:5:27 - error TS2835: Relative import paths need explicit file extensions in EcmaScript imports when '--moduleResolution' is 'node16' or 'nodenext'. Did you mean '../API.js'?

5 import * as APITypes from "../API";
                            ~~~~~~~~

src/graphql/subscriptions.ts:5:27 - error TS2835: Relative import paths need explicit file extensions in EcmaScript imports when '--moduleResolution' is 'node16' or 'nodenext'. Did you mean '../API.js'?

5 import * as APITypes from "../API";
                            ~~~~~~~~

See for additional details: https://github.com/dpilch/codegen-esm-error

Expected behavior

The imports should have .js when using ESM.

Reproduction steps

See sample app here: https://github.com/dpilch/codegen-esm-error

GraphQL schema(s)

Any GraphQL schema will have this issue.

Log output

# Put your logs below this line
src/graphql/mutations.ts:5:27 - error TS2835: Relative import paths need explicit file extensions in EcmaScript imports when '--moduleResolution' is 'node16' or 'nodenext'. Did you mean '../API.js'?

5 import * as APITypes from "../API";
                            ~~~~~~~~

src/graphql/queries.ts:5:27 - error TS2835: Relative import paths need explicit file extensions in EcmaScript imports when '--moduleResolution' is 'node16' or 'nodenext'. Did you mean '../API.js'?

5 import * as APITypes from "../API";
                            ~~~~~~~~

src/graphql/subscriptions.ts:5:27 - error TS2835: Relative import paths need explicit file extensions in EcmaScript imports when '--moduleResolution' is 'node16' or 'nodenext'. Did you mean '../API.js'?

5 import * as APITypes from "../API";
                            ~~~~~~~~

Additional information

We will likely need to add a new codegen configuration for this option (such as moduleResolution).

dpilch avatar Oct 12 '23 15:10 dpilch

Actually seems to be a larger issue of getting a similar error when trying to get any non-existent item from:

{
    "errorType": "TypeError",
    "errorMessage": "Cannot read properties of null (reading 'id')",
    "stack": [
        "TypeError: Cannot read properties of null (reading 'id')",
        "    at file:///var/task/index.mjs:47136:45",
        "    at Array.map (<anonymous>)",
        "    at file:///var/task/index.mjs:47134:50",
        "    at Array.map (<anonymous>)",
        "    at initializeModel (file:///var/task/index.mjs:47035:17)",
        "    at _get (file:///var/task/index.mjs:47690:31)",
        "    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)",
        "    at async getPlayerCharacterRelationship (file:///var/task/index.mjs:55787:42)",
        "    at async processMessages (file:///var/task/index.mjs:56154:15)",
        "    at async SpeechCompletion_default (file:///var/task/index.mjs:56194:7)"
    ]
}

I would expect it to fail gracefully by returning { data: null | {}, errors: {...} }

AakashKB avatar Apr 04 '24 03:04 AakashKB

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

ykethan avatar Apr 04 '24 14:04 ykethan

Any update on this?

AakashKB avatar Apr 25 '24 16:04 AakashKB

I am also experiencing this, weirdly enough it occurs on some models and not others

AnaCoda avatar May 08 '24 02:05 AnaCoda

Hi @AakashKB,

It looks like you're using the preview version of the libraries. In addition to bug fixes around relationship management, the GA data modeling experience has changed a bit since preview. You can see the new interface in the "Modeling relationships" documentation. When you read through this, pay close attention to the changes in modeling signatures and how they work with reference fields.

In your example, the hasOne() from PlayerCharacterRelationship would create a reference field on Conversation. This hasOne() also requires an associated belongsTo() to exist on Conversation. Grossly simplifying your schema, that might give us something like this:

const schema = a
  .schema({
    PlayerCharacterRelationship: a.model({
      lastConversation: a.hasOne("Conversation", "pcLastConversationId"),
    }),
    Conversation: a.model({
      pcLastConversationId: a.id(),
      playerCharacter: a.belongsTo("PlayerCharacterRelationship", "pcLastConversationId"),
    }),
  })
  // Auth is only simplified here for my own manual testing
  .authorization((allow) => [allow.publicApiKey()]);

If it helps your understanding, the lastConversation property is effectively loaded by listing the Conversation table with a filter under the hood like this:

client.models.Conversation.list({
  filter: {
    pcLastConversationId: { eq: theParentCharacterRelationship.id }
  }
});

In terms of getting your application up to date, you'd be looking at making these package upgrades:

  @aws-amplify/backend: 0.13.0-beta.14 --> 1.0.3
  @aws-amplify/backend-cli: 0.12.0-beta.16 --> 1.0.4
  aws-amplify: 6.0.20 --> 6.3.7

When you make these upgrade, I'd recommend cleaning out your node_modules and package/yarn lock files to ensure you don't end up with duplicate dependencies. In particular, if you end up with duplicate/nested dependencies on @aws-amplify/data-schema or @aws-amplify/data-schema-types, typescript won't be able to make sense of your ClientSchema or the resulting client from generateClient<Schema>().

svidgen avatar Jun 19 '24 17:06 svidgen

Since this bug pertains to the preview/beta versions of the libraries and the GA versions of gen2 is out now, I'm going to go ahead and close this issue.

svidgen avatar Jun 19 '24 17:06 svidgen

This issue is now closed. Comments on closed issues are hard for our team to see. If you need more assistance, please open a new issue that references this one.

github-actions[bot] avatar Jun 19 '24 17:06 github-actions[bot]