remult 0.22.9-exp.0 → 0.23.0-exp.10

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.
Files changed (72) hide show
  1. package/README.md +26 -27
  2. package/esm/index.d.ts +4 -3
  3. package/esm/index.js +5 -2
  4. package/esm/internals.d.ts +1 -0
  5. package/esm/remult-knex/index.js +1 -0
  6. package/esm/remult-mongo.d.ts +1 -1
  7. package/esm/remult-mongo.js +4 -2
  8. package/esm/server/JsonEntityFileStorage.js +1 -1
  9. package/esm/src/buildRestDataProvider.d.ts +1 -2
  10. package/esm/src/column-interfaces.d.ts +2 -2
  11. package/esm/src/column.d.ts +4 -17
  12. package/esm/src/column.js +7 -42
  13. package/esm/src/context.d.ts +1 -1
  14. package/esm/src/context.js +2 -1
  15. package/esm/src/data-interfaces.js +1 -2
  16. package/esm/src/data-providers/array-entity-data-provider.d.ts +1 -1
  17. package/esm/src/data-providers/array-entity-data-provider.js +6 -6
  18. package/esm/src/data-providers/web-sql-data-provider.js +3 -3
  19. package/esm/src/entity.d.ts +6 -6
  20. package/esm/src/entity.js +1 -0
  21. package/esm/src/filter/filter-interfaces.d.ts +2 -16
  22. package/esm/src/filter/filter-interfaces.js +85 -6
  23. package/esm/src/live-query/SubscriptionChannel.js +3 -3
  24. package/esm/src/remult-proxy.js +7 -1
  25. package/esm/src/remult3/Fields.d.ts +6 -5
  26. package/esm/src/remult3/Fields.js +28 -29
  27. package/esm/src/remult3/RepositoryImplementation.d.ts +5 -3
  28. package/esm/src/remult3/RepositoryImplementation.js +148 -41
  29. package/esm/src/remult3/getEntityRef.d.ts +1 -1
  30. package/esm/src/remult3/getEntityRef.js +1 -1
  31. package/esm/src/remult3/relation-loader.js +4 -1
  32. package/esm/src/remult3/remult3.d.ts +18 -4
  33. package/esm/src/remult3/remult3.js +0 -4
  34. package/esm/src/resultCompoundIdFilter.d.ts +1 -1
  35. package/esm/src/sort.d.ts +3 -3
  36. package/esm/src/sort.js +25 -7
  37. package/index.d.ts +4 -3
  38. package/index.js +7 -3
  39. package/internals.d.ts +1 -0
  40. package/package.json +1 -1
  41. package/remult-knex/index.js +1 -1
  42. package/remult-mongo.d.ts +1 -1
  43. package/remult-mongo.js +6 -3
  44. package/server/JsonEntityFileStorage.js +1 -1
  45. package/src/buildRestDataProvider.d.ts +1 -2
  46. package/src/column-interfaces.d.ts +2 -2
  47. package/src/column.d.ts +4 -17
  48. package/src/column.js +7 -54
  49. package/src/context.d.ts +1 -1
  50. package/src/context.js +2 -1
  51. package/src/data-interfaces.js +1 -2
  52. package/src/data-providers/array-entity-data-provider.d.ts +1 -1
  53. package/src/data-providers/array-entity-data-provider.js +5 -6
  54. package/src/data-providers/web-sql-data-provider.js +3 -3
  55. package/src/entity.d.ts +6 -6
  56. package/src/entity.js +1 -0
  57. package/src/filter/filter-interfaces.d.ts +2 -16
  58. package/src/filter/filter-interfaces.js +99 -9
  59. package/src/live-query/SubscriptionChannel.js +3 -3
  60. package/src/remult-proxy.js +9 -1
  61. package/src/remult3/Fields.d.ts +6 -5
  62. package/src/remult3/Fields.js +35 -32
  63. package/src/remult3/RepositoryImplementation.d.ts +5 -3
  64. package/src/remult3/RepositoryImplementation.js +312 -182
  65. package/src/remult3/getEntityRef.d.ts +1 -1
  66. package/src/remult3/getEntityRef.js +2 -1
  67. package/src/remult3/relation-loader.js +4 -1
  68. package/src/remult3/remult3.d.ts +18 -4
  69. package/src/remult3/remult3.js +0 -4
  70. package/src/resultCompoundIdFilter.d.ts +1 -1
  71. package/src/sort.d.ts +3 -3
  72. package/src/sort.js +32 -10
package/README.md CHANGED
@@ -22,7 +22,6 @@
22
22
  <a href="https://discord.gg/GXHk7ZfuG5" rel="nofollow">
23
23
  <img alt="Join Discord" src="https://badgen.net/discord/online-members/GXHk7ZfuG5?icon=discord&label=Discord"/>
24
24
  </a>
25
- </a>
26
25
  </div>
27
26
 
28
27
  <br/>
@@ -101,14 +100,14 @@ npm i remult
101
100
  ```ts
102
101
  // shared/product.ts
103
102
 
104
- import { Entity, Fields } from "remult"
103
+ import { Entity, Fields } from 'remult'
105
104
 
106
- @Entity("products", {
107
- allowApiCrud: true
105
+ @Entity('products', {
106
+ allowApiCrud: true,
108
107
  })
109
108
  export class Product {
110
109
  @Fields.string()
111
- name = ""
110
+ name = ''
112
111
 
113
112
  @Fields.number()
114
113
  unitPrice = 0
@@ -120,17 +119,17 @@ export class Product {
120
119
  ```ts
121
120
  // backend/index.ts
122
121
 
123
- import express from "express"
124
- import { remultExpress } from "remult/remult-express"
125
- import { Product } from "../shared/product"
122
+ import express from 'express'
123
+ import { remultExpress } from 'remult/remult-express'
124
+ import { Product } from '../shared/product'
126
125
 
127
126
  const port = 3001
128
127
  const app = express()
129
128
 
130
129
  app.use(
131
130
  remultExpress({
132
- entities: [Product]
133
- })
131
+ entities: [Product],
132
+ }),
134
133
  )
135
134
 
136
135
  app.listen(port, () => {
@@ -151,13 +150,13 @@ app.listen(port, () => {
151
150
  ```ts
152
151
  // frontend/code.ts
153
152
 
154
- import { remult } from "remult"
155
- import { Product } from "../shared/product"
153
+ import { remult } from 'remult'
154
+ import { Product } from '../shared/product'
156
155
 
157
156
  async function increasePriceOfTofu(priceIncrease: number) {
158
157
  const productsRepo = remult.repo(Product)
159
158
 
160
- const product = await productsRepo.findFirst({ name: "Tofu" }) // filter is passed through API request all the way to the db
159
+ const product = await productsRepo.findFirst({ name: 'Tofu' }) // filter is passed through API request all the way to the db
161
160
  product.unitPrice += priceIncrease
162
161
  productsRepo.save(product) // mutation request updates the db with no boilerplate code
163
162
  }
@@ -179,32 +178,32 @@ static async increasePriceOfTofu(priceIncrease: number) {
179
178
  ### :ballot_box_with_check: Data validation and constraints - defined once
180
179
 
181
180
  ```ts
182
- import { Entity, Fields, Validators } from "remult"
181
+ import { Entity, Fields, Validators } from 'remult'
183
182
 
184
- @Entity("products", {
185
- allowApiCrud: true
183
+ @Entity('products', {
184
+ allowApiCrud: true,
186
185
  })
187
186
  export class Product {
188
187
  @Fields.string({
189
- validate: Validators.required
188
+ validate: Validators.required,
190
189
  })
191
- name = ""
190
+ name = ''
192
191
 
193
192
  @Fields.string<Product>({
194
193
  validate: (product) => {
195
194
  if (product.description.trim().length < 50) {
196
- throw "too short"
195
+ throw 'too short'
197
196
  }
198
- }
197
+ },
199
198
  })
200
- description = ""
199
+ description = ''
201
200
 
202
201
  @Fields.number({
203
202
  validate: (_, field) => {
204
203
  if (field.value < 0) {
205
- field.error = "must not be less than 0" // or: throw "must not be less than 0";
204
+ field.error = 'must not be less than 0' // or: throw "must not be less than 0";
206
205
  }
207
- }
206
+ },
208
207
  })
209
208
  unitPrice = 0
210
209
  }
@@ -233,20 +232,20 @@ try {
233
232
  ### :lock: Secure the API with fine-grained authorization
234
233
 
235
234
  ```ts
236
- @Entity<Article>("Articles", {
235
+ @Entity<Article>('Articles', {
237
236
  allowApiRead: true,
238
237
  allowApiInsert: (_, remult) => remult.authenticated(),
239
- allowApiUpdate: (article, remult) => article.author.id == remult.user.id
238
+ allowApiUpdate: (article, remult) => article.author.id == remult.user.id,
240
239
  })
241
240
  export class Article {
242
241
  @Fields.string({ allowApiUpdate: false })
243
- slug = ""
242
+ slug = ''
244
243
 
245
244
  @Field(() => Profile, { allowApiUpdate: false })
246
245
  author!: Profile
247
246
 
248
247
  @Fields.string()
249
- content = ""
248
+ content = ''
250
249
  }
251
250
  ```
252
251
 
package/esm/index.d.ts CHANGED
@@ -1,8 +1,9 @@
1
- export { OmitEB, FieldsMetadata, FieldRef, IdFieldRef, FieldsRef, EntityMetadata, EntityOrderBy, EntityFilter, FindOptions, QueryResult, QueryOptions, Repository, FindFirstOptions, ComparisonValueFilter, ValueFilter, IdFilter, ContainsStringValueFilter, EntityRef, SortSegments, Paginator, LiveQuery, LiveQueryChangeInfo, Subscribable, RefSubscriber, RefSubscriberBase, RelationOptions, RelationOptionsBase, ObjectMembersOnly, MembersToInclude, RepositoryRelations, } from './src/remult3/remult3';
1
+ import type { ClassType } from './classType';
2
+ export { OmitEB, FieldsMetadata, FieldRef, IdFieldRef, FieldsRef, EntityMetadata, EntityOrderBy, EntityFilter, FindOptions, QueryResult, QueryOptions, Repository, FindFirstOptions, ComparisonValueFilter, ValueFilter, IdFilter, ContainsStringValueFilter, EntityRef, SortSegments, Paginator, LiveQuery, LiveQueryChangeInfo, Subscribable, RefSubscriber, RefSubscriberBase, RelationOptions, RelationOptionsBase, ObjectMembersOnly, MembersToInclude, RepositoryRelations, EntityIdFields, } from './src/remult3/remult3';
2
3
  export { EntityBase, ControllerBase, FieldType, getFields, ValueListFieldType, getValueList, ValueListFieldOptions, ValueListInfo, CaptionTransformer, } from './src/remult3/RepositoryImplementation';
3
4
  export { Entity } from './src/remult3/entity';
4
5
  export { getEntityRef } from './src/remult3/getEntityRef';
5
- export { Field, Fields, StringFieldOptions } from './src/remult3/Fields';
6
+ export { Field, Fields, StringFieldOptions, Relations, } from './src/remult3/Fields';
6
7
  export { IdEntity } from './src/remult3/IdEntity';
7
8
  export { describeClass } from './src/remult3/DecoratorReplacer';
8
9
  export { EntityOptions } from './src/entity';
@@ -21,7 +22,6 @@ export { Controller, BackendMethodOptions, BackendMethod, ProgressListener, } fr
21
22
  export { Allowed, Allow, Remult, RemultContext, ApiClient, isBackend, AllowedForInstance, EventDispatcher, EventSource, UserInfo, } from './src/context';
22
23
  export { ExternalHttpProvider } from './src/buildRestDataProvider';
23
24
  export { SortSegment, Sort } from './src/sort';
24
- export { OneToMany } from './src/column';
25
25
  export { CompoundIdField } from './src/CompoundIdField';
26
26
  export { Filter } from './src/filter/filter-interfaces';
27
27
  export { UrlBuilder } from './urlBuilder';
@@ -30,3 +30,4 @@ export { ValueConverters } from './src/valueConverters';
30
30
  export { remult } from './src/remult-proxy';
31
31
  export { SubscriptionServer, LiveQueryStorage, StoredQuery, InMemoryLiveQueryStorage, } from './src/live-query/SubscriptionServer';
32
32
  export { SubscriptionListener, SubscriptionClientConnection, SubscriptionClient, SubscriptionChannel, LiveQueryChange, Unsubscribe, } from './src/live-query/SubscriptionChannel';
33
+ export declare function repo<entityType>(entity: ClassType<entityType>): import("./src/remult3/remult3").Repository<entityType>;
package/esm/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  export { EntityBase, ControllerBase, FieldType, getFields, ValueListFieldType, getValueList, ValueListInfo, CaptionTransformer, } from './src/remult3/RepositoryImplementation';
2
2
  export { Entity } from './src/remult3/entity';
3
3
  export { getEntityRef } from './src/remult3/getEntityRef';
4
- export { Field, Fields } from './src/remult3/Fields';
4
+ export { Field, Fields, Relations, } from './src/remult3/Fields';
5
5
  export { IdEntity } from './src/remult3/IdEntity';
6
6
  export { describeClass } from './src/remult3/DecoratorReplacer';
7
7
  export { RestDataProvider } from './src/data-providers/rest-data-provider'; //V
@@ -15,13 +15,16 @@ export { JsonDataProvider, } from './src/data-providers/json-data-provider'; //V
15
15
  export { Controller, BackendMethod, ProgressListener, } from './src/server-action';
16
16
  export { Allow, Remult, isBackend, EventSource, } from './src/context';
17
17
  export { Sort } from './src/sort';
18
- export { OneToMany } from './src/column';
19
18
  export { CompoundIdField } from './src/CompoundIdField';
20
19
  export { Filter } from './src/filter/filter-interfaces';
21
20
  export { UrlBuilder } from './urlBuilder';
22
21
  export { Validators } from './src/validators';
23
22
  export { ValueConverters } from './src/valueConverters';
24
23
  export { remult } from './src/remult-proxy';
24
+ import { remult } from './src/remult-proxy';
25
25
  //export { getId } from './src/remult3/getId';
26
26
  export { InMemoryLiveQueryStorage, } from './src/live-query/SubscriptionServer';
27
27
  export { SubscriptionChannel, } from './src/live-query/SubscriptionChannel';
28
+ export function repo(entity) {
29
+ return remult.repo(entity);
30
+ }
@@ -4,3 +4,4 @@ export { getEntitySettings } from './src/remult3/getEntityRef';
4
4
  export { __updateEntityBasedOnWhere } from './src/filter/filter-interfaces';
5
5
  export { actionInfo } from './src/server-action-info';
6
6
  export { RelationInfo } from './src/remult3/remult3';
7
+ export { ClassType } from './classType';
@@ -86,6 +86,7 @@ class KnexEntityDataProvider {
86
86
  return +element;
87
87
  }
88
88
  }
89
+ throw Error("couldn't find count member");
89
90
  }
90
91
  async find(options) {
91
92
  const e = await this.init();
@@ -4,7 +4,7 @@ import type { RepositoryOverloads } from './src/remult3/RepositoryImplementation
4
4
  export declare class MongoDataProvider implements DataProvider {
5
5
  private db;
6
6
  private client;
7
- constructor(db: Db, client: MongoClient, options?: {
7
+ constructor(db: Db, client: MongoClient | undefined, options?: {
8
8
  session?: ClientSession;
9
9
  disableTransactions?: boolean;
10
10
  });
@@ -10,7 +10,7 @@ export class MongoDataProvider {
10
10
  this.db = db;
11
11
  this.client = client;
12
12
  this.session = options?.session;
13
- this.disableTransactions = options?.disableTransactions;
13
+ this.disableTransactions = Boolean(options?.disableTransactions);
14
14
  }
15
15
  session;
16
16
  disableTransactions = false;
@@ -28,6 +28,8 @@ export class MongoDataProvider {
28
28
  await action(this);
29
29
  }
30
30
  else {
31
+ if (!this.client)
32
+ throw new Error("Can't use transactions within transactions");
31
33
  let session = await this.client.startSession();
32
34
  session.startTransaction();
33
35
  const db = this.client.db(this.db.databaseName);
@@ -198,7 +200,7 @@ class FilterConsumerBridgeToMongo {
198
200
  f._addWhere = false;
199
201
  element.__applyToConsumer(f);
200
202
  let where = await f.resolveWhere();
201
- if (where?.$and?.length > 0) {
203
+ if (where?.$and?.length) {
202
204
  result.push(where);
203
205
  }
204
206
  else
@@ -8,7 +8,7 @@ export class JsonEntityFileStorage {
8
8
  if (fs.existsSync(fn)) {
9
9
  return fs.readFileSync(fn).toString();
10
10
  }
11
- return undefined;
11
+ return null;
12
12
  }
13
13
  setItem(entityDbName, json) {
14
14
  if (!fs.existsSync(this.folderPath)) {
@@ -1,6 +1,5 @@
1
1
  import type { RestDataProviderHttpProvider } from './data-interfaces';
2
- import { RestDataProviderHttpProviderUsingFetch } from './data-providers/rest-data-provider';
3
- export declare function buildRestDataProvider(provider: ExternalHttpProvider | typeof fetch): RestDataProviderHttpProviderUsingFetch | RestDataProviderHttpProvider;
2
+ export declare function buildRestDataProvider(provider: ExternalHttpProvider | typeof fetch): RestDataProviderHttpProvider;
4
3
  export declare function isExternalHttpProvider(item: any): boolean;
5
4
  export declare class HttpProviderBridgeToRestDataProviderHttpProvider implements RestDataProviderHttpProvider {
6
5
  private http;
@@ -1,6 +1,6 @@
1
1
  import type { ClassType } from '../classType';
2
2
  import type { Allowed, AllowedForInstance } from './context';
3
- import type { EntityMetadata, FieldRef, OmitEB } from './remult3/remult3';
3
+ import type { EntityMetadata, FieldRef, LifeCycleEvent, OmitEB } from './remult3/remult3';
4
4
  export interface FieldOptions<entityType = any, valueType = any> {
5
5
  /** A human readable name for the field. Can be used to achieve a consistent caption for a field throughout the app
6
6
  * @example
@@ -37,7 +37,7 @@ export interface FieldOptions<entityType = any, valueType = any> {
37
37
  */
38
38
  validate?: ((entity: entityType, fieldRef: FieldRef<entityType, valueType>) => any | Promise<any>) | ((entity: entityType, fieldRef: FieldRef<entityType, valueType>) => any | Promise<any>)[];
39
39
  /** Will be fired before this field is saved to the server/database */
40
- saving?: (entity: entityType, fieldRef: FieldRef<entityType, valueType>) => any | Promise<any>;
40
+ saving?: (entity: entityType, e: LifeCycleEvent<entityType>, fieldRef: FieldRef<entityType, valueType>) => any | Promise<any>;
41
41
  /** An expression that will determine this fields value on the backend and be provided to the front end*/
42
42
  serverExpression?: (entity: entityType) => valueType | Promise<valueType>;
43
43
  /** The name of the column in the database that holds the data for this field. If no name is set, the key will be used instead.
@@ -1,32 +1,19 @@
1
- import type { FindOptions, idType, Repository } from './remult3/remult3';
1
+ import type { idType } from './remult3/remult3';
2
2
  import type { RepositoryImplementation } from './remult3/RepositoryImplementation';
3
3
  export declare function makeTitle(name: string): string;
4
4
  export declare class LookupColumn<T> {
5
5
  private repository;
6
- private isManyToOneRelation;
6
+ private isReferenceRelation;
7
7
  toJson(): any;
8
8
  setId(val: any): void;
9
9
  waitLoadOf(id: any): Promise<T>;
10
10
  get(id: any): any;
11
- storedItem: {
11
+ storedItem?: {
12
12
  item: T;
13
13
  };
14
14
  set(item: T): void;
15
15
  id: idType<T>;
16
- constructor(repository: RepositoryImplementation<T>, isManyToOneRelation: any);
16
+ constructor(repository: RepositoryImplementation<T>, isReferenceRelation: any);
17
17
  get item(): T;
18
18
  waitLoad(): Promise<T>;
19
19
  }
20
- export declare class OneToMany<T> {
21
- private provider;
22
- private settings?;
23
- constructor(provider: Repository<T>, settings?: {
24
- create?: (newItem: T) => void;
25
- } & FindOptions<T>);
26
- private _items;
27
- private _currentPromise;
28
- get lazyItems(): T[];
29
- load(): Promise<T[]>;
30
- private find;
31
- create(item?: Partial<T>): T;
32
- }
package/esm/src/column.js CHANGED
@@ -1,5 +1,3 @@
1
- import { assign } from '../assign';
2
- import { __updateEntityBasedOnWhere } from './remult3/__updateEntityBasedOnWhere';
3
1
  import { getEntityRef } from './remult3/getEntityRef';
4
2
  export function makeTitle(name) {
5
3
  // insert a space before all caps
@@ -12,7 +10,7 @@ export function makeTitle(name) {
12
10
  }
13
11
  export class LookupColumn {
14
12
  repository;
15
- isManyToOneRelation;
13
+ isReferenceRelation;
16
14
  toJson() {
17
15
  if (!this.storedItem)
18
16
  return undefined;
@@ -33,7 +31,9 @@ export class LookupColumn {
33
31
  get(id) {
34
32
  if (id === undefined || id === null)
35
33
  return null;
36
- return this.repository.getCachedById(id, this.isManyToOneRelation);
34
+ if (this.isReferenceRelation && !this.storedItem)
35
+ return undefined;
36
+ return this.repository.getCachedById(id, this.isReferenceRelation);
37
37
  }
38
38
  storedItem;
39
39
  set(item) {
@@ -43,7 +43,7 @@ export class LookupColumn {
43
43
  this.id = item;
44
44
  else {
45
45
  let eo = getEntityRef(item, false);
46
- if (eo) {
46
+ if (eo && !this.isReferenceRelation) {
47
47
  this.repository.addToCache(item);
48
48
  this.id = eo.getId();
49
49
  }
@@ -61,9 +61,9 @@ export class LookupColumn {
61
61
  }
62
62
  }
63
63
  id;
64
- constructor(repository, isManyToOneRelation) {
64
+ constructor(repository, isReferenceRelation) {
65
65
  this.repository = repository;
66
- this.isManyToOneRelation = isManyToOneRelation;
66
+ this.isReferenceRelation = isReferenceRelation;
67
67
  }
68
68
  get item() {
69
69
  if (this.storedItem)
@@ -74,38 +74,3 @@ export class LookupColumn {
74
74
  return this.waitLoadOf(this.id);
75
75
  }
76
76
  }
77
- 9000;
78
- export class OneToMany {
79
- provider;
80
- settings;
81
- constructor(provider, settings) {
82
- this.provider = provider;
83
- this.settings = settings;
84
- }
85
- _items;
86
- _currentPromise;
87
- get lazyItems() {
88
- this.load();
89
- return this._items;
90
- }
91
- async load() {
92
- if (this._currentPromise != null)
93
- return this._currentPromise;
94
- if (this._items === undefined)
95
- this._items = [];
96
- return (this._currentPromise = this.find().then((x) => {
97
- this._items.splice(0);
98
- this._items.push(...x);
99
- return this._items;
100
- }));
101
- }
102
- async find() {
103
- return this.provider.find(this.settings);
104
- }
105
- create(item) {
106
- let r = this.provider.create();
107
- __updateEntityBasedOnWhere(this.provider.metadata, this.settings.where, r);
108
- assign(r, item);
109
- return r;
110
- }
111
- }
@@ -15,7 +15,7 @@ export declare class RemultAsyncLocalStorage {
15
15
  }
16
16
  type myAsyncLocalStorage<T> = {
17
17
  run<R>(store: T, callback: (...args: any[]) => R, ...args: any[]): R;
18
- getStore(): T;
18
+ getStore(): T | undefined;
19
19
  };
20
20
  export declare function isBackend(): boolean;
21
21
  export declare class Remult {
@@ -90,7 +90,7 @@ export class Remult {
90
90
  if (typeof roles === 'boolean')
91
91
  return roles;
92
92
  if (typeof roles === 'string')
93
- if (this.user?.roles?.indexOf(roles.toString()) >= 0)
93
+ if (this.user?.roles?.includes(roles.toString()))
94
94
  return true;
95
95
  return false;
96
96
  }
@@ -112,6 +112,7 @@ export class Remult {
112
112
  }
113
113
  else
114
114
  return this.isAllowed(allowed);
115
+ return undefined;
115
116
  }
116
117
  /** The current data provider */
117
118
  dataProvider = new RestDataProvider(() => this.apiClient);
@@ -1,7 +1,5 @@
1
1
  import { Sort } from './sort';
2
2
  export function extractSort(sort) {
3
- if (sort instanceof Sort)
4
- return sort;
5
3
  if (sort instanceof Array) {
6
4
  let r = new Sort();
7
5
  sort.forEach((i) => {
@@ -9,4 +7,5 @@ export function extractSort(sort) {
9
7
  });
10
8
  return r;
11
9
  }
10
+ return sort;
12
11
  }
@@ -4,8 +4,8 @@ import { Filter } from '../filter/filter-interfaces';
4
4
  import type { EntityFilter, EntityMetadata } from '../remult3/remult3';
5
5
  export declare class ArrayEntityDataProvider implements EntityDataProvider {
6
6
  private entity;
7
- private rows?;
8
7
  static rawFilter(filter: CustomArrayFilter): EntityFilter<any>;
8
+ private rows;
9
9
  constructor(entity: EntityMetadata, rows?: any[]);
10
10
  __names: EntityDbNamesBase;
11
11
  init(): Promise<EntityDbNamesBase>;
@@ -3,7 +3,6 @@ import { dbNamesOf, isDbReadonly, } from '../filter/filter-consumer-bridge-to-sq
3
3
  import { Filter, customDatabaseFilterToken } from '../filter/filter-interfaces';
4
4
  export class ArrayEntityDataProvider {
5
5
  entity;
6
- rows;
7
6
  static rawFilter(filter) {
8
7
  return {
9
8
  [customDatabaseFilterToken]: {
@@ -11,13 +10,13 @@ export class ArrayEntityDataProvider {
11
10
  },
12
11
  };
13
12
  }
13
+ rows;
14
14
  constructor(entity, rows) {
15
15
  this.entity = entity;
16
- this.rows = rows;
17
- if (!rows)
18
- rows = [];
19
- else {
20
- }
16
+ if (rows === undefined)
17
+ this.rows = [];
18
+ else
19
+ this.rows = rows;
21
20
  }
22
21
  __names;
23
22
  async init() {
@@ -88,6 +87,7 @@ export class ArrayEntityDataProvider {
88
87
  return rows.map((i) => {
89
88
  return this.translateFromJson(i, dbNames);
90
89
  });
90
+ return [];
91
91
  }
92
92
  translateFromJson(row, dbNames) {
93
93
  let result = {};
@@ -116,7 +116,7 @@ class WebSqlBridgeToSQLCommand {
116
116
  });
117
117
  t.executeSql(s, v, (t1, r) => resolve(new WebSqlBridgeToSQLQueryResult(r)), (t2, err) => {
118
118
  reject(err.message);
119
- return undefined;
119
+ return false;
120
120
  });
121
121
  }));
122
122
  }
@@ -125,13 +125,13 @@ class WebSqlBridgeToSQLQueryResult {
125
125
  r;
126
126
  getColumnKeyInResultForIndexInSelect(index) {
127
127
  if (this.rows.length == 0)
128
- return undefined;
128
+ throw Error('No rows');
129
129
  let i = 0;
130
130
  for (let m in this.rows[0]) {
131
131
  if (i++ == index)
132
132
  return m;
133
133
  }
134
- return undefined;
134
+ throw Error('index not found');
135
135
  }
136
136
  //@ts-ignore
137
137
  constructor(r) {
@@ -1,6 +1,6 @@
1
1
  import type { Allowed, AllowedForInstance } from './context';
2
2
  import type { FieldMetadata } from './column-interfaces';
3
- import type { EntityFilter, EntityMetadata, EntityOrderBy, EntityRef, FieldsMetadata } from './remult3/remult3';
3
+ import type { EntityFilter, EntityIdFields, EntityMetadata, EntityOrderBy, EntityRef, FieldsMetadata, LifeCycleEvent } from './remult3/remult3';
4
4
  export interface EntityOptions<entityType = any> {
5
5
  /**A human readable name for the entity */
6
6
  caption?: string;
@@ -60,13 +60,13 @@ export interface EntityOptions<entityType = any> {
60
60
  * }
61
61
  *})
62
62
  */
63
- saving?: (row: entityType, proceedWithoutSavingToDb: () => void) => Promise<any> | any;
63
+ saving?: (row: entityType, e: LifeCycleEvent<entityType>) => Promise<any> | any;
64
64
  /** will be called after the Entity was saved to the data source. */
65
- saved?: (row: entityType) => Promise<any> | any;
65
+ saved?: (row: entityType, e: LifeCycleEvent<entityType>) => Promise<any> | any;
66
66
  /** Will be called before an Entity is deleted. */
67
- deleting?: (row: entityType) => Promise<any> | any;
67
+ deleting?: (row: entityType, e: LifeCycleEvent<entityType>) => Promise<any> | any;
68
68
  /** Will be called after an Entity is deleted */
69
- deleted?: (row: entityType) => Promise<any> | any;
69
+ deleted?: (row: entityType, e: LifeCycleEvent<entityType>) => Promise<any> | any;
70
70
  /** Will be called when the entity is being validated, usually prior to the `saving` event */
71
71
  validation?: (row: entityType, ref: EntityRef<entityType>) => Promise<any> | any;
72
72
  /** The name of the table in the database that holds the data for this entity.
@@ -89,7 +89,7 @@ export interface EntityOptions<entityType = any> {
89
89
  * //Multiple columns id
90
90
  * @Entity<OrderDetails>("orderDetails", { id:od=> [od.orderId, od.productCode] })
91
91
  */
92
- id?: (entity: FieldsMetadata<entityType>) => FieldMetadata | FieldMetadata[];
92
+ id?: EntityIdFields<entityType> | ((entity: FieldsMetadata<entityType>) => FieldMetadata | FieldMetadata[]);
93
93
  entityRefInit?: (ref: EntityRef<entityType>, row: entityType) => void;
94
94
  apiRequireId?: Allowed;
95
95
  }
package/esm/src/entity.js CHANGED
@@ -1 +1,2 @@
1
1
  export {};
2
+ //[ ] make lazy only on field and not in Field Options
@@ -2,8 +2,8 @@ import type { FieldMetadata } from '../column-interfaces';
2
2
  import type { Remult } from '../context';
3
3
  import type { EntityFilter, EntityMetadata } from '../remult3/remult3';
4
4
  export declare class Filter {
5
- private apply?;
6
- constructor(apply?: (add: FilterConsumer) => void);
5
+ private apply;
6
+ constructor(apply: (add: FilterConsumer) => void);
7
7
  __applyToConsumer(add: FilterConsumer): void;
8
8
  static resolve<entityType>(filter: EntityFilter<entityType> | (() => EntityFilter<entityType> | Promise<EntityFilter<entityType>>)): Promise<EntityFilter<entityType>>;
9
9
  static createCustom<entityType>(rawFilterTranslator: (unused: never, r: Remult) => EntityFilter<entityType> | Promise<EntityFilter<entityType>>, key?: string): (() => EntityFilter<entityType>) & customFilterInfo<entityType>;
@@ -14,20 +14,6 @@ export declare class Filter {
14
14
  static entityFilterFromJson<T>(entityDefs: EntityMetadata<T>, packed: any): EntityFilter<T>;
15
15
  static translateCustomWhere<T>(r: Filter, entity: EntityMetadata<T>, remult: Remult): Promise<Filter>;
16
16
  }
17
- export declare class filterHelper {
18
- metadata: FieldMetadata;
19
- constructor(metadata: FieldMetadata);
20
- processVal(val: any): any;
21
- contains(val: string): Filter;
22
- isLessThan(val: any): Filter;
23
- isGreaterOrEqualTo(val: any): Filter;
24
- isNotIn(values: any[]): Filter;
25
- isDifferentFrom(val: any): Filter;
26
- isLessOrEqualTo(val: any): Filter;
27
- isGreaterThan(val: any): Filter;
28
- isEqualTo(val: any): Filter;
29
- isIn(val: any[]): Filter;
30
- }
31
17
  export interface FilterConsumer {
32
18
  or(orElements: Filter[]): any;
33
19
  isEqualTo(col: FieldMetadata, val: any): void;