remult 0.13.11 → 0.13.14

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "remult",
3
- "version": "0.13.11",
3
+ "version": "0.13.14",
4
4
  "description": "remult core lib",
5
5
  "homepage": "https://remult.dev/",
6
6
  "repository": {
package/readme.md CHANGED
@@ -99,23 +99,26 @@ static async increasePriceOfTofu(priceIncrease: number, remult?: Remult) {
99
99
  ## :ballot_box_with_check: Data validation and constraints - defined once
100
100
 
101
101
  ```ts
102
- import { Entity, EntityBase, Field } from 'remult';
103
- import { Min } from 'class-validator';
102
+ import { Entity, EntityBase, Fields } from 'remult';
104
103
 
105
104
  @Entity('products', {
106
105
  allowApiCrud: true
107
106
  })
108
107
  export class Product extends EntityBase {
109
108
  @Fields.string<Product>({
110
- validate: p => {
111
- if (p.name.trim().length == 0)
112
- p.$.name.error = 'required';
109
+ validate: product => {
110
+ if (product.name.trim().length == 0)
111
+ product.$.name.error = 'required';
113
112
  }
114
113
  })
115
114
  name = '';
116
115
 
117
- @Fields.number()
118
- @Min(0)
116
+ @Fields.number({
117
+ validate: (_, field) => {
118
+ if (field.value < 0)
119
+ field.error = "must not be less than 0";
120
+ }
121
+ })
119
122
  unitPrice = 0;
120
123
  }
121
124
  ```
@@ -136,7 +139,7 @@ catch {
136
139
  ```sh
137
140
  > curl -d "{""unitPrice"":-1}" -H "Content-Type: application/json" -X POST http://localhost:3001/api/products
138
141
 
139
- {"modelState":{"unitPrice":"unitPrice must not be less than 0","name":"required"},"message":"Name: required"}
142
+ {"modelState":{"unitPrice":"must not be less than 0","name":"required"},"message":"Name: required"}
140
143
  ```
141
144
 
142
145
  ## :lock: Secure the API with fine-grained authorization
package/src/context.js CHANGED
@@ -94,14 +94,14 @@ function toPromise(p) {
94
94
  }
95
95
  exports.toPromise = toPromise;
96
96
  function processHttpException(ex) {
97
- var _a, _b;
97
+ var _a, _b, _c;
98
98
  return tslib_1.__awaiter(this, void 0, void 0, function () {
99
- var z, error, result;
100
- return tslib_1.__generator(this, function (_c) {
101
- switch (_c.label) {
99
+ var z, error, httpStatusCode, result;
100
+ return tslib_1.__generator(this, function (_d) {
101
+ switch (_d.label) {
102
102
  case 0: return [4 /*yield*/, ex];
103
103
  case 1:
104
- z = _c.sent();
104
+ z = _d.sent();
105
105
  if (z.error)
106
106
  error = z.error;
107
107
  else if (z.isAxiosError) {
@@ -116,9 +116,15 @@ function processHttpException(ex) {
116
116
  error = "Network Error";
117
117
  if (typeof error === 'string') {
118
118
  error = {
119
- message: error
119
+ message: error,
120
120
  };
121
121
  }
122
+ httpStatusCode = z.status;
123
+ if (httpStatusCode === undefined)
124
+ httpStatusCode = (_c = z.response) === null || _c === void 0 ? void 0 : _c.status;
125
+ if (httpStatusCode !== undefined && httpStatusCode !== null) {
126
+ error.httpStatusCode = httpStatusCode;
127
+ }
122
128
  result = Object.assign(error, {
123
129
  // exception: ex disabled for now because JSON.stringify crashed with this
124
130
  });
@@ -33,4 +33,5 @@ export interface ErrorInfo<entityType = any> {
33
33
  };
34
34
  stack?: string;
35
35
  exception?: any;
36
+ httpStatusCode?: number;
36
37
  }
@@ -397,11 +397,12 @@ function entityFilterToJson(entityDefs, where) {
397
397
  }
398
398
  exports.entityFilterToJson = entityFilterToJson;
399
399
  function buildFilterFromRequestParameters(entity, filterInfo) {
400
- var e_3, _a, _b;
400
+ var _a;
401
401
  var where = [];
402
402
  tslib_1.__spread(entity.fields).forEach(function (col) {
403
403
  var _a, _b;
404
404
  function addFilter(operation, theFilter, jsonArray, asString) {
405
+ var e_3, _a;
405
406
  if (jsonArray === void 0) { jsonArray = false; }
406
407
  if (asString === void 0) { asString = false; }
407
408
  var val = filterInfo.get(col.key + operation);
@@ -430,8 +431,26 @@ function buildFilterFromRequestParameters(entity, filterInfo) {
430
431
  addFilter_1(v);
431
432
  });
432
433
  }
433
- else
434
- addFilter_1(val);
434
+ else {
435
+ if (jsonArray) {
436
+ if (typeof val === 'string')
437
+ val = JSON.parse(val);
438
+ }
439
+ var array = separateArrayFromInnerArray(val);
440
+ try {
441
+ for (var array_1 = tslib_1.__values(array), array_1_1 = array_1.next(); !array_1_1.done; array_1_1 = array_1.next()) {
442
+ var x = array_1_1.value;
443
+ addFilter_1(x);
444
+ }
445
+ }
446
+ catch (e_3_1) { e_3 = { error: e_3_1 }; }
447
+ finally {
448
+ try {
449
+ if (array_1_1 && !array_1_1.done && (_a = array_1.return)) _a.call(array_1);
450
+ }
451
+ finally { if (e_3) throw e_3.error; }
452
+ }
453
+ }
435
454
  }
436
455
  }
437
456
  var c = new filterHelper(col);
@@ -460,6 +479,29 @@ function buildFilterFromRequestParameters(entity, filterInfo) {
460
479
  });
461
480
  var val = filterInfo.get('OR');
462
481
  if (val) {
482
+ var array = separateArrayFromInnerArray(val);
483
+ where.push({
484
+ $and: array.map(function (v) { return ({
485
+ $or: v.map(function (x) {
486
+ return buildFilterFromRequestParameters(entity, { get: function (key) { return x[key]; } });
487
+ })
488
+ }); })
489
+ });
490
+ }
491
+ for (var key in entity.entityType) {
492
+ var element = entity.entityType[key];
493
+ if (element && element.customFilterInfo && element.customFilterInfo.customFilterTranslator) {
494
+ var custom = filterInfo.get(exports.customUrlToken + key);
495
+ if (custom !== undefined) {
496
+ where.push((_a = {}, _a[exports.customUrlToken + key] = custom, _a));
497
+ }
498
+ }
499
+ }
500
+ return { $and: where };
501
+ function separateArrayFromInnerArray(val) {
502
+ var e_4, _a;
503
+ if (!Array.isArray(val))
504
+ return [val];
463
505
  var nonArray = [], array = [];
464
506
  try {
465
507
  for (var val_1 = tslib_1.__values(val), val_1_1 = val_1.next(); !val_1_1.done; val_1_1 = val_1.next()) {
@@ -471,32 +513,16 @@ function buildFilterFromRequestParameters(entity, filterInfo) {
471
513
  nonArray.push(v);
472
514
  }
473
515
  }
474
- catch (e_3_1) { e_3 = { error: e_3_1 }; }
516
+ catch (e_4_1) { e_4 = { error: e_4_1 }; }
475
517
  finally {
476
518
  try {
477
519
  if (val_1_1 && !val_1_1.done && (_a = val_1.return)) _a.call(val_1);
478
520
  }
479
- finally { if (e_3) throw e_3.error; }
521
+ finally { if (e_4) throw e_4.error; }
480
522
  }
481
523
  array.push(nonArray);
482
- where.push({
483
- $and: array.map(function (v) { return ({
484
- $or: v.map(function (x) {
485
- return buildFilterFromRequestParameters(entity, { get: function (key) { return x[key]; } });
486
- })
487
- }); })
488
- });
489
- }
490
- for (var key in entity.entityType) {
491
- var element = entity.entityType[key];
492
- if (element && element.customFilterInfo && element.customFilterInfo.customFilterTranslator) {
493
- var custom = filterInfo.get(exports.customUrlToken + key);
494
- if (custom !== undefined) {
495
- where.push((_b = {}, _b[exports.customUrlToken + key] = custom, _b));
496
- }
497
- }
524
+ return array;
498
525
  }
499
- return { $and: where };
500
526
  }
501
527
  exports.buildFilterFromRequestParameters = buildFilterFromRequestParameters;
502
528
  var customTranslator = /** @class */ (function () {
@@ -38,6 +38,7 @@ export declare class RepositoryImplementation<entityType> implements Repository<
38
38
  } ? number : entityType extends {
39
39
  id: string;
40
40
  } ? string : (string | number)), entity: Partial<OmitEB<entityType>>): Promise<entityType>;
41
+ private getRefForExistingRow;
41
42
  save(item: Partial<OmitEB<entityType>>[]): Promise<entityType[]>;
42
43
  save(item: Partial<OmitEB<entityType>>): Promise<entityType>;
43
44
  find(options: FindOptions<entityType>): Promise<entityType[]>;
@@ -114,7 +115,7 @@ export declare class rowHelperImplementation<T> extends rowHelperBase<T> impleme
114
115
  private getIdFilter;
115
116
  delete(): Promise<void>;
116
117
  loadDataFrom(data: any, loadItems?: FieldMetadata[]): Promise<void>;
117
- private id;
118
+ id: any;
118
119
  getOriginalId(): any;
119
120
  private calcServerExpression;
120
121
  isNew(): boolean;
@@ -206,9 +207,6 @@ declare class EntityFullInfo<T> implements EntityMetadata<T> {
206
207
  caption: string;
207
208
  }
208
209
  export declare function FieldType<valueType = any>(...options: (FieldOptions<any, valueType> | ((options: FieldOptions<any, valueType>, remult: Remult) => void))[]): (target: any) => any;
209
- export declare const Fields1: {
210
- String: () => (a: any) => void;
211
- };
212
210
  export declare class Fields {
213
211
  static object<entityType = any, valueType = any>(...options: (FieldOptions<entityType, valueType> | ((options: FieldOptions<entityType, valueType>, remult: Remult) => void))[]): (target: any, key: any, c?: any) => void;
214
212
  static dateOnly<entityType = any>(...options: (FieldOptions<entityType, Date> | ((options: FieldOptions<entityType, Date>, remult: Remult) => void))[]): (target: any, key: any, c?: any) => void;