@rvoh/dream 2.36.0 → 2.37.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/dist/cjs/src/Dream.js +3 -1
- package/dist/cjs/src/db/dataTypes.js +0 -8
- package/dist/cjs/src/decorators/field/Encrypted.js +8 -3
- package/dist/cjs/src/dream/QueryDriver/Base.js +17 -24
- package/dist/cjs/src/dream/QueryDriver/Kysely.js +22 -23
- package/dist/cjs/src/dream/QueryDriver/Postgres.js +113 -31
- package/dist/cjs/src/encrypt/InternalEncrypt.js +28 -0
- package/dist/cjs/src/helpers/cli/ASTBuilder.js +11 -202
- package/dist/cjs/src/helpers/cli/ASTConnectionBuilder.js +97 -75
- package/dist/cjs/src/helpers/cli/ASTDbTypesBuilder.js +132 -0
- package/dist/cjs/src/helpers/cli/ASTSchemaBuilder.js +37 -81
- package/dist/cjs/src/helpers/cli/dbTypesNaming.js +90 -0
- package/dist/cjs/src/helpers/cli/tableMatchesPattern.js +21 -0
- package/dist/esm/src/Dream.js +3 -1
- package/dist/esm/src/db/dataTypes.js +0 -8
- package/dist/esm/src/decorators/field/Encrypted.js +8 -3
- package/dist/esm/src/dream/QueryDriver/Base.js +17 -24
- package/dist/esm/src/dream/QueryDriver/Kysely.js +22 -23
- package/dist/esm/src/dream/QueryDriver/Postgres.js +113 -31
- package/dist/esm/src/encrypt/InternalEncrypt.js +28 -0
- package/dist/esm/src/helpers/cli/ASTBuilder.js +11 -202
- package/dist/esm/src/helpers/cli/ASTConnectionBuilder.js +97 -75
- package/dist/esm/src/helpers/cli/ASTDbTypesBuilder.js +132 -0
- package/dist/esm/src/helpers/cli/ASTSchemaBuilder.js +37 -81
- package/dist/esm/src/helpers/cli/dbTypesNaming.js +90 -0
- package/dist/esm/src/helpers/cli/tableMatchesPattern.js +21 -0
- package/dist/types/src/Dream.d.ts +3 -1
- package/dist/types/src/db/dataTypes.d.ts +0 -2
- package/dist/types/src/dream/QueryDriver/Base.d.ts +16 -18
- package/dist/types/src/dream/QueryDriver/Kysely.d.ts +0 -9
- package/dist/types/src/dream/QueryDriver/Postgres.d.ts +9 -9
- package/dist/types/src/dream-app/index.d.ts +12 -12
- package/dist/types/src/encrypt/InternalEncrypt.d.ts +9 -0
- package/dist/types/src/helpers/cli/ASTBuilder.d.ts +11 -101
- package/dist/types/src/helpers/cli/ASTConnectionBuilder.d.ts +40 -37
- package/dist/types/src/helpers/cli/ASTDbTypesBuilder.d.ts +26 -0
- package/dist/types/src/helpers/cli/ASTSchemaBuilder.d.ts +5 -15
- package/dist/types/src/helpers/cli/dbTypesNaming.d.ts +37 -0
- package/dist/types/src/helpers/cli/tableMatchesPattern.d.ts +15 -0
- package/dist/types/src/package-exports/types.d.ts +1 -1
- package/dist/types/src/types/db.d.ts +71 -0
- package/dist/types/src/types/types/db.ts +91 -0
- package/docs/assets/hierarchy.js +1 -1
- package/docs/assets/navigation.js +1 -1
- package/docs/assets/search.js +1 -1
- package/docs/classes/db.DreamMigrationHelpers.html +11 -11
- package/docs/classes/db.KyselyQueryDriver.html +55 -54
- package/docs/classes/db.PostgresQueryDriver.html +56 -56
- package/docs/classes/db.QueryDriverBase.html +60 -59
- package/docs/classes/errors.CannotSaveMissingDream.html +2 -2
- package/docs/classes/errors.CheckConstraintViolation.html +3 -3
- package/docs/classes/errors.ColumnOverflow.html +3 -3
- package/docs/classes/errors.CreateOrFindByFailedToCreateAndFind.html +3 -3
- package/docs/classes/errors.DataIncompatibleWithDatabaseField.html +3 -3
- package/docs/classes/errors.DataTypeColumnTypeMismatch.html +3 -3
- package/docs/classes/errors.DecryptionError.html +2 -2
- package/docs/classes/errors.DecryptionParseError.html +2 -2
- package/docs/classes/errors.DecryptionRotationError.html +3 -3
- package/docs/classes/errors.GlobalNameNotSet.html +3 -3
- package/docs/classes/errors.InvalidCalendarDate.html +2 -2
- package/docs/classes/errors.InvalidClockTime.html +2 -2
- package/docs/classes/errors.InvalidClockTimeTz.html +2 -2
- package/docs/classes/errors.InvalidDateTime.html +2 -2
- package/docs/classes/errors.MissingSerializersDefinition.html +3 -3
- package/docs/classes/errors.NonLoadedAssociation.html +3 -3
- package/docs/classes/errors.NotNullViolation.html +3 -3
- package/docs/classes/errors.RecordNotFound.html +3 -3
- package/docs/classes/errors.SortableScopeDidNotStabilize.html +3 -3
- package/docs/classes/errors.SortableScopeLockWaitTimedOut.html +3 -3
- package/docs/classes/errors.ValidationError.html +3 -3
- package/docs/classes/index.CalendarDate.html +33 -33
- package/docs/classes/index.ClockTime.html +32 -32
- package/docs/classes/index.ClockTimeTz.html +35 -35
- package/docs/classes/index.DateTime.html +86 -86
- package/docs/classes/index.Decorators.html +19 -19
- package/docs/classes/index.Dream.html +125 -125
- package/docs/classes/index.DreamApp.html +11 -11
- package/docs/classes/index.DreamTransaction.html +3 -3
- package/docs/classes/index.Env.html +5 -5
- package/docs/classes/index.Query.html +65 -65
- package/docs/classes/system.CliFileWriter.html +4 -4
- package/docs/classes/system.DreamBin.html +3 -3
- package/docs/classes/system.DreamCLI.html +7 -7
- package/docs/classes/system.DreamImporter.html +2 -2
- package/docs/classes/system.DreamLogos.html +2 -2
- package/docs/classes/system.DreamSerializerBuilder.html +11 -11
- package/docs/classes/system.ObjectSerializerBuilder.html +8 -8
- package/docs/classes/system.PathHelpers.html +3 -3
- package/docs/classes/utils.Encrypt.html +4 -4
- package/docs/classes/utils.Range.html +2 -2
- package/docs/functions/db.closeAllDbConnections.html +1 -1
- package/docs/functions/db.dreamDbConnections.html +1 -1
- package/docs/functions/db.untypedDb.html +1 -1
- package/docs/functions/db.validateColumn.html +1 -1
- package/docs/functions/db.validateTable.html +1 -1
- package/docs/functions/errors.pgErrorType.html +1 -1
- package/docs/functions/index.DreamSerializer.html +1 -1
- package/docs/functions/index.ObjectSerializer.html +1 -1
- package/docs/functions/index.ReplicaSafe.html +1 -1
- package/docs/functions/index.STI.html +1 -1
- package/docs/functions/index.SoftDelete.html +1 -1
- package/docs/functions/utils.camelize.html +1 -1
- package/docs/functions/utils.capitalize.html +1 -1
- package/docs/functions/utils.cloneDeepSafe.html +1 -1
- package/docs/functions/utils.compact.html +1 -1
- package/docs/functions/utils.groupBy.html +1 -1
- package/docs/functions/utils.hyphenize.html +1 -1
- package/docs/functions/utils.intersection.html +1 -1
- package/docs/functions/utils.isEmpty.html +1 -1
- package/docs/functions/utils.normalizeUnicode.html +1 -1
- package/docs/functions/utils.pascalize.html +1 -1
- package/docs/functions/utils.percent.html +1 -1
- package/docs/functions/utils.range.html +1 -1
- package/docs/functions/utils.round.html +1 -1
- package/docs/functions/utils.sanitizeString.html +1 -1
- package/docs/functions/utils.snakeify.html +1 -1
- package/docs/functions/utils.sort.html +1 -1
- package/docs/functions/utils.sortBy.html +1 -1
- package/docs/functions/utils.sortObjectByKey.html +1 -1
- package/docs/functions/utils.sortObjectByValue.html +1 -1
- package/docs/functions/utils.uncapitalize.html +1 -1
- package/docs/functions/utils.uniq.html +1 -1
- package/docs/hierarchy.html +1 -1
- package/docs/interfaces/openapi.OpenapiDescription.html +2 -2
- package/docs/interfaces/openapi.OpenapiSchemaProperties.html +1 -1
- package/docs/interfaces/openapi.OpenapiSchemaPropertiesShorthand.html +1 -1
- package/docs/interfaces/openapi.OpenapiTypeFieldObject.html +1 -1
- package/docs/interfaces/types.BelongsToStatement.html +2 -2
- package/docs/interfaces/types.DecoratorContext.html +2 -2
- package/docs/interfaces/types.DecryptCallbacks.html +2 -2
- package/docs/interfaces/types.DreamAppInitOptions.html +2 -2
- package/docs/interfaces/types.DreamAppOpts.html +2 -2
- package/docs/interfaces/types.DreamDbConfig.html +6 -6
- package/docs/interfaces/types.DurationObject.html +2 -2
- package/docs/interfaces/types.EncryptOptions.html +2 -2
- package/docs/interfaces/types.EncryptionLegacyKeyUsedEvent.html +4 -4
- package/docs/interfaces/types.InternalAnyTypedSerializerRendersMany.html +2 -2
- package/docs/interfaces/types.InternalAnyTypedSerializerRendersOne.html +2 -2
- package/docs/interfaces/types.IntrospectedColumn.html +17 -0
- package/docs/interfaces/types.IntrospectedDatabase.html +7 -0
- package/docs/interfaces/types.IntrospectedEnum.html +5 -0
- package/docs/interfaces/types.IntrospectedTable.html +11 -0
- package/docs/interfaces/types.SerializerRendererOpts.html +2 -2
- package/docs/modules/types.html +1 -1
- package/docs/types/openapi.CommonOpenapiSchemaObjectFields.html +1 -1
- package/docs/types/openapi.OpenapiAllTypes.html +1 -1
- package/docs/types/openapi.OpenapiFormats.html +1 -1
- package/docs/types/openapi.OpenapiNumberFormats.html +1 -1
- package/docs/types/openapi.OpenapiPrimitiveBaseTypes.html +1 -1
- package/docs/types/openapi.OpenapiPrimitiveTypes.html +1 -1
- package/docs/types/openapi.OpenapiSchemaArray.html +1 -1
- package/docs/types/openapi.OpenapiSchemaArrayShorthand.html +1 -1
- package/docs/types/openapi.OpenapiSchemaBase.html +1 -1
- package/docs/types/openapi.OpenapiSchemaBody.html +1 -1
- package/docs/types/openapi.OpenapiSchemaBodyShorthand.html +1 -1
- package/docs/types/openapi.OpenapiSchemaCombinatorFields.html +1 -1
- package/docs/types/openapi.OpenapiSchemaCommonFields.html +1 -1
- package/docs/types/openapi.OpenapiSchemaExpressionAllOf.html +1 -1
- package/docs/types/openapi.OpenapiSchemaExpressionAnyOf.html +1 -1
- package/docs/types/openapi.OpenapiSchemaExpressionOneOf.html +1 -1
- package/docs/types/openapi.OpenapiSchemaExpressionRef.html +2 -2
- package/docs/types/openapi.OpenapiSchemaExpressionRefSchemaShorthand.html +2 -2
- package/docs/types/openapi.OpenapiSchemaInteger.html +1 -1
- package/docs/types/openapi.OpenapiSchemaNull.html +2 -2
- package/docs/types/openapi.OpenapiSchemaNumber.html +1 -1
- package/docs/types/openapi.OpenapiSchemaObject.html +1 -1
- package/docs/types/openapi.OpenapiSchemaObjectAllOf.html +1 -1
- package/docs/types/openapi.OpenapiSchemaObjectAllOfShorthand.html +1 -1
- package/docs/types/openapi.OpenapiSchemaObjectBase.html +1 -1
- package/docs/types/openapi.OpenapiSchemaObjectBaseShorthand.html +1 -1
- package/docs/types/openapi.OpenapiSchemaObjectShorthand.html +1 -1
- package/docs/types/openapi.OpenapiSchemaPrimitiveGeneric.html +1 -1
- package/docs/types/openapi.OpenapiSchemaShorthandExpressionAllOf.html +1 -1
- package/docs/types/openapi.OpenapiSchemaShorthandExpressionAnyOf.html +1 -1
- package/docs/types/openapi.OpenapiSchemaShorthandExpressionOneOf.html +1 -1
- package/docs/types/openapi.OpenapiSchemaShorthandExpressionSerializableRef.html +2 -2
- package/docs/types/openapi.OpenapiSchemaShorthandExpressionSerializerRef.html +2 -2
- package/docs/types/openapi.OpenapiSchemaShorthandPrimitiveGeneric.html +1 -1
- package/docs/types/openapi.OpenapiSchemaString.html +1 -1
- package/docs/types/openapi.OpenapiShorthandAllTypes.html +1 -1
- package/docs/types/openapi.OpenapiShorthandPrimitiveBaseTypes.html +1 -1
- package/docs/types/openapi.OpenapiShorthandPrimitiveTypes.html +1 -1
- package/docs/types/openapi.OpenapiTypeField.html +1 -1
- package/docs/types/system.DreamAppAllowedPackageManagersEnum.html +1 -1
- package/docs/types/types.CalendarDateDurationUnit.html +1 -1
- package/docs/types/types.CalendarDateObject.html +1 -1
- package/docs/types/types.Camelized.html +1 -1
- package/docs/types/types.ClockTimeObject.html +1 -1
- package/docs/types/types.DbConnectionType.html +1 -1
- package/docs/types/types.DbTypes.html +1 -1
- package/docs/types/types.DreamAssociationMetadata.html +1 -1
- package/docs/types/types.DreamAttributes.html +1 -1
- package/docs/types/types.DreamClassAssociationAndStatement.html +1 -1
- package/docs/types/types.DreamClassColumn.html +1 -1
- package/docs/types/types.DreamColumn.html +1 -1
- package/docs/types/types.DreamColumnNames.html +1 -1
- package/docs/types/types.DreamLogLevel.html +1 -1
- package/docs/types/types.DreamLogger.html +2 -2
- package/docs/types/types.DreamModelSerializerType.html +1 -1
- package/docs/types/types.DreamOrViewModelClassSerializerKey.html +1 -1
- package/docs/types/types.DreamOrViewModelSerializerKey.html +1 -1
- package/docs/types/types.DreamParamSafeAttributes.html +1 -1
- package/docs/types/types.DreamParamSafeColumnNames.html +1 -1
- package/docs/types/types.DreamSerializable.html +1 -1
- package/docs/types/types.DreamSerializableArray.html +1 -1
- package/docs/types/types.DreamSerializerKey.html +1 -1
- package/docs/types/types.DreamSerializers.html +1 -1
- package/docs/types/types.DreamVirtualColumns.html +1 -1
- package/docs/types/types.DurationUnit.html +1 -1
- package/docs/types/types.EncryptAlgorithm.html +1 -1
- package/docs/types/types.HasManyStatement.html +1 -1
- package/docs/types/types.HasOneStatement.html +1 -1
- package/docs/types/types.Hyphenized.html +1 -1
- package/docs/types/types.IntrospectedValueType.html +5 -0
- package/docs/types/types.Pascalized.html +1 -1
- package/docs/types/types.PrimaryKeyType.html +1 -1
- package/docs/types/types.RoundingPrecision.html +1 -1
- package/docs/types/types.SerializerCasing.html +1 -1
- package/docs/types/types.SimpleObjectSerializerType.html +1 -1
- package/docs/types/types.Snakeified.html +1 -1
- package/docs/types/types.StrictInterface.html +1 -1
- package/docs/types/types.UpdateableAssociationProperties.html +1 -1
- package/docs/types/types.UpdateableProperties.html +1 -1
- package/docs/types/types.ValidationType.html +1 -1
- package/docs/types/types.ViewModel.html +2 -2
- package/docs/types/types.ViewModelClass.html +1 -1
- package/docs/types/types.WeekdayName.html +1 -1
- package/docs/types/types.WhereStatementForDream.html +1 -1
- package/docs/types/types.WhereStatementForDreamClass.html +1 -1
- package/docs/variables/index.DreamConst.html +1 -1
- package/docs/variables/index.ops.html +1 -1
- package/docs/variables/openapi.openapiPrimitiveTypes.html +1 -1
- package/docs/variables/openapi.openapiShorthandPrimitiveTypes.html +1 -1
- package/docs/variables/system.DreamAppAllowedPackageManagersEnumValues.html +1 -1
- package/docs/variables/system.primaryKeyTypes.html +1 -1
- package/package.json +6 -3
- package/dist/cjs/src/db/helpers/syncDbTypesFiles.js +0 -41
- package/dist/cjs/src/helpers/cli/ASTKyselyCodegenEnhancer.js +0 -380
- package/dist/esm/src/db/helpers/syncDbTypesFiles.js +0 -41
- package/dist/esm/src/helpers/cli/ASTKyselyCodegenEnhancer.js +0 -380
- package/dist/types/src/db/helpers/syncDbTypesFiles.d.ts +0 -1
- package/dist/types/src/helpers/cli/ASTKyselyCodegenEnhancer.d.ts +0 -94
|
@@ -1,380 +0,0 @@
|
|
|
1
|
-
import ts from 'typescript';
|
|
2
|
-
import { CliFileWriter } from '../../cli/CliFileWriter.js';
|
|
3
|
-
import camelize from '../camelize.js';
|
|
4
|
-
import snakeify from '../snakeify.js';
|
|
5
|
-
import ASTConnectionBuilder from './ASTConnectionBuilder.js';
|
|
6
|
-
import autogeneratedFileDisclaimer from './autoGeneratedFileDisclaimer.js';
|
|
7
|
-
const f = ts.factory;
|
|
8
|
-
/**
|
|
9
|
-
* Responsible for enhancing the kysely-codegen output, which can be found at
|
|
10
|
-
* types/db.ts. If you are leveraging multiple db connections,
|
|
11
|
-
* then this file will also be responsible for building all variants,
|
|
12
|
-
* i.e. types/db.alternateConnection.ts, etc...
|
|
13
|
-
*
|
|
14
|
-
* This class leverages internal AST building mechanisms built into
|
|
15
|
-
* typescript to manually build up object literals and interfaces
|
|
16
|
-
* for our app to consume.
|
|
17
|
-
*/
|
|
18
|
-
export default class ASTKyselyCodegenEnhancer extends ASTConnectionBuilder {
|
|
19
|
-
/**
|
|
20
|
-
* enhances the kysely codegen output for the given connection name
|
|
21
|
-
* by reading the relevant db.ts file into AST nodes, then enhancing them
|
|
22
|
-
* with a variety of transformations necessary to lock this file in with
|
|
23
|
-
* our other schema files, allowing types to flow correctly throughout the app.
|
|
24
|
-
*/
|
|
25
|
-
async enhance() {
|
|
26
|
-
let dbSourceFile = await this.getDbSourceFile();
|
|
27
|
-
dbSourceFile = this.camelizeKeys(dbSourceFile);
|
|
28
|
-
dbSourceFile = this.removeIgnoredColumns(dbSourceFile);
|
|
29
|
-
dbSourceFile = this.replaceTimestampExport(dbSourceFile);
|
|
30
|
-
dbSourceFile = await this.replaceTimeFieldsInInterfaces(dbSourceFile);
|
|
31
|
-
dbSourceFile = this.addMissingImports(dbSourceFile);
|
|
32
|
-
dbSourceFile = this.replaceInt8Export(dbSourceFile);
|
|
33
|
-
dbSourceFile = this.sortExportedInterfacesTransformer(dbSourceFile);
|
|
34
|
-
dbSourceFile = await this.addEnumValueExports(dbSourceFile);
|
|
35
|
-
dbSourceFile = this.addDeprecatedDbClassExportForBackwardsCompatibility(dbSourceFile);
|
|
36
|
-
const output = this.printOutput(dbSourceFile);
|
|
37
|
-
const finalOutput = await this.prettier(`\
|
|
38
|
-
${autogeneratedFileDisclaimer()}
|
|
39
|
-
${output}`);
|
|
40
|
-
await CliFileWriter.write(this.dbPath(), finalOutput);
|
|
41
|
-
}
|
|
42
|
-
addDeprecatedDbClassExportForBackwardsCompatibility(dbSourceFile) {
|
|
43
|
-
const transformer = () => {
|
|
44
|
-
return sourceFile => {
|
|
45
|
-
const dbInterface = this.findDbExport(sourceFile, 'DB');
|
|
46
|
-
if (!dbInterface)
|
|
47
|
-
return sourceFile;
|
|
48
|
-
const classDec = ts.factory.createClassDeclaration([ts.factory.createModifier(ts.SyntaxKind.ExportKeyword)], ts.factory.createIdentifier('DBClass'), undefined, [], dbInterface.members.filter(ts.isPropertySignature).map(propertySignature => {
|
|
49
|
-
return f.createPropertyDeclaration([], propertySignature.name, undefined, propertySignature.type, undefined);
|
|
50
|
-
}));
|
|
51
|
-
return ts.factory.updateSourceFile(sourceFile, [...sourceFile.statements, classDec], sourceFile.isDeclarationFile, sourceFile.referencedFiles, sourceFile.typeReferenceDirectives, undefined);
|
|
52
|
-
};
|
|
53
|
-
};
|
|
54
|
-
const result = ts.transform(dbSourceFile, [transformer]);
|
|
55
|
-
return result.transformed[0];
|
|
56
|
-
}
|
|
57
|
-
/**
|
|
58
|
-
* @internal
|
|
59
|
-
*
|
|
60
|
-
* returns the output of the provided dbSourceFile, ensuring that all exports
|
|
61
|
-
* have a new line above them.
|
|
62
|
-
*/
|
|
63
|
-
printOutput(dbSourceFile) {
|
|
64
|
-
const printer = ts.createPrinter({ newLine: ts.NewLineKind.LineFeed });
|
|
65
|
-
const output = printer.printNode(ts.EmitHint.SourceFile, dbSourceFile, dbSourceFile);
|
|
66
|
-
return output.replace(/export /g, '\nexport ');
|
|
67
|
-
}
|
|
68
|
-
/**
|
|
69
|
-
* @internal
|
|
70
|
-
*
|
|
71
|
-
* ensures that the `Timestamp` exported from db.ts points correctly to either
|
|
72
|
-
* the DateTime or CalendarDate class, depending on the db type.
|
|
73
|
-
*/
|
|
74
|
-
replaceTimestampExport(dbSourceFile) {
|
|
75
|
-
const transformer = context => {
|
|
76
|
-
return rootNode => {
|
|
77
|
-
const visit = (node) => {
|
|
78
|
-
const typeAlias = this.exportedTypeAliasOrNull(node, 'Timestamp');
|
|
79
|
-
if (typeAlias) {
|
|
80
|
-
const updatedNode = f.updateTypeAliasDeclaration(typeAlias, typeAlias.modifiers, typeAlias.name, typeAlias.typeParameters, f.createTypeReferenceNode('ColumnType', [
|
|
81
|
-
f.createUnionTypeNode([
|
|
82
|
-
f.createTypeReferenceNode(f.createIdentifier('DateTime')),
|
|
83
|
-
f.createTypeReferenceNode(f.createIdentifier('CalendarDate')),
|
|
84
|
-
]),
|
|
85
|
-
]));
|
|
86
|
-
return updatedNode;
|
|
87
|
-
}
|
|
88
|
-
return ts.visitEachChild(node, visit, context);
|
|
89
|
-
};
|
|
90
|
-
return ts.visitNode(rootNode, visit);
|
|
91
|
-
};
|
|
92
|
-
};
|
|
93
|
-
const result = ts.transform(dbSourceFile, [transformer]);
|
|
94
|
-
return result.transformed[0];
|
|
95
|
-
}
|
|
96
|
-
/**
|
|
97
|
-
* @internal
|
|
98
|
-
*
|
|
99
|
-
* Replaces string types with TimeWithZone or TimeWithoutZone for TIME columns
|
|
100
|
-
* based on the schema metadata from dream.ts
|
|
101
|
-
*/
|
|
102
|
-
async replaceTimeFieldsInInterfaces(dbSourceFile) {
|
|
103
|
-
const schemaData = await this.getSchemaData();
|
|
104
|
-
const transformer = context => {
|
|
105
|
-
return sourceFile => {
|
|
106
|
-
const visitor = (node) => {
|
|
107
|
-
if (ts.isInterfaceDeclaration(node) && node.name.text !== 'DB') {
|
|
108
|
-
const tableName = snakeify(node.name.text);
|
|
109
|
-
const tableSchema = schemaData[tableName];
|
|
110
|
-
if (!tableSchema) {
|
|
111
|
-
return ts.visitEachChild(node, visitor, context);
|
|
112
|
-
}
|
|
113
|
-
const updatedMembers = node.members.map(member => {
|
|
114
|
-
if (ts.isPropertySignature(member) && ts.isIdentifier(member.name)) {
|
|
115
|
-
const columnName = member.name.text;
|
|
116
|
-
const columnSchema = tableSchema.columns[columnName];
|
|
117
|
-
if (!columnSchema)
|
|
118
|
-
return member;
|
|
119
|
-
const dbType = columnSchema.dbType;
|
|
120
|
-
// Check if this is a TIME field that's currently typed as string
|
|
121
|
-
if (this.isTimeDbType(dbType) && member.type) {
|
|
122
|
-
const isTimeTz = this.isTimeWithTimeZoneDbType(dbType);
|
|
123
|
-
const newType = this.replaceStringWithClockTimeType(member.type, sourceFile, isTimeTz);
|
|
124
|
-
if (newType !== member.type) {
|
|
125
|
-
return f.updatePropertySignature(member, member.modifiers, member.name, member.questionToken, newType);
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
return member;
|
|
130
|
-
});
|
|
131
|
-
return f.updateInterfaceDeclaration(node, node.modifiers, node.name, node.typeParameters, node.heritageClauses, updatedMembers);
|
|
132
|
-
}
|
|
133
|
-
return ts.visitEachChild(node, visitor, context);
|
|
134
|
-
};
|
|
135
|
-
return ts.visitNode(sourceFile, visitor);
|
|
136
|
-
};
|
|
137
|
-
};
|
|
138
|
-
const result = ts.transform(dbSourceFile, [transformer]);
|
|
139
|
-
return result.transformed[0];
|
|
140
|
-
}
|
|
141
|
-
/**
|
|
142
|
-
* @internal
|
|
143
|
-
*
|
|
144
|
-
* Helper to replace string type references with ClockTime or ClockTimeTz type references
|
|
145
|
-
*/
|
|
146
|
-
replaceStringWithClockTimeType(typeNode, sourceFile, isTimeTz) {
|
|
147
|
-
const toTimeType = () => f.createTypeReferenceNode(f.createIdentifier(isTimeTz ? 'ClockTimeTz' : 'ClockTime'));
|
|
148
|
-
// Handle union types (e.g., string | null)
|
|
149
|
-
if (ts.isUnionTypeNode(typeNode)) {
|
|
150
|
-
const updatedTypes = typeNode.types.map(t => this.replaceStringWithClockTimeType(t, sourceFile, isTimeTz));
|
|
151
|
-
return f.createUnionTypeNode(updatedTypes);
|
|
152
|
-
}
|
|
153
|
-
// Handle array syntax (e.g., string[])
|
|
154
|
-
if (ts.isArrayTypeNode(typeNode)) {
|
|
155
|
-
const elementType = this.isStringLikeType(typeNode.elementType, sourceFile)
|
|
156
|
-
? toTimeType()
|
|
157
|
-
: this.replaceStringWithClockTimeType(typeNode.elementType, sourceFile, isTimeTz);
|
|
158
|
-
return f.createArrayTypeNode(elementType);
|
|
159
|
-
}
|
|
160
|
-
// Handle generic array syntax (e.g., Array<string>)
|
|
161
|
-
if (ts.isTypeReferenceNode(typeNode) &&
|
|
162
|
-
typeNode.typeName.getText(sourceFile) === 'Array' &&
|
|
163
|
-
typeNode.typeArguments?.length === 1) {
|
|
164
|
-
const arg = typeNode.typeArguments?.[0];
|
|
165
|
-
if (!arg)
|
|
166
|
-
return typeNode;
|
|
167
|
-
const nextArg = this.isStringLikeType(arg, sourceFile)
|
|
168
|
-
? toTimeType()
|
|
169
|
-
: this.replaceStringWithClockTimeType(arg, sourceFile, isTimeTz);
|
|
170
|
-
return f.createTypeReferenceNode(f.createIdentifier('Array'), [nextArg]);
|
|
171
|
-
}
|
|
172
|
-
// Handle direct string type
|
|
173
|
-
if (this.isStringLikeType(typeNode, sourceFile)) {
|
|
174
|
-
return toTimeType();
|
|
175
|
-
}
|
|
176
|
-
return typeNode;
|
|
177
|
-
}
|
|
178
|
-
/**
|
|
179
|
-
* @internal
|
|
180
|
-
*
|
|
181
|
-
* massages the `Int8` exported from db.ts to make it more flexible
|
|
182
|
-
*/
|
|
183
|
-
replaceInt8Export(dbSourceFile) {
|
|
184
|
-
const transformer = context => {
|
|
185
|
-
return rootNode => {
|
|
186
|
-
const visit = (node) => {
|
|
187
|
-
const typeAlias = this.exportedTypeAliasOrNull(node, 'Int8');
|
|
188
|
-
if (typeAlias) {
|
|
189
|
-
return f.updateTypeAliasDeclaration(typeAlias, typeAlias.modifiers, typeAlias.name, typeAlias.typeParameters, f.createTypeReferenceNode('ColumnType', [
|
|
190
|
-
f.createKeywordTypeNode(ts.SyntaxKind.StringKeyword),
|
|
191
|
-
f.createUnionTypeNode([
|
|
192
|
-
f.createKeywordTypeNode(ts.SyntaxKind.BigIntKeyword),
|
|
193
|
-
f.createKeywordTypeNode(ts.SyntaxKind.NumberKeyword),
|
|
194
|
-
f.createKeywordTypeNode(ts.SyntaxKind.StringKeyword),
|
|
195
|
-
]),
|
|
196
|
-
f.createUnionTypeNode([
|
|
197
|
-
f.createKeywordTypeNode(ts.SyntaxKind.BigIntKeyword),
|
|
198
|
-
f.createKeywordTypeNode(ts.SyntaxKind.NumberKeyword),
|
|
199
|
-
f.createKeywordTypeNode(ts.SyntaxKind.StringKeyword),
|
|
200
|
-
]),
|
|
201
|
-
]));
|
|
202
|
-
}
|
|
203
|
-
return ts.visitEachChild(node, visit, context);
|
|
204
|
-
};
|
|
205
|
-
return ts.visitNode(rootNode, visit);
|
|
206
|
-
};
|
|
207
|
-
};
|
|
208
|
-
const result = ts.transform(dbSourceFile, [transformer]);
|
|
209
|
-
return result.transformed[0];
|
|
210
|
-
}
|
|
211
|
-
/**
|
|
212
|
-
* @internal
|
|
213
|
-
*
|
|
214
|
-
* injects missing CalendarDate and DateTime imports from dream
|
|
215
|
-
*/
|
|
216
|
-
addMissingImports(dbSourceFile) {
|
|
217
|
-
const transformer = () => {
|
|
218
|
-
return (sourceFile) => f.updateSourceFile(sourceFile, [...this.dateAndDateTimeImports(), ...sourceFile.statements]);
|
|
219
|
-
};
|
|
220
|
-
const result = ts.transform(dbSourceFile, [transformer]);
|
|
221
|
-
return result.transformed[0];
|
|
222
|
-
}
|
|
223
|
-
/**
|
|
224
|
-
* @internal
|
|
225
|
-
*
|
|
226
|
-
* sorts all exported interfaces and puts them above the DB interface
|
|
227
|
-
*/
|
|
228
|
-
sortExportedInterfacesTransformer(dbSourceFile) {
|
|
229
|
-
const transformer = () => {
|
|
230
|
-
return (sourceFile) => {
|
|
231
|
-
const sortedInterfaceStatements = [];
|
|
232
|
-
const finalInterfaceStatements = [];
|
|
233
|
-
const otherStatements = [];
|
|
234
|
-
sourceFile.statements.forEach(statement => {
|
|
235
|
-
if (ts.isInterfaceDeclaration(statement) &&
|
|
236
|
-
statement.modifiers?.some(m => m.kind === ts.SyntaxKind.ExportKeyword)) {
|
|
237
|
-
if (statement.name.text !== 'DB') {
|
|
238
|
-
sortedInterfaceStatements.push(statement);
|
|
239
|
-
}
|
|
240
|
-
else {
|
|
241
|
-
finalInterfaceStatements.push(statement);
|
|
242
|
-
}
|
|
243
|
-
}
|
|
244
|
-
else {
|
|
245
|
-
otherStatements.push(statement);
|
|
246
|
-
}
|
|
247
|
-
});
|
|
248
|
-
sortedInterfaceStatements.sort((a, b) => a.name.text.localeCompare(b.name.text));
|
|
249
|
-
return f.updateSourceFile(sourceFile, [...otherStatements, ...sortedInterfaceStatements, ...finalInterfaceStatements], sourceFile.isDeclarationFile, sourceFile.referencedFiles);
|
|
250
|
-
};
|
|
251
|
-
};
|
|
252
|
-
const result = ts.transform(dbSourceFile, [transformer]);
|
|
253
|
-
return result.transformed[0];
|
|
254
|
-
}
|
|
255
|
-
/**
|
|
256
|
-
* @internal
|
|
257
|
-
*
|
|
258
|
-
* camelizes the keys on all interfaces except the DB interface
|
|
259
|
-
* (since the DB interface is indexed by table name, which must not be camelized)
|
|
260
|
-
*/
|
|
261
|
-
camelizeKeys(dbSourceFile) {
|
|
262
|
-
// @ts-expect-error cannot lock this type down, though implementation is correct
|
|
263
|
-
const transformer = context => {
|
|
264
|
-
const visit = node => {
|
|
265
|
-
const interfaceNode = this.exportedInterfaceOrNull(node);
|
|
266
|
-
if (interfaceNode &&
|
|
267
|
-
!['DB'].includes(interfaceNode.name.text) // Check exclusion list
|
|
268
|
-
) {
|
|
269
|
-
const updatedMembers = interfaceNode.members.map(member => {
|
|
270
|
-
if (ts.isPropertySignature(member) && ts.isIdentifier(member.name)) {
|
|
271
|
-
const camelizedKey = camelize(member.name.text);
|
|
272
|
-
if (member.name.text !== camelizedKey) {
|
|
273
|
-
return f.updatePropertySignature(member, member.modifiers, f.createIdentifier(camelizedKey), member.questionToken, member.type);
|
|
274
|
-
}
|
|
275
|
-
}
|
|
276
|
-
return member;
|
|
277
|
-
});
|
|
278
|
-
return f.updateInterfaceDeclaration(interfaceNode, interfaceNode.modifiers, interfaceNode.name, interfaceNode.typeParameters, interfaceNode.heritageClauses, updatedMembers);
|
|
279
|
-
}
|
|
280
|
-
return ts.visitEachChild(node, visit, context);
|
|
281
|
-
};
|
|
282
|
-
return node => ts.visitNode(node, visit);
|
|
283
|
-
};
|
|
284
|
-
const result = ts.transform(dbSourceFile, [transformer]);
|
|
285
|
-
return result.transformed[0];
|
|
286
|
-
}
|
|
287
|
-
/**
|
|
288
|
-
* @internal
|
|
289
|
-
*
|
|
290
|
-
* removes columns declared in model `ignoredColumns` getters from the
|
|
291
|
-
* table interfaces generated by kysely-codegen. This is what removes
|
|
292
|
-
* ignored columns from the generated db types file: every column-name
|
|
293
|
-
* level type (`DreamColumnNames`, `UpdateableProperties`, where-clause
|
|
294
|
-
* statements) derives from the Kysely `DB` interface, so filtering here
|
|
295
|
-
* turns any remaining code reference to an ignored column into a type
|
|
296
|
-
* error. Runs after camelizeKeys so that member names align with the
|
|
297
|
-
* camelCase column names models declare in ignoredColumns.
|
|
298
|
-
*/
|
|
299
|
-
removeIgnoredColumns(dbSourceFile) {
|
|
300
|
-
const dbInterface = this.findDbExport(dbSourceFile, 'DB');
|
|
301
|
-
if (!dbInterface)
|
|
302
|
-
return dbSourceFile;
|
|
303
|
-
// the DB interface maps table names to table interfaces (e.g.
|
|
304
|
-
// `collars: Collars`), so it provides the table name each table
|
|
305
|
-
// interface corresponds to
|
|
306
|
-
const ignoredColumnsByInterfaceName = {};
|
|
307
|
-
dbInterface.members.forEach(member => {
|
|
308
|
-
if (!ts.isPropertySignature(member))
|
|
309
|
-
return;
|
|
310
|
-
if (!member.type || !ts.isTypeReferenceNode(member.type))
|
|
311
|
-
return;
|
|
312
|
-
if (!ts.isIdentifier(member.type.typeName))
|
|
313
|
-
return;
|
|
314
|
-
const tableName = ts.isIdentifier(member.name)
|
|
315
|
-
? member.name.text
|
|
316
|
-
: ts.isStringLiteral(member.name)
|
|
317
|
-
? member.name.text
|
|
318
|
-
: null;
|
|
319
|
-
if (!tableName)
|
|
320
|
-
return;
|
|
321
|
-
const ignoredColumns = this.ignoredColumnsForTable(tableName);
|
|
322
|
-
if (ignoredColumns.size)
|
|
323
|
-
ignoredColumnsByInterfaceName[member.type.typeName.text] = ignoredColumns;
|
|
324
|
-
});
|
|
325
|
-
if (!Object.keys(ignoredColumnsByInterfaceName).length)
|
|
326
|
-
return dbSourceFile;
|
|
327
|
-
// @ts-expect-error cannot lock this type down, though implementation is correct
|
|
328
|
-
const transformer = context => {
|
|
329
|
-
const visit = node => {
|
|
330
|
-
const interfaceNode = this.exportedInterfaceOrNull(node);
|
|
331
|
-
const ignoredColumns = interfaceNode
|
|
332
|
-
? ignoredColumnsByInterfaceName[interfaceNode.name.text]
|
|
333
|
-
: undefined;
|
|
334
|
-
if (interfaceNode && ignoredColumns) {
|
|
335
|
-
return f.updateInterfaceDeclaration(interfaceNode, interfaceNode.modifiers, interfaceNode.name, interfaceNode.typeParameters, interfaceNode.heritageClauses, interfaceNode.members.filter(member => !(ts.isPropertySignature(member) &&
|
|
336
|
-
(ts.isIdentifier(member.name) || ts.isStringLiteral(member.name)) &&
|
|
337
|
-
ignoredColumns.has(member.name.text))));
|
|
338
|
-
}
|
|
339
|
-
return ts.visitEachChild(node, visit, context);
|
|
340
|
-
};
|
|
341
|
-
return node => ts.visitNode(node, visit);
|
|
342
|
-
};
|
|
343
|
-
const result = ts.transform(dbSourceFile, [transformer]);
|
|
344
|
-
return result.transformed[0];
|
|
345
|
-
}
|
|
346
|
-
/**
|
|
347
|
-
* @internal
|
|
348
|
-
*
|
|
349
|
-
* for each found enum in the app (i.e. LocalizedTextsEnum), this will also
|
|
350
|
-
* inject below it a `LocalizedTextsEnumValues` const, which can be used
|
|
351
|
-
* at runtime to grab the actual enum values.
|
|
352
|
-
*/
|
|
353
|
-
async addEnumValueExports(dbSourceFile) {
|
|
354
|
-
const enums = await this.getAllEnumValueNames();
|
|
355
|
-
const enumTypes = enums.map(e => e.enumType);
|
|
356
|
-
// @ts-expect-error cannot lock this type down, though implementation is correct
|
|
357
|
-
const transformer = context => {
|
|
358
|
-
const visit = (node) => {
|
|
359
|
-
const typeAlias = this.exportedTypeAliasOrNull(node);
|
|
360
|
-
const isEnum = typeAlias ? enumTypes.includes(typeAlias.name.text) : false;
|
|
361
|
-
if (typeAlias && isEnum) {
|
|
362
|
-
const literals = this.extractStringLiteralTypeNodesFromTypeOrUnion(typeAlias).map(node => node.literal.text);
|
|
363
|
-
if (literals.length > 0) {
|
|
364
|
-
return [
|
|
365
|
-
typeAlias,
|
|
366
|
-
f.createVariableStatement([f.createModifier(ts.SyntaxKind.ExportKeyword)], f.createVariableDeclarationList([
|
|
367
|
-
f.createVariableDeclaration(f.createIdentifier(`${typeAlias.name.text}Values`), undefined, undefined, f.createAsExpression(f.createArrayLiteralExpression(literals.map(literal => f.createStringLiteral(literal)), true // multiLine
|
|
368
|
-
), f.createKeywordTypeNode(ts.SyntaxKind.ConstKeyword))),
|
|
369
|
-
], ts.NodeFlags.Const)),
|
|
370
|
-
];
|
|
371
|
-
}
|
|
372
|
-
}
|
|
373
|
-
return ts.visitEachChild(node, visit, context);
|
|
374
|
-
};
|
|
375
|
-
return node => ts.visitNode(node, visit);
|
|
376
|
-
};
|
|
377
|
-
const result = ts.transform(dbSourceFile, [transformer]);
|
|
378
|
-
return result.transformed[0];
|
|
379
|
-
}
|
|
380
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export default function syncDbTypesFiles(connectionName: string): Promise<void>;
|
|
@@ -1,94 +0,0 @@
|
|
|
1
|
-
import ASTConnectionBuilder from './ASTConnectionBuilder.js';
|
|
2
|
-
/**
|
|
3
|
-
* Responsible for enhancing the kysely-codegen output, which can be found at
|
|
4
|
-
* types/db.ts. If you are leveraging multiple db connections,
|
|
5
|
-
* then this file will also be responsible for building all variants,
|
|
6
|
-
* i.e. types/db.alternateConnection.ts, etc...
|
|
7
|
-
*
|
|
8
|
-
* This class leverages internal AST building mechanisms built into
|
|
9
|
-
* typescript to manually build up object literals and interfaces
|
|
10
|
-
* for our app to consume.
|
|
11
|
-
*/
|
|
12
|
-
export default class ASTKyselyCodegenEnhancer extends ASTConnectionBuilder {
|
|
13
|
-
/**
|
|
14
|
-
* enhances the kysely codegen output for the given connection name
|
|
15
|
-
* by reading the relevant db.ts file into AST nodes, then enhancing them
|
|
16
|
-
* with a variety of transformations necessary to lock this file in with
|
|
17
|
-
* our other schema files, allowing types to flow correctly throughout the app.
|
|
18
|
-
*/
|
|
19
|
-
enhance(): Promise<void>;
|
|
20
|
-
private addDeprecatedDbClassExportForBackwardsCompatibility;
|
|
21
|
-
/**
|
|
22
|
-
* @internal
|
|
23
|
-
*
|
|
24
|
-
* returns the output of the provided dbSourceFile, ensuring that all exports
|
|
25
|
-
* have a new line above them.
|
|
26
|
-
*/
|
|
27
|
-
private printOutput;
|
|
28
|
-
/**
|
|
29
|
-
* @internal
|
|
30
|
-
*
|
|
31
|
-
* ensures that the `Timestamp` exported from db.ts points correctly to either
|
|
32
|
-
* the DateTime or CalendarDate class, depending on the db type.
|
|
33
|
-
*/
|
|
34
|
-
private replaceTimestampExport;
|
|
35
|
-
/**
|
|
36
|
-
* @internal
|
|
37
|
-
*
|
|
38
|
-
* Replaces string types with TimeWithZone or TimeWithoutZone for TIME columns
|
|
39
|
-
* based on the schema metadata from dream.ts
|
|
40
|
-
*/
|
|
41
|
-
private replaceTimeFieldsInInterfaces;
|
|
42
|
-
/**
|
|
43
|
-
* @internal
|
|
44
|
-
*
|
|
45
|
-
* Helper to replace string type references with ClockTime or ClockTimeTz type references
|
|
46
|
-
*/
|
|
47
|
-
private replaceStringWithClockTimeType;
|
|
48
|
-
/**
|
|
49
|
-
* @internal
|
|
50
|
-
*
|
|
51
|
-
* massages the `Int8` exported from db.ts to make it more flexible
|
|
52
|
-
*/
|
|
53
|
-
private replaceInt8Export;
|
|
54
|
-
/**
|
|
55
|
-
* @internal
|
|
56
|
-
*
|
|
57
|
-
* injects missing CalendarDate and DateTime imports from dream
|
|
58
|
-
*/
|
|
59
|
-
private addMissingImports;
|
|
60
|
-
/**
|
|
61
|
-
* @internal
|
|
62
|
-
*
|
|
63
|
-
* sorts all exported interfaces and puts them above the DB interface
|
|
64
|
-
*/
|
|
65
|
-
private sortExportedInterfacesTransformer;
|
|
66
|
-
/**
|
|
67
|
-
* @internal
|
|
68
|
-
*
|
|
69
|
-
* camelizes the keys on all interfaces except the DB interface
|
|
70
|
-
* (since the DB interface is indexed by table name, which must not be camelized)
|
|
71
|
-
*/
|
|
72
|
-
private camelizeKeys;
|
|
73
|
-
/**
|
|
74
|
-
* @internal
|
|
75
|
-
*
|
|
76
|
-
* removes columns declared in model `ignoredColumns` getters from the
|
|
77
|
-
* table interfaces generated by kysely-codegen. This is what removes
|
|
78
|
-
* ignored columns from the generated db types file: every column-name
|
|
79
|
-
* level type (`DreamColumnNames`, `UpdateableProperties`, where-clause
|
|
80
|
-
* statements) derives from the Kysely `DB` interface, so filtering here
|
|
81
|
-
* turns any remaining code reference to an ignored column into a type
|
|
82
|
-
* error. Runs after camelizeKeys so that member names align with the
|
|
83
|
-
* camelCase column names models declare in ignoredColumns.
|
|
84
|
-
*/
|
|
85
|
-
private removeIgnoredColumns;
|
|
86
|
-
/**
|
|
87
|
-
* @internal
|
|
88
|
-
*
|
|
89
|
-
* for each found enum in the app (i.e. LocalizedTextsEnum), this will also
|
|
90
|
-
* inject below it a `LocalizedTextsEnumValues` const, which can be used
|
|
91
|
-
* at runtime to grab the actual enum values.
|
|
92
|
-
*/
|
|
93
|
-
private addEnumValueExports;
|
|
94
|
-
}
|