remult 3.1.0-next.1 → 3.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/esm/index.js +1 -0
- package/esm/src/remult3/Fields.js +37 -13
- package/esm/src/standard-schema/StandardSchemaV1.js +1 -0
- package/esm/src/standard-schema/index.js +52 -0
- package/index.d.ts +1 -0
- package/index.js +4 -2
- package/package.json +1 -1
- package/src/remult3/Fields.d.ts +28 -6
- package/src/remult3/Fields.js +39 -14
- package/src/standard-schema/StandardSchemaV1.d.ts +56 -0
- package/src/standard-schema/StandardSchemaV1.js +2 -0
- package/src/standard-schema/index.d.ts +22 -0
- package/src/standard-schema/index.js +88 -0
package/esm/index.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export { ArrayEntityDataProvider } from './src/data-providers/array-entity-data-provider.js';
|
|
2
|
+
export { standardSchema } from './src/standard-schema/index.js';
|
|
2
3
|
export { EntityBase, ControllerBase, FieldType, getFields, ValueListFieldType, getValueList, ValueListInfo, } from './src/remult3/RepositoryImplementation.js';
|
|
3
4
|
import { LabelTransformer } from './src/remult3/RepositoryImplementation.js';
|
|
4
5
|
export { LabelTransformer } from './src/remult3/RepositoryImplementation.js';
|
|
@@ -84,51 +84,77 @@ export class Fields {
|
|
|
84
84
|
...options,
|
|
85
85
|
});
|
|
86
86
|
}
|
|
87
|
-
|
|
87
|
+
/**
|
|
88
|
+
* ### cuid
|
|
89
|
+
* @example
|
|
90
|
+
* ```ts
|
|
91
|
+
* import { Fields } from 'remult'
|
|
92
|
+
* import { createId } from '@paralleldrive/cuid2'
|
|
93
|
+
* Fields.defaultIdFactory = () => createId()
|
|
94
|
+
* ```
|
|
95
|
+
*
|
|
96
|
+
* ### nanoid
|
|
97
|
+
* @example
|
|
98
|
+
* ```ts
|
|
99
|
+
* import { Fields } from 'remult'
|
|
100
|
+
* import { nanoid } from 'nanoid'
|
|
101
|
+
* Fields.defaultIdFactory = () => nanoid()
|
|
102
|
+
* ```
|
|
103
|
+
*
|
|
104
|
+
*/
|
|
88
105
|
static get defaultIdFactory() {
|
|
89
|
-
return
|
|
106
|
+
return (remultStatic.defaultIdFactory ??
|
|
107
|
+
(remultStatic.defaultIdFactory = () => crypto.randomUUID()));
|
|
90
108
|
}
|
|
91
109
|
static set defaultIdFactory(value) {
|
|
92
|
-
this._defaultIdFactory = value;
|
|
93
110
|
remultStatic.defaultIdFactory = value;
|
|
94
111
|
}
|
|
95
112
|
/**
|
|
113
|
+
* ### Default
|
|
96
114
|
* Defines a field that will be used as the id of the entity.
|
|
97
115
|
* By default it will use `crypto.randomUUID` to generate the id.
|
|
98
116
|
*
|
|
99
|
-
*
|
|
100
|
-
*
|
|
101
|
-
*
|
|
102
|
-
* This needs to be
|
|
117
|
+
* ---
|
|
118
|
+
* ### Global `IdFactory`
|
|
119
|
+
* You can change the algorithm used to generate the id by setting `Fields.defaultIdFactory`
|
|
120
|
+
* globally. This code needs to be in a shared file to be accessible frontend and backend.
|
|
103
121
|
*
|
|
104
122
|
* ```ts
|
|
105
123
|
* import { createId } from '@paralleldrive/cuid2'
|
|
106
124
|
* Fields.defaultIdFactory = () => createId()
|
|
107
125
|
* ```
|
|
108
126
|
*
|
|
109
|
-
*
|
|
127
|
+
* ---
|
|
128
|
+
* ### Local `IdFactory`
|
|
129
|
+
* You can also pass an `idFactory` as an option to the `@Fields.id` to have a different value on this field.
|
|
110
130
|
* @example
|
|
111
131
|
* ```ts
|
|
112
132
|
* import { createId } from '@paralleldrive/cuid2'
|
|
113
133
|
* // import { v4 as uuid } from 'uuid'
|
|
134
|
+
* // import { nanoid } from 'nanoid'
|
|
114
135
|
*
|
|
115
136
|
* class MyEntity {
|
|
116
137
|
* \@Fields.id({
|
|
117
138
|
* idFactory: () => createId()
|
|
118
139
|
* // idFactory: () => uuid()
|
|
140
|
+
* // idFactory: () => nanoid()
|
|
119
141
|
* })
|
|
120
142
|
* id: string = '';
|
|
121
143
|
* }
|
|
122
144
|
* ```
|
|
123
145
|
*/
|
|
124
146
|
static id(options) {
|
|
125
|
-
let idFactory = options?.idFactory ?? remultStatic.defaultIdFactory;
|
|
126
147
|
return Field(() => String, {
|
|
127
148
|
allowApiUpdate: false,
|
|
128
|
-
defaultValue: () =>
|
|
149
|
+
defaultValue: () => {
|
|
150
|
+
let idFactory = options?.idFactory ?? Fields.defaultIdFactory;
|
|
151
|
+
return idFactory();
|
|
152
|
+
},
|
|
129
153
|
saving: (_, r) => {
|
|
130
|
-
if (!r.value)
|
|
154
|
+
if (!r.value) {
|
|
155
|
+
let idFactory = options?.idFactory ?? Fields.defaultIdFactory;
|
|
131
156
|
r.value = idFactory();
|
|
157
|
+
}
|
|
132
158
|
},
|
|
133
159
|
...options,
|
|
134
160
|
});
|
|
@@ -202,8 +228,6 @@ export class Fields {
|
|
|
202
228
|
return Field(() => Boolean, ...options);
|
|
203
229
|
}
|
|
204
230
|
}
|
|
205
|
-
// Initialize remultStatic.defaultIdFactory with the default value
|
|
206
|
-
remultStatic.defaultIdFactory = Fields.defaultIdFactory;
|
|
207
231
|
export class Relations {
|
|
208
232
|
/**
|
|
209
233
|
* Define a to-one relation between entities, indicating a one-to-one relationship.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Implementation of the [Standard Schema](https://standardschema.dev/) specification
|
|
3
|
+
*
|
|
4
|
+
* @usage
|
|
5
|
+
* ```ts
|
|
6
|
+
* // The schema for the entire entity
|
|
7
|
+
* const schema = standardSchema(repo(User))
|
|
8
|
+
*
|
|
9
|
+
* // The schema for a specific field
|
|
10
|
+
* const schema = standardSchema(repo(User), 'id')
|
|
11
|
+
*
|
|
12
|
+
* // The schema for multiple fields
|
|
13
|
+
* const schema = standardSchema(repo(User), 'name', 'age')
|
|
14
|
+
* ```
|
|
15
|
+
*/
|
|
16
|
+
export function standardSchema(repo, ...fields) {
|
|
17
|
+
return {
|
|
18
|
+
'~standard': {
|
|
19
|
+
version: 1,
|
|
20
|
+
vendor: 'remult',
|
|
21
|
+
async validate(value) {
|
|
22
|
+
const item = value;
|
|
23
|
+
try {
|
|
24
|
+
const error = await repo.validate(item, ...fields);
|
|
25
|
+
if (error && error.modelState) {
|
|
26
|
+
return {
|
|
27
|
+
issues: Object.entries(error.modelState).map(([key, message]) => ({
|
|
28
|
+
message: message,
|
|
29
|
+
path: [key],
|
|
30
|
+
})),
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
catch (err) {
|
|
35
|
+
if (err instanceof Error) {
|
|
36
|
+
return { issues: [{ message: err.message, path: [] }] };
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
if (fields.length > 0) {
|
|
40
|
+
const filteredItem = {};
|
|
41
|
+
for (const field of fields) {
|
|
42
|
+
if (field in item) {
|
|
43
|
+
filteredItem[field] = item[field];
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
return { value: filteredItem };
|
|
47
|
+
}
|
|
48
|
+
return { value: item };
|
|
49
|
+
},
|
|
50
|
+
},
|
|
51
|
+
};
|
|
52
|
+
}
|
package/index.d.ts
CHANGED
|
@@ -4,6 +4,7 @@ export { ArrayEntityDataProvider } from './src/data-providers/array-entity-data-
|
|
|
4
4
|
export type { ClassType } from './classType.js';
|
|
5
5
|
export { ValidateFieldEvent, MembersOnly, NumericKeys, FieldsMetadata, FieldRef, IdFieldRef, FieldsRef, EntityMetadata, EntityOrderBy, EntityFilter, FindOptions, FindOptionsBase, QueryResult, QueryOptions, UpsertOptions, Repository, GroupByOptions, GroupByResult, FindFirstOptions, ComparisonValueFilter, ValueFilter, IdFilter, ContainsStringValueFilter, EntityRef, SortSegments, Paginator, LiveQuery, LiveQueryChangeInfo, Subscribable, RefSubscriber, RefSubscriberBase, RelationOptions, ObjectMembersOnly, MembersToInclude, RepositoryRelations, EntityIdFields, ClassFieldDecorator, ClassFieldDecoratorContextStub, //n1 consider removing in ts5
|
|
6
6
|
LifecycleEvent, FieldsRefBase, FieldsRefForEntityBase, RepositoryRelationsForEntityBase, ControllerRefForControllerBase, ControllerRefBase, ControllerRef, EntityRefForEntityBase, IdMetadata, FindFirstOptionsBase, } from './src/remult3/remult3.js';
|
|
7
|
+
export { standardSchema } from './src/standard-schema/index.js';
|
|
7
8
|
export { EntityBase, ControllerBase, FieldType, getFields, ValueListFieldType, getValueList, ValueListFieldOptions, ValueListInfo, } from './src/remult3/RepositoryImplementation.js';
|
|
8
9
|
export { LabelTransformer } from './src/remult3/RepositoryImplementation.js';
|
|
9
10
|
/**
|
package/index.js
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
4
|
-
exports.SubscriptionChannel = void 0;
|
|
3
|
+
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.JsonEntityIndexedDbStorage = exports.JsonEntityOpfsStorage = exports.JsonDataProvider = exports.dbNamesOf = exports.CustomSqlFilterBuilder = exports.SqlDatabase = exports.InMemoryDataProvider = exports.RestDataProvider = exports.EntityError = exports.describeEntity = exports.describeBackendMethods = exports.describeClass = exports.IdEntity = exports.Relations = exports.Fields = exports.Field = exports.getEntityRef = exports.Entity = exports.CaptionTransformer = exports.LabelTransformer = exports.ValueListInfo = exports.getValueList = exports.ValueListFieldType = exports.getFields = exports.FieldType = exports.ControllerBase = exports.EntityBase = exports.standardSchema = exports.ArrayEntityDataProvider = void 0;
|
|
4
|
+
exports.SubscriptionChannel = exports.InMemoryLiveQueryStorage = void 0;
|
|
5
5
|
exports.repo = repo;
|
|
6
6
|
var array_entity_data_provider_js_1 = require("./src/data-providers/array-entity-data-provider.js");
|
|
7
7
|
Object.defineProperty(exports, "ArrayEntityDataProvider", { enumerable: true, get: function () { return array_entity_data_provider_js_1.ArrayEntityDataProvider; } });
|
|
8
|
+
var index_js_1 = require("./src/standard-schema/index.js");
|
|
9
|
+
Object.defineProperty(exports, "standardSchema", { enumerable: true, get: function () { return index_js_1.standardSchema; } });
|
|
8
10
|
var RepositoryImplementation_js_1 = require("./src/remult3/RepositoryImplementation.js");
|
|
9
11
|
Object.defineProperty(exports, "EntityBase", { enumerable: true, get: function () { return RepositoryImplementation_js_1.EntityBase; } });
|
|
10
12
|
Object.defineProperty(exports, "ControllerBase", { enumerable: true, get: function () { return RepositoryImplementation_js_1.ControllerBase; } });
|
package/package.json
CHANGED
package/src/remult3/Fields.d.ts
CHANGED
|
@@ -17,33 +17,55 @@ export declare class Fields {
|
|
|
17
17
|
static updatedAt<entityType = unknown>(...options: (FieldOptions<entityType, Date> | ((options: FieldOptions<entityType, Date>, remult: Remult) => void))[]): ClassFieldDecorator<entityType, Date | undefined>;
|
|
18
18
|
/** @deprecated use `@Fields.id()` instead */
|
|
19
19
|
static uuid<entityType = unknown>(...options: (FieldOptions<entityType, string> | ((options: FieldOptions<entityType, string>, remult: Remult) => void))[]): ClassFieldDecorator<entityType, string | undefined>;
|
|
20
|
-
|
|
20
|
+
/**
|
|
21
|
+
* ### cuid
|
|
22
|
+
* @example
|
|
23
|
+
* ```ts
|
|
24
|
+
* import { Fields } from 'remult'
|
|
25
|
+
* import { createId } from '@paralleldrive/cuid2'
|
|
26
|
+
* Fields.defaultIdFactory = () => createId()
|
|
27
|
+
* ```
|
|
28
|
+
*
|
|
29
|
+
* ### nanoid
|
|
30
|
+
* @example
|
|
31
|
+
* ```ts
|
|
32
|
+
* import { Fields } from 'remult'
|
|
33
|
+
* import { nanoid } from 'nanoid'
|
|
34
|
+
* Fields.defaultIdFactory = () => nanoid()
|
|
35
|
+
* ```
|
|
36
|
+
*
|
|
37
|
+
*/
|
|
21
38
|
static get defaultIdFactory(): () => string;
|
|
22
39
|
static set defaultIdFactory(value: () => string);
|
|
23
40
|
/**
|
|
41
|
+
* ### Default
|
|
24
42
|
* Defines a field that will be used as the id of the entity.
|
|
25
43
|
* By default it will use `crypto.randomUUID` to generate the id.
|
|
26
44
|
*
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
*
|
|
30
|
-
* This needs to be
|
|
45
|
+
* ---
|
|
46
|
+
* ### Global `IdFactory`
|
|
47
|
+
* You can change the algorithm used to generate the id by setting `Fields.defaultIdFactory`
|
|
48
|
+
* globally. This code needs to be in a shared file to be accessible frontend and backend.
|
|
31
49
|
*
|
|
32
50
|
* ```ts
|
|
33
51
|
* import { createId } from '@paralleldrive/cuid2'
|
|
34
52
|
* Fields.defaultIdFactory = () => createId()
|
|
35
53
|
* ```
|
|
36
54
|
*
|
|
37
|
-
*
|
|
55
|
+
* ---
|
|
56
|
+
* ### Local `IdFactory`
|
|
57
|
+
* You can also pass an `idFactory` as an option to the `@Fields.id` to have a different value on this field.
|
|
38
58
|
* @example
|
|
39
59
|
* ```ts
|
|
40
60
|
* import { createId } from '@paralleldrive/cuid2'
|
|
41
61
|
* // import { v4 as uuid } from 'uuid'
|
|
62
|
+
* // import { nanoid } from 'nanoid'
|
|
42
63
|
*
|
|
43
64
|
* class MyEntity {
|
|
44
65
|
* \@Fields.id({
|
|
45
66
|
* idFactory: () => createId()
|
|
46
67
|
* // idFactory: () => uuid()
|
|
68
|
+
* // idFactory: () => nanoid()
|
|
47
69
|
* })
|
|
48
70
|
* id: string = '';
|
|
49
71
|
* }
|
package/src/remult3/Fields.js
CHANGED
|
@@ -135,51 +135,79 @@ var Fields = /** @class */ (function () {
|
|
|
135
135
|
return Fields.id(tslib_1.__assign({ idFactory: function () { return crypto.randomUUID(); } }, options));
|
|
136
136
|
};
|
|
137
137
|
Object.defineProperty(Fields, "defaultIdFactory", {
|
|
138
|
+
/**
|
|
139
|
+
* ### cuid
|
|
140
|
+
* @example
|
|
141
|
+
* ```ts
|
|
142
|
+
* import { Fields } from 'remult'
|
|
143
|
+
* import { createId } from '@paralleldrive/cuid2'
|
|
144
|
+
* Fields.defaultIdFactory = () => createId()
|
|
145
|
+
* ```
|
|
146
|
+
*
|
|
147
|
+
* ### nanoid
|
|
148
|
+
* @example
|
|
149
|
+
* ```ts
|
|
150
|
+
* import { Fields } from 'remult'
|
|
151
|
+
* import { nanoid } from 'nanoid'
|
|
152
|
+
* Fields.defaultIdFactory = () => nanoid()
|
|
153
|
+
* ```
|
|
154
|
+
*
|
|
155
|
+
*/
|
|
138
156
|
get: function () {
|
|
139
|
-
|
|
157
|
+
var _a;
|
|
158
|
+
return ((_a = remult_static_js_1.remultStatic.defaultIdFactory) !== null && _a !== void 0 ? _a : (remult_static_js_1.remultStatic.defaultIdFactory = function () { return crypto.randomUUID(); }));
|
|
140
159
|
},
|
|
141
160
|
set: function (value) {
|
|
142
|
-
this._defaultIdFactory = value;
|
|
143
161
|
remult_static_js_1.remultStatic.defaultIdFactory = value;
|
|
144
162
|
},
|
|
145
163
|
enumerable: false,
|
|
146
164
|
configurable: true
|
|
147
165
|
});
|
|
148
166
|
/**
|
|
167
|
+
* ### Default
|
|
149
168
|
* Defines a field that will be used as the id of the entity.
|
|
150
169
|
* By default it will use `crypto.randomUUID` to generate the id.
|
|
151
170
|
*
|
|
152
|
-
*
|
|
153
|
-
*
|
|
154
|
-
*
|
|
155
|
-
* This needs to be
|
|
171
|
+
* ---
|
|
172
|
+
* ### Global `IdFactory`
|
|
173
|
+
* You can change the algorithm used to generate the id by setting `Fields.defaultIdFactory`
|
|
174
|
+
* globally. This code needs to be in a shared file to be accessible frontend and backend.
|
|
156
175
|
*
|
|
157
176
|
* ```ts
|
|
158
177
|
* import { createId } from '@paralleldrive/cuid2'
|
|
159
178
|
* Fields.defaultIdFactory = () => createId()
|
|
160
179
|
* ```
|
|
161
180
|
*
|
|
162
|
-
*
|
|
181
|
+
* ---
|
|
182
|
+
* ### Local `IdFactory`
|
|
183
|
+
* You can also pass an `idFactory` as an option to the `@Fields.id` to have a different value on this field.
|
|
163
184
|
* @example
|
|
164
185
|
* ```ts
|
|
165
186
|
* import { createId } from '@paralleldrive/cuid2'
|
|
166
187
|
* // import { v4 as uuid } from 'uuid'
|
|
188
|
+
* // import { nanoid } from 'nanoid'
|
|
167
189
|
*
|
|
168
190
|
* class MyEntity {
|
|
169
191
|
* \@Fields.id({
|
|
170
192
|
* idFactory: () => createId()
|
|
171
193
|
* // idFactory: () => uuid()
|
|
194
|
+
* // idFactory: () => nanoid()
|
|
172
195
|
* })
|
|
173
196
|
* id: string = '';
|
|
174
197
|
* }
|
|
175
198
|
* ```
|
|
176
199
|
*/
|
|
177
200
|
Fields.id = function (options) {
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
201
|
+
return Field(function () { return String; }, tslib_1.__assign({ allowApiUpdate: false, defaultValue: function () {
|
|
202
|
+
var _a;
|
|
203
|
+
var idFactory = (_a = options === null || options === void 0 ? void 0 : options.idFactory) !== null && _a !== void 0 ? _a : Fields.defaultIdFactory;
|
|
204
|
+
return idFactory();
|
|
205
|
+
}, saving: function (_, r) {
|
|
206
|
+
var _a;
|
|
207
|
+
if (!r.value) {
|
|
208
|
+
var idFactory = (_a = options === null || options === void 0 ? void 0 : options.idFactory) !== null && _a !== void 0 ? _a : Fields.defaultIdFactory;
|
|
182
209
|
r.value = idFactory();
|
|
210
|
+
}
|
|
183
211
|
} }, options));
|
|
184
212
|
};
|
|
185
213
|
/**
|
|
@@ -276,12 +304,9 @@ var Fields = /** @class */ (function () {
|
|
|
276
304
|
}
|
|
277
305
|
return Field.apply(void 0, tslib_1.__spreadArray([function () { return Boolean; }], tslib_1.__read(options), false));
|
|
278
306
|
};
|
|
279
|
-
Fields._defaultIdFactory = function () { return crypto.randomUUID(); };
|
|
280
307
|
return Fields;
|
|
281
308
|
}());
|
|
282
309
|
exports.Fields = Fields;
|
|
283
|
-
// Initialize remultStatic.defaultIdFactory with the default value
|
|
284
|
-
remult_static_js_1.remultStatic.defaultIdFactory = Fields.defaultIdFactory;
|
|
285
310
|
var Relations = /** @class */ (function () {
|
|
286
311
|
function Relations() {
|
|
287
312
|
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/** The Standard Schema interface. */
|
|
2
|
+
export interface StandardSchemaV1<Input = unknown, Output = Input> {
|
|
3
|
+
/** The Standard Schema properties. */
|
|
4
|
+
readonly '~standard': StandardSchemaV1.Props<Input, Output>;
|
|
5
|
+
}
|
|
6
|
+
export declare namespace StandardSchemaV1 {
|
|
7
|
+
/** The Standard Schema properties interface. */
|
|
8
|
+
export interface Props<Input = unknown, Output = Input> {
|
|
9
|
+
/** The version number of the standard. */
|
|
10
|
+
readonly version: 1;
|
|
11
|
+
/** The vendor name of the schema library. */
|
|
12
|
+
readonly vendor: string;
|
|
13
|
+
/** Validates unknown input values. */
|
|
14
|
+
readonly validate: (value: unknown) => Result<Output> | Promise<Result<Output>>;
|
|
15
|
+
/** Inferred types associated with the schema. */
|
|
16
|
+
readonly types?: Types<Input, Output> | undefined;
|
|
17
|
+
}
|
|
18
|
+
/** The result interface of the validate function. */
|
|
19
|
+
export type Result<Output> = SuccessResult<Output> | FailureResult;
|
|
20
|
+
/** The result interface if validation succeeds. */
|
|
21
|
+
export interface SuccessResult<Output> {
|
|
22
|
+
/** The typed output value. */
|
|
23
|
+
readonly value: Output;
|
|
24
|
+
/** The non-existent issues. */
|
|
25
|
+
readonly issues?: undefined;
|
|
26
|
+
}
|
|
27
|
+
/** The result interface if validation fails. */
|
|
28
|
+
export interface FailureResult {
|
|
29
|
+
/** The issues of failed validation. */
|
|
30
|
+
readonly issues: ReadonlyArray<Issue>;
|
|
31
|
+
}
|
|
32
|
+
/** The issue interface of the failure output. */
|
|
33
|
+
export interface Issue {
|
|
34
|
+
/** The error message of the issue. */
|
|
35
|
+
readonly message: string;
|
|
36
|
+
/** The path of the issue, if any. */
|
|
37
|
+
readonly path?: ReadonlyArray<PropertyKey | PathSegment> | undefined;
|
|
38
|
+
}
|
|
39
|
+
/** The path segment interface of the issue. */
|
|
40
|
+
export interface PathSegment {
|
|
41
|
+
/** The key representing a path segment. */
|
|
42
|
+
readonly key: PropertyKey;
|
|
43
|
+
}
|
|
44
|
+
/** The Standard Schema types interface. */
|
|
45
|
+
export interface Types<Input = unknown, Output = Input> {
|
|
46
|
+
/** The input type of the schema. */
|
|
47
|
+
readonly input: Input;
|
|
48
|
+
/** The output type of the schema. */
|
|
49
|
+
readonly output: Output;
|
|
50
|
+
}
|
|
51
|
+
/** Infers the input type of a Standard Schema. */
|
|
52
|
+
export type InferInput<Schema extends StandardSchemaV1> = NonNullable<Schema['~standard']['types']>['input'];
|
|
53
|
+
/** Infers the output type of a Standard Schema. */
|
|
54
|
+
export type InferOutput<Schema extends StandardSchemaV1> = NonNullable<Schema['~standard']['types']>['output'];
|
|
55
|
+
export {};
|
|
56
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { MembersOnly, Repository } from '../../index.js';
|
|
2
|
+
import type { StandardSchemaV1 } from './StandardSchemaV1.js';
|
|
3
|
+
type OutputType<entityType, fields extends string[]> = fields extends [] ? Partial<entityType> : Pick<entityType, Extract<keyof entityType, fields[number]>>;
|
|
4
|
+
interface RemultEntitySchema<entityType, fields extends string[] = []> extends StandardSchemaV1<Partial<entityType>, OutputType<entityType, fields>> {
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* Implementation of the [Standard Schema](https://standardschema.dev/) specification
|
|
8
|
+
*
|
|
9
|
+
* @usage
|
|
10
|
+
* ```ts
|
|
11
|
+
* // The schema for the entire entity
|
|
12
|
+
* const schema = standardSchema(repo(User))
|
|
13
|
+
*
|
|
14
|
+
* // The schema for a specific field
|
|
15
|
+
* const schema = standardSchema(repo(User), 'id')
|
|
16
|
+
*
|
|
17
|
+
* // The schema for multiple fields
|
|
18
|
+
* const schema = standardSchema(repo(User), 'name', 'age')
|
|
19
|
+
* ```
|
|
20
|
+
*/
|
|
21
|
+
export declare function standardSchema<entityType, fieldsType extends Extract<keyof MembersOnly<entityType>, string>[] = []>(repo: Repository<entityType>, ...fields: fieldsType): RemultEntitySchema<entityType, fieldsType>;
|
|
22
|
+
export {};
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.standardSchema = standardSchema;
|
|
4
|
+
var tslib_1 = require("tslib");
|
|
5
|
+
/**
|
|
6
|
+
* Implementation of the [Standard Schema](https://standardschema.dev/) specification
|
|
7
|
+
*
|
|
8
|
+
* @usage
|
|
9
|
+
* ```ts
|
|
10
|
+
* // The schema for the entire entity
|
|
11
|
+
* const schema = standardSchema(repo(User))
|
|
12
|
+
*
|
|
13
|
+
* // The schema for a specific field
|
|
14
|
+
* const schema = standardSchema(repo(User), 'id')
|
|
15
|
+
*
|
|
16
|
+
* // The schema for multiple fields
|
|
17
|
+
* const schema = standardSchema(repo(User), 'name', 'age')
|
|
18
|
+
* ```
|
|
19
|
+
*/
|
|
20
|
+
function standardSchema(repo) {
|
|
21
|
+
var fields = [];
|
|
22
|
+
for (var _i = 1; _i < arguments.length; _i++) {
|
|
23
|
+
fields[_i - 1] = arguments[_i];
|
|
24
|
+
}
|
|
25
|
+
return {
|
|
26
|
+
'~standard': {
|
|
27
|
+
version: 1,
|
|
28
|
+
vendor: 'remult',
|
|
29
|
+
validate: function (value) {
|
|
30
|
+
return tslib_1.__awaiter(this, void 0, void 0, function () {
|
|
31
|
+
var item, error, err_1, filteredItem, fields_1, fields_1_1, field;
|
|
32
|
+
var e_1, _a;
|
|
33
|
+
return tslib_1.__generator(this, function (_b) {
|
|
34
|
+
switch (_b.label) {
|
|
35
|
+
case 0:
|
|
36
|
+
item = value;
|
|
37
|
+
_b.label = 1;
|
|
38
|
+
case 1:
|
|
39
|
+
_b.trys.push([1, 3, , 4]);
|
|
40
|
+
return [4 /*yield*/, repo.validate.apply(repo, tslib_1.__spreadArray([item], tslib_1.__read(fields), false))];
|
|
41
|
+
case 2:
|
|
42
|
+
error = _b.sent();
|
|
43
|
+
if (error && error.modelState) {
|
|
44
|
+
return [2 /*return*/, {
|
|
45
|
+
issues: Object.entries(error.modelState).map(function (_a) {
|
|
46
|
+
var _b = tslib_1.__read(_a, 2), key = _b[0], message = _b[1];
|
|
47
|
+
return ({
|
|
48
|
+
message: message,
|
|
49
|
+
path: [key],
|
|
50
|
+
});
|
|
51
|
+
}),
|
|
52
|
+
}];
|
|
53
|
+
}
|
|
54
|
+
return [3 /*break*/, 4];
|
|
55
|
+
case 3:
|
|
56
|
+
err_1 = _b.sent();
|
|
57
|
+
if (err_1 instanceof Error) {
|
|
58
|
+
return [2 /*return*/, { issues: [{ message: err_1.message, path: [] }] }];
|
|
59
|
+
}
|
|
60
|
+
return [3 /*break*/, 4];
|
|
61
|
+
case 4:
|
|
62
|
+
if (fields.length > 0) {
|
|
63
|
+
filteredItem = {};
|
|
64
|
+
try {
|
|
65
|
+
for (fields_1 = tslib_1.__values(fields), fields_1_1 = fields_1.next(); !fields_1_1.done; fields_1_1 = fields_1.next()) {
|
|
66
|
+
field = fields_1_1.value;
|
|
67
|
+
if (field in item) {
|
|
68
|
+
filteredItem[field] = item[field];
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
catch (e_1_1) { e_1 = { error: e_1_1 }; }
|
|
73
|
+
finally {
|
|
74
|
+
try {
|
|
75
|
+
if (fields_1_1 && !fields_1_1.done && (_a = fields_1.return)) _a.call(fields_1);
|
|
76
|
+
}
|
|
77
|
+
finally { if (e_1) throw e_1.error; }
|
|
78
|
+
}
|
|
79
|
+
return [2 /*return*/, { value: filteredItem }];
|
|
80
|
+
}
|
|
81
|
+
return [2 /*return*/, { value: item }];
|
|
82
|
+
}
|
|
83
|
+
});
|
|
84
|
+
});
|
|
85
|
+
},
|
|
86
|
+
},
|
|
87
|
+
};
|
|
88
|
+
}
|