@rvoh/dream 1.4.1 → 1.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +166 -0
- package/dist/cjs/src/Dream.js +12 -16
- package/dist/cjs/src/bin/index.js +23 -7
- package/dist/cjs/src/cli/index.js +18 -3
- package/dist/cjs/src/db/ConnectedToDB.js +0 -8
- package/dist/cjs/src/db/DreamDbConnection.js +25 -36
- package/dist/cjs/src/db/helpers/dbTypesFilenameForConnection.js +6 -0
- package/dist/cjs/src/{bin/helpers/sync.js → db/helpers/syncDbTypesFiles.js} +8 -5
- package/dist/cjs/src/db/index.js +3 -2
- package/dist/cjs/src/decorators/field/sortable/helpers/setPosition.js +17 -2
- package/dist/cjs/src/dream/Query.js +9 -6
- package/dist/cjs/src/dream/QueryDriver/Base.js +111 -7
- package/dist/cjs/src/dream/QueryDriver/Kysely.js +213 -86
- package/dist/cjs/src/dream/QueryDriver/Postgres.js +162 -0
- package/dist/cjs/src/{helpers/db → dream/QueryDriver/helpers/kysely}/runMigration.js +20 -16
- package/dist/cjs/src/{helpers/db → dream/QueryDriver/helpers/pg}/createDb.js +5 -5
- package/dist/cjs/src/{helpers/db → dream/QueryDriver/helpers/pg}/dropDb.js +6 -6
- package/dist/cjs/src/{helpers/db → dream/QueryDriver/helpers/pg}/loadPgClient.js +5 -3
- package/dist/cjs/src/dream/internal/destroyDream.js +3 -10
- package/dist/cjs/src/dream/internal/saveDream.js +1 -1
- package/dist/cjs/src/dream/internal/similarity/SimilarityBuilder.js +9 -3
- package/dist/cjs/src/dream-app/index.js +59 -65
- package/dist/cjs/src/helpers/cli/SchemaBuilder.js +30 -42
- package/dist/cjs/src/helpers/cli/addImportSuffix.js +17 -0
- package/dist/cjs/src/helpers/cli/generateDream.js +2 -0
- package/dist/cjs/src/helpers/cli/generateDreamContent.js +5 -3
- package/dist/cjs/src/helpers/cli/generateFactoryContent.js +29 -0
- package/dist/cjs/src/helpers/cli/generateMigration.js +7 -5
- package/dist/cjs/src/helpers/cli/generateMigrationContent.js +48 -15
- package/dist/cjs/src/helpers/db/primaryKeyType.js +4 -22
- package/dist/cjs/src/helpers/path/relativeDreamPath.js +4 -3
- package/dist/cjs/src/helpers/sqlAttributes.js +4 -1
- package/dist/cjs/src/index.js +8 -2
- package/dist/esm/src/Dream.js +10 -14
- package/dist/esm/src/bin/index.js +23 -7
- package/dist/esm/src/cli/index.js +18 -3
- package/dist/esm/src/db/ConnectedToDB.js +0 -8
- package/dist/esm/src/db/DreamDbConnection.js +22 -34
- package/dist/esm/src/db/helpers/dbTypesFilenameForConnection.js +3 -0
- package/dist/esm/src/{bin/helpers/sync.js → db/helpers/syncDbTypesFiles.js} +7 -4
- package/dist/esm/src/db/index.js +3 -2
- package/dist/esm/src/decorators/field/sortable/helpers/setPosition.js +16 -2
- package/dist/esm/src/dream/Query.js +9 -6
- package/dist/esm/src/dream/QueryDriver/Base.js +111 -7
- package/dist/esm/src/dream/QueryDriver/Kysely.js +215 -88
- package/dist/esm/src/dream/QueryDriver/Postgres.js +162 -0
- package/dist/esm/src/{helpers/db → dream/QueryDriver/helpers/kysely}/runMigration.js +14 -10
- package/dist/esm/src/{helpers/db → dream/QueryDriver/helpers/pg}/createDb.js +5 -5
- package/dist/esm/src/{helpers/db → dream/QueryDriver/helpers/pg}/dropDb.js +6 -6
- package/dist/esm/src/{helpers/db → dream/QueryDriver/helpers/pg}/loadPgClient.js +5 -3
- package/dist/esm/src/dream/internal/destroyDream.js +3 -10
- package/dist/esm/src/dream/internal/saveDream.js +1 -1
- package/dist/esm/src/dream/internal/similarity/SimilarityBuilder.js +9 -3
- package/dist/esm/src/dream-app/index.js +55 -61
- package/dist/esm/src/helpers/cli/SchemaBuilder.js +24 -36
- package/dist/esm/src/helpers/cli/addImportSuffix.js +14 -0
- package/dist/esm/src/helpers/cli/generateDream.js +2 -0
- package/dist/esm/src/helpers/cli/generateDreamContent.js +5 -3
- package/dist/esm/src/helpers/cli/generateFactoryContent.js +29 -0
- package/dist/esm/src/helpers/cli/generateMigration.js +7 -5
- package/dist/esm/src/helpers/cli/generateMigrationContent.js +48 -15
- package/dist/esm/src/helpers/db/primaryKeyType.js +4 -22
- package/dist/esm/src/helpers/path/relativeDreamPath.js +4 -3
- package/dist/esm/src/helpers/sqlAttributes.js +4 -1
- package/dist/esm/src/index.js +3 -0
- package/dist/types/src/Dream.d.ts +5 -3
- package/dist/types/src/bin/index.d.ts +3 -1
- package/dist/types/src/db/ConnectedToDB.d.ts +0 -2
- package/dist/types/src/db/DreamDbConnection.d.ts +7 -3
- package/dist/types/src/db/helpers/dbTypesFilenameForConnection.d.ts +1 -0
- package/dist/types/src/db/helpers/syncDbTypesFiles.d.ts +1 -0
- package/dist/types/src/db/index.d.ts +2 -1
- package/dist/types/src/decorators/field/sortable/helpers/setPosition.d.ts +2 -0
- package/dist/types/src/dream/Query.d.ts +5 -20
- package/dist/types/src/dream/QueryDriver/Base.d.ts +74 -13
- package/dist/types/src/dream/QueryDriver/Kysely.d.ts +75 -9
- package/dist/types/src/dream/QueryDriver/Postgres.d.ts +32 -0
- package/dist/types/src/dream/QueryDriver/helpers/kysely/foreignKeyTypeFromPrimaryKey.d.ts +2 -0
- package/dist/types/src/dream/QueryDriver/helpers/kysely/runMigration.d.ts +9 -0
- package/dist/types/src/dream/QueryDriver/helpers/pg/createDb.d.ts +2 -0
- package/dist/types/src/dream/QueryDriver/helpers/pg/dropDb.d.ts +2 -0
- package/dist/types/src/dream/QueryDriver/helpers/pg/loadPgClient.d.ts +5 -0
- package/dist/types/src/dream/internal/destroyOptions.d.ts +3 -3
- package/dist/types/src/dream-app/index.d.ts +16 -7
- package/dist/types/src/helpers/cli/SchemaBuilder.d.ts +26 -0
- package/dist/types/src/helpers/cli/addImportSuffix.d.ts +1 -0
- package/dist/types/src/helpers/cli/generateDream.d.ts +1 -0
- package/dist/types/src/helpers/cli/generateDreamContent.d.ts +2 -1
- package/dist/types/src/helpers/cli/generateMigration.d.ts +2 -1
- package/dist/types/src/helpers/cli/generateMigrationContent.d.ts +2 -1
- package/dist/types/src/helpers/db/primaryKeyType.d.ts +1 -1
- package/dist/types/src/index.d.ts +3 -0
- package/dist/types/src/types/dream.d.ts +4 -4
- package/dist/types/src/types/dream.ts +8 -9
- package/docs/assets/navigation.js +1 -1
- package/docs/assets/search.js +1 -1
- package/docs/classes/Benchmark.html +2 -2
- package/docs/classes/CalendarDate.html +2 -2
- package/docs/classes/CheckConstraintViolation.html +3 -3
- package/docs/classes/CliFileWriter.html +2 -2
- package/docs/classes/CreateOrFindByFailedToCreateAndFind.html +3 -3
- package/docs/classes/DataTypeColumnTypeMismatch.html +3 -3
- package/docs/classes/Decorators.html +19 -19
- package/docs/classes/Dream.html +117 -115
- package/docs/classes/DreamApp.html +9 -5
- package/docs/classes/DreamBin.html +2 -2
- package/docs/classes/DreamCLI.html +4 -4
- package/docs/classes/DreamImporter.html +2 -2
- package/docs/classes/DreamLogos.html +2 -2
- package/docs/classes/DreamMigrationHelpers.html +7 -7
- package/docs/classes/DreamSerializerBuilder.html +8 -8
- package/docs/classes/DreamTransaction.html +2 -2
- package/docs/classes/Encrypt.html +2 -2
- package/docs/classes/Env.html +2 -2
- package/docs/classes/GlobalNameNotSet.html +3 -3
- package/docs/classes/KyselyQueryDriver.html +163 -0
- package/docs/classes/NonLoadedAssociation.html +3 -3
- package/docs/classes/NotNullViolation.html +3 -3
- package/docs/classes/ObjectSerializerBuilder.html +8 -8
- package/docs/classes/PostgresQueryDriver.html +165 -0
- package/docs/classes/Query.html +59 -87
- package/docs/classes/QueryDriverBase.html +156 -0
- package/docs/classes/Range.html +2 -2
- package/docs/classes/RecordNotFound.html +3 -3
- package/docs/classes/ValidationError.html +3 -3
- package/docs/functions/DreamSerializer.html +1 -1
- package/docs/functions/ObjectSerializer.html +1 -1
- package/docs/functions/ReplicaSafe.html +1 -1
- package/docs/functions/STI.html +1 -1
- package/docs/functions/SoftDelete.html +1 -1
- package/docs/functions/camelize.html +1 -1
- package/docs/functions/capitalize.html +1 -1
- package/docs/functions/cloneDeepSafe.html +1 -1
- package/docs/functions/closeAllDbConnections.html +1 -1
- package/docs/functions/compact.html +1 -1
- package/docs/functions/dreamDbConnections.html +1 -1
- package/docs/functions/dreamPath.html +1 -1
- package/docs/functions/expandStiClasses.html +1 -1
- package/docs/functions/generateDream.html +1 -1
- package/docs/functions/globalClassNameFromFullyQualifiedModelName.html +1 -1
- package/docs/functions/groupBy.html +1 -1
- package/docs/functions/hyphenize.html +1 -1
- package/docs/functions/inferSerializerFromDreamOrViewModel.html +1 -1
- package/docs/functions/inferSerializersFromDreamClassOrViewModelClass.html +1 -1
- package/docs/functions/intersection.html +1 -1
- package/docs/functions/isDreamSerializer.html +1 -1
- package/docs/functions/isEmpty.html +1 -1
- package/docs/functions/loadRepl.html +1 -1
- package/docs/functions/lookupClassByGlobalName.html +1 -1
- package/docs/functions/normalizeUnicode.html +1 -1
- package/docs/functions/pascalize.html +1 -1
- package/docs/functions/pgErrorType.html +1 -1
- package/docs/functions/range-1.html +1 -1
- package/docs/functions/relativeDreamPath.html +1 -1
- package/docs/functions/round.html +1 -1
- package/docs/functions/serializerNameFromFullyQualifiedModelName.html +1 -1
- package/docs/functions/sharedPathPrefix.html +1 -1
- package/docs/functions/snakeify.html +1 -1
- package/docs/functions/sort.html +1 -1
- package/docs/functions/sortBy.html +1 -1
- package/docs/functions/sortObjectByKey.html +1 -1
- package/docs/functions/sortObjectByValue.html +1 -1
- package/docs/functions/standardizeFullyQualifiedModelName.html +1 -1
- package/docs/functions/uncapitalize.html +1 -1
- package/docs/functions/uniq.html +1 -1
- package/docs/functions/untypedDb.html +1 -1
- package/docs/functions/validateColumn.html +1 -1
- package/docs/functions/validateTable.html +1 -1
- package/docs/hierarchy.html +1 -0
- package/docs/interfaces/BelongsToStatement.html +2 -2
- package/docs/interfaces/DecoratorContext.html +2 -2
- package/docs/interfaces/DreamAppInitOptions.html +2 -2
- package/docs/interfaces/DreamAppOpts.html +2 -2
- package/docs/interfaces/EncryptOptions.html +2 -2
- package/docs/interfaces/InternalAnyTypedSerializerRendersMany.html +2 -2
- package/docs/interfaces/InternalAnyTypedSerializerRendersOne.html +2 -2
- package/docs/interfaces/OpenapiDescription.html +2 -2
- package/docs/interfaces/OpenapiSchemaProperties.html +1 -1
- package/docs/interfaces/OpenapiSchemaPropertiesShorthand.html +1 -1
- package/docs/interfaces/OpenapiTypeFieldObject.html +1 -1
- package/docs/interfaces/SerializerRendererOpts.html +2 -2
- package/docs/modules.html +3 -0
- package/docs/types/Camelized.html +1 -1
- package/docs/types/CommonOpenapiSchemaObjectFields.html +1 -1
- package/docs/types/DateTime.html +1 -1
- package/docs/types/DbConnectionType.html +1 -1
- package/docs/types/DbTypes.html +1 -1
- package/docs/types/DreamAppAllowedPackageManagersEnum.html +1 -1
- package/docs/types/DreamAssociationMetadata.html +1 -1
- package/docs/types/DreamAttributes.html +1 -1
- package/docs/types/DreamClassAssociationAndStatement.html +1 -1
- package/docs/types/DreamClassColumn.html +1 -1
- package/docs/types/DreamColumn.html +1 -1
- package/docs/types/DreamColumnNames.html +1 -1
- package/docs/types/DreamLogLevel.html +1 -1
- package/docs/types/DreamLogger.html +1 -1
- package/docs/types/DreamModelSerializerType.html +1 -1
- package/docs/types/DreamOrViewModelClassSerializerKey.html +1 -1
- package/docs/types/DreamOrViewModelSerializerKey.html +1 -1
- package/docs/types/DreamParamSafeAttributes.html +1 -1
- package/docs/types/DreamParamSafeColumnNames.html +1 -1
- package/docs/types/DreamSerializable.html +1 -1
- package/docs/types/DreamSerializableArray.html +1 -1
- package/docs/types/DreamSerializerKey.html +1 -1
- package/docs/types/DreamSerializers.html +1 -1
- package/docs/types/DreamVirtualColumns.html +1 -1
- package/docs/types/EncryptAlgorithm.html +1 -1
- package/docs/types/HasManyStatement.html +1 -1
- package/docs/types/HasOneStatement.html +1 -1
- package/docs/types/Hyphenized.html +1 -1
- package/docs/types/OpenapiAllTypes.html +1 -1
- package/docs/types/OpenapiFormats.html +1 -1
- package/docs/types/OpenapiNumberFormats.html +1 -1
- package/docs/types/OpenapiPrimitiveBaseTypes.html +1 -1
- package/docs/types/OpenapiPrimitiveTypes.html +1 -1
- package/docs/types/OpenapiSchemaArray.html +1 -1
- package/docs/types/OpenapiSchemaArrayShorthand.html +1 -1
- package/docs/types/OpenapiSchemaBase.html +1 -1
- package/docs/types/OpenapiSchemaBody.html +1 -1
- package/docs/types/OpenapiSchemaBodyShorthand.html +1 -1
- package/docs/types/OpenapiSchemaCommonFields.html +1 -1
- package/docs/types/OpenapiSchemaExpressionAllOf.html +1 -1
- package/docs/types/OpenapiSchemaExpressionAnyOf.html +1 -1
- package/docs/types/OpenapiSchemaExpressionOneOf.html +1 -1
- package/docs/types/OpenapiSchemaExpressionRef.html +1 -1
- package/docs/types/OpenapiSchemaExpressionRefSchemaShorthand.html +1 -1
- package/docs/types/OpenapiSchemaInteger.html +1 -1
- package/docs/types/OpenapiSchemaNull.html +1 -1
- package/docs/types/OpenapiSchemaNumber.html +1 -1
- package/docs/types/OpenapiSchemaObject.html +1 -1
- package/docs/types/OpenapiSchemaObjectAllOf.html +1 -1
- package/docs/types/OpenapiSchemaObjectAllOfShorthand.html +1 -1
- package/docs/types/OpenapiSchemaObjectAnyOf.html +1 -1
- package/docs/types/OpenapiSchemaObjectAnyOfShorthand.html +1 -1
- package/docs/types/OpenapiSchemaObjectBase.html +1 -1
- package/docs/types/OpenapiSchemaObjectBaseShorthand.html +1 -1
- package/docs/types/OpenapiSchemaObjectOneOf.html +1 -1
- package/docs/types/OpenapiSchemaObjectOneOfShorthand.html +1 -1
- package/docs/types/OpenapiSchemaObjectShorthand.html +1 -1
- package/docs/types/OpenapiSchemaPrimitiveGeneric.html +1 -1
- package/docs/types/OpenapiSchemaShorthandExpressionAllOf.html +1 -1
- package/docs/types/OpenapiSchemaShorthandExpressionAnyOf.html +1 -1
- package/docs/types/OpenapiSchemaShorthandExpressionOneOf.html +1 -1
- package/docs/types/OpenapiSchemaShorthandExpressionSerializableRef.html +1 -1
- package/docs/types/OpenapiSchemaShorthandExpressionSerializerRef.html +1 -1
- package/docs/types/OpenapiSchemaShorthandPrimitiveGeneric.html +1 -1
- package/docs/types/OpenapiSchemaString.html +1 -1
- package/docs/types/OpenapiShorthandAllTypes.html +1 -1
- package/docs/types/OpenapiShorthandPrimitiveBaseTypes.html +1 -1
- package/docs/types/OpenapiShorthandPrimitiveTypes.html +1 -1
- package/docs/types/OpenapiTypeField.html +1 -1
- package/docs/types/Pascalized.html +1 -1
- package/docs/types/RoundingPrecision.html +1 -1
- package/docs/types/SerializerCasing.html +1 -1
- package/docs/types/SimpleObjectSerializerType.html +1 -1
- package/docs/types/Snakeified.html +1 -1
- package/docs/types/UpdateableAssociationProperties.html +1 -1
- package/docs/types/UpdateableProperties.html +1 -1
- package/docs/types/ValidationType.html +1 -1
- package/docs/types/ViewModel.html +1 -1
- package/docs/types/ViewModelClass.html +1 -1
- package/docs/types/WhereStatementForDream.html +1 -1
- package/docs/types/WhereStatementForDreamClass.html +1 -1
- package/docs/variables/DateTime-1.html +1 -1
- package/docs/variables/DreamAppAllowedPackageManagersEnumValues.html +1 -1
- package/docs/variables/DreamConst.html +1 -1
- package/docs/variables/TRIGRAM_OPERATORS.html +1 -1
- package/docs/variables/openapiPrimitiveTypes-1.html +1 -1
- package/docs/variables/openapiShorthandPrimitiveTypes-1.html +1 -1
- package/docs/variables/ops.html +1 -1
- package/docs/variables/primaryKeyTypes.html +1 -1
- package/package.json +4 -3
- package/dist/cjs/src/helpers/db/truncateDb.js +0 -27
- package/dist/esm/src/helpers/db/truncateDb.js +0 -24
- package/dist/types/src/bin/helpers/sync.d.ts +0 -1
- package/dist/types/src/helpers/db/createDb.d.ts +0 -2
- package/dist/types/src/helpers/db/dropDb.d.ts +0 -2
- package/dist/types/src/helpers/db/foreignKeyTypeFromPrimaryKey.d.ts +0 -2
- package/dist/types/src/helpers/db/loadPgClient.d.ts +0 -4
- package/dist/types/src/helpers/db/runMigration.d.ts +0 -6
- package/dist/types/src/helpers/db/truncateDb.d.ts +0 -1
- /package/dist/cjs/src/{helpers/db → dream/QueryDriver/helpers/kysely}/foreignKeyTypeFromPrimaryKey.js +0 -0
- /package/dist/esm/src/{helpers/db → dream/QueryDriver/helpers/kysely}/foreignKeyTypeFromPrimaryKey.js +0 -0
|
@@ -1,15 +1,19 @@
|
|
|
1
1
|
import { FileMigrationProvider, Migrator } from 'kysely';
|
|
2
2
|
import * as fs from 'node:fs/promises';
|
|
3
3
|
import * as path from 'node:path';
|
|
4
|
-
import
|
|
5
|
-
import
|
|
6
|
-
import
|
|
7
|
-
import
|
|
8
|
-
import
|
|
9
|
-
export default async function runMigration({ mode = 'migrate'
|
|
4
|
+
import colorize from '../../../../cli/logger/loggable/colorize.js';
|
|
5
|
+
import { closeAllConnectionsForConnectionName, closeAllDbConnections, } from '../../../../db/DreamDbConnection.js';
|
|
6
|
+
import db from '../../../../db/index.js';
|
|
7
|
+
import DreamApp from '../../../../dream-app/index.js';
|
|
8
|
+
import DreamCLI from '../../../../cli/index.js';
|
|
9
|
+
export default async function runMigration({ connectionName, mode = 'migrate', dialectProvider, }) {
|
|
10
10
|
const dreamApp = DreamApp.getOrFail();
|
|
11
|
-
const migrationFolder =
|
|
12
|
-
|
|
11
|
+
const migrationFolder = connectionName === 'default'
|
|
12
|
+
? path.join(dreamApp.projectRoot, dreamApp.paths.db, 'migrations')
|
|
13
|
+
: path.join(dreamApp.projectRoot, dreamApp.paths.db, 'migrations', connectionName);
|
|
14
|
+
// Ensure the migration folder exists
|
|
15
|
+
await fs.mkdir(migrationFolder, { recursive: true });
|
|
16
|
+
const kyselyDb = db(connectionName, 'primary', dialectProvider);
|
|
13
17
|
const migrator = new Migrator({
|
|
14
18
|
db: kyselyDb,
|
|
15
19
|
allowUnorderedMigrations: true,
|
|
@@ -25,7 +29,7 @@ export default async function runMigration({ mode = 'migrate' } = {}) {
|
|
|
25
29
|
else if (mode === 'rollback') {
|
|
26
30
|
await rollback(migrator);
|
|
27
31
|
}
|
|
28
|
-
await
|
|
32
|
+
await closeAllConnectionsForConnectionName(connectionName);
|
|
29
33
|
}
|
|
30
34
|
async function migrate(migrator) {
|
|
31
35
|
let nextMigrationRequiringNewTransaction = await findNextMigrationRequiringNewTransaction(migrator);
|
|
@@ -71,7 +75,7 @@ async function rollback(migrator) {
|
|
|
71
75
|
await handleError(error, 'rollback');
|
|
72
76
|
}
|
|
73
77
|
async function handleError(error, mode) {
|
|
74
|
-
await
|
|
78
|
+
await closeAllDbConnections();
|
|
75
79
|
DreamApp.logWithLevel('error', `failed to ${migratedActionCurrentTense(mode)}`);
|
|
76
80
|
DreamApp.logWithLevel('error', error);
|
|
77
81
|
process.exit(1);
|
|
@@ -1,17 +1,17 @@
|
|
|
1
|
-
import DreamApp from '
|
|
2
|
-
import EnvInternal from '
|
|
1
|
+
import DreamApp from '../../../../dream-app/index.js';
|
|
2
|
+
import EnvInternal from '../../../../helpers/EnvInternal.js';
|
|
3
3
|
import loadPgClient from './loadPgClient.js';
|
|
4
|
-
export default async function createDb(
|
|
4
|
+
export default async function createDb(connectionName, connectionType, dbName) {
|
|
5
5
|
// this was only ever written to clear the db between tests or in development,
|
|
6
6
|
// so there is no way to drop in production
|
|
7
7
|
if (EnvInternal.isProduction)
|
|
8
8
|
return false;
|
|
9
9
|
const dreamApp = DreamApp.getOrFail();
|
|
10
|
-
const dbConf = dreamApp.dbConnectionConfig(
|
|
10
|
+
const dbConf = dreamApp.dbConnectionConfig(connectionName, connectionType);
|
|
11
11
|
dbName ||= dbConf.name || null;
|
|
12
12
|
if (!dbName)
|
|
13
13
|
throw new Error('Must either pass a dbName to the create function, or else ensure that DB_NAME is set in the env');
|
|
14
|
-
const client = await loadPgClient({ useSystemDb: true });
|
|
14
|
+
const client = await loadPgClient({ useSystemDb: true, connectionName });
|
|
15
15
|
await client.query(`CREATE DATABASE ${dbName};`);
|
|
16
16
|
await client.end();
|
|
17
17
|
}
|
|
@@ -1,18 +1,18 @@
|
|
|
1
|
-
import DreamCLI from '
|
|
2
|
-
import DreamApp from '
|
|
3
|
-
import EnvInternal from '
|
|
1
|
+
import DreamCLI from '../../../../cli/index.js';
|
|
2
|
+
import DreamApp from '../../../../dream-app/index.js';
|
|
3
|
+
import EnvInternal from '../../../../helpers/EnvInternal.js';
|
|
4
4
|
import loadPgClient from './loadPgClient.js';
|
|
5
|
-
export default async function dropDb(connection, dbName) {
|
|
5
|
+
export default async function dropDb(connectionName, connection, dbName) {
|
|
6
6
|
// this was only ever written to clear the db between tests or in development,
|
|
7
7
|
// so there is no way to drop in production
|
|
8
8
|
if (EnvInternal.isProduction)
|
|
9
9
|
return false;
|
|
10
10
|
const dreamApp = DreamApp.getOrFail();
|
|
11
|
-
const dbConf = dreamApp.dbConnectionConfig(connection);
|
|
11
|
+
const dbConf = dreamApp.dbConnectionConfig(connectionName, connection);
|
|
12
12
|
dbName ||= dbConf.name || null;
|
|
13
13
|
if (!dbName)
|
|
14
14
|
throw new Error('Must either pass a dbName to the drop function, or else ensure that DB_NAME is set in the env');
|
|
15
|
-
const client = await loadPgClient({ useSystemDb: true });
|
|
15
|
+
const client = await loadPgClient({ useSystemDb: true, connectionName });
|
|
16
16
|
await maybeDropDuplicateDatabases(client, dbName);
|
|
17
17
|
await client.query(`DROP DATABASE IF EXISTS ${dbName};`);
|
|
18
18
|
}
|
|
@@ -7,10 +7,12 @@
|
|
|
7
7
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
8
8
|
// @ts-ignore
|
|
9
9
|
import pg from 'pg';
|
|
10
|
-
import DreamApp from '
|
|
11
|
-
export default async function loadPgClient({ useSystemDb }
|
|
10
|
+
import DreamApp from '../../../../dream-app/index.js';
|
|
11
|
+
export default async function loadPgClient({ connectionName, useSystemDb, }) {
|
|
12
12
|
const dreamconf = DreamApp.getOrFail();
|
|
13
|
-
const creds = dreamconf.
|
|
13
|
+
const creds = dreamconf.dbCredentialsFor(connectionName)?.primary;
|
|
14
|
+
if (!creds)
|
|
15
|
+
throw new Error(`failed to load db credentials for connection: ${connectionName}`);
|
|
14
16
|
const client = new pg.Client({
|
|
15
17
|
host: creds.host || 'localhost',
|
|
16
18
|
port: creds.port,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
+
import DreamApp from '../../dream-app/index.js';
|
|
1
2
|
import destroyAssociatedRecords from './destroyAssociatedRecords.js';
|
|
2
3
|
import runHooksFor from './runHooksFor.js';
|
|
3
|
-
import softDeleteDream from './softDeleteDream.js';
|
|
4
4
|
/**
|
|
5
5
|
* @internal
|
|
6
6
|
*
|
|
@@ -56,13 +56,6 @@ function shouldSoftDelete(dream, reallyDestroy) {
|
|
|
56
56
|
* deleting by one of the beforeDestroy model hooks
|
|
57
57
|
*/
|
|
58
58
|
async function maybeDestroyDream(dream, txn, reallyDestroy) {
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
}
|
|
62
|
-
else if (!dream['_preventDeletion']) {
|
|
63
|
-
await txn.kyselyTransaction
|
|
64
|
-
.deleteFrom(dream.table)
|
|
65
|
-
.where(dream['_primaryKey'], '=', dream.primaryKeyValue())
|
|
66
|
-
.execute();
|
|
67
|
-
}
|
|
59
|
+
const dbDriverClass = DreamApp.getOrFail().dbConnectionQueryDriverClass(dream.connectionName);
|
|
60
|
+
await dbDriverClass.destroyDream(dream, txn, reallyDestroy);
|
|
68
61
|
}
|
|
@@ -28,7 +28,7 @@ export default async function saveDream(dream, txn = null, { skipHooks = false }
|
|
|
28
28
|
// BeforeSave/Update actions may clear all the data that we intended to save, leaving us with
|
|
29
29
|
// an invalid update command. The Sortable decorator is an example of this.
|
|
30
30
|
if (!alreadyPersisted || hasUnsavedData) {
|
|
31
|
-
const data = await Query.dbDriverClass().saveDream(dream, txn);
|
|
31
|
+
const data = await Query.dbDriverClass(dream.connectionName || 'default').saveDream(dream, txn);
|
|
32
32
|
dream['isPersisted'] = true;
|
|
33
33
|
dream.setAttributes(data);
|
|
34
34
|
}
|
|
@@ -8,6 +8,7 @@ import namespaceColumn from '../../../helpers/namespaceColumn.js';
|
|
|
8
8
|
import { TRIGRAM_OPERATORS } from '../../constants.js';
|
|
9
9
|
import similaritySelectSql from './similaritySelectSql.js';
|
|
10
10
|
import similarityWhereSql from './similarityWhereSql.js';
|
|
11
|
+
import { getPostgresQueryDriver } from '../../../decorators/field/sortable/helpers/setPosition.js';
|
|
11
12
|
export default class SimilarityBuilder extends ConnectedToDB {
|
|
12
13
|
whereStatement;
|
|
13
14
|
whereNotStatement;
|
|
@@ -214,8 +215,9 @@ export default class SimilarityBuilder extends ConnectedToDB {
|
|
|
214
215
|
const schema = this.dreamClass.prototype.schema;
|
|
215
216
|
const primaryKeyName = this.dreamClass.primaryKey;
|
|
216
217
|
const { tableName, tableAlias, columnName } = similarityStatement;
|
|
218
|
+
const queryDriverClass = getPostgresQueryDriver(this.dreamInstance.connectionName);
|
|
217
219
|
// eslint-disable-next-line @typescript-eslint/unbound-method
|
|
218
|
-
const { ref } =
|
|
220
|
+
const { ref } = queryDriverClass.dbFor(this.dreamInstance.connectionName, this.dbConnectionType('select')).dynamic;
|
|
219
221
|
const validatedTableAlias = validateTableAlias(tableAlias);
|
|
220
222
|
const validatedPrimaryKey = validateColumn(schema, tableName, primaryKeyName);
|
|
221
223
|
const nestedQuery = this.buildNestedSelectQuery({
|
|
@@ -245,7 +247,9 @@ export default class SimilarityBuilder extends ConnectedToDB {
|
|
|
245
247
|
statementType,
|
|
246
248
|
});
|
|
247
249
|
const trigramSearchAlias = this.similaritySearchId(tableAlias, columnName);
|
|
248
|
-
const
|
|
250
|
+
const queryDriverClass = getPostgresQueryDriver(this.dreamInstance.connectionName);
|
|
251
|
+
const selectQuery = queryDriverClass
|
|
252
|
+
.dbFor(this.dreamInstance.connectionName, this.dbConnectionType('select'))
|
|
249
253
|
.selectFrom(validatedTableAlias)
|
|
250
254
|
.select(`${trigramSearchAlias}.trigram_search_id`)
|
|
251
255
|
.innerJoin(nestedQuery.as(trigramSearchAlias), join => join.onRef(namespaceColumn(validatedPrimaryKey, validatedTableAlias), '=', namespaceColumn('trigram_search_id', trigramSearchAlias)));
|
|
@@ -257,7 +261,9 @@ export default class SimilarityBuilder extends ConnectedToDB {
|
|
|
257
261
|
const { columnName, opsStatement, tableName } = similarityStatement;
|
|
258
262
|
const validatedTable = validateTable(schema, tableName);
|
|
259
263
|
const validatedPrimaryKey = validateColumn(schema, tableName, primaryKeyName);
|
|
260
|
-
|
|
264
|
+
const queryDriverClass = getPostgresQueryDriver(this.dreamInstance.connectionName);
|
|
265
|
+
let nestedQuery = queryDriverClass
|
|
266
|
+
.dbFor(this.dreamInstance.connectionName, this.dbConnectionType('select'))
|
|
261
267
|
.selectFrom(tableName)
|
|
262
268
|
.select(eb => {
|
|
263
269
|
const tableNameRef = eb.ref(validatedTable);
|
|
@@ -1,26 +1,16 @@
|
|
|
1
|
-
// after building for esm, importing pg using the following:
|
|
2
|
-
//
|
|
3
|
-
// import * as pg from 'pg'
|
|
4
|
-
//
|
|
5
|
-
// will crash. This is difficult to discover, since it only happens
|
|
6
|
-
// when being imported from our esm build.
|
|
7
|
-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
8
|
-
// @ts-ignore
|
|
9
|
-
import pg from 'pg';
|
|
10
1
|
import * as util from 'node:util';
|
|
11
|
-
import db from '../db/index.js';
|
|
12
2
|
import validateTable from '../db/validators/validateTable.js';
|
|
3
|
+
import Query from '../dream/Query.js';
|
|
13
4
|
import Encrypt from '../encrypt/index.js';
|
|
14
5
|
import DreamAppInitMissingCallToLoadModels from '../errors/dream-app/DreamAppInitMissingCallToLoadModels.js';
|
|
15
6
|
import DreamAppInitMissingMissingProjectRoot from '../errors/dream-app/DreamAppInitMissingMissingProjectRoot.js';
|
|
16
7
|
import CalendarDate from '../helpers/CalendarDate.js';
|
|
17
|
-
import { findCitextArrayOid, findCorrespondingArrayOid, findEnumArrayOids, parsePostgresBigint, parsePostgresDate, parsePostgresDatetime, parsePostgresDecimal, } from '../helpers/customPgParsers.js';
|
|
18
8
|
import { DateTime, Settings } from '../helpers/DateTime.js';
|
|
19
9
|
import EnvInternal from '../helpers/EnvInternal.js';
|
|
20
10
|
import { cacheDreamApp, getCachedDreamAppOrFail } from './cache.js';
|
|
21
11
|
import importModels, { getModelsOrFail } from './helpers/importers/importModels.js';
|
|
22
12
|
import importSerializers, { getSerializersOrFail, setCachedSerializers, } from './helpers/importers/importSerializers.js';
|
|
23
|
-
|
|
13
|
+
import PostgresQueryDriver from '../dream/QueryDriver/Postgres.js';
|
|
24
14
|
// this needs to be done top-level to ensure proper configuration
|
|
25
15
|
Settings.defaultZone = 'UTC';
|
|
26
16
|
export default class DreamApp {
|
|
@@ -44,7 +34,7 @@ export default class DreamApp {
|
|
|
44
34
|
setCachedSerializers({});
|
|
45
35
|
cacheDreamApp(dreamApp);
|
|
46
36
|
if (!EnvInternal.boolean('BYPASS_DB_CONNECTIONS_DURING_INIT'))
|
|
47
|
-
await this.setDatabaseTypeParsers();
|
|
37
|
+
await this.setDatabaseTypeParsers(dreamApp);
|
|
48
38
|
await deferCb?.(dreamApp);
|
|
49
39
|
for (const plugin of dreamApp.plugins) {
|
|
50
40
|
await plugin(dreamApp);
|
|
@@ -87,43 +77,10 @@ export default class DreamApp {
|
|
|
87
77
|
*
|
|
88
78
|
*
|
|
89
79
|
*/
|
|
90
|
-
static async setDatabaseTypeParsers() {
|
|
91
|
-
const
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
pgTypes.setTypeParser(pgTypes.builtins.TIMESTAMPTZ, parsePostgresDatetime);
|
|
95
|
-
pgTypes.setTypeParser(pgTypes.builtins.NUMERIC, parsePostgresDecimal);
|
|
96
|
-
pgTypes.setTypeParser(pgTypes.builtins.INT8, parsePostgresBigint);
|
|
97
|
-
const textArrayOid = await findCorrespondingArrayOid(kyselyDb, pgTypes.builtins.TEXT);
|
|
98
|
-
if (textArrayOid) {
|
|
99
|
-
let oid;
|
|
100
|
-
const textArrayParser = pgTypes.getTypeParser(textArrayOid);
|
|
101
|
-
function transformPostgresArray(transformer) {
|
|
102
|
-
return (value) => textArrayParser(value).map(str => transformer(str));
|
|
103
|
-
}
|
|
104
|
-
const enumArrayOids = await findEnumArrayOids(kyselyDb);
|
|
105
|
-
enumArrayOids.forEach((enumArrayOid) => pgTypes.setTypeParser(enumArrayOid, textArrayParser));
|
|
106
|
-
oid = await findCitextArrayOid(kyselyDb);
|
|
107
|
-
if (oid)
|
|
108
|
-
pgTypes.setTypeParser(oid, textArrayParser);
|
|
109
|
-
oid = await findCorrespondingArrayOid(kyselyDb, pgTypes.builtins.UUID);
|
|
110
|
-
if (oid)
|
|
111
|
-
pgTypes.setTypeParser(oid, textArrayParser);
|
|
112
|
-
oid = await findCorrespondingArrayOid(kyselyDb, pgTypes.builtins.DATE);
|
|
113
|
-
if (oid)
|
|
114
|
-
pgTypes.setTypeParser(oid, transformPostgresArray(parsePostgresDate));
|
|
115
|
-
oid = await findCorrespondingArrayOid(kyselyDb, pgTypes.builtins.TIMESTAMP);
|
|
116
|
-
if (oid)
|
|
117
|
-
pgTypes.setTypeParser(oid, transformPostgresArray(parsePostgresDatetime));
|
|
118
|
-
oid = await findCorrespondingArrayOid(kyselyDb, pgTypes.builtins.TIMESTAMPTZ);
|
|
119
|
-
if (oid)
|
|
120
|
-
pgTypes.setTypeParser(oid, transformPostgresArray(parsePostgresDatetime));
|
|
121
|
-
oid = await findCorrespondingArrayOid(kyselyDb, pgTypes.builtins.NUMERIC);
|
|
122
|
-
if (oid)
|
|
123
|
-
pgTypes.setTypeParser(oid, transformPostgresArray(parsePostgresDecimal));
|
|
124
|
-
oid = await findCorrespondingArrayOid(kyselyDb, pgTypes.builtins.INT8);
|
|
125
|
-
if (oid)
|
|
126
|
-
pgTypes.setTypeParser(oid, transformPostgresArray(parsePostgresBigint));
|
|
80
|
+
static async setDatabaseTypeParsers(dreamApp) {
|
|
81
|
+
for (const connectionName of Object.keys(dreamApp._dbCredentials)) {
|
|
82
|
+
const dbDriverClass = Query.dbDriverClass(connectionName);
|
|
83
|
+
await dbDriverClass.setDatabaseTypeParsers(connectionName);
|
|
127
84
|
}
|
|
128
85
|
}
|
|
129
86
|
static checkKey(encryptionIdentifier, key, algorithm) {
|
|
@@ -165,10 +122,15 @@ Try setting it to something valid, like:
|
|
|
165
122
|
get specialHooks() {
|
|
166
123
|
return this._specialHooks;
|
|
167
124
|
}
|
|
168
|
-
_dbCredentials;
|
|
125
|
+
_dbCredentials = {};
|
|
169
126
|
get dbCredentials() {
|
|
170
127
|
return this._dbCredentials;
|
|
171
128
|
}
|
|
129
|
+
dbCredentialsFor(connectionName) {
|
|
130
|
+
if (this._dbCredentials[connectionName])
|
|
131
|
+
return this._dbCredentials[connectionName];
|
|
132
|
+
return null;
|
|
133
|
+
}
|
|
172
134
|
_encryption;
|
|
173
135
|
get encryption() {
|
|
174
136
|
return this._encryption;
|
|
@@ -217,10 +179,14 @@ Try setting it to something valid, like:
|
|
|
217
179
|
get packageManager() {
|
|
218
180
|
return this._packageManager;
|
|
219
181
|
}
|
|
182
|
+
_importExtension = '.js';
|
|
183
|
+
get importExtension() {
|
|
184
|
+
return this._importExtension;
|
|
185
|
+
}
|
|
220
186
|
loadedModels = false;
|
|
221
187
|
constructor(opts) {
|
|
222
188
|
if (opts?.db)
|
|
223
|
-
this._dbCredentials = opts.db;
|
|
189
|
+
this._dbCredentials['default'] = opts.db;
|
|
224
190
|
if (opts?.primaryKeyType)
|
|
225
191
|
this._primaryKeyType = opts.primaryKeyType;
|
|
226
192
|
if (opts?.projectRoot)
|
|
@@ -247,22 +213,38 @@ Try setting it to something valid, like:
|
|
|
247
213
|
get serializers() {
|
|
248
214
|
return getSerializersOrFail();
|
|
249
215
|
}
|
|
250
|
-
dbName(connection) {
|
|
251
|
-
const conf = this.dbConnectionConfig(connection);
|
|
216
|
+
dbName(connectionName, connection) {
|
|
217
|
+
const conf = this.dbConnectionConfig(connectionName, connection);
|
|
252
218
|
return this.parallelDatabasesEnabled ? `${conf.name}_${process.env.VITEST_POOL_ID}` : conf.name;
|
|
253
219
|
}
|
|
254
|
-
dbConnectionConfig(connection) {
|
|
255
|
-
const conf = this.
|
|
256
|
-
if (!conf)
|
|
220
|
+
dbConnectionConfig(connectionName, connection) {
|
|
221
|
+
const conf = this.dbCredentialsFor(connectionName)?.[connection] || this.dbCredentialsFor(connectionName)?.primary;
|
|
222
|
+
if (!conf) {
|
|
257
223
|
throw new Error(`
|
|
258
224
|
Cannot find a connection config given the following connection and node environment:
|
|
225
|
+
connectionName: ${connectionName}
|
|
259
226
|
connection: ${connection}
|
|
260
227
|
NODE_ENV: ${EnvInternal.nodeEnv}
|
|
261
228
|
`);
|
|
229
|
+
}
|
|
262
230
|
return conf;
|
|
263
231
|
}
|
|
264
|
-
|
|
265
|
-
|
|
232
|
+
dbConnectionQueryDriverClass(connectionName) {
|
|
233
|
+
const conf = this.dbCredentialsFor(connectionName);
|
|
234
|
+
if (!conf) {
|
|
235
|
+
throw new Error(`
|
|
236
|
+
Cannot find a db credentials for the given connectionName:
|
|
237
|
+
connectionName: ${connectionName}
|
|
238
|
+
NODE_ENV: ${EnvInternal.nodeEnv}
|
|
239
|
+
`);
|
|
240
|
+
}
|
|
241
|
+
return (conf.queryDriverClass) || (PostgresQueryDriver);
|
|
242
|
+
}
|
|
243
|
+
dbConnectionKeys() {
|
|
244
|
+
return Object.keys(this.dbCredentials);
|
|
245
|
+
}
|
|
246
|
+
hasReplicaConfig(connectionName) {
|
|
247
|
+
return !!this.dbCredentials[connectionName]?.replica;
|
|
266
248
|
}
|
|
267
249
|
get parallelDatabasesEnabled() {
|
|
268
250
|
return (!!this.parallelTests &&
|
|
@@ -283,10 +265,15 @@ Try setting it to something valid, like:
|
|
|
283
265
|
plugin(cb) {
|
|
284
266
|
this._plugins.push(cb);
|
|
285
267
|
}
|
|
286
|
-
set(applyOption, options) {
|
|
268
|
+
set(applyOption, options, secondaryOptions) {
|
|
287
269
|
switch (applyOption) {
|
|
288
270
|
case 'db':
|
|
289
|
-
|
|
271
|
+
if (typeof options === 'string') {
|
|
272
|
+
this._dbCredentials[options] = secondaryOptions;
|
|
273
|
+
}
|
|
274
|
+
else {
|
|
275
|
+
this._dbCredentials['default'] = options;
|
|
276
|
+
}
|
|
290
277
|
break;
|
|
291
278
|
case 'encryption':
|
|
292
279
|
this._encryption = options;
|
|
@@ -294,6 +281,9 @@ Try setting it to something valid, like:
|
|
|
294
281
|
case 'primaryKeyType':
|
|
295
282
|
this._primaryKeyType = options;
|
|
296
283
|
break;
|
|
284
|
+
case 'importExtension':
|
|
285
|
+
this._importExtension = options;
|
|
286
|
+
break;
|
|
297
287
|
case 'logger':
|
|
298
288
|
this._logger = options;
|
|
299
289
|
break;
|
|
@@ -356,3 +346,7 @@ function argToString(arg) {
|
|
|
356
346
|
return util.inspect(arg, { depth: 3 });
|
|
357
347
|
}
|
|
358
348
|
export const DreamAppAllowedPackageManagersEnumValues = ['yarn', 'npm', 'pnpm'];
|
|
349
|
+
// GeneratorImportStyles are used by CLI generators to determine how
|
|
350
|
+
// to style import suffixes. When integrating with other apps, this
|
|
351
|
+
// suffix style can change, and may need to be configured.
|
|
352
|
+
export const GeneratorImportStyles = ['.js', '.ts', 'none'];
|
|
@@ -1,11 +1,10 @@
|
|
|
1
|
-
import { sql } from 'kysely';
|
|
2
1
|
import * as fs from 'node:fs/promises';
|
|
3
2
|
import * as path from 'node:path';
|
|
4
3
|
import { CliFileWriter } from '../../cli/CliFileWriter.js';
|
|
5
|
-
import
|
|
6
|
-
import _db from '../../db/index.js';
|
|
4
|
+
import dbTypesFilenameForConnection from '../../db/helpers/dbTypesFilenameForConnection.js';
|
|
7
5
|
import DreamApp from '../../dream-app/index.js';
|
|
8
6
|
import { DreamConst } from '../../dream/constants.js';
|
|
7
|
+
import Query from '../../dream/Query.js';
|
|
9
8
|
import FailedToIdentifyAssociation from '../../errors/schema-builder/FailedToIdentifyAssociation.js';
|
|
10
9
|
import camelize from '../camelize.js';
|
|
11
10
|
import compact from '../compact.js';
|
|
@@ -16,7 +15,11 @@ import sortBy from '../sortBy.js';
|
|
|
16
15
|
import uniq from '../uniq.js';
|
|
17
16
|
import autogeneratedFileDisclaimer from './autoGeneratedFileDisclaimer.js';
|
|
18
17
|
export default class SchemaBuilder {
|
|
18
|
+
connectionName;
|
|
19
19
|
hasForeignKeyError = false;
|
|
20
|
+
constructor(connectionName) {
|
|
21
|
+
this.connectionName = connectionName;
|
|
22
|
+
}
|
|
20
23
|
async build() {
|
|
21
24
|
const { schemaConstContent, passthroughColumns, allDefaultScopeNames } = await this.buildSchemaContent();
|
|
22
25
|
const imports = await this.getSchemaImports(schemaConstContent);
|
|
@@ -37,19 +40,27 @@ ${importStr}
|
|
|
37
40
|
|
|
38
41
|
${schemaConstContent}
|
|
39
42
|
|
|
40
|
-
export const
|
|
43
|
+
export const connectionTypeConfig = {
|
|
41
44
|
passthroughColumns: ${stringifyArray(uniq(passthroughColumns.sort()), { indent: 4 })},
|
|
42
45
|
allDefaultScopeNames: ${stringifyArray(uniq(allDefaultScopeNames.sort()), { indent: 4 })},
|
|
43
46
|
globalNames: {
|
|
44
47
|
models: ${this.globalModelNames()},
|
|
45
|
-
serializers: ${stringifyArray(Object.keys(dreamApp.serializers || {}).sort(), { indent: 6 })},
|
|
46
48
|
},
|
|
47
49
|
} as const
|
|
48
50
|
`;
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
51
|
+
const schemaPath = this.connectionName === 'default'
|
|
52
|
+
? path.join(dreamApp.projectRoot, dreamApp.paths.types, 'dream.ts')
|
|
53
|
+
: path.join(dreamApp.projectRoot, dreamApp.paths.types, `dream.${camelize(this.connectionName)}.ts`);
|
|
54
|
+
await CliFileWriter.write(schemaPath, newSchemaFileContents);
|
|
55
|
+
}
|
|
56
|
+
static async buildGlobalTypes() {
|
|
57
|
+
const dreamApp = DreamApp.getOrFail();
|
|
58
|
+
const newSchemaFileContents = `\
|
|
59
|
+
export const globalTypeConfig = {
|
|
60
|
+
serializers: ${stringifyArray(Object.keys(dreamApp.serializers || {}).sort(), { indent: 6 })},
|
|
61
|
+
} as const
|
|
62
|
+
`;
|
|
63
|
+
const schemaPath = path.join(dreamApp.projectRoot, dreamApp.paths.types, 'dream.globals.ts');
|
|
53
64
|
await CliFileWriter.write(schemaPath, newSchemaFileContents);
|
|
54
65
|
}
|
|
55
66
|
globalModelNames() {
|
|
@@ -57,6 +68,7 @@ export const globalSchema = {
|
|
|
57
68
|
const models = dreamApp.models;
|
|
58
69
|
return `{
|
|
59
70
|
${Object.keys(models)
|
|
71
|
+
.filter(key => models[key]?.prototype?.connectionName === this.connectionName)
|
|
60
72
|
.map(key => `'${key}': '${models[key]?.prototype?.table}'`)
|
|
61
73
|
.join(',\n ')}
|
|
62
74
|
}`;
|
|
@@ -200,32 +212,8 @@ may need to update the table getter in the corresponding Dream.
|
|
|
200
212
|
};
|
|
201
213
|
}
|
|
202
214
|
async getColumnData(tableName, associationData) {
|
|
203
|
-
const
|
|
204
|
-
|
|
205
|
-
const columnToDBTypeMap = await sqlQuery.execute(db);
|
|
206
|
-
const rows = columnToDBTypeMap.rows;
|
|
207
|
-
const columnData = {};
|
|
208
|
-
rows.forEach(row => {
|
|
209
|
-
const isEnum = ['USER-DEFINED', 'ARRAY'].includes(row.dataType) && !isPrimitiveDataType(row.udtName);
|
|
210
|
-
const isArray = ['ARRAY'].includes(row.dataType);
|
|
211
|
-
const associationMetadata = associationData[row.columnName];
|
|
212
|
-
columnData[camelize(row.columnName)] = {
|
|
213
|
-
dbType: row.udtName,
|
|
214
|
-
allowNull: row.isNullable === 'YES',
|
|
215
|
-
enumType: isEnum ? this.enumType(row) : null,
|
|
216
|
-
enumValues: isEnum ? `${this.enumType(row)}Values` : null,
|
|
217
|
-
isArray,
|
|
218
|
-
foreignKey: associationMetadata?.foreignKey || null,
|
|
219
|
-
};
|
|
220
|
-
});
|
|
221
|
-
return Object.keys(columnData)
|
|
222
|
-
.sort()
|
|
223
|
-
.reduce((acc, key) => {
|
|
224
|
-
if (columnData[key] === undefined)
|
|
225
|
-
return acc;
|
|
226
|
-
acc[key] = columnData[key];
|
|
227
|
-
return acc;
|
|
228
|
-
}, {});
|
|
215
|
+
const dbDriverClass = Query.dbDriverClass(this.connectionName);
|
|
216
|
+
return await dbDriverClass.getColumnData(this.connectionName, tableName, associationData);
|
|
229
217
|
}
|
|
230
218
|
enumType(row) {
|
|
231
219
|
const enumName = pascalize(row.udtName.replace(/\[\]$/, ''));
|
|
@@ -385,7 +373,7 @@ may need to update the table getter in the corresponding Dream.
|
|
|
385
373
|
}
|
|
386
374
|
async loadDbSyncFile() {
|
|
387
375
|
const dreamApp = DreamApp.getOrFail();
|
|
388
|
-
const dbSyncPath = path.join(dreamApp.projectRoot, dreamApp.paths.types,
|
|
376
|
+
const dbSyncPath = path.join(dreamApp.projectRoot, dreamApp.paths.types, dbTypesFilenameForConnection(this.connectionName));
|
|
389
377
|
return (await fs.readFile(dbSyncPath)).toString();
|
|
390
378
|
}
|
|
391
379
|
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import DreamApp from '../../dream-app/index.js';
|
|
2
|
+
export default function addImportSuffix(filepath) {
|
|
3
|
+
return `${filepath.replace(/(\.ts|\.js)$/, '')}${suffix()}`;
|
|
4
|
+
}
|
|
5
|
+
function suffix() {
|
|
6
|
+
switch (DreamApp.getOrFail().importExtension) {
|
|
7
|
+
case '.js':
|
|
8
|
+
return '.js';
|
|
9
|
+
case '.ts':
|
|
10
|
+
return '.ts';
|
|
11
|
+
case 'none':
|
|
12
|
+
return '';
|
|
13
|
+
}
|
|
14
|
+
}
|
|
@@ -19,6 +19,7 @@ export default async function generateDream({ fullyQualifiedModelName, columnsWi
|
|
|
19
19
|
fullyQualifiedParentName,
|
|
20
20
|
serializer: options.serializer,
|
|
21
21
|
includeAdminSerializers: options.includeAdminSerializers,
|
|
22
|
+
connectionName: options.connectionName,
|
|
22
23
|
}));
|
|
23
24
|
}
|
|
24
25
|
catch (error) {
|
|
@@ -43,6 +44,7 @@ export default async function generateDream({ fullyQualifiedModelName, columnsWi
|
|
|
43
44
|
const isSTI = !!fullyQualifiedParentName;
|
|
44
45
|
if (columnsWithTypes.length || !isSTI) {
|
|
45
46
|
await generateMigration({
|
|
47
|
+
connectionName: options.connectionName,
|
|
46
48
|
migrationName: `Create${fullyQualifiedModelName}`,
|
|
47
49
|
columnsWithTypes,
|
|
48
50
|
fullyQualifiedModelName,
|
|
@@ -6,7 +6,8 @@ import relativeDreamPath from '../path/relativeDreamPath.js';
|
|
|
6
6
|
import snakeify from '../snakeify.js';
|
|
7
7
|
import standardizeFullyQualifiedModelName from '../standardizeFullyQualifiedModelName.js';
|
|
8
8
|
import uniq from '../uniq.js';
|
|
9
|
-
|
|
9
|
+
import pascalize from '../pascalize.js';
|
|
10
|
+
export default function generateDreamContent({ fullyQualifiedModelName, columnsWithTypes, fullyQualifiedParentName, serializer, includeAdminSerializers, connectionName = 'default', }) {
|
|
10
11
|
fullyQualifiedModelName = standardizeFullyQualifiedModelName(fullyQualifiedModelName);
|
|
11
12
|
const modelClassName = globalClassNameFromFullyQualifiedModelName(fullyQualifiedModelName);
|
|
12
13
|
let parentModelClassName;
|
|
@@ -20,9 +21,10 @@ export default function generateDreamContent({ fullyQualifiedModelName, columnsW
|
|
|
20
21
|
dreamImports.push('STI');
|
|
21
22
|
}
|
|
22
23
|
const idTypescriptType = `DreamColumn<${modelClassName}, 'id'>`;
|
|
24
|
+
const applicationModelName = connectionName === 'default' ? 'ApplicationModel' : `${pascalize(connectionName)}ApplicationModel`;
|
|
23
25
|
const modelImportStatements = isSTI
|
|
24
26
|
? [importStatementForModel(fullyQualifiedModelName, fullyQualifiedParentName)]
|
|
25
|
-
: [importStatementForModel(fullyQualifiedModelName,
|
|
27
|
+
: [importStatementForModel(fullyQualifiedModelName, applicationModelName)];
|
|
26
28
|
const attributeStatements = columnsWithTypes.map(attribute => {
|
|
27
29
|
const [attributeName, attributeType, ...descriptors] = attribute.split(':');
|
|
28
30
|
if (attributeName === undefined)
|
|
@@ -78,7 +80,7 @@ import { ${uniq(dreamImports).join(', ')} } from '@rvoh/dream'${uniq(modelImport
|
|
|
78
80
|
const deco = new Decorators<typeof ${modelClassName}>()
|
|
79
81
|
|
|
80
82
|
${isSTI ? `\n@STI(${parentModelClassName})` : ''}
|
|
81
|
-
export default class ${modelClassName} extends ${isSTI ? parentModelClassName :
|
|
83
|
+
export default class ${modelClassName} extends ${isSTI ? parentModelClassName : applicationModelName} {
|
|
82
84
|
${isSTI
|
|
83
85
|
? ''
|
|
84
86
|
: ` public override get table() {
|
|
@@ -44,27 +44,56 @@ export default function generateFactoryContent({ fullyQualifiedModelName, column
|
|
|
44
44
|
attributeDefaults.push(`${attributeVariable}: \`${fullyQualifiedModelName} ${attributeVariable} ${counterVariableIncremented ? '${counter}' : '${++counter}'}\`,`);
|
|
45
45
|
counterVariableIncremented = true;
|
|
46
46
|
break;
|
|
47
|
+
case 'string[]':
|
|
48
|
+
case 'text[]':
|
|
49
|
+
case 'citext[]':
|
|
50
|
+
attributeDefaults.push(`${attributeVariable}: [\`${fullyQualifiedModelName} ${attributeVariable} ${counterVariableIncremented ? '${counter}' : '${++counter}'}\`],`);
|
|
51
|
+
counterVariableIncremented = true;
|
|
52
|
+
break;
|
|
47
53
|
case 'enum':
|
|
48
54
|
attributeDefaults.push(`${attributeVariable}: '${(descriptors.at(-1) || '<tbd>').split(',')[0]}',`);
|
|
49
55
|
break;
|
|
56
|
+
case 'enum[]':
|
|
57
|
+
attributeDefaults.push(`${attributeVariable}: ['${(descriptors.at(-1) || '<tbd>').split(',')[0]}'],`);
|
|
58
|
+
break;
|
|
50
59
|
case 'integer':
|
|
51
60
|
attributeDefaults.push(`${attributeVariable}: 1,`);
|
|
52
61
|
break;
|
|
62
|
+
case 'integer[]':
|
|
63
|
+
attributeDefaults.push(`${attributeVariable}: [1],`);
|
|
64
|
+
break;
|
|
53
65
|
case 'bigint':
|
|
54
66
|
attributeDefaults.push(`${attributeVariable}: '11111111111111111',`);
|
|
55
67
|
break;
|
|
68
|
+
case 'bigint[]':
|
|
69
|
+
attributeDefaults.push(`${attributeVariable}: ['11111111111111111'],`);
|
|
70
|
+
break;
|
|
56
71
|
case 'decimal':
|
|
57
72
|
attributeDefaults.push(`${attributeVariable}: 1.1,`);
|
|
58
73
|
break;
|
|
74
|
+
case 'decimal[]':
|
|
75
|
+
attributeDefaults.push(`${attributeVariable}: [1.1],`);
|
|
76
|
+
break;
|
|
59
77
|
case 'date':
|
|
60
78
|
dreamImports.push('CalendarDate');
|
|
61
79
|
attributeDefaults.push(`${attributeVariable}: CalendarDate.today(),`);
|
|
62
80
|
break;
|
|
81
|
+
case 'date[]':
|
|
82
|
+
dreamImports.push('CalendarDate');
|
|
83
|
+
attributeDefaults.push(`${attributeVariable}: [CalendarDate.today()],`);
|
|
84
|
+
break;
|
|
63
85
|
case 'datetime':
|
|
64
86
|
dreamImports.push('DateTime');
|
|
65
87
|
attributeDefaults.push(`${attributeVariable}: DateTime.now(),`);
|
|
66
88
|
break;
|
|
89
|
+
case 'datetime[]':
|
|
90
|
+
dreamImports.push('DateTime');
|
|
91
|
+
attributeDefaults.push(`${attributeVariable}: [DateTime.now()],`);
|
|
92
|
+
break;
|
|
67
93
|
default:
|
|
94
|
+
if (/\[\]$/.test(attributeType)) {
|
|
95
|
+
attributeDefaults.push(`${attributeVariable}: [],`);
|
|
96
|
+
}
|
|
68
97
|
// noop
|
|
69
98
|
}
|
|
70
99
|
}
|