@rvoh/dream 1.5.0 → 1.5.2
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/db/migration-helpers/DreamMigrationHelpers.js +36 -0
- package/dist/cjs/src/decorators/field/sortable/helpers/setPosition.js +7 -1
- package/dist/cjs/src/dream/QueryDriver/Kysely.js +4 -4
- package/dist/cjs/src/dream/QueryDriver/helpers/kysely/runMigration.js +2 -1
- package/dist/cjs/src/helpers/sanitizeString.js +49 -0
- package/dist/cjs/src/index.js +3 -1
- package/dist/cjs/src/serializer/SerializerRenderer.js +7 -2
- package/dist/esm/src/db/migration-helpers/DreamMigrationHelpers.js +36 -0
- package/dist/esm/src/decorators/field/sortable/helpers/setPosition.js +7 -1
- package/dist/esm/src/dream/QueryDriver/Kysely.js +4 -4
- package/dist/esm/src/dream/QueryDriver/helpers/kysely/runMigration.js +2 -1
- package/dist/esm/src/helpers/sanitizeString.js +46 -0
- package/dist/esm/src/index.js +1 -0
- package/dist/esm/src/serializer/SerializerRenderer.js +7 -2
- package/dist/types/src/db/migration-helpers/DreamMigrationHelpers.d.ts +36 -0
- package/dist/types/src/helpers/sanitizeString.d.ts +2 -0
- package/dist/types/src/index.d.ts +1 -0
- package/dist/types/src/serializer/builders/DreamSerializerBuilder.d.ts +6 -3
- package/dist/types/src/types/associations/shared.d.ts +1 -1
- package/dist/types/src/types/associations/shared.ts +4 -2
- package/dist/types/src/types/serializer.d.ts +9 -0
- package/dist/types/src/types/serializer.ts +10 -0
- 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 +113 -113
- package/docs/classes/DreamApp.html +4 -4
- 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 +19 -7
- package/docs/classes/DreamSerializerBuilder.html +17 -17
- 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 +30 -30
- 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 +31 -31
- package/docs/classes/Query.html +53 -53
- package/docs/classes/QueryDriverBase.html +29 -29
- 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/sanitizeString.html +1 -0
- 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/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 +1 -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 +2 -2
- package/CHANGELOG.md +0 -166
|
@@ -94,6 +94,42 @@ class DreamMigrationHelpers {
|
|
|
94
94
|
ALTER TABLE ${kysely_1.sql.table(table)} DROP CONSTRAINT IF EXISTS ${kysely_1.sql.table(constraintName)};
|
|
95
95
|
`.execute(db);
|
|
96
96
|
}
|
|
97
|
+
/**
|
|
98
|
+
* Forces a new transaction boundary in migration execution.
|
|
99
|
+
*
|
|
100
|
+
* When called in a migration file, this method ensures that any existing transaction
|
|
101
|
+
* is committed before this migration runs, and a new transaction is started before the
|
|
102
|
+
* migration in this file. This is essential for migrations that depend on previously
|
|
103
|
+
* committed changes.
|
|
104
|
+
*
|
|
105
|
+
* Some database operations require that dependent changes be committed before they can
|
|
106
|
+
* be executed. For example, check constraints that reference enum values require those
|
|
107
|
+
* enum values to be committed to the database first.
|
|
108
|
+
*
|
|
109
|
+
* ```ts
|
|
110
|
+
* // first migration file: Add enum value
|
|
111
|
+
* export async function up(db: Kysely<any>): Promise<void> {
|
|
112
|
+
* await DreamMigrationHelpers.addEnumValue(db, {
|
|
113
|
+
* enumName: 'user_status',
|
|
114
|
+
* value: 'premium'
|
|
115
|
+
* })
|
|
116
|
+
* }
|
|
117
|
+
*
|
|
118
|
+
* // second migration file: Add check constraint that depends on the enum value
|
|
119
|
+
* export async function up(db: Kysely<any>): Promise<void> {
|
|
120
|
+
* DreamMigrationHelpers.newTransaction() // Ensure enum value is committed first
|
|
121
|
+
*
|
|
122
|
+
* await db.schema
|
|
123
|
+
* .alterTable('users')
|
|
124
|
+
* .addCheckConstraint(
|
|
125
|
+
* 'check_premium_users',
|
|
126
|
+
* sql`status = 'premium' OR credits < 100`
|
|
127
|
+
* )
|
|
128
|
+
* .execute()
|
|
129
|
+
* }
|
|
130
|
+
* ```
|
|
131
|
+
*/
|
|
132
|
+
static newTransaction() { }
|
|
97
133
|
/**
|
|
98
134
|
* Drop a value from an enum and replace it (or optionally remove it from array columns)
|
|
99
135
|
*
|
|
@@ -147,7 +147,13 @@ function applySortableScopesToQuery(dream, kyselyQuery, whereValueCB, scope) {
|
|
|
147
147
|
for (const singleScope of (0, scopeArray_js_1.default)(scope)) {
|
|
148
148
|
const column = (0, getColumnForSortableScope_js_1.default)(dream, singleScope);
|
|
149
149
|
if (column) {
|
|
150
|
-
|
|
150
|
+
const columnValue = whereValueCB(column);
|
|
151
|
+
if (columnValue === null) {
|
|
152
|
+
kyselyQuery = kyselyQuery.where(column, 'is', null);
|
|
153
|
+
}
|
|
154
|
+
else {
|
|
155
|
+
kyselyQuery = kyselyQuery.where(column, '=', columnValue);
|
|
156
|
+
}
|
|
151
157
|
}
|
|
152
158
|
}
|
|
153
159
|
return kyselyQuery;
|
|
@@ -61,11 +61,11 @@ const executeDatabaseQuery_js_1 = require("../internal/executeDatabaseQuery.js")
|
|
|
61
61
|
const orderByDirection_js_1 = require("../internal/orderByDirection.js");
|
|
62
62
|
const shouldBypassDefaultScope_js_1 = require("../internal/shouldBypassDefaultScope.js");
|
|
63
63
|
const SimilarityBuilder_js_1 = require("../internal/similarity/SimilarityBuilder.js");
|
|
64
|
+
const softDeleteDream_js_1 = require("../internal/softDeleteDream.js");
|
|
64
65
|
const sqlResultToDreamInstance_js_1 = require("../internal/sqlResultToDreamInstance.js");
|
|
65
66
|
const Query_js_1 = require("../Query.js");
|
|
66
67
|
const Base_js_1 = require("./Base.js");
|
|
67
68
|
const runMigration_js_1 = require("./helpers/kysely/runMigration.js");
|
|
68
|
-
const softDeleteDream_js_1 = require("../internal/softDeleteDream.js");
|
|
69
69
|
class KyselyQueryDriver extends Base_js_1.default {
|
|
70
70
|
// ATTENTION FRED
|
|
71
71
|
// stop trying to make this async. You never learn...
|
|
@@ -1081,11 +1081,11 @@ class KyselyQueryDriver extends Base_js_1.default {
|
|
|
1081
1081
|
return (0, kysely_1.sql) `FALSE`;
|
|
1082
1082
|
}
|
|
1083
1083
|
notInArrayWithNullExpressionBuilder(eb, a, b, c) {
|
|
1084
|
-
const
|
|
1084
|
+
const isNotNullStatement = eb(a, 'is not', null);
|
|
1085
1085
|
const compactedC = (0, compact_js_1.default)(c);
|
|
1086
1086
|
if (compactedC.length)
|
|
1087
|
-
return eb.and([eb(a, 'not in', compactedC),
|
|
1088
|
-
return
|
|
1087
|
+
return eb.and([eb(a, 'not in', compactedC), isNotNullStatement]);
|
|
1088
|
+
return isNotNullStatement;
|
|
1089
1089
|
}
|
|
1090
1090
|
dreamWhereStatementToExpressionBuilderParts(attr, val) {
|
|
1091
1091
|
let a;
|
|
@@ -66,7 +66,8 @@ async function findNextMigrationRequiringNewTransaction(migrator, { ignore } = {
|
|
|
66
66
|
const notYetRunMigrations = (await migrator.getMigrations()).filter(migrationInfo => !migrationInfo.executedAt && migrationInfo.name !== ignore);
|
|
67
67
|
for (const notYetRunMigration of notYetRunMigrations) {
|
|
68
68
|
const upAndDownString = notYetRunMigration.migration.up.toString() + (notYetRunMigration.migration.down || '').toString();
|
|
69
|
-
const migrationRequiresNewTransaction = upAndDownString.includes('DreamMigrationHelpers.dropEnumValue')
|
|
69
|
+
const migrationRequiresNewTransaction = upAndDownString.includes('DreamMigrationHelpers.dropEnumValue') ||
|
|
70
|
+
upAndDownString.includes('DreamMigrationHelpers.newTransaction');
|
|
70
71
|
if (migrationRequiresNewTransaction)
|
|
71
72
|
return notYetRunMigration;
|
|
72
73
|
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.default = sanitizeString;
|
|
4
|
+
function sanitizeString(value, sanitizationStrategy) {
|
|
5
|
+
switch (sanitizationStrategy) {
|
|
6
|
+
case 'unicodeString':
|
|
7
|
+
return sanitizeStringUnicodeStringStrategy(value);
|
|
8
|
+
case 'htmlEntity':
|
|
9
|
+
return sanitizeStringHtmlEntityStrategy(value);
|
|
10
|
+
default:
|
|
11
|
+
if (typeof sanitizationStrategy === 'function')
|
|
12
|
+
return sanitizationStrategy(value);
|
|
13
|
+
throw new UnrecognizedAttributeSerializationSanitizationStrategy(sanitizationStrategy);
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
function sanitizeStringUnicodeStringStrategy(str) {
|
|
17
|
+
if (str === undefined || str === null)
|
|
18
|
+
return str;
|
|
19
|
+
return str
|
|
20
|
+
.replace(/\\/g, '\\u005c')
|
|
21
|
+
.replace(/&/g, '\\u0026')
|
|
22
|
+
.replace(/</g, '\\u003c')
|
|
23
|
+
.replace(/>/g, '\\u003e')
|
|
24
|
+
.replace(/\//g, '\\u002f')
|
|
25
|
+
.replace(/'/g, '\\u0027')
|
|
26
|
+
.replace(/"/g, '\\u0022');
|
|
27
|
+
}
|
|
28
|
+
function sanitizeStringHtmlEntityStrategy(str) {
|
|
29
|
+
if (str === undefined || str === null)
|
|
30
|
+
return str;
|
|
31
|
+
return str
|
|
32
|
+
.replace(/&/g, '&')
|
|
33
|
+
.replace(/</g, '<')
|
|
34
|
+
.replace(/>/g, '>')
|
|
35
|
+
.replace(/\//g, '/')
|
|
36
|
+
.replace(/'/g, ''')
|
|
37
|
+
.replace(/"/g, '"');
|
|
38
|
+
}
|
|
39
|
+
class UnrecognizedAttributeSerializationSanitizationStrategy extends Error {
|
|
40
|
+
sanitizationStrategy;
|
|
41
|
+
constructor(sanitizationStrategy) {
|
|
42
|
+
super();
|
|
43
|
+
this.sanitizationStrategy = sanitizationStrategy;
|
|
44
|
+
}
|
|
45
|
+
get message() {
|
|
46
|
+
return `Unrecognized attribute serialization sanitization strategy:
|
|
47
|
+
${this.sanitizationStrategy.toString()}`;
|
|
48
|
+
}
|
|
49
|
+
}
|
package/dist/cjs/src/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.intersection = exports.hyphenize = exports.groupBy = exports.globalClassNameFromFullyQualifiedModelName = exports.Env = exports.DreamLogos = exports.DateTime = exports.compact = exports.cloneDeepSafe = exports.generateDream = exports.capitalize = exports.camelize = exports.CalendarDate = exports.Benchmark = exports.ValidationError = exports.RecordNotFound = exports.GlobalNameNotSet = exports.NotNullViolation = exports.DataTypeColumnTypeMismatch = exports.CheckConstraintViolation = exports.CreateOrFindByFailedToCreateAndFind = exports.NonLoadedAssociation = exports.Encrypt = exports.PostgresQueryDriver = exports.KyselyQueryDriver = exports.QueryDriverBase = exports.Query = exports.DreamTransaction = exports.openapiShorthandPrimitiveTypes = exports.openapiPrimitiveTypes = exports.DreamConst = exports.Dream = exports.DreamAppAllowedPackageManagersEnumValues = exports.DreamApp = exports.lookupClassByGlobalName = exports.DreamImporter = exports.Decorators = exports.STI = exports.SoftDelete = exports.ReplicaSafe = exports.validateTable = exports.validateColumn = exports.DreamMigrationHelpers = exports.untypedDb = exports.pgErrorType = exports.dreamDbConnections = exports.closeAllDbConnections = exports.DreamCLI = exports.CliFileWriter = exports.DreamBin = void 0;
|
|
4
|
-
exports.ObjectSerializerBuilder = exports.DreamSerializerBuilder = exports.ObjectSerializer = exports.DreamSerializer = exports.serializerNameFromFullyQualifiedModelName = exports.isDreamSerializer = exports.inferSerializersFromDreamClassOrViewModelClass = exports.inferSerializerFromDreamOrViewModel = exports.ops = exports.uniq = exports.uncapitalize = exports.expandStiClasses = exports.standardizeFullyQualifiedModelName = exports.sortObjectByValue = exports.sortObjectByKey = exports.sortBy = exports.sort = exports.snakeify = exports.round = exports.range = exports.Range = exports.sharedPathPrefix = exports.relativeDreamPath = exports.dreamPath = exports.pascalize = exports.normalizeUnicode = exports.loadRepl = exports.isEmpty = void 0;
|
|
4
|
+
exports.ObjectSerializerBuilder = exports.DreamSerializerBuilder = exports.ObjectSerializer = exports.DreamSerializer = exports.serializerNameFromFullyQualifiedModelName = exports.isDreamSerializer = exports.inferSerializersFromDreamClassOrViewModelClass = exports.inferSerializerFromDreamOrViewModel = exports.ops = exports.uniq = exports.uncapitalize = exports.expandStiClasses = exports.standardizeFullyQualifiedModelName = exports.sortObjectByValue = exports.sortObjectByKey = exports.sortBy = exports.sort = exports.snakeify = exports.sanitizeString = exports.round = exports.range = exports.Range = exports.sharedPathPrefix = exports.relativeDreamPath = exports.dreamPath = exports.pascalize = exports.normalizeUnicode = exports.loadRepl = exports.isEmpty = void 0;
|
|
5
5
|
var index_js_1 = require("./bin/index.js");
|
|
6
6
|
Object.defineProperty(exports, "DreamBin", { enumerable: true, get: function () { return index_js_1.default; } });
|
|
7
7
|
var CliFileWriter_js_1 = require("./cli/CliFileWriter.js");
|
|
@@ -117,6 +117,8 @@ Object.defineProperty(exports, "Range", { enumerable: true, get: function () { r
|
|
|
117
117
|
Object.defineProperty(exports, "range", { enumerable: true, get: function () { return range_js_1.default; } });
|
|
118
118
|
var round_js_1 = require("./helpers/round.js");
|
|
119
119
|
Object.defineProperty(exports, "round", { enumerable: true, get: function () { return round_js_1.default; } });
|
|
120
|
+
var sanitizeString_js_1 = require("./helpers/sanitizeString.js");
|
|
121
|
+
Object.defineProperty(exports, "sanitizeString", { enumerable: true, get: function () { return sanitizeString_js_1.default; } });
|
|
120
122
|
var snakeify_js_1 = require("./helpers/snakeify.js");
|
|
121
123
|
Object.defineProperty(exports, "snakeify", { enumerable: true, get: function () { return snakeify_js_1.default; } });
|
|
122
124
|
var sort_js_1 = require("./helpers/sort.js");
|
|
@@ -5,6 +5,7 @@ const CalendarDate_js_1 = require("../helpers/CalendarDate.js");
|
|
|
5
5
|
const compact_js_1 = require("../helpers/compact.js");
|
|
6
6
|
const DateTime_js_1 = require("../helpers/DateTime.js");
|
|
7
7
|
const round_js_1 = require("../helpers/round.js");
|
|
8
|
+
const sanitizeString_js_1 = require("../helpers/sanitizeString.js");
|
|
8
9
|
const snakeify_js_1 = require("../helpers/snakeify.js");
|
|
9
10
|
const DreamSerializerBuilder_js_1 = require("./builders/DreamSerializerBuilder.js");
|
|
10
11
|
const ObjectSerializerBuilder_js_1 = require("./builders/ObjectSerializerBuilder.js");
|
|
@@ -42,7 +43,9 @@ class SerializerRenderer {
|
|
|
42
43
|
case 'attribute': {
|
|
43
44
|
const outputAttributeName = this.setCase(attribute.options?.as ?? attribute.name);
|
|
44
45
|
const value = data[attribute.name] ?? attribute.options?.default;
|
|
45
|
-
accumulator[outputAttributeName] = applyRenderingOptionsToAttribute(
|
|
46
|
+
accumulator[outputAttributeName] = applyRenderingOptionsToAttribute(attribute.options?.sanitize && typeof value === 'string'
|
|
47
|
+
? (0, sanitizeString_js_1.default)(value, attribute.options.sanitize)
|
|
48
|
+
: value, attribute.options, this.passthroughData, this.renderOpts);
|
|
46
49
|
return accumulator;
|
|
47
50
|
}
|
|
48
51
|
/////////////////////
|
|
@@ -55,7 +58,9 @@ class SerializerRenderer {
|
|
|
55
58
|
const outputAttributeName = this.setCase(attribute.options?.as ?? attribute.name);
|
|
56
59
|
const target = data[attribute.targetName];
|
|
57
60
|
const value = target?.[attribute.name] ?? attribute.options?.default;
|
|
58
|
-
accumulator[outputAttributeName] = applyRenderingOptionsToAttribute(
|
|
61
|
+
accumulator[outputAttributeName] = applyRenderingOptionsToAttribute(attribute.options?.sanitize && typeof value === 'string'
|
|
62
|
+
? (0, sanitizeString_js_1.default)(value, attribute.options.sanitize)
|
|
63
|
+
: value, attribute.options, this.passthroughData, this.renderOpts);
|
|
59
64
|
return accumulator;
|
|
60
65
|
}
|
|
61
66
|
//////////////////////////////
|
|
@@ -92,6 +92,42 @@ export default class DreamMigrationHelpers {
|
|
|
92
92
|
ALTER TABLE ${sql.table(table)} DROP CONSTRAINT IF EXISTS ${sql.table(constraintName)};
|
|
93
93
|
`.execute(db);
|
|
94
94
|
}
|
|
95
|
+
/**
|
|
96
|
+
* Forces a new transaction boundary in migration execution.
|
|
97
|
+
*
|
|
98
|
+
* When called in a migration file, this method ensures that any existing transaction
|
|
99
|
+
* is committed before this migration runs, and a new transaction is started before the
|
|
100
|
+
* migration in this file. This is essential for migrations that depend on previously
|
|
101
|
+
* committed changes.
|
|
102
|
+
*
|
|
103
|
+
* Some database operations require that dependent changes be committed before they can
|
|
104
|
+
* be executed. For example, check constraints that reference enum values require those
|
|
105
|
+
* enum values to be committed to the database first.
|
|
106
|
+
*
|
|
107
|
+
* ```ts
|
|
108
|
+
* // first migration file: Add enum value
|
|
109
|
+
* export async function up(db: Kysely<any>): Promise<void> {
|
|
110
|
+
* await DreamMigrationHelpers.addEnumValue(db, {
|
|
111
|
+
* enumName: 'user_status',
|
|
112
|
+
* value: 'premium'
|
|
113
|
+
* })
|
|
114
|
+
* }
|
|
115
|
+
*
|
|
116
|
+
* // second migration file: Add check constraint that depends on the enum value
|
|
117
|
+
* export async function up(db: Kysely<any>): Promise<void> {
|
|
118
|
+
* DreamMigrationHelpers.newTransaction() // Ensure enum value is committed first
|
|
119
|
+
*
|
|
120
|
+
* await db.schema
|
|
121
|
+
* .alterTable('users')
|
|
122
|
+
* .addCheckConstraint(
|
|
123
|
+
* 'check_premium_users',
|
|
124
|
+
* sql`status = 'premium' OR credits < 100`
|
|
125
|
+
* )
|
|
126
|
+
* .execute()
|
|
127
|
+
* }
|
|
128
|
+
* ```
|
|
129
|
+
*/
|
|
130
|
+
static newTransaction() { }
|
|
95
131
|
/**
|
|
96
132
|
* Drop a value from an enum and replace it (or optionally remove it from array columns)
|
|
97
133
|
*
|
|
@@ -142,7 +142,13 @@ export function applySortableScopesToQuery(dream, kyselyQuery, whereValueCB, sco
|
|
|
142
142
|
for (const singleScope of scopeArray(scope)) {
|
|
143
143
|
const column = getColumnForSortableScope(dream, singleScope);
|
|
144
144
|
if (column) {
|
|
145
|
-
|
|
145
|
+
const columnValue = whereValueCB(column);
|
|
146
|
+
if (columnValue === null) {
|
|
147
|
+
kyselyQuery = kyselyQuery.where(column, 'is', null);
|
|
148
|
+
}
|
|
149
|
+
else {
|
|
150
|
+
kyselyQuery = kyselyQuery.where(column, '=', columnValue);
|
|
151
|
+
}
|
|
146
152
|
}
|
|
147
153
|
}
|
|
148
154
|
return kyselyQuery;
|
|
@@ -59,11 +59,11 @@ import executeDatabaseQuery from '../internal/executeDatabaseQuery.js';
|
|
|
59
59
|
import orderByDirection from '../internal/orderByDirection.js';
|
|
60
60
|
import shouldBypassDefaultScope from '../internal/shouldBypassDefaultScope.js';
|
|
61
61
|
import SimilarityBuilder from '../internal/similarity/SimilarityBuilder.js';
|
|
62
|
+
import softDeleteDream from '../internal/softDeleteDream.js';
|
|
62
63
|
import sqlResultToDreamInstance from '../internal/sqlResultToDreamInstance.js';
|
|
63
64
|
import Query from '../Query.js';
|
|
64
65
|
import QueryDriverBase from './Base.js';
|
|
65
66
|
import runMigration from './helpers/kysely/runMigration.js';
|
|
66
|
-
import softDeleteDream from '../internal/softDeleteDream.js';
|
|
67
67
|
export default class KyselyQueryDriver extends QueryDriverBase {
|
|
68
68
|
// ATTENTION FRED
|
|
69
69
|
// stop trying to make this async. You never learn...
|
|
@@ -1079,11 +1079,11 @@ export default class KyselyQueryDriver extends QueryDriverBase {
|
|
|
1079
1079
|
return sql `FALSE`;
|
|
1080
1080
|
}
|
|
1081
1081
|
notInArrayWithNullExpressionBuilder(eb, a, b, c) {
|
|
1082
|
-
const
|
|
1082
|
+
const isNotNullStatement = eb(a, 'is not', null);
|
|
1083
1083
|
const compactedC = compact(c);
|
|
1084
1084
|
if (compactedC.length)
|
|
1085
|
-
return eb.and([eb(a, 'not in', compactedC),
|
|
1086
|
-
return
|
|
1085
|
+
return eb.and([eb(a, 'not in', compactedC), isNotNullStatement]);
|
|
1086
|
+
return isNotNullStatement;
|
|
1087
1087
|
}
|
|
1088
1088
|
dreamWhereStatementToExpressionBuilderParts(attr, val) {
|
|
1089
1089
|
let a;
|
|
@@ -63,7 +63,8 @@ async function findNextMigrationRequiringNewTransaction(migrator, { ignore } = {
|
|
|
63
63
|
const notYetRunMigrations = (await migrator.getMigrations()).filter(migrationInfo => !migrationInfo.executedAt && migrationInfo.name !== ignore);
|
|
64
64
|
for (const notYetRunMigration of notYetRunMigrations) {
|
|
65
65
|
const upAndDownString = notYetRunMigration.migration.up.toString() + (notYetRunMigration.migration.down || '').toString();
|
|
66
|
-
const migrationRequiresNewTransaction = upAndDownString.includes('DreamMigrationHelpers.dropEnumValue')
|
|
66
|
+
const migrationRequiresNewTransaction = upAndDownString.includes('DreamMigrationHelpers.dropEnumValue') ||
|
|
67
|
+
upAndDownString.includes('DreamMigrationHelpers.newTransaction');
|
|
67
68
|
if (migrationRequiresNewTransaction)
|
|
68
69
|
return notYetRunMigration;
|
|
69
70
|
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
export default function sanitizeString(value, sanitizationStrategy) {
|
|
2
|
+
switch (sanitizationStrategy) {
|
|
3
|
+
case 'unicodeString':
|
|
4
|
+
return sanitizeStringUnicodeStringStrategy(value);
|
|
5
|
+
case 'htmlEntity':
|
|
6
|
+
return sanitizeStringHtmlEntityStrategy(value);
|
|
7
|
+
default:
|
|
8
|
+
if (typeof sanitizationStrategy === 'function')
|
|
9
|
+
return sanitizationStrategy(value);
|
|
10
|
+
throw new UnrecognizedAttributeSerializationSanitizationStrategy(sanitizationStrategy);
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
function sanitizeStringUnicodeStringStrategy(str) {
|
|
14
|
+
if (str === undefined || str === null)
|
|
15
|
+
return str;
|
|
16
|
+
return str
|
|
17
|
+
.replace(/\\/g, '\\u005c')
|
|
18
|
+
.replace(/&/g, '\\u0026')
|
|
19
|
+
.replace(/</g, '\\u003c')
|
|
20
|
+
.replace(/>/g, '\\u003e')
|
|
21
|
+
.replace(/\//g, '\\u002f')
|
|
22
|
+
.replace(/'/g, '\\u0027')
|
|
23
|
+
.replace(/"/g, '\\u0022');
|
|
24
|
+
}
|
|
25
|
+
function sanitizeStringHtmlEntityStrategy(str) {
|
|
26
|
+
if (str === undefined || str === null)
|
|
27
|
+
return str;
|
|
28
|
+
return str
|
|
29
|
+
.replace(/&/g, '&')
|
|
30
|
+
.replace(/</g, '<')
|
|
31
|
+
.replace(/>/g, '>')
|
|
32
|
+
.replace(/\//g, '/')
|
|
33
|
+
.replace(/'/g, ''')
|
|
34
|
+
.replace(/"/g, '"');
|
|
35
|
+
}
|
|
36
|
+
class UnrecognizedAttributeSerializationSanitizationStrategy extends Error {
|
|
37
|
+
sanitizationStrategy;
|
|
38
|
+
constructor(sanitizationStrategy) {
|
|
39
|
+
super();
|
|
40
|
+
this.sanitizationStrategy = sanitizationStrategy;
|
|
41
|
+
}
|
|
42
|
+
get message() {
|
|
43
|
+
return `Unrecognized attribute serialization sanitization strategy:
|
|
44
|
+
${this.sanitizationStrategy.toString()}`;
|
|
45
|
+
}
|
|
46
|
+
}
|
package/dist/esm/src/index.js
CHANGED
|
@@ -53,6 +53,7 @@ export { default as relativeDreamPath } from './helpers/path/relativeDreamPath.j
|
|
|
53
53
|
export { default as sharedPathPrefix } from './helpers/path/sharedPathPrefix.js';
|
|
54
54
|
export { Range, default as range } from './helpers/range.js';
|
|
55
55
|
export { default as round } from './helpers/round.js';
|
|
56
|
+
export { default as sanitizeString } from './helpers/sanitizeString.js';
|
|
56
57
|
export { default as snakeify } from './helpers/snakeify.js';
|
|
57
58
|
export { default as sort } from './helpers/sort.js';
|
|
58
59
|
export { default as sortBy } from './helpers/sortBy.js';
|
|
@@ -3,6 +3,7 @@ import CalendarDate from '../helpers/CalendarDate.js';
|
|
|
3
3
|
import compact from '../helpers/compact.js';
|
|
4
4
|
import { DateTime } from '../helpers/DateTime.js';
|
|
5
5
|
import round from '../helpers/round.js';
|
|
6
|
+
import sanitizeString from '../helpers/sanitizeString.js';
|
|
6
7
|
import snakeify from '../helpers/snakeify.js';
|
|
7
8
|
import DreamSerializerBuilder from './builders/DreamSerializerBuilder.js';
|
|
8
9
|
import ObjectSerializerBuilder from './builders/ObjectSerializerBuilder.js';
|
|
@@ -40,7 +41,9 @@ export default class SerializerRenderer {
|
|
|
40
41
|
case 'attribute': {
|
|
41
42
|
const outputAttributeName = this.setCase(attribute.options?.as ?? attribute.name);
|
|
42
43
|
const value = data[attribute.name] ?? attribute.options?.default;
|
|
43
|
-
accumulator[outputAttributeName] = applyRenderingOptionsToAttribute(
|
|
44
|
+
accumulator[outputAttributeName] = applyRenderingOptionsToAttribute(attribute.options?.sanitize && typeof value === 'string'
|
|
45
|
+
? sanitizeString(value, attribute.options.sanitize)
|
|
46
|
+
: value, attribute.options, this.passthroughData, this.renderOpts);
|
|
44
47
|
return accumulator;
|
|
45
48
|
}
|
|
46
49
|
/////////////////////
|
|
@@ -53,7 +56,9 @@ export default class SerializerRenderer {
|
|
|
53
56
|
const outputAttributeName = this.setCase(attribute.options?.as ?? attribute.name);
|
|
54
57
|
const target = data[attribute.targetName];
|
|
55
58
|
const value = target?.[attribute.name] ?? attribute.options?.default;
|
|
56
|
-
accumulator[outputAttributeName] = applyRenderingOptionsToAttribute(
|
|
59
|
+
accumulator[outputAttributeName] = applyRenderingOptionsToAttribute(attribute.options?.sanitize && typeof value === 'string'
|
|
60
|
+
? sanitizeString(value, attribute.options.sanitize)
|
|
61
|
+
: value, attribute.options, this.passthroughData, this.renderOpts);
|
|
57
62
|
return accumulator;
|
|
58
63
|
}
|
|
59
64
|
//////////////////////////////
|
|
@@ -79,6 +79,42 @@ export default class DreamMigrationHelpers {
|
|
|
79
79
|
static dropConstraint(db: Kysely<any>, constraintName: string, { table }: {
|
|
80
80
|
table: string;
|
|
81
81
|
}): Promise<void>;
|
|
82
|
+
/**
|
|
83
|
+
* Forces a new transaction boundary in migration execution.
|
|
84
|
+
*
|
|
85
|
+
* When called in a migration file, this method ensures that any existing transaction
|
|
86
|
+
* is committed before this migration runs, and a new transaction is started before the
|
|
87
|
+
* migration in this file. This is essential for migrations that depend on previously
|
|
88
|
+
* committed changes.
|
|
89
|
+
*
|
|
90
|
+
* Some database operations require that dependent changes be committed before they can
|
|
91
|
+
* be executed. For example, check constraints that reference enum values require those
|
|
92
|
+
* enum values to be committed to the database first.
|
|
93
|
+
*
|
|
94
|
+
* ```ts
|
|
95
|
+
* // first migration file: Add enum value
|
|
96
|
+
* export async function up(db: Kysely<any>): Promise<void> {
|
|
97
|
+
* await DreamMigrationHelpers.addEnumValue(db, {
|
|
98
|
+
* enumName: 'user_status',
|
|
99
|
+
* value: 'premium'
|
|
100
|
+
* })
|
|
101
|
+
* }
|
|
102
|
+
*
|
|
103
|
+
* // second migration file: Add check constraint that depends on the enum value
|
|
104
|
+
* export async function up(db: Kysely<any>): Promise<void> {
|
|
105
|
+
* DreamMigrationHelpers.newTransaction() // Ensure enum value is committed first
|
|
106
|
+
*
|
|
107
|
+
* await db.schema
|
|
108
|
+
* .alterTable('users')
|
|
109
|
+
* .addCheckConstraint(
|
|
110
|
+
* 'check_premium_users',
|
|
111
|
+
* sql`status = 'premium' OR credits < 100`
|
|
112
|
+
* )
|
|
113
|
+
* .execute()
|
|
114
|
+
* }
|
|
115
|
+
* ```
|
|
116
|
+
*/
|
|
117
|
+
static newTransaction(): void;
|
|
82
118
|
/**
|
|
83
119
|
* Drop a value from an enum and replace it (or optionally remove it from array columns)
|
|
84
120
|
*
|
|
@@ -54,6 +54,7 @@ export { default as relativeDreamPath } from './helpers/path/relativeDreamPath.j
|
|
|
54
54
|
export { default as sharedPathPrefix } from './helpers/path/sharedPathPrefix.js';
|
|
55
55
|
export { Range, default as range } from './helpers/range.js';
|
|
56
56
|
export { default as round, type RoundingPrecision } from './helpers/round.js';
|
|
57
|
+
export { default as sanitizeString } from './helpers/sanitizeString.js';
|
|
57
58
|
export { default as snakeify } from './helpers/snakeify.js';
|
|
58
59
|
export { default as sort } from './helpers/sort.js';
|
|
59
60
|
export { default as sortBy } from './helpers/sortBy.js';
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import Dream from '../../Dream.js';
|
|
2
|
-
import { DreamOrViewModelSerializerKey, NonJsonDreamColumnNames, ViewModel, ViewModelClass } from '../../types/dream.js';
|
|
3
|
-
import {
|
|
2
|
+
import { DreamOrViewModelSerializerKey, DreamVirtualColumns, NonJsonDreamColumnNames, ViewModel, ViewModelClass } from '../../types/dream.js';
|
|
3
|
+
import { OpenapiSchemaBodyShorthand, OpenapiShorthandPrimitiveTypes } from '../../types/openapi.js';
|
|
4
|
+
import { AutomaticSerializerAttributeOptions, AutomaticSerializerAttributeOptionsForType, InternalAnyTypedSerializerAttribute, InternalAnyTypedSerializerCustomAttribute, InternalAnyTypedSerializerDelegatedAttribute, InternalAnyTypedSerializerRendersMany, InternalAnyTypedSerializerRendersOne, NonAutomaticSerializerAttributeOptionsWithPossibleDecimalRenderOption, SerializerAttributeOptionsForVirtualColumn, SerializerType } from '../../types/serializer.js';
|
|
4
5
|
import { SerializerRendererOpts } from '../SerializerRenderer.js';
|
|
5
6
|
export default class DreamSerializerBuilder<DataTypeForOpenapi extends typeof Dream, MaybeNullDataType extends Dream | null, PassthroughDataType = any, DataType extends Exclude<MaybeNullDataType, null> = Exclude<MaybeNullDataType, null>> {
|
|
6
7
|
protected $typeForOpenapi: DataTypeForOpenapi;
|
|
@@ -37,6 +38,7 @@ export default class DreamSerializerBuilder<DataTypeForOpenapi extends typeof Dr
|
|
|
37
38
|
* See: {@link https://your-docs-url.com/docs/serializers/attributes | Serializer Attributes Documentation}
|
|
38
39
|
*/
|
|
39
40
|
attribute<AttributeName extends NonJsonDreamColumnNames<DataType> & keyof DataType & 'type', Options extends AutomaticSerializerAttributeOptionsForType>(name: AttributeName, options?: Options): DreamSerializerBuilder<DataTypeForOpenapi, MaybeNullDataType, PassthroughDataType, DataType>;
|
|
41
|
+
attribute<AttributeName extends DreamVirtualColumns<DataType>[number], Options extends SerializerAttributeOptionsForVirtualColumn>(name: AttributeName, options?: Options): DreamSerializerBuilder<DataTypeForOpenapi, MaybeNullDataType, PassthroughDataType, DataType>;
|
|
40
42
|
attribute<MaybeAttributeName extends NonJsonDreamColumnNames<DataType> | (keyof DataType & string), AttributeName extends MaybeAttributeName extends NonJsonDreamColumnNames<DataType> ? never : Exclude<keyof DataType, keyof Dream> & string, Options extends NonAutomaticSerializerAttributeOptionsWithPossibleDecimalRenderOption>(name: AttributeName, options: Options): DreamSerializerBuilder<DataTypeForOpenapi, MaybeNullDataType, PassthroughDataType, DataType>;
|
|
41
43
|
attribute<AttributeName extends NonJsonDreamColumnNames<DataType> & keyof DataType & string, Options extends AutomaticSerializerAttributeOptions<DataType, AttributeName>>(name: AttributeName, options?: Options): DreamSerializerBuilder<DataTypeForOpenapi, MaybeNullDataType, PassthroughDataType, DataType>;
|
|
42
44
|
/**
|
|
@@ -99,7 +101,8 @@ export default class DreamSerializerBuilder<DataTypeForOpenapi extends typeof Dr
|
|
|
99
101
|
*
|
|
100
102
|
* See: {@link https://your-docs-url.com/docs/serializers/attributes | Serializer Attributes Documentation}
|
|
101
103
|
*/
|
|
102
|
-
customAttribute<Options extends
|
|
104
|
+
customAttribute<Options extends {
|
|
105
|
+
openapi: OpenapiSchemaBodyShorthand | OpenapiShorthandPrimitiveTypes;
|
|
103
106
|
flatten?: boolean;
|
|
104
107
|
}, CallbackFn extends () => unknown>(name: string, fn: CallbackFn, options: Options): this;
|
|
105
108
|
/**
|
|
@@ -41,7 +41,7 @@ type OnStatementForAssociationDefinition<DB, Schema, TableName extends Associati
|
|
|
41
41
|
export type SelfOnStatement<BaseInstance extends Dream, DB, Schema, TableName extends AssociationTableNames<DB, Schema> & keyof DB> = Partial<Record<keyof DB[TableName], DreamColumnNames<BaseInstance>>>;
|
|
42
42
|
export type WhereStatementForJoinedAssociation<JoinedAssociations extends Readonly<JoinedAssociation[]>, DB, Schema, TableName extends AssociationTableNames<DB, Schema> & keyof DB> = RecursiveWhereStatementForJoinedAssociation<JoinedAssociations, DB, Schema, WhereStatement<DB, Schema, TableName>>;
|
|
43
43
|
type RecursiveWhereStatementForJoinedAssociation<JoinedAssociations extends Readonly<JoinedAssociation[]>, DB, Schema, OriginalOnStatement, Depth extends number = 0, CurrentJoinedAssociation = JoinedAssociations[0], TableName = CurrentJoinedAssociation extends JoinedAssociation ? CurrentJoinedAssociation['table'] : never, AssociationName = CurrentJoinedAssociation extends JoinedAssociation ? CurrentJoinedAssociation['alias'] : never, NonNamespacedAssociationOnStatement = TableName extends never ? never : AssociationName extends never ? never : WhereStatement<DB, Schema, TableName & AssociationTableNames<DB, Schema> & keyof DB>, NextOnStatement = NonNamespacedAssociationOnStatement extends never ? OriginalOnStatement : OriginalOnStatement & {
|
|
44
|
-
[K in keyof NonNamespacedAssociationOnStatement as `${AssociationName & string}.${K & string}`]: NonNamespacedAssociationOnStatement[K & keyof NonNamespacedAssociationOnStatement];
|
|
44
|
+
[K in keyof NonNamespacedAssociationOnStatement as `${AssociationName & string}.${K & string}`]: NonNamespacedAssociationOnStatement[K & keyof NonNamespacedAssociationOnStatement] | null;
|
|
45
45
|
}> = JoinedAssociations['length'] extends 0 ? OriginalOnStatement : Depth extends MAX_JOINED_TABLES_DEPTH ? OriginalOnStatement : TableName extends never ? OriginalOnStatement : RecursiveWhereStatementForJoinedAssociation<ReadonlyTail<JoinedAssociations>, DB, Schema, NextOnStatement, Inc<Depth>>;
|
|
46
46
|
export type OrderStatement<DB, Schema, TableName extends AssociationTableNames<DB, Schema> & keyof DB> = TableColumnNames<DB, TableName> | Partial<Record<TableColumnNames<DB, TableName>, OrderDir>>;
|
|
47
47
|
export type LimitStatement = number;
|
|
@@ -266,8 +266,10 @@ type RecursiveWhereStatementForJoinedAssociation<
|
|
|
266
266
|
NextOnStatement = NonNamespacedAssociationOnStatement extends never
|
|
267
267
|
? OriginalOnStatement
|
|
268
268
|
: OriginalOnStatement & {
|
|
269
|
-
[K in keyof NonNamespacedAssociationOnStatement as `${AssociationName & string}.${K & string}`]:
|
|
270
|
-
keyof NonNamespacedAssociationOnStatement]
|
|
269
|
+
[K in keyof NonNamespacedAssociationOnStatement as `${AssociationName & string}.${K & string}`]:
|
|
270
|
+
| NonNamespacedAssociationOnStatement[K & keyof NonNamespacedAssociationOnStatement]
|
|
271
|
+
// `| null` so that we can query for models that don't have a particular association
|
|
272
|
+
| null
|
|
271
273
|
},
|
|
272
274
|
> = JoinedAssociations['length'] extends 0
|
|
273
275
|
? OriginalOnStatement
|
|
@@ -5,6 +5,7 @@ import ObjectSerializerBuilder from '../serializer/builders/ObjectSerializerBuil
|
|
|
5
5
|
import { DreamAttributeDbTypes, DreamSerializable, DreamSerializableArray, ViewModelClass } from './dream.js';
|
|
6
6
|
import { DecimalOpenapiTypesIncludingDbTypes, OpenapiDescription, OpenapiSchemaBodyShorthand, OpenapiShorthandPrimitiveTypes } from './openapi.js';
|
|
7
7
|
export type SerializerCasing = 'camel' | 'snake';
|
|
8
|
+
export type AttributeSerializationSanitizationStrategy = 'unicodeString' | 'htmlEntity' | ((val: any) => any);
|
|
8
9
|
export type DreamsOrSerializersOrViewModels = DreamSerializable | DreamSerializableArray;
|
|
9
10
|
export interface InternalAnyTypedSerializerAttribute {
|
|
10
11
|
type: 'attribute';
|
|
@@ -48,6 +49,7 @@ export interface InternalAnyTypedSerializerRendersMany<DataType, AttributeName e
|
|
|
48
49
|
export type AutomaticSerializerAttributeOptions<DreamInstance extends Dream, AttributeName extends keyof DreamInstance & string> = {
|
|
49
50
|
as?: string;
|
|
50
51
|
default?: any;
|
|
52
|
+
sanitize?: AttributeSerializationSanitizationStrategy;
|
|
51
53
|
openapi?: OpenapiDescription;
|
|
52
54
|
precision?: DreamAttributeDbTypes<DreamInstance>[AttributeName] extends DecimalOpenapiTypesIncludingDbTypes ? RoundingPrecision : never;
|
|
53
55
|
};
|
|
@@ -58,9 +60,16 @@ export type AutomaticSerializerAttributeOptionsForType = {
|
|
|
58
60
|
enum?: string[] | Readonly<string[]>;
|
|
59
61
|
};
|
|
60
62
|
};
|
|
63
|
+
export type SerializerAttributeOptionsForVirtualColumn = {
|
|
64
|
+
as?: string;
|
|
65
|
+
default?: any;
|
|
66
|
+
sanitize?: AttributeSerializationSanitizationStrategy;
|
|
67
|
+
openapi?: OpenapiDescription | OpenapiSchemaBodyShorthand | OpenapiShorthandPrimitiveTypes;
|
|
68
|
+
};
|
|
61
69
|
export type NonAutomaticSerializerAttributeOptions = {
|
|
62
70
|
as?: string;
|
|
63
71
|
default?: any;
|
|
72
|
+
sanitize?: AttributeSerializationSanitizationStrategy;
|
|
64
73
|
openapi: OpenapiSchemaBodyShorthand | OpenapiShorthandPrimitiveTypes;
|
|
65
74
|
};
|
|
66
75
|
export type NonAutomaticSerializerAttributeOptionsWithPossibleDecimalRenderOption = NonAutomaticSerializerAttributeOptions & {
|
|
@@ -11,6 +11,7 @@ import {
|
|
|
11
11
|
} from './openapi.js'
|
|
12
12
|
|
|
13
13
|
export type SerializerCasing = 'camel' | 'snake'
|
|
14
|
+
export type AttributeSerializationSanitizationStrategy = 'unicodeString' | 'htmlEntity' | ((val: any) => any)
|
|
14
15
|
export type DreamsOrSerializersOrViewModels = DreamSerializable | DreamSerializableArray
|
|
15
16
|
|
|
16
17
|
export interface InternalAnyTypedSerializerAttribute<> {
|
|
@@ -68,6 +69,7 @@ export type AutomaticSerializerAttributeOptions<
|
|
|
68
69
|
> = {
|
|
69
70
|
as?: string
|
|
70
71
|
default?: any
|
|
72
|
+
sanitize?: AttributeSerializationSanitizationStrategy
|
|
71
73
|
openapi?: OpenapiDescription
|
|
72
74
|
precision?: DreamAttributeDbTypes<DreamInstance>[AttributeName] extends DecimalOpenapiTypesIncludingDbTypes
|
|
73
75
|
? RoundingPrecision
|
|
@@ -82,9 +84,17 @@ export type AutomaticSerializerAttributeOptionsForType = {
|
|
|
82
84
|
}
|
|
83
85
|
}
|
|
84
86
|
|
|
87
|
+
export type SerializerAttributeOptionsForVirtualColumn = {
|
|
88
|
+
as?: string
|
|
89
|
+
default?: any
|
|
90
|
+
sanitize?: AttributeSerializationSanitizationStrategy
|
|
91
|
+
openapi?: OpenapiDescription | OpenapiSchemaBodyShorthand | OpenapiShorthandPrimitiveTypes
|
|
92
|
+
}
|
|
93
|
+
|
|
85
94
|
export type NonAutomaticSerializerAttributeOptions = {
|
|
86
95
|
as?: string
|
|
87
96
|
default?: any
|
|
97
|
+
sanitize?: AttributeSerializationSanitizationStrategy
|
|
88
98
|
openapi: OpenapiSchemaBodyShorthand | OpenapiShorthandPrimitiveTypes
|
|
89
99
|
}
|
|
90
100
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
window.navigationData = "data:application/octet-stream;base64,
|
|
1
|
+
window.navigationData = "data:application/octet-stream;base64,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"
|