remult 0.25.8 → 0.26.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.
Files changed (102) hide show
  1. package/README.md +194 -129
  2. package/esm/graphql.js +131 -59
  3. package/esm/index.js +1 -1
  4. package/esm/migrations/compare-migration-snapshots.js +61 -0
  5. package/esm/migrations/generate-migrations.js +68 -0
  6. package/esm/migrations/index.js +2 -0
  7. package/esm/migrations/migrate.js +90 -0
  8. package/esm/migrations/migration-types.js +36 -0
  9. package/esm/migrations/update-migrations-ts-file.js +115 -0
  10. package/esm/postgres/postgres-data-provider.js +24 -3
  11. package/esm/postgres/schema-builder.js +35 -26
  12. package/esm/remult-better-sqlite3.js +47 -0
  13. package/esm/remult-bun-sqlite.js +41 -0
  14. package/esm/remult-knex/index.js +180 -51
  15. package/esm/remult-mongo.js +2 -2
  16. package/esm/remult-sql-js.js +3 -78
  17. package/esm/remult-sqlite-core.js +104 -0
  18. package/esm/server/expressBridge.js +130 -29
  19. package/esm/server/initAsyncHooks.js +75 -1
  20. package/esm/src/CompoundIdField.js +8 -2
  21. package/esm/src/context.js +20 -24
  22. package/esm/src/data-api.js +71 -30
  23. package/esm/src/data-providers/rest-data-provider.js +17 -15
  24. package/esm/src/data-providers/sql-database.js +32 -7
  25. package/esm/src/data-providers/web-sql-data-provider.js +1 -9
  26. package/esm/src/filter/filter-consumer-bridge-to-sql-request.js +37 -11
  27. package/esm/src/filter/filter-interfaces.js +229 -17
  28. package/esm/src/isOfType.js +9 -0
  29. package/esm/src/remult3/Fields.js +70 -18
  30. package/esm/src/remult3/RepositoryImplementation.js +47 -21
  31. package/esm/src/remult3/addValidator.js +15 -0
  32. package/esm/src/remult3/remult3.js +28 -57
  33. package/esm/src/server-action.js +4 -4
  34. package/esm/src/validators.js +6 -3
  35. package/esm/src/valueConverters.js +1 -1
  36. package/graphql.js +156 -71
  37. package/index.d.ts +4 -4
  38. package/index.js +2 -1
  39. package/migrations/compare-migration-snapshots.d.ts +27 -0
  40. package/migrations/compare-migration-snapshots.js +165 -0
  41. package/migrations/generate-migrations.d.ts +21 -0
  42. package/migrations/generate-migrations.js +104 -0
  43. package/migrations/index.d.ts +3 -0
  44. package/migrations/index.js +7 -0
  45. package/migrations/migrate.d.ts +27 -0
  46. package/migrations/migrate.js +175 -0
  47. package/migrations/migration-types.d.ts +48 -0
  48. package/migrations/migration-types.js +88 -0
  49. package/migrations/update-migrations-ts-file.d.ts +1 -0
  50. package/migrations/update-migrations-ts-file.js +141 -0
  51. package/package.json +21 -1
  52. package/postgres/postgres-data-provider.d.ts +8 -3
  53. package/postgres/postgres-data-provider.js +46 -3
  54. package/postgres/schema-builder.js +81 -48
  55. package/remult-better-sqlite3.d.ts +12 -0
  56. package/remult-better-sqlite3.js +64 -0
  57. package/remult-bun-sqlite.d.ts +11 -0
  58. package/remult-bun-sqlite.js +56 -0
  59. package/remult-knex/index.d.ts +12 -5
  60. package/remult-knex/index.js +257 -90
  61. package/remult-mongo.d.ts +2 -2
  62. package/remult-mongo.js +2 -2
  63. package/remult-sql-js.d.ts +2 -15
  64. package/remult-sql-js.js +11 -152
  65. package/remult-sqlite-core.d.ts +21 -0
  66. package/remult-sqlite-core.js +217 -0
  67. package/server/expressBridge.d.ts +30 -1
  68. package/server/expressBridge.js +140 -32
  69. package/server/initAsyncHooks.d.ts +16 -0
  70. package/server/initAsyncHooks.js +128 -2
  71. package/src/CompoundIdField.js +8 -2
  72. package/src/column-interfaces.d.ts +9 -3
  73. package/src/context.d.ts +8 -6
  74. package/src/context.js +27 -36
  75. package/src/data-api.d.ts +13 -9
  76. package/src/data-api.js +184 -135
  77. package/src/data-providers/rest-data-provider.js +26 -15
  78. package/src/data-providers/sql-database.d.ts +17 -5
  79. package/src/data-providers/sql-database.js +31 -7
  80. package/src/data-providers/web-sql-data-provider.d.ts +1 -2
  81. package/src/data-providers/web-sql-data-provider.js +4 -8
  82. package/src/entity.d.ts +64 -6
  83. package/src/filter/filter-consumer-bridge-to-sql-request.d.ts +31 -7
  84. package/src/filter/filter-consumer-bridge-to-sql-request.js +46 -21
  85. package/src/filter/filter-interfaces.d.ts +106 -39
  86. package/src/filter/filter-interfaces.js +312 -32
  87. package/src/isOfType.d.ts +2 -0
  88. package/src/isOfType.js +14 -0
  89. package/src/remult3/Fields.d.ts +36 -0
  90. package/src/remult3/Fields.js +81 -19
  91. package/src/remult3/RepositoryImplementation.d.ts +7 -3
  92. package/src/remult3/RepositoryImplementation.js +106 -71
  93. package/src/remult3/addValidator.d.ts +2 -0
  94. package/src/remult3/addValidator.js +20 -0
  95. package/src/remult3/remult3.d.ts +6 -2
  96. package/src/remult3/remult3.js +28 -57
  97. package/src/server-action.d.ts +1 -1
  98. package/src/server-action.js +5 -4
  99. package/src/sql-command.d.ts +6 -1
  100. package/src/validators.d.ts +1 -0
  101. package/src/validators.js +10 -4
  102. package/src/valueConverters.js +1 -1
@@ -1,59 +1,39 @@
1
1
  export {};
2
- /*y1 - workshop
3
-
4
- * Experiment with doing this with version control - so the students can follow changes
5
- * Prepare stackblitz
6
-
7
-
8
- # influencer:
9
- * review react summit
10
- #
11
-
12
- //y1 - getFields didn't work for kobi in the home component
13
-
14
- //p1 - processError in remult express
15
- //p1 - I think there should be a way to throw a forbidden exception
16
- //p1 - add section to Fields doc, explaining field type in db
17
- //p1 - add section about union type
18
- //p1 - add section about value list field type
2
+ //p1 - add documentation for bun sqlite
3
+ //p2 - fix dark background to also work on groups
4
+ //y1 - JY suggestion of having generate as part of the ensure schema - not sure
5
+ //y1 - 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?
6
+ //y1 - consider changing the sql raw filter to return the sql, instead of setting the sql property
7
+ //p2 - create foreign key constraints in user code - https://codesandbox.io/p/devbox/fk-validator-tdshcs
8
+ //p1 - admin url1 - pocketbase use /_ for the admin //{allowed?:Allowed,url?:string}
9
+ //p2 - article auth.js with express - played with it, requires type="module" and a few more configurations - https://github.com/noam-honig/express-auth
10
+ //y1 - fix validators cache
11
+ //y2 - should we validate relations
12
+ //y1 - dependency of live query tables
13
+ //p1 - see why mongo tests do not run anymore
14
+ //y1 - consider the bot that updates dependencies
15
+ //y1 - consider replacing all errors with error classes that extend the base Error class
16
+ //y2 - should enforce integer - currently we probably round / truncate it
17
+ //y1 - talk about filter on objects that are not loaded - {
18
+ //category: repo(CompoundId).create({ company: 7, index: 3, name: '' }),
19
+ // }
20
+ //y1 - consider id to also support keyof (id:['company','index'])
21
+ /*y1 - talk about modules in init express with entities/controllers,initRequest,initApi
22
+ - support get with backend method, with url search params as the first parameter, & url as second parameter
23
+ - support returning redirect, and plain html (For sign in scenarios)
19
24
 
25
+ */
26
+ //p1 - in this video I'll use remult to turn a frontend app to a fullstack app
20
27
  /*y1 - Talk JYC - JYC - add some integrity checks on delete
21
28
  - soft delete
22
29
  - delete restrict (implicit, or user selected - and if so, how) (delete & update of id)
23
30
 
24
31
  */
25
- /*y1 currency.ts:10 Uncaught TypeError: Currency_1 is not a constructor
26
- // - ValueListFieldType - the decorator gives an error in react vite project - see langulage yedidya
27
- // happens in target 2022, ts<5.1.6
28
- //typescript 5.1.6
29
- @ValueListFieldType()
30
- export class Currency {
31
- constructor(
32
- public id: number,
33
- public caption: string,
34
- public symbol: string
35
- ) {}
36
- static shekel = new Currency(1, 'Shekel', '₪');
37
- static dollar = new Currency(2, 'Dollar', '$');
38
- static euro = new Currency(3, 'Euro', '€');
39
- static pound = new Currency(4, 'Pound', '£');
40
- static yen = new Currency(5, 'Yen', '¥');
41
- }
42
-
43
- */
44
- //y1 - allow api read to also support instance and filter. - problem with promise
45
- //y1 - admin url1 - pocketbase use /_ for the admin
46
32
  //y1 - consider sql expression gets a dbnames of it's own (that already has the "tableName" defined correctly) maybe also the filter translator
47
- /*y1 - talk about modules in init express with entities/controllers,initRequest,initApi
48
- - support get with backend method, with url search params as the first parameter, & url as second parameter
49
- - support returning redirect, and plain html (For sign in scenarios)
50
-
51
- */
52
33
  //y1 - tried to upgrade vitest, nuxt tests are failing with loading uuid - sounds familiar?
53
34
  //y1 - I think that the tests you've setup don't cover next app router - I added to the setup, but not sure where else
54
35
  //y1 - talk about the parameter issue with backend methods
55
36
  //y1 - select data provider per entity https://discord.com/channels/975754286384418847/976006081748807690/1201415305885397003
56
- //y1 - migrations
57
37
  //y1 - live query refresh of view on table update
58
38
  //y1 - main vs master
59
39
  //y2 - livequery for findfirst (@JY)
@@ -64,11 +44,9 @@ export class Currency {
64
44
  })
65
45
  Description = ""*/
66
46
  //y2 - get backend methods to work when specifying types for date, and entities as poco's
67
- //y2 - conside law-q db based on schema issue - I think that while running the dataProvider function, we should have a valid remult - maybe even have a valid remult, that will be valid until api is run
68
- //y2 - #239 - (@JY) add a way to get from fieldMetadata back to entity repo (like we have in fieldRef)
69
47
  //y2 - constraints (@JY)
70
48
  /*p2 remult admin
71
-
49
+ - when making a change and canceling - the changed value still appears
72
50
  - Small thing, I get SvelteKitError: Not found: /vite.svg
73
51
  - understand the to many relation for the admin, based on the to one
74
52
  - relation from order details to order gave a compound id info - and it is not true - same for the relation to product
@@ -80,11 +58,9 @@ export class Currency {
80
58
  - remult-admin didn't show a update for a table with a uniqua that is numeric
81
59
  */
82
60
  //remult
83
- //p1 - better support union types (status, etc... so it'll work also in filter etc...)
84
61
  //p1 - when a tasks table exists in a different schema - we get many errors
85
62
  //p1 - live query with include
86
63
  //p1 - adjust angular tutorial starter kit for latest angular (as is in tutorial)
87
- //p2 - allow find options preprocessor for api calls, to use for authorization
88
64
  //p2 - when subscribe is forbidden - the query still runs after the renew process
89
65
  //p2 - 'update tasks set where id = $1
90
66
  //p2 - type metadata.key - to keyof entity - based on cwis input
@@ -92,23 +68,18 @@ export class Currency {
92
68
  //p2 - when value changes for field with error, clear error - so the user will feel comfortable
93
69
  //p2 - allowApiUpdate should be false for include in api false
94
70
  //docs
95
- //p2 - make sure that internal members do not appear in the documentation - try running it on the d.ts instead of the code itself.
96
71
  //------
72
+ //y2 - wrap identifier for custom filter & sql expression
73
+ //y2 - Should we create a separate implementation of command - one that the user uses, and another that the database implements (with only the bear necesities) - for example, to provide a second paramter called field for toDb conversions
74
+ //y2 - should we simply inherit from SqlDataProvider - and send the required parameter in the call to the base class - I think that new SqlDatabase(new PostgresDataProvider()) is a bilt combersome
97
75
  //y2 - from the crm-demo(https://crm-demo.up.railway.app/deals), after editing a deal: - _updateEntityBasedOnApi
98
76
  //y2 - Backend methods are transactions, it's not intuitive and maybe should be optional / opt in
99
77
  //y2 - how to run a transaction as a user
100
- //p2 - enum column
101
- //y2 - message for invalid value
102
78
  //y2 - message for relation that is missing
103
79
  //y2 - consider multi tenancies
104
- //p2 - more column types
105
- //p2 - document validators
106
80
  //p2 - and validators to reference
107
81
  //y2 - discuss a default date formatter
108
82
  //y2 - add some api testing framework for user unit tests (will help with codesandbox based discussions)
109
83
  //[ ] V2 - what to do about for relations count?
110
84
  //[ ] V2 - condition? not to fetch if null etc....
111
- //[ ] V3 - all these fields will also appear in the where etc... in the typescript api - but we will not enforce them
112
- //y2 - consider if field types should include validation in them by default (string,number that it's not NaN etc...) and if so, what message?
113
- //y2 - should enforce integer - currently we probably round / truncate it
114
85
  //p1 - adjust react tutorial to esm
@@ -65,14 +65,14 @@ export class Action {
65
65
  // got a problem in next with instance of ForbiddenError - so replaced it with this bool
66
66
  res.forbidden();
67
67
  else
68
- res.error(err);
68
+ res.error(err, undefined);
69
69
  }
70
70
  });
71
71
  }
72
72
  }
73
73
  export class ForbiddenError extends Error {
74
- constructor() {
75
- super('Forbidden');
74
+ constructor(message = 'Forbidden') {
75
+ super(message);
76
76
  }
77
77
  isForbiddenError = true;
78
78
  }
@@ -245,7 +245,7 @@ export function BackendMethod(options) {
245
245
  // got a problem in next with instance of ForbiddenError - so replaced it with this bool
246
246
  res.forbidden();
247
247
  else
248
- res.error(err);
248
+ res.error(err, undefined);
249
249
  }
250
250
  });
251
251
  }
@@ -26,10 +26,9 @@ 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.join(', ')}`);
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
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 ${Object.values(enumObj)
32
- .filter((x) => typeof enumObj[x] !== 'number')
31
+ static enum = createValueValidatorWithArgs((value, enumObj) => Object.values(enumObj).includes(value), (enumObj) => `Value must be one of ${getEnumValues(enumObj)
33
32
  .join(', ')}`);
34
33
  static relationExists = createValidator(async (_, e) => {
35
34
  if (e.valueIsNull())
@@ -134,3 +133,7 @@ function createValidatorWithArgsInternal(validate, defaultMessage, isValueValida
134
133
  },
135
134
  });
136
135
  }
136
+ export function getEnumValues(enumObj) {
137
+ return Object.values(enumObj)
138
+ .filter((x) => typeof enumObj[x] !== 'number');
139
+ }
@@ -136,7 +136,7 @@ export class ValueConverters {
136
136
  toJson: (value) => ValueConverters.Number.toDb(value),
137
137
  fromInput: (x, type) => {
138
138
  let r = +x;
139
- if (!x)
139
+ if (x === null || x === undefined)
140
140
  return undefined;
141
141
  return r;
142
142
  },
package/graphql.js CHANGED
@@ -167,6 +167,11 @@ function remultGraphql(options) {
167
167
  var e_6, _p;
168
168
  var orderByFields = [];
169
169
  var key = meta.key;
170
+ var requiredWhereArg = {
171
+ key: 'where',
172
+ value: "".concat(key, "Where!"),
173
+ comment: "Remult filtering options",
174
+ };
170
175
  var currentType = upsertTypes(getMetaType(meta), 'type_impl_node');
171
176
  if (key) {
172
177
  var createResultPromise_1 = function (work) {
@@ -236,7 +241,7 @@ function remultGraphql(options) {
236
241
  });
237
242
  }); });
238
243
  };
239
- var handleMutationWithErrors = function (work) {
244
+ var handleMutationWithErrors_1 = function (work) {
240
245
  return handleRequestWithDataApiContext_1(function (dApi, response, origSetResult, arg1, req) { return tslib_1.__awaiter(_this, void 0, void 0, function () {
241
246
  var setResult;
242
247
  return tslib_1.__generator(this, function (_a) {
@@ -278,6 +283,7 @@ function remultGraphql(options) {
278
283
  }); });
279
284
  };
280
285
  var queryArgsConnection = getQueryArgsConnection(key);
286
+ var pluralEntityKey = key;
281
287
  var getSingleEntityKey_1 = toCamelCase(getMetaType(meta));
282
288
  if (getSingleEntityKey_1 === toCamelCase(key))
283
289
  getSingleEntityKey_1 = 'single' + key;
@@ -382,7 +388,7 @@ function remultGraphql(options) {
382
388
  key: "".concat(toCamelCase(getMetaType(meta))),
383
389
  value: getMetaType(meta),
384
390
  }, argErrorDetail, argClientMutationId);
385
- root[createResolverKey_1] = handleMutationWithErrors(function (dApi, response, setResult, arg1, req) { return tslib_1.__awaiter(_this, void 0, void 0, function () {
391
+ root[createResolverKey_1] = handleMutationWithErrors_1(function (dApi, response, setResult, arg1, req) { return tslib_1.__awaiter(_this, void 0, void 0, function () {
386
392
  return tslib_1.__generator(this, function (_a) {
387
393
  switch (_a.label) {
388
394
  case 0: return [4 /*yield*/, dApi.post(tslib_1.__assign(tslib_1.__assign({}, response), { created: function (y) {
@@ -404,76 +410,151 @@ function remultGraphql(options) {
404
410
  if (checkCanExist(meta.options.allowApiUpdate)) {
405
411
  // update
406
412
  var updateInput = "Update".concat(getMetaType(meta), "Input");
407
- var updatePayload = "Update".concat(getMetaType(meta), "Payload");
408
- var updateResolverKey_1 = "update".concat(getMetaType(meta));
409
- root_mutation.fields.push({
410
- key: updateResolverKey_1,
411
- args: [
412
- argId,
413
- { key: 'patch', value: "".concat(updateInput, "!") },
414
- argClientMutationId,
415
- ],
416
- value: "".concat(updatePayload),
417
- comment: "Update a `".concat(getMetaType(meta), "`"),
418
- });
419
- currentType.mutation.update.input = upsertTypes(updateInput, 'input');
420
- currentType.mutation.update.payload = upsertTypes(updatePayload);
421
- currentType.mutation.update.payload.fields.push({
422
- key: "".concat(toCamelCase(getMetaType(meta))),
423
- value: "".concat(getMetaType(meta)),
424
- }, argErrorDetail, argClientMutationId);
425
- root[updateResolverKey_1] = handleMutationWithErrors(function (dApi, response, setResult, arg1, req) { return tslib_1.__awaiter(_this, void 0, void 0, function () {
426
- return tslib_1.__generator(this, function (_a) {
427
- switch (_a.label) {
428
- case 0: return [4 /*yield*/, dApi.put(tslib_1.__assign(tslib_1.__assign({}, response), { success: function (y) {
429
- var _a;
430
- var orig = tslib_1.__assign({}, y);
431
- currentType.query.resultProcessors.forEach(function (z) { return z(y, orig); });
432
- setResult((_a = {},
433
- _a[toCamelCase(getMetaType(meta))] = y,
434
- _a));
435
- } }), arg1.id, arg1.patch)];
436
- case 1:
437
- _a.sent();
438
- return [2 /*return*/];
439
- }
413
+ {
414
+ var updatePayload = "Update".concat(getMetaType(meta), "Payload");
415
+ var updateResolverKey = "update".concat(getMetaType(meta));
416
+ root_mutation.fields.push({
417
+ key: updateResolverKey,
418
+ args: [
419
+ argId,
420
+ { key: 'patch', value: "".concat(updateInput, "!") },
421
+ argClientMutationId,
422
+ ],
423
+ value: "".concat(updatePayload),
424
+ comment: "Update a `".concat(getMetaType(meta), "`"),
440
425
  });
441
- }); });
442
- resolversMutation[updateResolverKey_1] = function (origItem, args, req, gqlInfo) { return root[updateResolverKey_1](args, req, gqlInfo); };
426
+ currentType.mutation.update.input = upsertTypes(updateInput, 'input');
427
+ currentType.mutation.update.payload = upsertTypes(updatePayload);
428
+ currentType.mutation.update.payload.fields.push({
429
+ key: "".concat(toCamelCase(getMetaType(meta))),
430
+ value: "".concat(getMetaType(meta)),
431
+ }, argErrorDetail, argClientMutationId);
432
+ resolversMutation[updateResolverKey] = function (origItem, args, req, gqlInfo) {
433
+ return handleMutationWithErrors_1(function (dApi, response, setResult, arg1, req) { return tslib_1.__awaiter(_this, void 0, void 0, function () {
434
+ return tslib_1.__generator(this, function (_a) {
435
+ switch (_a.label) {
436
+ case 0: return [4 /*yield*/, dApi.put(tslib_1.__assign(tslib_1.__assign({}, response), { success: function (y) {
437
+ var _a;
438
+ var orig = tslib_1.__assign({}, y);
439
+ currentType.query.resultProcessors.forEach(function (z) {
440
+ return z(y, orig);
441
+ });
442
+ setResult((_a = {},
443
+ _a[toCamelCase(getMetaType(meta))] = y,
444
+ _a));
445
+ } }), arg1.id, arg1.patch)];
446
+ case 1:
447
+ _a.sent();
448
+ return [2 /*return*/];
449
+ }
450
+ });
451
+ }); })(args, req);
452
+ };
453
+ }
454
+ // update many
455
+ {
456
+ var updateManyPayload = "UpdateMany".concat(upperFirstChar(pluralEntityKey), "Payload");
457
+ var updateManyResolverKey = "updateMany".concat(upperFirstChar(pluralEntityKey));
458
+ root_mutation.fields.push({
459
+ key: updateManyResolverKey,
460
+ args: [
461
+ requiredWhereArg,
462
+ { key: 'patch', value: "".concat(updateInput, "!") },
463
+ argClientMutationId,
464
+ ],
465
+ value: "".concat(updateManyPayload),
466
+ comment: "Update many `".concat(pluralEntityKey, "`"),
467
+ });
468
+ currentType.mutation.update.payload = upsertTypes(updateManyPayload);
469
+ currentType.mutation.update.payload.fields.push({
470
+ key: "updated",
471
+ value: "Int!",
472
+ }, argErrorDetail, argClientMutationId);
473
+ resolversMutation[updateManyResolverKey] = function (origItem, args, req, gqlInfo) {
474
+ return handleMutationWithErrors_1(function (dApi, response, setResult, arg1, req) { return tslib_1.__awaiter(_this, void 0, void 0, function () {
475
+ return tslib_1.__generator(this, function (_a) {
476
+ switch (_a.label) {
477
+ case 0: return [4 /*yield*/, dApi.updateManyImplementation(tslib_1.__assign(tslib_1.__assign({}, response), { success: function (updateManyResult) {
478
+ setResult(updateManyResult);
479
+ } }), { get: function () { return undefined; } }, tslib_1.__assign(tslib_1.__assign({}, translateWhereToRestBody(meta.fields, arg1)), { set: arg1.patch }))];
480
+ case 1:
481
+ _a.sent();
482
+ return [2 /*return*/];
483
+ }
484
+ });
485
+ }); })(args, req);
486
+ };
487
+ }
443
488
  }
444
489
  if (checkCanExist(meta.options.allowApiDelete)) {
445
490
  // delete
446
- var deletePayload = "Delete".concat(getMetaType(meta), "Payload");
447
- var deleteResolverKey_1 = "delete".concat(getMetaType(meta));
448
- root_mutation.fields.push({
449
- key: deleteResolverKey_1,
450
- args: [argId, argClientMutationId],
451
- value: "".concat(deletePayload),
452
- comment: "Delete a `".concat(getMetaType(meta), "`"),
453
- });
454
- currentType.mutation.delete.payload = upsertTypes(deletePayload);
455
- var deletedResultKey_1 = "id";
456
- var type = meta.idMetadata.field instanceof index_js_1.CompoundIdField
457
- ? 'String'
458
- : getGraphqlBaseType(meta.idMetadata.field);
459
- currentType.mutation.delete.payload.fields.push({
460
- key: deletedResultKey_1,
461
- value: "".concat(type),
462
- }, argErrorDetail, argClientMutationId);
463
- root[deleteResolverKey_1] = handleMutationWithErrors(function (dApi, response, setResult, arg1, req) { return tslib_1.__awaiter(_this, void 0, void 0, function () {
464
- return tslib_1.__generator(this, function (_a) {
465
- switch (_a.label) {
466
- case 0: return [4 /*yield*/, dApi.delete(tslib_1.__assign(tslib_1.__assign({}, response), { deleted: function () {
467
- var _a;
468
- setResult((_a = {}, _a[deletedResultKey_1] = arg1.id, _a));
469
- } }), arg1.id)];
470
- case 1:
471
- _a.sent();
472
- return [2 /*return*/];
473
- }
491
+ {
492
+ var deletePayload = "Delete".concat(getMetaType(meta), "Payload");
493
+ var deleteResolverKey = "delete".concat(getMetaType(meta));
494
+ root_mutation.fields.push({
495
+ key: deleteResolverKey,
496
+ args: [argId, argClientMutationId],
497
+ value: "".concat(deletePayload),
498
+ comment: "Delete a `".concat(getMetaType(meta), "`"),
474
499
  });
475
- }); });
476
- resolversMutation[deleteResolverKey_1] = function (origItem, args, req, gqlInfo) { return root[deleteResolverKey_1](args, req, gqlInfo); };
500
+ currentType.mutation.delete.payload = upsertTypes(deletePayload);
501
+ var deletedResultKey_1 = "id";
502
+ var type = meta.idMetadata.field instanceof index_js_1.CompoundIdField
503
+ ? 'String'
504
+ : getGraphqlBaseType(meta.idMetadata.field);
505
+ currentType.mutation.delete.payload.fields.push({
506
+ key: deletedResultKey_1,
507
+ value: "".concat(type),
508
+ }, argErrorDetail, argClientMutationId);
509
+ resolversMutation[deleteResolverKey] = function (origItem, args, req) {
510
+ return handleMutationWithErrors_1(function (dApi, response, setResult, arg1, req) { return tslib_1.__awaiter(_this, void 0, void 0, function () {
511
+ return tslib_1.__generator(this, function (_a) {
512
+ switch (_a.label) {
513
+ case 0: return [4 /*yield*/, dApi.delete(tslib_1.__assign(tslib_1.__assign({}, response), { deleted: function () {
514
+ var _a;
515
+ setResult((_a = {}, _a[deletedResultKey_1] = arg1.id, _a));
516
+ } }), arg1.id)];
517
+ case 1:
518
+ _a.sent();
519
+ return [2 /*return*/];
520
+ }
521
+ });
522
+ }); })(args, req);
523
+ };
524
+ }
525
+ // delete
526
+ {
527
+ var deleteManyPayload = "DeleteMany".concat(upperFirstChar(pluralEntityKey), "Payload");
528
+ var deleteManyResolverKey = "deleteMany".concat(upperFirstChar(pluralEntityKey));
529
+ root_mutation.fields.push({
530
+ key: deleteManyResolverKey,
531
+ args: [requiredWhereArg, argClientMutationId],
532
+ value: "".concat(deleteManyPayload),
533
+ comment: "Delete many `".concat(pluralEntityKey, "`"),
534
+ });
535
+ currentType.mutation.delete.payload = upsertTypes(deleteManyPayload);
536
+ var type = meta.idMetadata.field instanceof index_js_1.CompoundIdField
537
+ ? 'String'
538
+ : getGraphqlBaseType(meta.idMetadata.field);
539
+ currentType.mutation.delete.payload.fields.push({
540
+ key: 'deleted',
541
+ value: "Int!",
542
+ }, argErrorDetail, argClientMutationId);
543
+ resolversMutation[deleteManyResolverKey] = function (origItem, args, req) {
544
+ return handleMutationWithErrors_1(function (dApi, response, setResult, arg1, req) { return tslib_1.__awaiter(_this, void 0, void 0, function () {
545
+ return tslib_1.__generator(this, function (_a) {
546
+ switch (_a.label) {
547
+ case 0: return [4 /*yield*/, dApi.deleteMany(tslib_1.__assign(tslib_1.__assign({}, response), { success: function (deleteManyResult) {
548
+ setResult(deleteManyResult);
549
+ } }), { get: function () { return undefined; } }, translateWhereToRestBody(meta.fields, arg1))];
550
+ case 1:
551
+ _a.sent();
552
+ return [2 /*return*/];
553
+ }
554
+ });
555
+ }); })(args, req);
556
+ };
557
+ }
477
558
  }
478
559
  var whereTypeFields = [];
479
560
  var _loop_2 = function (f) {
@@ -986,6 +1067,12 @@ function getGraphqlBaseType(field) {
986
1067
  function getMetaType(entityMeta) {
987
1068
  return entityMeta.entityType.name;
988
1069
  }
1070
+ function upperFirstChar(str) {
1071
+ return str
1072
+ .split('')
1073
+ .map(function (c, i) { return (i === 0 ? c.toUpperCase() : c); })
1074
+ .join('');
1075
+ }
989
1076
  function toCamelCase(str) {
990
1077
  return str
991
1078
  .split('')
@@ -1081,10 +1168,8 @@ function translateWhereToRestBody(fields, _a) {
1081
1168
  finally { if (e_7) throw e_7.error; }
1082
1169
  }
1083
1170
  if (where.OR) {
1084
- result.OR = where.OR.map(function (where) {
1085
- return translateWhereToRestBody(fields, { where: where });
1086
- });
1171
+ result.OR = where.OR.map(function (where) { return translateWhereToRestBody(fields, { where: where }).where; });
1087
1172
  }
1088
- return result;
1173
+ return { where: result };
1089
1174
  }
1090
1175
  exports.translateWhereToRestBody = translateWhereToRestBody;
package/index.d.ts CHANGED
@@ -10,7 +10,7 @@ export { getEntityRef } from './src/remult3/getEntityRef.js';
10
10
  export { Field, Fields, StringFieldOptions, Relations, } from './src/remult3/Fields.js';
11
11
  export { IdEntity } from './src/remult3/IdEntity.js';
12
12
  export { describeClass } from './src/remult3/DecoratorReplacer.js';
13
- export { EntityOptions } from './src/entity.js';
13
+ export { EntityOptions, PreprocessFilterEvent } from './src/entity.js';
14
14
  export { DataProvider, EntityDataProvider, EntityDataProviderFindOptions, ErrorInfo, RestDataProviderHttpProvider, } from './src/data-interfaces.js';
15
15
  export { SqlCommand, SqlCommandWithParameters, SqlImplementation, SqlResult, } from './src/sql-command.js';
16
16
  export { FieldMetadata, FieldOptions, FieldValidator, ValueConverter, ValueListItem, // reconsider, maybe it should go to remult angular as the abstraction ?
@@ -19,15 +19,15 @@ export { RestDataProvider } from './src/data-providers/rest-data-provider.js';
19
19
  export { InMemoryDataProvider } from './src/data-providers/in-memory-database.js';
20
20
  export { WebSqlDataProvider } from './src/data-providers/web-sql-data-provider.js';
21
21
  export { SqlDatabase } from './src/data-providers/sql-database.js';
22
- export { CustomSqlFilterObject, CustomSqlFilterBuilder, dbNamesOf, dbNamesOfOptions, CustomSqlFilterBuilderFunction, EntityDbNames, } from './src/filter/filter-consumer-bridge-to-sql-request.js';
22
+ export { CustomSqlFilterBuilder, dbNamesOf, dbNamesOfOptions, CustomSqlFilterBuilderFunction, EntityDbNames, } from './src/filter/filter-consumer-bridge-to-sql-request.js';
23
23
  export { JsonDataProvider, JsonEntityStorage, } from './src/data-providers/json-data-provider.js';
24
24
  export { JsonEntityOpfsStorage } from './src/data-providers/json-entity-opfs-storage.js';
25
- export { Controller, BackendMethodOptions, BackendMethod, ProgressListener, } from './src/server-action.js';
25
+ export { Controller, BackendMethodOptions, BackendMethod, ProgressListener, ForbiddenError, } from './src/server-action.js';
26
26
  export { Allowed, Allow, Remult, withRemult, RemultContext, ApiClient, isBackend, AllowedForInstance, EventDispatcher, EventSource, UserInfo, } from './src/context.js';
27
27
  export { ExternalHttpProvider } from './src/buildRestDataProvider.js';
28
28
  export { SortSegment, Sort } from './src/sort.js';
29
29
  export { CompoundIdField } from './src/CompoundIdField.js';
30
- export { Filter, FilterConsumer, customFilterInfo, } from './src/filter/filter-interfaces.js';
30
+ export { Filter, FilterConsumer, FilterPreciseValues, } from './src/filter/filter-interfaces.js';
31
31
  export { UrlBuilder } from './urlBuilder.js';
32
32
  export { Validators, ValidationMessage, ValueValidationMessage, Validator, ValidatorWithArgs, valueValidator, createValidator, createValidatorWithArgs, createValueValidatorWithArgs, createValueValidator, } from './src/validators.js';
33
33
  export { ValueConverters } from './src/valueConverters.js';
package/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.repo = exports.SubscriptionChannel = exports.InMemoryLiveQueryStorage = exports.remult = exports.ValueConverters = exports.createValueValidator = exports.createValueValidatorWithArgs = exports.createValidatorWithArgs = exports.createValidator = exports.valueValidator = exports.Validators = exports.UrlBuilder = exports.Filter = exports.CompoundIdField = exports.Sort = exports.EventSource = exports.isBackend = exports.withRemult = exports.Remult = exports.Allow = exports.ProgressListener = exports.BackendMethod = exports.Controller = exports.JsonEntityOpfsStorage = exports.JsonDataProvider = exports.dbNamesOf = exports.CustomSqlFilterBuilder = exports.SqlDatabase = exports.WebSqlDataProvider = exports.InMemoryDataProvider = exports.RestDataProvider = exports.describeClass = exports.IdEntity = exports.Relations = exports.Fields = exports.Field = exports.getEntityRef = exports.Entity = exports.CaptionTransformer = exports.ValueListInfo = exports.getValueList = exports.ValueListFieldType = exports.getFields = exports.FieldType = exports.ControllerBase = exports.EntityBase = exports.ArrayEntityDataProvider = void 0;
3
+ exports.repo = exports.SubscriptionChannel = exports.InMemoryLiveQueryStorage = exports.remult = exports.ValueConverters = exports.createValueValidator = exports.createValueValidatorWithArgs = exports.createValidatorWithArgs = exports.createValidator = exports.valueValidator = exports.Validators = exports.UrlBuilder = exports.Filter = exports.CompoundIdField = exports.Sort = exports.EventSource = exports.isBackend = exports.withRemult = exports.Remult = exports.Allow = exports.ForbiddenError = exports.ProgressListener = exports.BackendMethod = exports.Controller = exports.JsonEntityOpfsStorage = exports.JsonDataProvider = exports.dbNamesOf = exports.CustomSqlFilterBuilder = exports.SqlDatabase = exports.WebSqlDataProvider = exports.InMemoryDataProvider = exports.RestDataProvider = exports.describeClass = exports.IdEntity = exports.Relations = exports.Fields = exports.Field = exports.getEntityRef = exports.Entity = exports.CaptionTransformer = exports.ValueListInfo = exports.getValueList = exports.ValueListFieldType = exports.getFields = exports.FieldType = exports.ControllerBase = exports.EntityBase = exports.ArrayEntityDataProvider = void 0;
4
4
  var array_entity_data_provider_js_1 = require("./src/data-providers/array-entity-data-provider.js");
5
5
  Object.defineProperty(exports, "ArrayEntityDataProvider", { enumerable: true, get: function () { return array_entity_data_provider_js_1.ArrayEntityDataProvider; } });
6
6
  var RepositoryImplementation_js_1 = require("./src/remult3/RepositoryImplementation.js");
@@ -44,6 +44,7 @@ var server_action_js_1 = require("./src/server-action.js");
44
44
  Object.defineProperty(exports, "Controller", { enumerable: true, get: function () { return server_action_js_1.Controller; } });
45
45
  Object.defineProperty(exports, "BackendMethod", { enumerable: true, get: function () { return server_action_js_1.BackendMethod; } });
46
46
  Object.defineProperty(exports, "ProgressListener", { enumerable: true, get: function () { return server_action_js_1.ProgressListener; } });
47
+ Object.defineProperty(exports, "ForbiddenError", { enumerable: true, get: function () { return server_action_js_1.ForbiddenError; } });
47
48
  var context_js_1 = require("./src/context.js");
48
49
  Object.defineProperty(exports, "Allow", { enumerable: true, get: function () { return context_js_1.Allow; } });
49
50
  Object.defineProperty(exports, "Remult", { enumerable: true, get: function () { return context_js_1.Remult; } });
@@ -0,0 +1,27 @@
1
+ import type { MigrationBuilder } from './migration-types.js';
2
+ export declare function compareMigrationSnapshot({ entities, snapshot, migrationBuilder, reporter, }: {
3
+ entities: any[];
4
+ snapshot: EntitiesSnapshot;
5
+ migrationBuilder: Required<MigrationBuilder>;
6
+ reporter: (what: string) => void;
7
+ }): Promise<{
8
+ version: number;
9
+ entities: Record<string, {
10
+ key: string;
11
+ className: string;
12
+ columns: Record<string, {
13
+ key: string;
14
+ }>;
15
+ }>;
16
+ }>;
17
+ export declare function emptySnapshot(): {
18
+ version: number;
19
+ entities: Record<string, {
20
+ key: string;
21
+ className: string;
22
+ columns: Record<string, {
23
+ key: string;
24
+ }>;
25
+ }>;
26
+ };
27
+ export type EntitiesSnapshot = ReturnType<typeof emptySnapshot>;