@nymphjs/nymph 1.0.0-beta.13 → 1.0.0-beta.130
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 +644 -0
- package/README.md +34 -24
- package/dist/Entity.d.ts +304 -15
- package/dist/Entity.js +609 -154
- package/dist/Entity.js.map +1 -1
- package/dist/Entity.test.js +75 -29
- package/dist/Entity.test.js.map +1 -1
- package/dist/Entity.types.d.ts +275 -28
- package/dist/Entity.types.js +1 -2
- package/dist/Nymph.d.ts +575 -11
- package/dist/Nymph.js +825 -288
- package/dist/Nymph.js.map +1 -1
- package/dist/Nymph.types.d.ts +117 -7
- package/dist/Nymph.types.js +47 -5
- package/dist/Nymph.types.js.map +1 -1
- package/dist/conf/defaults.d.ts +1 -1
- package/dist/conf/defaults.js +26 -3
- package/dist/conf/defaults.js.map +1 -1
- package/dist/conf/index.d.ts +50 -2
- package/dist/conf/index.js +2 -8
- package/dist/conf/index.js.map +1 -1
- package/dist/decorators/index.d.ts +1 -0
- package/dist/decorators/index.js +2 -0
- package/dist/decorators/index.js.map +1 -0
- package/dist/decorators/transactional.d.ts +12 -0
- package/dist/decorators/transactional.js +45 -0
- package/dist/decorators/transactional.js.map +1 -0
- package/dist/driver/NymphDriver.d.ts +209 -41
- package/dist/driver/NymphDriver.js +737 -242
- package/dist/driver/NymphDriver.js.map +1 -1
- package/dist/driver/index.d.ts +1 -2
- package/dist/driver/index.js +2 -23
- package/dist/driver/index.js.map +1 -1
- package/dist/driver/testArtifacts.d.ts +4 -4
- package/dist/driver/testArtifacts.js +2016 -1086
- package/dist/driver/testArtifacts.js.map +1 -1
- package/dist/errors/ClassNotAvailableError.js +1 -5
- package/dist/errors/ClassNotAvailableError.js.map +1 -1
- package/dist/errors/EntityConflictError.js +1 -5
- package/dist/errors/EntityConflictError.js.map +1 -1
- package/dist/errors/EntityInvalidDataError.d.ts +6 -0
- package/dist/errors/EntityInvalidDataError.js +8 -6
- package/dist/errors/EntityInvalidDataError.js.map +1 -1
- package/dist/errors/EntityIsSleepingReferenceError.js +1 -5
- package/dist/errors/EntityIsSleepingReferenceError.js.map +1 -1
- package/dist/errors/EntityUniqueConstraintError.d.ts +3 -0
- package/dist/errors/EntityUniqueConstraintError.js +7 -0
- package/dist/errors/EntityUniqueConstraintError.js.map +1 -0
- package/dist/errors/HttpError.d.ts +5 -0
- package/dist/errors/HttpError.js +11 -0
- package/dist/errors/HttpError.js.map +1 -0
- package/dist/errors/InvalidParametersError.js +1 -5
- package/dist/errors/InvalidParametersError.js.map +1 -1
- package/dist/errors/InvalidStateError.d.ts +3 -0
- package/dist/errors/InvalidStateError.js +7 -0
- package/dist/errors/InvalidStateError.js.map +1 -0
- package/dist/errors/MethodFailedError.d.ts +3 -0
- package/dist/errors/MethodFailedError.js +7 -0
- package/dist/errors/MethodFailedError.js.map +1 -0
- package/dist/errors/NotConfiguredError.js +1 -5
- package/dist/errors/NotConfiguredError.js.map +1 -1
- package/dist/errors/QueryFailedError.d.ts +2 -1
- package/dist/errors/QueryFailedError.js +5 -6
- package/dist/errors/QueryFailedError.js.map +1 -1
- package/dist/errors/UnableToConnectError.js +1 -5
- package/dist/errors/UnableToConnectError.js.map +1 -1
- package/dist/errors/index.d.ts +12 -8
- package/dist/errors/index.js +12 -24
- package/dist/errors/index.js.map +1 -1
- package/dist/helpers/index.d.ts +1 -0
- package/dist/helpers/index.js +2 -0
- package/dist/helpers/index.js.map +1 -0
- package/dist/helpers/transaction.d.ts +15 -0
- package/dist/helpers/transaction.js +47 -0
- package/dist/helpers/transaction.js.map +1 -0
- package/dist/index.d.ts +13 -11
- package/dist/index.js +16 -34
- package/dist/index.js.map +1 -1
- package/dist/nymphJoiProps.d.ts +1 -1
- package/dist/nymphJoiProps.js +10 -15
- package/dist/nymphJoiProps.js.map +1 -1
- package/dist/testArtifacts.d.ts +21 -6
- package/dist/testArtifacts.js +124 -50
- package/dist/testArtifacts.js.map +1 -1
- package/dist/testMocks.d.ts +27 -12
- package/dist/testMocks.js +44 -33
- package/dist/testMocks.js.map +1 -1
- package/dist/utils.d.ts +5 -5
- package/dist/utils.js +106 -68
- package/dist/utils.js.map +1 -1
- package/jest.config.js +31 -5
- package/package.json +43 -24
- package/src/Entity.test.ts +73 -23
- package/src/Entity.ts +555 -169
- package/src/Entity.types.ts +102 -90
- package/src/Nymph.ts +930 -517
- package/src/Nymph.types.ts +145 -39
- package/src/conf/defaults.ts +34 -1
- package/src/conf/index.ts +50 -2
- package/src/decorators/index.ts +1 -0
- package/src/decorators/transactional.ts +63 -0
- package/src/driver/NymphDriver.ts +987 -417
- package/src/driver/index.ts +1 -3
- package/src/driver/testArtifacts.ts +2699 -1628
- package/src/errors/EntityUniqueConstraintError.ts +6 -0
- package/src/errors/HttpError.ts +12 -0
- package/src/errors/InvalidStateError.ts +6 -0
- package/src/errors/MethodFailedError.ts +6 -0
- package/src/errors/QueryFailedError.ts +3 -1
- package/src/errors/index.ts +16 -8
- package/src/helpers/index.ts +1 -0
- package/src/helpers/transaction.ts +65 -0
- package/src/index.ts +13 -11
- package/src/nymphJoiProps.ts +2 -2
- package/src/testArtifacts.ts +69 -20
- package/src/testMocks.ts +107 -41
- package/src/utils.ts +102 -67
- package/tsconfig.json +6 -3
- package/typedoc.json +4 -0
- package/dist/conf/d.d.ts +0 -6
- package/dist/conf/d.js +0 -3
- package/dist/conf/d.js.map +0 -1
- package/src/conf/d.ts +0 -24
package/src/Nymph.types.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { EntityConstructor, EntityInterface } from './Entity.types';
|
|
2
|
-
import Nymph from './Nymph';
|
|
1
|
+
import type { EntityConstructor, EntityInterface } from './Entity.types.js';
|
|
2
|
+
import type Nymph from './Nymph.js';
|
|
3
3
|
|
|
4
4
|
export type NymphEventType =
|
|
5
5
|
| 'connect'
|
|
@@ -36,11 +36,11 @@ export type NymphEventType =
|
|
|
36
36
|
| 'afterRollbackTransaction';
|
|
37
37
|
export type NymphConnectCallback = (
|
|
38
38
|
nymph: Nymph,
|
|
39
|
-
result: Promise<boolean
|
|
39
|
+
result: Promise<boolean>,
|
|
40
40
|
) => Promise<void>;
|
|
41
41
|
export type NymphDisconnectCallback = (
|
|
42
42
|
nymph: Nymph,
|
|
43
|
-
result: Promise<boolean
|
|
43
|
+
result: Promise<boolean>,
|
|
44
44
|
) => Promise<void>;
|
|
45
45
|
/**
|
|
46
46
|
* The NymphQueryCallback will be called on both top level and qref queries.
|
|
@@ -56,142 +56,192 @@ export type NymphDisconnectCallback = (
|
|
|
56
56
|
export type NymphQueryCallback = (
|
|
57
57
|
nymph: Nymph,
|
|
58
58
|
options: Options,
|
|
59
|
-
selectors: FormattedSelector[]
|
|
59
|
+
selectors: FormattedSelector[],
|
|
60
60
|
) => void;
|
|
61
61
|
export type NymphBeforeGetEntityCallback = (
|
|
62
62
|
nymph: Nymph,
|
|
63
63
|
options: Options,
|
|
64
|
-
selectors: Selector[]
|
|
64
|
+
selectors: Selector[],
|
|
65
65
|
) => Promise<void>;
|
|
66
66
|
export type NymphBeforeGetEntitiesCallback = (
|
|
67
67
|
nymph: Nymph,
|
|
68
68
|
options: Options,
|
|
69
|
-
selectors: Selector[]
|
|
69
|
+
selectors: Selector[],
|
|
70
70
|
) => Promise<void>;
|
|
71
71
|
export type NymphBeforeSaveEntityCallback = (
|
|
72
72
|
nymph: Nymph,
|
|
73
|
-
entity: EntityInterface
|
|
73
|
+
entity: EntityInterface,
|
|
74
74
|
) => Promise<void>;
|
|
75
75
|
export type NymphAfterSaveEntityCallback = (
|
|
76
76
|
nymph: Nymph,
|
|
77
|
-
result: Promise<boolean
|
|
77
|
+
result: Promise<boolean>,
|
|
78
78
|
) => Promise<void>;
|
|
79
79
|
export type NymphFailedSaveEntityCallback = (
|
|
80
80
|
nymph: Nymph,
|
|
81
|
-
error: any
|
|
81
|
+
error: any,
|
|
82
82
|
) => Promise<void>;
|
|
83
83
|
export type NymphBeforeDeleteEntityCallback = (
|
|
84
84
|
nymph: Nymph,
|
|
85
|
-
entity: EntityInterface
|
|
85
|
+
entity: EntityInterface,
|
|
86
86
|
) => Promise<void>;
|
|
87
87
|
export type NymphAfterDeleteEntityCallback = (
|
|
88
88
|
nymph: Nymph,
|
|
89
|
-
result: Promise<boolean
|
|
89
|
+
result: Promise<boolean>,
|
|
90
90
|
) => Promise<void>;
|
|
91
91
|
export type NymphFailedDeleteEntityCallback = (
|
|
92
92
|
nymph: Nymph,
|
|
93
|
-
error: any
|
|
93
|
+
error: any,
|
|
94
94
|
) => Promise<void>;
|
|
95
95
|
export type NymphBeforeDeleteEntityByIDCallback = (
|
|
96
96
|
nymph: Nymph,
|
|
97
97
|
guid: string,
|
|
98
|
-
className?: string
|
|
98
|
+
className?: string,
|
|
99
99
|
) => Promise<void>;
|
|
100
100
|
export type NymphAfterDeleteEntityByIDCallback = (
|
|
101
101
|
nymph: Nymph,
|
|
102
|
-
result: Promise<boolean
|
|
102
|
+
result: Promise<boolean>,
|
|
103
103
|
) => Promise<void>;
|
|
104
104
|
export type NymphFailedDeleteEntityByIDCallback = (
|
|
105
105
|
nymph: Nymph,
|
|
106
|
-
error: any
|
|
106
|
+
error: any,
|
|
107
107
|
) => Promise<void>;
|
|
108
108
|
export type NymphBeforeNewUIDCallback = (
|
|
109
109
|
nymph: Nymph,
|
|
110
|
-
name: string
|
|
110
|
+
name: string,
|
|
111
111
|
) => Promise<void>;
|
|
112
112
|
export type NymphAfterNewUIDCallback = (
|
|
113
113
|
nymph: Nymph,
|
|
114
|
-
result: Promise<number | null
|
|
114
|
+
result: Promise<number | null>,
|
|
115
115
|
) => Promise<void>;
|
|
116
116
|
export type NymphFailedNewUIDCallback = (
|
|
117
117
|
nymph: Nymph,
|
|
118
|
-
error: any
|
|
118
|
+
error: any,
|
|
119
119
|
) => Promise<void>;
|
|
120
120
|
export type NymphBeforeSetUIDCallback = (
|
|
121
121
|
nymph: Nymph,
|
|
122
122
|
name: string,
|
|
123
|
-
value: number
|
|
123
|
+
value: number,
|
|
124
124
|
) => Promise<void>;
|
|
125
125
|
export type NymphAfterSetUIDCallback = (
|
|
126
126
|
nymph: Nymph,
|
|
127
|
-
result: Promise<boolean
|
|
127
|
+
result: Promise<boolean>,
|
|
128
128
|
) => Promise<void>;
|
|
129
129
|
export type NymphFailedSetUIDCallback = (
|
|
130
130
|
nymph: Nymph,
|
|
131
|
-
error: any
|
|
131
|
+
error: any,
|
|
132
132
|
) => Promise<void>;
|
|
133
133
|
export type NymphBeforeRenameUIDCallback = (
|
|
134
134
|
nymph: Nymph,
|
|
135
135
|
oldName: string,
|
|
136
|
-
newName: string
|
|
136
|
+
newName: string,
|
|
137
137
|
) => Promise<void>;
|
|
138
138
|
export type NymphAfterRenameUIDCallback = (
|
|
139
139
|
nymph: Nymph,
|
|
140
|
-
result: Promise<boolean
|
|
140
|
+
result: Promise<boolean>,
|
|
141
141
|
) => Promise<void>;
|
|
142
142
|
export type NymphFailedRenameUIDCallback = (
|
|
143
143
|
nymph: Nymph,
|
|
144
|
-
error: any
|
|
144
|
+
error: any,
|
|
145
145
|
) => Promise<void>;
|
|
146
146
|
export type NymphBeforeDeleteUIDCallback = (
|
|
147
147
|
nymph: Nymph,
|
|
148
|
-
name: string
|
|
148
|
+
name: string,
|
|
149
149
|
) => Promise<void>;
|
|
150
150
|
export type NymphAfterDeleteUIDCallback = (
|
|
151
151
|
nymph: Nymph,
|
|
152
|
-
result: Promise<boolean
|
|
152
|
+
result: Promise<boolean>,
|
|
153
153
|
) => Promise<void>;
|
|
154
154
|
export type NymphFailedDeleteUIDCallback = (
|
|
155
155
|
nymph: Nymph,
|
|
156
|
-
error: any
|
|
156
|
+
error: any,
|
|
157
157
|
) => Promise<void>;
|
|
158
158
|
export type NymphBeforeStartTransactionCallback = (
|
|
159
159
|
nymph: Nymph,
|
|
160
|
-
name: string
|
|
160
|
+
name: string,
|
|
161
161
|
) => Promise<void>;
|
|
162
162
|
export type NymphAfterStartTransactionCallback = (
|
|
163
163
|
nymph: Nymph,
|
|
164
164
|
name: string,
|
|
165
|
-
result: Nymph
|
|
165
|
+
result: Nymph,
|
|
166
166
|
) => Promise<void>;
|
|
167
167
|
export type NymphBeforeCommitTransactionCallback = (
|
|
168
168
|
nymph: Nymph,
|
|
169
|
-
name: string
|
|
169
|
+
name: string,
|
|
170
170
|
) => Promise<void>;
|
|
171
171
|
export type NymphAfterCommitTransactionCallback = (
|
|
172
172
|
nymph: Nymph,
|
|
173
173
|
name: string,
|
|
174
|
-
result: boolean
|
|
174
|
+
result: boolean,
|
|
175
175
|
) => Promise<void>;
|
|
176
176
|
export type NymphBeforeRollbackTransactionCallback = (
|
|
177
177
|
nymph: Nymph,
|
|
178
|
-
name: string
|
|
178
|
+
name: string,
|
|
179
179
|
) => Promise<void>;
|
|
180
180
|
export type NymphAfterRollbackTransactionCallback = (
|
|
181
181
|
nymph: Nymph,
|
|
182
182
|
name: string,
|
|
183
|
-
result: boolean
|
|
183
|
+
result: boolean,
|
|
184
184
|
) => Promise<void>;
|
|
185
185
|
|
|
186
186
|
export type Options<T extends EntityConstructor = EntityConstructor> = {
|
|
187
|
+
/**
|
|
188
|
+
* The Entity class to query.
|
|
189
|
+
*/
|
|
187
190
|
class?: T;
|
|
191
|
+
/**
|
|
192
|
+
* The limit of entities to be returned. Not needed when using `getEntity`, as
|
|
193
|
+
* it always returns only one.
|
|
194
|
+
*/
|
|
188
195
|
limit?: number;
|
|
196
|
+
/**
|
|
197
|
+
* The offset from the first matching entity, in order, to start retrieving.
|
|
198
|
+
*/
|
|
189
199
|
offset?: number;
|
|
200
|
+
/**
|
|
201
|
+
* If true, entities will be retrieved from newest to oldest/largest to
|
|
202
|
+
* smallest (with regard to `sort`).
|
|
203
|
+
*/
|
|
190
204
|
reverse?: boolean;
|
|
191
|
-
|
|
192
|
-
|
|
205
|
+
/**
|
|
206
|
+
* How to sort the entities. Should be "cdate", "mdate", or the name of a
|
|
207
|
+
* property.
|
|
208
|
+
*
|
|
209
|
+
* When null, the result set will not be sorted in any particular way. It's
|
|
210
|
+
* really up to the DB how the results are returned. In this case, limit and
|
|
211
|
+
* offset may work for pagination, but shouldn't be relied on.
|
|
212
|
+
*/
|
|
213
|
+
sort?: 'cdate' | 'mdate' | string | null;
|
|
214
|
+
/**
|
|
215
|
+
* What to return, the entities with their data, just the entity data, just
|
|
216
|
+
* the GUIDs, or just a count.
|
|
217
|
+
*
|
|
218
|
+
* 'object' is only available on the server, as there are substantial security
|
|
219
|
+
* implications with using it. It returns the full entity data as a simple
|
|
220
|
+
* object. You should only use it for operations where instantiating the
|
|
221
|
+
* entities has an unacceptable performance cost.
|
|
222
|
+
*/
|
|
223
|
+
return?: 'entity' | 'object' | 'guid' | 'count';
|
|
224
|
+
/**
|
|
225
|
+
* Will be 'client' if the query came from a REST request or the PubSub
|
|
226
|
+
* server. (Mainly used in Tilmeld for access control.)
|
|
227
|
+
*/
|
|
193
228
|
source?: string;
|
|
229
|
+
/**
|
|
230
|
+
* If true, Nymph will skip the cache and retrieve the entity from the DB.
|
|
231
|
+
*/
|
|
194
232
|
skipCache?: boolean;
|
|
233
|
+
/**
|
|
234
|
+
* The level(s) of access control requested.
|
|
235
|
+
*
|
|
236
|
+
* Limiting the access control can significantly improve the performance of
|
|
237
|
+
* the query.
|
|
238
|
+
*/
|
|
239
|
+
acRequest?: TilmeldAccessRequest;
|
|
240
|
+
/**
|
|
241
|
+
* If true, Tilmeld will not filter returned entities according to access
|
|
242
|
+
* controls. (If Tilmeld is installed.) (This is always set to false by the
|
|
243
|
+
* REST endpoint and PubSub server.)
|
|
244
|
+
*/
|
|
195
245
|
skipAc?: boolean;
|
|
196
246
|
};
|
|
197
247
|
|
|
@@ -218,6 +268,9 @@ type PrimitiveSelector = {
|
|
|
218
268
|
contain?: [string, any];
|
|
219
269
|
'!contain'?: PrimitiveSelector['contain'];
|
|
220
270
|
|
|
271
|
+
search?: [string, string];
|
|
272
|
+
'!search'?: PrimitiveSelector['search'];
|
|
273
|
+
|
|
221
274
|
match?: [string, string];
|
|
222
275
|
'!match'?: PrimitiveSelector['match'];
|
|
223
276
|
|
|
@@ -273,6 +326,9 @@ export type Selector = {
|
|
|
273
326
|
contain?: Clause<OrWithTime<PrimitiveSelector['contain']>>;
|
|
274
327
|
'!contain'?: Clause<OrWithTime<PrimitiveSelector['contain']>>;
|
|
275
328
|
|
|
329
|
+
search?: Clause<PrimitiveSelector['search']>;
|
|
330
|
+
'!search'?: Clause<PrimitiveSelector['search']>;
|
|
331
|
+
|
|
276
332
|
match?: Clause<PrimitiveSelector['match']>;
|
|
277
333
|
'!match'?: Clause<PrimitiveSelector['match']>;
|
|
278
334
|
|
|
@@ -328,6 +384,9 @@ export type FormattedSelector = {
|
|
|
328
384
|
contain?: PrimitiveSelector['contain'][];
|
|
329
385
|
'!contain'?: PrimitiveSelector['contain'][];
|
|
330
386
|
|
|
387
|
+
search?: PrimitiveSelector['search'][];
|
|
388
|
+
'!search'?: PrimitiveSelector['search'][];
|
|
389
|
+
|
|
331
390
|
match?: PrimitiveSelector['match'][];
|
|
332
391
|
'!match'?: PrimitiveSelector['match'][];
|
|
333
392
|
|
|
@@ -370,6 +429,50 @@ export enum TilmeldAccessLevels {
|
|
|
370
429
|
FULL_ACCESS = 4,
|
|
371
430
|
}
|
|
372
431
|
|
|
432
|
+
export enum TilmeldAccessRequest {
|
|
433
|
+
/**
|
|
434
|
+
* The default level, any possible entity readable by the user.
|
|
435
|
+
*
|
|
436
|
+
* This is the same as or-ing together all of the levels listed below.
|
|
437
|
+
*/
|
|
438
|
+
ALL_LEVELS = 0,
|
|
439
|
+
/**
|
|
440
|
+
* Owned by and accessible to the user.
|
|
441
|
+
*
|
|
442
|
+
* This is always enabled, so not including it has no effect. It's here to
|
|
443
|
+
* allow the selection of _only_ user owned entities.
|
|
444
|
+
*/
|
|
445
|
+
USER_OWNED = 1,
|
|
446
|
+
/**
|
|
447
|
+
* Owned by and accessible to the user's primary group.
|
|
448
|
+
*/
|
|
449
|
+
PRIMARY_GROUP_OWNED = 2,
|
|
450
|
+
/**
|
|
451
|
+
* Owned by and accessible to one of the user's secondary groups.
|
|
452
|
+
*/
|
|
453
|
+
SECONDARY_GROUP_OWNED = 4,
|
|
454
|
+
/**
|
|
455
|
+
* The user is listed in an access control list.
|
|
456
|
+
*/
|
|
457
|
+
USER_ACCESSIBLE = 8,
|
|
458
|
+
/**
|
|
459
|
+
* The user's primary group is listed in an access control list.
|
|
460
|
+
*/
|
|
461
|
+
PRIMARY_GROUP_ACCESSIBLE = 16,
|
|
462
|
+
/**
|
|
463
|
+
* One of the user's secondary groups is listed in an access control list.
|
|
464
|
+
*/
|
|
465
|
+
SECONDARY_GROUP_ACCESSIBLE = 32,
|
|
466
|
+
/**
|
|
467
|
+
* The entity is accessible to any user.
|
|
468
|
+
*/
|
|
469
|
+
OTHER_ACCESSIBLE = 64,
|
|
470
|
+
/**
|
|
471
|
+
* The entity is not owned by anyone.
|
|
472
|
+
*/
|
|
473
|
+
UNOWNED = 128,
|
|
474
|
+
}
|
|
475
|
+
|
|
373
476
|
export interface TilmeldInterface {
|
|
374
477
|
nymph: Nymph;
|
|
375
478
|
request: any;
|
|
@@ -377,9 +480,12 @@ export interface TilmeldInterface {
|
|
|
377
480
|
init(nymph: Nymph): void;
|
|
378
481
|
clone(): TilmeldInterface;
|
|
379
482
|
gatekeeper(ability?: string): boolean;
|
|
380
|
-
authenticate():
|
|
483
|
+
authenticate(skipXsrfToken?: boolean, skipRenew?: boolean): Promise<boolean>;
|
|
381
484
|
clearSession(): void;
|
|
382
485
|
extractToken(token: string): Promise<any>;
|
|
383
|
-
fillSession(user: any): void
|
|
384
|
-
checkClientUIDPermissions(
|
|
486
|
+
fillSession(user: any): Promise<void>;
|
|
487
|
+
checkClientUIDPermissions(
|
|
488
|
+
name: string,
|
|
489
|
+
type?: TilmeldAccessLevels,
|
|
490
|
+
): Promise<boolean>;
|
|
385
491
|
}
|
package/src/conf/defaults.ts
CHANGED
|
@@ -1,8 +1,41 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import createDebug, { type Debugger } from 'debug';
|
|
2
|
+
|
|
3
|
+
import type { Config } from './index.js';
|
|
4
|
+
|
|
5
|
+
const debuggers: {
|
|
6
|
+
[k: string]: { info: Debugger; log: Debugger; error: Debugger };
|
|
7
|
+
} = {};
|
|
8
|
+
|
|
9
|
+
function getDebuggers(source: string) {
|
|
10
|
+
if (source in debuggers) {
|
|
11
|
+
return debuggers[source];
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
debuggers[source] = {
|
|
15
|
+
info: createDebug(`nymphjs:info:${source}`),
|
|
16
|
+
log: createDebug(`nymphjs:log:${source}`),
|
|
17
|
+
error: createDebug(`nymphjs:error:${source}`),
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
debuggers[source].info.log = console.info.bind(console);
|
|
21
|
+
debuggers[source].log.log = console.log.bind(console);
|
|
22
|
+
|
|
23
|
+
return debuggers[source];
|
|
24
|
+
}
|
|
2
25
|
|
|
3
26
|
export default {
|
|
4
27
|
cache: false,
|
|
5
28
|
cacheThreshold: 4,
|
|
6
29
|
cacheLimit: 50,
|
|
7
30
|
emptyListError: false,
|
|
31
|
+
updateMDate: true,
|
|
32
|
+
debugInfo: (source, message) => {
|
|
33
|
+
getDebuggers(source).info(message);
|
|
34
|
+
},
|
|
35
|
+
debugLog: (source, message) => {
|
|
36
|
+
getDebuggers(source).log(message);
|
|
37
|
+
},
|
|
38
|
+
debugError: (source, message) => {
|
|
39
|
+
getDebuggers(source).error(message);
|
|
40
|
+
},
|
|
8
41
|
} as Config;
|
package/src/conf/index.ts
CHANGED
|
@@ -1,4 +1,52 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Nymph Config
|
|
3
|
+
*/
|
|
4
|
+
export interface Config {
|
|
5
|
+
/**
|
|
6
|
+
* Cache recently retrieved entities to speed up database queries. Uses more
|
|
7
|
+
* memory.
|
|
8
|
+
*/
|
|
9
|
+
cache: boolean;
|
|
10
|
+
/**
|
|
11
|
+
* Cache entities after they're accessed this many times.
|
|
12
|
+
*/
|
|
13
|
+
cacheThreshold: number;
|
|
14
|
+
/**
|
|
15
|
+
* The number of recently retrieved entities to cache. If you're running out
|
|
16
|
+
* of memory, try lowering this value. 0 means unlimited.
|
|
17
|
+
*/
|
|
18
|
+
cacheLimit: number;
|
|
19
|
+
/**
|
|
20
|
+
* When querying for multiple entities with NymphREST, if the list is empty,
|
|
21
|
+
* return a 404 error.
|
|
22
|
+
*/
|
|
23
|
+
emptyListError: boolean;
|
|
24
|
+
/**
|
|
25
|
+
* Whether to update the mdate property when saving an entity.
|
|
26
|
+
*
|
|
27
|
+
* You should probably only set this to false if you're doing migrations. Some
|
|
28
|
+
* things depend on having updated mdates (like conflict detection to avoid
|
|
29
|
+
* lost updates).
|
|
30
|
+
*
|
|
31
|
+
* If you set this to a number, that amount of milliseconds will be added to
|
|
32
|
+
* the mdate on any entities that are saved. This should solve the lost update
|
|
33
|
+
* problem when set to a small number (~1000), and keep mdates relatively
|
|
34
|
+
* unchanged.
|
|
35
|
+
*/
|
|
36
|
+
updateMDate: boolean | number;
|
|
37
|
+
/**
|
|
38
|
+
* A function to log info messages. By default, uses the `debug` package.
|
|
39
|
+
*/
|
|
40
|
+
debugInfo: (source: string, message: string) => void;
|
|
41
|
+
/**
|
|
42
|
+
* A function to log debug messages. By default, uses the `debug` package.
|
|
43
|
+
*/
|
|
44
|
+
debugLog: (source: string, message: string) => void;
|
|
45
|
+
/**
|
|
46
|
+
* A function to log error messages. By default, uses the `debug` package.
|
|
47
|
+
*/
|
|
48
|
+
debugError: (source: string, message: string) => void;
|
|
49
|
+
}
|
|
2
50
|
|
|
3
|
-
import defaults from './defaults';
|
|
51
|
+
import defaults from './defaults.js';
|
|
4
52
|
export { defaults as ConfigDefaults };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './transactional.js';
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { nanoid } from '@nymphjs/guid';
|
|
2
|
+
|
|
3
|
+
import Entity from '../Entity.js';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* A decorator that runs the decorated method inside a transaction.
|
|
7
|
+
*
|
|
8
|
+
* If the method resolves, the transaction is committed. If the method throws,
|
|
9
|
+
* the transaction is rolled back.
|
|
10
|
+
*
|
|
11
|
+
* Uses $setNymph to set the transactional instance of Nymph on the entity and
|
|
12
|
+
* return to the original instance after the transaction is committed or rolled
|
|
13
|
+
* back.
|
|
14
|
+
*/
|
|
15
|
+
export function transactional(
|
|
16
|
+
target: (...args: any[]) => Promise<any>,
|
|
17
|
+
context: ClassMethodDecoratorContext,
|
|
18
|
+
) {
|
|
19
|
+
const name = String(context.name);
|
|
20
|
+
return async function (this: Entity, ...args: unknown[]) {
|
|
21
|
+
const transactionName = `${name}-${nanoid()}`;
|
|
22
|
+
const nymph = this.$nymph;
|
|
23
|
+
nymph.config.debugInfo(
|
|
24
|
+
'nymph:transactional',
|
|
25
|
+
`Starting transaction ${transactionName}`,
|
|
26
|
+
);
|
|
27
|
+
const tnymph = await nymph.startTransaction(transactionName);
|
|
28
|
+
this.$setNymph(tnymph);
|
|
29
|
+
let committed = false;
|
|
30
|
+
let result: any;
|
|
31
|
+
try {
|
|
32
|
+
result = await target.apply(this, args);
|
|
33
|
+
nymph.config.debugInfo(
|
|
34
|
+
'nymph:transactional',
|
|
35
|
+
`Committing transaction ${transactionName}`,
|
|
36
|
+
);
|
|
37
|
+
committed = await tnymph.commit(transactionName);
|
|
38
|
+
} catch (e: any) {
|
|
39
|
+
try {
|
|
40
|
+
nymph.config.debugInfo(
|
|
41
|
+
'nymph:transactional',
|
|
42
|
+
`Rolling back transaction ${transactionName}, reason: ${e.message}`,
|
|
43
|
+
);
|
|
44
|
+
await tnymph.rollback(transactionName);
|
|
45
|
+
} catch (e: any) {
|
|
46
|
+
nymph.config.debugError(
|
|
47
|
+
'nymph:transactional',
|
|
48
|
+
`Rollback of transaction ${transactionName} failed, reason: ${e.message}`,
|
|
49
|
+
);
|
|
50
|
+
}
|
|
51
|
+
this.$setNymph(nymph);
|
|
52
|
+
throw e;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
this.$setNymph(nymph);
|
|
56
|
+
|
|
57
|
+
if (!committed) {
|
|
58
|
+
throw new Error('Transaction could not be committed.');
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
return result;
|
|
62
|
+
};
|
|
63
|
+
}
|