remult 3.2.3 → 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/remult-api-server.js +1 -1
- package/esm/src/data-api.js +30 -19
- package/esm/src/data-providers/rest-data-provider.js +50 -35
- package/esm/src/data-providers/sql-database.js +35 -13
- package/esm/src/filter/fieldDbName.js +4 -1
- package/esm/src/filter/filter-consumer-bridge-to-sql-request.js +5 -2
- package/esm/src/remult-proxy.js +4 -4
- package/esm/src/remult3/RepositoryImplementation.js +34 -17
- package/esm/src/remult3/remult3.js +8 -0
- package/esm/src/valueConverters.js +10 -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/remult-api-server.js +1 -0
- package/src/column-interfaces.d.ts +3 -1
- package/src/data-api.d.ts +4 -4
- package/src/data-api.js +50 -30
- package/src/data-interfaces.d.ts +7 -6
- package/src/data-providers/rest-data-provider.d.ts +4 -4
- package/src/data-providers/rest-data-provider.js +50 -35
- package/src/data-providers/sql-database.js +158 -90
- package/src/filter/fieldDbName.d.ts +2 -1
- package/src/filter/fieldDbName.js +5 -1
- package/src/filter/filter-consumer-bridge-to-sql-request.d.ts +1 -0
- package/src/filter/filter-consumer-bridge-to-sql-request.js +7 -2
- package/src/remult-proxy.js +4 -4
- package/src/remult3/RepositoryImplementation.d.ts +6 -6
- package/src/remult3/RepositoryImplementation.js +209 -169
- package/src/remult3/remult3.d.ts +11 -7
- package/src/remult3/remult3.js +8 -0
- package/src/valueConverters.d.ts +3 -1
- package/src/valueConverters.js +10 -6
|
@@ -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) {
|
|
@@ -583,6 +597,8 @@ export class RepositoryImplementation {
|
|
|
583
597
|
options = { ...options };
|
|
584
598
|
let opt = {};
|
|
585
599
|
opt = {};
|
|
600
|
+
if (options.args)
|
|
601
|
+
opt.args = options.args;
|
|
586
602
|
if (options.select) {
|
|
587
603
|
opt.select = Object.keys(options.select)
|
|
588
604
|
.filter((x) => options.select[x])
|
|
@@ -853,7 +869,7 @@ export class RepositoryImplementation {
|
|
|
853
869
|
async deleteMany({ where, }) {
|
|
854
870
|
Filter.throwErrorIfFilterIsEmpty(where, 'deleteMany');
|
|
855
871
|
if (this._dataProvider.isProxy) {
|
|
856
|
-
return this._edp.deleteMany(await this._translateWhereToFilter(where));
|
|
872
|
+
return this._edp.deleteMany(where === 'all' ? 'all' : await this._translateWhereToFilter(where));
|
|
857
873
|
}
|
|
858
874
|
else {
|
|
859
875
|
let deleted = 0;
|
|
@@ -1481,7 +1497,7 @@ export class rowHelperImplementation extends rowHelperBase {
|
|
|
1481
1497
|
return this._columns;
|
|
1482
1498
|
}
|
|
1483
1499
|
_saving = false;
|
|
1484
|
-
async save(onlyTheseFieldsSentOnlyInTheCaseOfProxySaveWithPartialObject) {
|
|
1500
|
+
async save(options, onlyTheseFieldsSentOnlyInTheCaseOfProxySaveWithPartialObject) {
|
|
1485
1501
|
try {
|
|
1486
1502
|
if (this._saving)
|
|
1487
1503
|
throw new Error('cannot save while entity is already saving');
|
|
@@ -1524,13 +1540,13 @@ export class rowHelperImplementation extends rowHelperBase {
|
|
|
1524
1540
|
try {
|
|
1525
1541
|
this._subscribers?.reportChanged();
|
|
1526
1542
|
if (this.isNew()) {
|
|
1527
|
-
if (doNotSave) {
|
|
1543
|
+
if (doNotSave && options?.select !== 'none') {
|
|
1528
1544
|
updatedRow = (updatedRow = await this.edp.find({
|
|
1529
1545
|
where: await this.getIdFilter(),
|
|
1530
1546
|
}))[0];
|
|
1531
1547
|
}
|
|
1532
1548
|
else
|
|
1533
|
-
updatedRow = await this.edp.insert(d);
|
|
1549
|
+
updatedRow = await this.edp.insert(d, options);
|
|
1534
1550
|
}
|
|
1535
1551
|
else {
|
|
1536
1552
|
let changesOnly = {};
|
|
@@ -1549,12 +1565,13 @@ export class rowHelperImplementation extends rowHelperBase {
|
|
|
1549
1565
|
if (!wasChanged)
|
|
1550
1566
|
return this.instance;
|
|
1551
1567
|
if (doNotSave) {
|
|
1552
|
-
|
|
1568
|
+
if (options?.select !== 'none')
|
|
1569
|
+
updatedRow = (await this.edp.find({ where: await this.getIdFilter() }))[0];
|
|
1553
1570
|
}
|
|
1554
1571
|
else {
|
|
1555
1572
|
if (this.id === undefined)
|
|
1556
1573
|
throw new Error('Invalid operation, id is undefined');
|
|
1557
|
-
updatedRow = await this.edp.update(this.id, changesOnly);
|
|
1574
|
+
updatedRow = await this.edp.update(this.id, changesOnly, options);
|
|
1558
1575
|
}
|
|
1559
1576
|
}
|
|
1560
1577
|
if (updatedRow)
|
|
@@ -41,6 +41,14 @@ export const flags = {
|
|
|
41
41
|
|
|
42
42
|
-
|
|
43
43
|
*/
|
|
44
|
+
/*p1 - https://github.com/remult/remult/discussions/438
|
|
45
|
+
- should we use the arg for update and insert? for the returning query?
|
|
46
|
+
- Does dbNamesOf still makes sense? I think that abstraction, regarding sql expression has lost it's merit
|
|
47
|
+
- remember caching of sql expression calculations that took a recursive amount of time for JYC
|
|
48
|
+
- maybe introduce a ready dbNamesOf of argument that will be aware of prefixes
|
|
49
|
+
- I've changed the order by to support order by 1
|
|
50
|
+
|
|
51
|
+
*/
|
|
44
52
|
//p1 - deleteAll({title:undefined}) should throw an error - not return 0 (with direct call to db)
|
|
45
53
|
//p1 - remult-create, move db question ahead of auth - everyone needs a database, not everyone need auth
|
|
46
54
|
//p1 - allow experimental route registration on remult server, with at least get route, and support redirect, read header and set header - (and the existing get html etc...)
|
|
@@ -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,
|
|
@@ -175,6 +179,7 @@ export class ValueConverters {
|
|
|
175
179
|
toDb: (x) => ValueConverters.JsonString.toDb(x),
|
|
176
180
|
fromInput: (x) => ValueConverters.Default.fromJson(x),
|
|
177
181
|
toInput: (x) => ValueConverters.Default.toJson(x),
|
|
182
|
+
toDbSql: (x) => x,
|
|
178
183
|
displayValue: (x) => x + '',
|
|
179
184
|
fieldTypeInDb: '',
|
|
180
185
|
inputType: 'text',
|
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';
|
package/package.json
CHANGED
package/remult-knex/index.js
CHANGED
|
@@ -354,7 +354,7 @@ var KnexEntityDataProvider = /** @class */ (function () {
|
|
|
354
354
|
});
|
|
355
355
|
});
|
|
356
356
|
};
|
|
357
|
-
KnexEntityDataProvider.prototype.update = function (id, data) {
|
|
357
|
+
KnexEntityDataProvider.prototype.update = function (id, data, options) {
|
|
358
358
|
return tslib_1.__awaiter(this, void 0, void 0, function () {
|
|
359
359
|
var e, f, updateObject, _a, _b, x, v, key, e_4_1, where;
|
|
360
360
|
var e_4, _c;
|
|
@@ -407,6 +407,8 @@ var KnexEntityDataProvider = /** @class */ (function () {
|
|
|
407
407
|
.where(function (b) { return where.forEach(function (w) { return w(b); }); })];
|
|
408
408
|
case 12:
|
|
409
409
|
_d.sent();
|
|
410
|
+
if ((options === null || options === void 0 ? void 0 : options.select) === 'none')
|
|
411
|
+
return [2 /*return*/, undefined];
|
|
410
412
|
return [2 /*return*/, (0, sql_database_js_1.getRowAfterUpdate)(this.entity, this, data, id, 'update')];
|
|
411
413
|
}
|
|
412
414
|
});
|
|
@@ -435,7 +437,7 @@ var KnexEntityDataProvider = /** @class */ (function () {
|
|
|
435
437
|
});
|
|
436
438
|
});
|
|
437
439
|
};
|
|
438
|
-
KnexEntityDataProvider.prototype.insert = function (data) {
|
|
440
|
+
KnexEntityDataProvider.prototype.insert = function (data, options) {
|
|
439
441
|
return tslib_1.__awaiter(this, void 0, void 0, function () {
|
|
440
442
|
var e, insertObject, _a, _b, x, v, key, e_5_1, insert, newId_1, result, result;
|
|
441
443
|
var e_5, _c;
|
|
@@ -493,16 +495,22 @@ var KnexEntityDataProvider = /** @class */ (function () {
|
|
|
493
495
|
result = _d.sent();
|
|
494
496
|
newId_1 = result[0][this.entity.idMetadata.field.dbName];
|
|
495
497
|
_d.label = 14;
|
|
496
|
-
case 14:
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
498
|
+
case 14:
|
|
499
|
+
if ((options === null || options === void 0 ? void 0 : options.select) === 'none')
|
|
500
|
+
return [2 /*return*/, undefined];
|
|
501
|
+
return [2 /*return*/, this.find({
|
|
502
|
+
where: new filter_interfaces_js_1.Filter(function (x) {
|
|
503
|
+
return x.isEqualTo(_this.entity.idMetadata.field, newId_1);
|
|
504
|
+
}),
|
|
505
|
+
}).then(function (y) { return y[0]; })];
|
|
501
506
|
case 15: return [4 /*yield*/, insert];
|
|
502
507
|
case 16:
|
|
503
508
|
_d.sent();
|
|
504
509
|
_d.label = 17;
|
|
505
|
-
case 17:
|
|
510
|
+
case 17:
|
|
511
|
+
if ((options === null || options === void 0 ? void 0 : options.select) === 'none')
|
|
512
|
+
return [2 /*return*/, undefined];
|
|
513
|
+
return [2 /*return*/, (0, sql_database_js_1.getRowAfterUpdate)(this.entity, this, data, undefined, 'insert')];
|
|
506
514
|
}
|
|
507
515
|
});
|
|
508
516
|
});
|
package/remult-mongo.js
CHANGED
|
@@ -476,7 +476,7 @@ var MongoEntityDataProvider = /** @class */ (function () {
|
|
|
476
476
|
});
|
|
477
477
|
});
|
|
478
478
|
};
|
|
479
|
-
MongoEntityDataProvider.prototype.update = function (id, data) {
|
|
479
|
+
MongoEntityDataProvider.prototype.update = function (id, data, options) {
|
|
480
480
|
return tslib_1.__awaiter(this, void 0, void 0, function () {
|
|
481
481
|
var _a, collection, e, f, newR, keys, _b, _c, f_1, r, _d, _e;
|
|
482
482
|
var e_11, _f;
|
|
@@ -514,6 +514,8 @@ var MongoEntityDataProvider = /** @class */ (function () {
|
|
|
514
514
|
{ session: this.session }])];
|
|
515
515
|
case 3:
|
|
516
516
|
r = _g.sent();
|
|
517
|
+
if ((options === null || options === void 0 ? void 0 : options.select) === 'none')
|
|
518
|
+
return [2 /*return*/, undefined];
|
|
517
519
|
return [2 /*return*/, (0, sql_database_js_1.getRowAfterUpdate)(this.entity, this, data, id, 'update')];
|
|
518
520
|
}
|
|
519
521
|
});
|
|
@@ -541,7 +543,7 @@ var MongoEntityDataProvider = /** @class */ (function () {
|
|
|
541
543
|
});
|
|
542
544
|
});
|
|
543
545
|
};
|
|
544
|
-
MongoEntityDataProvider.prototype.insert = function (data) {
|
|
546
|
+
MongoEntityDataProvider.prototype.insert = function (data, options) {
|
|
545
547
|
return tslib_1.__awaiter(this, void 0, void 0, function () {
|
|
546
548
|
var _a, collection, e, r, _b, _c, _d;
|
|
547
549
|
return tslib_1.__generator(this, function (_e) {
|
|
@@ -556,6 +558,8 @@ var MongoEntityDataProvider = /** @class */ (function () {
|
|
|
556
558
|
}])];
|
|
557
559
|
case 3:
|
|
558
560
|
r = _e.sent();
|
|
561
|
+
if ((options === null || options === void 0 ? void 0 : options.select) === 'none')
|
|
562
|
+
return [2 /*return*/, undefined];
|
|
559
563
|
_d = this.translateFromDb;
|
|
560
564
|
return [4 /*yield*/, collection.findOne({ _id: r.insertedId }, { session: this.session })];
|
|
561
565
|
case 4: return [4 /*yield*/, _d.apply(this, [_e.sent(), e])];
|
|
@@ -579,6 +579,7 @@ var RemultServerImplementation = /** @class */ (function () {
|
|
|
579
579
|
case 0:
|
|
580
580
|
_b = (_a = dataApiFactory(c)).put;
|
|
581
581
|
_c = [res,
|
|
582
|
+
req,
|
|
582
583
|
reqInfo.params.id];
|
|
583
584
|
return [4 /*yield*/, this.coreOptions.getRequestBody(orig)];
|
|
584
585
|
case 1: return [2 /*return*/, _b.apply(_a, _c.concat([_d.sent()]))];
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { ClassType } from '../classType.js';
|
|
2
2
|
import type { AllowedForInstance } from './context.js';
|
|
3
3
|
import type { EntityMetadata, FieldRef, LifecycleEvent, ValidateFieldEvent } from './remult3/remult3.js';
|
|
4
|
+
import type { SqlCommandWithParameters } from './sql-command.js';
|
|
4
5
|
export interface FieldOptions<entityType = unknown, valueType = unknown> {
|
|
5
6
|
/** A human readable name for the field. Can be used to achieve a consistent caption for a field throughout the app
|
|
6
7
|
* @example
|
|
@@ -103,7 +104,7 @@ export interface FieldOptions<entityType = unknown, valueType = unknown> {
|
|
|
103
104
|
* @Fields.string()
|
|
104
105
|
* title='';
|
|
105
106
|
*/
|
|
106
|
-
sqlExpression?: string | ((entity: EntityMetadata<entityType
|
|
107
|
+
sqlExpression?: string | ((entity: EntityMetadata<entityType>, args?: any, command?: SqlCommandWithParameters) => string | Promise<string>);
|
|
107
108
|
/** For fields that shouldn't be part of an update or insert statement */
|
|
108
109
|
dbReadOnly?: boolean;
|
|
109
110
|
/** The value converter to be used when loading and saving this field */
|
|
@@ -293,6 +294,7 @@ export interface ValueConverter<valueType> {
|
|
|
293
294
|
* toDb: val => val?.toISOString()
|
|
294
295
|
*/
|
|
295
296
|
toDb?(val: valueType): any;
|
|
297
|
+
toDbSql?(val: string): string;
|
|
296
298
|
/**
|
|
297
299
|
* Converts a value of valueType to a string suitable for an HTML input element.
|
|
298
300
|
*
|
package/src/data-api.d.ts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import type { Remult } from './context.js';
|
|
2
2
|
import { type ErrorInfo } from './data-interfaces.js';
|
|
3
3
|
import { type EntityMetadata, type FindOptions, type Repository } from './remult3/remult3.js';
|
|
4
|
-
import type { rowHelperImplementation } from './remult3/RepositoryImplementation.js';
|
|
5
4
|
export declare class DataApi<T = unknown> {
|
|
6
5
|
private repository;
|
|
7
6
|
private remult;
|
|
@@ -17,6 +16,7 @@ export declare class DataApi<T = unknown> {
|
|
|
17
16
|
get(response: DataApiResponse, id: any): Promise<void>;
|
|
18
17
|
count(response: DataApiResponse, request: DataApiRequest, body?: any): Promise<void>;
|
|
19
18
|
deleteMany(response: DataApiResponse, request: DataApiRequest, body?: any): Promise<void>;
|
|
19
|
+
private prepareWhereForManyOperation;
|
|
20
20
|
groupBy(request: DataApiRequest, body: any): Promise<import("./remult3/remult3.js").GroupByResult<T, any[], any[], any[], any[], any[], any[]>[]>;
|
|
21
21
|
getArrayImpl(request: DataApiRequest, body: any): Promise<{
|
|
22
22
|
r: any[];
|
|
@@ -33,11 +33,11 @@ export declare class DataApi<T = unknown> {
|
|
|
33
33
|
where?: any;
|
|
34
34
|
set?: any;
|
|
35
35
|
}): Promise<void>;
|
|
36
|
-
actualUpdate(row: any, body: any): Promise<
|
|
37
|
-
put(response: DataApiResponse, id: any, body: any): Promise<void>;
|
|
36
|
+
actualUpdate(row: any, body: any, req: DataApiRequest): Promise<any>;
|
|
37
|
+
put(response: DataApiResponse, req: DataApiRequest, id: any, body: any): Promise<void>;
|
|
38
38
|
actualDelete(row: any): Promise<void>;
|
|
39
39
|
delete(response: DataApiResponse, id: any): Promise<void>;
|
|
40
|
-
post(body: any): Promise<any>;
|
|
40
|
+
post(body: any, req: DataApiRequest): Promise<any>;
|
|
41
41
|
}
|
|
42
42
|
export interface DataApiResponse {
|
|
43
43
|
success(data: any): void;
|
package/src/data-api.js
CHANGED
|
@@ -99,7 +99,7 @@ var DataApi = /** @class */ (function () {
|
|
|
99
99
|
case 12: return [2 /*return*/, _e.apply(_d, [_h.sent()])];
|
|
100
100
|
case 13:
|
|
101
101
|
_g = (_f = res).created;
|
|
102
|
-
return [4 /*yield*/, this.post(body)];
|
|
102
|
+
return [4 /*yield*/, this.post(body, req)];
|
|
103
103
|
case 14: return [2 /*return*/, _g.apply(_f, [_h.sent()])];
|
|
104
104
|
case 15: return [3 /*break*/, 17];
|
|
105
105
|
case 16:
|
|
@@ -146,16 +146,16 @@ var DataApi = /** @class */ (function () {
|
|
|
146
146
|
r = _f.sent();
|
|
147
147
|
if (!(r.length == 0)) return [3 /*break*/, 6];
|
|
148
148
|
_b = (_a = result).push;
|
|
149
|
-
return [4 /*yield*/, this.post(tslib_1.__assign(tslib_1.__assign({}, item.where), item.set))];
|
|
149
|
+
return [4 /*yield*/, this.post(tslib_1.__assign(tslib_1.__assign({}, item.where), item.set), request)];
|
|
150
150
|
case 5:
|
|
151
151
|
_b.apply(_a, [_f.sent()]);
|
|
152
152
|
return [3 /*break*/, 9];
|
|
153
153
|
case 6:
|
|
154
154
|
if (!(item.set !== undefined)) return [3 /*break*/, 8];
|
|
155
155
|
_d = (_c = result).push;
|
|
156
|
-
return [4 /*yield*/, this.actualUpdate(r[0], item.set)];
|
|
156
|
+
return [4 /*yield*/, this.actualUpdate(r[0], item.set, request)];
|
|
157
157
|
case 7:
|
|
158
|
-
_d.apply(_c, [
|
|
158
|
+
_d.apply(_c, [_f.sent()]);
|
|
159
159
|
return [3 /*break*/, 9];
|
|
160
160
|
case 8:
|
|
161
161
|
result.push(this.repository.getEntityRef(r[0]).toApiJson());
|
|
@@ -282,10 +282,9 @@ var DataApi = /** @class */ (function () {
|
|
|
282
282
|
case 0:
|
|
283
283
|
_a.trys.push([0, 3, , 4]);
|
|
284
284
|
deleted_1 = 0;
|
|
285
|
-
return [4 /*yield*/, this.
|
|
285
|
+
return [4 /*yield*/, this.prepareWhereForManyOperation(body, request)];
|
|
286
286
|
case 1:
|
|
287
287
|
where_1 = _a.sent();
|
|
288
|
-
filter_interfaces_js_1.Filter.throwErrorIfFilterIsEmpty(where_1, 'deleteMany');
|
|
289
288
|
return [4 /*yield*/, (0, context_js_1.doTransaction)(this.remult, function () { return tslib_1.__awaiter(_this, void 0, void 0, function () {
|
|
290
289
|
var _a, _b, _c, x, e_2_1;
|
|
291
290
|
var _d, e_2, _e, _f;
|
|
@@ -346,6 +345,24 @@ var DataApi = /** @class */ (function () {
|
|
|
346
345
|
});
|
|
347
346
|
});
|
|
348
347
|
};
|
|
348
|
+
DataApi.prototype.prepareWhereForManyOperation = function (body, request) {
|
|
349
|
+
return tslib_1.__awaiter(this, void 0, void 0, function () {
|
|
350
|
+
var where;
|
|
351
|
+
return tslib_1.__generator(this, function (_a) {
|
|
352
|
+
switch (_a.label) {
|
|
353
|
+
case 0:
|
|
354
|
+
where = undefined;
|
|
355
|
+
if (!((body === null || body === void 0 ? void 0 : body.where) !== 'all')) return [3 /*break*/, 2];
|
|
356
|
+
return [4 /*yield*/, this.buildWhere(request, body)];
|
|
357
|
+
case 1:
|
|
358
|
+
where = _a.sent();
|
|
359
|
+
filter_interfaces_js_1.Filter.throwErrorIfFilterIsEmpty(where, 'deleteMany');
|
|
360
|
+
_a.label = 2;
|
|
361
|
+
case 2: return [2 /*return*/, where];
|
|
362
|
+
}
|
|
363
|
+
});
|
|
364
|
+
});
|
|
365
|
+
};
|
|
349
366
|
DataApi.prototype.groupBy = function (request, body) {
|
|
350
367
|
return tslib_1.__awaiter(this, void 0, void 0, function () {
|
|
351
368
|
var findOptions, orderBy, _a, _b, element, direction, group, result;
|
|
@@ -482,6 +499,8 @@ var DataApi = /** @class */ (function () {
|
|
|
482
499
|
return [4 /*yield*/, this.buildWhere(request, body)];
|
|
483
500
|
case 1:
|
|
484
501
|
_a.where = _b.sent();
|
|
502
|
+
if (body === null || body === void 0 ? void 0 : body.args)
|
|
503
|
+
findOptions.args = body.args;
|
|
485
504
|
if (request) {
|
|
486
505
|
sort = request.get('_sort');
|
|
487
506
|
if (sort != undefined) {
|
|
@@ -760,7 +779,7 @@ var DataApi = /** @class */ (function () {
|
|
|
760
779
|
return tslib_1.__generator(this, function (_a) {
|
|
761
780
|
action = request === null || request === void 0 ? void 0 : request.get('__action');
|
|
762
781
|
if (action == 'emptyId') {
|
|
763
|
-
return [2 /*return*/, this.put(response, '', body)];
|
|
782
|
+
return [2 /*return*/, this.put(response, request, '', body)];
|
|
764
783
|
}
|
|
765
784
|
return [2 /*return*/, this.updateManyImplementation(response, request, {
|
|
766
785
|
where: undefined,
|
|
@@ -777,10 +796,9 @@ var DataApi = /** @class */ (function () {
|
|
|
777
796
|
switch (_a.label) {
|
|
778
797
|
case 0:
|
|
779
798
|
_a.trys.push([0, 3, , 4]);
|
|
780
|
-
return [4 /*yield*/, this.
|
|
799
|
+
return [4 /*yield*/, this.prepareWhereForManyOperation(body, request)];
|
|
781
800
|
case 1:
|
|
782
801
|
where_2 = _a.sent();
|
|
783
|
-
filter_interfaces_js_1.Filter.throwErrorIfFilterIsEmpty(where_2, 'updateMany');
|
|
784
802
|
return [4 /*yield*/, (0, context_js_1.doTransaction)(this.remult, function () { return tslib_1.__awaiter(_this, void 0, void 0, function () {
|
|
785
803
|
var updated, _a, _b, _c, x, e_6_1;
|
|
786
804
|
var _d, e_6, _e, _f;
|
|
@@ -803,7 +821,7 @@ var DataApi = /** @class */ (function () {
|
|
|
803
821
|
_f = _c.value;
|
|
804
822
|
_a = false;
|
|
805
823
|
x = _f;
|
|
806
|
-
return [4 /*yield*/, this.actualUpdate(x, body.set)];
|
|
824
|
+
return [4 /*yield*/, this.actualUpdate(x, body.set, request)];
|
|
807
825
|
case 4:
|
|
808
826
|
_g.sent();
|
|
809
827
|
updated++;
|
|
@@ -844,9 +862,9 @@ var DataApi = /** @class */ (function () {
|
|
|
844
862
|
});
|
|
845
863
|
});
|
|
846
864
|
};
|
|
847
|
-
DataApi.prototype.actualUpdate = function (row, body) {
|
|
865
|
+
DataApi.prototype.actualUpdate = function (row, body, req) {
|
|
848
866
|
return tslib_1.__awaiter(this, void 0, void 0, function () {
|
|
849
|
-
var ref;
|
|
867
|
+
var ref, options;
|
|
850
868
|
return tslib_1.__generator(this, function (_a) {
|
|
851
869
|
switch (_a.label) {
|
|
852
870
|
case 0:
|
|
@@ -857,31 +875,30 @@ var DataApi = /** @class */ (function () {
|
|
|
857
875
|
if (!ref.apiUpdateAllowed) {
|
|
858
876
|
throw new server_action_js_1.ForbiddenError();
|
|
859
877
|
}
|
|
860
|
-
|
|
878
|
+
options = req.get('_select') === 'none' ? { select: 'none' } : undefined;
|
|
879
|
+
return [4 /*yield*/, ref.save(options)];
|
|
861
880
|
case 2:
|
|
862
881
|
_a.sent();
|
|
863
|
-
|
|
882
|
+
if ((options === null || options === void 0 ? void 0 : options.select) === 'none')
|
|
883
|
+
return [2 /*return*/, undefined];
|
|
884
|
+
return [2 /*return*/, ref.toApiJson()];
|
|
864
885
|
}
|
|
865
886
|
});
|
|
866
887
|
});
|
|
867
888
|
};
|
|
868
|
-
DataApi.prototype.put = function (response, id, body) {
|
|
889
|
+
DataApi.prototype.put = function (response, req, id, body) {
|
|
869
890
|
return tslib_1.__awaiter(this, void 0, void 0, function () {
|
|
870
891
|
var _this = this;
|
|
871
892
|
return tslib_1.__generator(this, function (_a) {
|
|
872
893
|
switch (_a.label) {
|
|
873
|
-
case 0: return [4 /*yield*/, this.doOnId(response, id, function (row) { return tslib_1.__awaiter(_this, void 0, void 0, function () {
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
return [2 /*return*/];
|
|
882
|
-
}
|
|
883
|
-
});
|
|
884
|
-
}); })];
|
|
894
|
+
case 0: return [4 /*yield*/, this.doOnId(response, id, function (row) { return tslib_1.__awaiter(_this, void 0, void 0, function () { var _a, _b; return tslib_1.__generator(this, function (_c) {
|
|
895
|
+
switch (_c.label) {
|
|
896
|
+
case 0:
|
|
897
|
+
_b = (_a = response).success;
|
|
898
|
+
return [4 /*yield*/, this.actualUpdate(row, body, req)];
|
|
899
|
+
case 1: return [2 /*return*/, _b.apply(_a, [_c.sent()])];
|
|
900
|
+
}
|
|
901
|
+
}); }); })];
|
|
885
902
|
case 1:
|
|
886
903
|
_a.sent();
|
|
887
904
|
return [2 /*return*/];
|
|
@@ -928,13 +945,14 @@ var DataApi = /** @class */ (function () {
|
|
|
928
945
|
});
|
|
929
946
|
});
|
|
930
947
|
};
|
|
931
|
-
DataApi.prototype.post = function (body) {
|
|
948
|
+
DataApi.prototype.post = function (body, req) {
|
|
932
949
|
return tslib_1.__awaiter(this, void 0, void 0, function () {
|
|
933
|
-
var insert, result_1;
|
|
950
|
+
var options, insert, result_1;
|
|
934
951
|
var _this = this;
|
|
935
952
|
return tslib_1.__generator(this, function (_a) {
|
|
936
953
|
switch (_a.label) {
|
|
937
954
|
case 0:
|
|
955
|
+
options = req.get('_select') === 'none' ? { select: 'none' } : undefined;
|
|
938
956
|
insert = function (what) { return tslib_1.__awaiter(_this, void 0, void 0, function () {
|
|
939
957
|
var newr;
|
|
940
958
|
return tslib_1.__generator(this, function (_a) {
|
|
@@ -947,9 +965,11 @@ var DataApi = /** @class */ (function () {
|
|
|
947
965
|
if (!this.repository.getEntityRef(newr).apiInsertAllowed) {
|
|
948
966
|
throw new server_action_js_1.ForbiddenError();
|
|
949
967
|
}
|
|
950
|
-
return [4 /*yield*/, this.repository.getEntityRef(newr).save()];
|
|
968
|
+
return [4 /*yield*/, this.repository.getEntityRef(newr).save(options)];
|
|
951
969
|
case 2:
|
|
952
970
|
_a.sent();
|
|
971
|
+
if ((options === null || options === void 0 ? void 0 : options.select) === 'none')
|
|
972
|
+
return [2 /*return*/, undefined];
|
|
953
973
|
return [2 /*return*/, this.repository.getEntityRef(newr).toApiJson()];
|
|
954
974
|
}
|
|
955
975
|
});
|
package/src/data-interfaces.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { FieldMetadata } from '../index.js';
|
|
2
2
|
import type { Filter } from './filter/filter-interfaces.js';
|
|
3
|
-
import type { GroupByOperators, EntityMetadata, MembersOnly } from './remult3/remult3.js';
|
|
3
|
+
import type { GroupByOperators, EntityMetadata, MembersOnly, InsertOrUpdateOptions } from './remult3/remult3.js';
|
|
4
4
|
import { Sort } from './sort.js';
|
|
5
5
|
export interface DataProvider {
|
|
6
6
|
getEntityDataProvider(entity: EntityMetadata): EntityDataProvider;
|
|
@@ -28,14 +28,14 @@ export interface EntityDataProvider {
|
|
|
28
28
|
count(where: Filter): Promise<number>;
|
|
29
29
|
find(options?: EntityDataProviderFindOptions): Promise<Array<any>>;
|
|
30
30
|
groupBy(options?: EntityDataProviderGroupByOptions): Promise<any[]>;
|
|
31
|
-
update(id: any, data: any): Promise<any>;
|
|
31
|
+
update(id: any, data: any, options?: InsertOrUpdateOptions): Promise<any>;
|
|
32
32
|
delete(id: any): Promise<void>;
|
|
33
|
-
insert(data: any): Promise<any>;
|
|
33
|
+
insert(data: any, options?: InsertOrUpdateOptions): Promise<any>;
|
|
34
34
|
}
|
|
35
35
|
export interface ProxyEntityDataProvider {
|
|
36
|
-
insertMany(data: any[]): Promise<any[]>;
|
|
37
|
-
deleteMany(where: Filter): Promise<number>;
|
|
38
|
-
updateMany(where: Filter, data: any): Promise<number>;
|
|
36
|
+
insertMany(data: any[], options?: InsertOrUpdateOptions): Promise<any[]>;
|
|
37
|
+
deleteMany(where: Filter | 'all'): Promise<number>;
|
|
38
|
+
updateMany(where: Filter | 'all', data: any): Promise<number>;
|
|
39
39
|
query(options: EntityDataProviderFindOptions, aggregateOptions: EntityDataProviderGroupByOptions): Promise<{
|
|
40
40
|
items: any[];
|
|
41
41
|
aggregates: any;
|
|
@@ -49,6 +49,7 @@ export interface EntityDataProviderFindOptions {
|
|
|
49
49
|
select?: string[];
|
|
50
50
|
where?: Filter;
|
|
51
51
|
limit?: number;
|
|
52
|
+
args?: any;
|
|
52
53
|
page?: number;
|
|
53
54
|
orderBy?: Sort;
|
|
54
55
|
}
|