@tstdl/base 0.92.76 → 0.92.77

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 columnEntries = columnDefinitions.map((entry) => [entry.name, entry.type]);
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>;
@@ -185,6 +185,24 @@ let EntityRepository = class EntityRepository {
185
185
  .from(this.table);
186
186
  return assertDefinedPass(result[0]).contains;
187
187
  }
188
+ /**
189
+ * Tries to insert using ON CONFLICT DO NOTHING
190
+ * @param entity entity to insert
191
+ * @returns entity if inserted, undefined on conflict
192
+ */
193
+ async tryInsert(entity) {
194
+ const transformContext = await this.getTransformContext();
195
+ const columns = await this.mapToInsertColumns(entity, transformContext);
196
+ const [row] = await this.session
197
+ .insert(this.table)
198
+ .values(columns)
199
+ .onConflictDoNothing()
200
+ .returning();
201
+ if (isUndefined(row)) {
202
+ return undefined;
203
+ }
204
+ return this.mapToEntity(row, transformContext);
205
+ }
188
206
  async insert(entity) {
189
207
  const transformContext = await this.getTransformContext();
190
208
  const columns = await this.mapToInsertColumns(entity, transformContext);
@@ -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.76",
3
+ "version": "0.92.77",
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.20",
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.21",
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",