sst / sst

SST v2
https://v2.sst.dev
MIT License
21.5k stars 1.63k forks source link

RDS migration type file only generated when using mysql engine #2813

Open geauser opened 1 year ago

geauser commented 1 year ago

If you create a new project with the graphql/rds template

npx create-sst@latest --template=graphql/rds

And use engine: "postgresql10.14" or engine: "postgresql11.13" in the RDS config, sql.generated.ts will not be generated upon migration, however using engine: "mysql5.7" seems to not cause any issues.

This is what I get in debug.log when running a migration with one of the postgresql engine

[debug] [kysely-codegen] {"name":"BadRequestException","$fault":"client","$metadata":{"httpStatusCode":400,

bjornlll commented 1 year ago

Not sure if related but I am currently battling a similar error.

export const DB = new Kysely<Database>({
  plugins: [new CamelCasePlugin()],
  log: JSON.parse(Config.SQL_LOGGING_LEVELS),
  // 👇👇👇 Triggers the TS error, below
  dialect: new DataApiDialect({
    mode: "postgres",
    driver: {
      secretArn: RDS.db.secretArn,
      resourceArn: RDS.db.clusterArn,
      database: RDS.db.defaultDatabaseName,
      client: new RDSData({ region: Config.REGION }),
    },
  }),
});

Of particular interest could be Types of property 'acquireMigrationLock' are incompatible.. Will let you know @geauser if I find out what's causing this. Next thing I'll try is to downgrade Kysely and see if that helps.

No overload matches this call.
  Overload 1 of 2, '(args: KyselyConfig): Kysely<Database>', gave the following error.
    Type 'DataApiDialect' is not assignable to type 'Dialect'.
      The types returned by 'createAdapter()' are incompatible between these types.
        Type 'PostgresAdapter | MysqlAdapter' is not assignable to type 'DialectAdapter'.
          Type 'PostgresAdapter' is not assignable to type 'DialectAdapter'.
            Types of property 'acquireMigrationLock' are incompatible.
              Type '(db: Kysely<any>) => Promise<void>' is not assignable to type '(db: Kysely<any>, options: MigrationLockOptions) => Promise<void>'.
                Types of parameters 'db' and 'db' are incompatible.
                  Type 'import("/Users/bjorn/Projects/seaboard/seaboard-backend-v2/services/node_modules/kysely/dist/cjs/kysely").Kysely<any>' is not assignable to type 'import("/Users/bjorn/Projects/seaboard/seaboard-backend-v2/node_modules/kysely/dist/cjs/kysely").Kysely<any>'.
                    Property '#private' in type 'Kysely' refers to a different member that cannot be accessed from within type 'Kysely'.
  Overload 2 of 2, '(args: KyselyProps): Kysely<Database>', gave the following error.
    Type 'DataApiDialect' is not assignable to type 'Dialect'.ts(2769)
kysely.d.ts(371, 14): The expected type comes from property 'dialect' which is declared here on type 'KyselyConfig'
kysely.d.ts(367, 14): The expected type comes from property 'dialect' which is declared here on type 'KyselyProps
bjornlll commented 1 year ago

It looks like koskimas added an argument to acquireMigrationLock() 3 months ago: https://github.com/kysely-org/kysely/commit/fbcf3e3853e6e466fc7e93ce0294d6da32554a14

What's really bizarre is that kysely is a peer dep in kysely-data-api. The PostgresAdapter and MySQLAdapter used, that have the interface responsible for my type error, is taken directly from Kysely. So it's basically complaining that a class/interface in its own package isn't satisfying an interface. Confusing.

I'm probably completely on the wrong track here. Just sharing what I've observed. Tried downgrading kysely - didn't help.

Edit: kysely's Postgres adapter isn't implementing the acquireMigrationLock() according to the interface: https://github.com/kysely-org/kysely/blob/master/src/dialect/postgres/postgres-adapter.ts

koskimas commented 1 year ago

A function property with less arguments than the interface does implement the interface in typescript. It's the same as not using the last argument.

https://www.typescriptlang.org/play?#code/JYOwLgpgTgZghgYwgAgJLIN4FgBQzkwAUcAXMgM5hSgDmANMgEZmMD2rANhHCAJRkA3VsAAmuAL65cCViErIAHmXQBeTLnxFSFKrV7q8+ZDLmcIAOg6saxXhuSSc4oA

Property '#private' in type 'Kysely' refers to a different member that cannot be accessed from within type 'Kysely'

This implies that you have two versions of Kysely. Some stuff comes from kysely#1 and some stuff from kysely#2. Two classes that have private properties can't be assigned to each other even if they have the same public interface:

https://www.typescriptlang.org/play?#code/MYGwhgzhAECC0G8CwAoa0DEYBc0IBcAnASwDsBzVVdYAe1IMIFdh9bCAKHPIs8gSkTV00fAAtiEAHRZoAXmhhhAX1SqUqUJBgAhIWkzdGfKgboMiLNpyO8Kg5AfTjJMsPMUq1p8wUW54BVIAUwB3aB0OACIxYJAQWij+IA

in your case one class comes from kysely#1 and the other from kysely#2. Even though they have the exact same stuff in them, they are two distinct classes since they come from two different modules.

The error even tells you the locations of the two kysely modules: /Users/bjorn/Projects/seaboard/seaboard-backend-v2/node_modules/kysely/dist/cjs/kysely /Users/bjorn/Projects/seaboard/seaboard-backend-v2/services/node_modules/kysely/dist/cjs/kysely

jayair commented 1 year ago

Please open a new thread in #help on Discord.

bjornlll commented 1 year ago

Thank you @koskimas ❤️ that's super helpful. Really really. Most people wouldn't take the time to root cause diagnose, thoughtfully reply and educate the way you just did now. Much appreciated!

@jayair - will open a new thread. First, will add some context below that could help tracking down the conflicting versions/installs of kysely.

I have a monorepo setup with two packages:

Within kysely-data-api, kysely 0.x is listed as a peer dependency. I'm not super familiar with how NPM works, but to my understanding that means that kysely-data-api will not install its own version but rely and demand on one provided by the package.

If kysely-data-api is not the culprit responsible for the 2 parallel versions, the other packages I'd turn my attention to would be kysely-codegen (which is, I assume, used within SST) and sst (that may have some kysely dep somewhere).

Including complete list of deps here for my two packages, if it helps anyone:

 // package.json
  "devDependencies": {
    "@seed-run/cli": "^0.1.2",
    "@semantic-release/changelog": "^6.0.3",
    "@semantic-release/git": "^10.0.1",
    "@semantic-release/npm": "^10.0.3",
    "@tsconfig/node18": "^1.0.2",
    "@typescript-eslint/eslint-plugin": "^5.59.0",
    "@typescript-eslint/parser": "^5.59.0",
    "aws-cdk-lib": "2.72.1",
    "constructs": "10.1.156",
    "conventional-changelog-conventionalcommits": "^5.0.0",
    "eslint": "^8.38.0",
    "hygen": "^6.2.11",
    "prettier": "^2.8.7",
    "semantic-release": "^21.0.1",
    "sst": "2.7.2",
    "typescript": "^5.0.4",
    "vitest": "^0.30.1"
  }

 // services/package.json
 "dependencies": {
    "@aws-sdk/client-rds-data": "^3.321.1",
    "@casl/ability": "^6.4.0",
    "@middy/core": "^4.3.1",
    "@middy/http-header-normalizer": "^4.3.1",
    "@middy/http-json-body-parser": "^4.3.1",
    "@middy/http-multipart-body-parser": "^4.3.1",
    "@middy/http-response-serializer": "^4.3.1",
    "aws-sdk": "^2.1360.0",
    "change-case": "^4.1.2",
    "exponential-backoff": "^3.1.1",
    "fast-jwt": "^2.2.1",
    "kysely": "^0.24.2",
    "kysely-data-api": "^0.2.0",
    "lodash": "^4.17.21",
    "node-fetch": "^3.3.0",
    "nodemailer": "^6.9.1",
    "papaparse": "^5.4.1",
    "postmark": "^3.0.15",
    "uuid": "^9.0.0",
    "zod": "^3.21.4"
  },
  "devDependencies": {
    "@faker-js/faker": "^7.6.0",
    "@tsconfig/node18": "^1.0.2",
    "@types/aws-lambda": "^8.10.114",
    "@types/ejs": "^3.1.2",
    "@types/lodash": "^4.14.194",
    "@types/nodemailer": "^6.4.7",
    "@types/papaparse": "^5.3.7",
    "@types/uuid": "^9.0.1",
    "sst": "2.7.2"
  }

Edit: koskimas praise