remult 0.23.0-exp.26 → 0.23.0-exp.28

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.
@@ -1,4 +1,4 @@
1
- import type { ClientSession, Db, MongoClient } from 'mongodb';
1
+ import { type ClientSession, type Db, type MongoClient } from 'mongodb';
2
2
  import type { DataProvider, EntityDataProvider, EntityFilter, EntityMetadata, Remult } from '.';
3
3
  import type { RepositoryOverloads } from './src/remult3/RepositoryImplementation';
4
4
  export declare class MongoDataProvider implements DataProvider {
@@ -1,3 +1,4 @@
1
+ import { ObjectId, } from 'mongodb';
1
2
  import { CompoundIdField, Filter } from '.';
2
3
  import { dbNamesOf } from './src/filter/filter-consumer-bridge-to-sql-request';
3
4
  import { remult as remultContext } from './src/remult-proxy';
@@ -75,14 +76,14 @@ class MongoEntityDataProvider {
75
76
  let val = row[nameProvider.$dbNameOf(col)];
76
77
  if (isNull(val))
77
78
  val = null;
78
- result[col.key] = col.valueConverter.fromDb(val);
79
+ result[col.key] = fromDb(col, val);
79
80
  }
80
81
  return result;
81
82
  }
82
83
  translateToDb(row, nameProvider) {
83
84
  let result = {};
84
85
  for (const col of this.entity.fields) {
85
- let val = col.valueConverter.toDb(row[col.key]);
86
+ let val = toDb(col, row[col.key]);
86
87
  if (val === null)
87
88
  val = NULL;
88
89
  result[nameProvider.$dbNameOf(col)] = val;
@@ -221,7 +222,7 @@ class FilterConsumerBridgeToMongo {
221
222
  isIn(col, val) {
222
223
  this.result.push(() => ({
223
224
  [this.nameProvider.$dbNameOf(col)]: {
224
- $in: val.map((x) => col.valueConverter.toDb(x)),
225
+ $in: val.map((x) => toDb(col, x)),
225
226
  },
226
227
  }));
227
228
  }
@@ -253,7 +254,7 @@ class FilterConsumerBridgeToMongo {
253
254
  add(col, val, operator) {
254
255
  this.result.push(() => ({
255
256
  [this.nameProvider.$dbNameOf(col)]: {
256
- [operator]: isNull(val) ? val : col.valueConverter.toDb(val),
257
+ [operator]: isNull(val) ? val : toDb(col, val),
257
258
  },
258
259
  }));
259
260
  }
@@ -270,3 +271,13 @@ class FilterConsumerBridgeToMongo {
270
271
  // })());
271
272
  }
272
273
  }
274
+ function toDb(col, val) {
275
+ if (col.valueConverter.fieldTypeInDb == 'dbid')
276
+ return val ? new ObjectId(val) : val === null ? null : undefined;
277
+ return col.valueConverter.toDb(val);
278
+ }
279
+ function fromDb(col, val) {
280
+ if (col.valueConverter.fieldTypeInDb == 'dbid')
281
+ return val ? val.toHexString() : val === null ? null : undefined;
282
+ return col.valueConverter.fromDb(val);
283
+ }
@@ -992,4 +992,4 @@ JobsInQueueEntity = __decorate([
992
992
  ], JobsInQueueEntity);
993
993
  export { JobsInQueueEntity };
994
994
  allEntities.splice(allEntities.indexOf(JobsInQueueEntity), 1);
995
- //p1 - https://codesandbox.io/p/sandbox/fervent-yalow-66m78n?file=%2Fsrc%2Findex.ts%3A35%2C93
995
+ //p1 - implement dbname based on related field https://codesandbox.io/p/sandbox/fervent-yalow-66m78n?file=%2Fsrc%2Findex.ts%3A35%2C93
@@ -289,4 +289,4 @@ class transactionLiveQueryPublisher {
289
289
  //p1 - seems that after backend methods relations are loaded for some reason - see trempim - intake doRequest backend method
290
290
  //p1 - reconsider the case in tremping where create user id was updated with some user and not the actual user
291
291
  //[ ] - when value changes for field with error, clear error - so the user will feel comfortable
292
- //y1 - require filter argument - and perform validation checks for it - site, id etc.. changelog, status changes etc...,
292
+ //y2 - require filter argument - and perform validation checks for it - site, id etc.. changelog, status changes etc...,
@@ -54,26 +54,6 @@ export declare class Relations {
54
54
  * ```
55
55
  */
56
56
  static toOne<entityType, toEntityType>(toEntityType: () => ClassType<toEntityType>, fieldInMyEntity?: keyof entityType): ClassFieldDecorator<entityType, toEntityType | undefined>;
57
- /**
58
- * Define a to-one relation between entities, indicating a one-to-one relationship.
59
- * This overload allows you to define the relation using options.
60
- * If no field or fields are provided, it will automatically create a field in the database
61
- * to represent the relation.
62
- *
63
- * @param toEntityType A function that returns the target entity type.
64
- * @param options An object containing options for configuring the to-one relation.
65
- * - field (Optional): The name of the field in the related entity that corresponds to this relation.
66
- * @returns A decorator function to apply the virtual to-one relation to an entity field.
67
- *
68
- * Example usage:
69
- * ```
70
- * @Relations.toOne(() => Customer, {
71
- * field: "customerId",
72
- * })
73
- * customer?: Customer;
74
- * ```
75
- */
76
- static toOne<entityType, toEntityType>(toEntityType: () => ClassType<toEntityType>, fieldInMyEntity?: keyof entityType): ClassFieldDecorator<entityType, toEntityType | undefined>;
77
57
  /**
78
58
  * Define a to-one relation between entities, indicating a one-to-one relationship.
79
59
  * If no field or fields are provided, it will automatically create a field in the database
@@ -524,7 +524,11 @@ export class RepositoryImplementation {
524
524
  if (options.field) {
525
525
  if (rel.type === 'toOne') {
526
526
  requireField(options.field, this.metadata);
527
- where.push(otherRepo.metadata.idMetadata.getIdFilter(row[options.field]));
527
+ const val = row[options.field];
528
+ if (val === null)
529
+ returnNull = true;
530
+ else
531
+ where.push(otherRepo.metadata.idMetadata.getIdFilter(val));
528
532
  }
529
533
  else {
530
534
  requireField(options.field, otherRepo.metadata);
@@ -3,35 +3,17 @@ export {};
3
3
  //p1 - include Relation options in the api docs
4
4
  //p1 - fix { allowApiRead: r => r.user.name === 'superman' } } in allowed for instace docs
5
5
  //p1 - fix seeallowed in ref_entity
6
- //p1 - write doc about controlling updates of rows...
7
- //p1 - 'eventId' autocomplete in task app did not work
8
- //p1 - need a way to extract the fields from the relation - for generating relation based sql
9
- //p1 - remult object was used outside context
10
- // ```
11
- // sqlExpression: async (e) => {
12
- // const v = await dbNamesOf(volunteerInTask)
13
- // return `select true from ${v} where ${
14
- // v.task
15
- // }=${await e.getDbName()}.${await e.fields.id.getDbName()} and ${SqlDatabase.filterToRaw<volunteerInTask>(
16
- // repo(volunteerInTask),
17
- // {
18
- // canceled: false,
19
- // }
20
- // )}`
21
- // },
22
- // })
23
- // ```
24
- //p2 - consider includeInApi as AllowedForInstance
25
- //p1 - why didn't this._.relations.statusChanges.insert({})work?
6
+ //p2 - write doc about controlling updates of rows...
7
+ //p2 - need a way to extract the fields from the relation - for generating relation based sql
8
+ //p1 - omit functions from fields and relations
26
9
  //p1 - active record with include thinks that the row was change!
27
- //p1 - add docs for apply changes
28
- //p1 - update related field with null should respect it's allowed null - otherwise we get a null error for that field.
10
+ //p2 - add docs for apply changes
29
11
  //p1 - when the include doesn't find the many to one - it deletes the id!!!
30
- //y1 - discuss a default date formatter
31
- //p1 - consider using this in saving etc...
32
- //p1 - when subscribe is forbidden - the query still runs after the renew process
33
- //p1 - JSON FIELD LOST JSON STORAGE WHEN SET INPUT VALUE
34
- //p1 - doc this:
12
+ //y2 - discuss a default date formatter
13
+ //[ ] - consider using this in saving etc...
14
+ //p2 - when subscribe is forbidden - the query still runs after the renew process
15
+ //p2 - JSON FIELD LOST JSON STORAGE WHEN SET INPUT VALUE
16
+ //p2 - doc this:
35
17
  /**
36
18
  * //p1 - doc this
37
19
  remult.apiClient.httpClient = (
@@ -52,6 +34,26 @@ remult.apiClient.url='localhost:3007/api
52
34
 
53
35
 
54
36
  */
55
- //p1 - with remult promise for remultexpress
56
- //p1 - 'update tasks set where id = $1
57
- //p1 - live query refresh of view on table update
37
+ //p2 - with remult promise for remultexpress
38
+ //p2 - 'update tasks set where id = $1
39
+ //p2 - live query refresh of view on table update
40
+ //p2 - Operator '>' cannot be applied to types 'Number' and 'number'.ts(2365) - change fields to <entityType,number> (now it's Number)
41
+ //p2 - Field(()=>String) - doesn't play nice with strict mode - it prevents people from extending basic types
42
+ //p2 - with remult for remultexpress
43
+ //p1 - Add a with remult promise to Remult!
44
+ //p1 - YONI field didn't appear in intelisence of manyToNe
45
+ //p1 - YONI with relation to one, fields doesn't appear well in the overload options when trying to set driver phone on trempim
46
+ //p1 - YONI why didn't this._.relations.statusChanges.insert({})work?
47
+ //p1 - YONI 'taskid' toOne field parameter did not autocomplete in task app - C:\repos\help-zahal\src\app\events\volunteerInTask.ts 49
48
+ //p2 - filterToRaw should get a dbnames of - and we should create a dbnames of that supports an alias
49
+ //p1 - DO NOT BREAK - move fieldref to second parameter, and lifecycle to 3rd consider the breaking signature change of saving on field options - the field becomes the 3rd parameter.
50
+ //p1 - test what happens with a many to one relation where the one no longer exist, in all 3 cases (toOne,reference,toone with fields)
51
+ //p1 - findid by default has cache - it sucks!
52
+ //p1 - mongo db relation based on _id did not work - https://codesandbox.io/p/devbox/mong-db-remult-pch8zc?file=%2Fsrc%2Findex.ts%3A53%2C51
53
+ //y2 - livequery for findfirst (@JY)
54
+ //y2 - #239 - (@JY) add a way to get from fieldMetadata back to entity repo (like we have in fieldRef)
55
+ //p2 - constraints (@JY)
56
+ //p2 - Add ability to process query that comes from the api
57
+ //p2 - too much data by mistake
58
+ //p2 - postgres case sensitive
59
+ //p1 - talk about mongo object id
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "remult",
3
- "version": "0.23.0-exp.26",
3
+ "version": "0.23.0-exp.28",
4
4
  "description": "A CRUD framework for full-stack TypeScript",
5
5
  "types": "index.d.ts",
6
6
  "module": "esm/index.js",
package/remult-mongo.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import type { ClientSession, Db, MongoClient } from 'mongodb';
1
+ import { type ClientSession, type Db, type MongoClient } from 'mongodb';
2
2
  import type { DataProvider, EntityDataProvider, EntityFilter, EntityMetadata, Remult } from '.';
3
3
  import type { RepositoryOverloads } from './src/remult3/RepositoryImplementation';
4
4
  export declare class MongoDataProvider implements DataProvider {
package/remult-mongo.js CHANGED
@@ -2,6 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.MongoDataProvider = void 0;
4
4
  var tslib_1 = require("tslib");
5
+ var mongodb_1 = require("mongodb");
5
6
  var _1 = require(".");
6
7
  var filter_consumer_bridge_to_sql_request_1 = require("./src/filter/filter-consumer-bridge-to-sql-request");
7
8
  var remult_proxy_1 = require("./src/remult-proxy");
@@ -115,7 +116,7 @@ var MongoEntityDataProvider = /** @class */ (function () {
115
116
  var val = row[nameProvider.$dbNameOf(col)];
116
117
  if (isNull(val))
117
118
  val = null;
118
- result[col.key] = col.valueConverter.fromDb(val);
119
+ result[col.key] = fromDb(col, val);
119
120
  }
120
121
  }
121
122
  catch (e_1_1) { e_1 = { error: e_1_1 }; }
@@ -133,7 +134,7 @@ var MongoEntityDataProvider = /** @class */ (function () {
133
134
  try {
134
135
  for (var _b = tslib_1.__values(this.entity.fields), _c = _b.next(); !_c.done; _c = _b.next()) {
135
136
  var col = _c.value;
136
- var val = col.valueConverter.toDb(row[col.key]);
137
+ var val = toDb(col, row[col.key]);
137
138
  if (val === null)
138
139
  val = NULL;
139
140
  result[nameProvider.$dbNameOf(col)] = val;
@@ -462,7 +463,7 @@ var FilterConsumerBridgeToMongo = /** @class */ (function () {
462
463
  var _a;
463
464
  return (_a = {},
464
465
  _a[_this.nameProvider.$dbNameOf(col)] = {
465
- $in: val.map(function (x) { return col.valueConverter.toDb(x); }),
466
+ $in: val.map(function (x) { return toDb(col, x); }),
466
467
  },
467
468
  _a);
468
469
  });
@@ -498,7 +499,7 @@ var FilterConsumerBridgeToMongo = /** @class */ (function () {
498
499
  var _a, _b;
499
500
  return (_a = {},
500
501
  _a[_this.nameProvider.$dbNameOf(col)] = (_b = {},
501
- _b[operator] = isNull(val) ? val : col.valueConverter.toDb(val),
502
+ _b[operator] = isNull(val) ? val : toDb(col, val),
502
503
  _b),
503
504
  _a);
504
505
  });
@@ -517,3 +518,13 @@ var FilterConsumerBridgeToMongo = /** @class */ (function () {
517
518
  };
518
519
  return FilterConsumerBridgeToMongo;
519
520
  }());
521
+ function toDb(col, val) {
522
+ if (col.valueConverter.fieldTypeInDb == 'dbid')
523
+ return val ? new mongodb_1.ObjectId(val) : val === null ? null : undefined;
524
+ return col.valueConverter.toDb(val);
525
+ }
526
+ function fromDb(col, val) {
527
+ if (col.valueConverter.fieldTypeInDb == 'dbid')
528
+ return val ? val.toHexString() : val === null ? null : undefined;
529
+ return col.valueConverter.fromDb(val);
530
+ }
@@ -1406,4 +1406,4 @@ var JobsInQueueEntity = /** @class */ (function (_super) {
1406
1406
  }(IdEntity_1.IdEntity));
1407
1407
  exports.JobsInQueueEntity = JobsInQueueEntity;
1408
1408
  context_1.allEntities.splice(context_1.allEntities.indexOf(JobsInQueueEntity), 1);
1409
- //p1 - https://codesandbox.io/p/sandbox/fervent-yalow-66m78n?file=%2Fsrc%2Findex.ts%3A35%2C93
1409
+ //p1 - implement dbname based on related field https://codesandbox.io/p/sandbox/fervent-yalow-66m78n?file=%2Fsrc%2Findex.ts%3A35%2C93
package/src/context.js CHANGED
@@ -453,4 +453,4 @@ var transactionLiveQueryPublisher = /** @class */ (function () {
453
453
  //p1 - seems that after backend methods relations are loaded for some reason - see trempim - intake doRequest backend method
454
454
  //p1 - reconsider the case in tremping where create user id was updated with some user and not the actual user
455
455
  //[ ] - when value changes for field with error, clear error - so the user will feel comfortable
456
- //y1 - require filter argument - and perform validation checks for it - site, id etc.. changelog, status changes etc...,
456
+ //y2 - require filter argument - and perform validation checks for it - site, id etc.. changelog, status changes etc...,
@@ -54,26 +54,6 @@ export declare class Relations {
54
54
  * ```
55
55
  */
56
56
  static toOne<entityType, toEntityType>(toEntityType: () => ClassType<toEntityType>, fieldInMyEntity?: keyof entityType): ClassFieldDecorator<entityType, toEntityType | undefined>;
57
- /**
58
- * Define a to-one relation between entities, indicating a one-to-one relationship.
59
- * This overload allows you to define the relation using options.
60
- * If no field or fields are provided, it will automatically create a field in the database
61
- * to represent the relation.
62
- *
63
- * @param toEntityType A function that returns the target entity type.
64
- * @param options An object containing options for configuring the to-one relation.
65
- * - field (Optional): The name of the field in the related entity that corresponds to this relation.
66
- * @returns A decorator function to apply the virtual to-one relation to an entity field.
67
- *
68
- * Example usage:
69
- * ```
70
- * @Relations.toOne(() => Customer, {
71
- * field: "customerId",
72
- * })
73
- * customer?: Customer;
74
- * ```
75
- */
76
- static toOne<entityType, toEntityType>(toEntityType: () => ClassType<toEntityType>, fieldInMyEntity?: keyof entityType): ClassFieldDecorator<entityType, toEntityType | undefined>;
77
57
  /**
78
58
  * Define a to-one relation between entities, indicating a one-to-one relationship.
79
59
  * If no field or fields are provided, it will automatically create a field in the database
@@ -877,7 +877,11 @@ var RepositoryImplementation = /** @class */ (function () {
877
877
  if (options.field) {
878
878
  if (rel.type === 'toOne') {
879
879
  requireField(options.field, this.metadata);
880
- where.push(otherRepo.metadata.idMetadata.getIdFilter(row[options.field]));
880
+ var val = row[options.field];
881
+ if (val === null)
882
+ returnNull = true;
883
+ else
884
+ where.push(otherRepo.metadata.idMetadata.getIdFilter(val));
881
885
  }
882
886
  else {
883
887
  requireField(options.field, otherRepo.metadata);
@@ -4,35 +4,17 @@ Object.defineProperty(exports, "__esModule", { value: true });
4
4
  //p1 - include Relation options in the api docs
5
5
  //p1 - fix { allowApiRead: r => r.user.name === 'superman' } } in allowed for instace docs
6
6
  //p1 - fix seeallowed in ref_entity
7
- //p1 - write doc about controlling updates of rows...
8
- //p1 - 'eventId' autocomplete in task app did not work
9
- //p1 - need a way to extract the fields from the relation - for generating relation based sql
10
- //p1 - remult object was used outside context
11
- // ```
12
- // sqlExpression: async (e) => {
13
- // const v = await dbNamesOf(volunteerInTask)
14
- // return `select true from ${v} where ${
15
- // v.task
16
- // }=${await e.getDbName()}.${await e.fields.id.getDbName()} and ${SqlDatabase.filterToRaw<volunteerInTask>(
17
- // repo(volunteerInTask),
18
- // {
19
- // canceled: false,
20
- // }
21
- // )}`
22
- // },
23
- // })
24
- // ```
25
- //p2 - consider includeInApi as AllowedForInstance
26
- //p1 - why didn't this._.relations.statusChanges.insert({})work?
7
+ //p2 - write doc about controlling updates of rows...
8
+ //p2 - need a way to extract the fields from the relation - for generating relation based sql
9
+ //p1 - omit functions from fields and relations
27
10
  //p1 - active record with include thinks that the row was change!
28
- //p1 - add docs for apply changes
29
- //p1 - update related field with null should respect it's allowed null - otherwise we get a null error for that field.
11
+ //p2 - add docs for apply changes
30
12
  //p1 - when the include doesn't find the many to one - it deletes the id!!!
31
- //y1 - discuss a default date formatter
32
- //p1 - consider using this in saving etc...
33
- //p1 - when subscribe is forbidden - the query still runs after the renew process
34
- //p1 - JSON FIELD LOST JSON STORAGE WHEN SET INPUT VALUE
35
- //p1 - doc this:
13
+ //y2 - discuss a default date formatter
14
+ //[ ] - consider using this in saving etc...
15
+ //p2 - when subscribe is forbidden - the query still runs after the renew process
16
+ //p2 - JSON FIELD LOST JSON STORAGE WHEN SET INPUT VALUE
17
+ //p2 - doc this:
36
18
  /**
37
19
  * //p1 - doc this
38
20
  remult.apiClient.httpClient = (
@@ -53,6 +35,26 @@ remult.apiClient.url='localhost:3007/api
53
35
 
54
36
 
55
37
  */
56
- //p1 - with remult promise for remultexpress
57
- //p1 - 'update tasks set where id = $1
58
- //p1 - live query refresh of view on table update
38
+ //p2 - with remult promise for remultexpress
39
+ //p2 - 'update tasks set where id = $1
40
+ //p2 - live query refresh of view on table update
41
+ //p2 - Operator '>' cannot be applied to types 'Number' and 'number'.ts(2365) - change fields to <entityType,number> (now it's Number)
42
+ //p2 - Field(()=>String) - doesn't play nice with strict mode - it prevents people from extending basic types
43
+ //p2 - with remult for remultexpress
44
+ //p1 - Add a with remult promise to Remult!
45
+ //p1 - YONI field didn't appear in intelisence of manyToNe
46
+ //p1 - YONI with relation to one, fields doesn't appear well in the overload options when trying to set driver phone on trempim
47
+ //p1 - YONI why didn't this._.relations.statusChanges.insert({})work?
48
+ //p1 - YONI 'taskid' toOne field parameter did not autocomplete in task app - C:\repos\help-zahal\src\app\events\volunteerInTask.ts 49
49
+ //p2 - filterToRaw should get a dbnames of - and we should create a dbnames of that supports an alias
50
+ //p1 - DO NOT BREAK - move fieldref to second parameter, and lifecycle to 3rd consider the breaking signature change of saving on field options - the field becomes the 3rd parameter.
51
+ //p1 - test what happens with a many to one relation where the one no longer exist, in all 3 cases (toOne,reference,toone with fields)
52
+ //p1 - findid by default has cache - it sucks!
53
+ //p1 - mongo db relation based on _id did not work - https://codesandbox.io/p/devbox/mong-db-remult-pch8zc?file=%2Fsrc%2Findex.ts%3A53%2C51
54
+ //y2 - livequery for findfirst (@JY)
55
+ //y2 - #239 - (@JY) add a way to get from fieldMetadata back to entity repo (like we have in fieldRef)
56
+ //p2 - constraints (@JY)
57
+ //p2 - Add ability to process query that comes from the api
58
+ //p2 - too much data by mistake
59
+ //p2 - postgres case sensitive
60
+ //p1 - talk about mongo object id