@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.
- package/.eslintrc.json +5 -1
- package/{reflection/reflection-data-map.d.ts → data-structures/context-data-map.d.ts} +3 -2
- package/{reflection/reflection-data-map.js → data-structures/context-data-map.js} +13 -6
- package/data-structures/index.d.ts +1 -0
- package/data-structures/index.js +1 -0
- package/examples/orm/drizzle.config.d.ts +2 -0
- package/examples/orm/drizzle.config.js +5 -0
- package/examples/orm/schemas.d.ts +3 -0
- package/examples/orm/schemas.js +4 -0
- package/examples/orm/test.js +10 -0
- package/examples/orm/user.model.d.ts +9 -0
- package/examples/orm/user.model.js +39 -0
- package/key-value-store/index.d.ts +0 -1
- package/key-value-store/index.js +0 -1
- package/key-value-store/key-value.store.d.ts +9 -10
- package/key-value-store/mongo/mongo-key-value.store.js +2 -1
- package/orm/database-schema.d.ts +8 -0
- package/orm/database-schema.js +13 -0
- package/orm/decorators.d.ts +26 -0
- package/orm/decorators.js +21 -2
- package/orm/drizzle/schema-converter.d.ts +19 -0
- package/orm/drizzle/schema-converter.js +116 -0
- package/orm/entity.d.ts +6 -2
- package/orm/entity.js +6 -6
- package/orm/index.d.ts +1 -2
- package/orm/index.js +1 -2
- package/orm/repository.d.ts +27 -24
- package/orm/repository.js +124 -7
- package/orm/schemas/index.d.ts +1 -0
- package/orm/schemas/index.js +1 -0
- package/orm/schemas/uuid.d.ts +11 -0
- package/orm/schemas/uuid.js +16 -0
- package/orm/types.d.ts +20 -7
- package/orm/types.js +3 -5
- package/package.json +6 -3
- package/reflection/registry.d.ts +9 -6
- package/reflection/registry.js +25 -14
- package/schema/decorators/types.d.ts +1 -0
- package/schema/schema.d.ts +1 -1
- package/schema/schemas/number.d.ts +1 -0
- package/schema/schemas/number.js +2 -0
- package/schema/schemas/string.d.ts +1 -1
- package/utils/math.d.ts +11 -1
- package/utils/math.js +28 -0
- package/utils/string/index.d.ts +1 -0
- package/utils/string/index.js +1 -0
- package/utils/string/snake-case.d.ts +1 -0
- package/utils/string/snake-case.js +4 -0
- package/orm/schema-converter.d.ts +0 -99
- package/orm/schema-converter.js +0 -74
- package/orm/schema.d.ts +0 -3
- /package/{orm/schema.js → examples/orm/test.d.ts} +0 -0
package/orm/repository.js
CHANGED
|
@@ -1,11 +1,128 @@
|
|
|
1
|
-
|
|
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
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
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 {
|
|
3
|
-
import
|
|
4
|
-
export
|
|
5
|
-
export type
|
|
6
|
-
export type
|
|
7
|
-
|
|
8
|
-
|
|
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 {
|
|
3
|
-
|
|
4
|
-
|
|
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.
|
|
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.
|
|
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": "
|
|
157
|
+
"pg": "8.13",
|
|
155
158
|
"playwright": "^1.48",
|
|
156
159
|
"preact": "^10.24",
|
|
157
160
|
"preact-render-to-string": "^6.5",
|
package/reflection/registry.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { AbstractConstructor } from '../types.js';
|
|
2
|
-
import {
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
36
|
+
data: ContextDataMap;
|
|
35
37
|
};
|
|
36
38
|
export type MethodParameterMetadata = MetadataBase<'method-parameter'> & {
|
|
37
39
|
type: AbstractConstructor;
|
|
38
40
|
index: number;
|
|
39
|
-
data:
|
|
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();
|
package/reflection/registry.js
CHANGED
|
@@ -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
|
-
|
|
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(
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
125
|
+
data: { initializer: () => new ContextDataMap() }
|
|
115
126
|
});
|
|
116
127
|
}
|
|
117
128
|
export const reflectionRegistry = new ReflectionRegistry();
|
package/schema/schema.d.ts
CHANGED
|
@@ -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;
|
package/schema/schemas/number.js
CHANGED
|
@@ -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
|
|
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
|
|
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
|
+
}
|
package/utils/string/index.d.ts
CHANGED
package/utils/string/index.js
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function toSnakeCase(value: string): string;
|
|
@@ -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 {};
|