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

"A type annotation is necessary" for auth and schema. #496

Open
Gsciarra opened this issue Jul 17, 2024 · 18 comments
Open

"A type annotation is necessary" for auth and schema. #496

Gsciarra opened this issue Jul 17, 2024 · 18 comments
Assignees
Labels
bug Something isn't working

Comments

@Gsciarra
Copy link

Environment information

System:
  OS: macOS 14.5
  CPU: (16) x64 Intel(R) Core(TM) i9-9980HK CPU @ 2.40GHz
  Memory: 6.91 GB / 32.00 GB
  Shell: /bin/zsh
Binaries:
  Node: 20.15.1 - ~/.nvm/versions/node/v20.15.1/bin/node
  Yarn: undefined - undefined
  npm: 10.7.0 - ~/.nvm/versions/node/v20.15.1/bin/npm
  pnpm: 9.4.0 - ~/Library/pnpm/pnpm
NPM Packages:
  @aws-amplify/backend: 1.0.4
  @aws-amplify/backend-cli: 1.1.1
  aws-amplify: 6.4.0
  aws-cdk: 2.149.0
  aws-cdk-lib: 2.149.0
  typescript: 5.3.3
AWS environment variables:
  AWS_STS_REGIONAL_ENDPOINTS = regional
  AWS_NODEJS_CONNECTION_REUSE_ENABLED = 1
  AWS_SDK_LOAD_CONFIG = 1
No CDK environment variables

Description

To reproduce:

pnpx create-turbo@latest
# ? Where would you like to create your Turborepo? ./example
# ? Which package manager do you want to use? pnpm
cd example/apps/web
pnpm create amplify@latest
#? Where should we create your project? .
pnpm run build

You will get:

./amplify/auth/resource.ts:7:14
Type error: The inferred type of 'auth' cannot be named without a reference to '.pnpm/@[email protected]_@[email protected][email protected][email protected]__swdgfxo5jm6atwmthef7zzd4ly/node_modules/@aws-amplify/backend-auth'. This is likely not portable. A type annotation is necessary.

   5 |  * @see https://docs.amplify.aws/gen2/build-a-backend/auth
   6 |  */
>  7 | export const auth = defineAuth({
     |              ^
   8 |   loginWith: {
   9 |     email: true,
  10 |   },

You can "fix" this with export const auth: ReturnType<typeof defineAuth> = defineAuth({, and then you will end up with

./amplify/data/resource.ts:9:7
Type error: The inferred type of 'schema' cannot be named without a reference to '../../../../node_modules/.pnpm/@[email protected]/node_modules/@aws-amplify/data-schema/dist/esm/Authorization'. This is likely not portable. A type annotation is necessary.

   7 | and "delete" any "Todo" records.
   8 | =========================================================================*/
>  9 | const schema = a.schema({
     |       ^
  10 |   Todo: a
  11 |     .model({
  12 |       content: a.string(),
 ELIFECYCLE  Command failed with exit code 1.
@ykethan
Copy link
Member

ykethan commented Jul 19, 2024

Hey @Gsciarra, thank you for reaching out. I was able to reproduce the issue, marking as bug.

@chrisl777
Copy link

I ran into this issue as well. I would like to add type annotation to the schema const, but I can't figure out which type definition to use, and I'm not sure a definition is exported anyway.

It seems like it could be:

import { type DerivedModelSchema } from "@aws-amplify/data-schema-types"

const schema: DerivedModelSchema = a.schema({...})

But then I run into an issue on this line:

export type Schema = ClientSchema<typeof schema>;
Type 'DerivedModelSchema' does not satisfy the constraint 'GenericModelSchema<any> | CombinedModelSchema<any>'.
  Type 'DerivedModelSchema' is not assignable to type 'GenericModelSchema<any>'.
    Property 'models' is missing in type 'DerivedModelSchema' but required in type 'BaseSchema<any, false>'.ts(2344)
ModelSchema.d.ts(39, 5): 'models' is declared here.

@mpetersen910
Copy link

mpetersen910 commented Aug 26, 2024

Running into the same issue, not following:

`
import { type ClientSchema, a, defineData } from "@aws-amplify/backend";
import { postConfirmation } from "../auth/post-confirmation/resource";

const schema = a
.schema({
UserProfile: a
.model({
email: a.string(),
profileOwner: a.string(),
})
.authorization((allow) => [
allow.ownerDefinedIn("profileOwner"),
]),
})
.authorization((allow) => [allow.resource(postConfirmation)]);
export type Schema = ClientSchema;

export const data = defineData({
schema,
authorizationModes: {
defaultAuthorizationMode: "apiKey",
apiKeyAuthorizationMode: {
expiresInDays: 30,
},
},
}
);`

--error later in amplify cli
in)
$ amplify codegen add --apiId hpnak7nalvekhc6lvlqhuj2eua --region us-east-1 --debug
? Choose the type of app that you're building javascript
? What javascript framework are you using react
√ Getting API details
? Choose the code generation language target typescript
? Enter the file name pattern of graphql queries, mutations and subscriptions sr
c\graphql***.ts
? Do you want to generate/update all possible GraphQL operations - queries, muta
tions and subscriptions Yes
? Enter maximum statement depth [increase from default if your schema is deeply
nested] 2
? Enter the file name for the generated code src/API.ts
? Do you want to generate code for your newly created GraphQL API Yes
× Downloading schema failed
errors=[InvalidSyntaxError{ message=Invalid Syntax ,locations=[SourceLocation{line=1, column=0}]}]

@ylli2000
Copy link

ylli2000 commented Sep 10, 2024

I found a working version after looking back at my git repo. I've frozen these relevant packages to their exact versions. You won't like this:

(my package.json)

"dependencies": {
    "aws-amplify": "6.6.0",
...
"devDependencies": {
    "typescript": "5.5.4",
    "@aws-amplify/backend": "1.2.1",
    "@aws-amplify/backend-cli": "1.2.5",
    "@types/aws-lambda": "8.10.145",
    "@types/node": "20.11.6",
    "aws-cdk": "2",
    "aws-cdk-lib": "2",
...

It is far from ideal but it seems to bypass the Amplify backend type errors in my project for now.

@chrisl777
Copy link

chrisl777 commented Sep 25, 2024

In my case, I'd like to create a client wrapper that I can use inside a monorepo.

In packages/backend I have a file that includes the client that I want to export so other packages can use it:

import { generateClient } from 'aws-amplify/data';
import { type Schema } from '@/amplify/data/resource'; 
const client = generateClient<Schema>();
class MyAPI {
  async listUsers() {
    const data = async client.models.User.list()
    return data 
  }
}
export default MyAPI 

It's a simplified example. But ideally, we'd wrap the API code, so that we can re-use it for mobile, web and Lambdas, so we don't have to keep rewriting the fetching code, and it protects us against future changes to the API methods.

In this simplified example, a client would use:

import { MyAPI } from "@myCompany/backend" 

const myAPI = new MyAPI()
const users = await myAPI.listUsers() 

However, in the above export, I get the same "A type annotation is necessary" message. In our case, we have a combined schema of a Postgres and DynamoDB, but I get a similar message for just the DynamoDB-related schema (see the last three lines):

amplify/data/resource.ts(85,7): error TS2742: The inferred type of 'combinedSchema' cannot be named without a reference to '../../../../node_modules/@aws-amplify/data-schema/dist/esm/Authorization'. This is likely not portable. A type annotation is necessary.
amplify/data/resource.ts(85,7): error TS2742: The inferred type of 'combinedSchema' cannot be named without a reference to '../../../../node_modules/@aws-amplify/data-schema/dist/esm/CombineSchema'. This is likely not portable. A type annotation is necessary.
amplify/data/resource.ts(85,7): error TS2742: The inferred type of 'combinedSchema' cannot be named without a reference to '../../../../node_modules/@aws-amplify/data-schema/dist/esm/EnumType'. This is likely not portable. A type annotation is necessary.
amplify/data/resource.ts(85,7): error TS2742: The inferred type of 'combinedSchema' cannot be named without a reference to '../../../../node_modules/@aws-amplify/data-schema/dist/esm/ModelField'. This is likely not portable. A type annotation is necessary.
amplify/data/resource.ts(85,7): error TS2742: The inferred type of 'combinedSchema' cannot be named without a reference to '../../../../node_modules/@aws-amplify/data-schema/dist/esm/ModelSchema'. This is likely not portable. A type annotation is necessary.
amplify/data/resource.ts(85,7): error TS2742: The inferred type of 'combinedSchema' cannot be named without a reference to '../../../../node_modules/@aws-amplify/data-schema/dist/esm/ModelType'. This is likely not portable. A type annotation is necessary.
amplify/data/schema.sql.ts(7,14): error TS2742: The inferred type of 'schema' cannot be named without a reference to '../../../../node_modules/@aws-amplify/data-schema/dist/esm/ModelField'. This is likely not portable. A type annotation is necessary.
amplify/data/schema.sql.ts(7,14): error TS2742: The inferred type of 'schema' cannot be named without a reference to '../../../../node_modules/@aws-amplify/data-schema/dist/esm/ModelSchema'. This is likely not portable. A type annotation is necessary.
amplify/data/schema.sql.ts(7,14): error TS2742: The inferred type of 'schema' cannot be named without a reference to '../../../../node_modules/@aws-amplify/data-schema/dist/esm/ModelType'. This is likely not portable. A type annotation is necessary.

@stocaaro
Copy link
Member

stocaaro commented Oct 7, 2024

A new version of the schema builder (@aws-amplify/data-schema version 1.10.0) was released this morning that exposes many of the types discussed in this issue.

@chrisl777, This release didn't include CombineSchema, so I would expect to see your errors drop to this one line with the update. Can you confirm and let me know if there are any other issues left with your schema?

If possible, could you provide a minimal schema that replicates the problem so I can include it in our tests to ensure we protect for your use-case?

Thanks,
Aaron

@stocaaro stocaaro self-assigned this Oct 7, 2024
@chrisl777
Copy link

chrisl777 commented Oct 8, 2024

@stocaaro I'll try my export of the client again.

In the meantime, after updating to 1.10.0, I see an error for my sqlSchema on this line:

const combinedSchema = a.combine([schema, sqlSchema]);

Type 'RDSModelSchema<{ types: { active_storage_attachments: ModelType<SetTypeSubArg<{ fields: { id: ModelField<number, "required", undefined>; name: ModelField<string, "required", undefined>; record_type: ModelField<...>; record_id: ModelField<...>; blob_id: ModelField<...>; created_at: ModelField<...>; }; identifier: Mod...' is not assignable to type 'GenericModelSchema<any>'.

...

Property '[brandSymbol]' is missing in type 'GenericModelSchema<any>' but required in type 'Brand<"DDBSchema" | "RDSSchema">'

^ I've filed this issue as aws-amplify/amplify-category-api#2934.

@chrisl777
Copy link

@stocaaro I'm still seeing the same error message:

amplify/data/resource.ts(19,7): error TS2742: The inferred type of 'schema' cannot be named without a reference to '../../../../node_modules/@aws-amplify/backend/node_modules/@aws-amplify/data-schema/dist/esm/Authorization'. This is likely not portable. A type annotation is necessary.
amplify/data/resource.ts(19,7): error TS2742: The inferred type of 'schema' cannot be named without a reference to '../../../../node_modules/@aws-amplify/backend/node_modules/@aws-amplify/data-schema/dist/esm/CustomType'. This is likely not portable. A type annotation is necessary.
amplify/data/resource.ts(19,7): error TS2742: The inferred type of 'schema' cannot be named without a reference to '../../../../node_modules/@aws-amplify/backend/node_modules/@aws-amplify/data-schema/dist/esm/EnumType'. This is likely not portable. A type annotation is necessary.
amplify/data/resource.ts(19,7): error TS2742: The inferred type of 'schema' cannot be named without a reference to '../../../../node_modules/@aws-amplify/backend/node_modules/@aws-amplify/data-schema/dist/esm/ModelField'. This is likely not portable. A type annotation is necessary.
amplify/data/resource.ts(19,7): error TS2742: The inferred type of 'schema' cannot be named without a reference to '../../../../node_modules/@aws-amplify/backend/node_modules/@aws-amplify/data-schema/dist/esm/ModelRelationalField'. This is likely not portable. A type annotation is necessary.
amplify/data/resource.ts(19,7): error TS2742: The inferred type of 'schema' cannot be named without a reference to '../../../../node_modules/@aws-amplify/backend/node_modules/@aws-amplify/data-schema/dist/esm/ModelSchema'. This is likely not portable. A type annotation is necessary.
amplify/data/resource.ts(19,7): error TS2742: The inferred type of 'schema' cannot be named without a reference to '../../../../node_modules/@aws-amplify/backend/node_modules/@aws-amplify/data-schema/dist/esm/ModelType'. This is likely not portable. A type annotation is necessary.
amplify/data/resource.ts(19,7): error TS2742: The inferred type of 'schema' cannot be named without a reference to '../../../../node_modules/@aws-amplify/backend/node_modules/@aws-amplify/data-schema/dist/esm/RefType'. This is likely not portable. A type annotation is necessary.
amplify/data/schema.sql.ts(7,14): error TS2742: The inferred type of 'schema' cannot be named without a reference to '../../../../node_modules/@aws-amplify/data-schema/dist/esm/ModelSchema'. This is likely not portable. A type annotation is necessary.

@stocaaro
Copy link
Member

stocaaro commented Oct 9, 2024

Thats unexpected. Can you confirm that @aws-amplify/[email protected] is installed?
This should be visible by running either npm ls @aws-amplify/data-schema or yarn list @aws-amplify/data-schema or inspecting your lock file.

If its easy to reproduce, it would be helpful to have an example app with the problem to inspect.

@chrisl777
Copy link

@stocaaro Here's that output:

% yarn list @aws-amplify/data-schema  
yarn list v1.22.22
warning Filtering by arguments is deprecated. Please use the pattern option instead.
├─ @aws-amplify/[email protected]
│  └─ @aws-amplify/[email protected]
├─ @aws-amplify/[email protected]
│  └─ @aws-amplify/[email protected]
└─ @aws-amplify/[email protected]

I wish I could get an example app up, but that would likely take me a bit of time that I don't have at the moment.

@stocaaro
Copy link
Member

stocaaro commented Oct 9, 2024

Thanks and understood. Worth asking just in case you where working with a sample app that is easily published.

@chrisl777
Copy link

@stocaaro So, I ended up deleting node_modules and yarn.lock, and reinstalling:

% yarn list @aws-amplify/data-schema
yarn list v1.22.22
warning Filtering by arguments is deprecated. Please use the pattern option instead.
└─ @aws-amplify/[email protected]
✨  Done in 0.47s.

I still get my error when trying to build my packages/backend to share with the rest of my monorepo:

amplify/data/resource.ts(19,7): error TS2742: The inferred type of 'schema' cannot be named without a reference to '../../../../node_modules/@aws-amplify/data-schema/dist/esm/Authorization'. This is likely not portable. A type annotation is necessary.
amplify/data/schema.sql.ts(7,14): error TS2742: The inferred type of 'schema' cannot be named without a reference to '../../../../node_modules/@aws-amplify/data-schema/dist/esm/ModelSchema'. This is likely not portable. A type annotation is necessary.

However, I do have a workaround, in that I can use just-in-time compilation by adding a ./schema entry to my package.json file:

"exports": {
    ".": {
      "types": "./dist/index.d.ts",
      "require": "./dist/index.cjs",
      "import": "./dist/index.js"
    },
    "./schema": "./amplify/data/resource.ts"
  },

And then in my app, I can import it like:

import type { Schema } from "@myCompany/backend/schema";

@chrisl777
Copy link

I'm still seeing this issue above

The inferred type of 'schema' cannot be named without a reference to...

And when I combine the schemas:

The inferred type of 'combinedSchema' cannot be named without a reference to...

@stocaaro
Copy link
Member

stocaaro commented Nov 8, 2024

Hi @chrisl777,

There is an update in the works that is expected to fix this error. Expect an update next week.

Thanks,
Aaron

@zxl629
Copy link
Contributor

zxl629 commented Nov 12, 2024

Hi @chrisl777 ,

Thank you for bringing up the issue! A new version of the schema builder (@aws-amplify/data-schema version 1.13.2) was released and a.combine behavior now works with declaration file. Let me know if this change doesn't resolve all of the issues you have been seeing!

Thanks,
Jack

@chrisl777
Copy link

@stocaaro @zxl629 I am seeing this issue currently, though slightly different output than before:

error TS2742: The inferred type of 'combinedSchema' cannot be named without a reference to '../../../../node_modules/@aws-amplify/data-schema/dist/esm/util'. This is likely not portable. A type annotation is necessary.

@stocaaro
Copy link
Member

@chrisl777,

Interesting. Do you have a sample of the schema definition code in your application that is causing this error? We're building up tests from these examples to ensure when we fix them they stay fixed.

Thanks!
Aaron

@stocaaro stocaaro reopened this Jan 10, 2025
@stocaaro
Copy link
Member

Reopening while we look at the error @chrisl777 posted.

@stocaaro stocaaro transferred this issue from aws-amplify/amplify-backend Jan 10, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

7 participants