@tstdl/base 0.91.28 → 0.91.30

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 (52) hide show
  1. package/.eslintrc.json +5 -1
  2. package/{reflection/reflection-data-map.d.ts → data-structures/context-data-map.d.ts} +3 -2
  3. package/{reflection/reflection-data-map.js → data-structures/context-data-map.js} +13 -6
  4. package/data-structures/index.d.ts +1 -0
  5. package/data-structures/index.js +1 -0
  6. package/examples/orm/drizzle.config.d.ts +2 -0
  7. package/examples/orm/drizzle.config.js +5 -0
  8. package/examples/orm/schemas.d.ts +3 -0
  9. package/examples/orm/schemas.js +4 -0
  10. package/examples/orm/test.js +10 -0
  11. package/examples/orm/user.model.d.ts +9 -0
  12. package/examples/orm/user.model.js +39 -0
  13. package/key-value-store/index.d.ts +0 -1
  14. package/key-value-store/index.js +0 -1
  15. package/key-value-store/key-value.store.d.ts +9 -10
  16. package/key-value-store/mongo/mongo-key-value.store.js +2 -1
  17. package/orm/database-schema.d.ts +8 -0
  18. package/orm/database-schema.js +13 -0
  19. package/orm/decorators.d.ts +26 -0
  20. package/orm/decorators.js +21 -2
  21. package/orm/drizzle/schema-converter.d.ts +19 -0
  22. package/orm/drizzle/schema-converter.js +116 -0
  23. package/orm/entity.d.ts +6 -2
  24. package/orm/entity.js +6 -6
  25. package/orm/index.d.ts +1 -2
  26. package/orm/index.js +1 -2
  27. package/orm/repository.d.ts +27 -24
  28. package/orm/repository.js +124 -7
  29. package/orm/schemas/index.d.ts +1 -0
  30. package/orm/schemas/index.js +1 -0
  31. package/orm/schemas/uuid.d.ts +11 -0
  32. package/orm/schemas/uuid.js +16 -0
  33. package/orm/types.d.ts +20 -7
  34. package/orm/types.js +3 -5
  35. package/package.json +6 -3
  36. package/reflection/registry.d.ts +9 -6
  37. package/reflection/registry.js +25 -14
  38. package/schema/decorators/types.d.ts +1 -0
  39. package/schema/schema.d.ts +1 -1
  40. package/schema/schemas/number.d.ts +1 -0
  41. package/schema/schemas/number.js +2 -0
  42. package/schema/schemas/string.d.ts +1 -1
  43. package/utils/math.d.ts +11 -1
  44. package/utils/math.js +28 -0
  45. package/utils/string/index.d.ts +1 -0
  46. package/utils/string/index.js +1 -0
  47. package/utils/string/snake-case.d.ts +1 -0
  48. package/utils/string/snake-case.js +4 -0
  49. package/orm/schema-converter.d.ts +0 -99
  50. package/orm/schema-converter.js +0 -74
  51. package/orm/schema.d.ts +0 -3
  52. /package/{orm/schema.js → examples/orm/test.d.ts} +0 -0
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.30",
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
155
  "mongodb": "^6.9",
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();
@@ -1,9 +1,9 @@
1
1
  import { FactoryMap } from '../utils/factory-map.js';
2
2
  import { lazyObject, lazyObjectValue } from '../utils/object/lazy-property.js';
3
3
  import { getDesignType, getParameterTypes, getReturnType } from '../utils/reflection.js';
4
- import { isDefined, isUndefined } from '../utils/type-guards.js';
4
+ import { isDefined, isNotNull, isUndefined } from '../utils/type-guards.js';
5
+ import { ContextDataMap } from '../data-structures/context-data-map.js';
5
6
  import { getDecoratorData } from './decorator-data.js';
6
- import { ReflectionDataMap } from './reflection-data-map.js';
7
7
  export class ReflectionRegistry {
8
8
  metadataMap;
9
9
  finalizedTypesSet;
@@ -17,11 +17,7 @@ export class ReflectionRegistry {
17
17
  getMetadata(type) {
18
18
  const metadata = this.metadataMap.get(type);
19
19
  if (isDefined(metadata) && !this.finalizedTypesSet.has(type)) {
20
- metadata.properties = new Map(metadata.properties);
21
- metadata.staticProperties = new Map(metadata.staticProperties);
22
- metadata.methods = new Map(metadata.methods);
23
- metadata.staticMethods = new Map(metadata.staticMethods);
24
- this.finalizedTypesSet.add(type);
20
+ this.#finalizeMetadata(metadata);
25
21
  }
26
22
  return metadata;
27
23
  }
@@ -73,23 +69,38 @@ export class ReflectionRegistry {
73
69
  }
74
70
  return this.metadataMap.get(type);
75
71
  }
72
+ #finalizeMetadata(metadata) {
73
+ const parentMetadata = isNotNull(metadata.parent) ? reflectionRegistry.getMetadata(metadata.parent) : undefined;
74
+ metadata.properties = new Map([...getInheritedMetadataEntries(parentMetadata?.properties), ...metadata.properties]);
75
+ metadata.staticProperties = new Map([...getInheritedMetadataEntries(parentMetadata?.staticProperties), ...metadata.staticProperties]);
76
+ metadata.methods = new Map([...getInheritedMetadataEntries(parentMetadata?.methods), ...metadata.methods]);
77
+ metadata.staticMethods = new Map([...getInheritedMetadataEntries(parentMetadata?.staticMethods), ...metadata.staticMethods]);
78
+ this.finalizedTypesSet.add(metadata.constructor);
79
+ }
80
+ }
81
+ function getInheritedMetadataEntries(metadata) {
82
+ return [...(metadata ?? [])].map(([key, value]) => [key, toInheritedMetadata(value)]);
83
+ }
84
+ function toInheritedMetadata(metadata) {
85
+ return { ...metadata, inherited: true };
76
86
  }
77
87
  function initializeType(type) {
88
+ const parent = Reflect.getPrototypeOf(type);
78
89
  return lazyObject({
79
90
  metadataType: 'type',
80
91
  constructor: lazyObjectValue(type),
81
- parent: lazyObjectValue(Reflect.getPrototypeOf(type)),
92
+ parent: lazyObjectValue(parent),
82
93
  parameters: {
83
94
  initializer() {
84
95
  const parametersTypes = getParameterTypes(type);
85
- return parametersTypes?.map((parameterType, index) => ({ metadataType: 'constructor-parameter', index, type: parameterType, data: new ReflectionDataMap() }));
96
+ return parametersTypes?.map((parameterType, index) => ({ metadataType: 'constructor-parameter', index, type: parameterType, data: new ContextDataMap() }));
86
97
  }
87
98
  },
88
99
  properties: {
89
- initializer: () => new FactoryMap((key) => ({ metadataType: 'property', key, type: getDesignType(type.prototype, key), isAccessor: false, data: new ReflectionDataMap() }))
100
+ initializer: () => new FactoryMap((key) => ({ metadataType: 'property', key, type: getDesignType(type.prototype, key), isAccessor: false, data: new ContextDataMap(), inherited: false }))
90
101
  },
91
102
  staticProperties: {
92
- initializer: () => new FactoryMap((key) => ({ metadataType: 'property', key, type: getDesignType(type, key), isAccessor: false, data: new ReflectionDataMap() }))
103
+ initializer: () => new FactoryMap((key) => ({ metadataType: 'property', key, type: getDesignType(type, key), isAccessor: false, data: new ContextDataMap(), inherited: false }))
93
104
  },
94
105
  methods: {
95
106
  initializer: () => new FactoryMap((key) => {
@@ -98,7 +109,7 @@ function initializeType(type) {
98
109
  if (isUndefined(parameters)) {
99
110
  throw new Error(`Could not get parameters for method ${key.toString()} of type ${type.name}`);
100
111
  }
101
- return { metadataType: 'method', parameters: parameters.map((parameter, index) => ({ metadataType: 'method-parameter', index, type: parameter, data: new ReflectionDataMap() })), returnType, data: new ReflectionDataMap() };
112
+ return { metadataType: 'method', parameters: parameters.map((parameter, index) => ({ metadataType: 'method-parameter', index, type: parameter, data: new ContextDataMap() })), returnType, data: new ContextDataMap(), inherited: false };
102
113
  })
103
114
  },
104
115
  staticMethods: {
@@ -108,10 +119,10 @@ function initializeType(type) {
108
119
  if (isUndefined(parameters)) {
109
120
  throw new Error(`Could not get parameters for static method ${key.toString()} of type ${type.name}`);
110
121
  }
111
- return { metadataType: 'method', parameters: parameters.map((parameter, index) => ({ metadataType: 'method-parameter', index, type: parameter, data: new ReflectionDataMap() })), returnType, data: new ReflectionDataMap() };
122
+ return { metadataType: 'method', parameters: parameters.map((parameter, index) => ({ metadataType: 'method-parameter', index, type: parameter, data: new ContextDataMap() })), returnType, data: new ContextDataMap(), inherited: false };
112
123
  })
113
124
  },
114
- data: { initializer: () => new ReflectionDataMap() }
125
+ data: { initializer: () => new ContextDataMap() }
115
126
  });
116
127
  }
117
128
  export const reflectionRegistry = new ReflectionRegistry();
@@ -11,4 +11,5 @@ export type SchemaPropertyReflectionData = {
11
11
  array?: boolean;
12
12
  optional?: boolean;
13
13
  nullable?: boolean;
14
+ data?: Record<PropertyKey, any>;
14
15
  };
@@ -23,8 +23,8 @@ export type SchemaTestable<T = unknown> = Schema<T> | AbstractConstructor<T> | N
23
23
  export type SchemaOutput<T extends SchemaTestable> = T extends SchemaTestable<infer U> ? U : never;
24
24
  export declare const OPTIONAL: unique symbol;
25
25
  export declare abstract class Schema<T = unknown> {
26
- abstract readonly name: string;
27
26
  readonly [OPTIONAL]: boolean;
27
+ abstract readonly name: string;
28
28
  /**
29
29
  * Test an unknown value to see whether it corresponds to the schema.
30
30
  * @param schema schema to test against
@@ -5,6 +5,7 @@ export type NumberSchemaOptions = SimpleSchemaOptions & {
5
5
  };
6
6
  export declare class NumberSchema extends SimpleSchema<number> {
7
7
  readonly name = "number";
8
+ readonly integer: boolean;
8
9
  constructor(options?: NumberSchemaOptions);
9
10
  }
10
11
  export declare function number(options?: NumberSchemaOptions): NumberSchema;
@@ -4,6 +4,7 @@ import { SchemaError } from '../schema.error.js';
4
4
  import { SimpleSchema } from './simple.js';
5
5
  export class NumberSchema extends SimpleSchema {
6
6
  name = 'number';
7
+ integer;
7
8
  constructor(options) {
8
9
  super('number', isNumber, options, {
9
10
  coercers: {
@@ -20,6 +21,7 @@ export class NumberSchema extends SimpleSchema {
20
21
  (options?.integer == true) ? (value) => globalThis.Number.isInteger(value) ? ({ success: true }) : ({ success: false, error: 'value is not an integer.' }) : null
21
22
  ]
22
23
  });
24
+ this.integer = options?.integer ?? false;
23
25
  }
24
26
  }
25
27
  export function number(options) {
@@ -4,7 +4,7 @@ export type StringSchemaOptions = SimpleSchemaOptions & {
4
4
  pattern?: RegExp | string;
5
5
  };
6
6
  export declare class StringSchema extends SimpleSchema<string> {
7
- readonly name = "string";
7
+ readonly name: string;
8
8
  constructor(options?: StringSchemaOptions);
9
9
  }
10
10
  export declare function string(options?: StringSchemaOptions): StringSchema;
package/utils/math.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import type { RandomNumberGeneratorFn } from '../random/number-generator/random-number-generator-function.js';
1
+ import { type RandomNumberGeneratorFn } from '../random/number-generator/random-number-generator-function.js';
2
2
  /**
3
3
  * Generate a random float in interval [min, max).
4
4
  * @param min minimum value
@@ -81,3 +81,13 @@ export declare function clamp(value: number, minimum: number, maximum: number):
81
81
  * @returns nth-root of base
82
82
  */
83
83
  export declare function nthRoot(base: number, root: number): number;
84
+ /**
85
+ *
86
+ * @param t Time in interval [0, 1]
87
+ * @param attenuationExponentStart Sensible values are between 1 (linear attenuation) and ~10 (no attenuation until t = ~0.9, then sharply increasing attenuation)
88
+ * @param attenuationExponentEnd Sensible values are between 1 (linear attenuation) and ~10 (no attenuation until t = ~0.9, then sharply increasing attenuation)
89
+ * @param deadzoneWidthStart Deadzone width to add in front of 0.5. Sensible values are between 0 and 0.5
90
+ * @param deadzoneWidthEnd Deadzone width to add to interval [0.5, 1]. Sensible values are between 0 and 0.5
91
+ * @returns Coefficient in interval [0, 1]
92
+ */
93
+ export declare function getAttenuationCoefficient(t: number, attenuationExponentStart: number | null, attenuationExponentEnd: number | null, deadzoneWidthStart?: number, deadzoneWidthEnd?: number): number;
package/utils/math.js CHANGED
@@ -1,5 +1,6 @@
1
1
  import { NotSupportedError } from '../errors/not-supported.error.js';
2
2
  import { defaultRandomNumberGeneratorFn } from '../random/number-generator/random-number-generator-function.js';
3
+ import { isNull } from './type-guards.js';
3
4
  /**
4
5
  * Generate a random float in interval [min, max).
5
6
  * @param min minimum value
@@ -111,3 +112,30 @@ export function clamp(value, minimum, maximum) {
111
112
  export function nthRoot(base, root) {
112
113
  return (base < 0) ? -((-base) ** (1 / root)) : (base ** (1 / root));
113
114
  }
115
+ /**
116
+ *
117
+ * @param t Time in interval [0, 1]
118
+ * @param attenuationExponentStart Sensible values are between 1 (linear attenuation) and ~10 (no attenuation until t = ~0.9, then sharply increasing attenuation)
119
+ * @param attenuationExponentEnd Sensible values are between 1 (linear attenuation) and ~10 (no attenuation until t = ~0.9, then sharply increasing attenuation)
120
+ * @param deadzoneWidthStart Deadzone width to add in front of 0.5. Sensible values are between 0 and 0.5
121
+ * @param deadzoneWidthEnd Deadzone width to add to interval [0.5, 1]. Sensible values are between 0 and 0.5
122
+ * @returns Coefficient in interval [0, 1]
123
+ */
124
+ export function getAttenuationCoefficient(t, attenuationExponentStart, attenuationExponentEnd, deadzoneWidthStart = 0, deadzoneWidthEnd = 0) {
125
+ if ((t < 0) || (t > 1)) {
126
+ return 0;
127
+ }
128
+ if (t <= 0.5) {
129
+ if (isNull(attenuationExponentStart)) {
130
+ return 1;
131
+ }
132
+ if (t >= (0.5 - deadzoneWidthStart)) {
133
+ return 1;
134
+ }
135
+ return 1 - (-2 * (t - (0.5 - deadzoneWidthStart)) * (0.5 / (0.5 - deadzoneWidthStart))) ** (attenuationExponentStart ** 1.5);
136
+ }
137
+ if (isNull(attenuationExponentEnd) || (t <= (0.5 + deadzoneWidthEnd))) {
138
+ return 1;
139
+ }
140
+ return 1 - (-2 * (-(t - 1) - (0.5 - deadzoneWidthEnd)) * (0.5 / (0.5 - deadzoneWidthEnd))) ** (attenuationExponentEnd ** 1.5);
141
+ }
@@ -1,3 +1,4 @@
1
1
  export * from './hypenate.js';
2
+ export * from './snake-case.js';
2
3
  export * from './title-case.js';
3
4
  export * from './trim.js';
@@ -1,3 +1,4 @@
1
1
  export * from './hypenate.js';
2
+ export * from './snake-case.js';
2
3
  export * from './title-case.js';
3
4
  export * from './trim.js';
@@ -0,0 +1 @@
1
+ export declare function toSnakeCase(value: string): string;
@@ -0,0 +1,4 @@
1
+ const pattern = /(?=[A-Z])/u; // eslint-disable-line prefer-named-capture-group
2
+ export function toSnakeCase(value) {
3
+ return value.split(pattern).join('_').toLowerCase();
4
+ }
@@ -1,99 +0,0 @@
1
- import { boolean, doublePrecision, text, type PgTableWithColumns } from 'drizzle-orm/pg-core';
2
- import type { GetTagMetadata, SnakeCase, Tagged } from 'type-fest';
3
- import type { Type } from '../types.js';
4
- import { BuildColumns, NotNull } from 'drizzle-orm';
5
- import type { DbSchemaStatic } from './schema.js';
6
- import { Integer } from './types.js';
7
- export declare const mySchema: import("drizzle-orm/pg-core").PgSchema<"my_schema">;
8
- export declare const colors: import("drizzle-orm/pg-core").PgEnum<["red", "green", "blue"]>;
9
- export declare const mySchemaUsers: PgTableWithColumns<{
10
- name: "users";
11
- schema: "my_schema";
12
- columns: {
13
- id: import("drizzle-orm/pg-core").PgColumn<{
14
- name: "id";
15
- tableName: "users";
16
- dataType: "string";
17
- columnType: "PgUUID";
18
- data: string;
19
- driverParam: string;
20
- notNull: false;
21
- hasDefault: false;
22
- isPrimaryKey: false;
23
- isAutoincrement: false;
24
- hasRuntimeDefault: false;
25
- enumValues: undefined;
26
- baseColumn: never;
27
- generated: undefined;
28
- }, {}, {}>;
29
- name: import("drizzle-orm/pg-core").PgColumn<{
30
- name: "name";
31
- tableName: "users";
32
- dataType: "string";
33
- columnType: "PgText";
34
- data: string;
35
- driverParam: string;
36
- notNull: false;
37
- hasDefault: false;
38
- isPrimaryKey: false;
39
- isAutoincrement: false;
40
- hasRuntimeDefault: false;
41
- enumValues: [string, ...string[]];
42
- baseColumn: never;
43
- generated: undefined;
44
- }, {}, {}>;
45
- age: import("drizzle-orm/pg-core").PgColumn<{
46
- name: "age";
47
- tableName: "users";
48
- dataType: "number";
49
- columnType: "PgInteger";
50
- data: number;
51
- driverParam: string | number;
52
- notNull: false;
53
- hasDefault: false;
54
- isPrimaryKey: false;
55
- isAutoincrement: false;
56
- hasRuntimeDefault: false;
57
- enumValues: undefined;
58
- baseColumn: never;
59
- generated: undefined;
60
- }, {}, {}>;
61
- color: import("drizzle-orm/pg-core").PgColumn<{
62
- name: "color";
63
- tableName: "users";
64
- dataType: "string";
65
- columnType: "PgEnumColumn";
66
- data: "red" | "green" | "blue";
67
- driverParam: string;
68
- notNull: false;
69
- hasDefault: true;
70
- isPrimaryKey: false;
71
- isAutoincrement: false;
72
- hasRuntimeDefault: false;
73
- enumValues: ["red", "green", "blue"];
74
- baseColumn: never;
75
- generated: undefined;
76
- }, {}, {}>;
77
- };
78
- dialect: "pg";
79
- }>;
80
- type ColumnBase<Name extends string, T> = T extends Tagged<T, 'column', any> ? GetTagMetadata<T, 'column'> : T extends string ? ReturnType<typeof text<Name, string, [string, ...string[]]>> : T extends number ? ReturnType<typeof doublePrecision<Name>> : T extends boolean ? ReturnType<typeof boolean<Name>> : never;
81
- type Column<Name extends string, T> = null extends T ? ColumnBase<Name, T> : NotNull<ColumnBase<Name, T>>;
82
- export declare function getDrizzleSchemaFromType<T extends Type & DbSchemaStatic>(type: T): PgTableWithColumns<{
83
- name: SnakeCase<T['entityName']>;
84
- schema: '';
85
- columns: BuildColumns<T['entityName'], {
86
- [P in keyof InstanceType<T>]: Column<Extract<P, string>, InstanceType<T>[P]>;
87
- }, 'pg'>;
88
- dialect: '';
89
- }>;
90
- export declare class Entity2 {
91
- id: string;
92
- }
93
- export declare class User extends Entity2 {
94
- static entityName: 'UserData';
95
- name: string;
96
- age: Integer<'age'> | null;
97
- hasAge: boolean;
98
- }
99
- export {};