remult 3.4.0-next.7 → 3.4.0-next.9

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.
@@ -181,7 +181,7 @@ export class SqlDatabase {
181
181
  static async selectToRaw(repo, options, sql) {
182
182
  const r = getRepository(repo);
183
183
  const built = await buildFindSql(r.metadata, await getRepositoryInternals(r)._buildEntityDataProviderFindOptions(options ?? {}), sql?.dbNames ??
184
- (await dbNamesOfWithForceSqlExpression(r.metadata, sql?.wrapIdentifier ?? wrapIdentifierOf(r))), sql?.sqlCommand ?? new myDummySQLCommand(), false, sql?.limitSyntax ?? limitSyntaxRequired, { aliasColumns: true, defaultOrderBy: false });
184
+ (await dbNamesOfWithForceSqlExpression(r.metadata, sql?.wrapIdentifier ?? wrapIdentifierOf(r))), sql?.sqlCommand ?? new myDummySQLCommand(), false, sql?.limitSyntax ?? limitSyntaxRequired, { aliasColumns: true });
185
185
  return {
186
186
  sql: built.select,
187
187
  toResult: (row) => built.toResult((_, alias) => row[alias]),
@@ -353,6 +353,8 @@ class ActualSQLEntityDataProvider {
353
353
  async find(options) {
354
354
  const e = await this.init();
355
355
  const r = this.sql.createCommand();
356
+ if (options && !options.orderBy)
357
+ options.orderBy = Sort.createUniqueSort(this.entity, new Sort());
356
358
  const { select, toResult } = await buildFindSql(this.entity, options, e, r, this.sql._getSourceSql().orderByNullsFirst, (limit, offset) => this.strategy.getLimitSqlSyntax(limit, offset));
357
359
  const result = await r.execute(select);
358
360
  return result.rows.map((y) => toResult((i) => y[result.getColumnKeyInResultForIndexInSelect(i)]));
@@ -560,7 +562,7 @@ export function getRowAfterUpdate(meta, dataProvider, data, id, operation) {
560
562
  });
561
563
  }
562
564
  /** The select that `find` runs, and the mapping of one result row to field values. With `aliasColumns`, every column is aliased through `wrapIdentifier`, so a row can be read by alias as well as by position. */
563
- export async function buildFindSql(entity, options, e, r, orderByNullsFirst, limitSyntax, { aliasColumns = false, defaultOrderBy = true } = {}) {
565
+ export async function buildFindSql(entity, options, e, r, orderByNullsFirst, limitSyntax, { aliasColumns = false } = {}) {
564
566
  const { colKeys, select: columns } = await selectColumns(entity, e, r, options?.select, options?.args, aliasColumns);
565
567
  let select = 'select ' + columns + '\n from ' + e.$entityName;
566
568
  if (options) {
@@ -572,9 +574,6 @@ export async function buildFindSql(entity, options, e, r, orderByNullsFirst, lim
572
574
  if (options.limit) {
573
575
  options.orderBy = Sort.createUniqueSort(entity, options.orderBy);
574
576
  }
575
- if (!options.orderBy && defaultOrderBy) {
576
- options.orderBy = Sort.createUniqueSort(entity, new Sort());
577
- }
578
577
  if (options.orderBy) {
579
578
  let first = true;
580
579
  for (const c of options.orderBy.Segments) {
@@ -597,7 +597,16 @@ export class RepositoryImplementation {
597
597
  if (this._defaultFindOptions) {
598
598
  options = { ...this._defaultFindOptions, ...options };
599
599
  }
600
- let opt = await this._buildEntityDataProviderFindOptions(options);
600
+ let findOptions = options;
601
+ if ((!findOptions.orderBy || Object.keys(findOptions.orderBy).length === 0) &&
602
+ !this._dataProvider.isProxy &&
603
+ this._info.entityInfo.defaultOrderBy) {
604
+ findOptions = {
605
+ ...findOptions,
606
+ orderBy: this._info.entityInfo.defaultOrderBy,
607
+ };
608
+ }
609
+ let opt = await this._buildEntityDataProviderFindOptions(findOptions);
601
610
  if (skipOrderByAndLimit) {
602
611
  delete opt.orderBy;
603
612
  delete opt.limit;
@@ -633,10 +642,6 @@ export class RepositoryImplementation {
633
642
  return f.key;
634
643
  });
635
644
  }
636
- if (!options.orderBy || Object.keys(options.orderBy).length === 0) {
637
- if (!this._dataProvider.isProxy)
638
- options.orderBy = this._info.entityInfo.defaultOrderBy;
639
- }
640
645
  opt.where = await this._translateWhereToFilter(options.where);
641
646
  if (options.orderBy !== undefined)
642
647
  opt.orderBy = Sort.translateOrderByToSort(this.metadata, options.orderBy);
@@ -2454,21 +2459,21 @@ export class ValueListInfo {
2454
2459
  getValues() {
2455
2460
  return this.values;
2456
2461
  }
2457
- byId(key) {
2458
- if (this.isNumeric)
2459
- key = +key;
2460
- return this.byIdMap.get(key);
2461
- }
2462
- fromJson(val) {
2463
- const known = this.byId(val);
2464
- if (known !== undefined)
2462
+ /** Declared id only. Pass `useUnknownIdValue` to also apply `unknownIdValue` (`null` and `undefined` still return `undefined`). */
2463
+ byId(key, useUnknownIdValue = false) {
2464
+ const lookupKey = this.isNumeric ? +key : key;
2465
+ const known = this.byIdMap.get(lookupKey);
2466
+ if (known !== undefined || !useUnknownIdValue)
2465
2467
  return known;
2466
- if (val == null)
2468
+ if (key == null)
2467
2469
  return undefined;
2468
2470
  const fallback = this.unknownIdValue;
2469
2471
  if (typeof fallback !== 'function')
2470
2472
  return fallback;
2471
- return fallback(this.isNumeric ? +val : val);
2473
+ return fallback(lookupKey);
2474
+ }
2475
+ fromJson(val) {
2476
+ return this.byId(val, true);
2472
2477
  }
2473
2478
  toJson(val) {
2474
2479
  if (!val)
package/esm/src/sort.js CHANGED
@@ -128,9 +128,6 @@ export class Sort {
128
128
  * @returns {Sort} A `Sort` instance representing the unique sort criteria.
129
129
  */
130
130
  static createUniqueSort(entityMetadata, orderBy) {
131
- if ((!orderBy || Object.keys(orderBy).length === 0) &&
132
- entityMetadata.options.defaultOrderBy)
133
- orderBy = Sort.translateOrderByToSort(entityMetadata, entityMetadata.options.defaultOrderBy);
134
131
  if (!orderBy)
135
132
  orderBy = new Sort();
136
133
  for (const field of entityMetadata.idMetadata.fields) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "remult",
3
- "version": "3.4.0-next.7",
3
+ "version": "3.4.0-next.9",
4
4
  "description": "A CRUD framework for full-stack TypeScript",
5
5
  "homepage": "https://remult.dev",
6
6
  "repository": {
@@ -124,9 +124,8 @@ export interface RawSelectOptions {
124
124
  }
125
125
  export declare function getRowAfterUpdate<entityType>(meta: EntityMetadata<entityType>, dataProvider: EntityDataProvider, data: any, id: any, operation: string): any;
126
126
  /** The select that `find` runs, and the mapping of one result row to field values. With `aliasColumns`, every column is aliased through `wrapIdentifier`, so a row can be read by alias as well as by position. */
127
- export declare function buildFindSql(entity: EntityMetadata, options: EntityDataProviderFindOptions | undefined, e: EntityDbNamesBase, r: SqlCommandWithParameters, orderByNullsFirst: boolean | undefined, limitSyntax: (limit: number, offset: number) => string, { aliasColumns, defaultOrderBy }?: {
127
+ export declare function buildFindSql(entity: EntityMetadata, options: EntityDataProviderFindOptions | undefined, e: EntityDbNamesBase, r: SqlCommandWithParameters, orderByNullsFirst: boolean | undefined, limitSyntax: (limit: number, offset: number) => string, { aliasColumns }?: {
128
128
  aliasColumns?: boolean | undefined;
129
- defaultOrderBy?: boolean | undefined;
130
129
  }): Promise<{
131
130
  select: string;
132
131
  colKeys: FieldMetadata<unknown, unknown>[];
@@ -315,7 +315,7 @@ var SqlDatabase = /** @class */ (function () {
315
315
  case 3:
316
316
  _c = (_h.sent());
317
317
  _h.label = 4;
318
- case 4: return [4 /*yield*/, _a.apply(void 0, _b.concat([_c, (_f = sql === null || sql === void 0 ? void 0 : sql.sqlCommand) !== null && _f !== void 0 ? _f : new myDummySQLCommand(), false, (_g = sql === null || sql === void 0 ? void 0 : sql.limitSyntax) !== null && _g !== void 0 ? _g : limitSyntaxRequired, { aliasColumns: true, defaultOrderBy: false }]))];
318
+ case 4: return [4 /*yield*/, _a.apply(void 0, _b.concat([_c, (_f = sql === null || sql === void 0 ? void 0 : sql.sqlCommand) !== null && _f !== void 0 ? _f : new myDummySQLCommand(), false, (_g = sql === null || sql === void 0 ? void 0 : sql.limitSyntax) !== null && _g !== void 0 ? _g : limitSyntaxRequired, { aliasColumns: true }]))];
319
319
  case 5:
320
320
  built = _h.sent();
321
321
  return [2 /*return*/, {
@@ -548,6 +548,8 @@ var ActualSQLEntityDataProvider = /** @class */ (function () {
548
548
  case 1:
549
549
  e = _b.sent();
550
550
  r = this.sql.createCommand();
551
+ if (options && !options.orderBy)
552
+ options.orderBy = sort_js_1.Sort.createUniqueSort(this.entity, new sort_js_1.Sort());
551
553
  return [4 /*yield*/, buildFindSql(this.entity, options, e, r, this.sql._getSourceSql().orderByNullsFirst, function (limit, offset) { return _this.strategy.getLimitSqlSyntax(limit, offset); })];
552
554
  case 2:
553
555
  _a = _b.sent(), select = _a.select, toResult = _a.toResult;
@@ -918,12 +920,12 @@ function buildFindSql(entity_1, options_1, e_8, r_1, orderByNullsFirst_1, limitS
918
920
  return tslib_1.__awaiter(this, arguments, void 0, function (entity, options, e, r, orderByNullsFirst, limitSyntax, _a) {
919
921
  var _b, colKeys, columns, select, where, _c, first, _d, _e, c, _f, _g, e_9_1, page;
920
922
  var e_9, _h;
921
- var _j = _a === void 0 ? {} : _a, _k = _j.aliasColumns, aliasColumns = _k === void 0 ? false : _k, _l = _j.defaultOrderBy, defaultOrderBy = _l === void 0 ? true : _l;
922
- return tslib_1.__generator(this, function (_m) {
923
- switch (_m.label) {
923
+ var _j = _a === void 0 ? {} : _a, _k = _j.aliasColumns, aliasColumns = _k === void 0 ? false : _k;
924
+ return tslib_1.__generator(this, function (_l) {
925
+ switch (_l.label) {
924
926
  case 0: return [4 /*yield*/, selectColumns(entity, e, r, options === null || options === void 0 ? void 0 : options.select, options === null || options === void 0 ? void 0 : options.args, aliasColumns)];
925
927
  case 1:
926
- _b = _m.sent(), colKeys = _b.colKeys, columns = _b.select;
928
+ _b = _l.sent(), colKeys = _b.colKeys, columns = _b.select;
927
929
  select = 'select ' + columns + '\n from ' + e.$entityName;
928
930
  if (!options) return [3 /*break*/, 14];
929
931
  if (!options.where) return [3 /*break*/, 3];
@@ -932,22 +934,19 @@ function buildFindSql(entity_1, options_1, e_8, r_1, orderByNullsFirst_1, limitS
932
934
  _c = select;
933
935
  return [4 /*yield*/, where.resolveWhere()];
934
936
  case 2:
935
- select = _c + _m.sent();
936
- _m.label = 3;
937
+ select = _c + _l.sent();
938
+ _l.label = 3;
937
939
  case 3:
938
940
  if (options.limit) {
939
941
  options.orderBy = sort_js_1.Sort.createUniqueSort(entity, options.orderBy);
940
942
  }
941
- if (!options.orderBy && defaultOrderBy) {
942
- options.orderBy = sort_js_1.Sort.createUniqueSort(entity, new sort_js_1.Sort());
943
- }
944
943
  if (!options.orderBy) return [3 /*break*/, 13];
945
944
  first = true;
946
- _m.label = 4;
945
+ _l.label = 4;
947
946
  case 4:
948
- _m.trys.push([4, 11, 12, 13]);
947
+ _l.trys.push([4, 11, 12, 13]);
949
948
  _d = tslib_1.__values(options.orderBy.Segments), _e = _d.next();
950
- _m.label = 5;
949
+ _l.label = 5;
951
950
  case 5:
952
951
  if (!!_e.done) return [3 /*break*/, 10];
953
952
  c = _e.value;
@@ -963,8 +962,8 @@ function buildFindSql(entity_1, options_1, e_8, r_1, orderByNullsFirst_1, limitS
963
962
  return [3 /*break*/, 8];
964
963
  case 6: return [4 /*yield*/, e.$dbNameOf(c.field)];
965
964
  case 7:
966
- _g = _m.sent();
967
- _m.label = 8;
965
+ _g = _l.sent();
966
+ _l.label = 8;
968
967
  case 8:
969
968
  select = _f + _g;
970
969
  if (c.isDescending)
@@ -975,13 +974,13 @@ function buildFindSql(entity_1, options_1, e_8, r_1, orderByNullsFirst_1, limitS
975
974
  else
976
975
  select += ' nulls first';
977
976
  }
978
- _m.label = 9;
977
+ _l.label = 9;
979
978
  case 9:
980
979
  _e = _d.next();
981
980
  return [3 /*break*/, 5];
982
981
  case 10: return [3 /*break*/, 13];
983
982
  case 11:
984
- e_9_1 = _m.sent();
983
+ e_9_1 = _l.sent();
985
984
  e_9 = { error: e_9_1 };
986
985
  return [3 /*break*/, 13];
987
986
  case 12:
@@ -999,7 +998,7 @@ function buildFindSql(entity_1, options_1, e_8, r_1, orderByNullsFirst_1, limitS
999
998
  page = 1;
1000
999
  select += ' ' + limitSyntax(options.limit, (page - 1) * options.limit);
1001
1000
  }
1002
- _m.label = 14;
1001
+ _l.label = 14;
1003
1002
  case 14: return [2 /*return*/, {
1004
1003
  select: select,
1005
1004
  colKeys: colKeys,
@@ -302,7 +302,7 @@ export declare function isAutoIncrement(f: FieldMetadata): boolean;
302
302
  export declare function ValueListFieldType<valueType extends ValueListItem = ValueListItem>(...options: (ValueListFieldOptions<any, valueType> | ((options: FieldOptions<any, valueType>, remult: Remult) => void))[]): (type: ClassType<valueType>, context?: any) => void;
303
303
  export interface ValueListFieldOptions<entityType, valueType> extends FieldOptions<entityType, valueType> {
304
304
  getValues?: () => valueType[];
305
- /** Value used when a stored id is not in the list. A value, or `(id) => value`. @default undefined */
305
+ /** Value used when a stored id is not in the list. A value, or `(id) => value`. Only `null` and `undefined` stay `undefined`; a blank `''` uses this, which is the usual legacy column. A declared id of `''` is unaffected. @default undefined */
306
306
  unknownIdValue?: valueType | ((id: any) => valueType | undefined);
307
307
  }
308
308
  export declare class ValueListInfo<T extends ValueListItem> implements ValueConverter<T> {
@@ -314,7 +314,8 @@ export declare class ValueListInfo<T extends ValueListItem> implements ValueConv
314
314
  private unknownIdValue?;
315
315
  private constructor();
316
316
  getValues(): T[];
317
- byId(key: any): T | undefined;
317
+ /** Declared id only. Pass `useUnknownIdValue` to also apply `unknownIdValue` (`null` and `undefined` still return `undefined`). */
318
+ byId(key: any, useUnknownIdValue?: boolean): T | undefined;
318
319
  fromJson(val: any): T;
319
320
  toJson(val: T): any;
320
321
  fromDb(val: any): T;
@@ -954,7 +954,7 @@ var RepositoryImplementation = /** @class */ (function () {
954
954
  };
955
955
  RepositoryImplementation.prototype._rawFind = function (options_1) {
956
956
  return tslib_1.__awaiter(this, arguments, void 0, function (options, skipOrderByAndLimit, loader, actualFind) {
957
- var opt, rawRows, result;
957
+ var findOptions, opt, rawRows, result;
958
958
  if (skipOrderByAndLimit === void 0) { skipOrderByAndLimit = false; }
959
959
  return tslib_1.__generator(this, function (_a) {
960
960
  switch (_a.label) {
@@ -964,7 +964,13 @@ var RepositoryImplementation = /** @class */ (function () {
964
964
  if (this._defaultFindOptions) {
965
965
  options = tslib_1.__assign(tslib_1.__assign({}, this._defaultFindOptions), options);
966
966
  }
967
- return [4 /*yield*/, this._buildEntityDataProviderFindOptions(options)];
967
+ findOptions = options;
968
+ if ((!findOptions.orderBy || Object.keys(findOptions.orderBy).length === 0) &&
969
+ !this._dataProvider.isProxy &&
970
+ this._info.entityInfo.defaultOrderBy) {
971
+ findOptions = tslib_1.__assign(tslib_1.__assign({}, findOptions), { orderBy: this._info.entityInfo.defaultOrderBy });
972
+ }
973
+ return [4 /*yield*/, this._buildEntityDataProviderFindOptions(findOptions)];
968
974
  case 1:
969
975
  opt = _a.sent();
970
976
  if (skipOrderByAndLimit) {
@@ -1029,10 +1035,6 @@ var RepositoryImplementation = /** @class */ (function () {
1029
1035
  return f.key;
1030
1036
  });
1031
1037
  }
1032
- if (!options.orderBy || Object.keys(options.orderBy).length === 0) {
1033
- if (!this._dataProvider.isProxy)
1034
- options.orderBy = this._info.entityInfo.defaultOrderBy;
1035
- }
1036
1038
  _a = opt;
1037
1039
  return [4 /*yield*/, this._translateWhereToFilter(options.where)];
1038
1040
  case 1:
@@ -4045,21 +4047,22 @@ var ValueListInfo = /** @class */ (function () {
4045
4047
  ValueListInfo.prototype.getValues = function () {
4046
4048
  return this.values;
4047
4049
  };
4048
- ValueListInfo.prototype.byId = function (key) {
4049
- if (this.isNumeric)
4050
- key = +key;
4051
- return this.byIdMap.get(key);
4052
- };
4053
- ValueListInfo.prototype.fromJson = function (val) {
4054
- var known = this.byId(val);
4055
- if (known !== undefined)
4050
+ /** Declared id only. Pass `useUnknownIdValue` to also apply `unknownIdValue` (`null` and `undefined` still return `undefined`). */
4051
+ ValueListInfo.prototype.byId = function (key, useUnknownIdValue) {
4052
+ if (useUnknownIdValue === void 0) { useUnknownIdValue = false; }
4053
+ var lookupKey = this.isNumeric ? +key : key;
4054
+ var known = this.byIdMap.get(lookupKey);
4055
+ if (known !== undefined || !useUnknownIdValue)
4056
4056
  return known;
4057
- if (val == null)
4057
+ if (key == null)
4058
4058
  return undefined;
4059
4059
  var fallback = this.unknownIdValue;
4060
4060
  if (typeof fallback !== 'function')
4061
4061
  return fallback;
4062
- return fallback(this.isNumeric ? +val : val);
4062
+ return fallback(lookupKey);
4063
+ };
4064
+ ValueListInfo.prototype.fromJson = function (val) {
4065
+ return this.byId(val, true);
4063
4066
  };
4064
4067
  ValueListInfo.prototype.toJson = function (val) {
4065
4068
  if (!val)
package/src/sort.js CHANGED
@@ -159,9 +159,6 @@ var Sort = /** @class */ (function () {
159
159
  */
160
160
  Sort.createUniqueSort = function (entityMetadata, orderBy) {
161
161
  var e_3, _a;
162
- if ((!orderBy || Object.keys(orderBy).length === 0) &&
163
- entityMetadata.options.defaultOrderBy)
164
- orderBy = Sort.translateOrderByToSort(entityMetadata, entityMetadata.options.defaultOrderBy);
165
162
  if (!orderBy)
166
163
  orderBy = new Sort();
167
164
  var _loop_2 = function (field) {