@rvoh/dream 0.43.0-beta.7 → 0.43.0-beta.9
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/Query.js +4 -4
- package/dist/cjs/src/errors/serializers/MissingSerializersDefinitionForKey.js +4 -3
- package/dist/cjs/src/helpers/cli/generateDreamContent.js +14 -7
- package/dist/cjs/src/helpers/cli/generateSerializerContent.js +1 -0
- package/dist/cjs/src/helpers/normalizeUnicode.js +40 -0
- package/dist/cjs/src/helpers/sqlAttributes.js +3 -3
- package/dist/cjs/src/index.js +4 -2
- package/dist/cjs/src/serializer/helpers/inferSerializerFromDreamOrViewModel.js +5 -2
- package/dist/esm/src/dream/Query.js +4 -4
- package/dist/esm/src/errors/serializers/MissingSerializersDefinitionForKey.js +4 -3
- package/dist/esm/src/helpers/cli/generateDreamContent.js +14 -7
- package/dist/esm/src/helpers/cli/generateSerializerContent.js +1 -1
- package/dist/esm/src/helpers/normalizeUnicode.js +37 -0
- package/dist/esm/src/helpers/sqlAttributes.js +3 -3
- package/dist/esm/src/index.js +1 -0
- package/dist/esm/src/serializer/helpers/inferSerializerFromDreamOrViewModel.js +5 -2
- package/dist/types/src/helpers/cli/generateSerializerContent.d.ts +1 -0
- package/dist/types/src/helpers/normalizeUnicode.d.ts +31 -0
- package/dist/types/src/index.d.ts +4 -0
- package/dist/types/src/types/dream.d.ts +1 -1
- package/dist/types/src/types/dream.ts +3 -1
- package/dist/types/src/types/openapi.d.ts +1 -0
- package/dist/types/src/types/openapi.ts +1 -2
- 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/CreateOrFindByFailedToCreateAndFind.html +3 -3
- package/docs/classes/Decorators.html +19 -19
- package/docs/classes/Dream.html +131 -131
- 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 +7 -7
- package/docs/classes/DreamSerializerBuilder.html +2 -2
- 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/NonLoadedAssociation.html +3 -3
- package/docs/classes/ObjectSerializerBuilder.html +2 -2
- package/docs/classes/Query.html +51 -51
- 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 +20 -0
- 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/interfaces/BelongsToStatement.html +14 -0
- 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 +5 -1
- 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/DreamAssociationMetadata.html +1 -1
- package/docs/types/DreamAttributes.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/DreamTableSchema.html +1 -1
- package/docs/types/DreamVirtualColumns.html +1 -1
- package/docs/types/EncryptAlgorithm.html +1 -1
- package/docs/types/HasManyStatement.html +1 -0
- package/docs/types/HasOneStatement.html +1 -0
- package/docs/types/Hyphenized.html +1 -1
- package/docs/types/IdType.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/PrimaryKeyType.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/Timestamp.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/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 +1 -1
- package/dist/cjs/src/helpers/normalizeString.js +0 -10
- package/dist/esm/src/helpers/normalizeString.js +0 -7
- package/dist/types/src/helpers/normalizeString.d.ts +0 -1
|
@@ -34,7 +34,7 @@ const DateTime_js_1 = require("../helpers/DateTime.js");
|
|
|
34
34
|
const isEmpty_js_1 = require("../helpers/isEmpty.js");
|
|
35
35
|
const isObject_js_1 = require("../helpers/isObject.js");
|
|
36
36
|
const namespaceColumn_js_1 = require("../helpers/namespaceColumn.js");
|
|
37
|
-
const
|
|
37
|
+
const normalizeUnicode_js_1 = require("../helpers/normalizeUnicode.js");
|
|
38
38
|
const objectPathsToArrays_js_1 = require("../helpers/objectPathsToArrays.js");
|
|
39
39
|
const protectAgainstPollutingAssignment_js_1 = require("../helpers/protectAgainstPollutingAssignment.js");
|
|
40
40
|
const range_js_1 = require("../helpers/range.js");
|
|
@@ -2504,7 +2504,7 @@ class Query extends ConnectedToDB_js_1.default {
|
|
|
2504
2504
|
c = val.map(v => v instanceof DateTime_js_1.DateTime || v instanceof CalendarDate_js_1.default
|
|
2505
2505
|
? v.toSQL()
|
|
2506
2506
|
: typeof v === 'string'
|
|
2507
|
-
? (0,
|
|
2507
|
+
? (0, normalizeUnicode_js_1.default)(v)
|
|
2508
2508
|
: v);
|
|
2509
2509
|
}
|
|
2510
2510
|
else if (val instanceof curried_ops_statement_js_1.default) {
|
|
@@ -2549,11 +2549,11 @@ class Query extends ConnectedToDB_js_1.default {
|
|
|
2549
2549
|
if (c instanceof DateTime_js_1.DateTime || c instanceof CalendarDate_js_1.default)
|
|
2550
2550
|
c = c.toSQL();
|
|
2551
2551
|
else if (typeof c === 'string')
|
|
2552
|
-
c = (0,
|
|
2552
|
+
c = (0, normalizeUnicode_js_1.default)(c);
|
|
2553
2553
|
if (c2 instanceof DateTime_js_1.DateTime || c2 instanceof CalendarDate_js_1.default)
|
|
2554
2554
|
c2 = c2.toSQL();
|
|
2555
2555
|
else if (typeof c2 === 'string')
|
|
2556
|
-
c2 = (0,
|
|
2556
|
+
c2 = (0, normalizeUnicode_js_1.default)(c2);
|
|
2557
2557
|
if (a && c === undefined)
|
|
2558
2558
|
throw new CannotPassUndefinedAsAValueToAWhereClause_js_1.default(this.dreamClass, a);
|
|
2559
2559
|
if (a2 && c2 === undefined)
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const pascalize_js_1 = require("../../helpers/pascalize.js");
|
|
3
4
|
class MissingSerializersDefinitionForKey extends Error {
|
|
4
5
|
viewModel;
|
|
5
6
|
serializerKey;
|
|
@@ -16,10 +17,10 @@ Missing serializers definition for \`${this.serializerKey}\` on class \`${classN
|
|
|
16
17
|
Try something like this in your ${className}'s serializer getter:
|
|
17
18
|
|
|
18
19
|
class ${className} {
|
|
19
|
-
public get serializers()
|
|
20
|
+
public get serializers() {
|
|
20
21
|
return {
|
|
21
|
-
default:
|
|
22
|
-
${this.serializerKey}:
|
|
22
|
+
default: ${className}Serializer
|
|
23
|
+
${this.serializerKey}: ${className}${(0, pascalize_js_1.default)(this.serializerKey)}Serializer
|
|
23
24
|
}
|
|
24
25
|
}
|
|
25
26
|
...
|
|
@@ -2,30 +2,34 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.default = generateDreamContent;
|
|
4
4
|
const pluralize_esm_1 = require("pluralize-esm");
|
|
5
|
-
const
|
|
5
|
+
const serializerNameFromFullyQualifiedModelName_js_1 = require("../../serializer/helpers/serializerNameFromFullyQualifiedModelName.js");
|
|
6
6
|
const camelize_js_1 = require("../camelize.js");
|
|
7
7
|
const globalClassNameFromFullyQualifiedModelName_js_1 = require("../globalClassNameFromFullyQualifiedModelName.js");
|
|
8
8
|
const relativeDreamPath_js_1 = require("../path/relativeDreamPath.js");
|
|
9
9
|
const snakeify_js_1 = require("../snakeify.js");
|
|
10
10
|
const standardizeFullyQualifiedModelName_js_1 = require("../standardizeFullyQualifiedModelName.js");
|
|
11
11
|
const uniq_js_1 = require("../uniq.js");
|
|
12
|
+
const generateSerializerContent_js_1 = require("./generateSerializerContent.js");
|
|
12
13
|
function generateDreamContent({ fullyQualifiedModelName, columnsWithTypes, fullyQualifiedParentName, serializer, }) {
|
|
13
14
|
fullyQualifiedModelName = (0, standardizeFullyQualifiedModelName_js_1.default)(fullyQualifiedModelName);
|
|
14
15
|
const modelClassName = (0, globalClassNameFromFullyQualifiedModelName_js_1.default)(fullyQualifiedModelName);
|
|
15
16
|
let parentModelClassName;
|
|
16
17
|
const dreamImports = ['Decorators', 'DreamColumn'];
|
|
17
|
-
if (serializer)
|
|
18
|
-
dreamImports.push('DreamSerializers');
|
|
19
18
|
const isSTI = !!fullyQualifiedParentName;
|
|
20
19
|
if (isSTI) {
|
|
21
20
|
fullyQualifiedParentName = (0, standardizeFullyQualifiedModelName_js_1.default)(fullyQualifiedParentName);
|
|
22
21
|
parentModelClassName = (0, globalClassNameFromFullyQualifiedModelName_js_1.default)(fullyQualifiedParentName);
|
|
23
22
|
dreamImports.push('STI');
|
|
24
23
|
}
|
|
24
|
+
const serialzerClassName = (0, serializerNameFromFullyQualifiedModelName_js_1.default)((0, generateSerializerContent_js_1.fullyQualifiedModelNameToSerializerBaseName)(fullyQualifiedModelName));
|
|
25
|
+
const summarySerialzerClassName = (0, serializerNameFromFullyQualifiedModelName_js_1.default)((0, generateSerializerContent_js_1.fullyQualifiedModelNameToSerializerBaseName)(fullyQualifiedModelName), 'summary');
|
|
25
26
|
const idTypescriptType = `DreamColumn<${modelClassName}, 'id'>`;
|
|
26
27
|
const modelImportStatements = isSTI
|
|
27
28
|
? [importStatementForModel(fullyQualifiedModelName, fullyQualifiedParentName)]
|
|
28
29
|
: [importStatementForModel(fullyQualifiedModelName, 'ApplicationModel')];
|
|
30
|
+
const serializerImportStatement = serializer
|
|
31
|
+
? importStatementForSerializers(fullyQualifiedModelName, serialzerClassName, summarySerialzerClassName)
|
|
32
|
+
: '';
|
|
29
33
|
const attributeStatements = columnsWithTypes.map(attribute => {
|
|
30
34
|
const [attributeName, attributeType, ...descriptors] = attribute.split(':');
|
|
31
35
|
if (attributeName === undefined)
|
|
@@ -76,7 +80,7 @@ public ${(0, camelize_js_1.default)(attributeName)}: ${getAttributeType(attribut
|
|
|
76
80
|
timestamps = timestamps.replace(/\n$/, '');
|
|
77
81
|
const tableName = (0, snakeify_js_1.default)((0, pluralize_esm_1.default)(fullyQualifiedModelName.replace(/\//g, '_')));
|
|
78
82
|
return `\
|
|
79
|
-
import { ${(0, uniq_js_1.default)(dreamImports).join(', ')} } from '@rvoh/dream'${(0, uniq_js_1.default)(modelImportStatements).join('')}
|
|
83
|
+
import { ${(0, uniq_js_1.default)(dreamImports).join(', ')} } from '@rvoh/dream'${(0, uniq_js_1.default)(modelImportStatements).join('')}${serializerImportStatement}
|
|
80
84
|
|
|
81
85
|
const deco = new Decorators<typeof ${modelClassName}>()
|
|
82
86
|
|
|
@@ -89,10 +93,10 @@ ${isSTI
|
|
|
89
93
|
}
|
|
90
94
|
|
|
91
95
|
`}${serializer
|
|
92
|
-
? ` public ${isSTI ? 'override ' : ''}get serializers()
|
|
96
|
+
? ` public ${isSTI ? 'override ' : ''}get serializers() {
|
|
93
97
|
return {
|
|
94
|
-
default:
|
|
95
|
-
summary:
|
|
98
|
+
default: ${serialzerClassName},
|
|
99
|
+
summary: ${summarySerialzerClassName},
|
|
96
100
|
}
|
|
97
101
|
}
|
|
98
102
|
|
|
@@ -107,3 +111,6 @@ function getAttributeType(attribute, modelClassName) {
|
|
|
107
111
|
function importStatementForModel(originModelName, destinationModelName = originModelName) {
|
|
108
112
|
return `\nimport ${(0, globalClassNameFromFullyQualifiedModelName_js_1.default)(destinationModelName)} from '${(0, relativeDreamPath_js_1.default)('models', 'models', originModelName, destinationModelName)}'`;
|
|
109
113
|
}
|
|
114
|
+
function importStatementForSerializers(originModelName, serialzerClassName, summarySerialzerClassName) {
|
|
115
|
+
return `\nimport { ${serialzerClassName}, ${summarySerialzerClassName} } from '${(0, relativeDreamPath_js_1.default)('models', 'serializers', originModelName)}'`;
|
|
116
|
+
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.default = generateSerializerContent;
|
|
4
|
+
exports.fullyQualifiedModelNameToSerializerBaseName = fullyQualifiedModelNameToSerializerBaseName;
|
|
4
5
|
const serializerNameFromFullyQualifiedModelName_js_1 = require("../../serializer/helpers/serializerNameFromFullyQualifiedModelName.js");
|
|
5
6
|
const camelize_js_1 = require("../camelize.js");
|
|
6
7
|
const globalClassNameFromFullyQualifiedModelName_js_1 = require("../globalClassNameFromFullyQualifiedModelName.js");
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.default = normalizeUnicode;
|
|
4
|
+
const index_js_1 = require("../dream-app/index.js");
|
|
5
|
+
/**
|
|
6
|
+
* Normalizes a Unicode string according to the application's configured normalization form.
|
|
7
|
+
*
|
|
8
|
+
* Unicode normalization ensures text consistency by converting characters to a canonical
|
|
9
|
+
* representation. This is crucial for text comparison, searching, and data integrity,
|
|
10
|
+
* as the same visual text can be represented differently in Unicode (e.g., é as a single
|
|
11
|
+
* character vs. e + combining accent).
|
|
12
|
+
*
|
|
13
|
+
* The normalization form is configured via `psy.set('unicodeNormalization', form)`
|
|
14
|
+
* in app/conf.ts. The default form is 'NFC'. All strings and string arrays passed
|
|
15
|
+
* into Dream models are automatically normalized before database storage (values
|
|
16
|
+
* in JSON/JSONB fields are not automatically normalized). String values in queries
|
|
17
|
+
* (e.g., `where`, `and`) are automatically normalized to ensure search consistency.
|
|
18
|
+
*
|
|
19
|
+
* @param val - The string to normalize
|
|
20
|
+
* @returns The normalized string, or the original string if normalization is disabled ('none')
|
|
21
|
+
*
|
|
22
|
+
* @see {@link https://unicode.org/reports/tr15/ | Unicode Normalization Forms (UAX #15)}
|
|
23
|
+
* @see {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/normalize | String.prototype.normalize()}
|
|
24
|
+
*
|
|
25
|
+
* @example
|
|
26
|
+
* ```typescript
|
|
27
|
+
* // With NFC normalization (default)
|
|
28
|
+
* normalizeUnicode('café') // Returns normalized form of café
|
|
29
|
+
*
|
|
30
|
+
* // With normalization disabled
|
|
31
|
+
* psy.set('unicodeNormalization', 'none')
|
|
32
|
+
* normalizeUnicode('café') // Returns original string unchanged
|
|
33
|
+
* ```
|
|
34
|
+
*/
|
|
35
|
+
function normalizeUnicode(val) {
|
|
36
|
+
const normalizationForm = index_js_1.default.getOrFail().unicodeNormalization;
|
|
37
|
+
if (normalizationForm === 'none')
|
|
38
|
+
return val;
|
|
39
|
+
return typeof val === 'string' ? val.normalize(normalizationForm) : val;
|
|
40
|
+
}
|
|
@@ -5,7 +5,7 @@ const CalendarDate_js_1 = require("./CalendarDate.js");
|
|
|
5
5
|
const DateTime_js_1 = require("./DateTime.js");
|
|
6
6
|
const isDatetimeOrDatetimeArrayColumn_js_1 = require("./db/types/isDatetimeOrDatetimeArrayColumn.js");
|
|
7
7
|
const isTextOrTextArrayColumn_js_1 = require("./db/types/isTextOrTextArrayColumn.js");
|
|
8
|
-
const
|
|
8
|
+
const normalizeUnicode_js_1 = require("./normalizeUnicode.js");
|
|
9
9
|
function sqlAttributes(dream) {
|
|
10
10
|
const attributes = dream.dirtyAttributes();
|
|
11
11
|
const dreamClass = dream.constructor;
|
|
@@ -17,13 +17,13 @@ function sqlAttributes(dream) {
|
|
|
17
17
|
if ((0, isDatetimeOrDatetimeArrayColumn_js_1.default)(dreamClass, key))
|
|
18
18
|
val = val.map(valueToDatetime);
|
|
19
19
|
else if ((0, isTextOrTextArrayColumn_js_1.default)(dreamClass, key))
|
|
20
|
-
val = val.map(
|
|
20
|
+
val = val.map(normalizeUnicode_js_1.default);
|
|
21
21
|
}
|
|
22
22
|
else {
|
|
23
23
|
if ((0, isDatetimeOrDatetimeArrayColumn_js_1.default)(dreamClass, key))
|
|
24
24
|
val = valueToDatetime(val);
|
|
25
25
|
else if ((0, isTextOrTextArrayColumn_js_1.default)(dreamClass, key))
|
|
26
|
-
val = (0,
|
|
26
|
+
val = (0, normalizeUnicode_js_1.default)(val);
|
|
27
27
|
}
|
|
28
28
|
if (val instanceof DateTime_js_1.DateTime || val instanceof CalendarDate_js_1.default) {
|
|
29
29
|
// Converting toJSDate resulted in the correct timezone, but even with process.env.TZ=UTC,
|
package/dist/cjs/src/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
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 = void 0;
|
|
3
|
+
exports.Range = exports.sharedPathPrefix = exports.relativeDreamPath = exports.dreamPath = exports.pascalize = exports.normalizeUnicode = exports.loadRepl = exports.isEmpty = 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.CreateOrFindByFailedToCreateAndFind = exports.NonLoadedAssociation = exports.Encrypt = exports.Query = exports.DreamTransaction = exports.openapiShorthandPrimitiveTypes = exports.openapiPrimitiveTypes = exports.DreamConst = exports.Dream = 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.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 = 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 index_js_2 = require("./cli/index.js");
|
|
@@ -87,6 +87,8 @@ var isEmpty_js_1 = require("./helpers/isEmpty.js");
|
|
|
87
87
|
Object.defineProperty(exports, "isEmpty", { enumerable: true, get: function () { return isEmpty_js_1.default; } });
|
|
88
88
|
var loadRepl_js_1 = require("./helpers/loadRepl.js");
|
|
89
89
|
Object.defineProperty(exports, "loadRepl", { enumerable: true, get: function () { return loadRepl_js_1.default; } });
|
|
90
|
+
var normalizeUnicode_js_1 = require("./helpers/normalizeUnicode.js");
|
|
91
|
+
Object.defineProperty(exports, "normalizeUnicode", { enumerable: true, get: function () { return normalizeUnicode_js_1.default; } });
|
|
90
92
|
var pascalize_js_1 = require("./helpers/pascalize.js");
|
|
91
93
|
Object.defineProperty(exports, "pascalize", { enumerable: true, get: function () { return pascalize_js_1.default; } });
|
|
92
94
|
var dreamPath_js_1 = require("./helpers/path/dreamPath.js");
|
|
@@ -18,9 +18,12 @@ function inferSerializerFromDreamOrViewModel(obj, serializerKey = exports.DEFAUL
|
|
|
18
18
|
const serializers = obj.serializers;
|
|
19
19
|
if (!serializers)
|
|
20
20
|
throw new MissingSerializersDefinition_js_1.default(obj);
|
|
21
|
-
const
|
|
22
|
-
if (!
|
|
21
|
+
const serializerOrGlobalName = serializers[serializerKey];
|
|
22
|
+
if (!serializerOrGlobalName)
|
|
23
23
|
throw new MissingSerializersDefinitionForKey_js_1.default(obj, serializerKey);
|
|
24
|
+
if ((0, isDreamSerializer_js_1.default)(serializerOrGlobalName))
|
|
25
|
+
return serializerOrGlobalName;
|
|
26
|
+
const globalName = serializerOrGlobalName;
|
|
24
27
|
const dreamApp = index_js_1.default.getOrFail();
|
|
25
28
|
const serializer = dreamApp.serializers[globalName];
|
|
26
29
|
if (!serializer)
|
|
@@ -32,7 +32,7 @@ import { DateTime } from '../helpers/DateTime.js';
|
|
|
32
32
|
import isEmpty from '../helpers/isEmpty.js';
|
|
33
33
|
import isObject from '../helpers/isObject.js';
|
|
34
34
|
import namespaceColumn from '../helpers/namespaceColumn.js';
|
|
35
|
-
import
|
|
35
|
+
import normalizeUnicode from '../helpers/normalizeUnicode.js';
|
|
36
36
|
import objectPathsToArrays from '../helpers/objectPathsToArrays.js';
|
|
37
37
|
import protectAgainstPollutingAssignment from '../helpers/protectAgainstPollutingAssignment.js';
|
|
38
38
|
import { Range } from '../helpers/range.js';
|
|
@@ -2502,7 +2502,7 @@ export default class Query extends ConnectedToDB {
|
|
|
2502
2502
|
c = val.map(v => v instanceof DateTime || v instanceof CalendarDate
|
|
2503
2503
|
? v.toSQL()
|
|
2504
2504
|
: typeof v === 'string'
|
|
2505
|
-
?
|
|
2505
|
+
? normalizeUnicode(v)
|
|
2506
2506
|
: v);
|
|
2507
2507
|
}
|
|
2508
2508
|
else if (val instanceof CurriedOpsStatement) {
|
|
@@ -2547,11 +2547,11 @@ export default class Query extends ConnectedToDB {
|
|
|
2547
2547
|
if (c instanceof DateTime || c instanceof CalendarDate)
|
|
2548
2548
|
c = c.toSQL();
|
|
2549
2549
|
else if (typeof c === 'string')
|
|
2550
|
-
c =
|
|
2550
|
+
c = normalizeUnicode(c);
|
|
2551
2551
|
if (c2 instanceof DateTime || c2 instanceof CalendarDate)
|
|
2552
2552
|
c2 = c2.toSQL();
|
|
2553
2553
|
else if (typeof c2 === 'string')
|
|
2554
|
-
c2 =
|
|
2554
|
+
c2 = normalizeUnicode(c2);
|
|
2555
2555
|
if (a && c === undefined)
|
|
2556
2556
|
throw new CannotPassUndefinedAsAValueToAWhereClause(this.dreamClass, a);
|
|
2557
2557
|
if (a2 && c2 === undefined)
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import pascalize from '../../helpers/pascalize.js';
|
|
1
2
|
export default class MissingSerializersDefinitionForKey extends Error {
|
|
2
3
|
viewModel;
|
|
3
4
|
serializerKey;
|
|
@@ -14,10 +15,10 @@ Missing serializers definition for \`${this.serializerKey}\` on class \`${classN
|
|
|
14
15
|
Try something like this in your ${className}'s serializer getter:
|
|
15
16
|
|
|
16
17
|
class ${className} {
|
|
17
|
-
public get serializers()
|
|
18
|
+
public get serializers() {
|
|
18
19
|
return {
|
|
19
|
-
default:
|
|
20
|
-
${this.serializerKey}:
|
|
20
|
+
default: ${className}Serializer
|
|
21
|
+
${this.serializerKey}: ${className}${pascalize(this.serializerKey)}Serializer
|
|
21
22
|
}
|
|
22
23
|
}
|
|
23
24
|
...
|
|
@@ -1,28 +1,32 @@
|
|
|
1
1
|
import pluralize from 'pluralize-esm';
|
|
2
|
-
import
|
|
2
|
+
import serializerNameFromFullyQualifiedModelName from '../../serializer/helpers/serializerNameFromFullyQualifiedModelName.js';
|
|
3
3
|
import camelize from '../camelize.js';
|
|
4
4
|
import globalClassNameFromFullyQualifiedModelName from '../globalClassNameFromFullyQualifiedModelName.js';
|
|
5
5
|
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
|
+
import { fullyQualifiedModelNameToSerializerBaseName } from './generateSerializerContent.js';
|
|
9
10
|
export default function generateDreamContent({ fullyQualifiedModelName, columnsWithTypes, fullyQualifiedParentName, serializer, }) {
|
|
10
11
|
fullyQualifiedModelName = standardizeFullyQualifiedModelName(fullyQualifiedModelName);
|
|
11
12
|
const modelClassName = globalClassNameFromFullyQualifiedModelName(fullyQualifiedModelName);
|
|
12
13
|
let parentModelClassName;
|
|
13
14
|
const dreamImports = ['Decorators', 'DreamColumn'];
|
|
14
|
-
if (serializer)
|
|
15
|
-
dreamImports.push('DreamSerializers');
|
|
16
15
|
const isSTI = !!fullyQualifiedParentName;
|
|
17
16
|
if (isSTI) {
|
|
18
17
|
fullyQualifiedParentName = standardizeFullyQualifiedModelName(fullyQualifiedParentName);
|
|
19
18
|
parentModelClassName = globalClassNameFromFullyQualifiedModelName(fullyQualifiedParentName);
|
|
20
19
|
dreamImports.push('STI');
|
|
21
20
|
}
|
|
21
|
+
const serialzerClassName = serializerNameFromFullyQualifiedModelName(fullyQualifiedModelNameToSerializerBaseName(fullyQualifiedModelName));
|
|
22
|
+
const summarySerialzerClassName = serializerNameFromFullyQualifiedModelName(fullyQualifiedModelNameToSerializerBaseName(fullyQualifiedModelName), 'summary');
|
|
22
23
|
const idTypescriptType = `DreamColumn<${modelClassName}, 'id'>`;
|
|
23
24
|
const modelImportStatements = isSTI
|
|
24
25
|
? [importStatementForModel(fullyQualifiedModelName, fullyQualifiedParentName)]
|
|
25
26
|
: [importStatementForModel(fullyQualifiedModelName, 'ApplicationModel')];
|
|
27
|
+
const serializerImportStatement = serializer
|
|
28
|
+
? importStatementForSerializers(fullyQualifiedModelName, serialzerClassName, summarySerialzerClassName)
|
|
29
|
+
: '';
|
|
26
30
|
const attributeStatements = columnsWithTypes.map(attribute => {
|
|
27
31
|
const [attributeName, attributeType, ...descriptors] = attribute.split(':');
|
|
28
32
|
if (attributeName === undefined)
|
|
@@ -73,7 +77,7 @@ public ${camelize(attributeName)}: ${getAttributeType(attribute, modelClassName)
|
|
|
73
77
|
timestamps = timestamps.replace(/\n$/, '');
|
|
74
78
|
const tableName = snakeify(pluralize(fullyQualifiedModelName.replace(/\//g, '_')));
|
|
75
79
|
return `\
|
|
76
|
-
import { ${uniq(dreamImports).join(', ')} } from '@rvoh/dream'${uniq(modelImportStatements).join('')}
|
|
80
|
+
import { ${uniq(dreamImports).join(', ')} } from '@rvoh/dream'${uniq(modelImportStatements).join('')}${serializerImportStatement}
|
|
77
81
|
|
|
78
82
|
const deco = new Decorators<typeof ${modelClassName}>()
|
|
79
83
|
|
|
@@ -86,10 +90,10 @@ ${isSTI
|
|
|
86
90
|
}
|
|
87
91
|
|
|
88
92
|
`}${serializer
|
|
89
|
-
? ` public ${isSTI ? 'override ' : ''}get serializers()
|
|
93
|
+
? ` public ${isSTI ? 'override ' : ''}get serializers() {
|
|
90
94
|
return {
|
|
91
|
-
default:
|
|
92
|
-
summary:
|
|
95
|
+
default: ${serialzerClassName},
|
|
96
|
+
summary: ${summarySerialzerClassName},
|
|
93
97
|
}
|
|
94
98
|
}
|
|
95
99
|
|
|
@@ -104,3 +108,6 @@ function getAttributeType(attribute, modelClassName) {
|
|
|
104
108
|
function importStatementForModel(originModelName, destinationModelName = originModelName) {
|
|
105
109
|
return `\nimport ${globalClassNameFromFullyQualifiedModelName(destinationModelName)} from '${relativeDreamPath('models', 'models', originModelName, destinationModelName)}'`;
|
|
106
110
|
}
|
|
111
|
+
function importStatementForSerializers(originModelName, serialzerClassName, summarySerialzerClassName) {
|
|
112
|
+
return `\nimport { ${serialzerClassName}, ${summarySerialzerClassName} } from '${relativeDreamPath('models', 'serializers', originModelName)}'`;
|
|
113
|
+
}
|
|
@@ -84,6 +84,6 @@ function importStatementForModel(originModelName, destinationModelName = originM
|
|
|
84
84
|
const importFrom = relativeDreamPath('serializers', 'models', originModelName, destinationModelName);
|
|
85
85
|
return `import ${modelName} from '${importFrom}'\n`;
|
|
86
86
|
}
|
|
87
|
-
function fullyQualifiedModelNameToSerializerBaseName(fullyQualifiedModelName) {
|
|
87
|
+
export function fullyQualifiedModelNameToSerializerBaseName(fullyQualifiedModelName) {
|
|
88
88
|
return fullyQualifiedModelName.replace(/\//g, '');
|
|
89
89
|
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import DreamApp from '../dream-app/index.js';
|
|
2
|
+
/**
|
|
3
|
+
* Normalizes a Unicode string according to the application's configured normalization form.
|
|
4
|
+
*
|
|
5
|
+
* Unicode normalization ensures text consistency by converting characters to a canonical
|
|
6
|
+
* representation. This is crucial for text comparison, searching, and data integrity,
|
|
7
|
+
* as the same visual text can be represented differently in Unicode (e.g., é as a single
|
|
8
|
+
* character vs. e + combining accent).
|
|
9
|
+
*
|
|
10
|
+
* The normalization form is configured via `psy.set('unicodeNormalization', form)`
|
|
11
|
+
* in app/conf.ts. The default form is 'NFC'. All strings and string arrays passed
|
|
12
|
+
* into Dream models are automatically normalized before database storage (values
|
|
13
|
+
* in JSON/JSONB fields are not automatically normalized). String values in queries
|
|
14
|
+
* (e.g., `where`, `and`) are automatically normalized to ensure search consistency.
|
|
15
|
+
*
|
|
16
|
+
* @param val - The string to normalize
|
|
17
|
+
* @returns The normalized string, or the original string if normalization is disabled ('none')
|
|
18
|
+
*
|
|
19
|
+
* @see {@link https://unicode.org/reports/tr15/ | Unicode Normalization Forms (UAX #15)}
|
|
20
|
+
* @see {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/normalize | String.prototype.normalize()}
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* ```typescript
|
|
24
|
+
* // With NFC normalization (default)
|
|
25
|
+
* normalizeUnicode('café') // Returns normalized form of café
|
|
26
|
+
*
|
|
27
|
+
* // With normalization disabled
|
|
28
|
+
* psy.set('unicodeNormalization', 'none')
|
|
29
|
+
* normalizeUnicode('café') // Returns original string unchanged
|
|
30
|
+
* ```
|
|
31
|
+
*/
|
|
32
|
+
export default function normalizeUnicode(val) {
|
|
33
|
+
const normalizationForm = DreamApp.getOrFail().unicodeNormalization;
|
|
34
|
+
if (normalizationForm === 'none')
|
|
35
|
+
return val;
|
|
36
|
+
return typeof val === 'string' ? val.normalize(normalizationForm) : val;
|
|
37
|
+
}
|
|
@@ -2,7 +2,7 @@ import CalendarDate from './CalendarDate.js';
|
|
|
2
2
|
import { DateTime } from './DateTime.js';
|
|
3
3
|
import isDatetimeOrDatetimeArrayColumn from './db/types/isDatetimeOrDatetimeArrayColumn.js';
|
|
4
4
|
import isTextOrTextArrayColumn from './db/types/isTextOrTextArrayColumn.js';
|
|
5
|
-
import
|
|
5
|
+
import normalizeUnicode from './normalizeUnicode.js';
|
|
6
6
|
export default function sqlAttributes(dream) {
|
|
7
7
|
const attributes = dream.dirtyAttributes();
|
|
8
8
|
const dreamClass = dream.constructor;
|
|
@@ -14,13 +14,13 @@ export default function sqlAttributes(dream) {
|
|
|
14
14
|
if (isDatetimeOrDatetimeArrayColumn(dreamClass, key))
|
|
15
15
|
val = val.map(valueToDatetime);
|
|
16
16
|
else if (isTextOrTextArrayColumn(dreamClass, key))
|
|
17
|
-
val = val.map(
|
|
17
|
+
val = val.map(normalizeUnicode);
|
|
18
18
|
}
|
|
19
19
|
else {
|
|
20
20
|
if (isDatetimeOrDatetimeArrayColumn(dreamClass, key))
|
|
21
21
|
val = valueToDatetime(val);
|
|
22
22
|
else if (isTextOrTextArrayColumn(dreamClass, key))
|
|
23
|
-
val =
|
|
23
|
+
val = normalizeUnicode(val);
|
|
24
24
|
}
|
|
25
25
|
if (val instanceof DateTime || val instanceof CalendarDate) {
|
|
26
26
|
// Converting toJSDate resulted in the correct timezone, but even with process.env.TZ=UTC,
|
package/dist/esm/src/index.js
CHANGED
|
@@ -39,6 +39,7 @@ export { default as hyphenize } from './helpers/hyphenize.js';
|
|
|
39
39
|
export { default as intersection } from './helpers/intersection.js';
|
|
40
40
|
export { default as isEmpty } from './helpers/isEmpty.js';
|
|
41
41
|
export { default as loadRepl } from './helpers/loadRepl.js';
|
|
42
|
+
export { default as normalizeUnicode } from './helpers/normalizeUnicode.js';
|
|
42
43
|
export { default as pascalize } from './helpers/pascalize.js';
|
|
43
44
|
export { default as dreamPath } from './helpers/path/dreamPath.js';
|
|
44
45
|
export { default as relativeDreamPath } from './helpers/path/relativeDreamPath.js';
|
|
@@ -13,9 +13,12 @@ export default function inferSerializerFromDreamOrViewModel(obj, serializerKey =
|
|
|
13
13
|
const serializers = obj.serializers;
|
|
14
14
|
if (!serializers)
|
|
15
15
|
throw new MissingSerializersDefinition(obj);
|
|
16
|
-
const
|
|
17
|
-
if (!
|
|
16
|
+
const serializerOrGlobalName = serializers[serializerKey];
|
|
17
|
+
if (!serializerOrGlobalName)
|
|
18
18
|
throw new MissingSerializersDefinitionForKey(obj, serializerKey);
|
|
19
|
+
if (isDreamSerializer(serializerOrGlobalName))
|
|
20
|
+
return serializerOrGlobalName;
|
|
21
|
+
const globalName = serializerOrGlobalName;
|
|
19
22
|
const dreamApp = DreamApp.getOrFail();
|
|
20
23
|
const serializer = dreamApp.serializers[globalName];
|
|
21
24
|
if (!serializer)
|
|
@@ -4,3 +4,4 @@ export default function generateSerializerContent({ fullyQualifiedModelName, col
|
|
|
4
4
|
fullyQualifiedParentName?: string | undefined;
|
|
5
5
|
stiBaseSerializer?: boolean;
|
|
6
6
|
}): string;
|
|
7
|
+
export declare function fullyQualifiedModelNameToSerializerBaseName(fullyQualifiedModelName: string): string;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Normalizes a Unicode string according to the application's configured normalization form.
|
|
3
|
+
*
|
|
4
|
+
* Unicode normalization ensures text consistency by converting characters to a canonical
|
|
5
|
+
* representation. This is crucial for text comparison, searching, and data integrity,
|
|
6
|
+
* as the same visual text can be represented differently in Unicode (e.g., é as a single
|
|
7
|
+
* character vs. e + combining accent).
|
|
8
|
+
*
|
|
9
|
+
* The normalization form is configured via `psy.set('unicodeNormalization', form)`
|
|
10
|
+
* in app/conf.ts. The default form is 'NFC'. All strings and string arrays passed
|
|
11
|
+
* into Dream models are automatically normalized before database storage (values
|
|
12
|
+
* in JSON/JSONB fields are not automatically normalized). String values in queries
|
|
13
|
+
* (e.g., `where`, `and`) are automatically normalized to ensure search consistency.
|
|
14
|
+
*
|
|
15
|
+
* @param val - The string to normalize
|
|
16
|
+
* @returns The normalized string, or the original string if normalization is disabled ('none')
|
|
17
|
+
*
|
|
18
|
+
* @see {@link https://unicode.org/reports/tr15/ | Unicode Normalization Forms (UAX #15)}
|
|
19
|
+
* @see {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/normalize | String.prototype.normalize()}
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* ```typescript
|
|
23
|
+
* // With NFC normalization (default)
|
|
24
|
+
* normalizeUnicode('café') // Returns normalized form of café
|
|
25
|
+
*
|
|
26
|
+
* // With normalization disabled
|
|
27
|
+
* psy.set('unicodeNormalization', 'none')
|
|
28
|
+
* normalizeUnicode('café') // Returns original string unchanged
|
|
29
|
+
* ```
|
|
30
|
+
*/
|
|
31
|
+
export default function normalizeUnicode(val: string): string;
|
|
@@ -40,6 +40,7 @@ export { default as hyphenize } from './helpers/hyphenize.js';
|
|
|
40
40
|
export { default as intersection } from './helpers/intersection.js';
|
|
41
41
|
export { default as isEmpty } from './helpers/isEmpty.js';
|
|
42
42
|
export { default as loadRepl } from './helpers/loadRepl.js';
|
|
43
|
+
export { default as normalizeUnicode } from './helpers/normalizeUnicode.js';
|
|
43
44
|
export { default as pascalize } from './helpers/pascalize.js';
|
|
44
45
|
export { default as dreamPath } from './helpers/path/dreamPath.js';
|
|
45
46
|
export { default as relativeDreamPath } from './helpers/path/relativeDreamPath.js';
|
|
@@ -65,6 +66,9 @@ export { default as DreamSerializer } from './serializer/DreamSerializer.js';
|
|
|
65
66
|
export { default as ObjectSerializer } from './serializer/ObjectSerializer.js';
|
|
66
67
|
export { default as DreamSerializerBuilder } from './serializer/builders/DreamSerializerBuilder.js';
|
|
67
68
|
export { default as ObjectSerializerBuilder } from './serializer/builders/ObjectSerializerBuilder.js';
|
|
69
|
+
export { type BelongsToStatement } from './types/associations/belongsTo.js';
|
|
70
|
+
export { type HasManyStatement } from './types/associations/hasMany.js';
|
|
71
|
+
export { type HasOneStatement } from './types/associations/hasOne.js';
|
|
68
72
|
export { type WhereStatementForDream, type WhereStatementForDreamClass } from './types/associations/shared.js';
|
|
69
73
|
export { type DbConnectionType, type DbTypes } from './types/db.js';
|
|
70
74
|
export { type DreamAssociationMetadata, type DreamAttributes, type DreamClassColumn, type DreamColumn, type DreamColumnNames, type DreamOrViewModelClassSerializerKey, type DreamOrViewModelSerializerKey, type DreamParamSafeAttributes, type DreamParamSafeColumnNames, type DreamSerializable, type DreamSerializableArray, type DreamSerializerKey, type DreamSerializers, type DreamTableSchema, type DreamVirtualColumns, type IdType, type PrimaryKeyType, type Timestamp, type UpdateableAssociationProperties, type UpdateableProperties, type ViewModel, type ViewModelClass, } from './types/dream.js';
|
|
@@ -84,7 +84,7 @@ type GlobalSerializerNames<I extends Dream, GlobalSchema = I['globalSchema'], Gl
|
|
|
84
84
|
export type DreamSerializers<I extends Dream> = Record<'default', GlobalSerializerName<I>> & Record<string, GlobalSerializerName<I>>;
|
|
85
85
|
export type DreamConstructorType<T extends Dream> = (new (...arguments_: any[]) => T) & typeof Dream;
|
|
86
86
|
export type ViewModel = {
|
|
87
|
-
serializers: Record<string, string>;
|
|
87
|
+
serializers: Record<string, DreamModelSerializerType | SimpleObjectSerializerType | string>;
|
|
88
88
|
};
|
|
89
89
|
export type ViewModelClass = abstract new (...args: any) => ViewModel;
|
|
90
90
|
export type NextPreloadArgumentType<Schema, PreviousTableNames, PreviousSchemaAssociations = PreviousTableNames extends undefined ? undefined : Schema[PreviousTableNames & keyof Schema]['associations' & keyof Schema[PreviousTableNames & keyof Schema]]> = PreviousTableNames extends undefined ? undefined : (keyof PreviousSchemaAssociations & string) | (keyof PreviousSchemaAssociations & string)[];
|
|
@@ -345,7 +345,9 @@ export type DreamSerializers<I extends Dream> = Record<'default', GlobalSerializ
|
|
|
345
345
|
|
|
346
346
|
export type DreamConstructorType<T extends Dream> = (new (...arguments_: any[]) => T) & typeof Dream
|
|
347
347
|
|
|
348
|
-
export type ViewModel = {
|
|
348
|
+
export type ViewModel = {
|
|
349
|
+
serializers: Record<string, DreamModelSerializerType | SimpleObjectSerializerType | string>
|
|
350
|
+
}
|
|
349
351
|
export type ViewModelClass = abstract new (...args: any) => ViewModel
|
|
350
352
|
|
|
351
353
|
// preload
|
|
@@ -21,6 +21,7 @@ export type OpenapiSchemaShorthandExpressionSerializerRef = {
|
|
|
21
21
|
};
|
|
22
22
|
export type OpenapiSchemaShorthandExpressionSerializableRef = {
|
|
23
23
|
$serializable: typeof Dream | ViewModelClass;
|
|
24
|
+
$serializableSerializerKey?: string;
|
|
24
25
|
key?: string;
|
|
25
26
|
many?: boolean;
|
|
26
27
|
maybeNull?: boolean;
|
|
@@ -50,10 +50,9 @@ export type OpenapiSchemaShorthandExpressionSerializerRef = {
|
|
|
50
50
|
maybeNull?: boolean
|
|
51
51
|
}
|
|
52
52
|
|
|
53
|
-
// TODO: remove $serializable or else add support for it (keeping in mind that STI
|
|
54
|
-
// base Dream models get expanded into an array of Dream models)
|
|
55
53
|
export type OpenapiSchemaShorthandExpressionSerializableRef = {
|
|
56
54
|
$serializable: typeof Dream | ViewModelClass
|
|
55
|
+
$serializableSerializerKey?: string
|
|
57
56
|
key?: string
|
|
58
57
|
many?: boolean
|
|
59
58
|
maybeNull?: boolean
|
|
@@ -1 +1 @@
|
|
|
1
|
-
window.navigationData = "data:application/octet-stream;base64,H4sIAAAAAAAAE62bXZPaNhSG/wvX6UfSJG1zB+
|
|
1
|
+
window.navigationData = "data:application/octet-stream;base64,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"
|