remult 0.26.3 → 0.26.5-exp.0

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.
@@ -155,10 +155,11 @@ export class PostgresSchemaBuilder {
155
155
  else {
156
156
  result += postgresColumnSyntax(x, e.$dbNameOf(x));
157
157
  }
158
- if (x == entity.idMetadata.field)
159
- result += ' primary key';
160
158
  }
161
159
  }
160
+ result += `,\r\n primary key (${entity.idMetadata.fields
161
+ .map((f) => e.$dbNameOf(f))
162
+ .join(',')})`;
162
163
  let sql = `CREATE SCHEMA IF NOT EXISTS ${this.schemaOnly(e)};
163
164
  CREATE table ${this.schemaAndName(e)} (${result}\r\n)`;
164
165
  return sql;
@@ -1,12 +1,10 @@
1
1
  import { CustomSqlFilterBuilder, } from '../src/filter/filter-consumer-bridge-to-sql-request.js';
2
2
  import { dbNamesOf, isDbReadonly, shouldCreateEntity, shouldNotCreateField, } from '../src/filter/filter-consumer-bridge-to-sql-request.js';
3
3
  import { customDatabaseFilterToken, Filter, } from '../src/filter/filter-interfaces.js';
4
- import { CompoundIdField } from '../src/CompoundIdField.js';
5
4
  import { remult as remultContext } from '../src/remult-proxy.js';
6
5
  import { getRepository, isAutoIncrement, } from '../src/remult3/RepositoryImplementation.js';
7
6
  import { Sort } from '../src/sort.js';
8
7
  import { ValueConverters } from '../src/valueConverters.js';
9
- import { resultCompoundIdFilter as resultCompoundIdFilter } from '../src/resultCompoundIdFilter.js';
10
8
  import { getRepositoryInternals } from '../src/remult3/repository-internals.js';
11
9
  import { remultStatic } from '../src/remult-static.js';
12
10
  export class KnexDataProvider {
@@ -233,10 +231,7 @@ class KnexEntityDataProvider {
233
231
  async insert(data) {
234
232
  const e = await this.init();
235
233
  let resultFilter;
236
- if (this.entity.idMetadata.field instanceof CompoundIdField)
237
- resultFilter = resultCompoundIdFilter(this.entity.idMetadata.field, undefined, data);
238
- else
239
- resultFilter = Filter.fromEntityFilter(this.entity, this.entity.idMetadata.getIdFilter(data[this.entity.idMetadata.field.key]));
234
+ resultFilter = Filter.fromEntityFilter(this.entity, this.entity.idMetadata.getIdFilter(data[this.entity.idMetadata.field.key]));
240
235
  let insertObject = {};
241
236
  for (const x of this.entity.fields) {
242
237
  if (isDbReadonly(x, e)) {
@@ -426,11 +421,10 @@ export class KnexSchemaBuilder {
426
421
  b.increments(cols.get(x).name);
427
422
  else {
428
423
  buildColumn(x, cols.get(x).name, b, supportsJsonDataStorage(this.knex));
429
- if (x == entity.idMetadata.field)
430
- b.primary([cols.get(x).name]);
431
424
  }
432
425
  }
433
426
  }
427
+ b.primary(entity.idMetadata.fields.map((f) => e.$dbNameOf(f)));
434
428
  });
435
429
  }
436
430
  async addColumnIfNotExist(entity, c) {
@@ -1,9 +1,8 @@
1
1
  import { ObjectId, } from 'mongodb';
2
- import { CompoundIdField, Filter } from './index.js';
2
+ import { Filter } from './index.js';
3
3
  import { dbNamesOf } from './src/filter/filter-consumer-bridge-to-sql-request.js';
4
4
  import { remult as remultContext } from './src/remult-proxy.js';
5
5
  import { getRepository } from './src/remult3/RepositoryImplementation.js';
6
- import { resultCompoundIdFilter } from './src/resultCompoundIdFilter.js';
7
6
  import { getRepositoryInternals } from './src/remult3/repository-internals.js';
8
7
  export class MongoDataProvider {
9
8
  db;
@@ -130,11 +129,6 @@ class MongoEntityDataProvider {
130
129
  let resultFilter = this.entity.idMetadata.getIdFilter(id);
131
130
  if (data.id != undefined)
132
131
  resultFilter = this.entity.idMetadata.getIdFilter(data.id);
133
- for (const x of this.entity.fields) {
134
- if (x instanceof CompoundIdField) {
135
- resultFilter = resultCompoundIdFilter(x, id, data);
136
- }
137
- }
138
132
  let newR = {};
139
133
  let keys = Object.keys(data);
140
134
  for (const f of this.entity.fields) {
@@ -84,7 +84,7 @@ export class SqliteCoreDataProvider {
84
84
  result += '\r\n ';
85
85
  if (isAutoIncrement(x)) {
86
86
  if (x.key != entity.idMetadata.field.key)
87
- throw 'in web sql, autoincrement is only allowed for primary key';
87
+ throw 'in sqlite, autoincrement is only allowed for primary key';
88
88
  result += e.$dbNameOf(x) + ' integer primary key autoincrement';
89
89
  }
90
90
  else {
@@ -1,4 +1,3 @@
1
- import { CompoundIdField } from '../src/CompoundIdField.js';
2
1
  import { getRelationFieldInfo, } from '../src/remult3/relationInfoMember.js';
3
2
  import { Filter } from '../src/filter/filter-interfaces.js';
4
3
  import { getHtml } from './get-remult-admin-html.js';
@@ -17,13 +16,9 @@ export function buildEntityInfo(options) {
17
16
  let fields = [];
18
17
  let relations = [];
19
18
  let ids = {};
20
- if (metadata.idMetadata.field instanceof CompoundIdField) {
21
- for (const field of metadata.idMetadata.field.fields) {
22
- ids[field.key] = true;
23
- }
19
+ for (const f of metadata.idMetadata.fields) {
20
+ ids[f.key] = true;
24
21
  }
25
- else
26
- ids[metadata.idMetadata.field.key] = true;
27
22
  for (const x of metadata.fields.toArray()) {
28
23
  if (!x.includedInApi(undefined))
29
24
  continue;
@@ -1,4 +1,3 @@
1
- import { CompoundIdField } from '../CompoundIdField.js';
2
1
  import { FilterConsumerBridgeToSqlRequest, dbNamesOf, isDbReadonly, } from '../filter/filter-consumer-bridge-to-sql-request.js';
3
2
  import { Filter, customDatabaseFilterToken, } from '../filter/filter-interfaces.js';
4
3
  import { remult as defaultRemult } from '../remult-proxy.js';
@@ -256,14 +255,7 @@ class ActualSQLServerDataProvider {
256
255
  let first = true;
257
256
  let segs = [];
258
257
  for (const s of options.orderBy.Segments) {
259
- if (s.field instanceof CompoundIdField) {
260
- segs.push(...s.field.fields.map((c) => ({
261
- field: c,
262
- isDescending: s.isDescending,
263
- })));
264
- }
265
- else
266
- segs.push(s);
258
+ segs.push(s);
267
259
  }
268
260
  for (const c of segs) {
269
261
  if (first) {
@@ -336,8 +328,6 @@ class ActualSQLServerDataProvider {
336
328
  let statement = 'update ' + e.$entityName + ' set ';
337
329
  let added = false;
338
330
  for (const x of this.entity.fields) {
339
- if (x instanceof CompoundIdField) {
340
- }
341
331
  if (isDbReadonly(x, e)) {
342
332
  }
343
333
  else if (data[x.key] !== undefined) {
@@ -229,7 +229,15 @@ export async function entityDbName(metadata, wrapIdentifier = (x) => x) {
229
229
  if (typeof metadata.options.sqlExpression === 'string')
230
230
  return metadata.options.sqlExpression;
231
231
  else if (typeof metadata.options.sqlExpression === 'function') {
232
- return await metadata.options.sqlExpression(metadata);
232
+ const prev = metadata.options.sqlExpression;
233
+ try {
234
+ metadata.options.sqlExpression =
235
+ "recursive sqlExpression call for entity '" + metadata.key + "'. ";
236
+ return await prev(metadata);
237
+ }
238
+ finally {
239
+ metadata.options.sqlExpression = prev;
240
+ }
233
241
  }
234
242
  }
235
243
  return wrapIdentifier(metadata.dbName);
@@ -1,8 +1,8 @@
1
1
  import { createId } from '@paralleldrive/cuid2';
2
2
  import { v4 as uuid } from 'uuid';
3
3
  import { ValueConverters } from '../valueConverters.js';
4
- import { buildOptions } from './RepositoryImplementation.js';
5
- import { Validators, createValueValidator, getEnumValues } from '../validators.js';
4
+ import { buildOptions, fieldOptionalValuesFunctionKey, } from './RepositoryImplementation.js';
5
+ import { Validators, createValueValidator, getEnumValues, } from '../validators.js';
6
6
  import { relationInfoMemberInOptions } from './relationInfoMember.js';
7
7
  import { remultStatic } from '../remult-static.js';
8
8
  import { addValidator } from './addValidator.js';
@@ -84,10 +84,10 @@ export class Fields {
84
84
  }, ...options);
85
85
  }
86
86
  /**
87
- * A CUID (Collision Resistant Unique Identifier) field.
88
- * This id value is determined on the backend on insert, and can't be updated through the API.
89
- * The CUID is generated using the `@paralleldrive/cuid2` npm package.
90
- */
87
+ * A CUID (Collision Resistant Unique Identifier) field.
88
+ * This id value is determined on the backend on insert, and can't be updated through the API.
89
+ * The CUID is generated using the `@paralleldrive/cuid2` npm package.
90
+ */
91
91
  static cuid(...options) {
92
92
  return Field(() => String, {
93
93
  allowApiUpdate: false,
@@ -129,7 +129,9 @@ export class Fields {
129
129
  */
130
130
  static literal(optionalValues, ...options) {
131
131
  return Fields.string({
132
- validate: (entity, event) => Validators.in(optionalValues())(entity, event)
132
+ validate: (entity, event) => Validators.in(optionalValues())(entity, event),
133
+ //@ts-expect-error as we are adding this to options without it being defined in options
134
+ [fieldOptionalValuesFunctionKey]: optionalValues,
133
135
  }, ...options);
134
136
  }
135
137
  static enum(enumType, ...options) {
@@ -137,12 +139,16 @@ export class Fields {
137
139
  return Field(() =>
138
140
  //@ts-ignore
139
141
  enumType(), {
140
- validate: (entity, event) => Validators.enum(enumType())(entity, event)
142
+ validate: (entity, event) => Validators.enum(enumType())(entity, event),
143
+ [fieldOptionalValuesFunctionKey]: () => getEnumValues(enumType()),
141
144
  }, ...options, (options) => {
145
+ options[fieldOptionalValuesFunctionKey] = () => getEnumValues(enumType());
142
146
  if (valueConverter === undefined) {
143
147
  let enumObj = enumType();
144
148
  let enumValues = getEnumValues(enumObj);
145
- valueConverter = enumValues.find(x => typeof x === "string") ? ValueConverters.String : ValueConverters.Integer;
149
+ valueConverter = enumValues.find((x) => typeof x === 'string')
150
+ ? ValueConverters.String
151
+ : ValueConverters.Integer;
146
152
  }
147
153
  if (!options.valueConverter) {
148
154
  options.valueConverter = valueConverter;
@@ -16,6 +16,7 @@ import { entityDbName, fieldDbName, } from '../filter/filter-consumer-bridge-to-
16
16
  import { remultStatic } from '../remult-static.js';
17
17
  import { Validators } from '../validators.js';
18
18
  import { addValidator } from './addValidator.js';
19
+ import { isOfType } from '../isOfType.js';
19
20
  //import { remult } from "../remult-proxy";
20
21
  let classValidatorValidate = undefined;
21
22
  // import ("class-validator".toString())
@@ -271,7 +272,7 @@ export class RepositoryImplementation {
271
272
  }
272
273
  }
273
274
  }
274
- async updateMany({ where }, set) {
275
+ async updateMany({ where, set, }) {
275
276
  Filter.throwErrorIfFilterIsEmpty(where, 'updateMany');
276
277
  if (this._dataProvider.isProxy) {
277
278
  return this._edp.updateMany(await this._translateWhereToFilter(where), set);
@@ -1927,6 +1928,11 @@ class EntityFullInfo {
1927
1928
  return item[this.idMetadata.field.key];
1928
1929
  },
1929
1930
  field: undefined,
1931
+ get fields() {
1932
+ return this.field instanceof CompoundIdField
1933
+ ? this.field.fields
1934
+ : [this.field];
1935
+ },
1930
1936
  createIdInFilter: (items) => {
1931
1937
  if (items.length > 0)
1932
1938
  return {
@@ -2079,19 +2085,22 @@ export class ValueListInfo {
2079
2085
  }
2080
2086
  const typeCache = new Map();
2081
2087
  export function getValueList(type) {
2082
- {
2083
- const fr = type?.metadata?.valueType;
2084
- if (fr)
2085
- return ValueListInfo.get(fr).getValues();
2086
- }
2087
- {
2088
- const fr = type?.valueType;
2089
- if (fr)
2090
- return ValueListInfo.get(fr).getValues();
2091
- }
2092
- return ValueListInfo.get(type).getValues();
2088
+ let meta = type?.metadata;
2089
+ if (!meta && isOfType(type, 'options'))
2090
+ meta = type;
2091
+ type = meta?.valueType || type;
2092
+ if (type) {
2093
+ var options = type[storableMember];
2094
+ if (options)
2095
+ return ValueListInfo.get(type).getValues();
2096
+ }
2097
+ let optionalValues = meta?.options[fieldOptionalValuesFunctionKey];
2098
+ if (optionalValues)
2099
+ return optionalValues();
2100
+ return undefined;
2093
2101
  }
2094
2102
  export const storableMember = Symbol.for('storableMember');
2103
+ export const fieldOptionalValuesFunctionKey = Symbol.for('fieldOptionalValues');
2095
2104
  export function buildOptions(options, remult) {
2096
2105
  let r = {};
2097
2106
  for (const o of options) {
@@ -1,22 +1,31 @@
1
1
  export {};
2
2
  //y1 - https://discord.com/channels/975754286384418847/1230386433093533698/1230386433093533698
3
3
  //y1 - fix async hooks - was it fixed?
4
+ //y1 - repo batch - for multiple operations:
5
+ /*
6
+ const result = await repo.batch(x=>({
7
+ data:x.find(),
8
+ count:x.count()
9
+ }))
10
+ */
11
+ //p1 - adjust react tutorial to esm
12
+ //p1 - add solid tutorial to the getting started page
13
+ //p1 - update the examples section
14
+ //p1 - add documentation for bun sqlite
4
15
  //p1 - consider upsert (where,set)
5
- //p1 - consider id to also support keyof (id:['company','index'])
6
16
  //p1 - wait a second to close stream
7
- //p1 - reconsider update many, maybe the second parameter should be in a set option - break existing
8
- //p1 - add documentation for bun sqlite
17
+ //y1 - consider id to also support keyof (id:['company','index']) - had problem with | (keyof Partial<entityType>)[] & `entity`
9
18
  //p1 - describe entity
10
19
  //p1 - prepare the createEntity discussion
11
20
  //p1 - write active record article
12
- //p1 - maybe add decorator comment in the readme as well (I heard you've lost me in decorators) - and improve the describeClass function
13
21
  //p1 - return error on connection error
14
22
  //p1 - consider including the admin in the tutorial - and maybe even in the demo when we setup the api
23
+ //p1 - reconsider key typing to be keyof & string
15
24
  //p2 -fix remult admin not to load the html into memory until used
16
25
  //y2 - JY suggestion of having generate as part of the ensure schema - not sure
17
26
  //y2 - currently for string fields we default for 255 in knex (which is their default) why not just use text (varchar max) - and only use exact length when one is provided?
18
27
  //p2 - create foreign key constraints in user code - https://codesandbox.io/p/devbox/fk-validator-tdshcs
19
- //p1 - admin url1 - pocketbase use /_ for the admin //{allowed?:Allowed,url?:string} also checkout the admin* as it should probably be something else and didn't work in hono
28
+ //p2 - admin url1 - pocketbase use /_ for the admin //{allowed?:Allowed,url?:string} also checkout the admin* as it should probably be something else and didn't work in hono
20
29
  //p1 - article auth.js with express - played with it, requires type="module" and a few more configurations - https://github.com/noam-honig/express-auth
21
30
  //y2 - fix validators cache
22
31
  //y2 - should we validate relations
@@ -88,4 +97,3 @@ export {};
88
97
  //y2 - add some api testing framework for user unit tests (will help with codesandbox based discussions)
89
98
  //[ ] V2 - what to do about for relations count?
90
99
  //[ ] V2 - condition? not to fetch if null etc....
91
- //p1 - adjust react tutorial to esm
@@ -26,10 +26,15 @@ export class Validators {
26
26
  static regex = createValueValidatorWithArgs((val, regex) => regex.test(val));
27
27
  static email = createValueValidator((val) => /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(val), 'Invalid Email');
28
28
  static url = createValueValidator((val) => !!new URL(val), 'Invalid Url');
29
- static in = createValueValidatorWithArgs((val, values) => values.includes(val), (values) => `Value must be one of ${values.map(y => typeof y === "object" ? y['id'] !== undefined ? y['id'] : y.toString() : y).join(', ')}`);
30
- static notNull = createValueValidator((val) => val != null, 'Should not be null');
31
- static enum = createValueValidatorWithArgs((value, enumObj) => Object.values(enumObj).includes(value), (enumObj) => `Value must be one of ${getEnumValues(enumObj)
29
+ static in = createValueValidatorWithArgs((val, values) => values.includes(val), (values) => `Value must be one of: ${values
30
+ .map((y) => typeof y === 'object'
31
+ ? y['id'] !== undefined
32
+ ? y['id']
33
+ : y.toString()
34
+ : y)
32
35
  .join(', ')}`);
36
+ static notNull = createValueValidator((val) => val != null, 'Should not be null');
37
+ static enum = createValueValidatorWithArgs((value, enumObj) => Object.values(enumObj).includes(value), (enumObj) => `Value must be one of ${getEnumValues(enumObj).join(', ')}`);
33
38
  static relationExists = createValidator(async (_, e) => {
34
39
  if (e.valueIsNull())
35
40
  return true;
@@ -134,6 +139,5 @@ function createValidatorWithArgsInternal(validate, defaultMessage, isValueValida
134
139
  });
135
140
  }
136
141
  export function getEnumValues(enumObj) {
137
- return Object.values(enumObj)
138
- .filter((x) => typeof enumObj[x] !== 'number');
142
+ return Object.values(enumObj).filter((x) => typeof enumObj[x] !== 'number');
139
143
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "remult",
3
- "version": "0.26.3",
3
+ "version": "0.26.5-exp.0",
4
4
  "description": "A CRUD framework for full-stack TypeScript",
5
5
  "homepage": "https://remult.dev",
6
6
  "repository": {
@@ -287,8 +287,6 @@ var PostgresSchemaBuilder = /** @class */ (function () {
287
287
  else {
288
288
  result += postgresColumnSyntax(x, e.$dbNameOf(x));
289
289
  }
290
- if (x == entity.idMetadata.field)
291
- result += ' primary key';
292
290
  }
293
291
  }
294
292
  }
@@ -299,6 +297,9 @@ var PostgresSchemaBuilder = /** @class */ (function () {
299
297
  }
300
298
  finally { if (e_3) throw e_3.error; }
301
299
  }
300
+ result += ",\r\n primary key (".concat(entity.idMetadata.fields
301
+ .map(function (f) { return e.$dbNameOf(f); })
302
+ .join(','), ")");
302
303
  sql = "CREATE SCHEMA IF NOT EXISTS ".concat(this.schemaOnly(e), ";\nCREATE table ").concat(this.schemaAndName(e), " (").concat(result, "\r\n)");
303
304
  return [2 /*return*/, sql];
304
305
  }
@@ -5,12 +5,10 @@ var tslib_1 = require("tslib");
5
5
  var filter_consumer_bridge_to_sql_request_js_1 = require("../src/filter/filter-consumer-bridge-to-sql-request.js");
6
6
  var filter_consumer_bridge_to_sql_request_js_2 = require("../src/filter/filter-consumer-bridge-to-sql-request.js");
7
7
  var filter_interfaces_js_1 = require("../src/filter/filter-interfaces.js");
8
- var CompoundIdField_js_1 = require("../src/CompoundIdField.js");
9
8
  var remult_proxy_js_1 = require("../src/remult-proxy.js");
10
9
  var RepositoryImplementation_js_1 = require("../src/remult3/RepositoryImplementation.js");
11
10
  var sort_js_1 = require("../src/sort.js");
12
11
  var valueConverters_js_1 = require("../src/valueConverters.js");
13
- var resultCompoundIdFilter_js_1 = require("../src/resultCompoundIdFilter.js");
14
12
  var repository_internals_js_1 = require("../src/remult3/repository-internals.js");
15
13
  var remult_static_js_1 = require("../src/remult-static.js");
16
14
  var KnexDataProvider = /** @class */ (function () {
@@ -422,10 +420,7 @@ var KnexEntityDataProvider = /** @class */ (function () {
422
420
  case 0: return [4 /*yield*/, this.init()];
423
421
  case 1:
424
422
  e = _d.sent();
425
- if (this.entity.idMetadata.field instanceof CompoundIdField_js_1.CompoundIdField)
426
- resultFilter = (0, resultCompoundIdFilter_js_1.resultCompoundIdFilter)(this.entity.idMetadata.field, undefined, data);
427
- else
428
- resultFilter = filter_interfaces_js_1.Filter.fromEntityFilter(this.entity, this.entity.idMetadata.getIdFilter(data[this.entity.idMetadata.field.key]));
423
+ resultFilter = filter_interfaces_js_1.Filter.fromEntityFilter(this.entity, this.entity.idMetadata.getIdFilter(data[this.entity.idMetadata.field.key]));
429
424
  insertObject = {};
430
425
  _d.label = 2;
431
426
  case 2:
@@ -838,8 +833,6 @@ var KnexSchemaBuilder = /** @class */ (function () {
838
833
  b.increments(cols.get(x).name);
839
834
  else {
840
835
  buildColumn(x, cols.get(x).name, b, supportsJsonDataStorage(_this.knex));
841
- if (x == entity.idMetadata.field)
842
- b.primary([cols.get(x).name]);
843
836
  }
844
837
  }
845
838
  }
@@ -851,6 +844,7 @@ var KnexSchemaBuilder = /** @class */ (function () {
851
844
  }
852
845
  finally { if (e_10) throw e_10.error; }
853
846
  }
847
+ b.primary(entity.idMetadata.fields.map(function (f) { return e.$dbNameOf(f); }));
854
848
  });
855
849
  };
856
850
  KnexSchemaBuilder.prototype.addColumnIfNotExist = function (entity, c) {
package/remult-mongo.js CHANGED
@@ -7,7 +7,6 @@ var index_js_1 = require("./index.js");
7
7
  var filter_consumer_bridge_to_sql_request_js_1 = require("./src/filter/filter-consumer-bridge-to-sql-request.js");
8
8
  var remult_proxy_js_1 = require("./src/remult-proxy.js");
9
9
  var RepositoryImplementation_js_1 = require("./src/remult3/RepositoryImplementation.js");
10
- var resultCompoundIdFilter_js_1 = require("./src/resultCompoundIdFilter.js");
11
10
  var repository_internals_js_1 = require("./src/remult3/repository-internals.js");
12
11
  var MongoDataProvider = /** @class */ (function () {
13
12
  function MongoDataProvider(db, client, options) {
@@ -222,38 +221,23 @@ var MongoEntityDataProvider = /** @class */ (function () {
222
221
  };
223
222
  MongoEntityDataProvider.prototype.update = function (id, data) {
224
223
  return tslib_1.__awaiter(this, void 0, void 0, function () {
225
- var _a, collection, e, f, resultFilter, _b, _c, x, newR, keys, _d, _e, f_1, r, _f, _g;
226
- var e_4, _h, e_5, _j;
227
- return tslib_1.__generator(this, function (_k) {
228
- switch (_k.label) {
224
+ var _a, collection, e, f, resultFilter, newR, keys, _b, _c, f_1, r, _d, _e;
225
+ var e_4, _f;
226
+ return tslib_1.__generator(this, function (_g) {
227
+ switch (_g.label) {
229
228
  case 0: return [4 /*yield*/, this.collection()];
230
229
  case 1:
231
- _a = _k.sent(), collection = _a.collection, e = _a.e;
230
+ _a = _g.sent(), collection = _a.collection, e = _a.e;
232
231
  f = new FilterConsumerBridgeToMongo(e);
233
232
  index_js_1.Filter.fromEntityFilter(this.entity, this.entity.idMetadata.getIdFilter(id)).__applyToConsumer(f);
234
233
  resultFilter = this.entity.idMetadata.getIdFilter(id);
235
234
  if (data.id != undefined)
236
235
  resultFilter = this.entity.idMetadata.getIdFilter(data.id);
237
- try {
238
- for (_b = tslib_1.__values(this.entity.fields), _c = _b.next(); !_c.done; _c = _b.next()) {
239
- x = _c.value;
240
- if (x instanceof index_js_1.CompoundIdField) {
241
- resultFilter = (0, resultCompoundIdFilter_js_1.resultCompoundIdFilter)(x, id, data);
242
- }
243
- }
244
- }
245
- catch (e_4_1) { e_4 = { error: e_4_1 }; }
246
- finally {
247
- try {
248
- if (_c && !_c.done && (_h = _b.return)) _h.call(_b);
249
- }
250
- finally { if (e_4) throw e_4.error; }
251
- }
252
236
  newR = {};
253
237
  keys = Object.keys(data);
254
238
  try {
255
- for (_d = tslib_1.__values(this.entity.fields), _e = _d.next(); !_e.done; _e = _d.next()) {
256
- f_1 = _e.value;
239
+ for (_b = tslib_1.__values(this.entity.fields), _c = _b.next(); !_c.done; _c = _b.next()) {
240
+ f_1 = _c.value;
257
241
  if (!f_1.dbReadOnly && !f_1.isServerExpression) {
258
242
  if (keys.includes(f_1.key)) {
259
243
  newR[f_1.key] = toDb(f_1, data[f_1.key]);
@@ -261,21 +245,21 @@ var MongoEntityDataProvider = /** @class */ (function () {
261
245
  }
262
246
  }
263
247
  }
264
- catch (e_5_1) { e_5 = { error: e_5_1 }; }
248
+ catch (e_4_1) { e_4 = { error: e_4_1 }; }
265
249
  finally {
266
250
  try {
267
- if (_e && !_e.done && (_j = _d.return)) _j.call(_d);
251
+ if (_c && !_c.done && (_f = _b.return)) _f.call(_b);
268
252
  }
269
- finally { if (e_5) throw e_5.error; }
253
+ finally { if (e_4) throw e_4.error; }
270
254
  }
271
- _g = (_f = collection).updateOne;
255
+ _e = (_d = collection).updateOne;
272
256
  return [4 /*yield*/, f.resolveWhere()];
273
- case 2: return [4 /*yield*/, _g.apply(_f, [_k.sent(), {
257
+ case 2: return [4 /*yield*/, _e.apply(_d, [_g.sent(), {
274
258
  $set: newR,
275
259
  },
276
260
  { session: this.session }])];
277
261
  case 3:
278
- r = _k.sent();
262
+ r = _g.sent();
279
263
  return [2 /*return*/, this.find({
280
264
  where: index_js_1.Filter.fromEntityFilter(this.entity, resultFilter),
281
265
  }).then(function (y) { return y[0]; })];
@@ -350,8 +334,8 @@ var FilterConsumerBridgeToMongo = /** @class */ (function () {
350
334
  }
351
335
  FilterConsumerBridgeToMongo.prototype.resolveWhere = function () {
352
336
  return tslib_1.__awaiter(this, void 0, void 0, function () {
353
- var p, p_1, p_1_1, pr, e_6_1;
354
- var e_6, _a;
337
+ var p, p_1, p_1_1, pr, e_5_1;
338
+ var e_5, _a;
355
339
  return tslib_1.__generator(this, function (_b) {
356
340
  switch (_b.label) {
357
341
  case 0:
@@ -361,7 +345,7 @@ var FilterConsumerBridgeToMongo = /** @class */ (function () {
361
345
  _b.label = 1;
362
346
  case 1:
363
347
  _b.trys.push([1, 6, 7, 8]);
364
- p_1 = (e_6 = void 0, tslib_1.__values(p)), p_1_1 = p_1.next();
348
+ p_1 = (e_5 = void 0, tslib_1.__values(p)), p_1_1 = p_1.next();
365
349
  _b.label = 2;
366
350
  case 2:
367
351
  if (!!p_1_1.done) return [3 /*break*/, 5];
@@ -375,14 +359,14 @@ var FilterConsumerBridgeToMongo = /** @class */ (function () {
375
359
  return [3 /*break*/, 2];
376
360
  case 5: return [3 /*break*/, 8];
377
361
  case 6:
378
- e_6_1 = _b.sent();
379
- e_6 = { error: e_6_1 };
362
+ e_5_1 = _b.sent();
363
+ e_5 = { error: e_5_1 };
380
364
  return [3 /*break*/, 8];
381
365
  case 7:
382
366
  try {
383
367
  if (p_1_1 && !p_1_1.done && (_a = p_1.return)) _a.call(p_1);
384
368
  }
385
- finally { if (e_6) throw e_6.error; }
369
+ finally { if (e_5) throw e_5.error; }
386
370
  return [7 /*endfinally*/];
387
371
  case 8: return [3 /*break*/, 0];
388
372
  case 9:
@@ -401,8 +385,8 @@ var FilterConsumerBridgeToMongo = /** @class */ (function () {
401
385
  FilterConsumerBridgeToMongo.prototype.or = function (orElements) {
402
386
  var _this = this;
403
387
  this.promises.push((function () { return tslib_1.__awaiter(_this, void 0, void 0, function () {
404
- var result, orElements_1, orElements_1_1, element, f, where, e_7_1;
405
- var e_7, _a;
388
+ var result, orElements_1, orElements_1_1, element, f, where, e_6_1;
389
+ var e_6, _a;
406
390
  var _b;
407
391
  return tslib_1.__generator(this, function (_c) {
408
392
  switch (_c.label) {
@@ -433,14 +417,14 @@ var FilterConsumerBridgeToMongo = /** @class */ (function () {
433
417
  return [3 /*break*/, 2];
434
418
  case 5: return [3 /*break*/, 8];
435
419
  case 6:
436
- e_7_1 = _c.sent();
437
- e_7 = { error: e_7_1 };
420
+ e_6_1 = _c.sent();
421
+ e_6 = { error: e_6_1 };
438
422
  return [3 /*break*/, 8];
439
423
  case 7:
440
424
  try {
441
425
  if (orElements_1_1 && !orElements_1_1.done && (_a = orElements_1.return)) _a.call(orElements_1);
442
426
  }
443
- finally { if (e_7) throw e_7.error; }
427
+ finally { if (e_6) throw e_6.error; }
444
428
  return [7 /*endfinally*/];
445
429
  case 8:
446
430
  this.result.push(function () { return ({
@@ -184,7 +184,7 @@ var SqliteCoreDataProvider = /** @class */ (function () {
184
184
  result += '\r\n ';
185
185
  if ((0, RepositoryImplementation_js_1.isAutoIncrement)(x)) {
186
186
  if (x.key != entity.idMetadata.field.key)
187
- throw 'in web sql, autoincrement is only allowed for primary key';
187
+ throw 'in sqlite, autoincrement is only allowed for primary key';
188
188
  result += e.$dbNameOf(x) + ' integer primary key autoincrement';
189
189
  }
190
190
  else {
@@ -50,7 +50,10 @@ export interface RemultServerOptions<RequestType> {
50
50
  /** When set to true, will display an admin ui in the `/api/admin` url.
51
51
  * Can also be set to an arrow function for fine grained control
52
52
  * @example
53
- * allowed: ()=> remult.isAllowed('admin')
53
+ * admin: true
54
+ * @example
55
+ * admin: ()=> remult.isAllowed('admin')
56
+ * @see [allowed](http://remult.dev/docs/allowed.html)
54
57
  */
55
58
  admin?: Allowed;
56
59
  /** Storage to use for backend methods that use queue */
@@ -2,7 +2,6 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.buildEntityInfo = void 0;
4
4
  var tslib_1 = require("tslib");
5
- var CompoundIdField_js_1 = require("../src/CompoundIdField.js");
6
5
  var relationInfoMember_js_1 = require("../src/remult3/relationInfoMember.js");
7
6
  var filter_interfaces_js_1 = require("../src/filter/filter-interfaces.js");
8
7
  var get_remult_admin_html_js_1 = require("./get-remult-admin-html.js");
@@ -24,23 +23,19 @@ function buildEntityInfo(options) {
24
23
  var fields = [];
25
24
  var relations = [];
26
25
  var ids = {};
27
- if (metadata.idMetadata.field instanceof CompoundIdField_js_1.CompoundIdField) {
28
- try {
29
- for (var _g = (e_2 = void 0, tslib_1.__values(metadata.idMetadata.field.fields)), _h = _g.next(); !_h.done; _h = _g.next()) {
30
- var field = _h.value;
31
- ids[field.key] = true;
32
- }
26
+ try {
27
+ for (var _g = (e_2 = void 0, tslib_1.__values(metadata.idMetadata.fields)), _h = _g.next(); !_h.done; _h = _g.next()) {
28
+ var f = _h.value;
29
+ ids[f.key] = true;
33
30
  }
34
- catch (e_2_1) { e_2 = { error: e_2_1 }; }
35
- finally {
36
- try {
37
- if (_h && !_h.done && (_b = _g.return)) _b.call(_g);
38
- }
39
- finally { if (e_2) throw e_2.error; }
31
+ }
32
+ catch (e_2_1) { e_2 = { error: e_2_1 }; }
33
+ finally {
34
+ try {
35
+ if (_h && !_h.done && (_b = _g.return)) _b.call(_g);
40
36
  }
37
+ finally { if (e_2) throw e_2.error; }
41
38
  }
42
- else
43
- ids[metadata.idMetadata.field.key] = true;
44
39
  var _loop_1 = function (x) {
45
40
  if (!x.includedInApi(undefined))
46
41
  return "continue";
@@ -2,7 +2,6 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.SqlDatabase = void 0;
4
4
  var tslib_1 = require("tslib");
5
- var CompoundIdField_js_1 = require("../CompoundIdField.js");
6
5
  var filter_consumer_bridge_to_sql_request_js_1 = require("../filter/filter-consumer-bridge-to-sql-request.js");
7
6
  var filter_interfaces_js_1 = require("../filter/filter-interfaces.js");
8
7
  var remult_proxy_js_1 = require("../remult-proxy.js");
@@ -343,7 +342,7 @@ var ActualSQLServerDataProvider = /** @class */ (function () {
343
342
  };
344
343
  ActualSQLServerDataProvider.prototype.find = function (options) {
345
344
  return tslib_1.__awaiter(this, void 0, void 0, function () {
346
- var e, _a, colKeys, select, r, where, _b, first, segs, _loop_1, _c, _d, s, segs_1, segs_1_1, c, page;
345
+ var e, _a, colKeys, select, r, where, _b, first, segs, _c, _d, s, segs_1, segs_1_1, c, page;
347
346
  var e_2, _e, e_3, _f;
348
347
  var _this = this;
349
348
  return tslib_1.__generator(this, function (_g) {
@@ -374,20 +373,10 @@ var ActualSQLServerDataProvider = /** @class */ (function () {
374
373
  if (options.orderBy) {
375
374
  first = true;
376
375
  segs = [];
377
- _loop_1 = function (s) {
378
- if (s.field instanceof CompoundIdField_js_1.CompoundIdField) {
379
- segs.push.apply(segs, tslib_1.__spreadArray([], tslib_1.__read(s.field.fields.map(function (c) { return ({
380
- field: c,
381
- isDescending: s.isDescending,
382
- }); })), false));
383
- }
384
- else
385
- segs.push(s);
386
- };
387
376
  try {
388
377
  for (_c = tslib_1.__values(options.orderBy.Segments), _d = _c.next(); !_d.done; _d = _c.next()) {
389
378
  s = _d.value;
390
- _loop_1(s);
379
+ segs.push(s);
391
380
  }
392
381
  }
393
382
  catch (e_2_1) { e_2 = { error: e_2_1 }; }
@@ -502,8 +491,6 @@ var ActualSQLServerDataProvider = /** @class */ (function () {
502
491
  try {
503
492
  for (_a = tslib_1.__values(this.entity.fields), _b = _a.next(); !_b.done; _b = _a.next()) {
504
493
  x = _b.value;
505
- if (x instanceof CompoundIdField_js_1.CompoundIdField) {
506
- }
507
494
  if ((0, filter_consumer_bridge_to_sql_request_js_1.isDbReadonly)(x, e)) {
508
495
  }
509
496
  else if (data[x.key] !== undefined) {
@@ -652,14 +639,14 @@ var myDummySQLCommand = /** @class */ (function () {
652
639
  }());
653
640
  function bulkInsert(array, db) {
654
641
  return tslib_1.__awaiter(this, void 0, void 0, function () {
655
- var chunkSize, _loop_2, i;
642
+ var chunkSize, _loop_1, i;
656
643
  return tslib_1.__generator(this, function (_a) {
657
644
  switch (_a.label) {
658
645
  case 0:
659
646
  if (array.length == 0)
660
647
  return [2 /*return*/];
661
648
  chunkSize = 250;
662
- _loop_2 = function (i) {
649
+ _loop_1 = function (i) {
663
650
  var items, c, sql, _b, _c;
664
651
  return tslib_1.__generator(this, function (_d) {
665
652
  switch (_d.label) {
@@ -697,7 +684,7 @@ function bulkInsert(array, db) {
697
684
  _a.label = 1;
698
685
  case 1:
699
686
  if (!(i < array.length)) return [3 /*break*/, 4];
700
- return [5 /*yield**/, _loop_2(i)];
687
+ return [5 /*yield**/, _loop_1(i)];
701
688
  case 2:
702
689
  _a.sent();
703
690
  _a.label = 3;
package/src/entity.d.ts CHANGED
@@ -150,7 +150,19 @@ export interface EntityOptions<entityType = any> {
150
150
  * dbName:'public."myProducts"'
151
151
  */
152
152
  dbName?: string;
153
- /** For entities that are based on SQL expressions instead of a physical table or view*/
153
+ /** For entities that are based on SQL expressions instead of a physical table or view
154
+ * @example
155
+ * .@Entity('people',{
156
+ * sqlExpression:`select id,name from employees
157
+ * union all select id,name from contractors`,
158
+ * })
159
+ * export class Person{
160
+ * .@Fields.string()
161
+ * id=''
162
+ * .@Fields.string()
163
+ * name=''
164
+ * }
165
+ */
154
166
  sqlExpression?: string | ((entity: EntityMetadata<entityType>) => string | Promise<string>);
155
167
  /** An arrow function that identifies the `id` column to use for this entity
156
168
  * @example
@@ -369,17 +369,27 @@ exports.dbNamesOf = dbNamesOf;
369
369
  function entityDbName(metadata, wrapIdentifier) {
370
370
  if (wrapIdentifier === void 0) { wrapIdentifier = function (x) { return x; }; }
371
371
  return tslib_1.__awaiter(this, void 0, void 0, function () {
372
+ var prev;
372
373
  return tslib_1.__generator(this, function (_a) {
373
374
  switch (_a.label) {
374
375
  case 0:
375
- if (!metadata.options.sqlExpression) return [3 /*break*/, 3];
376
+ if (!metadata.options.sqlExpression) return [3 /*break*/, 5];
376
377
  if (!(typeof metadata.options.sqlExpression === 'string')) return [3 /*break*/, 1];
377
378
  return [2 /*return*/, metadata.options.sqlExpression];
378
379
  case 1:
379
- if (!(typeof metadata.options.sqlExpression === 'function')) return [3 /*break*/, 3];
380
- return [4 /*yield*/, metadata.options.sqlExpression(metadata)];
381
- case 2: return [2 /*return*/, _a.sent()];
382
- case 3: return [2 /*return*/, wrapIdentifier(metadata.dbName)];
380
+ if (!(typeof metadata.options.sqlExpression === 'function')) return [3 /*break*/, 5];
381
+ prev = metadata.options.sqlExpression;
382
+ _a.label = 2;
383
+ case 2:
384
+ _a.trys.push([2, , 4, 5]);
385
+ metadata.options.sqlExpression =
386
+ "recursive sqlExpression call for entity '" + metadata.key + "'. ";
387
+ return [4 /*yield*/, prev(metadata)];
388
+ case 3: return [2 /*return*/, _a.sent()];
389
+ case 4:
390
+ metadata.options.sqlExpression = prev;
391
+ return [7 /*endfinally*/];
392
+ case 5: return [2 /*return*/, wrapIdentifier(metadata.dbName)];
383
393
  }
384
394
  });
385
395
  });
@@ -17,10 +17,10 @@ export declare class Fields {
17
17
  static updatedAt<entityType = any>(...options: (FieldOptions<entityType, Date> | ((options: FieldOptions<entityType, Date>, remult: Remult) => void))[]): ClassFieldDecorator<entityType, Date | undefined>;
18
18
  static uuid<entityType = any>(...options: (FieldOptions<entityType, string> | ((options: FieldOptions<entityType, string>, remult: Remult) => void))[]): ClassFieldDecorator<entityType, string | undefined>;
19
19
  /**
20
- * A CUID (Collision Resistant Unique Identifier) field.
21
- * This id value is determined on the backend on insert, and can't be updated through the API.
22
- * The CUID is generated using the `@paralleldrive/cuid2` npm package.
23
- */
20
+ * A CUID (Collision Resistant Unique Identifier) field.
21
+ * This id value is determined on the backend on insert, and can't be updated through the API.
22
+ * The CUID is generated using the `@paralleldrive/cuid2` npm package.
23
+ */
24
24
  static cuid<entityType = any>(...options: (FieldOptions<entityType, string> | ((options: FieldOptions<entityType, string>, remult: Remult) => void))[]): ClassFieldDecorator<entityType, string | undefined>;
25
25
  /**
26
26
  * Defines a field that can hold a value from a specified set of string literals.
@@ -87,7 +87,8 @@ var Fields = /** @class */ (function () {
87
87
  for (var _i = 0; _i < arguments.length; _i++) {
88
88
  options[_i] = arguments[_i];
89
89
  }
90
- return Field.apply(void 0, tslib_1.__spreadArray([function () { return Number; }, {
90
+ return Field.apply(void 0, tslib_1.__spreadArray([function () { return Number; },
91
+ {
91
92
  validate: validateNumber,
92
93
  }], tslib_1.__read(options), false));
93
94
  };
@@ -135,10 +136,10 @@ var Fields = /** @class */ (function () {
135
136
  }], tslib_1.__read(options), false));
136
137
  };
137
138
  /**
138
- * A CUID (Collision Resistant Unique Identifier) field.
139
- * This id value is determined on the backend on insert, and can't be updated through the API.
140
- * The CUID is generated using the `@paralleldrive/cuid2` npm package.
141
- */
139
+ * A CUID (Collision Resistant Unique Identifier) field.
140
+ * This id value is determined on the backend on insert, and can't be updated through the API.
141
+ * The CUID is generated using the `@paralleldrive/cuid2` npm package.
142
+ */
142
143
  Fields.cuid = function () {
143
144
  var options = [];
144
145
  for (var _i = 0; _i < arguments.length; _i++) {
@@ -184,15 +185,22 @@ var Fields = /** @class */ (function () {
184
185
  * // This approach allows easy management and updates of the allowed values for the `status` field.
185
186
  */
186
187
  Fields.literal = function (optionalValues) {
188
+ var _a;
187
189
  var options = [];
188
190
  for (var _i = 1; _i < arguments.length; _i++) {
189
191
  options[_i - 1] = arguments[_i];
190
192
  }
191
- return Fields.string.apply(Fields, tslib_1.__spreadArray([{
192
- validate: function (entity, event) { return validators_js_1.Validators.in(optionalValues())(entity, event); }
193
- }], tslib_1.__read(options), false));
193
+ return Fields.string.apply(Fields, tslib_1.__spreadArray([(_a = {
194
+ validate: function (entity, event) {
195
+ return validators_js_1.Validators.in(optionalValues())(entity, event);
196
+ }
197
+ },
198
+ //@ts-expect-error as we are adding this to options without it being defined in options
199
+ _a[RepositoryImplementation_js_1.fieldOptionalValuesFunctionKey] = optionalValues,
200
+ _a)], tslib_1.__read(options), false));
194
201
  };
195
202
  Fields.enum = function (enumType) {
203
+ var _a;
196
204
  var options = [];
197
205
  for (var _i = 1; _i < arguments.length; _i++) {
198
206
  options[_i - 1] = arguments[_i];
@@ -201,14 +209,20 @@ var Fields = /** @class */ (function () {
201
209
  return Field.apply(void 0, tslib_1.__spreadArray(tslib_1.__spreadArray([function () {
202
210
  //@ts-ignore
203
211
  return (enumType());
204
- },
205
- {
206
- validate: function (entity, event) { return validators_js_1.Validators.enum(enumType())(entity, event); }
207
- }], tslib_1.__read(options), false), [function (options) {
212
+ }, (_a = {
213
+ validate: function (entity, event) { return validators_js_1.Validators.enum(enumType())(entity, event); }
214
+ },
215
+ _a[RepositoryImplementation_js_1.fieldOptionalValuesFunctionKey] = function () { return (0, validators_js_1.getEnumValues)(enumType()); },
216
+ _a)], tslib_1.__read(options), false), [function (options) {
217
+ options[RepositoryImplementation_js_1.fieldOptionalValuesFunctionKey] = function () {
218
+ return (0, validators_js_1.getEnumValues)(enumType());
219
+ };
208
220
  if (valueConverter === undefined) {
209
221
  var enumObj = enumType();
210
222
  var enumValues = (0, validators_js_1.getEnumValues)(enumObj);
211
- valueConverter = enumValues.find(function (x) { return typeof x === "string"; }) ? valueConverters_js_1.ValueConverters.String : valueConverters_js_1.ValueConverters.Integer;
223
+ valueConverter = enumValues.find(function (x) { return typeof x === 'string'; })
224
+ ? valueConverters_js_1.ValueConverters.String
225
+ : valueConverters_js_1.ValueConverters.Integer;
212
226
  }
213
227
  if (!options.valueConverter) {
214
228
  options.valueConverter = valueConverter;
@@ -47,9 +47,10 @@ export declare class RepositoryImplementation<entityType> implements Repository<
47
47
  insert(item: Partial<MembersOnly<entityType>>): Promise<entityType>;
48
48
  get fields(): FieldsMetadata<entityType>;
49
49
  validate(entity: Partial<MembersOnly<entityType>>, ...fields: Extract<keyof MembersOnly<entityType>, string>[]): Promise<ErrorInfo<entityType> | undefined>;
50
- updateMany({ where }: {
50
+ updateMany({ where, set, }: {
51
51
  where: EntityFilter<entityType>;
52
- }, set: Partial<MembersOnly<entityType>>): Promise<number>;
52
+ set: Partial<MembersOnly<entityType>>;
53
+ }): Promise<number>;
53
54
  update(id: idType<entityType>, item: Partial<MembersOnly<entityType>>): Promise<entityType>;
54
55
  update(originalItem: Partial<MembersOnly<entityType>>, item: Partial<MembersOnly<entityType>>): Promise<entityType>;
55
56
  private _getRefForExistingRow;
@@ -295,6 +296,7 @@ export declare function getValueList<T>(field: FieldRef<T>): T[];
295
296
  export declare function getValueList<T>(field: FieldMetadata<T>): T[];
296
297
  export declare function getValueList<T>(type: ClassType<T>): T[];
297
298
  export declare const storableMember: unique symbol;
299
+ export declare const fieldOptionalValuesFunctionKey: unique symbol;
298
300
  export declare function buildOptions<entityType = any, valueType = any>(options: (FieldOptions<entityType, valueType> | ((options: FieldOptions<entityType, valueType>, remult: Remult) => void))[], remult: Remult): FieldOptions<entityType, valueType>;
299
301
  export declare function decorateColumnSettings<valueType>(settings: FieldOptions<any, valueType>, remult: Remult): FieldOptions<any, valueType>;
300
302
  export declare class EntityBase {
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getRepository = exports.getEntityMetadata = exports.ControllerBase = exports.EntityBase = exports.decorateColumnSettings = exports.buildOptions = exports.storableMember = exports.getValueList = exports.ValueListInfo = exports.ValueListFieldType = exports.isAutoIncrement = exports.FieldType = exports.columnDefsImpl = exports.buildCaption = exports.CaptionTransformer = exports.FieldRefImplementation = exports.controllerRefImpl = exports.getControllerRef = exports.getFields = exports.rowHelperImplementation = exports.createOldEntity = exports.RepositoryImplementation = void 0;
3
+ exports.getRepository = exports.getEntityMetadata = exports.ControllerBase = exports.EntityBase = exports.decorateColumnSettings = exports.buildOptions = exports.fieldOptionalValuesFunctionKey = exports.storableMember = exports.getValueList = exports.ValueListInfo = exports.ValueListFieldType = exports.isAutoIncrement = exports.FieldType = exports.columnDefsImpl = exports.buildCaption = exports.CaptionTransformer = exports.FieldRefImplementation = exports.controllerRefImpl = exports.getControllerRef = exports.getFields = exports.rowHelperImplementation = exports.createOldEntity = exports.RepositoryImplementation = void 0;
4
4
  var tslib_1 = require("tslib");
5
5
  var column_js_1 = require("../column.js");
6
6
  var CompoundIdField_js_1 = require("../CompoundIdField.js");
@@ -20,6 +20,7 @@ var filter_consumer_bridge_to_sql_request_js_1 = require("../filter/filter-consu
20
20
  var remult_static_js_1 = require("../remult-static.js");
21
21
  var validators_js_1 = require("../validators.js");
22
22
  var addValidator_js_1 = require("./addValidator.js");
23
+ var isOfType_js_1 = require("../isOfType.js");
23
24
  //import { remult } from "../remult-proxy";
24
25
  var classValidatorValidate = undefined;
25
26
  // import ("class-validator".toString())
@@ -437,9 +438,9 @@ var RepositoryImplementation = /** @class */ (function () {
437
438
  });
438
439
  });
439
440
  };
440
- RepositoryImplementation.prototype.updateMany = function (_a, set) {
441
+ RepositoryImplementation.prototype.updateMany = function (_a) {
441
442
  var _b, e_7, _c, _d;
442
- var where = _a.where;
443
+ var where = _a.where, set = _a.set;
443
444
  return tslib_1.__awaiter(this, void 0, void 0, function () {
444
445
  var _e, _f, updated, _g, _h, _j, item, e_7_1;
445
446
  return tslib_1.__generator(this, function (_k) {
@@ -3100,6 +3101,11 @@ var EntityFullInfo = /** @class */ (function () {
3100
3101
  return item[_this.idMetadata.field.key];
3101
3102
  },
3102
3103
  field: undefined,
3104
+ get fields() {
3105
+ return this.field instanceof CompoundIdField_js_1.CompoundIdField
3106
+ ? this.field.fields
3107
+ : [this.field];
3108
+ },
3103
3109
  createIdInFilter: function (items) {
3104
3110
  if (items.length > 0)
3105
3111
  return {
@@ -3385,21 +3391,23 @@ var ValueListInfo = /** @class */ (function () {
3385
3391
  exports.ValueListInfo = ValueListInfo;
3386
3392
  var typeCache = new Map();
3387
3393
  function getValueList(type) {
3388
- var _a;
3389
- {
3390
- var fr = (_a = type === null || type === void 0 ? void 0 : type.metadata) === null || _a === void 0 ? void 0 : _a.valueType;
3391
- if (fr)
3392
- return ValueListInfo.get(fr).getValues();
3393
- }
3394
- {
3395
- var fr = type === null || type === void 0 ? void 0 : type.valueType;
3396
- if (fr)
3397
- return ValueListInfo.get(fr).getValues();
3394
+ var meta = type === null || type === void 0 ? void 0 : type.metadata;
3395
+ if (!meta && (0, isOfType_js_1.isOfType)(type, 'options'))
3396
+ meta = type;
3397
+ type = (meta === null || meta === void 0 ? void 0 : meta.valueType) || type;
3398
+ if (type) {
3399
+ var options = type[exports.storableMember];
3400
+ if (options)
3401
+ return ValueListInfo.get(type).getValues();
3398
3402
  }
3399
- return ValueListInfo.get(type).getValues();
3403
+ var optionalValues = meta === null || meta === void 0 ? void 0 : meta.options[exports.fieldOptionalValuesFunctionKey];
3404
+ if (optionalValues)
3405
+ return optionalValues();
3406
+ return undefined;
3400
3407
  }
3401
3408
  exports.getValueList = getValueList;
3402
3409
  exports.storableMember = Symbol.for('storableMember');
3410
+ exports.fieldOptionalValuesFunctionKey = Symbol.for('fieldOptionalValues');
3403
3411
  function buildOptions(options, remult) {
3404
3412
  var e_47, _a;
3405
3413
  var r = {};
@@ -174,6 +174,7 @@ export interface IdMetadata<entityType = any> {
174
174
  */
175
175
  getId(item: Partial<MembersOnly<entityType>>): any;
176
176
  field: FieldMetadata<any>;
177
+ fields: FieldMetadata<unknown>[];
177
178
  getIdFilter(...ids: any[]): EntityFilter<entityType>;
178
179
  isIdField(col: FieldMetadata): boolean;
179
180
  createIdInFilter(items: Partial<MembersOnly<entityType>>[]): EntityFilter<entityType>;
@@ -317,7 +318,8 @@ export interface Repository<entityType> {
317
318
  */
318
319
  updateMany(options: {
319
320
  where: EntityFilter<entityType>;
320
- }, item: Partial<MembersOnly<entityType>>): Promise<number>;
321
+ set: Partial<MembersOnly<entityType>>;
322
+ }): Promise<number>;
321
323
  /** Deletes an Item*/
322
324
  delete(id: idType<entityType>): Promise<void>;
323
325
  delete(item: Partial<MembersOnly<entityType>>): Promise<void>;
@@ -2,22 +2,31 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  //y1 - https://discord.com/channels/975754286384418847/1230386433093533698/1230386433093533698
4
4
  //y1 - fix async hooks - was it fixed?
5
+ //y1 - repo batch - for multiple operations:
6
+ /*
7
+ const result = await repo.batch(x=>({
8
+ data:x.find(),
9
+ count:x.count()
10
+ }))
11
+ */
12
+ //p1 - adjust react tutorial to esm
13
+ //p1 - add solid tutorial to the getting started page
14
+ //p1 - update the examples section
15
+ //p1 - add documentation for bun sqlite
5
16
  //p1 - consider upsert (where,set)
6
- //p1 - consider id to also support keyof (id:['company','index'])
7
17
  //p1 - wait a second to close stream
8
- //p1 - reconsider update many, maybe the second parameter should be in a set option - break existing
9
- //p1 - add documentation for bun sqlite
18
+ //y1 - consider id to also support keyof (id:['company','index']) - had problem with | (keyof Partial<entityType>)[] & `entity`
10
19
  //p1 - describe entity
11
20
  //p1 - prepare the createEntity discussion
12
21
  //p1 - write active record article
13
- //p1 - maybe add decorator comment in the readme as well (I heard you've lost me in decorators) - and improve the describeClass function
14
22
  //p1 - return error on connection error
15
23
  //p1 - consider including the admin in the tutorial - and maybe even in the demo when we setup the api
24
+ //p1 - reconsider key typing to be keyof & string
16
25
  //p2 -fix remult admin not to load the html into memory until used
17
26
  //y2 - JY suggestion of having generate as part of the ensure schema - not sure
18
27
  //y2 - currently for string fields we default for 255 in knex (which is their default) why not just use text (varchar max) - and only use exact length when one is provided?
19
28
  //p2 - create foreign key constraints in user code - https://codesandbox.io/p/devbox/fk-validator-tdshcs
20
- //p1 - admin url1 - pocketbase use /_ for the admin //{allowed?:Allowed,url?:string} also checkout the admin* as it should probably be something else and didn't work in hono
29
+ //p2 - admin url1 - pocketbase use /_ for the admin //{allowed?:Allowed,url?:string} also checkout the admin* as it should probably be something else and didn't work in hono
21
30
  //p1 - article auth.js with express - played with it, requires type="module" and a few more configurations - https://github.com/noam-honig/express-auth
22
31
  //y2 - fix validators cache
23
32
  //y2 - should we validate relations
@@ -89,4 +98,3 @@ Object.defineProperty(exports, "__esModule", { value: true });
89
98
  //y2 - add some api testing framework for user unit tests (will help with codesandbox based discussions)
90
99
  //[ ] V2 - what to do about for relations count?
91
100
  //[ ] V2 - condition? not to fetch if null etc....
92
- //p1 - adjust react tutorial to esm
package/src/validators.js CHANGED
@@ -48,14 +48,19 @@ var Validators = /** @class */ (function () {
48
48
  });
49
49
  Validators.email = createValueValidator(function (val) { return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(val); }, 'Invalid Email');
50
50
  Validators.url = createValueValidator(function (val) { return !!new URL(val); }, 'Invalid Url');
51
- Validators.in = createValueValidatorWithArgs(function (val, values) { return values.includes(val); }, function (values) { return "Value must be one of ".concat(values.map(function (y) {
52
- return typeof y === "object" ? y['id'] !== undefined ? y['id'] : y.toString() : y;
53
- }).join(', ')); });
54
- Validators.notNull = createValueValidator(function (val) { return val != null; }, 'Should not be null');
55
- Validators.enum = createValueValidatorWithArgs(function (value, enumObj) { return Object.values(enumObj).includes(value); }, function (enumObj) {
56
- return "Value must be one of ".concat(getEnumValues(enumObj)
51
+ Validators.in = createValueValidatorWithArgs(function (val, values) { return values.includes(val); }, function (values) {
52
+ return "Value must be one of: ".concat(values
53
+ .map(function (y) {
54
+ return typeof y === 'object'
55
+ ? y['id'] !== undefined
56
+ ? y['id']
57
+ : y.toString()
58
+ : y;
59
+ })
57
60
  .join(', '));
58
61
  });
62
+ Validators.notNull = createValueValidator(function (val) { return val != null; }, 'Should not be null');
63
+ Validators.enum = createValueValidatorWithArgs(function (value, enumObj) { return Object.values(enumObj).includes(value); }, function (enumObj) { return "Value must be one of ".concat(getEnumValues(enumObj).join(', ')); });
59
64
  Validators.relationExists = createValidator(function (_, e) { return tslib_1.__awaiter(void 0, void 0, void 0, function () {
60
65
  var _b;
61
66
  return tslib_1.__generator(_a, function (_c) {
@@ -209,7 +214,6 @@ function createValidatorWithArgsInternal(validate, defaultMessage, isValueValida
209
214
  });
210
215
  }
211
216
  function getEnumValues(enumObj) {
212
- return Object.values(enumObj)
213
- .filter(function (x) { return typeof enumObj[x] !== 'number'; });
217
+ return Object.values(enumObj).filter(function (x) { return typeof enumObj[x] !== 'number'; });
214
218
  }
215
219
  exports.getEnumValues = getEnumValues;
@@ -1,16 +0,0 @@
1
- import { Filter } from './filter/filter-interfaces.js';
2
- export function resultCompoundIdFilter(idField, id, data) {
3
- return new Filter((add) => {
4
- let idParts = [];
5
- if (id != undefined)
6
- idParts = id.split(',');
7
- idField.fields.forEach((c, i) => {
8
- let val = undefined;
9
- if (i < idParts.length)
10
- val = idParts[i];
11
- if (data[c.key] != undefined)
12
- val = data[c.key];
13
- add.isEqualTo(c, val);
14
- });
15
- });
16
- }
@@ -1,3 +0,0 @@
1
- import type { CompoundIdField } from './CompoundIdField.js';
2
- import { Filter } from './filter/filter-interfaces.js';
3
- export declare function resultCompoundIdFilter(idField: CompoundIdField, id: string | undefined, data: any): Filter;
@@ -1,20 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.resultCompoundIdFilter = void 0;
4
- var filter_interfaces_js_1 = require("./filter/filter-interfaces.js");
5
- function resultCompoundIdFilter(idField, id, data) {
6
- return new filter_interfaces_js_1.Filter(function (add) {
7
- var idParts = [];
8
- if (id != undefined)
9
- idParts = id.split(',');
10
- idField.fields.forEach(function (c, i) {
11
- var val = undefined;
12
- if (i < idParts.length)
13
- val = idParts[i];
14
- if (data[c.key] != undefined)
15
- val = data[c.key];
16
- add.isEqualTo(c, val);
17
- });
18
- });
19
- }
20
- exports.resultCompoundIdFilter = resultCompoundIdFilter;