remult 0.13.18 → 0.13.21

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.
@@ -4,6 +4,7 @@ exports.addFilterToUrlAndReturnTrueIfSuccessful = exports.RestDataProviderHttpPr
4
4
  var tslib_1 = require("tslib");
5
5
  var urlBuilder_1 = require("../../urlBuilder");
6
6
  var filter_interfaces_1 = require("../filter/filter-interfaces");
7
+ var context_1 = require("../context");
7
8
  var RestDataProvider = /** @class */ (function () {
8
9
  function RestDataProvider(url, http) {
9
10
  this.url = url;
@@ -152,67 +153,76 @@ var RestEntityDataProvider = /** @class */ (function () {
152
153
  return RestEntityDataProvider;
153
154
  }());
154
155
  exports.RestEntityDataProvider = RestEntityDataProvider;
155
- function JsonContent(add) {
156
- add('Content-type', "application/json");
157
- }
158
156
  var RestDataProviderHttpProviderUsingFetch = /** @class */ (function () {
159
- function RestDataProviderHttpProviderUsingFetch(addRequestHeader) {
160
- this.addRequestHeader = addRequestHeader;
161
- if (!addRequestHeader)
162
- this.addRequestHeader = function () { };
157
+ function RestDataProviderHttpProviderUsingFetch(fetch) {
158
+ this.fetch = fetch;
163
159
  }
164
160
  RestDataProviderHttpProviderUsingFetch.prototype.get = function (url) {
165
- return myFetch(url, undefined, this.addRequestHeader).then(function (r) {
166
- return r;
161
+ return tslib_1.__awaiter(this, void 0, void 0, function () {
162
+ var _this = this;
163
+ return tslib_1.__generator(this, function (_a) {
164
+ switch (_a.label) {
165
+ case 0: return [4 /*yield*/, context_1.retry(function () { return tslib_1.__awaiter(_this, void 0, void 0, function () {
166
+ return tslib_1.__generator(this, function (_a) {
167
+ return [2 /*return*/, this.myFetch(url).then(function (r) {
168
+ return r;
169
+ })];
170
+ });
171
+ }); })];
172
+ case 1: return [2 /*return*/, _a.sent()];
173
+ }
174
+ });
167
175
  });
168
176
  };
169
177
  RestDataProviderHttpProviderUsingFetch.prototype.put = function (url, data) {
170
- return myFetch(url, {
178
+ return this.myFetch(url, {
171
179
  method: 'put',
172
180
  body: JSON.stringify(data)
173
- }, this.addRequestHeader, JsonContent);
181
+ });
174
182
  };
175
183
  RestDataProviderHttpProviderUsingFetch.prototype.delete = function (url) {
176
- var h = new Headers();
177
- this.addRequestHeader(function (name, value) { return h.append(name, value); });
178
- return fetch(url, { method: 'delete', credentials: 'include' }).then(onSuccess, onError);
184
+ return this.myFetch(url, { method: 'delete', credentials: 'include' });
179
185
  };
180
186
  RestDataProviderHttpProviderUsingFetch.prototype.post = function (url, data) {
181
- return myFetch(url, {
182
- method: 'post',
183
- body: JSON.stringify(data)
184
- }, this.addRequestHeader, JsonContent);
187
+ return tslib_1.__awaiter(this, void 0, void 0, function () {
188
+ var _this = this;
189
+ return tslib_1.__generator(this, function (_a) {
190
+ switch (_a.label) {
191
+ case 0: return [4 /*yield*/, context_1.retry(function () { return _this.myFetch(url, {
192
+ method: 'post',
193
+ body: JSON.stringify(data)
194
+ }); })];
195
+ case 1: return [2 /*return*/, _a.sent()];
196
+ }
197
+ });
198
+ });
199
+ };
200
+ RestDataProviderHttpProviderUsingFetch.prototype.myFetch = function (url, init) {
201
+ var _this = this;
202
+ if (!init)
203
+ init = {};
204
+ if (!init.headers)
205
+ init.headers = new Headers();
206
+ var h = init.headers;
207
+ h.append('Content-type', "application/json");
208
+ init.credentials = 'include';
209
+ return (this.fetch || fetch)(url, init).then(function (response) {
210
+ return onSuccess(response);
211
+ }).catch(function (error) { return tslib_1.__awaiter(_this, void 0, void 0, function () {
212
+ var r;
213
+ return tslib_1.__generator(this, function (_a) {
214
+ switch (_a.label) {
215
+ case 0: return [4 /*yield*/, error];
216
+ case 1:
217
+ r = _a.sent();
218
+ throw r;
219
+ }
220
+ });
221
+ }); });
185
222
  };
186
223
  return RestDataProviderHttpProviderUsingFetch;
187
224
  }());
188
225
  exports.RestDataProviderHttpProviderUsingFetch = RestDataProviderHttpProviderUsingFetch;
189
- function myFetch(url, init) {
190
- var _this = this;
191
- var addRequestHeader = [];
192
- for (var _i = 2; _i < arguments.length; _i++) {
193
- addRequestHeader[_i - 2] = arguments[_i];
194
- }
195
- if (!init)
196
- init = {};
197
- if (!init.headers)
198
- init.headers = new Headers();
199
- var h = init.headers;
200
- addRequestHeader.forEach(function (x) { return x(function (n, v) { return h.append(n, v); }); });
201
- init.credentials = 'include';
202
- return fetch(url, init).then(function (response) {
203
- return onSuccess(response);
204
- }).catch(function (error) { return tslib_1.__awaiter(_this, void 0, void 0, function () {
205
- var r;
206
- return tslib_1.__generator(this, function (_a) {
207
- switch (_a.label) {
208
- case 0: return [4 /*yield*/, error];
209
- case 1:
210
- r = _a.sent();
211
- throw r;
212
- }
213
- });
214
- }); });
215
- }
216
226
  function onSuccess(response) {
217
227
  if (response.status == 204)
218
228
  return;
@@ -220,9 +230,7 @@ function onSuccess(response) {
220
230
  return response.json();
221
231
  else {
222
232
  throw response.json().then(function (x) {
223
- if (!x.message)
224
- x.message = response.statusText;
225
- return x;
233
+ return tslib_1.__assign(tslib_1.__assign({}, x), { message: x.message || response.statusText, url: response.url, status: response.status });
226
234
  }).catch(function () {
227
235
  throw {
228
236
  message: response.statusText,
@@ -232,9 +240,6 @@ function onSuccess(response) {
232
240
  });
233
241
  }
234
242
  }
235
- function onError(error) {
236
- throw Promise.resolve(error);
237
- }
238
243
  function addFilterToUrlAndReturnTrueIfSuccessful(filter, url) {
239
244
  for (var key in filter) {
240
245
  if (Object.prototype.hasOwnProperty.call(filter, key)) {
@@ -121,17 +121,13 @@ var LogSQLCommand = /** @class */ (function () {
121
121
  if (this.allQueries) {
122
122
  d = new Date().valueOf() - start.valueOf();
123
123
  if (d > SqlDatabase.durationThreshold) {
124
- console.log('Query:', sql);
125
- console.log("Arguments:", this.args);
126
- console.log("Duration", d / 1000);
124
+ console.log({ query: sql, arguments: this.args, duration: d / 1000 });
127
125
  }
128
126
  }
129
127
  return [2 /*return*/, r];
130
128
  case 2:
131
129
  err_1 = _a.sent();
132
- console.error('Error:', err_1);
133
- console.error('Query:', sql);
134
- console.error("Arguments", this.args);
130
+ console.error({ error: err_1, query: sql, arguments: this.args });
135
131
  throw err_1;
136
132
  case 3: return [2 /*return*/];
137
133
  }
package/src/entity.d.ts CHANGED
@@ -2,39 +2,35 @@ import { Allowed, AllowedForInstance } from "./context";
2
2
  import { FieldMetadata as FieldMetadata } from './column-interfaces';
3
3
  import { EntityOrderBy, FieldsMetadata, EntityFilter, EntityRef } from "./remult3";
4
4
  export interface EntityOptions<entityType = any> {
5
- id?: (entity: FieldsMetadata<entityType>) => FieldMetadata;
6
- /**
7
- * The name of the table in the database that holds the data for this entity.
8
- * If no name is set, the `key` will be used instead.
9
- * @example
10
- * dbName:'myProducts'
11
- */
12
- dbName?: string;
13
- sqlExpression?: string | ((entity: FieldsMetadata<entityType>) => string | Promise<string>);
14
5
  /**A human readable name for the entity */
15
6
  caption?: string;
16
7
  /**
17
8
  * Determines if this Entity is available for get requests using Rest Api
18
- * @see [allowed](http://remult.dev/guide/allowed.html)*/
9
+ * @see [allowed](http://remult.dev/docs/allowed.html)*/
19
10
  allowApiRead?: Allowed;
20
11
  /**
21
12
  * Determines if this entity can be updated through the api.
22
- * @see [allowed](http://remult.dev/guide/allowed.html)*/
13
+ * @see [allowed](http://remult.dev/docs/allowed.html)*/
23
14
  allowApiUpdate?: AllowedForInstance<entityType>;
24
- /** @see [allowed](http://remult.dev/guide/allowed.html)*/
15
+ /** Determines if entries for this entity can be deleted through the api.
16
+ * @see [allowed](http://remult.dev/docs/allowed.html)*/
25
17
  allowApiDelete?: AllowedForInstance<entityType>;
26
- /** @see [allowed](http://remult.dev/guide/allowed.html)*/
18
+ /** Determines if new entries for this entity can be posted through the api.
19
+ * @see [allowed](http://remult.dev/docs/allowed.html)*/
27
20
  allowApiInsert?: AllowedForInstance<entityType>;
28
21
  /** sets the `allowApiUpdate`, `allowApiDelete` and `allowApiInsert` properties in a single set */
29
22
  allowApiCrud?: Allowed;
30
23
  /** A filter that determines which rows can be queries using the api.
31
-
24
+ * @example
25
+ * apiPrefilter: { archive:false }
26
+ *
27
+ * @see [EntityFilter](http://remult.dev/docs/entityFilter.html)
32
28
  */
33
29
  apiPrefilter?: EntityFilter<entityType> | (() => EntityFilter<entityType> | Promise<EntityFilter<entityType>>);
34
- apiRequireId?: Allowed;
35
- /** A filter that will be used for all queries from this entity both from the API and from within the server.
30
+ /** A filter that will be used for all queries from this entity both from the API and from within the backend.
36
31
  * @example
37
- * fixedWhereFilter: () => this.archive.isEqualTo(false)
32
+ * fixedWhereFilter: { archive:false }
33
+ * @see [EntityFilter](http://remult.dev/docs/entityFilter.html)
38
34
  */
39
35
  backendPrefilter?: EntityFilter<entityType> | (() => EntityFilter<entityType> | Promise<EntityFilter<entityType>>);
40
36
  /** An order by to be used, in case no order by was specified
@@ -42,23 +38,18 @@ export interface EntityOptions<entityType = any> {
42
38
  * defaultOrderBy: { name: "asc" }
43
39
  *
44
40
  * @example
45
- * defaultOrderBy: { price: "asc", name: "asc" }
46
- *
47
- * @example
48
41
  * defaultOrderBy: { price: "desc", name: "asc" }
49
42
  */
50
43
  defaultOrderBy?: EntityOrderBy<entityType>;
51
44
  /** An event that will be fired before the Entity will be saved to the database.
52
- * If the `validationError` property of the entity or any of it's columns will be set, the save will be aborted and an exception will be thrown.
45
+ * If the `error` property of the entity's ref or any of it's fields will be set, the save will be aborted and an exception will be thrown.
53
46
  * this is the place to run logic that we want to run in any case before an entity is saved.
54
47
  * @example
55
- * saving: async (self) => {
56
- * if (isBackend()) {
57
- * if (self.isNew()) {
58
- * self.createDate.value = new Date();
59
- * }
60
- * }
61
- * }
48
+ * .@Entity<Task>("tasks", {
49
+ * saving: async task => {
50
+ * task.lastUpdated = new Date()
51
+ * }
52
+ *})
62
53
  */
63
54
  saving?: (row: entityType, proceedWithoutSavingToDb: () => void) => Promise<any> | any;
64
55
  /** will be called after the Entity was saved to the data source. */
@@ -67,6 +58,18 @@ export interface EntityOptions<entityType = any> {
67
58
  deleting?: (row: entityType) => Promise<any> | any;
68
59
  /** Will be called after an Entity is deleted */
69
60
  deleted?: (row: entityType) => Promise<any> | any;
61
+ /** Will be called when the entity is being validated, usually prior to the `saving` event */
70
62
  validation?: (row: entityType, ref: EntityRef<entityType>) => Promise<any> | any;
63
+ /** The name of the table in the database that holds the data for this entity.
64
+ * If no name is set, the `key` will be used instead.
65
+ * @example
66
+ * dbName:'myProducts'
67
+ */
68
+ dbName?: string;
69
+ /** For entities that are based on SQL expressions instead of a physical table or view*/
70
+ sqlExpression?: string | ((entity: FieldsMetadata<entityType>) => string | Promise<string>);
71
+ /** An arrow function that identifies the `id` column to use for this entity */
72
+ id?: (entity: FieldsMetadata<entityType>) => FieldMetadata;
71
73
  entityRefInit?: (ref: EntityRef<entityType>, row: entityType) => void;
74
+ apiRequireId?: Allowed;
72
75
  }
@@ -26,17 +26,17 @@ export declare class RepositoryImplementation<entityType> implements Repository<
26
26
  query(options?: QueryOptions<entityType>): QueryResult<entityType>;
27
27
  getEntityRef(entity: entityType): EntityRef<entityType>;
28
28
  delete(id: (entityType extends {
29
- id: number;
29
+ id?: number;
30
30
  } ? number : entityType extends {
31
- id: string;
31
+ id?: string;
32
32
  } ? string : (string | number))): Promise<void>;
33
33
  delete(item: entityType): Promise<void>;
34
34
  insert(item: Partial<OmitEB<entityType>>[]): Promise<entityType[]>;
35
35
  insert(item: Partial<OmitEB<entityType>>): Promise<entityType>;
36
36
  update(id: (entityType extends {
37
- id: number;
37
+ id?: number;
38
38
  } ? number : entityType extends {
39
- id: string;
39
+ id?: string;
40
40
  } ? string : (string | number)), entity: Partial<OmitEB<entityType>>): Promise<entityType>;
41
41
  private getRefForExistingRow;
42
42
  save(item: Partial<OmitEB<entityType>>[]): Promise<entityType[]>;
@@ -157,6 +157,7 @@ export declare class FieldRefImplementation<entityType, valueType> implements Fi
157
157
  get originalValue(): any;
158
158
  private rawOriginalValue;
159
159
  setId(id: (string | number)): void;
160
+ getId(): any;
160
161
  get inputValue(): string;
161
162
  set inputValue(val: string);
162
163
  valueChanged(): boolean;
@@ -249,6 +250,19 @@ export declare class ValueListInfo<T extends ValueListItem> implements ValueConv
249
250
  export declare function getValueList<T>(field: FieldRef<T>): T[];
250
251
  export declare function getValueList<T>(field: FieldMetadata<T>): T[];
251
252
  export declare function getValueList<T>(type: ClassType<T>): T[];
253
+ /**Decorates fields that should be used as fields.
254
+ * for more info see: [Field Types](https://remult.dev/docs/field-types.html)
255
+ *
256
+ * FieldOptions can be set in two ways:
257
+ * @example
258
+ * // as an object
259
+ * .@Fields.string({ includeInApi:false })
260
+ * title='';
261
+ * @example
262
+ * // as an arrow function that receives `remult` as a parameter
263
+ * .@Fields.string((options,remult) => options.includeInApi = true)
264
+ * title='';
265
+ */
252
266
  export declare function Field<entityType = any, valueType = any>(valueType: () => ClassType<valueType>, ...options: (FieldOptions<entityType, valueType> | ((options: FieldOptions<entityType, valueType>, remult: Remult) => void))[]): (target: any, key: any, c?: any) => void;
253
267
  export declare const storableMember: unique symbol;
254
268
  export declare function decorateColumnSettings<valueType>(settings: FieldOptions<any, valueType>, remult: Remult): FieldOptions<any, valueType>;
@@ -260,6 +274,29 @@ export declare type BuildEntityFields<entityType> = {
260
274
  [Properties in keyof Partial<OmitEB<entityType>>]: any;
261
275
  };
262
276
  export declare function BuildEntity<entityType>(c: ClassType<entityType>, key: string, fields: BuildEntityFields<entityType>, ...options: (EntityOptions<entityType> | ((options: EntityOptions<entityType>, remult: Remult) => void))[]): void;
277
+ /**Decorates classes that should be used as entities.
278
+ * Receives a key and an array of EntityOptions.
279
+ * @example
280
+ * import { Entity, Fields } from "remult";
281
+ * @Entity("tasks", {
282
+ * allowApiCrud: true
283
+ * })
284
+ * export class Task {
285
+ * @Fields.uuid()
286
+ * id!: string;
287
+ * @Fields.string()
288
+ * title = '';
289
+ * @Fields.boolean()
290
+ * completed = false;
291
+ * }
292
+ * *EntityOptions can be set in two ways:*
293
+ * @example
294
+ * // as an object
295
+ * .@Entity("tasks",{ allowApiCrud:true })
296
+ * @example
297
+ * // as an arrow function that receives `remult` as a parameter
298
+ * .@Entity("tasks", (options,remult) => options.allowApiCrud = true)
299
+ */
263
300
  export declare function Entity<entityType>(key: string, ...options: (EntityOptions<entityType> | ((options: EntityOptions<entityType>, remult: Remult) => void))[]): (target: any) => any;
264
301
  export declare class EntityBase {
265
302
  get _(): EntityRef<this>;