remult 3.4.0 → 3.4.1

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.
@@ -124,10 +124,10 @@ export class RemultProxy {
124
124
  .remultFactory()
125
125
  .repo(...args)
126
126
  .updateMany(...args2),
127
- find: (options) => self
127
+ find: (...args2) => self
128
128
  .remultFactory()
129
129
  .repo(...args)
130
- .find(options),
130
+ .find(...args2),
131
131
  groupBy: (...args2) => self
132
132
  .remultFactory()
133
133
  .repo(...args)
@@ -138,14 +138,14 @@ export class RemultProxy {
138
138
  .repo(...args)
139
139
  //@ts-ignore
140
140
  .aggregate(...args2),
141
- findFirst: (where, options) => self
141
+ findFirst: (...args2) => self
142
142
  .remultFactory()
143
143
  .repo(...args)
144
- .findFirst(where, options),
145
- findOne: (options) => self
144
+ .findFirst(...args2),
145
+ findOne: (...args2) => self
146
146
  .remultFactory()
147
147
  .repo(...args)
148
- .findOne(options),
148
+ .findOne(...args2),
149
149
  findId: (a, b) => self
150
150
  .remultFactory()
151
151
  .repo(...args)
@@ -41,18 +41,6 @@ let classValidatorValidate = undefined;
41
41
  // })
42
42
  // .catch(() => {
43
43
  // });
44
- // Assigning a `toOne` also writes its `field`/`fields`, which would wipe the FK of a row whose
45
- // target is missing.
46
- function setMissingRelationToNull(row, key) {
47
- const ref = getEntityRef(row);
48
- ref._skipRelationFieldSync = true;
49
- try {
50
- row[key] = null;
51
- }
52
- finally {
53
- ref._skipRelationFieldSync = false;
54
- }
55
- }
56
44
  export class RepositoryImplementation {
57
45
  _entity;
58
46
  _remult;
@@ -744,12 +732,10 @@ export class RepositoryImplementation {
744
732
  for (const row of result) {
745
733
  let { findOptions, returnNull, returnUndefined } = this._findOptionsBasedOnRelation(rel, col, incl, row, otherRepo);
746
734
  const colKey = col.key;
747
- if (returnNull || returnUndefined) {
748
- if (rel.type === 'toMany')
749
- row[colKey] = (returnNull ? null : undefined);
750
- else
751
- setMissingRelationToNull(row, colKey);
752
- }
735
+ if (returnNull)
736
+ row[colKey] = null;
737
+ else if (returnUndefined)
738
+ row[colKey] = undefined;
753
739
  else {
754
740
  const entityType = rel.toEntity;
755
741
  const toRepo = otherRepo;
@@ -760,12 +746,14 @@ export class RepositoryImplementation {
760
746
  metadata: toRepo.metadata,
761
747
  }, findOptions)
762
748
  .then((result) => {
763
- if (rel.type === 'toMany')
764
- row[colKey] = result;
765
- else if (result.length == 0)
766
- setMissingRelationToNull(row, colKey);
767
- else
768
- row[colKey] = result[0];
749
+ if (result.length == 0 && rel.type == 'toOne')
750
+ return;
751
+ row[colKey] =
752
+ rel.type !== 'toMany'
753
+ ? result.length == 0
754
+ ? null
755
+ : result[0]
756
+ : result;
769
757
  });
770
758
  }
771
759
  }
@@ -1201,7 +1189,7 @@ class rowHelperBase {
1201
1189
  },
1202
1190
  set: (newVal) => {
1203
1191
  val = newVal;
1204
- if (newVal === undefined || this._skipRelationFieldSync)
1192
+ if (newVal === undefined)
1205
1193
  return;
1206
1194
  const op = col.options;
1207
1195
  if (op.field) {
@@ -1226,7 +1214,6 @@ class rowHelperBase {
1226
1214
  }
1227
1215
  }
1228
1216
  }
1229
- _skipRelationFieldSync = false;
1230
1217
  _subscribers;
1231
1218
  subscribe(listener) {
1232
1219
  this.initSubscribers();
@@ -1685,9 +1672,7 @@ export class rowHelperImplementation extends rowHelperBase {
1685
1672
  await listener.saved?.(this.instance, true);
1686
1673
  }
1687
1674
  }
1688
- this.repo._remult.liveQueryPublisher.itemChanged(this.repo.metadata.key, [
1689
- { id: this.getId(), oldId: this.getOriginalId(), deleted: false },
1690
- ]);
1675
+ this.repo._remult.liveQueryPublisher.itemChanged(this.repo.metadata.key, [{ id: this.getId(), oldId: this.getOriginalId(), deleted: false }]);
1691
1676
  this.saveOriginalData();
1692
1677
  this._isNew = false;
1693
1678
  return this.instance;
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 type { 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, Loaded, RepositoryRelations, EntityIdFields, EntitySelectFields, InsertOrUpdateOptions, ClassFieldDecorator, ClassFieldDecoratorContextStub, //n1 consider removing in ts5
5
+ export type { 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, ValueListInfo, } from './src/remult3/RepositoryImplementation.js';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "remult",
3
- "version": "3.4.0",
3
+ "version": "3.4.1",
4
4
  "description": "A CRUD framework for full-stack TypeScript",
5
5
  "homepage": "https://remult.dev",
6
6
  "repository": {
@@ -112,11 +112,16 @@ var RemultProxy = /** @class */ (function () {
112
112
  .repo.apply(_b, tslib_1.__spreadArray([], tslib_1.__read(args), false)))
113
113
  .updateMany.apply(_a, tslib_1.__spreadArray([], tslib_1.__read(args2), false));
114
114
  },
115
- _a.find = function (options) {
116
- var _a;
117
- return (_a = self
115
+ _a.find = function () {
116
+ var _a, _b;
117
+ var args2 = [];
118
+ for (var _i = 0; _i < arguments.length; _i++) {
119
+ args2[_i] = arguments[_i];
120
+ }
121
+ return (_a = (_b = self
118
122
  .remultFactory())
119
- .repo.apply(_a, tslib_1.__spreadArray([], tslib_1.__read(args), false)).find(options);
123
+ .repo.apply(_b, tslib_1.__spreadArray([], tslib_1.__read(args), false)))
124
+ .find.apply(_a, tslib_1.__spreadArray([], tslib_1.__read(args2), false));
120
125
  },
121
126
  _a.groupBy = function () {
122
127
  var _a, _b;
@@ -140,17 +145,27 @@ var RemultProxy = /** @class */ (function () {
140
145
  .repo.apply(_b, tslib_1.__spreadArray([], tslib_1.__read(args), false)))
141
146
  .aggregate.apply(_a, tslib_1.__spreadArray([], tslib_1.__read(args2), false));
142
147
  },
143
- _a.findFirst = function (where, options) {
144
- var _a;
145
- return (_a = self
148
+ _a.findFirst = function () {
149
+ var _a, _b;
150
+ var args2 = [];
151
+ for (var _i = 0; _i < arguments.length; _i++) {
152
+ args2[_i] = arguments[_i];
153
+ }
154
+ return (_a = (_b = self
146
155
  .remultFactory())
147
- .repo.apply(_a, tslib_1.__spreadArray([], tslib_1.__read(args), false)).findFirst(where, options);
156
+ .repo.apply(_b, tslib_1.__spreadArray([], tslib_1.__read(args), false)))
157
+ .findFirst.apply(_a, tslib_1.__spreadArray([], tslib_1.__read(args2), false));
148
158
  },
149
- _a.findOne = function (options) {
150
- var _a;
151
- return (_a = self
159
+ _a.findOne = function () {
160
+ var _a, _b;
161
+ var args2 = [];
162
+ for (var _i = 0; _i < arguments.length; _i++) {
163
+ args2[_i] = arguments[_i];
164
+ }
165
+ return (_a = (_b = self
152
166
  .remultFactory())
153
- .repo.apply(_a, tslib_1.__spreadArray([], tslib_1.__read(args), false)).findOne(options);
167
+ .repo.apply(_b, tslib_1.__spreadArray([], tslib_1.__read(args), false)))
168
+ .findOne.apply(_a, tslib_1.__spreadArray([], tslib_1.__read(args2), false));
154
169
  },
155
170
  _a.findId = function (a, b) {
156
171
  var _a;
@@ -106,7 +106,6 @@ declare abstract class rowHelperBase<T> {
106
106
  * must not be serialized by {@link toApiJson}. */
107
107
  _fieldsExcludedBySelect?: Set<string>;
108
108
  constructor(fieldsMetadata: FieldMetadata[], instance: T, remult: Remult, isNewRow: boolean, excludeRelationMembers?: Set<string>);
109
- _skipRelationFieldSync: boolean;
110
109
  _subscribers?: SubscribableImp;
111
110
  subscribe(listener: RefSubscriber): Unsubscribe;
112
111
  _isLoading: boolean;
@@ -57,18 +57,6 @@ var classValidatorValidate = undefined;
57
57
  // })
58
58
  // .catch(() => {
59
59
  // });
60
- // Assigning a `toOne` also writes its `field`/`fields`, which would wipe the FK of a row whose
61
- // target is missing.
62
- function setMissingRelationToNull(row, key) {
63
- var ref = (0, getEntityRef_js_1.getEntityRef)(row);
64
- ref._skipRelationFieldSync = true;
65
- try {
66
- row[key] = null;
67
- }
68
- finally {
69
- ref._skipRelationFieldSync = false;
70
- }
71
- }
72
60
  var RepositoryImplementation = /** @class */ (function () {
73
61
  function RepositoryImplementation(_entity, _remult, _dataProvider, _info, _defaultFindOptions) {
74
62
  this._entity = _entity;
@@ -1239,12 +1227,10 @@ var RepositoryImplementation = /** @class */ (function () {
1239
1227
  var _loop_2 = function (row) {
1240
1228
  var _e = this_1._findOptionsBasedOnRelation(rel, col, incl, row, otherRepo), findOptions = _e.findOptions, returnNull = _e.returnNull, returnUndefined = _e.returnUndefined;
1241
1229
  var colKey = col.key;
1242
- if (returnNull || returnUndefined) {
1243
- if (rel.type === 'toMany')
1244
- row[colKey] = (returnNull ? null : undefined);
1245
- else
1246
- setMissingRelationToNull(row, colKey);
1247
- }
1230
+ if (returnNull)
1231
+ row[colKey] = null;
1232
+ else if (returnUndefined)
1233
+ row[colKey] = undefined;
1248
1234
  else {
1249
1235
  var entityType = rel.toEntity;
1250
1236
  var toRepo_1 = otherRepo;
@@ -1259,12 +1245,14 @@ var RepositoryImplementation = /** @class */ (function () {
1259
1245
  metadata: toRepo_1.metadata,
1260
1246
  }, findOptions)
1261
1247
  .then(function (result) {
1262
- if (rel.type === 'toMany')
1263
- row[colKey] = result;
1264
- else if (result.length == 0)
1265
- setMissingRelationToNull(row, colKey);
1266
- else
1267
- row[colKey] = result[0];
1248
+ if (result.length == 0 && rel.type == 'toOne')
1249
+ return;
1250
+ row[colKey] =
1251
+ rel.type !== 'toMany'
1252
+ ? result.length == 0
1253
+ ? null
1254
+ : result[0]
1255
+ : result;
1268
1256
  });
1269
1257
  }
1270
1258
  };
@@ -1908,7 +1896,6 @@ var rowHelperBase = /** @class */ (function () {
1908
1896
  this.instance = instance;
1909
1897
  this.remult = remult;
1910
1898
  this.isNewRow = isNewRow;
1911
- this._skipRelationFieldSync = false;
1912
1899
  this._isLoading = false;
1913
1900
  this.lookups = new Map();
1914
1901
  this.originalValues = {};
@@ -1968,7 +1955,7 @@ var rowHelperBase = /** @class */ (function () {
1968
1955
  },
1969
1956
  set: function (newVal) {
1970
1957
  val_1 = newVal;
1971
- if (newVal === undefined || _this._skipRelationFieldSync)
1958
+ if (newVal === undefined)
1972
1959
  return;
1973
1960
  var op = col.options;
1974
1961
  if (op.field) {
@@ -2819,9 +2806,7 @@ var rowHelperImplementation = /** @class */ (function (_super) {
2819
2806
  finally { if (e_41) throw e_41.error; }
2820
2807
  return [7 /*endfinally*/];
2821
2808
  case 12:
2822
- this.repo._remult.liveQueryPublisher.itemChanged(this.repo.metadata.key, [
2823
- { id: this.getId(), oldId: this.getOriginalId(), deleted: false },
2824
- ]);
2809
+ this.repo._remult.liveQueryPublisher.itemChanged(this.repo.metadata.key, [{ id: this.getId(), oldId: this.getOriginalId(), deleted: false }]);
2825
2810
  this.saveOriginalData();
2826
2811
  this._isNew = false;
2827
2812
  return [2 /*return*/, this.instance];
@@ -395,10 +395,6 @@ export type GroupByResult<entityType, groupByFields extends (keyof entityType)[]
395
395
  };
396
396
  /** used to perform CRUD operations on an `entityType` */
397
397
  export interface Repository<entityType> {
398
- /** returns an array based on the provided options. Included relations drop their `?`, see {@link Loaded} */
399
- find<const include extends MembersToInclude<entityType>>(options: FindOptions<entityType> & {
400
- include: include;
401
- }): Promise<Loaded<entityType, include>[]>;
402
398
  /** returns an array based on the provided options */
403
399
  find(options?: FindOptions<entityType>): Promise<entityType[]>;
404
400
  /** Using the same options as the {@link find} method, but subscribing to entity changes.
@@ -414,9 +410,6 @@ export interface Repository<entityType> {
414
410
  * @example
415
411
  * await taskRepo.findFirst({ completed:false },{ createIfNotFound: true })
416
412
  * */
417
- findFirst<const include extends MembersToInclude<entityType>>(where: EntityFilter<entityType> | undefined, options: FindFirstOptions<entityType> & {
418
- include: include;
419
- }): Promise<Loaded<entityType, include> | undefined>;
420
413
  findFirst(where?: EntityFilter<entityType>, options?: FindFirstOptions<entityType>): Promise<entityType | undefined>;
421
414
  /** returns the first item that matchers the `where` condition
422
415
  * @example
@@ -424,14 +417,8 @@ export interface Repository<entityType> {
424
417
  * @example
425
418
  * await taskRepo.findFirst({ where:{ completed:false }, createIfNotFound: true })
426
419
  * */
427
- findOne<const include extends MembersToInclude<entityType>>(options: FindFirstOptions<entityType> & {
428
- include: include;
429
- }): Promise<Loaded<entityType, include> | undefined>;
430
420
  findOne(options?: FindFirstOptions<entityType>): Promise<entityType | undefined>;
431
421
  /** returns the items that matches the id. If id is undefined | null, returns null */
432
- findId<const include extends MembersToInclude<entityType>>(id: idType<entityType>, options: FindFirstOptionsBase<entityType> & {
433
- include: include;
434
- }): Promise<Loaded<entityType, include> | undefined | null>;
435
422
  findId(id: idType<entityType>, options?: FindFirstOptionsBase<entityType>): Promise<entityType | undefined | null>;
436
423
  /**
437
424
  * Performs an aggregation on the repository's entity type based on the specified options.
@@ -1196,29 +1183,6 @@ export type ObjectMembersOnly<T> = MembersOnly<{
1196
1183
  export type MembersToInclude<T> = {
1197
1184
  [K in keyof ObjectMembersOnly<T>]?: boolean | (NonNullable<T[K]> extends Array<any> ? FindOptions<NonNullable<T[K]>[number]> : FindFirstOptions<NonNullable<T[K]>>);
1198
1185
  };
1199
- type LoadedTarget<target, include> = include extends {
1200
- include: infer nested;
1201
- } ? Loaded<target, nested> : target;
1202
- type LoadedRelation<value, include> = NonNullable<value> extends (infer target)[] ? LoadedTarget<target, include>[] : null extends value ? LoadedTarget<NonNullable<value>, include> | null : LoadedTarget<NonNullable<value>, include>;
1203
- type LoadedKeys<entityType, include> = {
1204
- [K in keyof include & keyof entityType]-?: [include[K]] extends [
1205
- true | object
1206
- ] ? K : never;
1207
- }[keyof include & keyof entityType];
1208
- /**
1209
- * The entity type `find` returns for a given `include`.
1210
- * Included relations drop their `?`, and nested `include`s work the same way.
1211
- * A relation declared `| null` stays nullable.
1212
- * A relation included with `false` or a widened `boolean` keeps its declared type.
1213
- * An included relation whose target row is missing loads as `null`.
1214
- * Declare it `| null` when that can happen, e.g. an optional FK or a target a `backendPrefilter` can hide.
1215
- * @example
1216
- * const tasks = await repo(Task).find({ include: { category: true } })
1217
- * tasks[0].category.name // `category` is loaded, no `?.` needed
1218
- */
1219
- export type Loaded<entityType, include> = 0 extends 1 & (entityType | include) ? entityType : [LoadedKeys<entityType, include>] extends [never] ? entityType : Omit<entityType, LoadedKeys<entityType, include>> & {
1220
- [K in LoadedKeys<entityType, include>]-?: LoadedRelation<Exclude<entityType[K], undefined>, include[K]>;
1221
- };
1222
1186
  export type RepositoryRelations<entityType> = {
1223
1187
  [K in keyof ObjectMembersOnly<entityType>]-?: NonNullable<entityType[K]> extends Array<infer R> ? Repository<R> : entityType[K] extends infer R ? {
1224
1188
  findOne: (options?: FindOptionsBase<R>) => Promise<R>;
@@ -1265,4 +1229,3 @@ export declare const flags: {
1265
1229
  /** Version poll while SSE is stale */
1266
1230
  liveQueryPollWhenStaleMs: number;
1267
1231
  };
1268
- export {};