@tstdl/base 0.92.76 → 0.92.78
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.
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { toCamelCase, toSnakeCase } from 'drizzle-orm/casing';
|
|
2
|
-
import { boolean, doublePrecision, index, integer, jsonb, pgSchema, text, unique, uniqueIndex, uuid } from 'drizzle-orm/pg-core';
|
|
2
|
+
import { boolean, doublePrecision, index, integer, jsonb, pgSchema, primaryKey, text, unique, uniqueIndex, uuid } from 'drizzle-orm/pg-core';
|
|
3
3
|
import { MultiKeyMap } from '../../../data-structures/multi-key-map.js';
|
|
4
4
|
import { tryGetEnumName } from '../../../enumeration/enumeration.js';
|
|
5
5
|
import { NotSupportedError } from '../../../errors/not-supported.error.js';
|
|
@@ -54,8 +54,13 @@ export function _getDrizzleTableFromType(type, schemaName) {
|
|
|
54
54
|
const indexFn = (data.options?.unique == true) ? uniqueIndex : index;
|
|
55
55
|
return indexFn(data.name).using(data.options?.using ?? 'btree', ...columns);
|
|
56
56
|
}
|
|
57
|
-
const
|
|
57
|
+
const primaryKeyColumns = columnDefinitions.filter((columnDefinition) => columnDefinition.reflectionData?.primaryKey == true);
|
|
58
|
+
const skipPrimaryKey = primaryKeyColumns.length > 1;
|
|
59
|
+
const columnEntries = columnDefinitions.map((entry) => [entry.name, entry.buildType({ skipPrimaryKey })]);
|
|
58
60
|
const drizzleSchema = dbSchema.table(tableName, fromEntries(columnEntries), (table) => [
|
|
61
|
+
...((primaryKeyColumns.length > 1)
|
|
62
|
+
? [primaryKey({ columns: primaryKeyColumns.map((columnDefinition) => getColumn(table, columnDefinition.name)) })]
|
|
63
|
+
: []),
|
|
59
64
|
...(columnDefinitions.map((columnDefinition) => {
|
|
60
65
|
const indexData = columnDefinition.reflectionData?.index;
|
|
61
66
|
if (isUndefined(indexData)) {
|
|
@@ -105,21 +110,19 @@ function getPostgresColumnEntries(type, tableName, dbSchema, path = new JsonPath
|
|
|
105
110
|
}
|
|
106
111
|
: (value) => value;
|
|
107
112
|
const prefixedColumnName = [prefix, columnName].join('');
|
|
108
|
-
return [
|
|
109
|
-
{
|
|
113
|
+
return [{
|
|
110
114
|
name: toCamelCase(prefixedColumnName),
|
|
111
115
|
objectPath,
|
|
112
|
-
type: getPostgresColumn(toSnakeCase(prefixedColumnName), dbSchema, schema, columnReflectionData ?? {}, { type, property }),
|
|
113
116
|
reflectionData: columnReflectionData,
|
|
117
|
+
buildType: (options) => getPostgresColumn(toSnakeCase(prefixedColumnName), dbSchema, schema, columnReflectionData ?? {}, options, { type, property }),
|
|
114
118
|
dereferenceObjectPath: compileDereferencer(objectPath, { optional: true }),
|
|
115
119
|
toDatabase,
|
|
116
120
|
fromDatabase
|
|
117
|
-
}
|
|
118
|
-
];
|
|
121
|
+
}];
|
|
119
122
|
});
|
|
120
123
|
return entries;
|
|
121
124
|
}
|
|
122
|
-
function getPostgresColumn(columnName, dbSchema, propertySchema, reflectionData, context) {
|
|
125
|
+
function getPostgresColumn(columnName, dbSchema, propertySchema, reflectionData, options, context) {
|
|
123
126
|
let nullable = false;
|
|
124
127
|
let array = false;
|
|
125
128
|
let baseSchema = propertySchema;
|
|
@@ -146,7 +149,7 @@ function getPostgresColumn(columnName, dbSchema, propertySchema, reflectionData,
|
|
|
146
149
|
if (isDefined(reflectionData.unique)) {
|
|
147
150
|
column = column.unique(reflectionData.unique.name, isString(reflectionData.unique.options?.nulls) ? { nulls: reflectionData.unique.options.nulls } : undefined);
|
|
148
151
|
}
|
|
149
|
-
if (reflectionData.primaryKey == true) {
|
|
152
|
+
if ((reflectionData.primaryKey == true) && (options.skipPrimaryKey != true)) {
|
|
150
153
|
column = column.primaryKey();
|
|
151
154
|
}
|
|
152
155
|
if (isDefined(reflectionData.references)) {
|
|
@@ -60,6 +60,12 @@ export declare class EntityRepository<T extends Entity = Entity> implements Reso
|
|
|
60
60
|
has(id: string): Promise<boolean>;
|
|
61
61
|
hasByQuery(query: Query<T>): Promise<boolean>;
|
|
62
62
|
hasAll(ids: string[]): Promise<boolean>;
|
|
63
|
+
/**
|
|
64
|
+
* Tries to insert using ON CONFLICT DO NOTHING
|
|
65
|
+
* @param entity entity to insert
|
|
66
|
+
* @returns entity if inserted, undefined on conflict
|
|
67
|
+
*/
|
|
68
|
+
tryInsert(entity: NewEntity<T>): Promise<T | undefined>;
|
|
63
69
|
insert(entity: NewEntity<T>): Promise<T>;
|
|
64
70
|
insertMany(entities: NewEntity<T>[]): Promise<T[]>;
|
|
65
71
|
upsert(target: OneOrMany<Paths<UntaggedDeep<T>>>, entity: NewEntity<T>, update?: EntityUpdate<T>): Promise<T>;
|
package/orm/server/repository.js
CHANGED
|
@@ -13,7 +13,8 @@ import { PgTransaction as DrizzlePgTransaction } from 'drizzle-orm/pg-core';
|
|
|
13
13
|
import { createContextProvider } from '../../context/context.js';
|
|
14
14
|
import { NotFoundError } from '../../errors/not-found.error.js';
|
|
15
15
|
import { Singleton } from '../../injector/decorators.js';
|
|
16
|
-
import {
|
|
16
|
+
import { Injector } from '../../injector/index.js';
|
|
17
|
+
import { inject, injectArgument, runInInjectionContext } from '../../injector/inject.js';
|
|
17
18
|
import { resolveArgumentType } from '../../injector/interfaces.js';
|
|
18
19
|
import { Schema } from '../../schema/schema.js';
|
|
19
20
|
import { toArray } from '../../utils/array/array.js';
|
|
@@ -35,6 +36,7 @@ const entityTypeToken = Symbol('EntityType');
|
|
|
35
36
|
const TRANSACTION_TIMESTAMP = sql `transaction_timestamp()`;
|
|
36
37
|
const { getCurrentEntityRepositoryContext, runInEntityRepositoryContext, isInEntityRepositoryContext } = createContextProvider('EntityRepository');
|
|
37
38
|
let EntityRepository = class EntityRepository {
|
|
39
|
+
#injector = inject(Injector);
|
|
38
40
|
#repositoryConstructor;
|
|
39
41
|
#withTransactionCache = new WeakMap();
|
|
40
42
|
#encryptionSecret = isInEntityRepositoryContext() ? getCurrentEntityRepositoryContext()?.encryptionSecret : inject(ENCRYPTION_SECRET, undefined, { optional: true });
|
|
@@ -75,7 +77,7 @@ let EntityRepository = class EntityRepository {
|
|
|
75
77
|
encryptionSecret: this.#encryptionSecret,
|
|
76
78
|
transformContext: this.#transformContext
|
|
77
79
|
};
|
|
78
|
-
const repositoryWithTransaction = runInEntityRepositoryContext(context, () => new this.#repositoryConstructor());
|
|
80
|
+
const repositoryWithTransaction = runInInjectionContext(this.#injector, () => runInEntityRepositoryContext(context, () => new this.#repositoryConstructor()));
|
|
79
81
|
this.#withTransactionCache.set(transaction, repositoryWithTransaction);
|
|
80
82
|
return repositoryWithTransaction;
|
|
81
83
|
}
|
|
@@ -185,6 +187,24 @@ let EntityRepository = class EntityRepository {
|
|
|
185
187
|
.from(this.table);
|
|
186
188
|
return assertDefinedPass(result[0]).contains;
|
|
187
189
|
}
|
|
190
|
+
/**
|
|
191
|
+
* Tries to insert using ON CONFLICT DO NOTHING
|
|
192
|
+
* @param entity entity to insert
|
|
193
|
+
* @returns entity if inserted, undefined on conflict
|
|
194
|
+
*/
|
|
195
|
+
async tryInsert(entity) {
|
|
196
|
+
const transformContext = await this.getTransformContext();
|
|
197
|
+
const columns = await this.mapToInsertColumns(entity, transformContext);
|
|
198
|
+
const [row] = await this.session
|
|
199
|
+
.insert(this.table)
|
|
200
|
+
.values(columns)
|
|
201
|
+
.onConflictDoNothing()
|
|
202
|
+
.returning();
|
|
203
|
+
if (isUndefined(row)) {
|
|
204
|
+
return undefined;
|
|
205
|
+
}
|
|
206
|
+
return this.mapToEntity(row, transformContext);
|
|
207
|
+
}
|
|
188
208
|
async insert(entity) {
|
|
189
209
|
const transformContext = await this.getTransformContext();
|
|
190
210
|
const columns = await this.mapToInsertColumns(entity, transformContext);
|
package/orm/server/types.d.ts
CHANGED
|
@@ -8,11 +8,14 @@ import type { Tagged } from '../../types/index.js';
|
|
|
8
8
|
import type { OrmColumnReflectionData } from '../decorators.js';
|
|
9
9
|
import type { EntityType } from '../entity.js';
|
|
10
10
|
import type { ColumnBuilder, EmbeddedConfigTag } from '../types.js';
|
|
11
|
+
export type BuildTypeOptions = {
|
|
12
|
+
skipPrimaryKey?: boolean;
|
|
13
|
+
};
|
|
11
14
|
export type ColumnDefinition = {
|
|
12
15
|
name: string;
|
|
13
16
|
objectPath: JsonPath;
|
|
14
|
-
type: PgColumnBuilder<any, any, any, any>;
|
|
15
17
|
reflectionData: OrmColumnReflectionData | undefined;
|
|
18
|
+
buildType: (options: BuildTypeOptions) => PgColumnBuilder<any, any, any, any>;
|
|
16
19
|
dereferenceObjectPath: (obj: Record) => any;
|
|
17
20
|
toDatabase: (value: unknown, context: TransformContext) => any;
|
|
18
21
|
fromDatabase: (value: unknown, context: TransformContext) => any;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tstdl/base",
|
|
3
|
-
"version": "0.92.
|
|
3
|
+
"version": "0.92.78",
|
|
4
4
|
"author": "Patrick Hein",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
@@ -148,14 +148,14 @@
|
|
|
148
148
|
"@typescript-eslint/eslint-plugin": "8.24",
|
|
149
149
|
"concurrently": "9.1",
|
|
150
150
|
"drizzle-kit": "0.30",
|
|
151
|
-
"eslint": "9.
|
|
151
|
+
"eslint": "9.21",
|
|
152
152
|
"globals": "16.0",
|
|
153
153
|
"tsc-alias": "1.8",
|
|
154
154
|
"typescript": "5.7"
|
|
155
155
|
},
|
|
156
156
|
"peerDependencies": {
|
|
157
157
|
"@elastic/elasticsearch": "^8.17",
|
|
158
|
-
"@google/generative-ai": "^0.
|
|
158
|
+
"@google/generative-ai": "^0.22",
|
|
159
159
|
"@tstdl/angular": "^0.92",
|
|
160
160
|
"@zxcvbn-ts/core": "^3.0",
|
|
161
161
|
"@zxcvbn-ts/language-common": "^3.0",
|