@uql/core 3.1.0 → 3.1.2
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/CHANGELOG.md +134 -176
- package/README.md +413 -0
- package/package.json +31 -26
- package/dist/package.json +0 -131
- package/src/@types/index.d.ts +0 -1
- package/src/@types/jest.d.ts +0 -6
- package/src/browser/http/bus.spec.ts +0 -22
- package/src/browser/http/bus.ts +0 -17
- package/src/browser/http/http.spec.ts +0 -70
- package/src/browser/http/http.ts +0 -55
- package/src/browser/http/index.ts +0 -2
- package/src/browser/index.ts +0 -4
- package/src/browser/options.spec.ts +0 -37
- package/src/browser/options.ts +0 -18
- package/src/browser/querier/genericClientRepository.spec.ts +0 -105
- package/src/browser/querier/genericClientRepository.ts +0 -49
- package/src/browser/querier/httpQuerier.ts +0 -82
- package/src/browser/querier/index.ts +0 -3
- package/src/browser/querier/querier.util.spec.ts +0 -35
- package/src/browser/querier/querier.util.ts +0 -18
- package/src/browser/type/clientQuerier.ts +0 -45
- package/src/browser/type/clientQuerierPool.ts +0 -5
- package/src/browser/type/clientRepository.ts +0 -22
- package/src/browser/type/index.ts +0 -4
- package/src/browser/type/request.ts +0 -25
- package/src/dialect/abstractDialect.ts +0 -28
- package/src/dialect/abstractSqlDialect-spec.ts +0 -1309
- package/src/dialect/abstractSqlDialect.ts +0 -805
- package/src/dialect/index.ts +0 -3
- package/src/dialect/namingStrategy.spec.ts +0 -52
- package/src/dialect/queryContext.ts +0 -69
- package/src/entity/decorator/definition.spec.ts +0 -736
- package/src/entity/decorator/definition.ts +0 -265
- package/src/entity/decorator/entity.ts +0 -8
- package/src/entity/decorator/field.ts +0 -9
- package/src/entity/decorator/id.ts +0 -9
- package/src/entity/decorator/index.ts +0 -5
- package/src/entity/decorator/relation.spec.ts +0 -41
- package/src/entity/decorator/relation.ts +0 -34
- package/src/entity/index.ts +0 -1
- package/src/express/@types/express.d.ts +0 -8
- package/src/express/@types/index.d.ts +0 -1
- package/src/express/index.ts +0 -2
- package/src/express/querierMiddleware.ts +0 -217
- package/src/express/query.util.spec.ts +0 -40
- package/src/express/query.util.ts +0 -21
- package/src/index.ts +0 -9
- package/src/maria/index.ts +0 -3
- package/src/maria/mariaDialect.spec.ts +0 -207
- package/src/maria/mariaDialect.ts +0 -42
- package/src/maria/mariaQuerierPool.test.ts +0 -23
- package/src/maria/mariadbQuerier.test.ts +0 -23
- package/src/maria/mariadbQuerier.ts +0 -45
- package/src/maria/mariadbQuerierPool.ts +0 -21
- package/src/migrate/cli.ts +0 -301
- package/src/migrate/generator/index.ts +0 -4
- package/src/migrate/generator/mongoSchemaGenerator.spec.ts +0 -112
- package/src/migrate/generator/mongoSchemaGenerator.ts +0 -115
- package/src/migrate/generator/mysqlSchemaGenerator.spec.ts +0 -34
- package/src/migrate/generator/mysqlSchemaGenerator.ts +0 -92
- package/src/migrate/generator/postgresSchemaGenerator.spec.ts +0 -44
- package/src/migrate/generator/postgresSchemaGenerator.ts +0 -127
- package/src/migrate/generator/sqliteSchemaGenerator.spec.ts +0 -33
- package/src/migrate/generator/sqliteSchemaGenerator.ts +0 -81
- package/src/migrate/index.ts +0 -41
- package/src/migrate/introspection/index.ts +0 -4
- package/src/migrate/introspection/mongoIntrospector.spec.ts +0 -75
- package/src/migrate/introspection/mongoIntrospector.ts +0 -47
- package/src/migrate/introspection/mysqlIntrospector.spec.ts +0 -113
- package/src/migrate/introspection/mysqlIntrospector.ts +0 -278
- package/src/migrate/introspection/postgresIntrospector.spec.ts +0 -112
- package/src/migrate/introspection/postgresIntrospector.ts +0 -329
- package/src/migrate/introspection/sqliteIntrospector.spec.ts +0 -112
- package/src/migrate/introspection/sqliteIntrospector.ts +0 -296
- package/src/migrate/migrator-mongo.test.ts +0 -54
- package/src/migrate/migrator.spec.ts +0 -255
- package/src/migrate/migrator.test.ts +0 -94
- package/src/migrate/migrator.ts +0 -719
- package/src/migrate/namingStrategy.spec.ts +0 -22
- package/src/migrate/schemaGenerator-advanced.spec.ts +0 -138
- package/src/migrate/schemaGenerator.spec.ts +0 -190
- package/src/migrate/schemaGenerator.ts +0 -478
- package/src/migrate/storage/databaseStorage.spec.ts +0 -69
- package/src/migrate/storage/databaseStorage.ts +0 -100
- package/src/migrate/storage/index.ts +0 -2
- package/src/migrate/storage/jsonStorage.ts +0 -58
- package/src/migrate/type.ts +0 -1
- package/src/mongo/index.ts +0 -3
- package/src/mongo/mongoDialect.spec.ts +0 -251
- package/src/mongo/mongoDialect.ts +0 -238
- package/src/mongo/mongodbQuerier.test.ts +0 -45
- package/src/mongo/mongodbQuerier.ts +0 -256
- package/src/mongo/mongodbQuerierPool.test.ts +0 -25
- package/src/mongo/mongodbQuerierPool.ts +0 -24
- package/src/mysql/index.ts +0 -3
- package/src/mysql/mysql2Querier.test.ts +0 -20
- package/src/mysql/mysql2Querier.ts +0 -49
- package/src/mysql/mysql2QuerierPool.test.ts +0 -20
- package/src/mysql/mysql2QuerierPool.ts +0 -21
- package/src/mysql/mysqlDialect.spec.ts +0 -20
- package/src/mysql/mysqlDialect.ts +0 -16
- package/src/namingStrategy/defaultNamingStrategy.ts +0 -18
- package/src/namingStrategy/index.spec.ts +0 -36
- package/src/namingStrategy/index.ts +0 -2
- package/src/namingStrategy/snakeCaseNamingStrategy.ts +0 -15
- package/src/options.spec.ts +0 -41
- package/src/options.ts +0 -18
- package/src/postgres/index.ts +0 -3
- package/src/postgres/manual-types.d.ts +0 -4
- package/src/postgres/pgQuerier.test.ts +0 -25
- package/src/postgres/pgQuerier.ts +0 -45
- package/src/postgres/pgQuerierPool.test.ts +0 -28
- package/src/postgres/pgQuerierPool.ts +0 -21
- package/src/postgres/postgresDialect.spec.ts +0 -428
- package/src/postgres/postgresDialect.ts +0 -144
- package/src/querier/abstractQuerier-test.ts +0 -584
- package/src/querier/abstractQuerier.ts +0 -353
- package/src/querier/abstractQuerierPool-test.ts +0 -20
- package/src/querier/abstractQuerierPool.ts +0 -18
- package/src/querier/abstractSqlQuerier-spec.ts +0 -979
- package/src/querier/abstractSqlQuerier-test.ts +0 -21
- package/src/querier/abstractSqlQuerier.ts +0 -138
- package/src/querier/decorator/index.ts +0 -3
- package/src/querier/decorator/injectQuerier.spec.ts +0 -74
- package/src/querier/decorator/injectQuerier.ts +0 -45
- package/src/querier/decorator/serialized.spec.ts +0 -98
- package/src/querier/decorator/serialized.ts +0 -13
- package/src/querier/decorator/transactional.spec.ts +0 -240
- package/src/querier/decorator/transactional.ts +0 -56
- package/src/querier/index.ts +0 -4
- package/src/repository/genericRepository.spec.ts +0 -111
- package/src/repository/genericRepository.ts +0 -74
- package/src/repository/index.ts +0 -1
- package/src/sqlite/index.ts +0 -3
- package/src/sqlite/manual-types.d.ts +0 -4
- package/src/sqlite/sqliteDialect.spec.ts +0 -155
- package/src/sqlite/sqliteDialect.ts +0 -76
- package/src/sqlite/sqliteQuerier.spec.ts +0 -36
- package/src/sqlite/sqliteQuerier.test.ts +0 -21
- package/src/sqlite/sqliteQuerier.ts +0 -37
- package/src/sqlite/sqliteQuerierPool.test.ts +0 -12
- package/src/sqlite/sqliteQuerierPool.ts +0 -38
- package/src/test/entityMock.ts +0 -375
- package/src/test/index.ts +0 -3
- package/src/test/it.util.ts +0 -69
- package/src/test/spec.util.ts +0 -57
- package/src/type/entity.ts +0 -218
- package/src/type/index.ts +0 -9
- package/src/type/migration.ts +0 -241
- package/src/type/namingStrategy.ts +0 -17
- package/src/type/querier.ts +0 -143
- package/src/type/querierPool.ts +0 -26
- package/src/type/query.ts +0 -506
- package/src/type/repository.ts +0 -142
- package/src/type/universalQuerier.ts +0 -133
- package/src/type/utility.ts +0 -21
- package/src/util/dialect.util-extra.spec.ts +0 -96
- package/src/util/dialect.util.spec.ts +0 -23
- package/src/util/dialect.util.ts +0 -134
- package/src/util/index.ts +0 -5
- package/src/util/object.util.spec.ts +0 -29
- package/src/util/object.util.ts +0 -27
- package/src/util/raw.ts +0 -11
- package/src/util/sql.util-extra.spec.ts +0 -17
- package/src/util/sql.util.spec.ts +0 -208
- package/src/util/sql.util.ts +0 -104
- package/src/util/string.util.spec.ts +0 -46
- package/src/util/string.util.ts +0 -35
- package/tsconfig.build.json +0 -5
- package/tsconfig.json +0 -8
|
@@ -1,133 +0,0 @@
|
|
|
1
|
-
import type { IdValue } from './entity.js';
|
|
2
|
-
import type { Query, QueryConflictPaths, QueryOne, QueryOptions, QuerySearch } from './query.js';
|
|
3
|
-
import type { UniversalRepository } from './repository.js';
|
|
4
|
-
import type { Type } from './utility.js';
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* A `querier` allows to interact with the datasource to perform persistence operations on any entity.
|
|
8
|
-
*/
|
|
9
|
-
export interface UniversalQuerier {
|
|
10
|
-
/**
|
|
11
|
-
* obtains the record with the given primary key.
|
|
12
|
-
* @param entity the target entity
|
|
13
|
-
* @param id the primary key value
|
|
14
|
-
* @param q the additional criteria options
|
|
15
|
-
* @return the record
|
|
16
|
-
*/
|
|
17
|
-
findOneById<E>(entity: Type<E>, id: IdValue<E>, q?: QueryOne<E>): Promise<unknown>;
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* obtains the first record matching the given search parameters.
|
|
21
|
-
* @param entity the target entity
|
|
22
|
-
* @param q the criteria options
|
|
23
|
-
* @return the record
|
|
24
|
-
*/
|
|
25
|
-
findOne<E>(entity: Type<E>, q: QueryOne<E>): Promise<unknown>;
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
* obtains the records matching the given search parameters.
|
|
29
|
-
* @param entity the target entity
|
|
30
|
-
* @param q the criteria options
|
|
31
|
-
* @return the records
|
|
32
|
-
*/
|
|
33
|
-
findMany<E>(entity: Type<E>, q: Query<E>): Promise<unknown>;
|
|
34
|
-
|
|
35
|
-
/**
|
|
36
|
-
* obtains the records matching the given search parameters,
|
|
37
|
-
* also counts the number of matches ignoring pagination.
|
|
38
|
-
* @param entity the target entity
|
|
39
|
-
* @param q the criteria options
|
|
40
|
-
* @return the records and the count
|
|
41
|
-
*/
|
|
42
|
-
findManyAndCount<E>(entity: Type<E>, q: Query<E>): Promise<unknown>;
|
|
43
|
-
|
|
44
|
-
/**
|
|
45
|
-
* counts the number of records matching the given search parameters.
|
|
46
|
-
* @param entity the target entity
|
|
47
|
-
* @param q the search options
|
|
48
|
-
* @return the count
|
|
49
|
-
*/
|
|
50
|
-
count<E>(entity: Type<E>, q: QuerySearch<E>): Promise<unknown>;
|
|
51
|
-
|
|
52
|
-
/**
|
|
53
|
-
* inserts a record.
|
|
54
|
-
* @param entity the entity to persist on
|
|
55
|
-
* @param payload the data to be persisted
|
|
56
|
-
* @return the ID
|
|
57
|
-
*/
|
|
58
|
-
insertOne<E>(entity: Type<E>, payload: E): Promise<unknown>;
|
|
59
|
-
|
|
60
|
-
/**
|
|
61
|
-
* Inserts many records.
|
|
62
|
-
* @param entity the entity to persist on
|
|
63
|
-
* @param payload the data to be persisted
|
|
64
|
-
* @return the IDs
|
|
65
|
-
*/
|
|
66
|
-
insertMany?<E>(entity: Type<E>, payload: E[]): Promise<unknown>;
|
|
67
|
-
|
|
68
|
-
/**
|
|
69
|
-
* updates a record partially.
|
|
70
|
-
* @param entity the entity to persist on
|
|
71
|
-
* @param id the primary key of the record to be updated
|
|
72
|
-
* @param payload the data to be persisted
|
|
73
|
-
* @return the number of affected records
|
|
74
|
-
*/
|
|
75
|
-
updateOneById<E>(entity: Type<E>, id: IdValue<E>, payload: E): Promise<unknown>;
|
|
76
|
-
|
|
77
|
-
/**
|
|
78
|
-
* updates many records partially.
|
|
79
|
-
* @param entity the entity to persist on
|
|
80
|
-
* @param q the criteria to look for the records
|
|
81
|
-
* @param payload the data to be persisted
|
|
82
|
-
* @return the number of affected records
|
|
83
|
-
*/
|
|
84
|
-
updateMany?<E>(entity: Type<E>, q: QuerySearch<E>, payload: E): Promise<unknown>;
|
|
85
|
-
|
|
86
|
-
/**
|
|
87
|
-
* Insert or update a record given a search criteria.
|
|
88
|
-
* @param entity the entity to persist on
|
|
89
|
-
* @param conflictPaths the keys to use for the unique search
|
|
90
|
-
* @param payload the data to be persisted
|
|
91
|
-
* @return void
|
|
92
|
-
*/
|
|
93
|
-
upsertOne?<E>(entity: Type<E>, conflictPaths: QueryConflictPaths<E>, payload: E): Promise<unknown>;
|
|
94
|
-
|
|
95
|
-
/**
|
|
96
|
-
* insert or update a record.
|
|
97
|
-
* @param entity the entity to persist on
|
|
98
|
-
* @param payload the data to be persisted
|
|
99
|
-
* @return the ID
|
|
100
|
-
*/
|
|
101
|
-
saveOne<E>(entity: Type<E>, payload: E): Promise<unknown>;
|
|
102
|
-
|
|
103
|
-
/**
|
|
104
|
-
* Insert or update records.
|
|
105
|
-
* @param entity the entity to persist on
|
|
106
|
-
* @param payload the data to be persisted
|
|
107
|
-
* @return the IDs
|
|
108
|
-
*/
|
|
109
|
-
saveMany?<E>(entity: Type<E>, payload: E[]): Promise<unknown>;
|
|
110
|
-
|
|
111
|
-
/**
|
|
112
|
-
* delete or SoftDelete a record.
|
|
113
|
-
* @param entity the entity to persist on
|
|
114
|
-
* @param id the primary key of the record
|
|
115
|
-
* @return the number of affected records
|
|
116
|
-
*/
|
|
117
|
-
deleteOneById<E>(entity: Type<E>, id: IdValue<E>, opts?: QueryOptions): Promise<unknown>;
|
|
118
|
-
|
|
119
|
-
/**
|
|
120
|
-
* delete or SoftDelete records.
|
|
121
|
-
* @param entity the entity to persist on
|
|
122
|
-
* @param q the criteria to look for the records
|
|
123
|
-
* @return the number of affected records
|
|
124
|
-
*/
|
|
125
|
-
deleteMany<E>(entity: Type<E>, q: QuerySearch<E>, opts?: QueryOptions): Promise<unknown>;
|
|
126
|
-
|
|
127
|
-
/**
|
|
128
|
-
* get a repository for the given entity.
|
|
129
|
-
* @param entity the entity to get the repository for
|
|
130
|
-
* @return the repository
|
|
131
|
-
*/
|
|
132
|
-
getRepository<E>(entity: Type<E>): UniversalRepository<E>;
|
|
133
|
-
}
|
package/src/type/utility.ts
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
export type Type<T> = new (...args: unknown[]) => T;
|
|
2
|
-
|
|
3
|
-
export type BooleanLike = boolean | 0 | 1;
|
|
4
|
-
|
|
5
|
-
export type MongoId = {
|
|
6
|
-
toHexString: () => string;
|
|
7
|
-
};
|
|
8
|
-
|
|
9
|
-
export type Scalar = string | number | boolean | bigint | Date | RegExp | Buffer | MongoId;
|
|
10
|
-
|
|
11
|
-
export type ExpandScalar<T> = null | (T extends Date ? Date | string : T);
|
|
12
|
-
|
|
13
|
-
export type Writable<T> = { -readonly [K in keyof T]: T[K] };
|
|
14
|
-
|
|
15
|
-
export type Unpacked<T> = T extends (infer U)[]
|
|
16
|
-
? U
|
|
17
|
-
: T extends (...args: unknown[]) => infer U
|
|
18
|
-
? U
|
|
19
|
-
: T extends Promise<infer U>
|
|
20
|
-
? U
|
|
21
|
-
: T;
|
|
@@ -1,96 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from 'bun:test';
|
|
2
|
-
import { Entity, Field, getMeta, Id, OneToMany } from '../entity/index.js';
|
|
3
|
-
import { QueryRaw } from '../type/index.js';
|
|
4
|
-
import {
|
|
5
|
-
buildSortMap,
|
|
6
|
-
buldQueryWhereAsMap,
|
|
7
|
-
fillOnFields,
|
|
8
|
-
filterFieldKeys,
|
|
9
|
-
filterPersistableRelationKeys,
|
|
10
|
-
filterRelationKeys,
|
|
11
|
-
getFieldCallbackValue,
|
|
12
|
-
isCascadable,
|
|
13
|
-
isSelectingRelations,
|
|
14
|
-
} from './dialect.util.js';
|
|
15
|
-
|
|
16
|
-
@Entity()
|
|
17
|
-
class DialectUser {
|
|
18
|
-
@Id() id?: number;
|
|
19
|
-
@Field({ updatable: false }) readonlyProp?: string;
|
|
20
|
-
@Field({ virtual: new QueryRaw('1') }) virtualProp?: string;
|
|
21
|
-
@Field({ onInsert: () => 'inserted', onUpdate: 'updated' }) callbackProp?: string;
|
|
22
|
-
@OneToMany({ entity: () => DialectPost, mappedBy: 'user', cascade: true }) posts?: DialectPost[];
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
@Entity()
|
|
26
|
-
class DialectPost {
|
|
27
|
-
@Id() id?: number;
|
|
28
|
-
@Field() user?: DialectUser;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
describe('dialect.util', () => {
|
|
32
|
-
const meta = getMeta(DialectUser);
|
|
33
|
-
|
|
34
|
-
it('filterFieldKeys should filter virtual and non-updatable keys', () => {
|
|
35
|
-
const payload = { id: 1, readonlyProp: 'val', virtualProp: 'val', other: 'val' } as DialectUser;
|
|
36
|
-
const insertKeys = filterFieldKeys(meta, payload, 'onInsert');
|
|
37
|
-
expect(insertKeys).toContain('readonlyProp');
|
|
38
|
-
expect(insertKeys).not.toContain('virtualProp');
|
|
39
|
-
|
|
40
|
-
const updateKeys = filterFieldKeys(meta, payload, 'onUpdate');
|
|
41
|
-
expect(updateKeys).not.toContain('readonlyProp');
|
|
42
|
-
expect(updateKeys).not.toContain('virtualProp');
|
|
43
|
-
});
|
|
44
|
-
|
|
45
|
-
it('getFieldCallbackValue should handle functions and constants', () => {
|
|
46
|
-
expect(getFieldCallbackValue(() => 'test')).toBe('test');
|
|
47
|
-
expect(getFieldCallbackValue('constant')).toBe('constant');
|
|
48
|
-
});
|
|
49
|
-
|
|
50
|
-
it('fillOnFields should populate callback fields', () => {
|
|
51
|
-
const payload = { id: 1 } as DialectUser;
|
|
52
|
-
const filled = fillOnFields(meta, { ...payload }, 'onInsert');
|
|
53
|
-
expect(filled[0].callbackProp).toBe('inserted');
|
|
54
|
-
|
|
55
|
-
const updated = fillOnFields(meta, { ...payload }, 'onUpdate');
|
|
56
|
-
expect(updated[0].callbackProp).toBe('updated');
|
|
57
|
-
});
|
|
58
|
-
|
|
59
|
-
it('isCascadable should check action', () => {
|
|
60
|
-
expect(isCascadable('persist', true)).toBe(true);
|
|
61
|
-
expect(isCascadable('persist', false)).toBe(false);
|
|
62
|
-
expect(isCascadable('persist', 'persist')).toBe(true);
|
|
63
|
-
expect(isCascadable('persist', 'delete')).toBe(false);
|
|
64
|
-
});
|
|
65
|
-
|
|
66
|
-
it('filterPersistableRelationKeys should filter by cascade', () => {
|
|
67
|
-
const payload = { posts: [] } as DialectUser;
|
|
68
|
-
const keys = filterPersistableRelationKeys(meta, payload, 'persist');
|
|
69
|
-
expect(keys).toContain('posts');
|
|
70
|
-
});
|
|
71
|
-
|
|
72
|
-
it('filterRelationKeys should return relation keys from select', () => {
|
|
73
|
-
const select = { id: true, posts: true } as import('../type/index.js').QuerySelect<DialectUser>;
|
|
74
|
-
const keys = filterRelationKeys(meta, select);
|
|
75
|
-
expect(keys).toContain('posts');
|
|
76
|
-
expect(keys).not.toContain('id');
|
|
77
|
-
});
|
|
78
|
-
|
|
79
|
-
it('isSelectingRelations should check if any relation is selected', () => {
|
|
80
|
-
expect(isSelectingRelations(meta, { posts: true } as any)).toBe(true);
|
|
81
|
-
expect(isSelectingRelations(meta, { id: true } as any)).toBe(false);
|
|
82
|
-
});
|
|
83
|
-
|
|
84
|
-
it('buildSortMap should handle arrays and objects', () => {
|
|
85
|
-
expect(buildSortMap({ id: 1 } as any)).toEqual({ id: 1 });
|
|
86
|
-
expect(buildSortMap([['id', 1], { field: 'id', sort: -1 }] as any)).toEqual({ id: -1 });
|
|
87
|
-
});
|
|
88
|
-
|
|
89
|
-
it('buldQueryWhereAsMap should handle various types', () => {
|
|
90
|
-
expect(buldQueryWhereAsMap(meta, 123)).toEqual({ id: 123 });
|
|
91
|
-
expect(buldQueryWhereAsMap(meta, [1, 2])).toEqual({ id: [1, 2] });
|
|
92
|
-
const raw = new QueryRaw('test');
|
|
93
|
-
expect(buldQueryWhereAsMap(meta, raw)).toEqual({ $and: [raw] });
|
|
94
|
-
expect(buldQueryWhereAsMap(meta, { id: 1 } as any)).toEqual({ id: 1 });
|
|
95
|
-
});
|
|
96
|
-
});
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
import { expect, it } from 'bun:test';
|
|
2
|
-
import { getMeta } from '../entity/decorator/index.js';
|
|
3
|
-
import { User } from '../test/entityMock.js';
|
|
4
|
-
import { augmentWhere } from './dialect.util.js';
|
|
5
|
-
import { raw } from './raw.js';
|
|
6
|
-
|
|
7
|
-
it('augmentWhere empty', () => {
|
|
8
|
-
const meta = getMeta(User);
|
|
9
|
-
expect(augmentWhere(meta)).toEqual({});
|
|
10
|
-
expect(augmentWhere(meta, {})).toEqual({});
|
|
11
|
-
expect(augmentWhere(meta, {}, {})).toEqual({});
|
|
12
|
-
});
|
|
13
|
-
|
|
14
|
-
it('augmentWhere', () => {
|
|
15
|
-
const meta = getMeta(User);
|
|
16
|
-
expect(augmentWhere(meta, { name: 'a' }, { name: 'b' })).toEqual({ name: 'b' });
|
|
17
|
-
expect(augmentWhere(meta, { name: 'a' }, { id: 1 })).toEqual({ name: 'a', id: 1 });
|
|
18
|
-
expect(augmentWhere(meta, { name: 'a' }, { $and: [1, 2] })).toEqual({ name: 'a', $and: [1, 2] });
|
|
19
|
-
expect(augmentWhere(meta, 1, { $or: [2, 3] })).toEqual({ id: 1, $or: [2, 3] });
|
|
20
|
-
const rawFilter = raw(() => 'a > 1');
|
|
21
|
-
expect(augmentWhere(meta, rawFilter, 1)).toEqual({ $and: [rawFilter], id: 1 });
|
|
22
|
-
expect(augmentWhere(meta, 1, rawFilter)).toEqual({ id: 1, $and: [rawFilter] });
|
|
23
|
-
});
|
package/src/util/dialect.util.ts
DELETED
|
@@ -1,134 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
type CascadeType,
|
|
3
|
-
type EntityMeta,
|
|
4
|
-
type FieldKey,
|
|
5
|
-
type FieldOptions,
|
|
6
|
-
type IdValue,
|
|
7
|
-
type Key,
|
|
8
|
-
type MongoId,
|
|
9
|
-
type OnFieldCallback,
|
|
10
|
-
QueryRaw,
|
|
11
|
-
type QuerySelect,
|
|
12
|
-
type QuerySort,
|
|
13
|
-
type QuerySortMap,
|
|
14
|
-
type QueryWhere,
|
|
15
|
-
type QueryWhereMap,
|
|
16
|
-
type RelationKey,
|
|
17
|
-
} from '../type/index.js';
|
|
18
|
-
import { getKeys } from './object.util.js';
|
|
19
|
-
|
|
20
|
-
export type CallbackKey = keyof Pick<FieldOptions, 'onInsert' | 'onUpdate' | 'onDelete'>;
|
|
21
|
-
|
|
22
|
-
export function filterFieldKeys<E>(meta: EntityMeta<E>, payload: E, callbackKey: CallbackKey): FieldKey<E>[] {
|
|
23
|
-
const persistableKeys = getKeys(payload).filter((key) => {
|
|
24
|
-
const fieldOpts = meta.fields[key as FieldKey<E>];
|
|
25
|
-
return fieldOpts && !fieldOpts.virtual && (callbackKey !== 'onUpdate' || (fieldOpts.updatable ?? true));
|
|
26
|
-
}) as FieldKey<E>[];
|
|
27
|
-
return persistableKeys;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
export function getFieldCallbackValue(val: OnFieldCallback) {
|
|
31
|
-
return typeof val === 'function' ? val() : val;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
export function fillOnFields<E>(meta: EntityMeta<E>, payload: E | E[], callbackKey: CallbackKey): E[] {
|
|
35
|
-
const payloads = Array.isArray(payload) ? payload : [payload];
|
|
36
|
-
const keys = getKeys(meta.fields).filter((key) => meta.fields[key][callbackKey]);
|
|
37
|
-
return payloads.map((it) => {
|
|
38
|
-
for (const key of keys) {
|
|
39
|
-
if (it[key] === undefined) {
|
|
40
|
-
it[key] = getFieldCallbackValue(meta.fields[key][callbackKey]);
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
return it;
|
|
44
|
-
});
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
export function filterPersistableRelationKeys<E>(
|
|
48
|
-
meta: EntityMeta<E>,
|
|
49
|
-
payload: E,
|
|
50
|
-
action: CascadeType,
|
|
51
|
-
): RelationKey<E>[] {
|
|
52
|
-
const keys = getKeys(payload);
|
|
53
|
-
return keys.filter((key) => {
|
|
54
|
-
const relOpts = meta.relations[key as RelationKey<E>];
|
|
55
|
-
return relOpts && isCascadable(action, relOpts.cascade);
|
|
56
|
-
}) as RelationKey<E>[];
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
export function isCascadable(action: CascadeType, configuration?: boolean | CascadeType): boolean {
|
|
60
|
-
if (typeof configuration === 'boolean') {
|
|
61
|
-
return configuration;
|
|
62
|
-
}
|
|
63
|
-
return configuration === action;
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
export function filterRelationKeys<E>(meta: EntityMeta<E>, select: QuerySelect<E>): RelationKey<E>[] {
|
|
67
|
-
const keys = filterPositiveKeys(select);
|
|
68
|
-
return keys.filter((key) => key in meta.relations) as RelationKey<E>[];
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
export function isSelectingRelations<E>(meta: EntityMeta<E>, select: QuerySelect<E>): boolean {
|
|
72
|
-
const keys = filterPositiveKeys(select);
|
|
73
|
-
return keys.some((key) => key in meta.relations);
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
function filterPositiveKeys<E>(select: QuerySelect<E>): Key<E>[] {
|
|
77
|
-
if (Array.isArray(select)) {
|
|
78
|
-
return select as Key<E>[];
|
|
79
|
-
}
|
|
80
|
-
return getKeys(select).filter((key) => select[key]) as Key<E>[];
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
export function buildSortMap<E>(sort: QuerySort<E>): QuerySortMap<E> {
|
|
84
|
-
if (Array.isArray(sort)) {
|
|
85
|
-
return sort.reduce(
|
|
86
|
-
(acc, it) => {
|
|
87
|
-
if (Array.isArray(it)) {
|
|
88
|
-
acc[it[0]] = it[1];
|
|
89
|
-
} else {
|
|
90
|
-
acc[it.field] = it.sort;
|
|
91
|
-
}
|
|
92
|
-
return acc;
|
|
93
|
-
},
|
|
94
|
-
{} as QuerySortMap<E>,
|
|
95
|
-
);
|
|
96
|
-
}
|
|
97
|
-
return sort as QuerySortMap<E>;
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
export function augmentWhere<E>(
|
|
101
|
-
meta: EntityMeta<E>,
|
|
102
|
-
target: QueryWhere<E> = {},
|
|
103
|
-
source: QueryWhere<E> = {},
|
|
104
|
-
): QueryWhere<E> {
|
|
105
|
-
const targetComparison = buldQueryWhereAsMap(meta, target);
|
|
106
|
-
const sourceComparison = buldQueryWhereAsMap(meta, source);
|
|
107
|
-
return {
|
|
108
|
-
...targetComparison,
|
|
109
|
-
...sourceComparison,
|
|
110
|
-
};
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
export function buldQueryWhereAsMap<E>(meta: EntityMeta<E>, filter: QueryWhere<E> = {}): QueryWhereMap<E> {
|
|
114
|
-
if (filter instanceof QueryRaw) {
|
|
115
|
-
return { $and: [filter] } as QueryWhereMap<E>;
|
|
116
|
-
}
|
|
117
|
-
if (isIdValue(filter)) {
|
|
118
|
-
return {
|
|
119
|
-
[meta.id]: filter,
|
|
120
|
-
} as QueryWhereMap<E>;
|
|
121
|
-
}
|
|
122
|
-
return filter as QueryWhereMap<E>;
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
function isIdValue<E>(filter: QueryWhere<E>): filter is IdValue<E> | IdValue<E>[] {
|
|
126
|
-
const type = typeof filter;
|
|
127
|
-
return (
|
|
128
|
-
type === 'string' ||
|
|
129
|
-
type === 'number' ||
|
|
130
|
-
type === 'bigint' ||
|
|
131
|
-
typeof (filter as MongoId).toHexString === 'function' ||
|
|
132
|
-
Array.isArray(filter)
|
|
133
|
-
);
|
|
134
|
-
}
|
package/src/util/index.ts
DELETED
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
import { expect, it } from 'bun:test';
|
|
2
|
-
import { clone, getKeys, hasKeys } from './object.util.js';
|
|
3
|
-
|
|
4
|
-
it('clone', () => {
|
|
5
|
-
expect(clone({})).toEqual({});
|
|
6
|
-
expect(clone({ a: 1 })).toEqual({ a: 1 });
|
|
7
|
-
expect(clone([])).toEqual([]);
|
|
8
|
-
expect(clone([{ a: 1 }])).toEqual([{ a: 1 }]);
|
|
9
|
-
|
|
10
|
-
const source = [{ a: 1 }];
|
|
11
|
-
const cloned = clone(source);
|
|
12
|
-
|
|
13
|
-
expect(cloned[0]).not.toBe(source[0]);
|
|
14
|
-
expect(cloned).not.toBe(source);
|
|
15
|
-
expect(cloned[0]).toEqual(source[0]);
|
|
16
|
-
expect(cloned).toEqual(source);
|
|
17
|
-
});
|
|
18
|
-
|
|
19
|
-
it('hasKeys', () => {
|
|
20
|
-
expect(hasKeys({})).toBe(false);
|
|
21
|
-
expect(hasKeys({ a: 1 })).toBe(true);
|
|
22
|
-
});
|
|
23
|
-
|
|
24
|
-
it('getKeys', () => {
|
|
25
|
-
expect(getKeys(undefined)).toEqual([]);
|
|
26
|
-
expect(getKeys(null)).toEqual([]);
|
|
27
|
-
expect(getKeys({})).toEqual([]);
|
|
28
|
-
expect(getKeys({ a: 1 })).toEqual(['a']);
|
|
29
|
-
});
|
package/src/util/object.util.ts
DELETED
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
import type { FieldKey, FieldOptions } from '../type/index.js';
|
|
2
|
-
|
|
3
|
-
export function clone<T>(value: T): T {
|
|
4
|
-
if (typeof value !== 'object' || value === null) {
|
|
5
|
-
return value;
|
|
6
|
-
}
|
|
7
|
-
if (Array.isArray(value)) {
|
|
8
|
-
return value.map((it) => clone(it)) as unknown as T;
|
|
9
|
-
}
|
|
10
|
-
return { ...value };
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
export function hasKeys<T>(obj: T): boolean {
|
|
14
|
-
return getKeys(obj).length > 0;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
export function getKeys<T>(obj: T): string[] {
|
|
18
|
-
return obj ? Object.keys(obj) : [];
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
export function getFieldKeys<E>(
|
|
22
|
-
fields: {
|
|
23
|
-
[K in FieldKey<E>]?: FieldOptions;
|
|
24
|
-
},
|
|
25
|
-
): FieldKey<E>[] {
|
|
26
|
-
return getKeys(fields).filter((field) => fields[field as FieldKey<E>].eager ?? true) as FieldKey<E>[];
|
|
27
|
-
}
|
package/src/util/raw.ts
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import { QueryRaw, type QueryRawFn, type Scalar } from '../type/index.js';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Allow using any raw value that shouldn't be automatically escaped by the ORM.
|
|
5
|
-
* @param value the raw value
|
|
6
|
-
* @param alias optional alias
|
|
7
|
-
* @returns a QueryRaw instance
|
|
8
|
-
*/
|
|
9
|
-
export function raw(value: Scalar | QueryRawFn, alias?: string): any {
|
|
10
|
-
return new QueryRaw(value, alias);
|
|
11
|
-
}
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from 'bun:test';
|
|
2
|
-
import { obtainAttrsPaths } from './sql.util.js';
|
|
3
|
-
|
|
4
|
-
describe('sql.util extras', () => {
|
|
5
|
-
it('obtainAttrsPaths should handle nested objects with depth', () => {
|
|
6
|
-
const res = obtainAttrsPaths({
|
|
7
|
-
'user.profile.name': 1,
|
|
8
|
-
'user.email': 1,
|
|
9
|
-
user_profile_name: 1,
|
|
10
|
-
});
|
|
11
|
-
expect(res).toEqual({
|
|
12
|
-
'user.profile.name': ['user', 'profile', 'name'],
|
|
13
|
-
'user.email': ['user', 'email'],
|
|
14
|
-
user_profile_name: ['user', 'profile', 'name'],
|
|
15
|
-
});
|
|
16
|
-
});
|
|
17
|
-
});
|