@tstdl/base 0.93.29 → 0.93.31
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/orm/query/parade.d.ts +1 -1
- package/orm/schemas/index.d.ts +1 -0
- package/orm/schemas/index.js +1 -0
- package/orm/schemas/numeric.d.ts +17 -0
- package/orm/schemas/numeric.js +23 -0
- package/orm/server/drizzle/schema-converter.js +3 -6
- package/orm/server/query-converter.js +1 -2
- package/orm/types.d.ts +3 -8
- package/package.json +1 -1
- package/test/test.model.js +1 -5
- package/test1.js +12 -9
package/orm/query/parade.d.ts
CHANGED
|
@@ -112,7 +112,7 @@ export type ParadeSpecialQueryObject<T extends BaseEntity = BaseEntity> = {
|
|
|
112
112
|
empty?: null;
|
|
113
113
|
moreLikeThis?: {
|
|
114
114
|
keyValue?: any;
|
|
115
|
-
document?: Record<TargetColumnPath<T
|
|
115
|
+
document?: Record<TargetColumnPath<T>>;
|
|
116
116
|
fields?: readonly TargetColumnPath<T>[];
|
|
117
117
|
minDocFrequency?: number;
|
|
118
118
|
maxDocFrequency?: number;
|
package/orm/schemas/index.d.ts
CHANGED
package/orm/schemas/index.js
CHANGED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { NumberSchema, type NumberSchemaOptions, type SchemaDecoratorOptions, type SchemaPropertyDecorator } from '../../schema/index.js';
|
|
2
|
+
import type { TypedOmit } from '../../types/types.js';
|
|
3
|
+
export type NumericSchemaOptions = NumberSchemaOptions & {
|
|
4
|
+
precision?: number;
|
|
5
|
+
scale?: number;
|
|
6
|
+
mode?: 'string' | 'number' | 'bigint';
|
|
7
|
+
};
|
|
8
|
+
export declare class NumericSchema extends NumberSchema {
|
|
9
|
+
readonly name = "Numeric";
|
|
10
|
+
readonly precision: number | null;
|
|
11
|
+
readonly scale: number | null;
|
|
12
|
+
readonly mode: 'string' | 'number' | 'bigint' | null;
|
|
13
|
+
constructor(options?: NumericSchemaOptions);
|
|
14
|
+
}
|
|
15
|
+
export declare function numeric(precision: number, scale: number, options?: TypedOmit<NumericSchemaOptions, 'precision' | 'scale'>): NumericSchema;
|
|
16
|
+
export declare function numeric(options?: NumericSchemaOptions): NumericSchema;
|
|
17
|
+
export declare function NumericProperty(options?: NumericSchemaOptions & SchemaDecoratorOptions): SchemaPropertyDecorator;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { NumberSchema, Property } from '../../schema/index.js';
|
|
2
|
+
import { isObject } from '../../utils/type-guards.js';
|
|
3
|
+
export class NumericSchema extends NumberSchema {
|
|
4
|
+
name = 'Numeric';
|
|
5
|
+
precision;
|
|
6
|
+
scale;
|
|
7
|
+
mode;
|
|
8
|
+
constructor(options) {
|
|
9
|
+
super(options);
|
|
10
|
+
this.precision = options?.precision ?? null;
|
|
11
|
+
this.scale = options?.scale ?? null;
|
|
12
|
+
this.mode = options?.mode ?? null;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
export function numeric(precisionOrOptions, scale, options) {
|
|
16
|
+
if (isObject(precisionOrOptions)) {
|
|
17
|
+
return new NumericSchema(precisionOrOptions);
|
|
18
|
+
}
|
|
19
|
+
return new NumericSchema({ precision: precisionOrOptions, scale, ...options });
|
|
20
|
+
}
|
|
21
|
+
export function NumericProperty(options) {
|
|
22
|
+
return Property(numeric(options), options);
|
|
23
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { sql, SQL } from 'drizzle-orm';
|
|
2
2
|
import { toCamelCase, toSnakeCase } from 'drizzle-orm/casing';
|
|
3
|
-
import { boolean, check, doublePrecision, foreignKey, index, integer, jsonb, pgSchema, primaryKey, text, unique, uniqueIndex, uuid } from 'drizzle-orm/pg-core';
|
|
3
|
+
import { boolean, check, doublePrecision, foreignKey, index, integer, jsonb, numeric, pgSchema, primaryKey, text, unique, uniqueIndex, uuid } from 'drizzle-orm/pg-core';
|
|
4
4
|
import { match, P } from 'ts-pattern';
|
|
5
5
|
import { MultiKeyMap } from '../../../data-structures/multi-key-map.js';
|
|
6
6
|
import { tryGetEnumName } from '../../../enumeration/enumeration.js';
|
|
@@ -17,11 +17,7 @@ import { fromEntries, mapObjectKeysToSnakeCase, objectEntries } from '../../../u
|
|
|
17
17
|
import { assertDefined, assertDefinedPass, isArray, isDefined, isNotNull, isNotNullOrUndefined, isNull, isString, isUndefined } from '../../../utils/type-guards.js';
|
|
18
18
|
import { resolveValueOrProvider } from '../../../utils/value-or-provider.js';
|
|
19
19
|
import { bytea, numericDate, timestamp, tsvector } from '../../data-types/index.js';
|
|
20
|
-
import { JsonSchema } from '../../schemas/
|
|
21
|
-
import { NumericDateSchema } from '../../schemas/numeric-date.js';
|
|
22
|
-
import { TimestampSchema } from '../../schemas/timestamp.js';
|
|
23
|
-
import { TsVectorSchema } from '../../schemas/tsvector.js';
|
|
24
|
-
import { UuidSchema } from '../../schemas/uuid.js';
|
|
20
|
+
import { JsonSchema, NumericDateSchema, NumericSchema, TimestampSchema, TsVectorSchema, UuidSchema } from '../../schemas/index.js';
|
|
25
21
|
import { decryptBytes, encryptBytes } from '../encryption.js';
|
|
26
22
|
import { convertQuery, resolveTargetColumn, resolveTargetColumns } from '../query-converter.js';
|
|
27
23
|
const getDbSchema = memoizeSingle(pgSchema);
|
|
@@ -315,6 +311,7 @@ function getPostgresBaseColumn(columnName, dbSchema, schema, reflectionData, con
|
|
|
315
311
|
})
|
|
316
312
|
.with(P.instanceOf(TimestampSchema), () => timestamp(columnName))
|
|
317
313
|
.with(P.instanceOf(NumericDateSchema), () => numericDate(columnName))
|
|
314
|
+
.with(P.instanceOf(NumericSchema), (n) => numeric(columnName, { precision: n.precision ?? undefined, scale: n.scale ?? undefined, mode: n.mode ?? 'number' }))
|
|
318
315
|
.with(P.instanceOf(NumberSchema), (s) => (s.integer ? integer(columnName) : doublePrecision(columnName)))
|
|
319
316
|
.with(P.instanceOf(StringSchema), () => text(columnName))
|
|
320
317
|
.with(P.instanceOf(BooleanSchema), () => boolean(columnName))
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { and, Column, eq, gt, gte, inArray, isNotNull, isNull, isSQLWrapper, lt, lte, ne, not, notInArray, or, SQL, sql } from 'drizzle-orm';
|
|
2
|
-
import { PgColumn } from 'drizzle-orm/pg-core';
|
|
3
2
|
import { match } from 'ts-pattern';
|
|
4
3
|
import { NotSupportedError } from '../../errors/not-supported.error.js';
|
|
5
4
|
import { hasOwnProperty, mapObject, mapObjectKeysToSnakeCase, objectEntries } from '../../utils/object/object.js';
|
|
@@ -371,7 +370,7 @@ function convertParadeSpecialQuery(query, table, columnDefinitionsMap) {
|
|
|
371
370
|
return jsonbBuildObject({
|
|
372
371
|
...properties,
|
|
373
372
|
fields: fieldsArraySql,
|
|
374
|
-
document: documentJson
|
|
373
|
+
document: documentJson,
|
|
375
374
|
});
|
|
376
375
|
})
|
|
377
376
|
.exhaustive();
|
package/orm/types.d.ts
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* like primary keys and default values. It also re-exports common decorators and schemas.
|
|
6
6
|
*/
|
|
7
7
|
import type { $Type, HasDefault as DrizzleHasDefault, IsPrimaryKey as DrizzleIsPrimaryKey } from 'drizzle-orm';
|
|
8
|
-
import type { boolean, doublePrecision, integer, jsonb, PgColumnBuilder, PgColumnBuilderBase, PgEnumColumnBuilderInitial, text, uuid } from 'drizzle-orm/pg-core';
|
|
8
|
+
import type { boolean, doublePrecision, integer, jsonb, numeric, PgColumnBuilder, PgColumnBuilderBase, PgEnumColumnBuilderInitial, text, uuid } from 'drizzle-orm/pg-core';
|
|
9
9
|
import type { AbstractConstructor, EnumerationObject, EnumerationValue, GetTagMetadata, HasTag, ObjectLiteral, Tagged, UnionToTuple, UnwrapTagged } from '../types/index.js';
|
|
10
10
|
import type { bytea, numericDate, timestamp } from './data-types/index.js';
|
|
11
11
|
/** Tag identifier for column type information. */
|
|
@@ -64,21 +64,16 @@ export type Json<T> = Tagged<T, ColumnTypeTag, $Type<ReturnType<typeof jsonb>, T
|
|
|
64
64
|
* @template T - The enumeration object type.
|
|
65
65
|
*/
|
|
66
66
|
export type Enum<T extends string | number> = Tagged<T, ColumnTypeTag, EnumColumn<T>>;
|
|
67
|
-
/** Tagged type representing a `text` column. */
|
|
68
67
|
export type Text<T extends string = string> = Tagged<string, ColumnTypeTag, ReturnType<typeof text<string, TextTuple<T>>>>;
|
|
69
|
-
/** Tagged type representing a `uuid` column. Stores the UUID as a string. */
|
|
70
68
|
export type Uuid = Tagged<string, ColumnTypeTag, ReturnType<typeof uuid>>;
|
|
71
|
-
/** Tagged type representing an `integer` column. */
|
|
72
69
|
export type Integer = Tagged<number, ColumnTypeTag, ReturnType<typeof integer>>;
|
|
73
|
-
/** Tagged type representing a `double precision` column. */
|
|
74
70
|
export type DoublePrecision = Tagged<number, ColumnTypeTag, ReturnType<typeof doublePrecision>>;
|
|
75
|
-
/** Tagged type representing a `boolean` column. */
|
|
76
71
|
export type Boolean = Tagged<number, ColumnTypeTag, ReturnType<typeof boolean>>;
|
|
77
|
-
|
|
72
|
+
export type Numeric<T extends number | string | bigint = number> = Tagged<T, ColumnTypeTag, ReturnType<typeof numeric<T extends number ? 'number' : T extends string ? 'string' : 'bigint'>>>;
|
|
73
|
+
/** Tagged type representing a custom `numericDate` column (stores date as number - days since epoch). */
|
|
78
74
|
export type NumericDate = Tagged<number, ColumnTypeTag, ReturnType<typeof numericDate>>;
|
|
79
75
|
/** Tagged type representing a `timestamp` column (stores timestamp as number - milliseconds since epoch). */
|
|
80
76
|
export type Timestamp = Tagged<number, ColumnTypeTag, ReturnType<typeof timestamp>>;
|
|
81
|
-
/** Tagged type representing a `bytea` (byte array) column. */
|
|
82
77
|
export type Bytea = Tagged<Uint8Array, ColumnTypeTag, ReturnType<typeof bytea>>;
|
|
83
78
|
/**
|
|
84
79
|
* Tagged type representing an encrypted column.
|
package/package.json
CHANGED
package/test/test.model.js
CHANGED
|
@@ -38,7 +38,7 @@ __decorate([
|
|
|
38
38
|
Test = __decorate([
|
|
39
39
|
ParadeExpressionIndex('foo', () => sql `'foo'`),
|
|
40
40
|
ParadeCompoundIndex('search_text', (table) => [table.title, 'content', 'tags']),
|
|
41
|
-
ParadeIndex({ columns: ['language']
|
|
41
|
+
ParadeIndex({ columns: ['language'] })
|
|
42
42
|
], Test);
|
|
43
43
|
export { Test };
|
|
44
44
|
export const testData = [
|
|
@@ -132,7 +132,6 @@ export const testData = [
|
|
|
132
132
|
tags: ['testing', 'database', 'automation', 'best practices'],
|
|
133
133
|
language: 'english',
|
|
134
134
|
},
|
|
135
|
-
// --- Cooking Posts (16-25) ---
|
|
136
135
|
{
|
|
137
136
|
title: 'The Perfect Weeknight Pasta Recipe',
|
|
138
137
|
content: 'A quick and delicious pasta recipe that you can make in under 30 minutes. Perfect for a busy weeknight. This recipe uses fresh tomatoes and basil.',
|
|
@@ -193,7 +192,6 @@ export const testData = [
|
|
|
193
192
|
tags: ['smoothie', 'recipe', 'breakfast', 'healthy'],
|
|
194
193
|
language: 'english',
|
|
195
194
|
},
|
|
196
|
-
// --- Travel Posts (26-35) ---
|
|
197
195
|
{
|
|
198
196
|
title: 'A Backpacker\'s Guide to Southeast Asia',
|
|
199
197
|
content: 'Explore the wonders of Southeast Asia on a budget. This guide covers top destinations, packing tips, and how to travel safely and affordably.',
|
|
@@ -254,7 +252,6 @@ export const testData = [
|
|
|
254
252
|
tags: ['solo travel', 'travel tips', 'adventure'],
|
|
255
253
|
language: 'english',
|
|
256
254
|
},
|
|
257
|
-
// --- Science & Lifestyle Posts (36-45) ---
|
|
258
255
|
{
|
|
259
256
|
title: 'The Mysteries of Black Holes Explained',
|
|
260
257
|
content: 'What are black holes and how do they form? This article provides a simple explanation of one of the universe\'s most fascinating phenomena.',
|
|
@@ -315,7 +312,6 @@ export const testData = [
|
|
|
315
312
|
tags: ['fitness', 'health', 'wellness', 'exercise'],
|
|
316
313
|
language: 'english',
|
|
317
314
|
},
|
|
318
|
-
// --- Multi-Language Posts (46-50) ---
|
|
319
315
|
{
|
|
320
316
|
title: 'Einführung in die Volltextsuche mit PostgreSQL',
|
|
321
317
|
content: 'Dieser Leitfaden erklärt die Grundlagen der Volltextsuche in einer PostgreSQL Datenbank. Wir behandeln Konfiguration und Abfragen.',
|
package/test1.js
CHANGED
|
@@ -10,6 +10,7 @@ import { configureOrm, injectRepository } from './orm/server/index.js';
|
|
|
10
10
|
import { configurePostgresQueue, migratePostgresQueueSchema } from './queue/postgres/index.js';
|
|
11
11
|
import { migrateTestSchema } from './test/module.js';
|
|
12
12
|
import { Test, testData } from './test/test.model.js';
|
|
13
|
+
import { timedBenchmarkAsync } from './utils/benchmark.js';
|
|
13
14
|
import * as configParser from './utils/config-parser.js';
|
|
14
15
|
const config = {
|
|
15
16
|
database: {
|
|
@@ -53,18 +54,20 @@ async function main(_cancellationSignal) {
|
|
|
53
54
|
if (await repository.count() == 0) {
|
|
54
55
|
await repository.insertMany(testData);
|
|
55
56
|
}
|
|
56
|
-
|
|
57
|
-
|
|
57
|
+
let result;
|
|
58
|
+
const benchmarkResult = await timedBenchmarkAsync(1000, async () => {
|
|
59
|
+
result = await repository.search({
|
|
60
|
+
query: {
|
|
61
|
+
$parade: { fields: ['content'], query: 'vitamins' },
|
|
62
|
+
},
|
|
63
|
+
highlight: { source: 'content', includePositions: true },
|
|
64
|
+
score: true,
|
|
65
|
+
});
|
|
58
66
|
});
|
|
59
|
-
const
|
|
60
|
-
query: {
|
|
61
|
-
$parade: { fields: ['content'], query: 'vibrant city' },
|
|
62
|
-
},
|
|
63
|
-
highlight: { source: 'content', includePositions: true },
|
|
64
|
-
});
|
|
65
|
-
for (const item of result2) {
|
|
67
|
+
for (const item of result) {
|
|
66
68
|
console.log(item);
|
|
67
69
|
}
|
|
70
|
+
console.log('Benchmark result:', benchmarkResult);
|
|
68
71
|
}
|
|
69
72
|
Application.run('Test', [
|
|
70
73
|
provideInitializer(bootstrap),
|