akanjs 3.0.0-alpha.2 → 3.0.0-alpha.3
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/document/database.ts +21 -0
- package/document/filterMeta.ts +7 -0
- package/document/into.ts +5 -1
- package/package.json +1 -1
- package/server/resolver/database.resolver.ts +34 -1
- package/server/resolver/service.resolver.ts +29 -0
- package/service/predefinedAdaptor/database.adaptor.ts +8 -0
- package/service/serviceModule.ts +17 -0
- package/service/types.ts +4 -0
- package/types/document/database.d.ts +20 -0
- package/types/document/filterMeta.d.ts +1 -0
- package/types/document/into.d.ts +4 -1
- package/types/service/predefinedAdaptor/database.adaptor.d.ts +12 -0
- package/types/service/types.d.ts +4 -1
package/document/database.ts
CHANGED
|
@@ -3,6 +3,7 @@ import { Logger } from "akanjs/common";
|
|
|
3
3
|
import type { DocumentModel, QueryOf } from "akanjs/constant";
|
|
4
4
|
import type { CacheAdaptor, CacheSetOptions } from "akanjs/service";
|
|
5
5
|
import type { DataLoader } from "./dataLoader";
|
|
6
|
+
import type { DocumentUpdateInput } from "./documentQuery";
|
|
6
7
|
import type { ExtractQuery, ExtractSort, FilterInstance } from "./filterMeta";
|
|
7
8
|
import type { CRUDEventType, Mdl, SaveEventType, UpdateResult } from "./into";
|
|
8
9
|
import type { DataInputOf, FindQueryOption, ListQueryOption } from "./types";
|
|
@@ -25,6 +26,15 @@ export class CacheDatabase<T = unknown> {
|
|
|
25
26
|
await this.cache.delete(this.refName, `${topic}:${key}`);
|
|
26
27
|
}
|
|
27
28
|
}
|
|
29
|
+
/**
|
|
30
|
+
* What `update<Filter>` returns. The patch cannot be a trailing parameter — a filter's own args may be optional,
|
|
31
|
+
* and no tuple type puts a required element after those — and leading it reads backwards. So it lands here, on a
|
|
32
|
+
* terminal `.set()` that mirrors the `UPDATE … SET …` it compiles to.
|
|
33
|
+
*/
|
|
34
|
+
export interface UpdateChain<Doc = any> {
|
|
35
|
+
set(update: DocumentUpdateInput<Doc>): Promise<UpdateResult>;
|
|
36
|
+
}
|
|
37
|
+
|
|
28
38
|
type QueryMethodOfKey<
|
|
29
39
|
CapitalizedK extends string,
|
|
30
40
|
Doc,
|
|
@@ -53,6 +63,14 @@ type QueryMethodOfKey<
|
|
|
53
63
|
[K in `insight${CapitalizedK}`]: (...args: _Args) => Promise<Insight>;
|
|
54
64
|
} & {
|
|
55
65
|
[K in `query${CapitalizedK}`]: (...args: _Args) => _QueryOfDoc;
|
|
66
|
+
} & {
|
|
67
|
+
[K in `remove${CapitalizedK}`]: (...args: _Args) => Promise<UpdateResult>;
|
|
68
|
+
} & {
|
|
69
|
+
[K in `removeOne${CapitalizedK}`]: (...args: _Args) => Promise<UpdateResult>;
|
|
70
|
+
} & {
|
|
71
|
+
[K in `update${CapitalizedK}`]: (...args: _Args) => UpdateChain<Doc>;
|
|
72
|
+
} & {
|
|
73
|
+
[K in `updateOne${CapitalizedK}`]: (...args: _Args) => UpdateChain<Doc>;
|
|
56
74
|
};
|
|
57
75
|
type QueryMethodMap<Query, Doc, Insight, _FindQueryOption, _ListQueryOption, _QueryOfDoc> = {
|
|
58
76
|
[K in keyof Query]: K extends string
|
|
@@ -106,6 +124,9 @@ type DatabaseModelWithQuerySort<
|
|
|
106
124
|
__update: (id: string, data: Partial<Doc>) => Promise<Doc>;
|
|
107
125
|
__remove: (id: string) => Promise<Doc>;
|
|
108
126
|
__removeMany: (query: _QueryOfDoc) => Promise<UpdateResult>;
|
|
127
|
+
__removeOne: (query: _QueryOfDoc) => Promise<UpdateResult>;
|
|
128
|
+
__updateMany: (query: _QueryOfDoc, update: DocumentUpdateInput<Doc>) => Promise<UpdateResult>;
|
|
129
|
+
__updateOne: (query: _QueryOfDoc, update: DocumentUpdateInput<Doc>) => Promise<UpdateResult>;
|
|
109
130
|
__list(query: _QueryOfDoc, queryOption?: _ListQueryOption): Promise<Doc[]>;
|
|
110
131
|
__listIds(query: _QueryOfDoc, queryOption?: _ListQueryOption): Promise<string[]>;
|
|
111
132
|
__find(query: _QueryOfDoc, queryOption?: _FindQueryOption): Promise<Doc | null>;
|
package/document/filterMeta.ts
CHANGED
|
@@ -98,6 +98,13 @@ export const fillMissingFilterArgs = (filterInfo: FilterInfo, args: unknown[]) =
|
|
|
98
98
|
return [...args, ...Array(filterInfo.args.length - args.length).fill(undefined)];
|
|
99
99
|
};
|
|
100
100
|
|
|
101
|
+
export const assertFilterFitsCrud = (refName: string, queryKey: string, className: string) => {
|
|
102
|
+
if (queryKey.toLowerCase() !== refName.toLowerCase()) return;
|
|
103
|
+
throw new Error(
|
|
104
|
+
`Filter "${queryKey}" on "${refName}" generates remove${className}/update${className}, which are the generated CRUD methods; rename the filter`,
|
|
105
|
+
);
|
|
106
|
+
};
|
|
107
|
+
|
|
101
108
|
export type BaseFilterSortKey = "latest" | "oldest" | "relevance";
|
|
102
109
|
export type BaseFilterQueryKey = "any";
|
|
103
110
|
export type BaseFilterKey = BaseFilterSortKey | BaseFilterQueryKey;
|
package/document/into.ts
CHANGED
|
@@ -77,16 +77,20 @@ export type Mdl<
|
|
|
77
77
|
find(query: _RawQuery, projection?: _Projection): FindManyChain<Doc>;
|
|
78
78
|
findOne(query: _RawQuery, projection?: _Projection): FindOneChain<Doc>;
|
|
79
79
|
findById(id: string | undefined, projection?: _Projection): Promise<Doc | null>;
|
|
80
|
-
|
|
80
|
+
count(query: _RawQuery): Promise<number>;
|
|
81
81
|
exists(query: _RawQuery): Promise<string | null>;
|
|
82
|
+
|
|
82
83
|
updateOne(
|
|
83
84
|
query: _RawQuery,
|
|
84
85
|
update: DocumentUpdateInput<_RawDoc>,
|
|
85
86
|
options?: DocumentUpdateOptions,
|
|
86
87
|
): Promise<UpdateResult>;
|
|
87
88
|
updateMany(query: _RawQuery, update: DocumentUpdateInput<_RawDoc>): Promise<UpdateResult>;
|
|
89
|
+
removeOne(query: _RawQuery): Promise<UpdateResult>;
|
|
88
90
|
removeMany(query: _RawQuery): Promise<UpdateResult>;
|
|
89
91
|
bulkWrite(operations: BulkWriteOperation<Raw, _RawDoc, _RawQuery>[]): Promise<UpdateResult>;
|
|
92
|
+
/** @deprecated Renamed to `count`. */
|
|
93
|
+
countDocuments(query: _RawQuery): Promise<number>;
|
|
90
94
|
};
|
|
91
95
|
|
|
92
96
|
interface IntoConstantModel<T extends string, _CapitalizedRefName extends string, Raw, Insight> {
|
package/package.json
CHANGED
|
@@ -2,6 +2,7 @@ import type { PromiseOrObject } from "akanjs/base";
|
|
|
2
2
|
import { applyMixins, capitalize } from "akanjs/common";
|
|
3
3
|
import { type ConstantModel, DEFAULT_PAGE_SIZE, type QueryOf } from "akanjs/constant";
|
|
4
4
|
import {
|
|
5
|
+
assertFilterFitsCrud,
|
|
5
6
|
CacheDatabase,
|
|
6
7
|
type CRUDEventType,
|
|
7
8
|
type DatabaseInstance,
|
|
@@ -20,6 +21,7 @@ import {
|
|
|
20
21
|
type ListQueryOption,
|
|
21
22
|
type Mdl,
|
|
22
23
|
type SaveEventType,
|
|
24
|
+
type UpdateChain,
|
|
23
25
|
} from "akanjs/document";
|
|
24
26
|
import {
|
|
25
27
|
type AdaptorCls,
|
|
@@ -232,11 +234,14 @@ export class DatabaseResolver {
|
|
|
232
234
|
find: (query: QueryOf<any>) => createFindManyChain(query),
|
|
233
235
|
findOne: (query: QueryOf<any>) => createFindOneChain(query),
|
|
234
236
|
findById: (id: string | undefined) => (id ? store.findOne({ id }) : Promise.resolve(null)),
|
|
235
|
-
|
|
237
|
+
count: (query: QueryOf<any>) => store.count(query),
|
|
236
238
|
updateOne: (query: QueryOf<any>, update: DocumentUpdateInput, options?: { upsert?: boolean }) =>
|
|
237
239
|
store.updateOneByQuery(query, update, options),
|
|
238
240
|
updateMany: (query: QueryOf<any>, update: DocumentUpdateInput) => store.updateManyByQuery(query, update),
|
|
241
|
+
removeOne: (query: QueryOf<any>) => store.removeOneByQuery(query),
|
|
239
242
|
removeMany: (query: QueryOf<any>) => store.removeManyByQuery(query),
|
|
243
|
+
|
|
244
|
+
countDocuments: (query: QueryOf<any>) => store.count(query),
|
|
240
245
|
bulkWrite: (
|
|
241
246
|
operations: { updateOne: { filter: QueryOf<any>; update: DocumentUpdateInput; upsert?: boolean } }[],
|
|
242
247
|
) => store.bulkWrite(operations),
|
|
@@ -339,6 +344,15 @@ export class DatabaseResolver {
|
|
|
339
344
|
async __removeMany(query: QueryOf<any>) {
|
|
340
345
|
return await timedQuery(() => this.__store.removeManyByQuery(query));
|
|
341
346
|
}
|
|
347
|
+
async __removeOne(query: QueryOf<any>) {
|
|
348
|
+
return await timedQuery(() => this.__store.removeOneByQuery(query));
|
|
349
|
+
}
|
|
350
|
+
async __updateMany(query: QueryOf<any>, update: DocumentUpdateInput) {
|
|
351
|
+
return await timedQuery(() => this.__store.updateManyByQuery(query, update));
|
|
352
|
+
}
|
|
353
|
+
async __updateOne(query: QueryOf<any>, update: DocumentUpdateInput) {
|
|
354
|
+
return await timedQuery(() => this.__store.updateOneByQuery(query, update));
|
|
355
|
+
}
|
|
342
356
|
async [`remove${className}`](id: string) {
|
|
343
357
|
return this.__remove(id);
|
|
344
358
|
}
|
|
@@ -364,6 +378,7 @@ export class DatabaseResolver {
|
|
|
364
378
|
Object.entries(filterMeta.query).forEach(([queryKey, filterInfo]) => {
|
|
365
379
|
const queryFn = filterInfo.queryFn;
|
|
366
380
|
if (!queryFn) throw new Error(`No query function for key: ${queryKey}`);
|
|
381
|
+
assertFilterFitsCrud(modelName, queryKey, className);
|
|
367
382
|
Object.assign(DatabaseModelInstance.prototype, {
|
|
368
383
|
[`list${capitalize(queryKey)}`]: async function (...args: any) {
|
|
369
384
|
const { query, queryOption } = getQueryDataFromKey(queryKey, args);
|
|
@@ -403,6 +418,24 @@ export class DatabaseResolver {
|
|
|
403
418
|
},
|
|
404
419
|
[`query${capitalize(queryKey)}`]: (...args: any) =>
|
|
405
420
|
queryFn(...fillMissingFilterArgs(filterInfo, args), documentQueryHelper),
|
|
421
|
+
[`remove${capitalize(queryKey)}`]: async function (...args: any) {
|
|
422
|
+
const query = queryFn(...fillMissingFilterArgs(filterInfo, args), documentQueryHelper);
|
|
423
|
+
return (this as unknown as DatabaseInstance).__removeMany(query);
|
|
424
|
+
},
|
|
425
|
+
[`removeOne${capitalize(queryKey)}`]: async function (...args: any) {
|
|
426
|
+
const query = queryFn(...fillMissingFilterArgs(filterInfo, args), documentQueryHelper);
|
|
427
|
+
return (this as unknown as DatabaseInstance).__removeOne(query);
|
|
428
|
+
},
|
|
429
|
+
[`update${capitalize(queryKey)}`]: function (...args: any): UpdateChain {
|
|
430
|
+
const instance = this as unknown as DatabaseInstance;
|
|
431
|
+
const query = queryFn(...fillMissingFilterArgs(filterInfo, args), documentQueryHelper);
|
|
432
|
+
return { set: (update) => instance.__updateMany(query, update) };
|
|
433
|
+
},
|
|
434
|
+
[`updateOne${capitalize(queryKey)}`]: function (...args: any): UpdateChain {
|
|
435
|
+
const instance = this as unknown as DatabaseInstance;
|
|
436
|
+
const query = queryFn(...fillMissingFilterArgs(filterInfo, args), documentQueryHelper);
|
|
437
|
+
return { set: (update) => instance.__updateOne(query, update) };
|
|
438
|
+
},
|
|
406
439
|
});
|
|
407
440
|
});
|
|
408
441
|
applyMixins(DatabaseModelInstance, [database.model]);
|
|
@@ -2,10 +2,12 @@ import type { PromiseOrObject } from "akanjs/base";
|
|
|
2
2
|
import { capitalize } from "akanjs/common";
|
|
3
3
|
import type { QueryOf } from "akanjs/constant";
|
|
4
4
|
import {
|
|
5
|
+
assertFilterFitsCrud,
|
|
5
6
|
type CRUDEventType,
|
|
6
7
|
type DatabaseModel,
|
|
7
8
|
type DataInputOf,
|
|
8
9
|
type Doc,
|
|
10
|
+
type DocumentUpdateInput,
|
|
9
11
|
documentQueryHelper,
|
|
10
12
|
type FindQueryOption,
|
|
11
13
|
fillMissingFilterArgs,
|
|
@@ -13,6 +15,7 @@ import {
|
|
|
13
15
|
getFilterMeta,
|
|
14
16
|
type ListQueryOption,
|
|
15
17
|
type SaveEventType,
|
|
18
|
+
type UpdateChain,
|
|
16
19
|
} from "akanjs/document";
|
|
17
20
|
import type { DatabaseService, ServiceCls } from "akanjs/service";
|
|
18
21
|
import type { CascadeRunner } from "./CascadeRunner";
|
|
@@ -108,6 +111,15 @@ export class ServiceResolver {
|
|
|
108
111
|
async __removeMany(this: DatabaseService, query: QueryOf<any>) {
|
|
109
112
|
return await this.__databaseModel.__removeMany(query);
|
|
110
113
|
},
|
|
114
|
+
async __removeOne(this: DatabaseService, query: QueryOf<any>) {
|
|
115
|
+
return await this.__databaseModel.__removeOne(query);
|
|
116
|
+
},
|
|
117
|
+
async __updateMany(this: DatabaseService, query: QueryOf<any>, update: DocumentUpdateInput) {
|
|
118
|
+
return await this.__databaseModel.__updateMany(query, update);
|
|
119
|
+
},
|
|
120
|
+
async __updateOne(this: DatabaseService, query: QueryOf<any>, update: DocumentUpdateInput) {
|
|
121
|
+
return await this.__databaseModel.__updateOne(query, update);
|
|
122
|
+
},
|
|
111
123
|
};
|
|
112
124
|
return dbServiceMethods;
|
|
113
125
|
}
|
|
@@ -138,6 +150,7 @@ export class ServiceResolver {
|
|
|
138
150
|
const queryFn = filterInfo.queryFn;
|
|
139
151
|
if (!queryFn) throw new Error(`No query function for key: ${queryKey}`);
|
|
140
152
|
const capitalizedQueryKey = capitalize(queryKey);
|
|
153
|
+
assertFilterFitsCrud(database.refName, queryKey, className);
|
|
141
154
|
Object.assign(srvRef.prototype, {
|
|
142
155
|
[`list${capitalizedQueryKey}`]: async function (this: DatabaseService, ...args: any) {
|
|
143
156
|
const { query, queryOption } = getQueryDataFromKey(queryKey, args);
|
|
@@ -178,6 +191,22 @@ export class ServiceResolver {
|
|
|
178
191
|
[`query${capitalize(queryKey)}`]: function (this: DatabaseService, ...args: any) {
|
|
179
192
|
return queryFn(...fillMissingFilterArgs(filterInfo, args), documentQueryHelper);
|
|
180
193
|
},
|
|
194
|
+
[`remove${capitalizedQueryKey}`]: async function (this: DatabaseService, ...args: any) {
|
|
195
|
+
const { query } = getQueryDataFromKey(queryKey, args);
|
|
196
|
+
return this.__removeMany(query);
|
|
197
|
+
},
|
|
198
|
+
[`removeOne${capitalizedQueryKey}`]: async function (this: DatabaseService, ...args: any) {
|
|
199
|
+
const { query } = getQueryDataFromKey(queryKey, args);
|
|
200
|
+
return this.__removeOne(query);
|
|
201
|
+
},
|
|
202
|
+
[`update${capitalizedQueryKey}`]: function (this: DatabaseService, ...args: any): UpdateChain {
|
|
203
|
+
const { query } = getQueryDataFromKey(queryKey, args);
|
|
204
|
+
return { set: (update) => this.__updateMany(query, update) };
|
|
205
|
+
},
|
|
206
|
+
[`updateOne${capitalizedQueryKey}`]: function (this: DatabaseService, ...args: any): UpdateChain {
|
|
207
|
+
const { query } = getQueryDataFromKey(queryKey, args);
|
|
208
|
+
return { set: (update) => this.__updateOne(query, update) };
|
|
209
|
+
},
|
|
181
210
|
});
|
|
182
211
|
});
|
|
183
212
|
return srvRef;
|
|
@@ -98,6 +98,9 @@ export interface DocumentStore {
|
|
|
98
98
|
removeManyByQuery(
|
|
99
99
|
query: DocumentQuery,
|
|
100
100
|
): Promise<{ acknowledged: boolean; matchedCount: number; modifiedCount: number }>;
|
|
101
|
+
removeOneByQuery(
|
|
102
|
+
query: DocumentQuery,
|
|
103
|
+
): Promise<{ acknowledged: boolean; matchedCount: number; modifiedCount: number; upsertedId: string | null }>;
|
|
101
104
|
bulkWrite(
|
|
102
105
|
operations: { updateOne: { filter: DocumentQuery; update: DocumentUpdateInput; upsert?: boolean } }[],
|
|
103
106
|
): Promise<{ acknowledged: boolean; matchedCount: number; modifiedCount: number; upsertedId: string | null }>;
|
|
@@ -1086,6 +1089,11 @@ export class SqlDocumentStore {
|
|
|
1086
1089
|
return this.updateManyByQuery(query, { removedAt: dayjs() });
|
|
1087
1090
|
}
|
|
1088
1091
|
|
|
1092
|
+
async removeOneByQuery(query: DocumentQuery) {
|
|
1093
|
+
|
|
1094
|
+
return this.updateOneByQuery(query, { removedAt: dayjs() });
|
|
1095
|
+
}
|
|
1096
|
+
|
|
1089
1097
|
private compiledUpdate(update: DocumentUpdate) {
|
|
1090
1098
|
const compiled = this.updateCompiler.compile(update);
|
|
1091
1099
|
return {
|
package/service/serviceModule.ts
CHANGED
|
@@ -9,6 +9,7 @@ import type {
|
|
|
9
9
|
FindQueryOption,
|
|
10
10
|
ListQueryOption,
|
|
11
11
|
SaveEventType,
|
|
12
|
+
UpdateChain,
|
|
12
13
|
} from "akanjs/document";
|
|
13
14
|
import type { ServiceCls } from "./serve";
|
|
14
15
|
import type { DatabaseService } from "./types";
|
|
@@ -210,6 +211,22 @@ export class ServiceModel<
|
|
|
210
211
|
[`query${capitalizedQueryKey}`]: function (this: DatabaseService, ...args: any) {
|
|
211
212
|
return queryFn(...args);
|
|
212
213
|
},
|
|
214
|
+
[`remove${capitalizedQueryKey}`]: async function (this: DatabaseService, ...args: any) {
|
|
215
|
+
const { query } = getQueryDataFromKey(queryKey, args);
|
|
216
|
+
return this.__removeMany(query);
|
|
217
|
+
},
|
|
218
|
+
[`removeOne${capitalizedQueryKey}`]: async function (this: DatabaseService, ...args: any) {
|
|
219
|
+
const { query } = getQueryDataFromKey(queryKey, args);
|
|
220
|
+
return this.__removeOne(query);
|
|
221
|
+
},
|
|
222
|
+
[`update${capitalizedQueryKey}`]: function (this: DatabaseService, ...args: any): UpdateChain {
|
|
223
|
+
const { query } = getQueryDataFromKey(queryKey, args);
|
|
224
|
+
return { set: (update) => this.__updateMany(query, update) };
|
|
225
|
+
},
|
|
226
|
+
[`updateOne${capitalizedQueryKey}`]: function (this: DatabaseService, ...args: any): UpdateChain {
|
|
227
|
+
const { query } = getQueryDataFromKey(queryKey, args);
|
|
228
|
+
return { set: (update) => this.__updateOne(query, update) };
|
|
229
|
+
},
|
|
213
230
|
};
|
|
214
231
|
return filterServiceMethods;
|
|
215
232
|
}
|
package/service/types.ts
CHANGED
|
@@ -5,6 +5,7 @@ import type {
|
|
|
5
5
|
CRUDEventType,
|
|
6
6
|
DatabaseModel,
|
|
7
7
|
DataInputOf,
|
|
8
|
+
DocumentUpdateInput,
|
|
8
9
|
FilterInstance,
|
|
9
10
|
FindQueryOption,
|
|
10
11
|
GetDocObject,
|
|
@@ -103,6 +104,9 @@ export type DatabaseService<
|
|
|
103
104
|
__update: (id: string, data: Partial<Doc>) => Promise<Doc>;
|
|
104
105
|
__remove: (id: string) => Promise<Doc>;
|
|
105
106
|
__removeMany: (query: _QueryOfDoc) => Promise<UpdateResult>;
|
|
107
|
+
__removeOne: (query: _QueryOfDoc) => Promise<UpdateResult>;
|
|
108
|
+
__updateMany: (query: _QueryOfDoc, update: DocumentUpdateInput<Doc>) => Promise<UpdateResult>;
|
|
109
|
+
__updateOne: (query: _QueryOfDoc, update: DocumentUpdateInput<Doc>) => Promise<UpdateResult>;
|
|
106
110
|
__list(query?: _QueryOfDoc, queryOption?: _ListQueryOption): Promise<Doc[]>;
|
|
107
111
|
__listIds(query?: _QueryOfDoc, queryOption?: _ListQueryOption): Promise<string[]>;
|
|
108
112
|
__find(query?: _QueryOfDoc, queryOption?: _FindQueryOption): Promise<Doc | null>;
|
|
@@ -3,6 +3,7 @@ import { Logger } from "akanjs/common";
|
|
|
3
3
|
import type { DocumentModel, QueryOf } from "akanjs/constant";
|
|
4
4
|
import type { CacheAdaptor, CacheSetOptions } from "akanjs/service";
|
|
5
5
|
import type { DataLoader } from "./dataLoader.d.ts";
|
|
6
|
+
import type { DocumentUpdateInput } from "./documentQuery.d.ts";
|
|
6
7
|
import type { ExtractQuery, ExtractSort, FilterInstance } from "./filterMeta.d.ts";
|
|
7
8
|
import type { CRUDEventType, Mdl, SaveEventType, UpdateResult } from "./into.d.ts";
|
|
8
9
|
import type { DataInputOf, FindQueryOption, ListQueryOption } from "./types.d.ts";
|
|
@@ -15,6 +16,14 @@ export declare class CacheDatabase<T = unknown> {
|
|
|
15
16
|
get<T extends string | number | Buffer>(topic: string, key: string): Promise<T | undefined>;
|
|
16
17
|
delete(topic: string, key: string): Promise<void>;
|
|
17
18
|
}
|
|
19
|
+
/**
|
|
20
|
+
* What `update<Filter>` returns. The patch cannot be a trailing parameter — a filter's own args may be optional,
|
|
21
|
+
* and no tuple type puts a required element after those — and leading it reads backwards. So it lands here, on a
|
|
22
|
+
* terminal `.set()` that mirrors the `UPDATE … SET …` it compiles to.
|
|
23
|
+
*/
|
|
24
|
+
export interface UpdateChain<Doc = any> {
|
|
25
|
+
set(update: DocumentUpdateInput<Doc>): Promise<UpdateResult>;
|
|
26
|
+
}
|
|
18
27
|
type QueryMethodOfKey<CapitalizedK extends string, Doc, Insight, _Args extends any[], _ListArgs extends any[], _FindArgs extends any[], _QueryOfDoc = QueryOf<Doc>> = {
|
|
19
28
|
[K in `list${CapitalizedK}`]: (...args: _ListArgs) => Promise<Doc[]>;
|
|
20
29
|
} & {
|
|
@@ -35,6 +44,14 @@ type QueryMethodOfKey<CapitalizedK extends string, Doc, Insight, _Args extends a
|
|
|
35
44
|
[K in `insight${CapitalizedK}`]: (...args: _Args) => Promise<Insight>;
|
|
36
45
|
} & {
|
|
37
46
|
[K in `query${CapitalizedK}`]: (...args: _Args) => _QueryOfDoc;
|
|
47
|
+
} & {
|
|
48
|
+
[K in `remove${CapitalizedK}`]: (...args: _Args) => Promise<UpdateResult>;
|
|
49
|
+
} & {
|
|
50
|
+
[K in `removeOne${CapitalizedK}`]: (...args: _Args) => Promise<UpdateResult>;
|
|
51
|
+
} & {
|
|
52
|
+
[K in `update${CapitalizedK}`]: (...args: _Args) => UpdateChain<Doc>;
|
|
53
|
+
} & {
|
|
54
|
+
[K in `updateOne${CapitalizedK}`]: (...args: _Args) => UpdateChain<Doc>;
|
|
38
55
|
};
|
|
39
56
|
type QueryMethodMap<Query, Doc, Insight, _FindQueryOption, _ListQueryOption, _QueryOfDoc> = {
|
|
40
57
|
[K in keyof Query]: K extends string ? Query[K] extends (...args: infer Args) => any ? QueryMethodOfKey<Capitalize<K>, Doc, Insight, Args, [
|
|
@@ -58,6 +75,9 @@ type DatabaseModelWithQuerySort<T extends string, Input, Doc, Obj, Insight, Quer
|
|
|
58
75
|
__update: (id: string, data: Partial<Doc>) => Promise<Doc>;
|
|
59
76
|
__remove: (id: string) => Promise<Doc>;
|
|
60
77
|
__removeMany: (query: _QueryOfDoc) => Promise<UpdateResult>;
|
|
78
|
+
__removeOne: (query: _QueryOfDoc) => Promise<UpdateResult>;
|
|
79
|
+
__updateMany: (query: _QueryOfDoc, update: DocumentUpdateInput<Doc>) => Promise<UpdateResult>;
|
|
80
|
+
__updateOne: (query: _QueryOfDoc, update: DocumentUpdateInput<Doc>) => Promise<UpdateResult>;
|
|
61
81
|
__list(query: _QueryOfDoc, queryOption?: _ListQueryOption): Promise<Doc[]>;
|
|
62
82
|
__listIds(query: _QueryOfDoc, queryOption?: _ListQueryOption): Promise<string[]>;
|
|
63
83
|
__find(query: _QueryOfDoc, queryOption?: _FindQueryOption): Promise<Doc | null>;
|
|
@@ -19,6 +19,7 @@ export declare const getFilterInfoByKey: <ArgNames extends string[] = [], Args e
|
|
|
19
19
|
export declare const setFilterInfoByKey: <ArgNames extends string[] = [], Args extends any[] = any[], Model = any>(modelRef: Cls<Model>, key: string, filterInfo: FilterInfo<ArgNames, Args, Model>) => void;
|
|
20
20
|
export declare const getFilterSortByKey: (modelRef: FilterCls, key: string) => unknown;
|
|
21
21
|
export declare const fillMissingFilterArgs: (filterInfo: FilterInfo, args: unknown[]) => any[];
|
|
22
|
+
export declare const assertFilterFitsCrud: (refName: string, queryKey: string, className: string) => void;
|
|
22
23
|
export type BaseFilterSortKey = "latest" | "oldest" | "relevance";
|
|
23
24
|
export type BaseFilterQueryKey = "any";
|
|
24
25
|
export type BaseFilterKey = BaseFilterSortKey | BaseFilterQueryKey;
|
package/types/document/into.d.ts
CHANGED
|
@@ -56,12 +56,15 @@ export type Mdl<Doc, Raw, _RawDoc = DocumentModel<Raw>, _RawQuery extends Docume
|
|
|
56
56
|
find(query: _RawQuery, projection?: _Projection): FindManyChain<Doc>;
|
|
57
57
|
findOne(query: _RawQuery, projection?: _Projection): FindOneChain<Doc>;
|
|
58
58
|
findById(id: string | undefined, projection?: _Projection): Promise<Doc | null>;
|
|
59
|
-
|
|
59
|
+
count(query: _RawQuery): Promise<number>;
|
|
60
60
|
exists(query: _RawQuery): Promise<string | null>;
|
|
61
61
|
updateOne(query: _RawQuery, update: DocumentUpdateInput<_RawDoc>, options?: DocumentUpdateOptions): Promise<UpdateResult>;
|
|
62
62
|
updateMany(query: _RawQuery, update: DocumentUpdateInput<_RawDoc>): Promise<UpdateResult>;
|
|
63
|
+
removeOne(query: _RawQuery): Promise<UpdateResult>;
|
|
63
64
|
removeMany(query: _RawQuery): Promise<UpdateResult>;
|
|
64
65
|
bulkWrite(operations: BulkWriteOperation<Raw, _RawDoc, _RawQuery>[]): Promise<UpdateResult>;
|
|
66
|
+
/** @deprecated Renamed to `count`. */
|
|
67
|
+
countDocuments(query: _RawQuery): Promise<number>;
|
|
65
68
|
};
|
|
66
69
|
interface IntoConstantModel<T extends string, _CapitalizedRefName extends string, Raw, Insight> {
|
|
67
70
|
refName: T;
|
|
@@ -61,6 +61,12 @@ export interface DocumentStore {
|
|
|
61
61
|
matchedCount: number;
|
|
62
62
|
modifiedCount: number;
|
|
63
63
|
}>;
|
|
64
|
+
removeOneByQuery(query: DocumentQuery): Promise<{
|
|
65
|
+
acknowledged: boolean;
|
|
66
|
+
matchedCount: number;
|
|
67
|
+
modifiedCount: number;
|
|
68
|
+
upsertedId: string | null;
|
|
69
|
+
}>;
|
|
64
70
|
bulkWrite(operations: {
|
|
65
71
|
updateOne: {
|
|
66
72
|
filter: DocumentQuery;
|
|
@@ -314,6 +320,12 @@ export declare class SqlDocumentStore {
|
|
|
314
320
|
matchedCount: number;
|
|
315
321
|
modifiedCount: number;
|
|
316
322
|
}>;
|
|
323
|
+
removeOneByQuery(query: DocumentQuery): Promise<{
|
|
324
|
+
acknowledged: boolean;
|
|
325
|
+
matchedCount: number;
|
|
326
|
+
modifiedCount: number;
|
|
327
|
+
upsertedId: any;
|
|
328
|
+
}>;
|
|
317
329
|
private compiledUpdate;
|
|
318
330
|
bulkWrite(operations: {
|
|
319
331
|
updateOne: {
|
package/types/service/types.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { Cls, MergeAllTypes, PromiseOrObject } from "akanjs/base";
|
|
2
2
|
import type { Logger } from "akanjs/common";
|
|
3
3
|
import type { QueryOf } from "akanjs/constant";
|
|
4
|
-
import type { CRUDEventType, DatabaseModel, DataInputOf, FilterInstance, FindQueryOption, GetDocObject, ListQueryOption, QueryMethodPart, SaveEventType, UpdateResult } from "akanjs/document";
|
|
4
|
+
import type { CRUDEventType, DatabaseModel, DataInputOf, DocumentUpdateInput, FilterInstance, FindQueryOption, GetDocObject, ListQueryOption, QueryMethodPart, SaveEventType, UpdateResult } from "akanjs/document";
|
|
5
5
|
type ServiceMixinOmitKey = "onInit" | "onDestroy" | "_libsOnInit" | "_libsOnDestroy" | "_preCreate" | "_postCreate" | "_preUpdate" | "_postUpdate" | "_preRemove" | "_postRemove" | "_libsPreCreate" | "_libsPostCreate" | "_libsPreUpdate" | "_libsPostUpdate" | "_libsPreRemove" | "_libsPostRemove";
|
|
6
6
|
type DatabaseQueryMethods<Query, Sort, Obj, Doc, Insight, FindQueryOption, ListQueryOption, DocQuery> = QueryMethodPart<Query, Sort, Obj, Doc, Insight, FindQueryOption, ListQueryOption, DocQuery>;
|
|
7
7
|
type DocumentLike = {
|
|
@@ -32,6 +32,9 @@ export type DatabaseService<T extends string = string, Input = any, Doc = any, O
|
|
|
32
32
|
__update: (id: string, data: Partial<Doc>) => Promise<Doc>;
|
|
33
33
|
__remove: (id: string) => Promise<Doc>;
|
|
34
34
|
__removeMany: (query: _QueryOfDoc) => Promise<UpdateResult>;
|
|
35
|
+
__removeOne: (query: _QueryOfDoc) => Promise<UpdateResult>;
|
|
36
|
+
__updateMany: (query: _QueryOfDoc, update: DocumentUpdateInput<Doc>) => Promise<UpdateResult>;
|
|
37
|
+
__updateOne: (query: _QueryOfDoc, update: DocumentUpdateInput<Doc>) => Promise<UpdateResult>;
|
|
35
38
|
__list(query?: _QueryOfDoc, queryOption?: _ListQueryOption): Promise<Doc[]>;
|
|
36
39
|
__listIds(query?: _QueryOfDoc, queryOption?: _ListQueryOption): Promise<string[]>;
|
|
37
40
|
__find(query?: _QueryOfDoc, queryOption?: _FindQueryOption): Promise<Doc | null>;
|