@tstdl/base 0.91.50 → 0.91.52

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.
Files changed (164) hide show
  1. package/ai/data-extracting.d.ts +1 -0
  2. package/ai/data-extracting.js +62 -0
  3. package/authentication/server/authentication.api-controller.js +4 -4
  4. package/cancellation/token.d.ts +1 -2
  5. package/cancellation/token.js +1 -1
  6. package/core.d.ts +1 -1
  7. package/core.js +1 -1
  8. package/document-management/api/document-management.api.d.ts +753 -0
  9. package/document-management/api/document-management.api.js +222 -0
  10. package/document-management/api/index.d.ts +1 -0
  11. package/document-management/api/index.js +1 -0
  12. package/document-management/drizzle/0000_wakeful_firebrand.sql +228 -0
  13. package/document-management/drizzle/meta/0000_snapshot.json +1538 -0
  14. package/document-management/drizzle/meta/_journal.json +13 -0
  15. package/document-management/drizzle.config.d.ts +2 -0
  16. package/document-management/drizzle.config.js +11 -0
  17. package/document-management/index.d.ts +5 -0
  18. package/document-management/index.js +5 -0
  19. package/document-management/localizations/english.d.ts +2 -0
  20. package/document-management/localizations/english.js +9 -0
  21. package/document-management/localizations/german.d.ts +2 -0
  22. package/document-management/localizations/german.js +9 -0
  23. package/document-management/localizations/index.d.ts +5 -0
  24. package/document-management/localizations/index.js +9 -0
  25. package/document-management/localizations/localization.d.ts +9 -0
  26. package/document-management/localizations/localization.js +2 -0
  27. package/document-management/models/document-category.model.d.ts +4 -0
  28. package/document-management/models/document-category.model.js +18 -0
  29. package/document-management/models/document-collection-document.model.d.ts +7 -0
  30. package/document-management/models/document-collection-document.model.js +33 -0
  31. package/document-management/models/document-collection.model.d.ts +3 -0
  32. package/document-management/models/document-collection.model.js +14 -0
  33. package/document-management/models/document-file.model.d.ts +7 -0
  34. package/document-management/models/document-file.model.js +33 -0
  35. package/document-management/models/document-property-value.model.d.ts +21 -0
  36. package/document-management/models/document-property-value.model.js +58 -0
  37. package/document-management/models/document-property.model.d.ts +11 -0
  38. package/document-management/models/document-property.model.js +30 -0
  39. package/document-management/models/document-request-collection.model.d.ts +6 -0
  40. package/document-management/models/document-request-collection.model.js +28 -0
  41. package/document-management/models/document-request-file.model.d.ts +11 -0
  42. package/document-management/models/document-request-file.model.js +56 -0
  43. package/document-management/models/document-request-template.d.ts +10 -0
  44. package/document-management/models/document-request-template.js +39 -0
  45. package/document-management/models/document-request.model.d.ts +9 -0
  46. package/document-management/models/document-request.model.js +37 -0
  47. package/document-management/models/document-requests-template.d.ts +5 -0
  48. package/document-management/models/document-requests-template.js +23 -0
  49. package/document-management/models/document-type-property.model.d.ts +6 -0
  50. package/document-management/models/document-type-property.model.js +28 -0
  51. package/document-management/models/document-type.model.d.ts +7 -0
  52. package/document-management/models/document-type.model.js +32 -0
  53. package/document-management/models/document.model.d.ts +9 -0
  54. package/document-management/models/document.model.js +44 -0
  55. package/document-management/models/index.d.ts +15 -0
  56. package/document-management/models/index.js +15 -0
  57. package/document-management/models/schemas.d.ts +33 -0
  58. package/document-management/models/schemas.js +34 -0
  59. package/document-management/models/service-models/categories-and-types.view-model.d.ts +6 -0
  60. package/document-management/models/service-models/categories-and-types.view-model.js +24 -0
  61. package/document-management/models/service-models/document-folders.view-model.d.ts +22 -0
  62. package/document-management/models/service-models/document-folders.view-model.js +56 -0
  63. package/document-management/models/service-models/document-requests-template.view-model.d.ts +8 -0
  64. package/document-management/models/service-models/document-requests-template.view-model.js +26 -0
  65. package/document-management/models/service-models/document.service-model.d.ts +262 -0
  66. package/document-management/models/service-models/document.service-model.js +50 -0
  67. package/document-management/models/service-models/document.view-model.d.ts +33 -0
  68. package/document-management/models/service-models/document.view-model.js +99 -0
  69. package/document-management/models/service-models/index.d.ts +8 -0
  70. package/document-management/models/service-models/index.js +8 -0
  71. package/document-management/models/service-models/normalized-document-collection-view.model.d.ts +73 -0
  72. package/document-management/models/service-models/normalized-document-collection-view.model.js +110 -0
  73. package/document-management/models/service-models/normalized-requests-template-data.model.d.ts +16 -0
  74. package/document-management/models/service-models/normalized-requests-template-data.model.js +13 -0
  75. package/document-management/models/service-models/stats.view-model.d.ts +6 -0
  76. package/document-management/models/service-models/stats.view-model.js +32 -0
  77. package/document-management/module.d.ts +11 -0
  78. package/document-management/module.js +27 -0
  79. package/document-management/services/document-management.service.d.ts +65 -0
  80. package/document-management/services/document-management.service.js +376 -0
  81. package/document-management/services/index.d.ts +1 -0
  82. package/document-management/services/index.js +1 -0
  83. package/examples/document-management/main.d.ts +1 -0
  84. package/examples/document-management/main.js +30 -0
  85. package/examples/orm/drizzle.config.js +2 -1
  86. package/examples/orm/schemas.d.ts +1 -1
  87. package/examples/orm/user.model.d.ts +1 -2
  88. package/examples/orm/user.model.js +0 -1
  89. package/http/server/node/node-http-server.js +5 -5
  90. package/injector/injector.d.ts +4 -1
  91. package/injector/injector.js +4 -1
  92. package/injector/interfaces.d.ts +3 -3
  93. package/json-path/json-path.d.ts +2 -0
  94. package/json-path/json-path.js +7 -0
  95. package/message-bus/message-bus.d.ts +4 -6
  96. package/orm/database-schema.d.ts +3 -0
  97. package/orm/database-schema.js +6 -2
  98. package/orm/database.d.ts +6 -0
  99. package/orm/database.js +14 -0
  100. package/orm/decorators.d.ts +25 -2
  101. package/orm/decorators.js +15 -0
  102. package/orm/drizzle/index.d.ts +1 -0
  103. package/orm/drizzle/index.js +1 -0
  104. package/orm/drizzle/schema-converter.d.ts +37 -8
  105. package/orm/drizzle/schema-converter.js +121 -40
  106. package/orm/entity.d.ts +15 -12
  107. package/orm/entity.js +24 -11
  108. package/orm/index.d.ts +3 -2
  109. package/orm/index.js +3 -2
  110. package/orm/module.d.ts +6 -0
  111. package/orm/module.js +15 -0
  112. package/orm/query-converter.d.ts +5 -0
  113. package/orm/query-converter.js +114 -0
  114. package/orm/query.d.ts +15 -13
  115. package/orm/repository.d.ts +90 -31
  116. package/orm/repository.js +357 -55
  117. package/orm/schemas/index.d.ts +3 -0
  118. package/orm/schemas/index.js +3 -0
  119. package/orm/schemas/json.d.ts +9 -0
  120. package/orm/schemas/json.js +19 -0
  121. package/orm/schemas/numeric-date.d.ts +8 -0
  122. package/orm/schemas/numeric-date.js +13 -0
  123. package/orm/schemas/timestamp.d.ts +10 -0
  124. package/orm/schemas/timestamp.js +20 -0
  125. package/orm/transaction.d.ts +29 -0
  126. package/orm/transaction.js +73 -0
  127. package/orm/types.d.ts +15 -8
  128. package/orm/types.js +3 -2
  129. package/package.json +23 -12
  130. package/{rxjs → rxjs-utils}/reject-error.d.ts +1 -1
  131. package/{rxjs → rxjs-utils}/retry-backoff.d.ts +2 -2
  132. package/{rxjs → rxjs-utils}/slow-array.d.ts +7 -7
  133. package/{rxjs → rxjs-utils}/slow-array.js +2 -2
  134. package/{rxjs → rxjs-utils}/start-with-provider.d.ts +1 -1
  135. package/{rxjs → rxjs-utils}/teardown.d.ts +1 -1
  136. package/{rxjs → rxjs-utils}/untrack.d.ts +1 -1
  137. package/schema/decorators/types.d.ts +2 -2
  138. package/schema/schemas/number.d.ts +1 -1
  139. package/signals/pipe.d.ts +1 -1
  140. package/signals/pipe.js +1 -2
  141. package/sse/server-sent-events.d.ts +54 -0
  142. package/sse/server-sent-events.js +54 -0
  143. package/types.d.ts +5 -1
  144. package/utils/comparison.d.ts +2 -1
  145. package/utils/comparison.js +4 -3
  146. package/utils/compression.d.ts +4 -4
  147. package/utils/compression.js +35 -43
  148. package/utils/object/dereference.d.ts +6 -4
  149. package/utils/object/dereference.js +20 -8
  150. package/utils/object/object.d.ts +2 -0
  151. package/utils/object/object.js +20 -0
  152. /package/{rxjs → rxjs-utils}/cast.d.ts +0 -0
  153. /package/{rxjs → rxjs-utils}/cast.js +0 -0
  154. /package/{rxjs → rxjs-utils}/index.d.ts +0 -0
  155. /package/{rxjs → rxjs-utils}/index.js +0 -0
  156. /package/{rxjs → rxjs-utils}/noop.d.ts +0 -0
  157. /package/{rxjs → rxjs-utils}/noop.js +0 -0
  158. /package/{rxjs → rxjs-utils}/reject-error.js +0 -0
  159. /package/{rxjs → rxjs-utils}/retry-backoff.js +0 -0
  160. /package/{rxjs → rxjs-utils}/start-with-provider.js +0 -0
  161. /package/{rxjs → rxjs-utils}/teardown.js +0 -0
  162. /package/{rxjs → rxjs-utils}/timing.d.ts +0 -0
  163. /package/{rxjs → rxjs-utils}/timing.js +0 -0
  164. /package/{rxjs → rxjs-utils}/untrack.js +0 -0
@@ -0,0 +1,6 @@
1
+ import { NodePgDatabase } from 'drizzle-orm/node-postgres';
2
+ import { Resolvable, type resolveArgumentType } from '../injector/interfaces.js';
3
+ import { DatabaseArgument } from './module.js';
4
+ export declare class Database extends NodePgDatabase<any> implements Resolvable<DatabaseArgument> {
5
+ readonly [resolveArgumentType]?: DatabaseArgument;
6
+ }
@@ -0,0 +1,14 @@
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
7
+ import { NodePgDatabase } from 'drizzle-orm/node-postgres';
8
+ import { ReplaceClass } from '../injector/decorators.js';
9
+ let Database = class Database extends NodePgDatabase {
10
+ };
11
+ Database = __decorate([
12
+ ReplaceClass(NodePgDatabase)
13
+ ], Database);
14
+ export { Database };
@@ -1,27 +1,50 @@
1
+ import type { PgIndexMethod } from 'drizzle-orm/pg-core';
2
+ import type { AbstractConstructor, TypedOmit } from '../types.js';
3
+ import type { EntityType } from './entity.js';
1
4
  export type OrmTableReflectionData = {
2
5
  name?: string;
3
6
  unique?: UniqueReflectionData[];
7
+ index?: IndexReflectionData[];
4
8
  };
5
9
  export type OrmColumnReflectionData = {
6
10
  name?: string;
7
11
  primaryKey?: boolean;
8
12
  unique?: UniqueReflectionData;
13
+ index?: IndexReflectionData;
9
14
  uuid?: {
10
15
  defaultRandom?: boolean;
11
16
  };
17
+ embedded?: {
18
+ type: AbstractConstructor;
19
+ prefix?: string | null;
20
+ };
21
+ references?: () => EntityType;
12
22
  };
13
- type UniqueReflectionData = {
23
+ export type UniqueReflectionData = {
14
24
  name?: string;
15
25
  columns?: string[];
16
26
  options?: {
17
27
  nulls?: 'distinct' | 'not distinct';
18
28
  };
19
29
  };
30
+ export type IndexReflectionData = {
31
+ name?: string;
32
+ columns?: (string | [string, 'asc' | 'desc'])[];
33
+ order?: 'asc' | 'desc';
34
+ options?: {
35
+ using?: PgIndexMethod;
36
+ unique?: boolean;
37
+ nulls?: 'first' | 'last';
38
+ };
39
+ };
20
40
  export declare function createTableDecorator(data?: OrmTableReflectionData): ClassDecorator;
21
41
  export declare function createColumnDecorator(data?: OrmColumnReflectionData): PropertyDecorator;
22
42
  export declare function createTableAndColumnDecorator(data?: OrmColumnReflectionData): ClassDecorator & PropertyDecorator;
23
43
  export declare function Column(options: OrmColumnReflectionData): PropertyDecorator;
24
44
  export declare function PrimaryKey(): PropertyDecorator;
45
+ export declare function References(type: () => EntityType): PropertyDecorator;
46
+ export declare function Embedded(type: AbstractConstructor, options?: TypedOmit<NonNullable<OrmColumnReflectionData['embedded']>, 'type'>): PropertyDecorator;
25
47
  export declare function Unique(name?: string, options?: UniqueReflectionData['options']): PropertyDecorator;
26
48
  export declare function Unique(name: string | undefined, columns: [string, ...string[]], options?: UniqueReflectionData['options']): ClassDecorator;
27
- export {};
49
+ export declare function Index(name?: string, options?: IndexReflectionData['options']): PropertyDecorator;
50
+ export declare function Index(name: string | undefined, columns: [string, ...string[]], options?: IndexReflectionData['options']): ClassDecorator;
package/orm/decorators.js CHANGED
@@ -1,4 +1,5 @@
1
1
  import { createClassDecorator, createDecorator, createPropertyDecorator } from '../reflection/utils.js';
2
+ import { Property } from '../schema/index.js';
2
3
  import { isArray } from '../utils/type-guards.js';
3
4
  export function createTableDecorator(data) {
4
5
  return createClassDecorator({ data: { orm: data }, mergeData: true });
@@ -15,9 +16,23 @@ export function Column(options) {
15
16
  export function PrimaryKey() {
16
17
  return createColumnDecorator({ primaryKey: true });
17
18
  }
19
+ export function References(type) {
20
+ return createColumnDecorator({ references: type });
21
+ }
22
+ export function Embedded(type, options) {
23
+ return createPropertyDecorator({
24
+ include: [Property(type), createColumnDecorator({ embedded: { type, ...options } })]
25
+ });
26
+ }
18
27
  export function Unique(name, columnsOrOptions, options) {
19
28
  if (isArray(columnsOrOptions)) {
20
29
  return createTableDecorator({ unique: [{ name, columns: columnsOrOptions, options }] });
21
30
  }
22
31
  return createColumnDecorator({ unique: { name, options: columnsOrOptions ?? options } });
23
32
  }
33
+ export function Index(name, columnsOrOptions, options) {
34
+ if (isArray(columnsOrOptions)) {
35
+ return createTableDecorator({ index: [{ name, columns: columnsOrOptions, options }] });
36
+ }
37
+ return createColumnDecorator({ index: { name, options: columnsOrOptions ?? options } });
38
+ }
@@ -0,0 +1 @@
1
+ export * from './schema-converter.js';
@@ -0,0 +1 @@
1
+ export * from './schema-converter.js';
@@ -1,19 +1,48 @@
1
1
  import type { BuildColumns, NotNull } from 'drizzle-orm';
2
- import { type PgTableWithColumns } from 'drizzle-orm/pg-core';
3
- import type { SnakeCase } from 'type-fest';
4
- import type { Enumeration, Type } from '../../types.js';
2
+ import { type PgColumnBuilder, type PgEnum, type PgSchema, type PgTableWithColumns } from 'drizzle-orm/pg-core';
3
+ import type { CamelCase, ConditionalPick, SnakeCase } from 'type-fest';
4
+ import { JsonPath } from '../../json-path/json-path.js';
5
+ import { type Record } from '../../schema/index.js';
6
+ import type { AbstractConstructor, Enumeration } from '../../types.js';
7
+ import type { OrmColumnReflectionData } from '../decorators.js';
5
8
  import type { EntityType } from '../entity.js';
6
- import type { ColumnBuilder } from '../types.js';
9
+ import type { ColumnBuilder, embedded } from '../types.js';
7
10
  type Column<Name extends string, T> = null extends T ? ColumnBuilder<T, Name> : NotNull<ColumnBuilder<T, Name>>;
11
+ type ConverterContext = {
12
+ type: AbstractConstructor;
13
+ property: string;
14
+ };
15
+ export type ColumnDefinition = {
16
+ name: string;
17
+ objectPath: JsonPath;
18
+ type: PgColumnBuilder<any, any, any, any>;
19
+ reflectionData: OrmColumnReflectionData | undefined;
20
+ dereferenceObjectPath: (obj: Record) => any;
21
+ };
8
22
  export declare const getDrizzleTableFromType: typeof _getDrizzleTableFromType;
9
- export type PgTableFromType<S extends string, T extends Type, TableName extends string = T extends EntityType ? SnakeCase<T['entityName']> : string> = PgTableWithColumns<{
23
+ export type ColumnPrefix<T> = T extends {
24
+ prefix: infer Prefix;
25
+ } ? Prefix extends string ? Prefix : '' : '';
26
+ export type PgTableFromType<S extends string, T extends AbstractConstructor, TableName extends string = T extends Required<EntityType> ? SnakeCase<T['entityName']> : string> = PgTableWithColumns<{
10
27
  name: TableName;
11
28
  schema: S;
12
29
  columns: BuildColumns<TableName, {
13
- [P in keyof InstanceType<T>]: Column<Extract<P, string>, InstanceType<T>[P]>;
14
- }, 'pg'>;
30
+ [P in Exclude<keyof InstanceType<T>, keyof EmbeddedProperties<InstanceType<T>>>]: Column<CamelCase<Extract<P, string>>, InstanceType<T>[P]>;
31
+ } & {
32
+ [P in keyof EmbeddedProperties<InstanceType<T>>]: EmbeddedColumns<InstanceType<T>[P], ColumnPrefix<InstanceType<T>[P]>>;
33
+ }[keyof EmbeddedProperties<InstanceType<T>>], 'pg'>;
15
34
  dialect: 'pg';
16
35
  }>;
17
- export declare function _getDrizzleTableFromType<S extends string, T extends Type>(schemaName: S, type: T, tableName?: string): PgTableFromType<S, T>;
36
+ export type EmbeddedProperties<T> = ConditionalPick<T, {
37
+ [embedded]: {
38
+ prefix: any;
39
+ };
40
+ }>;
41
+ export type EmbeddedColumns<T, Prefix extends string> = {
42
+ [P in keyof T as CamelCase<`${Prefix}${Extract<P, string>}`>]: Column<CamelCase<`${Prefix}${Extract<P, string>}`>, T[P]>;
43
+ };
44
+ export declare function getColumnDefinitions(table: PgTableWithColumns<any>): ColumnDefinition[];
45
+ export declare function _getDrizzleTableFromType<T extends EntityType, S extends string>(type: T, schemaName: S, tableName?: string): PgTableFromType<S, T>;
18
46
  export declare function registerEnum(enumeration: Enumeration, name: string): void;
47
+ export declare function getPgEnum(schema: string | PgSchema, enumeration: Enumeration, context?: ConverterContext): PgEnum<[string, ...string[]]>;
19
48
  export {};
@@ -1,50 +1,103 @@
1
- import { toSnakeCase } from 'drizzle-orm/casing';
2
- import { boolean, doublePrecision, integer, pgSchema, text, unique, uuid } from 'drizzle-orm/pg-core';
1
+ import { toCamelCase, toSnakeCase } from 'drizzle-orm/casing';
2
+ import { boolean, date, doublePrecision, index, integer, jsonb, pgSchema, text, timestamp, unique, uniqueIndex, uuid } from 'drizzle-orm/pg-core';
3
+ import { MultiKeyMap } from '../../data-structures/multi-key-map.js';
3
4
  import { NotSupportedError } from '../../errors/not-supported.error.js';
5
+ import { JsonPath } from '../../json-path/json-path.js';
4
6
  import { reflectionRegistry } from '../../reflection/registry.js';
5
- import { ArraySchema, BooleanSchema, EnumerationSchema, getObjectSchema, NullableSchema, NumberSchema, OptionalSchema, StringSchema } from '../../schema/index.js';
7
+ import { ArraySchema, BooleanSchema, DefaultSchema, EnumerationSchema, getObjectSchema, NullableSchema, NumberSchema, ObjectSchema, OptionalSchema, StringSchema } from '../../schema/index.js';
8
+ import { compareByValueSelectionToOrder, orderRest } from '../../utils/comparison.js';
6
9
  import { enumValues } from '../../utils/enum.js';
7
10
  import { memoize, memoizeSingle } from '../../utils/function/memoize.js';
11
+ import { compileDereferencer } from '../../utils/object/dereference.js';
8
12
  import { fromEntries, objectEntries } from '../../utils/object/object.js';
9
- import { assertDefinedPass, assertStringPass, isArray, isDefined, isString, isUndefined } from '../../utils/type-guards.js';
13
+ import { assertDefined, assertDefinedPass, isArray, isDefined, isNull, isString, isUndefined } from '../../utils/type-guards.js';
14
+ import { JsonSchema } from '../schemas/json.js';
15
+ import { NumericDateSchema } from '../schemas/numeric-date.js';
16
+ import { TimestampSchema } from '../schemas/timestamp.js';
10
17
  import { UuidSchema } from '../schemas/uuid.js';
11
18
  const getDbSchema = memoizeSingle(pgSchema);
12
19
  export const getDrizzleTableFromType = memoize(_getDrizzleTableFromType);
13
- export function _getDrizzleTableFromType(schemaName, type, tableName = getDefaultTableName(type)) {
20
+ const columnDefinitionsSymbol = Symbol('columnDefinitions');
21
+ export function getColumnDefinitions(table) {
22
+ return table[columnDefinitionsSymbol];
23
+ }
24
+ export function _getDrizzleTableFromType(type, schemaName, tableName = getDefaultTableName(type)) {
14
25
  const metadata = reflectionRegistry.getMetadata(type);
15
- if (isUndefined(metadata)) {
16
- throw new Error('Type does not have reflection metadata.');
17
- }
26
+ assertDefined(metadata, `Type ${type.name} does not have reflection metadata.`);
18
27
  const dbSchema = getDbSchema(schemaName);
19
28
  const tableReflectionData = metadata.data.tryGet('orm');
20
- const objectSchema = getObjectSchema(type);
21
- const entries = objectEntries(objectSchema.properties).map(([property, schema]) => {
22
- const columnReflectionData = metadata.properties.get(property)?.data.tryGet('orm');
23
- const propertyName = columnReflectionData?.name ?? assertStringPass(toSnakeCase(property));
24
- return [
25
- property,
26
- getPostgresColumn(tableName, propertyName, dbSchema, schema, columnReflectionData ?? {})
27
- ];
28
- });
29
+ const columnDefinitions = getPostgresColumnEntries(type, tableName, dbSchema);
29
30
  function getColumn(table, propertyName) {
30
31
  return assertDefinedPass(table[propertyName], `Property "${propertyName}" does not exist on ${type.name}`);
31
32
  }
32
- const drizzleSchema = dbSchema.table(tableName, fromEntries(entries), (table) => {
33
- const uniqueEntries = tableReflectionData?.unique?.map((data, index) => {
33
+ function buildIndex(table, data, columnName) {
34
+ const columns = (data.columns ?? [columnName]).map((columnValue) => {
35
+ assertDefined(columnValue, 'Missing column name for index.');
36
+ const [columnName, columnOrder] = isString(columnValue) ? [columnValue] : columnValue;
37
+ const order = columnOrder ?? data.order ?? 'asc';
38
+ let column = getColumn(table, columnName);
39
+ column = column[order]();
40
+ if (data.options?.nulls == 'first') {
41
+ column = column.nullsFirst();
42
+ }
43
+ else if (data.options?.nulls == 'last') {
44
+ column = column.nullsLast();
45
+ }
46
+ return column;
47
+ });
48
+ const indexFn = (data.options?.unique == true) ? uniqueIndex : index;
49
+ return indexFn().using(data.options?.using ?? 'btree', ...columns);
50
+ }
51
+ const columnEntries = columnDefinitions.map((entry) => [entry.name, entry.type]);
52
+ const drizzleSchema = dbSchema.table(tableName, fromEntries(columnEntries), (table) => [
53
+ ...(columnDefinitions.map((columnDefinition) => {
54
+ const indexData = columnDefinition.reflectionData?.index;
55
+ if (isUndefined(indexData)) {
56
+ return undefined;
57
+ }
58
+ return buildIndex(table, indexData, columnDefinition.name);
59
+ }).filter(isDefined)),
60
+ ...(tableReflectionData?.unique?.map((data) => {
34
61
  const columns = data.columns?.map((column) => getColumn(table, column));
35
62
  let constraint = unique(isDefined(data.name) ? toSnakeCase(data.name) : undefined).on(...columns);
36
63
  if (data.options?.nulls == 'not distinct') {
37
64
  constraint = constraint.nullsNotDistinct();
38
65
  }
39
- return [`unique_${index}`, constraint];
40
- });
41
- return {
42
- ...isDefined(uniqueEntries) ? fromEntries(uniqueEntries) : undefined
43
- };
44
- });
66
+ return constraint;
67
+ }) ?? []),
68
+ ...(tableReflectionData?.index?.map((data) => buildIndex(table, data)) ?? [])
69
+ ]);
70
+ drizzleSchema[columnDefinitionsSymbol] = columnDefinitions;
45
71
  return drizzleSchema; // eslint-disable-line @typescript-eslint/no-unsafe-return
46
72
  }
47
- function getPostgresColumn(tableName, columnName, dbSchema, propertySchema, reflectionData) {
73
+ function getPostgresColumnEntries(type, tableName, dbSchema, path = new JsonPath({ dollar: false }), prefix = '') {
74
+ const metadata = reflectionRegistry.getMetadata(type);
75
+ assertDefined(metadata, `Type ${type.name} does not have reflection metadata (path: ${path.toString()}).`);
76
+ const objectSchema = getObjectSchema(type);
77
+ const entries = objectEntries(objectSchema.properties).toSorted(compareByValueSelectionToOrder(['id', orderRest, 'metadata'], (item) => item[0])).flatMap(([property, schema]) => {
78
+ const columnReflectionData = metadata.properties.get(property)?.data.tryGet('orm');
79
+ const columnName = columnReflectionData?.name ?? toSnakeCase(property);
80
+ if ((schema instanceof ObjectSchema) && !(schema instanceof JsonSchema)) {
81
+ const propertyMetadata = reflectionRegistry.getMetadata(type)?.properties.get(property);
82
+ assertDefined(propertyMetadata, `Property "${property}" of type "${type.name}" does not have reflection metadata (path: ${path.toString()}).`);
83
+ const propertyPrefix = columnReflectionData?.embedded?.prefix;
84
+ const nestedPrefix = [prefix, isNull(propertyPrefix) ? '' : propertyPrefix ?? `${columnName}_`].join('');
85
+ return getPostgresColumnEntries(columnReflectionData?.embedded?.type ?? propertyMetadata.type, tableName, dbSchema, path.add(property), nestedPrefix);
86
+ }
87
+ const objectPath = path.add(property);
88
+ return [
89
+ {
90
+ name: toCamelCase([prefix, columnName].join('')),
91
+ objectPath,
92
+ type: getPostgresColumn(columnName, dbSchema, schema, columnReflectionData ?? {}, { type, property }),
93
+ reflectionData: columnReflectionData,
94
+ dereferenceObjectPath: compileDereferencer(objectPath, { optional: true })
95
+ }
96
+ ];
97
+ });
98
+ return entries;
99
+ }
100
+ function getPostgresColumn(columnName, dbSchema, propertySchema, reflectionData, context) {
48
101
  let nullable = false;
49
102
  let array = false;
50
103
  let baseSchema = propertySchema;
@@ -61,7 +114,7 @@ function getPostgresColumn(tableName, columnName, dbSchema, propertySchema, refl
61
114
  break;
62
115
  }
63
116
  }
64
- let column = getPostgresBaseColumn(tableName, columnName, dbSchema, baseSchema);
117
+ let column = getPostgresBaseColumn(columnName, dbSchema, baseSchema, context);
65
118
  if (array) {
66
119
  column = column.array();
67
120
  }
@@ -74,13 +127,15 @@ function getPostgresColumn(tableName, columnName, dbSchema, propertySchema, refl
74
127
  if (reflectionData.primaryKey == true) {
75
128
  column = column.primaryKey();
76
129
  }
130
+ if (isDefined(reflectionData.references)) {
131
+ column = column.references(() => getDrizzleTableFromType(reflectionData.references(), dbSchema.schemaName).id);
132
+ }
77
133
  return column;
78
134
  }
79
- function getPostgresBaseColumn(tableName, columnName, dbSchema, schema) {
80
- if (schema instanceof NumberSchema) {
81
- return schema.integer
82
- ? integer(columnName)
83
- : doublePrecision(columnName);
135
+ function getPostgresBaseColumn(columnName, dbSchema, schema, context) {
136
+ if (schema instanceof DefaultSchema) {
137
+ const column = getPostgresBaseColumn(columnName, dbSchema, schema.schema, context);
138
+ return column.default(schema.defaultValue);
84
139
  }
85
140
  if (schema instanceof UuidSchema) {
86
141
  let column = uuid(columnName);
@@ -89,6 +144,17 @@ function getPostgresBaseColumn(tableName, columnName, dbSchema, schema) {
89
144
  }
90
145
  return column;
91
146
  }
147
+ if (schema instanceof TimestampSchema) {
148
+ return timestamp(columnName, { withTimezone: true });
149
+ }
150
+ if (schema instanceof NumericDateSchema) {
151
+ return date(columnName);
152
+ }
153
+ if (schema instanceof NumberSchema) {
154
+ return schema.integer
155
+ ? integer(columnName)
156
+ : doublePrecision(columnName);
157
+ }
92
158
  if (schema instanceof StringSchema) {
93
159
  return text(columnName);
94
160
  }
@@ -96,21 +162,36 @@ function getPostgresBaseColumn(tableName, columnName, dbSchema, schema) {
96
162
  return boolean(columnName);
97
163
  }
98
164
  if (schema instanceof EnumerationSchema) {
99
- const pgEnum = getPgEnum(tableName, columnName, dbSchema, schema.enumeration);
165
+ const pgEnum = getPgEnum(dbSchema, schema.enumeration, context);
100
166
  return pgEnum(columnName);
101
167
  }
102
- throw new NotSupportedError(`Schema ${schema.constructor.name} not supported`);
168
+ if (schema instanceof JsonSchema) {
169
+ return jsonb(columnName);
170
+ }
171
+ throw new NotSupportedError(`Schema "${schema.constructor.name}" not supported on type "${context.type.name}" for property "${context.property}"`);
103
172
  }
104
- const enums = new Map();
173
+ const enumNames = new Map();
174
+ const enums = new MultiKeyMap();
105
175
  export function registerEnum(enumeration, name) {
106
- enums.set(enumeration, name);
176
+ enumNames.set(enumeration, toSnakeCase(name));
107
177
  }
108
- function getPgEnum(tableName, columnName, dbSchema, enumeration) {
178
+ export function getPgEnum(schema, enumeration, context) {
179
+ const dbSchema = isString(schema) ? getDbSchema(schema) : schema;
180
+ const enumName = enumNames.get(enumeration);
181
+ if (isUndefined(enumName)) {
182
+ if (isDefined(context)) {
183
+ throw new Error(`Enum is not registered. (type: ${context.type.name}, property: ${context.property})`);
184
+ }
185
+ throw new Error('Enum is not registered.');
186
+ }
109
187
  const values = (isArray(enumeration) ? enumeration : enumValues(enumeration))
110
188
  .map((value) => value.toString());
111
- const enumName = enums.get(enumeration) ?? `${tableName}_${columnName}_enum`;
112
- return dbSchema.enum(enumName, values);
189
+ const dbEnum = dbSchema.enum(enumName, values);
190
+ if (enums.has([dbSchema.schemaName, enumeration])) {
191
+ enums.set([dbSchema.schemaName, enumeration], dbEnum);
192
+ }
193
+ return dbEnum;
113
194
  }
114
195
  function getDefaultTableName(type) {
115
- return toSnakeCase(isString(type.entityName) ? type.entityName : type.name);
196
+ return toSnakeCase(isString(type.entityName) ? type.entityName : type.name.replace(/\d+$/u, ''));
116
197
  }
package/orm/entity.d.ts CHANGED
@@ -1,20 +1,23 @@
1
- import type { Record, Type, TypedOmit } from '../types.js';
2
- import { type HasDefault, type IsPrimaryKey, Uuid } from './types.js';
1
+ import { Record } from '../schema/index.js';
2
+ import { Type, TypedOmit, UntaggedDeep } from '../types.js';
3
+ import { Embedded, type HasDefault, type IsPrimaryKey, Json, Timestamp, Uuid } from './types.js';
3
4
  export interface EntityType<T extends Entity = Entity> extends Type<T> {
4
- readonly entityName: string;
5
+ readonly entityName?: string;
6
+ }
7
+ export type NewEntity<T extends Entity> = UntaggedDeep<TypedOmit<T, 'id' | 'metadata'> & {
8
+ id?: string;
9
+ metadata?: Partial<Pick<EntityMetadata, 'attributes'>>;
10
+ }>;
11
+ export declare abstract class EntityMetadataAttributes implements Record {
5
12
  }
6
13
  export declare abstract class EntityMetadata {
7
14
  revision: number;
8
- revisionTimestamp: number;
9
- createTimestamp: number;
10
- deleteTimestamp: number | null;
11
- attributes: Record;
15
+ revisionTimestamp: Timestamp;
16
+ createTimestamp: Timestamp;
17
+ deleteTimestamp: Timestamp | null;
18
+ attributes: HasDefault<Json<EntityMetadataAttributes>>;
12
19
  }
13
20
  export declare abstract class Entity {
14
21
  id: IsPrimaryKey<HasDefault<Uuid>>;
15
- metadata: EntityMetadata;
22
+ metadata: Embedded<EntityMetadata>;
16
23
  }
17
- export type NewEntity<T extends Entity> = TypedOmit<T, 'id' | 'metadata'> & {
18
- id?: string;
19
- metadata?: Partial<Pick<EntityMetadata, 'attributes'>>;
20
- };
package/orm/entity.js CHANGED
@@ -7,39 +7,48 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
7
7
  var __metadata = (this && this.__metadata) || function (k, v) {
8
8
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
9
9
  };
10
- import { NumberProperty, Property, any, record } from '../schema/index.js';
11
- import { PrimaryKey } from './decorators.js';
12
- import { Uuid } from './types.js';
13
- export class EntityMetadata {
10
+ import { Defaulted, Integer } from '../schema/index.js';
11
+ import { Index, PrimaryKey } from './decorators.js';
12
+ import { Embedded, Json, Timestamp, Uuid } from './types.js';
13
+ let EntityMetadataAttributes = class EntityMetadataAttributes {
14
+ }; // eslint-disable-line @typescript-eslint/no-extraneous-class
15
+ EntityMetadataAttributes = __decorate([
16
+ Json()
17
+ ], EntityMetadataAttributes);
18
+ export { EntityMetadataAttributes };
19
+ let EntityMetadata = class EntityMetadata {
14
20
  revision;
15
21
  revisionTimestamp;
16
22
  createTimestamp;
17
23
  deleteTimestamp;
18
24
  attributes;
19
- }
25
+ };
20
26
  __decorate([
21
- NumberProperty(),
27
+ Integer(),
22
28
  __metadata("design:type", Number)
23
29
  ], EntityMetadata.prototype, "revision", void 0);
24
30
  __decorate([
25
- NumberProperty(),
31
+ Timestamp(),
26
32
  __metadata("design:type", Number)
27
33
  ], EntityMetadata.prototype, "revisionTimestamp", void 0);
28
34
  __decorate([
29
- NumberProperty(),
35
+ Timestamp(),
30
36
  __metadata("design:type", Number)
31
37
  ], EntityMetadata.prototype, "createTimestamp", void 0);
32
38
  __decorate([
33
- NumberProperty({ nullable: true }),
39
+ Timestamp({ nullable: true }),
34
40
  __metadata("design:type", Object)
35
41
  ], EntityMetadata.prototype, "deleteTimestamp", void 0);
36
42
  __decorate([
37
- Property(record(any(), any())),
43
+ Defaulted(EntityMetadataAttributes, {}),
38
44
  __metadata("design:type", Object)
39
45
  ], EntityMetadata.prototype, "attributes", void 0);
46
+ EntityMetadata = __decorate([
47
+ Index(undefined, ['revision', 'revisionTimestamp'])
48
+ ], EntityMetadata);
49
+ export { EntityMetadata };
40
50
  export class Entity {
41
51
  id;
42
- // @Property(EntityMetadata)
43
52
  metadata;
44
53
  }
45
54
  __decorate([
@@ -47,3 +56,7 @@ __decorate([
47
56
  Uuid({ defaultRandom: true }),
48
57
  __metadata("design:type", Object)
49
58
  ], Entity.prototype, "id", void 0);
59
+ __decorate([
60
+ Embedded(EntityMetadata, { prefix: null }),
61
+ __metadata("design:type", Object)
62
+ ], Entity.prototype, "metadata", void 0);
package/orm/index.d.ts CHANGED
@@ -1,7 +1,8 @@
1
1
  export * from './database-schema.js';
2
- export * from './decorators.js';
3
- export * from './drizzle/schema-converter.js';
2
+ export * from './database.js';
4
3
  export * from './entity.js';
4
+ export * from './module.js';
5
5
  export * from './query.js';
6
6
  export * from './repository.js';
7
+ export * from './transaction.js';
7
8
  export * from './types.js';
package/orm/index.js CHANGED
@@ -1,7 +1,8 @@
1
1
  export * from './database-schema.js';
2
- export * from './decorators.js';
3
- export * from './drizzle/schema-converter.js';
2
+ export * from './database.js';
4
3
  export * from './entity.js';
4
+ export * from './module.js';
5
5
  export * from './query.js';
6
6
  export * from './repository.js';
7
+ export * from './transaction.js';
7
8
  export * from './types.js';
@@ -0,0 +1,6 @@
1
+ import type { PoolConfig } from 'pg';
2
+ export type DatabaseConfig = {
3
+ connection: DatabaseArgument;
4
+ };
5
+ export type DatabaseArgument = string | PoolConfig;
6
+ export declare const DATABASE_CONFIG: import("../injector/index.js").InjectionToken<DatabaseConfig, never>;
package/orm/module.js ADDED
@@ -0,0 +1,15 @@
1
+ import { drizzle } from 'drizzle-orm/node-postgres';
2
+ import { inject, injectionToken } from '../injector/index.js';
3
+ import { Injector } from '../injector/injector.js';
4
+ import { isUndefined } from '../utils/type-guards.js';
5
+ import { Database } from './database.js';
6
+ export const DATABASE_CONFIG = injectionToken('EntityRepositoryConfig');
7
+ Injector.registerSingleton(Database, {
8
+ useFactory: (argument) => {
9
+ const connection = argument ?? inject(DATABASE_CONFIG, undefined, { optional: true })?.connection;
10
+ if (isUndefined(connection)) {
11
+ throw new Error('Missing postgres connection. Provide it either via injection argument or provider.');
12
+ }
13
+ return drizzle({ connection });
14
+ }
15
+ });
@@ -0,0 +1,5 @@
1
+ import { SQL } from 'drizzle-orm';
2
+ import type { ColumnDefinition, PgTableFromType } from './drizzle/schema-converter.js';
3
+ import type { EntityType } from './entity.js';
4
+ import type { Query } from './query.js';
5
+ export declare function convertQuery(query: Query, table: PgTableFromType<string, EntityType>, columnDefinitionsMap: Map<string, ColumnDefinition>): SQL;