remult 0.24.2-exp.0 → 0.25.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 (46) hide show
  1. package/README.md +4 -4
  2. package/esm/index.js +2 -2
  3. package/esm/remult-mongo.js +1 -1
  4. package/esm/remult-sql-js.js +113 -0
  5. package/esm/src/data-providers/array-entity-data-provider.js +1 -1
  6. package/esm/src/data-providers/json-data-provider.js +1 -1
  7. package/esm/src/data-providers/{ipfs-data-provider.js → json-entity-opfs-storage.js} +1 -1
  8. package/esm/src/data-providers/sql-database.js +10 -6
  9. package/esm/src/filter/filter-consumer-bridge-to-sql-request.js +4 -5
  10. package/esm/src/remult-proxy.js +4 -0
  11. package/esm/src/remult3/Fields.js +22 -0
  12. package/esm/src/remult3/RepositoryImplementation.js +109 -60
  13. package/esm/src/remult3/entity.js +2 -2
  14. package/esm/src/remult3/getEntityRef.js +5 -5
  15. package/esm/src/remult3/relationInfoMember.js +1 -1
  16. package/esm/src/remult3/remult3.js +6 -7
  17. package/esm/src/server-action-info.js +1 -1
  18. package/esm/src/server-action.js +1 -1
  19. package/esm/src/validators.js +120 -28
  20. package/index.d.ts +3 -3
  21. package/index.js +8 -3
  22. package/package.json +6 -1
  23. package/remult-mongo.js +1 -1
  24. package/remult-sql-js.d.ts +18 -0
  25. package/remult-sql-js.js +211 -0
  26. package/src/column-interfaces.d.ts +12 -6
  27. package/src/data-providers/array-entity-data-provider.js +9 -10
  28. package/src/data-providers/json-data-provider.js +1 -1
  29. package/src/data-providers/{ipfs-data-provider.d.ts → json-entity-opfs-storage.d.ts} +1 -1
  30. package/src/data-providers/{ipfs-data-provider.js → json-entity-opfs-storage.js} +7 -7
  31. package/src/data-providers/sql-database.js +14 -6
  32. package/src/filter/filter-consumer-bridge-to-sql-request.js +4 -5
  33. package/src/remult-proxy.js +11 -0
  34. package/src/remult3/Fields.js +22 -0
  35. package/src/remult3/RepositoryImplementation.d.ts +6 -6
  36. package/src/remult3/RepositoryImplementation.js +136 -78
  37. package/src/remult3/entity.js +2 -2
  38. package/src/remult3/getEntityRef.js +5 -5
  39. package/src/remult3/relationInfoMember.js +1 -1
  40. package/src/remult3/remult3.d.ts +33 -0
  41. package/src/remult3/remult3.js +6 -7
  42. package/src/server-action-info.js +1 -1
  43. package/src/server-action.js +1 -1
  44. package/src/sql-command.d.ts +1 -0
  45. package/src/validators.d.ts +41 -9
  46. package/src/validators.js +183 -54
package/index.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import type { ClassType } from './classType.js';
2
2
  import type { DataProvider } from './src/data-interfaces.js';
3
3
  export type { ClassType } from './classType.js';
4
- export { MembersOnly, FieldsMetadata, FieldRef, IdFieldRef, FieldsRef, EntityMetadata, EntityOrderBy, EntityFilter, FindOptions, FindOptionsBase, QueryResult, QueryOptions, Repository, FindFirstOptions, ComparisonValueFilter, ValueFilter, IdFilter, ContainsStringValueFilter, EntityRef, SortSegments, Paginator, LiveQuery, LiveQueryChangeInfo, Subscribable, RefSubscriber, RefSubscriberBase, RelationOptions, ObjectMembersOnly, MembersToInclude, RepositoryRelations, EntityIdFields, ClassFieldDecorator, ClassFieldDecoratorContextStub, //n1 consider removing in ts5
4
+ export { ValidateFieldEvent, MembersOnly, FieldsMetadata, FieldRef, IdFieldRef, FieldsRef, EntityMetadata, EntityOrderBy, EntityFilter, FindOptions, FindOptionsBase, QueryResult, QueryOptions, Repository, FindFirstOptions, ComparisonValueFilter, ValueFilter, IdFilter, ContainsStringValueFilter, EntityRef, SortSegments, Paginator, LiveQuery, LiveQueryChangeInfo, Subscribable, RefSubscriber, RefSubscriberBase, RelationOptions, ObjectMembersOnly, MembersToInclude, RepositoryRelations, EntityIdFields, ClassFieldDecorator, ClassFieldDecoratorContextStub, //n1 consider removing in ts5
5
5
  LifecycleEvent, FieldsRefBase, FieldsRefForEntityBase, RepositoryRelationsForEntityBase, ControllerRefForControllerBase, ControllerRefBase, ControllerRef, EntityRefForEntityBase, IdMetadata, FindFirstOptionsBase, } from './src/remult3/remult3.js';
6
6
  export { EntityBase, ControllerBase, FieldType, getFields, ValueListFieldType, getValueList, ValueListFieldOptions, ValueListInfo, CaptionTransformer, } from './src/remult3/RepositoryImplementation.js';
7
7
  export { Entity } from './src/remult3/entity.js';
@@ -20,7 +20,7 @@ export { WebSqlDataProvider } from './src/data-providers/web-sql-data-provider.j
20
20
  export { SqlDatabase } from './src/data-providers/sql-database.js';
21
21
  export { CustomSqlFilterObject, CustomSqlFilterBuilder, dbNamesOf, CustomSqlFilterBuilderFunction, EntityDbNames, } from './src/filter/filter-consumer-bridge-to-sql-request.js';
22
22
  export { JsonDataProvider, JsonEntityStorage, } from './src/data-providers/json-data-provider.js';
23
- export { IpfsEntityFileStorage } from './src/data-providers/ipfs-data-provider.js';
23
+ export { JsonEntityOpfsStorage } from './src/data-providers/json-entity-opfs-storage.js';
24
24
  export { Controller, BackendMethodOptions, BackendMethod, ProgressListener, } from './src/server-action.js';
25
25
  export { Allowed, Allow, Remult, withRemult, RemultContext, ApiClient, isBackend, AllowedForInstance, EventDispatcher, EventSource, UserInfo, } from './src/context.js';
26
26
  export { ExternalHttpProvider } from './src/buildRestDataProvider.js';
@@ -28,7 +28,7 @@ export { SortSegment, Sort } from './src/sort.js';
28
28
  export { CompoundIdField } from './src/CompoundIdField.js';
29
29
  export { Filter, FilterConsumer, customFilterInfo, } from './src/filter/filter-interfaces.js';
30
30
  export { UrlBuilder } from './urlBuilder.js';
31
- export { Validators } from './src/validators.js';
31
+ export { Validators, ValidationMessage, ValueValidationMessage, Validator, ValidatorWithArgs, valueValidator, createValidator, createValidatorWithArgs, createValueValidatorWithArgs, createValueValidator, } from './src/validators.js';
32
32
  export { ValueConverters } from './src/valueConverters.js';
33
33
  export { remult } from './src/remult-proxy.js';
34
34
  export { SubscriptionServer, LiveQueryStorage, StoredQuery, InMemoryLiveQueryStorage, } from './src/live-query/SubscriptionServer.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.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.IpfsEntityFileStorage = 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 = 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.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 = void 0;
4
4
  var RepositoryImplementation_js_1 = require("./src/remult3/RepositoryImplementation.js");
5
5
  Object.defineProperty(exports, "EntityBase", { enumerable: true, get: function () { return RepositoryImplementation_js_1.EntityBase; } });
6
6
  Object.defineProperty(exports, "ControllerBase", { enumerable: true, get: function () { return RepositoryImplementation_js_1.ControllerBase; } });
@@ -35,8 +35,8 @@ Object.defineProperty(exports, "CustomSqlFilterBuilder", { enumerable: true, get
35
35
  Object.defineProperty(exports, "dbNamesOf", { enumerable: true, get: function () { return filter_consumer_bridge_to_sql_request_js_1.dbNamesOf; } });
36
36
  var json_data_provider_js_1 = require("./src/data-providers/json-data-provider.js"); //V
37
37
  Object.defineProperty(exports, "JsonDataProvider", { enumerable: true, get: function () { return json_data_provider_js_1.JsonDataProvider; } });
38
- var ipfs_data_provider_js_1 = require("./src/data-providers/ipfs-data-provider.js");
39
- Object.defineProperty(exports, "IpfsEntityFileStorage", { enumerable: true, get: function () { return ipfs_data_provider_js_1.IpfsEntityFileStorage; } });
38
+ var json_entity_opfs_storage_js_1 = require("./src/data-providers/json-entity-opfs-storage.js");
39
+ Object.defineProperty(exports, "JsonEntityOpfsStorage", { enumerable: true, get: function () { return json_entity_opfs_storage_js_1.JsonEntityOpfsStorage; } });
40
40
  //export * from './src/data-api'; //reconsider if to make internal
41
41
  var server_action_js_1 = require("./src/server-action.js");
42
42
  Object.defineProperty(exports, "Controller", { enumerable: true, get: function () { return server_action_js_1.Controller; } });
@@ -58,6 +58,11 @@ var urlBuilder_js_1 = require("./urlBuilder.js");
58
58
  Object.defineProperty(exports, "UrlBuilder", { enumerable: true, get: function () { return urlBuilder_js_1.UrlBuilder; } });
59
59
  var validators_js_1 = require("./src/validators.js");
60
60
  Object.defineProperty(exports, "Validators", { enumerable: true, get: function () { return validators_js_1.Validators; } });
61
+ Object.defineProperty(exports, "valueValidator", { enumerable: true, get: function () { return validators_js_1.valueValidator; } });
62
+ Object.defineProperty(exports, "createValidator", { enumerable: true, get: function () { return validators_js_1.createValidator; } });
63
+ Object.defineProperty(exports, "createValidatorWithArgs", { enumerable: true, get: function () { return validators_js_1.createValidatorWithArgs; } });
64
+ Object.defineProperty(exports, "createValueValidatorWithArgs", { enumerable: true, get: function () { return validators_js_1.createValueValidatorWithArgs; } });
65
+ Object.defineProperty(exports, "createValueValidator", { enumerable: true, get: function () { return validators_js_1.createValueValidator; } });
61
66
  var valueConverters_js_1 = require("./src/valueConverters.js");
62
67
  Object.defineProperty(exports, "ValueConverters", { enumerable: true, get: function () { return valueConverters_js_1.ValueConverters; } });
63
68
  var remult_proxy_js_1 = require("./src/remult-proxy.js");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "remult",
3
- "version": "0.24.2-exp.0",
3
+ "version": "0.25.0",
4
4
  "description": "A CRUD framework for full-stack TypeScript",
5
5
  "homepage": "https://remult.dev",
6
6
  "repository": {
@@ -91,6 +91,11 @@
91
91
  "import": "./esm/remult-mongo.js",
92
92
  "types": "./remult-mongo.d.ts"
93
93
  },
94
+ "./remult-sql-js": {
95
+ "require": "./remult-sql-js.js",
96
+ "import": "./esm/remult-sql-js.js",
97
+ "types": "./remult-sql-js.d.ts"
98
+ },
94
99
  "./ably": {
95
100
  "require": "./ably.js",
96
101
  "import": "./esm/ably.js",
package/remult-mongo.js CHANGED
@@ -256,7 +256,7 @@ var MongoEntityDataProvider = /** @class */ (function () {
256
256
  f_1 = _e.value;
257
257
  if (!f_1.dbReadOnly && !f_1.isServerExpression) {
258
258
  if (keys.includes(f_1.key)) {
259
- newR[f_1.key] = f_1.valueConverter.toDb(data[f_1.key]);
259
+ newR[f_1.key] = toDb(f_1, data[f_1.key]);
260
260
  }
261
261
  }
262
262
  }
@@ -0,0 +1,18 @@
1
+ import type { EntityMetadata } from './src/remult3/remult3.js';
2
+ import type { SqlCommand, SqlImplementation } from './src/sql-command.js';
3
+ import type { Database } from 'sql.js';
4
+ export declare class SqlJsDataProvider implements SqlImplementation {
5
+ private db;
6
+ constructor(db: Promise<Database>);
7
+ getLimitSqlSyntax(limit: number, offset: number): string;
8
+ afterMutation?: VoidFunction;
9
+ createCommand(): SqlCommand;
10
+ transaction(action: (sql: SqlImplementation) => Promise<void>): Promise<void>;
11
+ entityIsUsedForTheFirstTime(entity: EntityMetadata): Promise<void>;
12
+ ensureSchema(entities: EntityMetadata<any>[]): Promise<void>;
13
+ dropTable(entity: EntityMetadata): Promise<void>;
14
+ private addColumnSqlSyntax;
15
+ createTable(entity: EntityMetadata<any>): Promise<void>;
16
+ supportsJsonColumnType?: boolean;
17
+ wrapIdentifier?(name: string): string;
18
+ }
@@ -0,0 +1,211 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SqlJsDataProvider = void 0;
4
+ var tslib_1 = require("tslib");
5
+ var sql_database_js_1 = require("./src/data-providers/sql-database.js");
6
+ var filter_consumer_bridge_to_sql_request_js_1 = require("./src/filter/filter-consumer-bridge-to-sql-request.js");
7
+ var RepositoryImplementation_js_1 = require("./src/remult3/RepositoryImplementation.js");
8
+ var SqlJsDataProvider = /** @class */ (function () {
9
+ function SqlJsDataProvider(db) {
10
+ this.db = db;
11
+ }
12
+ SqlJsDataProvider.prototype.getLimitSqlSyntax = function (limit, offset) {
13
+ return ' limit ' + limit + ' offset ' + offset;
14
+ };
15
+ SqlJsDataProvider.prototype.createCommand = function () {
16
+ return new SqlJsCommand(this.db);
17
+ };
18
+ SqlJsDataProvider.prototype.transaction = function (action) {
19
+ throw new Error('Method not implemented.');
20
+ };
21
+ SqlJsDataProvider.prototype.entityIsUsedForTheFirstTime = function (entity) {
22
+ return tslib_1.__awaiter(this, void 0, void 0, function () {
23
+ return tslib_1.__generator(this, function (_a) {
24
+ switch (_a.label) {
25
+ case 0: return [4 /*yield*/, this.createTable(entity)];
26
+ case 1:
27
+ _a.sent();
28
+ return [2 /*return*/];
29
+ }
30
+ });
31
+ });
32
+ };
33
+ SqlJsDataProvider.prototype.ensureSchema = function (entities) {
34
+ return tslib_1.__awaiter(this, void 0, void 0, function () {
35
+ var entities_1, entities_1_1, entity, e_1_1;
36
+ var e_1, _a;
37
+ return tslib_1.__generator(this, function (_b) {
38
+ switch (_b.label) {
39
+ case 0:
40
+ _b.trys.push([0, 5, 6, 7]);
41
+ entities_1 = tslib_1.__values(entities), entities_1_1 = entities_1.next();
42
+ _b.label = 1;
43
+ case 1:
44
+ if (!!entities_1_1.done) return [3 /*break*/, 4];
45
+ entity = entities_1_1.value;
46
+ return [4 /*yield*/, this.createTable(entity)];
47
+ case 2:
48
+ _b.sent();
49
+ _b.label = 3;
50
+ case 3:
51
+ entities_1_1 = entities_1.next();
52
+ return [3 /*break*/, 1];
53
+ case 4: return [3 /*break*/, 7];
54
+ case 5:
55
+ e_1_1 = _b.sent();
56
+ e_1 = { error: e_1_1 };
57
+ return [3 /*break*/, 7];
58
+ case 6:
59
+ try {
60
+ if (entities_1_1 && !entities_1_1.done && (_a = entities_1.return)) _a.call(entities_1);
61
+ }
62
+ finally { if (e_1) throw e_1.error; }
63
+ return [7 /*endfinally*/];
64
+ case 7: return [2 /*return*/];
65
+ }
66
+ });
67
+ });
68
+ };
69
+ SqlJsDataProvider.prototype.dropTable = function (entity) {
70
+ return tslib_1.__awaiter(this, void 0, void 0, function () {
71
+ var e, sql;
72
+ return tslib_1.__generator(this, function (_a) {
73
+ switch (_a.label) {
74
+ case 0: return [4 /*yield*/, (0, filter_consumer_bridge_to_sql_request_js_1.dbNamesOf)(entity)];
75
+ case 1:
76
+ e = _a.sent();
77
+ sql = 'drop table if exists ' + e.$entityName;
78
+ if (sql_database_js_1.SqlDatabase.LogToConsole)
79
+ console.info(sql);
80
+ return [4 /*yield*/, this.createCommand().execute(sql)];
81
+ case 2:
82
+ _a.sent();
83
+ return [2 /*return*/];
84
+ }
85
+ });
86
+ });
87
+ };
88
+ SqlJsDataProvider.prototype.addColumnSqlSyntax = function (x, dbName) {
89
+ var result = dbName;
90
+ var nullNumber = x.allowNull ? '' : ' default 0 not null';
91
+ if (x.valueType == Date)
92
+ result += ' integer';
93
+ else if (x.valueType == Boolean)
94
+ result += ' integer ' + nullNumber;
95
+ else if (x.valueType == Number) {
96
+ if (!x.valueConverter.fieldTypeInDb)
97
+ result += ' real ' + nullNumber;
98
+ else
99
+ result += ' ' + x.valueConverter.fieldTypeInDb + ' ' + nullNumber;
100
+ }
101
+ else
102
+ result += ' text' + (x.allowNull ? ' ' : " default '' not null ");
103
+ return result;
104
+ };
105
+ SqlJsDataProvider.prototype.createTable = function (entity) {
106
+ return tslib_1.__awaiter(this, void 0, void 0, function () {
107
+ var result, e, _a, _b, x, sql;
108
+ var e_2, _c;
109
+ return tslib_1.__generator(this, function (_d) {
110
+ switch (_d.label) {
111
+ case 0:
112
+ result = '';
113
+ return [4 /*yield*/, (0, filter_consumer_bridge_to_sql_request_js_1.dbNamesOf)(entity)];
114
+ case 1:
115
+ e = _d.sent();
116
+ try {
117
+ for (_a = tslib_1.__values(entity.fields), _b = _a.next(); !_b.done; _b = _a.next()) {
118
+ x = _b.value;
119
+ if (!(0, filter_consumer_bridge_to_sql_request_js_1.isDbReadonly)(x, e) || (0, RepositoryImplementation_js_1.isAutoIncrement)(x)) {
120
+ if (result.length != 0)
121
+ result += ',';
122
+ result += '\r\n ';
123
+ if ((0, RepositoryImplementation_js_1.isAutoIncrement)(x)) {
124
+ if (x.key != entity.idMetadata.field.key)
125
+ throw 'in web sql, autoincrement is only allowed for primary key';
126
+ result += e.$dbNameOf(x) + ' integer primary key autoincrement';
127
+ }
128
+ else {
129
+ result += this.addColumnSqlSyntax(x, e.$dbNameOf(x));
130
+ if (x.key == entity.idMetadata.field.key) {
131
+ result += ' primary key';
132
+ }
133
+ }
134
+ }
135
+ }
136
+ }
137
+ catch (e_2_1) { e_2 = { error: e_2_1 }; }
138
+ finally {
139
+ try {
140
+ if (_b && !_b.done && (_c = _a.return)) _c.call(_a);
141
+ }
142
+ finally { if (e_2) throw e_2.error; }
143
+ }
144
+ sql = 'create table if not exists ' + e.$entityName + ' (' + result + '\r\n)';
145
+ if (sql_database_js_1.SqlDatabase.LogToConsole)
146
+ console.log(sql);
147
+ return [4 /*yield*/, this.createCommand().execute(sql)];
148
+ case 2:
149
+ _d.sent();
150
+ return [2 /*return*/];
151
+ }
152
+ });
153
+ });
154
+ };
155
+ SqlJsDataProvider.prototype.wrapIdentifier = function (name) {
156
+ return name;
157
+ };
158
+ return SqlJsDataProvider;
159
+ }());
160
+ exports.SqlJsDataProvider = SqlJsDataProvider;
161
+ var SqlJsCommand = /** @class */ (function () {
162
+ function SqlJsCommand(db) {
163
+ this.db = db;
164
+ this.values = {};
165
+ this.i = 0;
166
+ }
167
+ SqlJsCommand.prototype.execute = function (sql) {
168
+ return tslib_1.__awaiter(this, void 0, void 0, function () {
169
+ var _a, _b;
170
+ return tslib_1.__generator(this, function (_c) {
171
+ switch (_c.label) {
172
+ case 0:
173
+ if (!(this.i == 0)) return [3 /*break*/, 2];
174
+ _a = SqlJsSqlResult.bind;
175
+ return [4 /*yield*/, this.db];
176
+ case 1: return [2 /*return*/, new (_a.apply(SqlJsSqlResult, [void 0, (_c.sent()).exec(sql)]))()];
177
+ case 2:
178
+ _b = SqlJsSqlResult.bind;
179
+ return [4 /*yield*/, this.db];
180
+ case 3: return [2 /*return*/, new (_b.apply(SqlJsSqlResult, [void 0, (_c.sent()).exec(sql, this.values)]))()];
181
+ }
182
+ });
183
+ });
184
+ };
185
+ SqlJsCommand.prototype.addParameterAndReturnSqlToken = function (val) {
186
+ if (val instanceof Date)
187
+ val = val.valueOf();
188
+ var key = ':' + ++this.i;
189
+ this.values[key] = val;
190
+ return key;
191
+ };
192
+ return SqlJsCommand;
193
+ }());
194
+ var SqlJsSqlResult = /** @class */ (function () {
195
+ function SqlJsSqlResult(result) {
196
+ var _a, _b;
197
+ this.result = result;
198
+ this.rows =
199
+ (_b = (_a = result[0]) === null || _a === void 0 ? void 0 : _a.values.map(function (row) {
200
+ return row.reduce(function (prev, curr, i) {
201
+ var _a;
202
+ return (tslib_1.__assign(tslib_1.__assign({}, prev), (_a = {}, _a[result[0].columns[i]] = curr, _a)));
203
+ }, {});
204
+ })) !== null && _b !== void 0 ? _b : [];
205
+ }
206
+ SqlJsSqlResult.prototype.getColumnKeyInResultForIndexInSelect = function (index) {
207
+ var _a;
208
+ return (_a = this.result[0]) === null || _a === void 0 ? void 0 : _a.columns[index];
209
+ };
210
+ return SqlJsSqlResult;
211
+ }());
@@ -1,6 +1,6 @@
1
1
  import type { ClassType } from '../classType.js';
2
2
  import type { AllowedForInstance } from './context.js';
3
- import type { EntityMetadata, FieldRef, LifecycleEvent } from './remult3/remult3.js';
3
+ import type { EntityMetadata, FieldRef, LifecycleEvent, ValidateFieldEvent } from './remult3/remult3.js';
4
4
  export interface FieldOptions<entityType = any, valueType = any> {
5
5
  /** A human readable name for the field. Can be used to achieve a consistent caption for a field throughout the app
6
6
  * @example
@@ -9,6 +9,8 @@ export interface FieldOptions<entityType = any, valueType = any> {
9
9
  caption?: string;
10
10
  /** If it can store null in the database */
11
11
  allowNull?: boolean;
12
+ /** If a value is required */
13
+ required?: boolean;
12
14
  /** If this field data is included in the api.
13
15
  * @see [allowed](http://remult.dev/docs/allowed.html)*/
14
16
  includeInApi?: AllowedForInstance<entityType>;
@@ -20,6 +22,10 @@ export interface FieldOptions<entityType = any, valueType = any> {
20
22
  * @Fields.string({
21
23
  * validate: Validators.required
22
24
  * })
25
+ * * @example
26
+ * @Fields.string<Task>({
27
+ * validate: task=>task.title.length>3 || "Too Short"
28
+ * })
23
29
  * @example
24
30
  * @Fields.string<Task>({
25
31
  * validate: task=>{
@@ -29,13 +35,13 @@ export interface FieldOptions<entityType = any, valueType = any> {
29
35
  * })
30
36
  * @example
31
37
  * @Fields.string({
32
- * validate: (_, fieldRef)=>{
33
- * if (fieldRef.value.length<3)
34
- * fieldRef.error = "Too Short";
38
+ * validate: (_, fieldValidationEvent)=>{
39
+ * if (fieldValidationEvent.value.length < 3)
40
+ * fieldValidationEvent.error = "Too Short";
35
41
  * }
36
42
  * })
37
43
  */
38
- validate?: ((entity: entityType, fieldRef: FieldRef<entityType, valueType>) => any | Promise<any>) | ((entity: entityType, fieldRef: FieldRef<entityType, valueType>) => any | Promise<any>)[];
44
+ validate?: FieldValidator<entityType, valueType> | FieldValidator<entityType, valueType>[];
39
45
  /** Will be fired before this field is saved to the server/database */
40
46
  saving?: (entity: entityType, fieldRef: FieldRef<entityType, valueType>, e: LifecycleEvent<entityType>) => any | Promise<any>;
41
47
  /** An expression that will determine this fields value on the backend and be provided to the front end*/
@@ -170,7 +176,7 @@ export interface ValueConverter<valueType> {
170
176
  readonly fieldTypeInDb?: string;
171
177
  readonly inputType?: string;
172
178
  }
173
- export declare type FieldValidator<entityType = any, valueType = any> = (entity: entityType, fieldRef: FieldRef<entityType, valueType>) => void | Promise<void>;
179
+ export declare type FieldValidator<entityType = any, valueType = any> = (entity: entityType, event: ValidateFieldEvent<entityType, valueType>) => boolean | string | void | undefined | Promise<boolean | string | void | undefined>;
174
180
  export declare type ValueOrExpression<valueType> = valueType | (() => valueType);
175
181
  export declare function valueOrExpressionToValue<valueType>(f: ValueOrExpression<valueType>): valueType;
176
182
  export interface ValueListItem {
@@ -259,23 +259,22 @@ var ArrayEntityDataProvider = /** @class */ (function () {
259
259
  });
260
260
  };
261
261
  ArrayEntityDataProvider.prototype.insert = function (data) {
262
- var _a;
263
262
  return tslib_1.__awaiter(this, void 0, void 0, function () {
264
- var names, j, idf, _b, _c, row;
265
- var e_6, _d;
266
- return tslib_1.__generator(this, function (_e) {
267
- switch (_e.label) {
263
+ var names, j, idf, _a, _b, row;
264
+ var e_6, _c;
265
+ return tslib_1.__generator(this, function (_d) {
266
+ switch (_d.label) {
268
267
  case 0: return [4 /*yield*/, this.init()];
269
268
  case 1:
270
- names = _e.sent();
269
+ names = _d.sent();
271
270
  j = this.translateToJson(data, names);
272
271
  idf = this.entity.idMetadata.field;
273
272
  if (!(idf instanceof CompoundIdField_js_1.CompoundIdField)) {
274
- if (((_a = idf.options.valueConverter) === null || _a === void 0 ? void 0 : _a.fieldTypeInDb) === 'autoincrement') {
273
+ if (idf.valueConverter.fieldTypeInDb === 'autoincrement') {
275
274
  j[idf.key] = 1;
276
275
  try {
277
- for (_b = tslib_1.__values(this.rows), _c = _b.next(); !_c.done; _c = _b.next()) {
278
- row = _c.value;
276
+ for (_a = tslib_1.__values(this.rows), _b = _a.next(); !_b.done; _b = _a.next()) {
277
+ row = _b.value;
279
278
  if (row[idf.key] >= j[idf.key])
280
279
  j[idf.key] = row[idf.key] + 1;
281
280
  }
@@ -283,7 +282,7 @@ var ArrayEntityDataProvider = /** @class */ (function () {
283
282
  catch (e_6_1) { e_6 = { error: e_6_1 }; }
284
283
  finally {
285
284
  try {
286
- if (_c && !_c.done && (_d = _b.return)) _d.call(_b);
285
+ if (_b && !_b.done && (_c = _a.return)) _c.call(_a);
287
286
  }
288
287
  finally { if (e_6) throw e_6.error; }
289
288
  }
@@ -39,7 +39,7 @@ var JsonEntityDataProvider = /** @class */ (function () {
39
39
  switch (_a.label) {
40
40
  case 0:
41
41
  data = [];
42
- return [4 /*yield*/, this.entity.options.dbName];
42
+ return [4 /*yield*/, this.entity.dbName];
43
43
  case 1:
44
44
  dbName = _a.sent();
45
45
  return [4 /*yield*/, this.helper.getItem(dbName)];
@@ -1,5 +1,5 @@
1
1
  import type { JsonEntityStorage } from './json-data-provider.js';
2
- export declare class IpfsEntityFileStorage implements JsonEntityStorage {
2
+ export declare class JsonEntityOpfsStorage implements JsonEntityStorage {
3
3
  getItem(entityDbName: string): Promise<string>;
4
4
  setItem(entityDbName: string, json: string): Promise<void>;
5
5
  }
@@ -1,11 +1,11 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.IpfsEntityFileStorage = void 0;
3
+ exports.JsonEntityOpfsStorage = void 0;
4
4
  var tslib_1 = require("tslib");
5
- var IpfsEntityFileStorage = /** @class */ (function () {
6
- function IpfsEntityFileStorage() {
5
+ var JsonEntityOpfsStorage = /** @class */ (function () {
6
+ function JsonEntityOpfsStorage() {
7
7
  }
8
- IpfsEntityFileStorage.prototype.getItem = function (entityDbName) {
8
+ JsonEntityOpfsStorage.prototype.getItem = function (entityDbName) {
9
9
  return tslib_1.__awaiter(this, void 0, void 0, function () {
10
10
  var _a, opfsFile, readable;
11
11
  return tslib_1.__generator(this, function (_b) {
@@ -31,7 +31,7 @@ var IpfsEntityFileStorage = /** @class */ (function () {
31
31
  });
32
32
  });
33
33
  };
34
- IpfsEntityFileStorage.prototype.setItem = function (entityDbName, json) {
34
+ JsonEntityOpfsStorage.prototype.setItem = function (entityDbName, json) {
35
35
  return tslib_1.__awaiter(this, void 0, void 0, function () {
36
36
  var opfsFile, writable;
37
37
  return tslib_1.__generator(this, function (_a) {
@@ -55,6 +55,6 @@ var IpfsEntityFileStorage = /** @class */ (function () {
55
55
  });
56
56
  });
57
57
  };
58
- return IpfsEntityFileStorage;
58
+ return JsonEntityOpfsStorage;
59
59
  }());
60
- exports.IpfsEntityFileStorage = IpfsEntityFileStorage;
60
+ exports.JsonEntityOpfsStorage = JsonEntityOpfsStorage;
@@ -504,6 +504,8 @@ var ActualSQLServerDataProvider = /** @class */ (function () {
504
504
  _d = this.buildSelect(e), colKeys = _d.colKeys, select = _d.select;
505
505
  statement += ' returning ' + select;
506
506
  return [2 /*return*/, r.execute(statement).then(function (sqlResult) {
507
+ var _a, _b;
508
+ (_b = (_a = _this.sql._getSourceSql()).afterMutation) === null || _b === void 0 ? void 0 : _b.call(_a);
507
509
  return _this.buildResultRow(colKeys, sqlResult.rows[0], sqlResult);
508
510
  })];
509
511
  }
@@ -513,6 +515,7 @@ var ActualSQLServerDataProvider = /** @class */ (function () {
513
515
  ActualSQLServerDataProvider.prototype.delete = function (id) {
514
516
  return tslib_1.__awaiter(this, void 0, void 0, function () {
515
517
  var e, r, f, statement, _a;
518
+ var _this = this;
516
519
  return tslib_1.__generator(this, function (_b) {
517
520
  switch (_b.label) {
518
521
  case 0: return [4 /*yield*/, this.init()];
@@ -526,7 +529,10 @@ var ActualSQLServerDataProvider = /** @class */ (function () {
526
529
  return [4 /*yield*/, f.resolveWhere()];
527
530
  case 2:
528
531
  statement = _a + _b.sent();
529
- return [2 /*return*/, r.execute(statement).then(function () { })];
532
+ return [2 /*return*/, r.execute(statement).then(function () {
533
+ var _a, _b;
534
+ (_b = (_a = _this.sql._getSourceSql()).afterMutation) === null || _b === void 0 ? void 0 : _b.call(_a);
535
+ })];
530
536
  }
531
537
  });
532
538
  });
@@ -575,9 +581,11 @@ var ActualSQLServerDataProvider = /** @class */ (function () {
575
581
  statement = "insert into ".concat(e.$entityName, " (").concat(cols, ") values (").concat(vals, ")");
576
582
  _c = this.buildSelect(e), colKeys = _c.colKeys, select = _c.select;
577
583
  statement += ' returning ' + select;
578
- return [4 /*yield*/, r
579
- .execute(statement)
580
- .then(function (sql) { return _this.buildResultRow(colKeys, sql.rows[0], sql); })];
584
+ return [4 /*yield*/, r.execute(statement).then(function (sql) {
585
+ var _a, _b;
586
+ (_b = (_a = _this.sql._getSourceSql()).afterMutation) === null || _b === void 0 ? void 0 : _b.call(_a);
587
+ return _this.buildResultRow(colKeys, sql.rows[0], sql);
588
+ })];
581
589
  case 2: return [2 /*return*/, _e.sent()];
582
590
  }
583
591
  });
@@ -623,12 +631,12 @@ function bulkInsert(array, db) {
623
631
  items = array.slice(i, i + chunkSize);
624
632
  c = db.createCommand();
625
633
  _b = 'insert into ';
626
- return [4 /*yield*/, items[0]._.metadata.options.dbName];
634
+ return [4 /*yield*/, items[0]._.metadata.dbName];
627
635
  case 1:
628
636
  _c = _b +
629
637
  (_d.sent()) +
630
638
  ' (';
631
- return [4 /*yield*/, Promise.all(items[0]._.metadata.fields.toArray().map(function (f) { return f.options.dbName; }))];
639
+ return [4 /*yield*/, Promise.all(items[0]._.metadata.fields.toArray().map(function (f) { return f.dbName; }))];
632
640
  case 2:
633
641
  sql = _c +
634
642
  (_d.sent()).join(',') +
@@ -260,8 +260,7 @@ exports.CustomSqlFilterBuilder = CustomSqlFilterBuilder;
260
260
  function isDbReadonly(field, dbNames) {
261
261
  return (field.dbReadOnly ||
262
262
  field.isServerExpression ||
263
- (field.options.sqlExpression &&
264
- field.options.dbName != dbNames.$dbNameOf(field)));
263
+ (field.options.sqlExpression && field.dbName != dbNames.$dbNameOf(field)));
265
264
  }
266
265
  exports.isDbReadonly = isDbReadonly;
267
266
  function dbNamesOf(repo, wrapIdentifier) {
@@ -334,7 +333,7 @@ function entityDbName(metadata, wrapIdentifier) {
334
333
  if (!(typeof metadata.options.sqlExpression === 'function')) return [3 /*break*/, 3];
335
334
  return [4 /*yield*/, metadata.options.sqlExpression(metadata)];
336
335
  case 2: return [2 /*return*/, _a.sent()];
337
- case 3: return [2 /*return*/, wrapIdentifier(metadata.options.dbName)];
336
+ case 3: return [2 /*return*/, wrapIdentifier(metadata.dbName)];
338
337
  }
339
338
  });
340
339
  });
@@ -360,7 +359,7 @@ function fieldDbName(f, meta, wrapIdentifier) {
360
359
  _a.label = 3;
361
360
  case 3:
362
361
  if (!result)
363
- return [2 /*return*/, f.options.dbName];
362
+ return [2 /*return*/, f.dbName];
364
363
  return [2 /*return*/, result];
365
364
  case 4:
366
365
  rel = (0, relationInfoMember_js_1.getRelationInfo)(f.options);
@@ -371,7 +370,7 @@ function fieldDbName(f, meta, wrapIdentifier) {
371
370
  if (fInfo)
372
371
  return [2 /*return*/, fieldDbName(fInfo, meta, wrapIdentifier)];
373
372
  }
374
- return [2 /*return*/, wrapIdentifier(f.options.dbName)];
373
+ return [2 /*return*/, wrapIdentifier(f.dbName)];
375
374
  case 5: return [7 /*endfinally*/];
376
375
  case 6: return [2 /*return*/];
377
376
  }
@@ -122,6 +122,17 @@ var RemultProxy = /** @class */ (function () {
122
122
  .repo.apply(_b, tslib_1.__spreadArray([], tslib_1.__read(args), false)))
123
123
  .findFirst.apply(_a, tslib_1.__spreadArray([], tslib_1.__read(args2), false));
124
124
  },
125
+ _a.findOne = function () {
126
+ var _a, _b;
127
+ var args2 = [];
128
+ for (var _i = 0; _i < arguments.length; _i++) {
129
+ args2[_i] = arguments[_i];
130
+ }
131
+ return (_a = (_b = self
132
+ .remultFactory())
133
+ .repo.apply(_b, tslib_1.__spreadArray([], tslib_1.__read(args), false)))
134
+ .findOne.apply(_a, tslib_1.__spreadArray([], tslib_1.__read(args2), false));
135
+ },
125
136
  _a.findId = function (a, b) {
126
137
  var _a;
127
138
  return (_a = self
@@ -7,6 +7,7 @@ var uuid_1 = require("uuid");
7
7
  var valueConverters_js_1 = require("../valueConverters.js");
8
8
  var RepositoryImplementation_js_1 = require("./RepositoryImplementation.js");
9
9
  var relationInfoMember_js_1 = require("./relationInfoMember.js");
10
+ var validators_js_1 = require("../validators.js");
10
11
  var Fields = /** @class */ (function () {
11
12
  function Fields() {
12
13
  }
@@ -260,6 +261,12 @@ function Field(valueType) {
260
261
  var key = typeof context === 'string' ? context : context.name.toString();
261
262
  var factory = function (remult) {
262
263
  var r = (0, RepositoryImplementation_js_1.buildOptions)(options, remult);
264
+ if (r.required) {
265
+ r.validate = addValidator(r.validate, validators_js_1.Validators.required);
266
+ }
267
+ if (r.maxLength) {
268
+ r.validate = addValidator(r.validate, validators_js_1.Validators.maxLength(r.maxLength));
269
+ }
263
270
  if (!r.valueType && valueType) {
264
271
  r.valueType = valueType();
265
272
  }
@@ -305,3 +312,18 @@ function checkTarget(target) {
305
312
  throw new Error("Set the 'experimentalDecorators:true' option in your 'tsconfig' or 'jsconfig' (target undefined)");
306
313
  }
307
314
  exports.checkTarget = checkTarget;
315
+ function addValidator(validators, newValidator, atStart) {
316
+ if (atStart === void 0) { atStart = false; }
317
+ if (!newValidator)
318
+ return;
319
+ var newValidators = Array.isArray(newValidator)
320
+ ? newValidator
321
+ : [newValidator];
322
+ var validatorsArray = Array.isArray(validators)
323
+ ? validators
324
+ : validators
325
+ ? [validators]
326
+ : [];
327
+ return atStart
328
+ ? tslib_1.__spreadArray(tslib_1.__spreadArray([], tslib_1.__read(newValidators), false), tslib_1.__read(validatorsArray), false) : tslib_1.__spreadArray(tslib_1.__spreadArray([], tslib_1.__read(validatorsArray), false), tslib_1.__read(newValidators), false);
329
+ }