Browse Source

fix(cli): Improve type generation for interfaces & gql types

Michael Bromley 1 year ago
parent
commit
f26a0bf438

+ 54 - 1
packages/cli/src/commands/add/api-extension/add-api-extension.ts

@@ -422,6 +422,23 @@ function createCrudApiExtension(project: Project, plugin: VendurePluginRef, serv
                     const entityRef = serviceRef.crudEntityRef;
                     if (entityRef) {
                         writer.indent(() => {
+                            if (entityRef.isTranslatable()) {
+                                const translationClass = entityRef.getTranslationClass();
+                                if (translationClass) {
+                                    writer.writeLine(`  type ${translationClass.getName() ?? ''} {`);
+                                    writer.writeLine(`    id: ID!`);
+                                    writer.writeLine(`    createdAt: DateTime!`);
+                                    writer.writeLine(`    updatedAt: DateTime!`);
+                                    writer.writeLine(`    languageCode: LanguageCode!`);
+                                    for (const { name, type, nullable } of entityRef.getProps()) {
+                                        if (type.getText().includes('LocaleString')) {
+                                            writer.writeLine(`    ${name}: String${nullable ? '' : '!'}`);
+                                        }
+                                    }
+                                    writer.writeLine(`  }`);
+                                    writer.newLine();
+                                }
+                            }
                             writer.writeLine(`  type ${entityRef.name} implements Node {`);
                             writer.writeLine(`    id: ID!`);
                             writer.writeLine(`    createdAt: DateTime!`);
@@ -432,6 +449,11 @@ function createCrudApiExtension(project: Project, plugin: VendurePluginRef, serv
                                     writer.writeLine(`    ${name}: ${graphQlType}${nullable ? '' : '!'}`);
                                 }
                             }
+                            if (entityRef.isTranslatable()) {
+                                writer.writeLine(
+                                    `    translations: [${entityRef.getTranslationClass()?.getName() ?? ''}!]!`,
+                                );
+                            }
                             writer.writeLine(`  }`);
                             writer.newLine();
 
@@ -460,6 +482,24 @@ function createCrudApiExtension(project: Project, plugin: VendurePluginRef, serv
                             writer.writeLine(`  }`);
                             writer.newLine();
 
+                            if (
+                                entityRef.isTranslatable() &&
+                                (serviceRef.features.create || serviceRef.features.update)
+                            ) {
+                                writer.writeLine(
+                                    `  input ${entityRef.getTranslationClass()?.getName() ?? ''}Input {`,
+                                );
+                                writer.writeLine(`    id: ID`);
+                                writer.writeLine(`    languageCode: LanguageCode!`);
+                                for (const { name, type, nullable } of entityRef.getProps()) {
+                                    if (type.getText().includes('LocaleString')) {
+                                        writer.writeLine(`    ${name}: String`);
+                                    }
+                                }
+                                writer.writeLine(`  }`);
+                                writer.newLine();
+                            }
+
                             if (serviceRef.features.create) {
                                 writer.writeLine(`  input Create${entityRef.name}Input {`);
                                 for (const { name, type, nullable } of entityRef.getProps()) {
@@ -468,6 +508,11 @@ function createCrudApiExtension(project: Project, plugin: VendurePluginRef, serv
                                         writer.writeLine(`    ${name}: ${graphQlType}${nullable ? '' : '!'}`);
                                     }
                                 }
+                                if (entityRef.isTranslatable()) {
+                                    writer.writeLine(
+                                        `    translations: [${entityRef.getTranslationClass()?.getName() ?? ''}Input!]!`,
+                                    );
+                                }
                                 writer.writeLine(`  }`);
                                 writer.newLine();
                             }
@@ -481,6 +526,11 @@ function createCrudApiExtension(project: Project, plugin: VendurePluginRef, serv
                                         writer.writeLine(`    ${name}: ${graphQlType}`);
                                     }
                                 }
+                                if (entityRef.isTranslatable()) {
+                                    writer.writeLine(
+                                        `    translations: [${entityRef.getTranslationClass()?.getName() ?? ''}Input!]`,
+                                    );
+                                }
                                 writer.writeLine(`  }`);
                                 writer.newLine();
                             }
@@ -567,9 +617,12 @@ function getGraphQLType(type: Type): string | undefined {
     if (type.isNumber()) {
         return 'Int';
     }
-    if (type.isClass() && type.getText() === 'Date') {
+    if (type.isObject() && type.getText() === 'Date') {
         return 'DateTime';
     }
+    if (type.getText().includes('LocaleString')) {
+        return 'String';
+    }
     return;
 }
 

+ 1 - 9
packages/cli/src/shared/entity-ref.ts

@@ -27,15 +27,7 @@ export class EntityRef {
         return this.classDeclaration.getProperties().map(prop => {
             const propType = prop.getType();
             const name = prop.getName();
-            if (propType.isUnion()) {
-                // get the non-null part of the union
-                const nonNullType = propType.getUnionTypes().find(t => !t.isNull() && !t.isUndefined());
-                if (!nonNullType) {
-                    throw new Error('Could not find non-null type in union');
-                }
-                return { name, type: nonNullType, nullable: true };
-            }
-            return { name, type: propType, nullable: false };
+            return { name, type: propType.getNonNullableType(), nullable: propType.isNullable() };
         });
     }
 

+ 5 - 3
packages/cli/src/utilities/ast-utils.ts

@@ -130,23 +130,25 @@ export function customizeCreateUpdateInputInterfaces(sourceFile: SourceFile, ent
         .getInterface('UpdateEntityInput')
         ?.rename(`Update${entityRef.name}Input`);
 
+    let index = 0;
     for (const { name, type, nullable } of entityRef.getProps()) {
         if (
             type.isBoolean() ||
             type.isString() ||
             type.isNumber() ||
-            (type.isClass() && type.getText() === 'Date')
+            (type.isObject() && type.getText() === 'Date')
         ) {
-            createInputInterface?.addProperty({
+            createInputInterface?.insertProperty(index, {
                 name,
                 type: writer => writer.write(type.getText()),
                 hasQuestionToken: nullable,
             });
-            updateInputInterface?.addProperty({
+            updateInputInterface?.insertProperty(index + 1, {
                 name,
                 type: writer => writer.write(type.getText()),
                 hasQuestionToken: true,
             });
+            index++;
         }
     }