remult 3.3.0-next.1 → 3.3.0
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/esm/graphql.js +1 -1
- package/esm/remult-knex/index.js +8 -2
- package/esm/remult-mongo.js +7 -3
- package/esm/server/get-remult-admin-html.js +125 -111
- package/esm/server/remult-admin.js +2 -0
- package/esm/server/remult-api-server.js +1 -1
- package/esm/src/data-api.js +28 -19
- package/esm/src/data-providers/rest-data-provider.js +48 -37
- package/esm/src/data-providers/sql-database.js +14 -3
- package/esm/src/remult-proxy.js +4 -4
- package/esm/src/remult3/RepositoryImplementation.js +41 -17
- package/esm/src/server-action.js +2 -2
- package/esm/src/valueConverters.js +9 -5
- package/graphql.js +1 -1
- package/index.d.ts +1 -1
- package/package.json +1 -1
- package/remult-knex/index.js +16 -8
- package/remult-mongo.js +6 -2
- package/server/get-remult-admin-html.js +1 -1
- package/server/remult-admin.d.ts +2 -0
- package/server/remult-admin.js +2 -1
- package/server/remult-api-server.js +1 -0
- package/src/data-api.d.ts +4 -4
- package/src/data-api.js +48 -30
- package/src/data-interfaces.d.ts +6 -6
- package/src/data-providers/rest-data-provider.d.ts +4 -4
- package/src/data-providers/rest-data-provider.js +48 -37
- package/src/data-providers/sql-database.js +14 -3
- package/src/remult-proxy.js +4 -4
- package/src/remult3/RepositoryImplementation.d.ts +8 -7
- package/src/remult3/RepositoryImplementation.js +225 -169
- package/src/remult3/remult3.d.ts +10 -7
- package/src/server-action.js +2 -2
- package/src/valueConverters.d.ts +3 -1
- package/src/valueConverters.js +9 -6
|
@@ -51,6 +51,7 @@ export function buildEntityInfo(options) {
|
|
|
51
51
|
if (relRepo.metadata.apiReadAllowed) {
|
|
52
52
|
relation = {
|
|
53
53
|
...relInfo,
|
|
54
|
+
allowNull: x.allowNull,
|
|
54
55
|
where,
|
|
55
56
|
entityKey: relRepo.metadata.key,
|
|
56
57
|
idField,
|
|
@@ -81,6 +82,7 @@ export function buildEntityInfo(options) {
|
|
|
81
82
|
caption: x.label,
|
|
82
83
|
relationToOne: relation,
|
|
83
84
|
inputType: x.inputType,
|
|
85
|
+
allowNull: x.allowNull,
|
|
84
86
|
type: x.inputType === InputTypes.json
|
|
85
87
|
? 'json'
|
|
86
88
|
: x.valueType === Number
|
|
@@ -316,7 +316,7 @@ export class RemultServerImplementation {
|
|
|
316
316
|
//@ts-ignore
|
|
317
317
|
.get(this.process(async (c, req, res, orig) => dataApiFactory(c).get(res, orig.params.id)))
|
|
318
318
|
//@ts-ignore
|
|
319
|
-
.put(this.process(async (c, req, res, reqInfo, _, orig) => dataApiFactory(c).put(res, reqInfo.params.id, await this.coreOptions.getRequestBody(orig))))
|
|
319
|
+
.put(this.process(async (c, req, res, reqInfo, _, orig) => dataApiFactory(c).put(res, req, reqInfo.params.id, await this.coreOptions.getRequestBody(orig))))
|
|
320
320
|
//@ts-ignore
|
|
321
321
|
.delete(this.process(async (c, req, res, orig) => dataApiFactory(c).delete(res, orig.params.id)));
|
|
322
322
|
}
|
package/esm/src/data-api.js
CHANGED
|
@@ -72,7 +72,7 @@ export class DataApi {
|
|
|
72
72
|
case 'query':
|
|
73
73
|
return res.success(await this.query(res, req, body));
|
|
74
74
|
default:
|
|
75
|
-
return res.created(await this.post(body));
|
|
75
|
+
return res.created(await this.post(body, req));
|
|
76
76
|
}
|
|
77
77
|
}
|
|
78
78
|
catch (err) {
|
|
@@ -93,11 +93,11 @@ export class DataApi {
|
|
|
93
93
|
include: this.includeNone(),
|
|
94
94
|
});
|
|
95
95
|
if (r.length == 0) {
|
|
96
|
-
result.push(await this.post({ ...item.where, ...item.set }));
|
|
96
|
+
result.push(await this.post({ ...item.where, ...item.set }, request));
|
|
97
97
|
}
|
|
98
98
|
else {
|
|
99
99
|
if (item.set !== undefined) {
|
|
100
|
-
result.push(
|
|
100
|
+
result.push(await this.actualUpdate(r[0], item.set, request));
|
|
101
101
|
}
|
|
102
102
|
else
|
|
103
103
|
result.push(this.repository.getEntityRef(r[0]).toApiJson());
|
|
@@ -154,8 +154,7 @@ export class DataApi {
|
|
|
154
154
|
async deleteMany(response, request, body) {
|
|
155
155
|
try {
|
|
156
156
|
let deleted = 0;
|
|
157
|
-
let where = await this.
|
|
158
|
-
Filter.throwErrorIfFilterIsEmpty(where, 'deleteMany');
|
|
157
|
+
let where = await this.prepareWhereForManyOperation(body, request);
|
|
159
158
|
return await doTransaction(this.remult, async () => {
|
|
160
159
|
for await (const x of this.repository.query({
|
|
161
160
|
where,
|
|
@@ -172,6 +171,14 @@ export class DataApi {
|
|
|
172
171
|
response.error(err, this.repository.metadata);
|
|
173
172
|
}
|
|
174
173
|
}
|
|
174
|
+
async prepareWhereForManyOperation(body, request) {
|
|
175
|
+
let where = undefined;
|
|
176
|
+
if (body?.where !== 'all') {
|
|
177
|
+
where = await this.buildWhere(request, body);
|
|
178
|
+
Filter.throwErrorIfFilterIsEmpty(where, 'deleteMany');
|
|
179
|
+
}
|
|
180
|
+
return where;
|
|
181
|
+
}
|
|
175
182
|
async groupBy(request, body) {
|
|
176
183
|
if (!this.repository.metadata.apiReadAllowed) {
|
|
177
184
|
throw new ForbiddenError();
|
|
@@ -412,7 +419,7 @@ export class DataApi {
|
|
|
412
419
|
async updateManyThroughPutRequest(response, request, body) {
|
|
413
420
|
const action = request?.get('__action');
|
|
414
421
|
if (action == 'emptyId') {
|
|
415
|
-
return this.put(response, '', body);
|
|
422
|
+
return this.put(response, request, '', body);
|
|
416
423
|
}
|
|
417
424
|
return this.updateManyImplementation(response, request, {
|
|
418
425
|
where: undefined,
|
|
@@ -421,8 +428,7 @@ export class DataApi {
|
|
|
421
428
|
}
|
|
422
429
|
async updateManyImplementation(response, request, body) {
|
|
423
430
|
try {
|
|
424
|
-
let where = await this.
|
|
425
|
-
Filter.throwErrorIfFilterIsEmpty(where, 'updateMany');
|
|
431
|
+
let where = await this.prepareWhereForManyOperation(body, request);
|
|
426
432
|
return await doTransaction(this.remult, async () => {
|
|
427
433
|
let updated = 0;
|
|
428
434
|
for await (const x of this.repository.query({
|
|
@@ -430,7 +436,7 @@ export class DataApi {
|
|
|
430
436
|
include: this.includeNone(),
|
|
431
437
|
aggregate: undefined,
|
|
432
438
|
})) {
|
|
433
|
-
await this.actualUpdate(x, body.set);
|
|
439
|
+
await this.actualUpdate(x, body.set, request);
|
|
434
440
|
updated++;
|
|
435
441
|
}
|
|
436
442
|
response.success({ updated });
|
|
@@ -440,20 +446,20 @@ export class DataApi {
|
|
|
440
446
|
response.error(err, this.repository.metadata);
|
|
441
447
|
}
|
|
442
448
|
}
|
|
443
|
-
async actualUpdate(row, body) {
|
|
449
|
+
async actualUpdate(row, body, req) {
|
|
444
450
|
let ref = this.repository.getEntityRef(row);
|
|
445
451
|
await ref._updateEntityBasedOnApi(body);
|
|
446
452
|
if (!ref.apiUpdateAllowed) {
|
|
447
453
|
throw new ForbiddenError();
|
|
448
454
|
}
|
|
449
|
-
|
|
450
|
-
|
|
455
|
+
let options = req.get('_select') === 'none' ? { select: 'none' } : undefined;
|
|
456
|
+
await ref.save(options);
|
|
457
|
+
if (options?.select === 'none')
|
|
458
|
+
return undefined;
|
|
459
|
+
return ref.toApiJson();
|
|
451
460
|
}
|
|
452
|
-
async put(response, id, body) {
|
|
453
|
-
await this.doOnId(response, id, async (row) =>
|
|
454
|
-
const ref = await this.actualUpdate(row, body);
|
|
455
|
-
response.success(ref.toApiJson());
|
|
456
|
-
});
|
|
461
|
+
async put(response, req, id, body) {
|
|
462
|
+
await this.doOnId(response, id, async (row) => response.success(await this.actualUpdate(row, body, req)));
|
|
457
463
|
}
|
|
458
464
|
async actualDelete(row) {
|
|
459
465
|
if (!this.repository.getEntityRef(row).apiDeleteAllowed) {
|
|
@@ -467,14 +473,17 @@ export class DataApi {
|
|
|
467
473
|
response.deleted();
|
|
468
474
|
});
|
|
469
475
|
}
|
|
470
|
-
async post(body) {
|
|
476
|
+
async post(body, req) {
|
|
477
|
+
let options = req.get('_select') === 'none' ? { select: 'none' } : undefined;
|
|
471
478
|
const insert = async (what) => {
|
|
472
479
|
let newr = this.repository.create();
|
|
473
480
|
await this.repository.getEntityRef(newr)._updateEntityBasedOnApi(what);
|
|
474
481
|
if (!this.repository.getEntityRef(newr).apiInsertAllowed) {
|
|
475
482
|
throw new ForbiddenError();
|
|
476
483
|
}
|
|
477
|
-
await this.repository.getEntityRef(newr).save();
|
|
484
|
+
await this.repository.getEntityRef(newr).save(options);
|
|
485
|
+
if (options?.select === 'none')
|
|
486
|
+
return undefined;
|
|
478
487
|
return this.repository.getEntityRef(newr).toApiJson();
|
|
479
488
|
};
|
|
480
489
|
if (Array.isArray(body)) {
|
|
@@ -199,37 +199,42 @@ export class RestEntityDataProvider {
|
|
|
199
199
|
let url = new UrlBuilder(this.url());
|
|
200
200
|
let filterObject;
|
|
201
201
|
if (options) {
|
|
202
|
-
if (options.where) {
|
|
203
|
-
filterObject =
|
|
204
|
-
if (options.args === undefined)
|
|
205
|
-
if (addFilterToUrlAndReturnTrueIfSuccessful(filterObject, url))
|
|
206
|
-
filterObject = undefined;
|
|
202
|
+
if (options.where === 'all') {
|
|
203
|
+
filterObject = 'all';
|
|
207
204
|
}
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
205
|
+
else {
|
|
206
|
+
if (options.where) {
|
|
207
|
+
filterObject = options.where.toJson();
|
|
208
|
+
if (options.args === undefined)
|
|
209
|
+
if (addFilterToUrlAndReturnTrueIfSuccessful(filterObject, url))
|
|
210
|
+
filterObject = undefined;
|
|
211
|
+
}
|
|
212
|
+
if (options.orderBy && options.orderBy.Segments) {
|
|
213
|
+
let sort = '';
|
|
214
|
+
let order = '';
|
|
215
|
+
let hasDescending = false;
|
|
216
|
+
options.orderBy.Segments.forEach((c) => {
|
|
217
|
+
if (sort.length > 0) {
|
|
218
|
+
sort += ',';
|
|
219
|
+
order += ',';
|
|
220
|
+
}
|
|
221
|
+
sort += c.field.key;
|
|
222
|
+
order += c.isDescending ? 'desc' : 'asc';
|
|
223
|
+
if (c.isDescending)
|
|
224
|
+
hasDescending = true;
|
|
225
|
+
});
|
|
226
|
+
if (sort)
|
|
227
|
+
url.add('_sort', sort);
|
|
228
|
+
if (hasDescending)
|
|
229
|
+
url.add('_order', order);
|
|
230
|
+
}
|
|
231
|
+
if (options.limit)
|
|
232
|
+
url.add('_limit', options.limit);
|
|
233
|
+
if (options.page)
|
|
234
|
+
url.add('_page', options.page);
|
|
235
|
+
if (options.select) {
|
|
236
|
+
url.add('_select', options.select.join(','));
|
|
237
|
+
}
|
|
233
238
|
}
|
|
234
239
|
}
|
|
235
240
|
const run = (action, body) => {
|
|
@@ -246,7 +251,7 @@ export class RestEntityDataProvider {
|
|
|
246
251
|
else
|
|
247
252
|
body = { ...body, where: filterObject };
|
|
248
253
|
}
|
|
249
|
-
if (options
|
|
254
|
+
if (options && 'args' in options)
|
|
250
255
|
body.args = options.args;
|
|
251
256
|
if (body && method != 'put')
|
|
252
257
|
return this.http().post(u.url, body);
|
|
@@ -269,10 +274,16 @@ export class RestEntityDataProvider {
|
|
|
269
274
|
},
|
|
270
275
|
};
|
|
271
276
|
}
|
|
272
|
-
update(id, data) {
|
|
277
|
+
update(id, data, options) {
|
|
278
|
+
const urlArgs = [];
|
|
279
|
+
if (id == '')
|
|
280
|
+
urlArgs.push('__action=emptyId');
|
|
281
|
+
if (options?.select === 'none')
|
|
282
|
+
urlArgs.push('_select=$none');
|
|
273
283
|
return this.http()
|
|
274
284
|
.put(this.url() +
|
|
275
|
-
(id != '' ? '/' + encodeURIComponent(id) : '
|
|
285
|
+
(id != '' ? '/' + encodeURIComponent(id) : '') +
|
|
286
|
+
(urlArgs.length > 0 ? '?' + urlArgs.join('&') : ''), this.toJsonOfIncludedKeys(data))
|
|
276
287
|
.then((y) => this.translateFromJson(y));
|
|
277
288
|
}
|
|
278
289
|
toJsonOfIncludedKeys(data) {
|
|
@@ -290,14 +301,14 @@ export class RestEntityDataProvider {
|
|
|
290
301
|
else
|
|
291
302
|
return this.http().delete(this.url() + '/' + encodeURIComponent(id));
|
|
292
303
|
}
|
|
293
|
-
insert(data) {
|
|
304
|
+
insert(data, options) {
|
|
294
305
|
return this.http()
|
|
295
|
-
.post(this.url(), this.translateToJson(data))
|
|
306
|
+
.post(this.url() + (options?.select === 'none' ? '?_select=$none' : ''), this.translateToJson(data))
|
|
296
307
|
.then((y) => this.translateFromJson(y));
|
|
297
308
|
}
|
|
298
|
-
insertMany(data) {
|
|
309
|
+
insertMany(data, options) {
|
|
299
310
|
return this.http()
|
|
300
|
-
.post(this.url(), data.map((data) => this.translateToJson(data)))
|
|
311
|
+
.post(this.url() + (options?.select === 'none' ? '?_select=$none' : ''), data.map((data) => this.translateToJson(data)))
|
|
301
312
|
.then((y) => y.map((y) => this.translateFromJson(y)));
|
|
302
313
|
}
|
|
303
314
|
}
|
|
@@ -392,7 +392,7 @@ class ActualSQLEntityDataProvider {
|
|
|
392
392
|
}
|
|
393
393
|
return { colKeys, select };
|
|
394
394
|
}
|
|
395
|
-
async update(id, data) {
|
|
395
|
+
async update(id, data, options) {
|
|
396
396
|
let e = await this.init();
|
|
397
397
|
let r = this.sql.createCommand();
|
|
398
398
|
let statement = 'update ' + e.$entityName + ' set ';
|
|
@@ -419,6 +419,8 @@ class ActualSQLEntityDataProvider {
|
|
|
419
419
|
let returning = true;
|
|
420
420
|
if (this.sql._getSourceSql().doesNotSupportReturningSyntax)
|
|
421
421
|
returning = false;
|
|
422
|
+
if (options?.select === 'none')
|
|
423
|
+
returning = false;
|
|
422
424
|
if (returning &&
|
|
423
425
|
this.sql._getSourceSql().doesNotSupportReturningSyntaxOnlyForUpdate)
|
|
424
426
|
returning = false;
|
|
@@ -427,6 +429,8 @@ class ActualSQLEntityDataProvider {
|
|
|
427
429
|
return r.execute(statement).then((sqlResult) => {
|
|
428
430
|
this.sql._getSourceSql().afterMutation?.();
|
|
429
431
|
if (!returning) {
|
|
432
|
+
if (options?.select === 'none')
|
|
433
|
+
return undefined;
|
|
430
434
|
return getRowAfterUpdate(this.entity, this, data, id, 'update');
|
|
431
435
|
}
|
|
432
436
|
if (sqlResult.rows.length != 1)
|
|
@@ -448,7 +452,7 @@ class ActualSQLEntityDataProvider {
|
|
|
448
452
|
this.sql._getSourceSql().afterMutation?.();
|
|
449
453
|
});
|
|
450
454
|
}
|
|
451
|
-
async insert(data) {
|
|
455
|
+
async insert(data, options) {
|
|
452
456
|
let e = await this.init();
|
|
453
457
|
let r = this.sql.createCommand();
|
|
454
458
|
let cols = '';
|
|
@@ -473,7 +477,8 @@ class ActualSQLEntityDataProvider {
|
|
|
473
477
|
}
|
|
474
478
|
let statement = `insert into ${e.$entityName} (${cols}) values (${vals})`;
|
|
475
479
|
let { colKeys, select } = await this.buildSelect(e, r, undefined, undefined);
|
|
476
|
-
if (!this.sql._getSourceSql().doesNotSupportReturningSyntax
|
|
480
|
+
if (!this.sql._getSourceSql().doesNotSupportReturningSyntax &&
|
|
481
|
+
!(options?.select === 'none'))
|
|
477
482
|
statement += ' returning ' + select;
|
|
478
483
|
return await r.execute(statement).then((sql) => {
|
|
479
484
|
this.sql._getSourceSql().afterMutation?.();
|
|
@@ -483,14 +488,20 @@ class ActualSQLEntityDataProvider {
|
|
|
483
488
|
if (typeof id !== 'number')
|
|
484
489
|
throw new Error('Auto increment, for a database that is does not support returning syntax, should return an array with the single last added id. Instead it returned: ' +
|
|
485
490
|
JSON.stringify(id));
|
|
491
|
+
if (options?.select === 'none')
|
|
492
|
+
return undefined;
|
|
486
493
|
return this.find({
|
|
487
494
|
where: new Filter((x) => x.isEqualTo(this.entity.idMetadata.field, id)),
|
|
488
495
|
}).then((r) => r[0]);
|
|
489
496
|
}
|
|
490
497
|
else {
|
|
498
|
+
if (options?.select === 'none')
|
|
499
|
+
return undefined;
|
|
491
500
|
return getRowAfterUpdate(this.entity, this, data, undefined, 'insert');
|
|
492
501
|
}
|
|
493
502
|
}
|
|
503
|
+
if (options?.select === 'none')
|
|
504
|
+
return undefined;
|
|
494
505
|
return this.buildResultRow(colKeys, sql.rows[0], sql);
|
|
495
506
|
});
|
|
496
507
|
}
|
package/esm/src/remult-proxy.js
CHANGED
|
@@ -156,10 +156,10 @@ export class RemultProxy {
|
|
|
156
156
|
.remultFactory()
|
|
157
157
|
.repo(...args)
|
|
158
158
|
.getEntityRef(...args2),
|
|
159
|
-
insert: (args2) => self
|
|
159
|
+
insert: (args2, args3) => self
|
|
160
160
|
.remultFactory()
|
|
161
161
|
.repo(...args)
|
|
162
|
-
.insert(args2),
|
|
162
|
+
.insert(args2, args3),
|
|
163
163
|
liveQuery: (...args2) => self
|
|
164
164
|
.remultFactory()
|
|
165
165
|
.repo(...args)
|
|
@@ -179,10 +179,10 @@ export class RemultProxy {
|
|
|
179
179
|
.remultFactory()
|
|
180
180
|
.repo(...args)
|
|
181
181
|
.upsert(args2),
|
|
182
|
-
update: (a, b) => self
|
|
182
|
+
update: (a, b, c) => self
|
|
183
183
|
.remultFactory()
|
|
184
184
|
.repo(...args)
|
|
185
|
-
.update(a, b),
|
|
185
|
+
.update(a, b, c),
|
|
186
186
|
};
|
|
187
187
|
entityCache.set(args[1], result);
|
|
188
188
|
return result;
|
|
@@ -317,7 +317,7 @@ export class RepositoryImplementation {
|
|
|
317
317
|
for (const field of this.fields) {
|
|
318
318
|
}
|
|
319
319
|
}
|
|
320
|
-
async insert(entity) {
|
|
320
|
+
async insert(entity, options) {
|
|
321
321
|
if (Array.isArray(entity)) {
|
|
322
322
|
if (this._dataProvider.isProxy) {
|
|
323
323
|
let refs = [];
|
|
@@ -335,27 +335,36 @@ export class RepositoryImplementation {
|
|
|
335
335
|
refs.push(ref);
|
|
336
336
|
raw.push(await ref.buildDtoForInsert());
|
|
337
337
|
}
|
|
338
|
-
|
|
338
|
+
const inserted = await this._edp.insertMany(raw, options);
|
|
339
|
+
if (options?.select === 'none')
|
|
340
|
+
return undefined;
|
|
341
|
+
return promiseAll(inserted, (item, i) => refs[i].processInsertResponseDto(item));
|
|
339
342
|
}
|
|
340
343
|
else {
|
|
341
344
|
let r = [];
|
|
342
345
|
for (const item of entity) {
|
|
343
|
-
r.push(await this.insert(item));
|
|
346
|
+
r.push(await this.insert(item, options));
|
|
344
347
|
}
|
|
348
|
+
if (options?.select === 'none')
|
|
349
|
+
return undefined;
|
|
345
350
|
return r;
|
|
346
351
|
}
|
|
347
352
|
}
|
|
348
353
|
else {
|
|
349
354
|
let ref = getEntityRef(entity, false);
|
|
355
|
+
let result = undefined;
|
|
350
356
|
if (ref) {
|
|
351
357
|
if (!ref.isNew())
|
|
352
358
|
throw 'Item is not new';
|
|
353
|
-
|
|
359
|
+
result = await ref.save(options);
|
|
354
360
|
}
|
|
355
361
|
else {
|
|
356
362
|
this.__cleanupPartialObject(entity);
|
|
357
|
-
|
|
363
|
+
result = await this.getEntityRef(this.create(entity)).save(options);
|
|
358
364
|
}
|
|
365
|
+
if (options?.select === 'none')
|
|
366
|
+
return undefined;
|
|
367
|
+
return result;
|
|
359
368
|
}
|
|
360
369
|
}
|
|
361
370
|
get fields() {
|
|
@@ -399,7 +408,7 @@ export class RepositoryImplementation {
|
|
|
399
408
|
this.__cleanupPartialObject(set);
|
|
400
409
|
Filter.throwErrorIfFilterIsEmpty(where, 'updateMany');
|
|
401
410
|
if (this._dataProvider.isProxy) {
|
|
402
|
-
return this._edp.updateMany(await this._translateWhereToFilter(where), this.__createDto({ ...set }));
|
|
411
|
+
return this._edp.updateMany(where === 'all' ? 'all' : await this._translateWhereToFilter(where), this.__createDto({ ...set }));
|
|
403
412
|
}
|
|
404
413
|
else {
|
|
405
414
|
let updated = 0;
|
|
@@ -411,17 +420,22 @@ export class RepositoryImplementation {
|
|
|
411
420
|
return updated;
|
|
412
421
|
}
|
|
413
422
|
}
|
|
414
|
-
async update(id, entity) {
|
|
423
|
+
async update(id, entity, options) {
|
|
424
|
+
function returnResult(result) {
|
|
425
|
+
if (options?.select === 'none')
|
|
426
|
+
return undefined;
|
|
427
|
+
return result;
|
|
428
|
+
}
|
|
415
429
|
{
|
|
416
430
|
let ref = getEntityRef(entity, false);
|
|
417
431
|
if (ref)
|
|
418
|
-
return (await ref.save());
|
|
432
|
+
return returnResult((await ref.save(options)));
|
|
419
433
|
}
|
|
420
434
|
{
|
|
421
435
|
let ref = getEntityRef(id, false);
|
|
422
436
|
if (ref) {
|
|
423
437
|
assign(id, entity);
|
|
424
|
-
return ref.save();
|
|
438
|
+
return returnResult(await ref.save(options));
|
|
425
439
|
}
|
|
426
440
|
}
|
|
427
441
|
this.__cleanupPartialObject(entity);
|
|
@@ -433,7 +447,7 @@ export class RepositoryImplementation {
|
|
|
433
447
|
else
|
|
434
448
|
ref = this._getRefForExistingRow(entity, id);
|
|
435
449
|
if (this._dataProvider.isProxy) {
|
|
436
|
-
return await ref.save(Object.keys(entity));
|
|
450
|
+
return returnResult(await ref.save(options, Object.keys(entity)));
|
|
437
451
|
}
|
|
438
452
|
else {
|
|
439
453
|
const r = await ref.reload();
|
|
@@ -450,7 +464,7 @@ export class RepositoryImplementation {
|
|
|
450
464
|
}
|
|
451
465
|
}
|
|
452
466
|
await this._fixTypes(r);
|
|
453
|
-
return await ref.save();
|
|
467
|
+
return returnResult(await ref.save(options));
|
|
454
468
|
}
|
|
455
469
|
}
|
|
456
470
|
async upsert(options) {
|
|
@@ -855,7 +869,7 @@ export class RepositoryImplementation {
|
|
|
855
869
|
async deleteMany({ where, }) {
|
|
856
870
|
Filter.throwErrorIfFilterIsEmpty(where, 'deleteMany');
|
|
857
871
|
if (this._dataProvider.isProxy) {
|
|
858
|
-
return this._edp.deleteMany(await this._translateWhereToFilter(where));
|
|
872
|
+
return this._edp.deleteMany(where === 'all' ? 'all' : await this._translateWhereToFilter(where));
|
|
859
873
|
}
|
|
860
874
|
else {
|
|
861
875
|
let deleted = 0;
|
|
@@ -1374,6 +1388,15 @@ export class rowHelperImplementation extends rowHelperBase {
|
|
|
1374
1388
|
repo;
|
|
1375
1389
|
edp;
|
|
1376
1390
|
_isNew;
|
|
1391
|
+
async _updateResultsFromServerAction(rowInfo) {
|
|
1392
|
+
await this._updateEntityBasedOnApi(rowInfo.data, true);
|
|
1393
|
+
if (this._isNew != rowInfo.isNewRow) {
|
|
1394
|
+
this._isNew = rowInfo.isNewRow;
|
|
1395
|
+
this.originalId = rowInfo.id;
|
|
1396
|
+
}
|
|
1397
|
+
if (!rowInfo.wasChanged)
|
|
1398
|
+
this.originalValues = this.copyDataToObject();
|
|
1399
|
+
}
|
|
1377
1400
|
constructor(info, instance, repo, edp, remult, _isNew, excludeRelationMembers) {
|
|
1378
1401
|
super(info.fieldsMetadata, instance, remult, _isNew, excludeRelationMembers);
|
|
1379
1402
|
this.info = info;
|
|
@@ -1474,7 +1497,7 @@ export class rowHelperImplementation extends rowHelperBase {
|
|
|
1474
1497
|
return this._columns;
|
|
1475
1498
|
}
|
|
1476
1499
|
_saving = false;
|
|
1477
|
-
async save(onlyTheseFieldsSentOnlyInTheCaseOfProxySaveWithPartialObject) {
|
|
1500
|
+
async save(options, onlyTheseFieldsSentOnlyInTheCaseOfProxySaveWithPartialObject) {
|
|
1478
1501
|
try {
|
|
1479
1502
|
if (this._saving)
|
|
1480
1503
|
throw new Error('cannot save while entity is already saving');
|
|
@@ -1517,13 +1540,13 @@ export class rowHelperImplementation extends rowHelperBase {
|
|
|
1517
1540
|
try {
|
|
1518
1541
|
this._subscribers?.reportChanged();
|
|
1519
1542
|
if (this.isNew()) {
|
|
1520
|
-
if (doNotSave) {
|
|
1543
|
+
if (doNotSave && options?.select !== 'none') {
|
|
1521
1544
|
updatedRow = (updatedRow = await this.edp.find({
|
|
1522
1545
|
where: await this.getIdFilter(),
|
|
1523
1546
|
}))[0];
|
|
1524
1547
|
}
|
|
1525
1548
|
else
|
|
1526
|
-
updatedRow = await this.edp.insert(d);
|
|
1549
|
+
updatedRow = await this.edp.insert(d, options);
|
|
1527
1550
|
}
|
|
1528
1551
|
else {
|
|
1529
1552
|
let changesOnly = {};
|
|
@@ -1542,12 +1565,13 @@ export class rowHelperImplementation extends rowHelperBase {
|
|
|
1542
1565
|
if (!wasChanged)
|
|
1543
1566
|
return this.instance;
|
|
1544
1567
|
if (doNotSave) {
|
|
1545
|
-
|
|
1568
|
+
if (options?.select !== 'none')
|
|
1569
|
+
updatedRow = (await this.edp.find({ where: await this.getIdFilter() }))[0];
|
|
1546
1570
|
}
|
|
1547
1571
|
else {
|
|
1548
1572
|
if (this.id === undefined)
|
|
1549
1573
|
throw new Error('Invalid operation, id is undefined');
|
|
1550
|
-
updatedRow = await this.edp.update(this.id, changesOnly);
|
|
1574
|
+
updatedRow = await this.edp.update(this.id, changesOnly, options);
|
|
1551
1575
|
}
|
|
1552
1576
|
}
|
|
1553
1577
|
if (updatedRow)
|
package/esm/src/server-action.js
CHANGED
|
@@ -193,7 +193,7 @@ export function BackendMethod(options) {
|
|
|
193
193
|
reg(controllerOptions.key +
|
|
194
194
|
'/' +
|
|
195
195
|
(options?.apiPrefix ? options.apiPrefix + '/' : '') +
|
|
196
|
-
key, options ? options.queue ?? false : false, options.allowed, async (d, req, res) => {
|
|
196
|
+
key, options ? (options.queue ?? false) : false, options.allowed, async (d, req, res) => {
|
|
197
197
|
d.args = d.args.map((x) => (isCustomUndefined(x) ? undefined : x));
|
|
198
198
|
let allowed = options.allowed;
|
|
199
199
|
try {
|
|
@@ -295,7 +295,7 @@ export function BackendMethod(options) {
|
|
|
295
295
|
id: defs.getOriginalId(),
|
|
296
296
|
},
|
|
297
297
|
}, baseUrl, http);
|
|
298
|
-
await defs.
|
|
298
|
+
await defs._updateResultsFromServerAction(r.rowInfo);
|
|
299
299
|
return r.result;
|
|
300
300
|
}
|
|
301
301
|
catch (err) {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { InputTypes } from '../inputTypes.js';
|
|
2
|
+
const zeroDate = new Date('0000-01-01');
|
|
2
3
|
export class ValueConverters {
|
|
3
4
|
static Date = {
|
|
4
5
|
toJson: (val) => {
|
|
@@ -65,6 +66,8 @@ export class ValueConverters {
|
|
|
65
66
|
fromJson: (value) => {
|
|
66
67
|
if (!value || value == '' || value == '0000-00-00')
|
|
67
68
|
return null;
|
|
69
|
+
if (value == '0000-01-01')
|
|
70
|
+
return zeroDate;
|
|
68
71
|
let d = new Date(Date.parse(value));
|
|
69
72
|
d.setMinutes(d.getMinutes() + d.getTimezoneOffset());
|
|
70
73
|
return d;
|
|
@@ -88,6 +91,8 @@ export class ValueConverters {
|
|
|
88
91
|
static DateOnlyString = {
|
|
89
92
|
...ValueConverters.DateOnly,
|
|
90
93
|
toDb: (d) => {
|
|
94
|
+
if (d === zeroDate)
|
|
95
|
+
return '00000000';
|
|
91
96
|
let val = ValueConverters.DateOnly.toJson(d);
|
|
92
97
|
if (!val)
|
|
93
98
|
return undefined;
|
|
@@ -98,12 +103,11 @@ export class ValueConverters {
|
|
|
98
103
|
return null;
|
|
99
104
|
if (!val)
|
|
100
105
|
return undefined;
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
'-' +
|
|
105
|
-
val.substring(6, 8));
|
|
106
|
+
if (val === '00000000')
|
|
107
|
+
return zeroDate;
|
|
108
|
+
return new Date(Number(val.substring(0, 4)), Number(val.substring(4, 6)) - 1, Number(val.substring(6, 8)));
|
|
106
109
|
},
|
|
110
|
+
zeroDate,
|
|
107
111
|
};
|
|
108
112
|
static Boolean = {
|
|
109
113
|
toDb: (val) => val,
|
package/graphql.js
CHANGED
|
@@ -443,7 +443,7 @@ function remultGraphql(options) {
|
|
|
443
443
|
setResult((_a = {},
|
|
444
444
|
_a[toCamelCase(getMetaType(meta))] = y,
|
|
445
445
|
_a));
|
|
446
|
-
} }), arg1.id, arg1.patch)];
|
|
446
|
+
} }), { get: function () { return undefined; } }, arg1.id, arg1.patch)];
|
|
447
447
|
case 1:
|
|
448
448
|
_a.sent();
|
|
449
449
|
return [2 /*return*/];
|
package/index.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ import type { ClassType } from './classType.js';
|
|
|
2
2
|
import type { DataProvider } from './src/data-interfaces.js';
|
|
3
3
|
export { ArrayEntityDataProvider } from './src/data-providers/array-entity-data-provider.js';
|
|
4
4
|
export type { ClassType } from './classType.js';
|
|
5
|
-
export { ValidateFieldEvent, MembersOnly, NumericKeys, FieldsMetadata, FieldRef, IdFieldRef, FieldsRef, EntityMetadata, EntityOrderBy, EntityFilter, FindOptions, FindOptionsBase, QueryResult, QueryOptions, UpsertOptions, Repository, GroupByOptions, GroupByResult, FindFirstOptions, ComparisonValueFilter, ValueFilter, IdFilter, ContainsStringValueFilter, EntityRef, SortSegments, Paginator, LiveQuery, LiveQueryChangeInfo, Subscribable, RefSubscriber, RefSubscriberBase, RelationOptions, ObjectMembersOnly, MembersToInclude, RepositoryRelations, EntityIdFields, EntitySelectFields, ClassFieldDecorator, ClassFieldDecoratorContextStub, //n1 consider removing in ts5
|
|
5
|
+
export { ValidateFieldEvent, MembersOnly, NumericKeys, FieldsMetadata, FieldRef, IdFieldRef, FieldsRef, EntityMetadata, EntityOrderBy, EntityFilter, FindOptions, FindOptionsBase, QueryResult, QueryOptions, UpsertOptions, Repository, GroupByOptions, GroupByResult, FindFirstOptions, ComparisonValueFilter, ValueFilter, IdFilter, ContainsStringValueFilter, EntityRef, SortSegments, Paginator, LiveQuery, LiveQueryChangeInfo, Subscribable, RefSubscriber, RefSubscriberBase, RelationOptions, ObjectMembersOnly, MembersToInclude, RepositoryRelations, EntityIdFields, EntitySelectFields, InsertOrUpdateOptions, ClassFieldDecorator, ClassFieldDecoratorContextStub, //n1 consider removing in ts5
|
|
6
6
|
LifecycleEvent, FieldsRefBase, FieldsRefForEntityBase, RepositoryRelationsForEntityBase, ControllerRefForControllerBase, ControllerRefBase, ControllerRef, EntityRefForEntityBase, IdMetadata, FindFirstOptionsBase, } from './src/remult3/remult3.js';
|
|
7
7
|
export { standardSchema } from './src/standard-schema/index.js';
|
|
8
8
|
export { EntityBase, ControllerBase, FieldType, getFields, ValueListFieldType, getValueList, ValueListFieldOptions, ValueListInfo, } from './src/remult3/RepositoryImplementation.js';
|