diff --git a/src/packages/cli/src/import/index.ts b/src/packages/cli/src/import/index.ts index f2348c7e8..ea9295c40 100644 --- a/src/packages/cli/src/import/index.ts +++ b/src/packages/cli/src/import/index.ts @@ -175,6 +175,7 @@ export const importDataSource = async ( } console.log(`${fileCount} files have been successfully created in the project.`); } catch (err: unknown) { + console.error(err); if (isIntrospectionError(err)) { console.warn(`\n\n${err.title}\n${err.message}\n\n`); } else { diff --git a/src/packages/end-to-end/databases/postgres.sql b/src/packages/end-to-end/databases/postgres.sql index f528a8ae4..60872c342 100644 --- a/src/packages/end-to-end/databases/postgres.sql +++ b/src/packages/end-to-end/databases/postgres.sql @@ -138,6 +138,19 @@ CREATE TABLE "Track" CONSTRAINT "PK_Track" PRIMARY KEY ("TrackId") ); +-- These are here to test a specific scenario that used to crash the introspection process. +CREATE TABLE "ToOne" ( + id text PRIMARY KEY, + name text NOT NULL +); + +CREATE UNIQUE INDEX to_one_pkey ON "ToOne"(id text_ops); +CREATE UNIQUE INDEX to_one_name_key ON "ToOne"(name text_ops); + +CREATE TABLE "ToOneKeyOwner" ( + id text PRIMARY KEY, + related_entity_name text NOT NULL REFERENCES "ToOne"(name) ON DELETE CASCADE ON UPDATE CASCADE +); /******************************************************************************* diff --git a/src/packages/mikroorm/src/introspection/files/data-entity-file.ts b/src/packages/mikroorm/src/introspection/files/data-entity-file.ts index 6f108f533..b6473b27b 100644 --- a/src/packages/mikroorm/src/introspection/files/data-entity-file.ts +++ b/src/packages/mikroorm/src/introspection/files/data-entity-file.ts @@ -111,6 +111,10 @@ export class DataEntityFile extends BaseFile { } protected getPropertyType(prop: EntityProperty): string { + if ([ReferenceKind.ONE_TO_ONE, ReferenceKind.MANY_TO_ONE].includes(prop.kind)) { + return prop.type.charAt(0).toUpperCase() + prop.type.slice(1); + } + const columnType = prop.columnTypes?.[0]?.toLowerCase(); if (['jsonb', 'json', 'any'].includes(columnType)) { diff --git a/src/packages/mikroorm/src/introspection/files/schema-entity-file.ts b/src/packages/mikroorm/src/introspection/files/schema-entity-file.ts index fdbe9d8a0..c3ac44b0d 100644 --- a/src/packages/mikroorm/src/introspection/files/schema-entity-file.ts +++ b/src/packages/mikroorm/src/introspection/files/schema-entity-file.ts @@ -104,6 +104,10 @@ export class SchemaEntityFile extends BaseFile { } protected getTypescriptPropertyType(prop: EntityProperty): string { + if ([ReferenceKind.ONE_TO_ONE, ReferenceKind.MANY_TO_ONE].includes(prop.kind)) { + return prop.type.charAt(0).toUpperCase() + prop.type.slice(1); + } + if (['jsonb', 'json', 'any'].includes(prop.columnTypes?.[0])) { return `Record`; } @@ -185,6 +189,10 @@ export class SchemaEntityFile extends BaseFile { return `[${prop.type.charAt(0).toUpperCase() + prop.type.slice(1).replace('[]', '')}]`; } + if ([ReferenceKind.ONE_TO_ONE, ReferenceKind.MANY_TO_ONE].includes(prop.kind)) { + return prop.type.charAt(0).toUpperCase() + prop.type.slice(1); + } + if ([ReferenceKind.MANY_TO_MANY, ReferenceKind.ONE_TO_MANY].includes(prop.kind)) { return `[${prop.type.charAt(0).toUpperCase() + prop.type.slice(1).replace('[]', '')}]`; } @@ -193,7 +201,14 @@ export class SchemaEntityFile extends BaseFile { return `[${prop.type.charAt(0).toUpperCase() + prop.type.slice(1)}]`; } - return prop.runtimeType.charAt(0).toUpperCase() + prop.runtimeType.slice(1); + const lastChanceType = prop.runtimeType ?? prop.type; + + if (!lastChanceType) { + console.error(`Property is malformed, it has no type or runtimeType:`, prop); + throw new Error(`Property ${prop.name} on ${prop.entity} entity has no type or runtimeType.`); + } + + return lastChanceType.charAt(0).toUpperCase() + lastChanceType.slice(1); } private getPropertyDecorator(prop: EntityProperty): string { diff --git a/src/packages/mikroorm/src/introspection/generate.ts b/src/packages/mikroorm/src/introspection/generate.ts index a026e3ea9..fd4212e12 100644 --- a/src/packages/mikroorm/src/introspection/generate.ts +++ b/src/packages/mikroorm/src/introspection/generate.ts @@ -298,6 +298,9 @@ export const generate = async (databaseType: DatabaseType, options: ConnectionOp } catch (err) { if (err instanceof IntrospectionError) throw err; + console.error('Got error during introspection:'); + console.error(err); + throw new IntrospectionError( `Warning: Unable to connect to database.`, hasErrorMessage(err) ? err.message : 'Please check the connection settings and try again'