-
Notifications
You must be signed in to change notification settings - Fork 77
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
fix: handle Enums correctly on Typescript data schema generation #2870
base: main
Are you sure you want to change the base?
Conversation
… to fix undefined field
...fy-graphql-schema-generator/src/__tests__/__snapshots__/generate-ts-data-schema.test.ts.snap
Show resolved
Hide resolved
@@ -15,6 +15,7 @@ export class Schema { | |||
} | |||
|
|||
public addModel(model: Model): void { | |||
console.log(this.engine); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: remove this logging
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure I will remove this and add a commit
|
||
const combinedEnums = nullEnums.concat(notNullEnums).flat() // making 1 D array | ||
|
||
if (engine === 'Postgres') { // for postgresql |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For future: Instead of introducing these engine based conditionals that bloats up this method, we could move these to separate methods inside an engine specific controller.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure I will look into it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@phani-srikar I have updated the implementation to make it less bloated in the current task as well and more strongly typed.
@@ -15,6 +15,7 @@ export class Schema { | |||
} | |||
|
|||
public addModel(model: Model): void { | |||
console.log(this.engine); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this leftover from dev/debugging? Any reason a customer needs to see this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes its a leftover might have missed it I will remove it
|
||
|
||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Run yarn prettier --write .
from the top-level project dir to fix this and other linting errors before submitting.
), | ||
], | ||
); | ||
if(engine === 'Postgres'){ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looking at the code without context, it looks like we don't handle enum types for MySQL engine. Since we clearly do, let's add a comment explaining the logic about why we're doing this.
* @returns Typescript data schema type in TS Node format | ||
*/ | ||
const createEnums = (type: EnumType, engine: string, modelName: string, enumName: string): ts.Node => { | ||
if (engine === 'Postgres'){ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: since engine
is a string rather than a strongly typed value, let's make the engine handling in this method explicit and fail for unsupported engine types. That'll protect against typos in calling code. Alternately, use a strongly typed engine type to ensure we are operating on a list of values known at compile time.
const tsSchema = ts.factory.createCallExpression( | ||
ts.factory.createPropertyAccessExpression( | ||
createConfigureExpression(schema, config), | ||
ts.factory.createIdentifier(TYPESCRIPT_DATA_SCHEMA_CONSTANTS.SCHEMA_METHOD), | ||
ts.factory.createIdentifier(TYPESCRIPT_DATA_SCHEMA_CONSTANTS.SCHEMA_METHOD), // create a.schema() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
prefer to remove dead code rather than leaving it commented
ts.factory.createIdentifier(TYPESCRIPT_DATA_SCHEMA_CONSTANTS.SCHEMA_METHOD), // create a.schema() | |
ts.factory.createIdentifier(TYPESCRIPT_DATA_SCHEMA_CONSTANTS.SCHEMA_METHOD), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It isn't a dead code its a comment, but its not very necessary since it is existing code so will probably remove it
@@ -147,19 +188,92 @@ export const createSchema = (schema: Schema, config?: DataSourceGenerateConfig): | |||
throw new Error('No valid tables found. Make sure at least one table has a primary key.'); | |||
} | |||
|
|||
const engine = schema.getEngine().type; | |||
|
|||
const nullEnums = schema // find null enums in all models |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
naming nit: I think you mean "nullable enum fields" or rather than "null" enums? (The latter implies a concrete value assignment, as opposed to a field type constraint)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I will update the naming to have more clear variable names to avoid confusion. NullEnumFields and RequiredEnumFields makes sense I will go ahead with these naming conventions to provide more readability and understanding
} | ||
})); | ||
|
||
const notNullEnums = schema // find Non null enums in all models |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
naming nit: I think you mean "required" enums or "non null enum types"?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I will update the naming to have more clear variable names to avoid confusion.
@@ -190,33 +195,35 @@ export const createSchema = (schema: Schema, config?: DataSourceGenerateConfig): | |||
|
|||
const engine = schema.getEngine().type; | |||
|
|||
const nullEnums = schema // find null enums in all models | |||
const nullEnumFields = schema // find null enum fields in all models |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit
const nullEnumFields = schema // find null enum fields in all models | |
const nullableEnumFields = schema |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
addressed it
|
||
const notNullEnums = schema // find Non null enums in all models | ||
const RequiredEnumFields = schema // find required enum fields in all models |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: don't PascalCase non-type, non-Class variables.
const RequiredEnumFields = schema // find required enum fields in all models | |
const requiredEnumFields = schema |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
for postgresql since enums are declared globally to void declaring duplicate enums we | ||
declare find unique enums and then pass it to the schema |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can't tell what you mean with this explanation. Can you reword to clarify? (I mean to say, based on our discussion and reading through the code, I know what you're trying to do--it's the comment wording that is unclear.)
Also, nit: reserve the double-asterisk block comment structure (/** ... */
for docComments (such as we put at the beginning of an exported symbol). Other comments should be delimited with a double-slash (//
)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure I will re word this and and remove the double-asterisk block structure
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added appropriate comment structure and comments to explain in brief the use case
@@ -1,6 +1,7 @@ | |||
import * as ts from 'typescript'; | |||
import { Schema } from '../schema-representation'; | |||
import { createImportExpression, createSchema, DataSourceGenerateConfig } from './helpers'; | |||
import { LogFormat } from '@aws-sdk/client-lambda'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: Are you using this somewhere since there are no other changes in this file.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removed it
let enumName = enumNamePrefix; | ||
let counter = 0; | ||
while (this.enums.has(enumName)) { | ||
enumName = [enumNamePrefix, counter.toString()].join('_'); | ||
enumName = toPascalCase([enumNamePrefix, counter.toString()]); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you confirm this wouldn't be a breaking change if we change the naming of enums from table_field
to TableField
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As per the discussion @palpatim the change could affect customers only if they reimport the schema which is highly unlikely, but we still are waiting for conformation from Josef on the same
.map((field) => { | ||
if (field.type.kind === 'NonNull' && field.type.type.kind === 'Enum') { | ||
return createEnums(field.type.type); | ||
} else { | ||
return undefined; | ||
} | ||
}), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is checking field.type.kind
and field.type.type.kind
redundant because of the filter?
.map((field) => { | |
if (field.type.kind === 'NonNull' && field.type.type.kind === 'Enum') { | |
return createEnums(field.type.type); | |
} else { | |
return undefined; | |
} | |
}), | |
.map((field) => createEnums(field.type.type)) |
…y-api into Handle-enums-sql
Description of changes
This change would only affect an existing customer only if they re import the schema which is highly unlikely so we have determined this change to be a non breaking change.
CDK / CloudFormation Parameters Changed
Issue #, if available
#2596
Description of how you validated changes
Checklist
yarn test
passesBy submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.