@tstdl/base 0.91.28 → 0.91.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.
Files changed (77) hide show
  1. package/.eslintrc.json +5 -1
  2. package/authentication/models/authentication-credentials.model.js +10 -10
  3. package/authentication/models/authentication-session.model.d.ts +2 -2
  4. package/authentication/models/authentication-session.model.js +16 -16
  5. package/authentication/models/init-secret-reset-data.model.js +3 -3
  6. package/authentication/models/token-payload-base.model.d.ts +4 -4
  7. package/authentication/models/token-payload-base.model.js +12 -12
  8. package/{reflection/reflection-data-map.d.ts → data-structures/context-data-map.d.ts} +3 -2
  9. package/{reflection/reflection-data-map.js → data-structures/context-data-map.js} +13 -6
  10. package/data-structures/index.d.ts +1 -0
  11. package/data-structures/index.js +1 -0
  12. package/examples/api/basic-overview.js +2 -2
  13. package/examples/api/custom-authentication.js +3 -3
  14. package/examples/orm/drizzle.config.d.ts +2 -0
  15. package/examples/orm/drizzle.config.js +5 -0
  16. package/examples/orm/schemas.d.ts +3 -0
  17. package/examples/orm/schemas.js +4 -0
  18. package/examples/orm/test.js +10 -0
  19. package/examples/orm/user.model.d.ts +9 -0
  20. package/examples/orm/user.model.js +39 -0
  21. package/key-value-store/index.d.ts +0 -1
  22. package/key-value-store/index.js +0 -1
  23. package/key-value-store/key-value.store.d.ts +9 -10
  24. package/key-value-store/mongo/mongo-key-value.store.js +2 -1
  25. package/mail/mail.client.js +5 -6
  26. package/orm/database-schema.d.ts +8 -0
  27. package/orm/database-schema.js +13 -0
  28. package/orm/decorators.d.ts +26 -0
  29. package/orm/decorators.js +21 -2
  30. package/orm/drizzle/schema-converter.d.ts +19 -0
  31. package/orm/drizzle/schema-converter.js +116 -0
  32. package/orm/entity.d.ts +6 -2
  33. package/orm/entity.js +9 -9
  34. package/orm/index.d.ts +1 -2
  35. package/orm/index.js +1 -2
  36. package/orm/repository.d.ts +27 -24
  37. package/orm/repository.js +124 -7
  38. package/orm/schemas/index.d.ts +1 -0
  39. package/orm/schemas/index.js +1 -0
  40. package/orm/schemas/uuid.d.ts +11 -0
  41. package/orm/schemas/uuid.js +16 -0
  42. package/orm/types.d.ts +20 -7
  43. package/orm/types.js +3 -5
  44. package/package.json +7 -4
  45. package/reflection/registry.d.ts +9 -6
  46. package/reflection/registry.js +25 -14
  47. package/schema/decorators/property.d.ts +2 -2
  48. package/schema/decorators/types.d.ts +1 -0
  49. package/schema/schema.d.ts +1 -1
  50. package/schema/schemas/array.d.ts +6 -3
  51. package/schema/schemas/array.js +9 -4
  52. package/schema/schemas/deferred.d.ts +12 -0
  53. package/schema/schemas/deferred.js +23 -0
  54. package/schema/schemas/index.d.ts +1 -0
  55. package/schema/schemas/index.js +1 -0
  56. package/schema/schemas/number.d.ts +5 -0
  57. package/schema/schemas/number.js +8 -1
  58. package/schema/schemas/string.d.ts +4 -1
  59. package/schema/schemas/string.js +8 -2
  60. package/schema/schemas/uint8-array.d.ts +3 -2
  61. package/schema/schemas/uint8-array.js +8 -5
  62. package/templates/resolvers/file.template-resolver.d.ts +1 -2
  63. package/templates/resolvers/file.template-resolver.js +2 -2
  64. package/templates/resolvers/jsx.template-resolver.d.ts +1 -3
  65. package/templates/resolvers/jsx.template-resolver.js +3 -7
  66. package/templates/template.model.d.ts +1 -1
  67. package/templates/template.model.js +5 -5
  68. package/utils/math.d.ts +11 -1
  69. package/utils/math.js +28 -0
  70. package/utils/string/index.d.ts +1 -0
  71. package/utils/string/index.js +1 -0
  72. package/utils/string/snake-case.d.ts +1 -0
  73. package/utils/string/snake-case.js +4 -0
  74. package/orm/schema-converter.d.ts +0 -99
  75. package/orm/schema-converter.js +0 -74
  76. package/orm/schema.d.ts +0 -3
  77. /package/{orm/schema.js → examples/orm/test.d.ts} +0 -0
package/orm/decorators.js CHANGED
@@ -1,4 +1,23 @@
1
- import { createPropertyDecorator } from '../reflection/utils.js';
1
+ import { createClassDecorator, createDecorator, createPropertyDecorator } from '../reflection/utils.js';
2
+ import { isArray } from '../utils/type-guards.js';
3
+ export function createTableDecorator(data) {
4
+ return createClassDecorator({ data: { orm: data }, mergeData: true });
5
+ }
6
+ export function createColumnDecorator(data) {
7
+ return createPropertyDecorator({ data: { orm: data }, mergeData: true });
8
+ }
9
+ export function createTableAndColumnDecorator(data) {
10
+ return createDecorator({ class: true, property: true, data: { orm: data }, mergeData: true });
11
+ }
12
+ export function Column(options) {
13
+ return createColumnDecorator({ ...options });
14
+ }
2
15
  export function PrimaryKey() {
3
- return createPropertyDecorator({ data: { orm: { primaryKey: true } }, mergeData: true });
16
+ return createColumnDecorator({ primaryKey: true });
17
+ }
18
+ export function Unique(name, columnsOrOptions, options) {
19
+ if (isArray(columnsOrOptions)) {
20
+ return createTableDecorator({ unique: [{ name, columns: columnsOrOptions, options }] });
21
+ }
22
+ return createColumnDecorator({ unique: { name, options: columnsOrOptions ?? options } });
4
23
  }
@@ -0,0 +1,19 @@
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';
5
+ import type { EntityType } from '../entity.js';
6
+ import type { ColumnBuilder } from '../types.js';
7
+ type Column<Name extends string, T> = null extends T ? ColumnBuilder<T, Name> : NotNull<ColumnBuilder<T, Name>>;
8
+ 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<{
10
+ name: TableName;
11
+ schema: S;
12
+ columns: BuildColumns<TableName, {
13
+ [P in keyof InstanceType<T>]: Column<Extract<P, string>, InstanceType<T>[P]>;
14
+ }, 'pg'>;
15
+ dialect: 'pg';
16
+ }>;
17
+ export declare function _getDrizzleTableFromType<S extends string, T extends Type>(schemaName: S, type: T, tableName?: string): PgTableFromType<S, T>;
18
+ export declare function registerEnum(enumeration: Enumeration, name: string): void;
19
+ export {};
@@ -0,0 +1,116 @@
1
+ import { toSnakeCase } from 'drizzle-orm/casing';
2
+ import { boolean, doublePrecision, integer, pgSchema, text, unique, uuid } from 'drizzle-orm/pg-core';
3
+ import { NotSupportedError } from '../../errors/not-supported.error.js';
4
+ import { reflectionRegistry } from '../../reflection/registry.js';
5
+ import { ArraySchema, BooleanSchema, EnumerationSchema, getObjectSchema, NullableSchema, NumberSchema, OptionalSchema, StringSchema } from '../../schema/index.js';
6
+ import { enumValues } from '../../utils/enum.js';
7
+ import { memoize, memoizeSingle } from '../../utils/function/memoize.js';
8
+ import { fromEntries, objectEntries } from '../../utils/object/object.js';
9
+ import { assertDefinedPass, assertStringPass, isArray, isDefined, isString, isUndefined } from '../../utils/type-guards.js';
10
+ import { UuidSchema } from '../schemas/uuid.js';
11
+ const getDbSchema = memoizeSingle(pgSchema);
12
+ export const getDrizzleTableFromType = memoize(_getDrizzleTableFromType);
13
+ export function _getDrizzleTableFromType(schemaName, type, tableName = getDefaultTableName(type)) {
14
+ const metadata = reflectionRegistry.getMetadata(type);
15
+ if (isUndefined(metadata)) {
16
+ throw new Error('Type does not have reflection metadata.');
17
+ }
18
+ const dbSchema = getDbSchema(schemaName);
19
+ 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
+ function getColumn(table, propertyName) {
30
+ return assertDefinedPass(table[propertyName], `Property "${propertyName}" does not exist on ${type.name}`);
31
+ }
32
+ const drizzleSchema = dbSchema.table(tableName, fromEntries(entries), (table) => {
33
+ const uniqueEntries = tableReflectionData?.unique?.map((data, index) => {
34
+ const columns = data.columns?.map((column) => getColumn(table, column));
35
+ let constraint = unique(isDefined(data.name) ? toSnakeCase(data.name) : undefined).on(...columns);
36
+ if (data.options?.nulls == 'not distinct') {
37
+ constraint = constraint.nullsNotDistinct();
38
+ }
39
+ return [`unique_${index}`, constraint];
40
+ });
41
+ return {
42
+ ...isDefined(uniqueEntries) ? fromEntries(uniqueEntries) : undefined
43
+ };
44
+ });
45
+ return drizzleSchema; // eslint-disable-line @typescript-eslint/no-unsafe-return
46
+ }
47
+ function getPostgresColumn(tableName, columnName, dbSchema, propertySchema, reflectionData) {
48
+ let nullable = false;
49
+ let array = false;
50
+ let baseSchema = propertySchema;
51
+ while (true) {
52
+ if ((baseSchema instanceof NullableSchema) || (baseSchema instanceof OptionalSchema)) {
53
+ nullable = true;
54
+ baseSchema = baseSchema.schema;
55
+ }
56
+ else if (baseSchema instanceof ArraySchema) {
57
+ array = true;
58
+ baseSchema = baseSchema.itemSchema;
59
+ }
60
+ else {
61
+ break;
62
+ }
63
+ }
64
+ let column = getPostgresBaseColumn(tableName, columnName, dbSchema, baseSchema);
65
+ if (array) {
66
+ column = column.array();
67
+ }
68
+ if (!nullable) {
69
+ column = column.notNull();
70
+ }
71
+ if (isDefined(reflectionData.unique)) {
72
+ column = column.unique(reflectionData.unique.name, isString(reflectionData.unique.options?.nulls) ? { nulls: reflectionData.unique.options.nulls } : undefined);
73
+ }
74
+ if (reflectionData.primaryKey == true) {
75
+ column = column.primaryKey();
76
+ }
77
+ return column;
78
+ }
79
+ function getPostgresBaseColumn(tableName, columnName, dbSchema, schema) {
80
+ if (schema instanceof NumberSchema) {
81
+ return schema.integer
82
+ ? integer(columnName)
83
+ : doublePrecision(columnName);
84
+ }
85
+ if (schema instanceof UuidSchema) {
86
+ let column = uuid(columnName);
87
+ if (schema.defaultRandom) {
88
+ column = column.defaultRandom();
89
+ }
90
+ return column;
91
+ }
92
+ if (schema instanceof StringSchema) {
93
+ return text(columnName);
94
+ }
95
+ if (schema instanceof BooleanSchema) {
96
+ return boolean(columnName);
97
+ }
98
+ if (schema instanceof EnumerationSchema) {
99
+ const pgEnum = getPgEnum(tableName, columnName, dbSchema, schema.enumeration);
100
+ return pgEnum(columnName);
101
+ }
102
+ throw new NotSupportedError(`Schema ${schema.constructor.name} not supported`);
103
+ }
104
+ const enums = new Map();
105
+ export function registerEnum(enumeration, name) {
106
+ enums.set(enumeration, name);
107
+ }
108
+ function getPgEnum(tableName, columnName, dbSchema, enumeration) {
109
+ const values = (isArray(enumeration) ? enumeration : enumValues(enumeration))
110
+ .map((value) => value.toString());
111
+ const enumName = enums.get(enumeration) ?? `${tableName}_${columnName}_enum`;
112
+ return dbSchema.enum(enumName, values);
113
+ }
114
+ function getDefaultTableName(type) {
115
+ return toSnakeCase(isString(type.entityName) ? type.entityName : type.name);
116
+ }
package/orm/entity.d.ts CHANGED
@@ -1,4 +1,8 @@
1
- import type { Record, TypedOmit } from '../types.js';
1
+ import type { Record, Type, TypedOmit } from '../types.js';
2
+ import { type HasDefault, type IsPrimaryKey, Uuid } from './types.js';
3
+ export interface EntityType<T extends Entity = Entity> extends Type<T> {
4
+ readonly entityName: string;
5
+ }
2
6
  export declare abstract class EntityMetadata {
3
7
  revision: number;
4
8
  revisionTimestamp: number;
@@ -7,7 +11,7 @@ export declare abstract class EntityMetadata {
7
11
  attributes: Record;
8
12
  }
9
13
  export declare abstract class Entity {
10
- id: string;
14
+ id: IsPrimaryKey<HasDefault<Uuid>>;
11
15
  metadata: EntityMetadata;
12
16
  }
13
17
  export type NewEntity<T extends Entity> = TypedOmit<T, 'id' | 'metadata'> & {
package/orm/entity.js CHANGED
@@ -8,6 +8,8 @@ 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
10
  import { NumberProperty, Property, any, record } from '../schema/index.js';
11
+ import { PrimaryKey } from './decorators.js';
12
+ import { Uuid } from './types.js';
11
13
  export class EntityMetadata {
12
14
  revision;
13
15
  revisionTimestamp;
@@ -16,15 +18,15 @@ export class EntityMetadata {
16
18
  attributes;
17
19
  }
18
20
  __decorate([
19
- Property(),
21
+ NumberProperty(),
20
22
  __metadata("design:type", Number)
21
23
  ], EntityMetadata.prototype, "revision", void 0);
22
24
  __decorate([
23
- Property(),
25
+ NumberProperty(),
24
26
  __metadata("design:type", Number)
25
27
  ], EntityMetadata.prototype, "revisionTimestamp", void 0);
26
28
  __decorate([
27
- Property(),
29
+ NumberProperty(),
28
30
  __metadata("design:type", Number)
29
31
  ], EntityMetadata.prototype, "createTimestamp", void 0);
30
32
  __decorate([
@@ -37,13 +39,11 @@ __decorate([
37
39
  ], EntityMetadata.prototype, "attributes", void 0);
38
40
  export class Entity {
39
41
  id;
42
+ // @Property(EntityMetadata)
40
43
  metadata;
41
44
  }
42
45
  __decorate([
43
- Property(),
44
- __metadata("design:type", String)
46
+ PrimaryKey(),
47
+ Uuid({ defaultRandom: true }),
48
+ __metadata("design:type", Object)
45
49
  ], Entity.prototype, "id", void 0);
46
- __decorate([
47
- Property(EntityMetadata),
48
- __metadata("design:type", EntityMetadata)
49
- ], Entity.prototype, "metadata", void 0);
package/orm/index.d.ts CHANGED
@@ -1,7 +1,6 @@
1
1
  export * from './decorators.js';
2
+ export * from './drizzle/schema-converter.js';
2
3
  export * from './entity.js';
3
4
  export * from './query.js';
4
5
  export * from './repository.js';
5
- export * from './schema-converter.js';
6
- export * from './schema.js';
7
6
  export * from './types.js';
package/orm/index.js CHANGED
@@ -1,7 +1,6 @@
1
1
  export * from './decorators.js';
2
+ export * from './drizzle/schema-converter.js';
2
3
  export * from './entity.js';
3
4
  export * from './query.js';
4
5
  export * from './repository.js';
5
- export * from './schema-converter.js';
6
- export * from './schema.js';
7
6
  export * from './types.js';
@@ -1,5 +1,6 @@
1
- import type { Paths, Type, TypedOmit } from '../types.js';
2
- import type { Entity, EntityMetadata, NewEntity } from './entity.js';
1
+ import type { Paths, TypedOmit } from '../types.js';
2
+ import { SQL } from 'drizzle-orm';
3
+ import type { Entity, EntityMetadata, EntityType, NewEntity } from './entity.js';
3
4
  import type { Query } from './query.js';
4
5
  export declare const repositoryType: unique symbol;
5
6
  export type OrderOptions<T extends Entity> = {
@@ -17,34 +18,36 @@ export type EntityMetadataUpdate = {
17
18
  metadata?: Partial<EntityMetadata>;
18
19
  };
19
20
  export type EntityUpdate<T extends Entity> = Partial<TypedOmit<T, 'metadata'>> & EntityMetadataUpdate;
21
+ export declare const entityType: import("../injector/token.js").InjectionToken<EntityType<any>, never>;
20
22
  export declare abstract class EntityRepository<T extends Entity = Entity> {
21
- readonly type: Type<T>;
23
+ readonly type: EntityType<T>;
24
+ readonly schema: import("./drizzle/schema-converter.js").PgTableFromType<"", EntityType<Entity>, string>;
22
25
  readonly database: import("drizzle-orm/node-postgres").NodePgDatabase<Record<string, never>> & {
23
- $client: null;
26
+ $client: import("drizzle-orm/node-postgres").NodePgClient;
24
27
  };
25
- load(_id: string): Promise<T>;
26
- abstract tryLoad(id: string): Promise<T | undefined>;
27
- abstract loadByFilter(query: Query<T>, options?: LoadOptions<T>): Promise<T>;
28
- abstract tryLoadByFilter(query: Query<T>, options?: LoadOptions<T>): Promise<T | undefined>;
29
- abstract loadMany(ids: string[], options?: LoadManyOptions<T>): Promise<T[]>;
30
- abstract loadManyCursor(ids: string[], options?: LoadManyOptions<T>): AsyncIterableIterator<T>;
31
- abstract loadManyByFilter(query: Query<T>, options?: LoadManyOptions<T>): Promise<T[]>;
32
- abstract loadManyByFilterCursor(query: Query<T>, options?: LoadManyOptions<T>): AsyncIterableIterator<T>;
33
- abstract loadAll(options?: LoadManyOptions<T>): Promise<T[]>;
34
- abstract loadAllCursor(options?: LoadManyOptions<T>): AsyncIterableIterator<T>;
35
- abstract count(): Promise<number>;
36
- abstract countByFilter(query: Query<T>): Promise<number>;
37
- abstract has(id: string): Promise<boolean>;
38
- abstract hasByFilter(query: Query<T>): Promise<boolean>;
39
- abstract hasAll(ids: string[]): Promise<boolean>;
40
- abstract insert(entity: NewEntity<T>): Promise<T>;
28
+ load(id: string): Promise<T>;
29
+ tryLoad(id: string): Promise<T | undefined>;
30
+ loadByQuery(query: Query<T> | SQL | undefined, options?: LoadOptions<T>): Promise<T>;
31
+ tryLoadByQuery(query: Query<T> | SQL | undefined, options?: LoadOptions<T>): Promise<T | undefined>;
32
+ loadMany(ids: string[], options?: LoadManyOptions<T>): Promise<T[]>;
33
+ loadManyCursor(ids: string[], options?: LoadManyOptions<T>): AsyncIterableIterator<T>;
34
+ loadManyByQuery(query: Query<T> | SQL | undefined, options?: LoadManyOptions<T>): Promise<T[]>;
35
+ loadManyByQueryCursor(query: Query<T> | SQL | undefined, options?: LoadManyOptions<T>): AsyncIterableIterator<T>;
36
+ loadAll(options?: LoadManyOptions<T>): Promise<T[]>;
37
+ loadAllCursor(options?: LoadManyOptions<T>): AsyncIterableIterator<T>;
38
+ count(): Promise<number>;
39
+ countByQuery(query: Query<T> | SQL): Promise<number>;
40
+ has(id: string): Promise<boolean>;
41
+ hasByQuery(query: Query<T> | SQL): Promise<boolean>;
42
+ hasAll(ids: string[]): Promise<boolean>;
43
+ insert(_entity: NewEntity<T>): Promise<T>;
41
44
  abstract insertMany(entities: NewEntity<T>[]): Promise<T[]>;
42
45
  abstract update(id: string, update: EntityUpdate<T>): Promise<void>;
43
- abstract updateByFilter(query: Query<T>, update: EntityUpdate<T>): Promise<void>;
46
+ abstract updateByQuery(query: Query<T>, update: EntityUpdate<T>): Promise<void>;
44
47
  abstract updateMany(ids: string[], update: EntityUpdate<T>): Promise<void>;
45
- abstract updateManyByFilter(filter: Query<T>, update: EntityUpdate<T>): Promise<void>;
48
+ abstract updateManyByQuery(filter: Query<T>, update: EntityUpdate<T>): Promise<void>;
46
49
  abstract delete(id: string): Promise<boolean>;
47
50
  abstract deleteMany(ids: string[]): Promise<number>;
48
- abstract deleteByFilter(query: Query<T>): Promise<boolean>;
49
- abstract deleteManyByFilter(query: Query<T>): Promise<number>;
51
+ abstract deleteByQuery(query: Query<T>): Promise<boolean>;
52
+ abstract deleteManyByQuery(query: Query<T>): Promise<number>;
50
53
  }
package/orm/repository.js CHANGED
@@ -1,11 +1,128 @@
1
- import { NotImplementedError } from '../errors/not-implemented.error.js';
1
+ /* eslint-disable @typescript-eslint/no-non-null-asserted-optional-chain */
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ 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;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
2
8
  import { drizzle } from 'drizzle-orm/node-postgres';
9
+ import { NotFoundError } from '../errors/not-found.error.js';
10
+ import { NotImplementedError } from '../errors/not-implemented.error.js';
11
+ import { NotSupportedError } from '../errors/not-supported.error.js';
12
+ import { Singleton } from '../injector/decorators.js';
13
+ import { inject } from '../injector/inject.js';
14
+ import { injectionToken } from '../injector/token.js';
15
+ import { assertDefinedPass, isUndefined } from '../utils/type-guards.js';
16
+ import { count, eq, inArray, sql, SQL } from 'drizzle-orm';
17
+ import { getDrizzleTableFromType } from './drizzle/schema-converter.js';
3
18
  export const repositoryType = Symbol('repositoryType');
4
- export class EntityRepository {
5
- type;
6
- database = drizzle(null);
7
- async load(_id) {
8
- // const result = await this.database.select({ name2: mySchemaUsers.name }).from(mySchemaUsers).leftJoin();
19
+ export const entityType = injectionToken('Entity type');
20
+ let EntityRepository = class EntityRepository {
21
+ type = inject(entityType);
22
+ schema = getDrizzleTableFromType('', this.type);
23
+ database = drizzle('');
24
+ async load(id) {
25
+ const entity = await this.tryLoad(id);
26
+ if (isUndefined(entity)) {
27
+ throw new NotFoundError(`${this.type.entityName} ${id} not found.`);
28
+ }
29
+ return entity;
30
+ }
31
+ async tryLoad(id) {
32
+ return this.tryLoadByQuery(eq(this.schema.id, id));
33
+ }
34
+ async loadByQuery(query, options) {
35
+ const entity = await this.tryLoadByQuery(query, options);
36
+ if (isUndefined(entity)) {
37
+ throw new NotFoundError(`${this.type.entityName} not found.`);
38
+ }
39
+ return entity;
40
+ }
41
+ async tryLoadByQuery(query, options) {
42
+ if (!(query instanceof SQL)) {
43
+ throw new NotSupportedError();
44
+ }
45
+ const dbQuery = this.database.select()
46
+ .from(this.schema)
47
+ .where(query)
48
+ .offset(options?.offset);
49
+ const [entity] = (await dbQuery);
50
+ return entity;
51
+ }
52
+ async loadMany(ids, options) {
53
+ return this.loadManyByQuery(inArray(this.schema.id, ids), options);
54
+ }
55
+ async *loadManyCursor(ids, options) {
56
+ const entities = await this.loadMany(ids, options);
57
+ yield* entities;
58
+ }
59
+ async loadManyByQuery(query, options) {
60
+ if (!(query instanceof SQL)) {
61
+ throw new NotSupportedError();
62
+ }
63
+ const dbQuery = this.database.select()
64
+ .from(this.schema)
65
+ .where(query)
66
+ .offset(options?.offset)
67
+ .limit(options?.limit);
68
+ return dbQuery;
69
+ }
70
+ async *loadManyByQueryCursor(query, options) {
71
+ const entities = await this.loadManyByQuery(query, options);
72
+ yield* entities;
73
+ }
74
+ async loadAll(options) {
75
+ return this.loadManyByQuery(undefined, options);
76
+ }
77
+ async *loadAllCursor(options) {
78
+ const entities = await this.loadAll(options);
79
+ yield* entities;
80
+ }
81
+ async count() {
82
+ const dbQuery = this.database
83
+ .select({ count: count() })
84
+ .from(this.schema);
85
+ const [result] = await dbQuery;
86
+ return assertDefinedPass(result).count;
87
+ }
88
+ async countByQuery(query) {
89
+ if (!(query instanceof SQL)) {
90
+ throw new NotSupportedError();
91
+ }
92
+ const dbQuery = this.database
93
+ .select({ count: count() })
94
+ .from(this.schema)
95
+ .where(query);
96
+ const [result] = await dbQuery;
97
+ return assertDefinedPass(result).count;
98
+ }
99
+ async has(id) {
100
+ return this.hasByQuery(eq(this.schema.id, id));
101
+ }
102
+ async hasByQuery(query) {
103
+ // SELECT EXISTS(SELECT 1 FROM contact WHERE id=12) as exists
104
+ if (!(query instanceof SQL)) {
105
+ throw new NotSupportedError();
106
+ }
107
+ const dbQuery = this.database
108
+ .select({
109
+ exists: sql `SELECT EXISTS(SELECT 1 FROM ${this.schema} WHERE ${query})`
110
+ })
111
+ .from(this.schema)
112
+ .where(query);
113
+ const [result] = await dbQuery;
114
+ return assertDefinedPass(result).exists;
115
+ }
116
+ async hasAll(ids) {
117
+ const result = await this.database.execute(sql `SELECT array_agg(id) @> ${ids} AS contains FROM ${this.schema};`);
118
+ return assertDefinedPass(result.rows[0]).contains;
119
+ }
120
+ async insert(_entity) {
121
+ // await this.database.insert(this.schema).values([entity as T]);
9
122
  throw new NotImplementedError();
10
123
  }
11
- }
124
+ };
125
+ EntityRepository = __decorate([
126
+ Singleton()
127
+ ], EntityRepository);
128
+ export { EntityRepository };
@@ -0,0 +1 @@
1
+ export * from './uuid.js';
@@ -0,0 +1 @@
1
+ export * from './uuid.js';
@@ -0,0 +1,11 @@
1
+ import { StringSchema, type SchemaPropertyDecorator, type SchemaPropertyDecoratorOptions } from '../../schema/index.js';
2
+ export type UuidSchemaOptions = {
3
+ defaultRandom?: boolean;
4
+ };
5
+ export declare class UuidSchema extends StringSchema {
6
+ readonly name = "uuid";
7
+ readonly defaultRandom: boolean;
8
+ constructor(options?: UuidSchemaOptions);
9
+ }
10
+ export declare function uuid(options?: UuidSchemaOptions): UuidSchema;
11
+ export declare function Uuid(options?: UuidSchemaOptions & SchemaPropertyDecoratorOptions): SchemaPropertyDecorator;
@@ -0,0 +1,16 @@
1
+ import { Property, StringSchema } from '../../schema/index.js';
2
+ const uuidPattern = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/u;
3
+ export class UuidSchema extends StringSchema {
4
+ name = 'uuid';
5
+ defaultRandom;
6
+ constructor(options) {
7
+ super({ pattern: uuidPattern });
8
+ this.defaultRandom = options?.defaultRandom ?? false;
9
+ }
10
+ }
11
+ export function uuid(options) {
12
+ return new UuidSchema(options);
13
+ }
14
+ export function Uuid(options) {
15
+ return Property(uuid(options), options);
16
+ }
package/orm/types.d.ts CHANGED
@@ -1,8 +1,21 @@
1
+ import type { HasDefault as DrizzleHasDefault, IsPrimaryKey as DrizzleIsPrimaryKey } from 'drizzle-orm';
2
+ import type { boolean, doublePrecision, integer, PgColumnBuilderBase, text, uuid } from 'drizzle-orm/pg-core';
3
+ import type { GetTagMetadata, Tagged, UnwrapTagged } from 'type-fest';
1
4
  import { Integer } from '../schema/index.js';
2
- import type { doublePrecision, integer, uuid } from 'drizzle-orm/pg-core';
3
- import type { Tagged } from 'type-fest';
4
- export declare function Uuid(): PropertyDecorator & MethodDecorator;
5
- export type Uuid<ColumnName extends string> = Tagged<string, 'column', ReturnType<typeof uuid<ColumnName>>>;
6
- export type Integer<ColumnName extends string> = Tagged<number, 'column', ReturnType<typeof integer<ColumnName>>>;
7
- export type DoublePrecision<ColumnName extends string> = Tagged<number, 'column', ReturnType<typeof doublePrecision<ColumnName>>>;
8
- export { Integer };
5
+ import type { Record } from '../types.js';
6
+ import { Uuid } from './schemas/index.js';
7
+ export type IsPrimaryKey<T> = T extends Tagged<unknown, 'column', PgColumnBuilderBase> ? Tagged<UnwrapTagged<T>, 'column', DrizzleIsPrimaryKey<GetTagMetadata<T, 'column'>>> : Tagged<T, 'column', ColumnBuilder<T>>;
8
+ export type HasDefault<T> = T extends Tagged<unknown, 'column', PgColumnBuilderBase> ? Tagged<UnwrapTagged<T>, 'column', DrizzleHasDefault<GetTagMetadata<T, 'column'>>> : Tagged<T, 'column', ColumnBuilder<T>>;
9
+ export type Nested<T extends Record> = Tagged<T, 'column', {
10
+ nested: T;
11
+ }>;
12
+ export type ColumnBuilder<T, ColumnName extends string = never> = T extends Tagged<T, 'column', any> ? GetTagMetadata<T, 'column'> : T extends string ? string extends ColumnName ? ReturnType<typeof text<ColumnName, string, [string, ...string[]]>> : ReturnType<typeof text<string, [string, ...string[]]>> : T extends number ? string extends ColumnName ? ReturnType<typeof doublePrecision<ColumnName>> : ReturnType<typeof doublePrecision> : T extends boolean ? string extends ColumnName ? ReturnType<typeof boolean<ColumnName>> : ReturnType<typeof boolean> : never;
13
+ export type TypeBuilder<T, ColumnName extends string = never> = [
14
+ ColumnName
15
+ ] extends [never] ? T extends Tagged<any, 'column', PgColumnBuilderBase> ? T : T extends infer U ? Tagged<U, 'column', ColumnBuilder<U>> : never : never;
16
+ export type Text = Tagged<string, 'column', ReturnType<typeof text<string, [string, ...string[]]>>>;
17
+ export type Uuid = Tagged<string, 'column', ReturnType<typeof uuid>>;
18
+ export type Integer = Tagged<number, 'column', ReturnType<typeof integer>>;
19
+ export type DoublePrecision = Tagged<number, 'column', ReturnType<typeof doublePrecision>>;
20
+ export type Boolean = Tagged<number, 'column', ReturnType<typeof boolean>>;
21
+ export { Integer, Uuid };
package/orm/types.js CHANGED
@@ -1,6 +1,4 @@
1
1
  /* eslint-disable @typescript-eslint/no-redeclare, @typescript-eslint/naming-convention */
2
- import { createSchemaPropertyDecorator, Integer, string } from '../schema/index.js';
3
- export function Uuid() {
4
- return createSchemaPropertyDecorator({ schema: string() });
5
- }
6
- export { Integer };
2
+ import { Integer } from '../schema/index.js';
3
+ import { Uuid } from './schemas/index.js';
4
+ export { Integer, Uuid };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tstdl/base",
3
- "version": "0.91.28",
3
+ "version": "0.91.31",
4
4
  "author": "Patrick Hein",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -56,6 +56,7 @@
56
56
  "./json-path": "./json-path/index.js",
57
57
  "./jsx": "./jsx/index.js",
58
58
  "./key-value-store": "./key-value-store/index.js",
59
+ "./key-value-store/mongo": "./key-value-store/mongo/index.js",
59
60
  "./lock": "./lock/index.js",
60
61
  "./lock/mongo": "./lock/mongo/index.js",
61
62
  "./lock/web": "./lock/web/index.js",
@@ -125,8 +126,10 @@
125
126
  "@types/mjml": "4.7",
126
127
  "@types/node": "22",
127
128
  "@types/nodemailer": "6.4",
129
+ "@types/pg": "8.11",
128
130
  "@typescript-eslint/eslint-plugin": "7.17",
129
131
  "concurrently": "9.0",
132
+ "drizzle-kit": "0.26",
130
133
  "eslint": "8.57",
131
134
  "eslint-import-resolver-typescript": "3.6",
132
135
  "eslint-plugin-import": "2.31",
@@ -144,14 +147,14 @@
144
147
  "@zxcvbn-ts/language-de": "^3.0",
145
148
  "@zxcvbn-ts/language-en": "^3.0",
146
149
  "chroma-js": "^2.6",
147
- "drizzle-orm": "^0.34",
150
+ "drizzle-orm": "^0.35",
148
151
  "handlebars": "^4.7",
149
152
  "koa": "^2.15",
150
153
  "minio": "^8.0",
151
154
  "mjml": "^4.15",
152
- "mongodb": "^6.9",
155
+ "mongodb": "^6.10",
153
156
  "nodemailer": "^6.9",
154
- "pg": "^8.13",
157
+ "pg": "8.13",
155
158
  "playwright": "^1.48",
156
159
  "preact": "^10.24",
157
160
  "preact-render-to-string": "^6.5",
@@ -1,5 +1,5 @@
1
1
  import type { AbstractConstructor } from '../types.js';
2
- import { ReflectionDataMap } from './reflection-data-map.js';
2
+ import { ContextDataMap } from '../data-structures/context-data-map.js';
3
3
  import type { DecoratorData } from './types.js';
4
4
  export type ReflectionMetadata = TypeMetadata | PropertyMetadata | MethodMetadata | ConstructorParameterMetadata | MethodParameterMetadata;
5
5
  export type MetadataType = 'type' | 'property' | 'method' | 'method-parameter' | 'constructor-parameter';
@@ -15,31 +15,34 @@ export type TypeMetadata = MetadataBase<'type'> & {
15
15
  readonly staticProperties: ReadonlyMap<string | symbol, PropertyMetadata>;
16
16
  readonly methods: ReadonlyMap<string | symbol, MethodMetadata>;
17
17
  readonly staticMethods: ReadonlyMap<string | symbol, MethodMetadata>;
18
- readonly data: ReflectionDataMap;
18
+ readonly data: ContextDataMap;
19
19
  };
20
20
  export type PropertyMetadata = MetadataBase<'property'> & {
21
21
  key: string | symbol;
22
22
  type: AbstractConstructor;
23
23
  isAccessor: boolean;
24
- data: ReflectionDataMap;
24
+ data: ContextDataMap;
25
+ inherited: boolean;
25
26
  };
26
27
  export type MethodMetadata = MetadataBase<'method'> & {
27
28
  parameters: MethodParameterMetadata[];
28
29
  returnType: AbstractConstructor | undefined;
29
- data: ReflectionDataMap;
30
+ data: ContextDataMap;
31
+ inherited: boolean;
30
32
  };
31
33
  export type ConstructorParameterMetadata = MetadataBase<'constructor-parameter'> & {
32
34
  type: AbstractConstructor | undefined;
33
35
  index: number;
34
- data: ReflectionDataMap;
36
+ data: ContextDataMap;
35
37
  };
36
38
  export type MethodParameterMetadata = MetadataBase<'method-parameter'> & {
37
39
  type: AbstractConstructor;
38
40
  index: number;
39
- data: ReflectionDataMap;
41
+ data: ContextDataMap;
40
42
  };
41
43
  export type ParameterMetadata = ConstructorParameterMetadata | MethodParameterMetadata;
42
44
  export declare class ReflectionRegistry {
45
+ #private;
43
46
  private readonly metadataMap;
44
47
  private readonly finalizedTypesSet;
45
48
  constructor();