remult 0.25.8-exp.2 → 0.25.8-exp.4

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/graphql.js CHANGED
@@ -904,7 +904,7 @@ export function translateWhereToRestBody(fields, { where }) {
904
904
  }
905
905
  }
906
906
  if (where.OR) {
907
- result.OR = where.OR.map((where) => translateWhereToRestBody(fields, { where }));
907
+ result.OR = where.OR.map((where) => translateWhereToRestBody(fields, { where }).where);
908
908
  }
909
- return result;
909
+ return { where: result };
910
910
  }
@@ -250,8 +250,8 @@ export class RemultServerImplementation {
250
250
  console.info('[remult] ' + myRoute);
251
251
  r.route(myRoute)
252
252
  .get(this.process((c, req, res, orig) => dataApiFactory(c).httpGet(res, req, () => this.serializeContext(c))))
253
- .put(this.process(async (c, req, res, _, __, orig) => dataApiFactory(c).put(res, '', await this.coreOptions.getRequestBody(orig))))
254
- .delete(this.process(async (c, req, res, orig) => dataApiFactory(c).delete(res, '')))
253
+ .put(this.process(async (c, req, res, _, __, orig) => dataApiFactory(c).updateMany(res, req, await this.coreOptions.getRequestBody(orig))))
254
+ .delete(this.process(async (c, req, res, _, __, orig) => dataApiFactory(c).deleteMany(res, req, undefined)))
255
255
  .post(this.process(async (c, req, res, _, __, orig) => dataApiFactory(c).httpPost(res, req, await this.coreOptions.getRequestBody(orig), () => this.serializeContext(c))));
256
256
  r.route(myRoute + '/:id')
257
257
  //@ts-ignore
@@ -467,6 +467,17 @@ export class RemultServerImplementation {
467
467
  return secureBase(condition, def, item);
468
468
  };
469
469
  let apiPath = (spec.paths[this.options.rootPath + '/' + key] = {});
470
+ let itemInBody = {
471
+ requestBody: {
472
+ content: {
473
+ 'application/json': {
474
+ schema: {
475
+ $ref: '#/components/schemas/' + mutationKey,
476
+ },
477
+ },
478
+ },
479
+ },
480
+ };
470
481
  let apiPathWithId = (spec.paths[this.options.rootPath + '/' + key + '/{id}'] = {});
471
482
  //https://github.com/2fd/open-api.d.ts
472
483
  apiPath.get = secure(meta.options.allowApiRead, true, {
@@ -519,6 +530,73 @@ export class RemultServerImplementation {
519
530
  },
520
531
  },
521
532
  });
533
+ apiPath.delete = secure(meta.options.allowApiDelete, true, {
534
+ description: 'deletes row of ' +
535
+ key +
536
+ '. supports filter operators. For more info on filtering [see this article](https://remult.dev/docs/rest-api.html#filter)',
537
+ parameters: [...parameters],
538
+ responses: {
539
+ '400': {
540
+ description: 'Error: Bad Request',
541
+ content: {
542
+ 'application/json': {
543
+ schema: {
544
+ $ref: '#/components/schemas/InvalidResponse',
545
+ },
546
+ },
547
+ },
548
+ },
549
+ '200': {
550
+ description: 'returns the number of deleted rows ' + key,
551
+ content: {
552
+ 'application/json': {
553
+ schema: {
554
+ type: 'object',
555
+ properties: {
556
+ deleted: {
557
+ type: 'number',
558
+ },
559
+ },
560
+ },
561
+ },
562
+ },
563
+ },
564
+ },
565
+ });
566
+ apiPath.put = secure(meta.options.allowApiDelete, true, {
567
+ description: 'updates row of ' +
568
+ key +
569
+ '. supports filter operators. For more info on filtering [see this article](https://remult.dev/docs/rest-api.html#filter)',
570
+ parameters: [...parameters],
571
+ ...itemInBody,
572
+ responses: {
573
+ '400': {
574
+ description: 'Error: Bad Request',
575
+ content: {
576
+ 'application/json': {
577
+ schema: {
578
+ $ref: '#/components/schemas/InvalidResponse',
579
+ },
580
+ },
581
+ },
582
+ },
583
+ '200': {
584
+ description: 'returns the number of updated rows ' + key,
585
+ content: {
586
+ 'application/json': {
587
+ schema: {
588
+ type: 'object',
589
+ properties: {
590
+ updated: {
591
+ type: 'number',
592
+ },
593
+ },
594
+ },
595
+ },
596
+ },
597
+ },
598
+ },
599
+ });
522
600
  let idParameter = {
523
601
  name: 'id',
524
602
  in: 'path',
@@ -526,17 +604,6 @@ export class RemultServerImplementation {
526
604
  required: true,
527
605
  schema: { type: 'string' },
528
606
  };
529
- let itemInBody = {
530
- requestBody: {
531
- content: {
532
- 'application/json': {
533
- schema: {
534
- $ref: '#/components/schemas/' + mutationKey,
535
- },
536
- },
537
- },
538
- },
539
- };
540
607
  apiPath.post = secure(meta.options.allowApiInsert, false, {
541
608
  //"summary": "insert a " + key,
542
609
  //"description": "insert a " + key,
@@ -22,11 +22,17 @@ export class CompoundIdField {
22
22
  return Promise.resolve('');
23
23
  }
24
24
  getId(instance) {
25
+ let get = (field) => {
26
+ return instance[field.key];
27
+ };
28
+ if (typeof instance === 'function') {
29
+ get = instance;
30
+ }
25
31
  let r = '';
26
32
  this.fields.forEach((c) => {
27
33
  if (r.length > 0)
28
34
  r += ',';
29
- r += instance[c.key];
35
+ r += c.valueConverter.toJson(get(c));
30
36
  });
31
37
  return r;
32
38
  }
@@ -49,7 +55,7 @@ export class CompoundIdField {
49
55
  let val = value.toString();
50
56
  let id = val.split(',');
51
57
  this.fields.forEach((c, i) => {
52
- result[c.key] = id[i];
58
+ result[c.key] = c.valueConverter.fromJson(id[i]);
53
59
  });
54
60
  return result;
55
61
  }
@@ -23,17 +23,31 @@ export class DataApi {
23
23
  }
24
24
  async httpPost(res, req, body, serializeContext) {
25
25
  const action = req?.get('__action');
26
- if (action?.startsWith(liveQueryAction))
26
+ function validateWhereInBody() {
27
+ if (!body?.where) {
28
+ throw {
29
+ message: `POST with action ${action} must have a where clause in the body`,
30
+ httpStatusCode: 400,
31
+ };
32
+ }
33
+ }
34
+ if (action?.startsWith(liveQueryAction)) {
35
+ validateWhereInBody();
27
36
  return this.liveQuery(res, req, body, serializeContext, action.substring(liveQueryAction.length));
37
+ }
28
38
  switch (action) {
29
39
  case 'get':
40
+ validateWhereInBody();
30
41
  return this.getArray(res, req, body);
31
42
  case 'count':
43
+ validateWhereInBody();
32
44
  return this.count(res, req, body);
33
45
  case 'deleteMany':
46
+ validateWhereInBody();
34
47
  return this.deleteMany(res, req, body);
35
48
  case 'updateMany':
36
- return this.updateMany(res, req, body);
49
+ validateWhereInBody();
50
+ return this.updateManyImplementation(res, req, body);
37
51
  case 'endLiveQuery':
38
52
  await this.remult.liveQueryStorage.remove(body.id);
39
53
  res.success('ok');
@@ -50,26 +64,28 @@ export class DataApi {
50
64
  }
51
65
  await this.doOnId(response, id, async (row) => response.success(this.repository.getEntityRef(row).toApiJson()));
52
66
  }
53
- async count(response, request, filterBody) {
67
+ async count(response, request, body) {
54
68
  if (!this.repository.metadata.apiReadAllowed) {
55
69
  response.forbidden();
56
70
  return;
57
71
  }
58
72
  try {
59
73
  response.success({
60
- count: +(await this.repository.count(await this.buildWhere(request, filterBody))),
74
+ count: +(await this.repository.count(await this.buildWhere(request, body))),
61
75
  });
62
76
  }
63
77
  catch (err) {
64
78
  response.error(err, this.repository.metadata);
65
79
  }
66
80
  }
67
- async deleteMany(response, request, filterBody) {
81
+ async deleteMany(response, request, body) {
68
82
  try {
83
+ let deleted = 0;
84
+ let where = await this.buildWhere(request, body);
85
+ Filter.throwErrorIfFilterIsEmpty(where, 'deleteMany');
69
86
  return await doTransaction(this.remult, async () => {
70
- let deleted = 0;
71
87
  for await (const x of this.repository.query({
72
- where: await this.buildWhere(request, filterBody),
88
+ where,
73
89
  include: this.includeNone(),
74
90
  })) {
75
91
  await this.actualDelete(x);
@@ -82,12 +98,12 @@ export class DataApi {
82
98
  response.error(err, this.repository.metadata);
83
99
  }
84
100
  }
85
- async getArrayImpl(response, request, filterBody) {
101
+ async getArrayImpl(response, request, body) {
86
102
  let findOptions = {
87
103
  load: () => [],
88
104
  include: this.includeNone(),
89
105
  };
90
- findOptions.where = await this.buildWhere(request, filterBody);
106
+ findOptions.where = await this.buildWhere(request, body);
91
107
  if (request) {
92
108
  let sort = request.get('_sort');
93
109
  if (sort != undefined) {
@@ -146,13 +162,13 @@ export class DataApi {
146
162
  }
147
163
  return include;
148
164
  }
149
- async getArray(response, request, filterBody) {
165
+ async getArray(response, request, body) {
150
166
  if (!this.repository.metadata.apiReadAllowed) {
151
167
  response.forbidden();
152
168
  return;
153
169
  }
154
170
  try {
155
- const { r } = await this.getArrayImpl(response, request, filterBody);
171
+ const { r } = await this.getArrayImpl(response, request, body);
156
172
  response.success(r);
157
173
  }
158
174
  catch (err) {
@@ -162,13 +178,13 @@ export class DataApi {
162
178
  response.error(err, this.repository.metadata);
163
179
  }
164
180
  }
165
- async liveQuery(response, request, filterBody, serializeContext, queryChannel) {
181
+ async liveQuery(response, request, body, serializeContext, queryChannel) {
166
182
  if (!this.repository.metadata.apiReadAllowed) {
167
183
  response.forbidden();
168
184
  return;
169
185
  }
170
186
  try {
171
- const r = await this.getArrayImpl(response, request, filterBody);
187
+ const r = await this.getArrayImpl(response, request, body);
172
188
  const data = {
173
189
  requestJson: await serializeContext(),
174
190
  findOptionsJson: findOptionsToJson(r.findOptions, this.repository.metadata),
@@ -188,7 +204,7 @@ export class DataApi {
188
204
  response.error(err, this.repository.metadata);
189
205
  }
190
206
  }
191
- async buildWhere(request, filterBody) {
207
+ async buildWhere(request, body) {
192
208
  var where = [];
193
209
  if (this.repository.metadata.options.apiPrefilter) {
194
210
  if (typeof this.repository.metadata.options.apiPrefilter === 'function')
@@ -208,8 +224,8 @@ export class DataApi {
208
224
  },
209
225
  }));
210
226
  }
211
- if (filterBody)
212
- where.push(Filter.entityFilterFromJson(this.repository.metadata, filterBody));
227
+ if (body?.where)
228
+ where.push(Filter.entityFilterFromJson(this.repository.metadata, body.where));
213
229
  return { $and: where };
214
230
  }
215
231
  async doOnId(response, id, what) {
@@ -245,11 +261,23 @@ export class DataApi {
245
261
  }
246
262
  }
247
263
  async updateMany(response, request, body) {
264
+ const action = request?.get('__action');
265
+ if (action == 'emptyId') {
266
+ return this.put(response, '', body);
267
+ }
268
+ let where = await this.buildWhere(request, body);
269
+ Filter.throwErrorIfFilterIsEmpty(where, 'updateMany');
270
+ return this.updateManyImplementation(response, request, {
271
+ where: undefined,
272
+ set: body,
273
+ });
274
+ }
275
+ async updateManyImplementation(response, request, body) {
248
276
  try {
249
277
  return await doTransaction(this.remult, async () => {
250
278
  let updated = 0;
251
279
  for await (const x of this.repository.query({
252
- where: await this.buildWhere(request, body.where),
280
+ where: await this.buildWhere(request, body),
253
281
  include: this.includeNone(),
254
282
  })) {
255
283
  await this.actualUpdate(x, body.set);
@@ -120,26 +120,27 @@ export class RestEntityDataProvider {
120
120
  return run('count').then((r) => +r.count);
121
121
  }
122
122
  async deleteMany(where) {
123
- const { run } = this.buildFindRequest({ where }, true);
123
+ const { run } = this.buildFindRequest({ where }, 'delete');
124
124
  return run('deleteMany').then((r) => +r.deleted);
125
125
  }
126
126
  async updateMany(where, data) {
127
- const { run } = this.buildFindRequest({ where }, true);
128
- return run('updateMany', { set: this.toJsonOfIncludedKeys(data) }).then((r) => +r.updated);
127
+ const { run } = this.buildFindRequest({ where }, 'put');
128
+ return run('updateMany', this.toJsonOfIncludedKeys(data)).then((r) => +r.updated);
129
129
  }
130
130
  find(options) {
131
131
  let { run } = this.buildFindRequest(options);
132
132
  return run().then((x) => x.map((y) => this.translateFromJson(y)));
133
133
  }
134
134
  //@internal
135
- buildFindRequest(options, forcePost = false) {
135
+ buildFindRequest(options, method) {
136
+ if (!method)
137
+ method = 'get';
136
138
  let url = new UrlBuilder(this.url());
137
139
  let filterObject;
138
140
  if (options) {
139
141
  if (options.where) {
140
142
  filterObject = options.where.toJson(); // options.where.__applyToConsumer(new FilterConsumnerBridgeToUrlBuilder(url));
141
- if (!forcePost &&
142
- addFilterToUrlAndReturnTrueIfSuccessful(filterObject, url))
143
+ if (addFilterToUrlAndReturnTrueIfSuccessful(filterObject, url))
143
144
  filterObject = undefined;
144
145
  }
145
146
  if (options.orderBy && options.orderBy.Segments) {
@@ -173,15 +174,12 @@ export class RestEntityDataProvider {
173
174
  }
174
175
  if (action)
175
176
  u.add('__action', action);
176
- if (filterObject || forcePost) {
177
- if (!body)
178
- body = filterObject;
179
- else
180
- body = { ...body, where: filterObject };
177
+ if (filterObject) {
178
+ body = { set: body, where: filterObject };
181
179
  return this.http().post(u.url, body);
182
180
  }
183
181
  else
184
- return this.http().get(u.url);
182
+ return this.http()[method](u.url, body);
185
183
  };
186
184
  return {
187
185
  createKey: () => JSON.stringify({ url, filterObject }),
@@ -201,7 +199,8 @@ export class RestEntityDataProvider {
201
199
  }
202
200
  update(id, data) {
203
201
  return this.http()
204
- .put(this.url() + '/' + encodeURIComponent(id), this.toJsonOfIncludedKeys(data))
202
+ .put(this.url() +
203
+ (id != '' ? '/' + encodeURIComponent(id) : '?__action=emptyId'), this.toJsonOfIncludedKeys(data))
205
204
  .then((y) => this.translateFromJson(y));
206
205
  }
207
206
  toJsonOfIncludedKeys(data) {
@@ -213,8 +212,11 @@ export class RestEntityDataProvider {
213
212
  }
214
213
  return result;
215
214
  }
216
- delete(id) {
217
- return this.http().delete(this.url() + '/' + encodeURIComponent(id));
215
+ async delete(id) {
216
+ if (id == '')
217
+ await this.deleteMany(Filter.fromEntityFilter(this.entity, this.entity.idMetadata.getIdFilter(id)));
218
+ else
219
+ return this.http().delete(this.url() + '/' + encodeURIComponent(id));
218
220
  }
219
221
  insert(data) {
220
222
  return this.http()
@@ -6,6 +6,37 @@ import { getRelationFieldInfo } from '../remult3/relationInfoMember.js';
6
6
  */
7
7
  export class Filter {
8
8
  apply;
9
+ //@internal
10
+ static throwErrorIfFilterIsEmpty(where, methodName) {
11
+ if (Filter.isFilterEmpty(where)) {
12
+ throw {
13
+ message: `${methodName}: requires a filter to protect against accidental delete/update of all rows`,
14
+ httpStatusCode: 400,
15
+ };
16
+ }
17
+ }
18
+ //@internal
19
+ static isFilterEmpty(where) {
20
+ if (where.$and) {
21
+ for (const a of where.$and) {
22
+ if (!Filter.isFilterEmpty(a)) {
23
+ return false;
24
+ }
25
+ }
26
+ }
27
+ if (where.$or) {
28
+ for (const a of where.$or) {
29
+ if (Filter.isFilterEmpty(a)) {
30
+ return true;
31
+ }
32
+ }
33
+ return false;
34
+ }
35
+ if (Object.keys(where).filter((x) => !['$or', '$and'].includes(x)).length == 0) {
36
+ return true;
37
+ }
38
+ return false;
39
+ }
9
40
  static createCustom(rawFilterTranslator, key = '') {
10
41
  let rawFilterInfo = { key: key, rawFilterTranslator };
11
42
  return Object.assign((x) => {
@@ -270,6 +270,7 @@ export class RepositoryImplementation {
270
270
  }
271
271
  }
272
272
  async updateMany(where, set) {
273
+ Filter.throwErrorIfFilterIsEmpty(where, 'updateMany');
273
274
  if (this._dataProvider.isProxy) {
274
275
  return this._edp.updateMany(await this._translateWhereToFilter(where), set);
275
276
  }
@@ -636,6 +637,7 @@ export class RepositoryImplementation {
636
637
  return this._edp.count(await this._translateWhereToFilter(where));
637
638
  }
638
639
  async deleteMany(where) {
640
+ Filter.throwErrorIfFilterIsEmpty(where, 'deleteMany');
639
641
  if (this._dataProvider.isProxy) {
640
642
  return this._edp.deleteMany(await this._translateWhereToFilter(where));
641
643
  }
@@ -1184,7 +1186,7 @@ export class rowHelperImplementation extends rowHelperBase {
1184
1186
  return this.instance[y.key];
1185
1187
  };
1186
1188
  if (this.metadata.idMetadata.field instanceof CompoundIdField)
1187
- return this.metadata.idMetadata.field.fields.map(getVal).join(',');
1189
+ return this.metadata.idMetadata.field.getId(getVal);
1188
1190
  return getVal(this.metadata.idMetadata.field);
1189
1191
  }
1190
1192
  saveMoreOriginalData() {
@@ -1,16 +1,8 @@
1
1
  export {};
2
+ //p1 - should the remult api be deleteMany({id:[1,2]}) or deleteMany({where:{id:[1,2]}})
2
3
  //p1 - in this video I'll use remult to turn a frontend app to a fullstack app
3
- /*p1 - discuss using delete & put - with url query language for deleteMany and updateMany -
4
- - put & delete, similar to get
5
- - add where to count, deleteMany,updateMany,
6
- - prevent delete all and update all - must have meaningful where.
7
- - try forcing this also in typescript
8
-
9
- - protect against deleting of all rows by mistake
10
- - https://github.com/remult/remult/issues/221#issuecomment-2016519746
11
-
12
- */
13
4
  //y1 - getFields didn't work for kobi in the home component
5
+ //y1 - consider replacing all errors with error classes that extend the base Error class
14
6
  //p1 - document offline support
15
7
  //p1 - add section to Fields doc, explaining field type in db
16
8
  //p1 - add section about union type
@@ -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
@@ -1081,10 +1081,8 @@ function translateWhereToRestBody(fields, _a) {
1081
1081
  finally { if (e_7) throw e_7.error; }
1082
1082
  }
1083
1083
  if (where.OR) {
1084
- result.OR = where.OR.map(function (where) {
1085
- return translateWhereToRestBody(fields, { where: where });
1086
- });
1084
+ result.OR = where.OR.map(function (where) { return translateWhereToRestBody(fields, { where: where }).where; });
1087
1085
  }
1088
- return result;
1086
+ return { where: result };
1089
1087
  }
1090
1088
  exports.translateWhereToRestBody = translateWhereToRestBody;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "remult",
3
- "version": "0.25.8-exp.2",
3
+ "version": "0.25.8-exp.4",
4
4
  "description": "A CRUD framework for full-stack TypeScript",
5
5
  "homepage": "https://remult.dev",
6
6
  "repository": {
@@ -444,16 +444,16 @@ var RemultServerImplementation = /** @class */ (function () {
444
444
  return tslib_1.__generator(this, function (_d) {
445
445
  switch (_d.label) {
446
446
  case 0:
447
- _b = (_a = dataApiFactory(c)).put;
447
+ _b = (_a = dataApiFactory(c)).updateMany;
448
448
  _c = [res,
449
- ''];
449
+ req];
450
450
  return [4 /*yield*/, this.coreOptions.getRequestBody(orig)];
451
451
  case 1: return [2 /*return*/, _b.apply(_a, _c.concat([_d.sent()]))];
452
452
  }
453
453
  });
454
454
  }); }))
455
- .delete(this.process(function (c, req, res, orig) { return tslib_1.__awaiter(_this, void 0, void 0, function () { return tslib_1.__generator(this, function (_a) {
456
- return [2 /*return*/, dataApiFactory(c).delete(res, '')];
455
+ .delete(this.process(function (c, req, res, _, __, orig) { return tslib_1.__awaiter(_this, void 0, void 0, function () { return tslib_1.__generator(this, function (_a) {
456
+ return [2 /*return*/, dataApiFactory(c).deleteMany(res, req, undefined)];
457
457
  }); }); }))
458
458
  .post(this.process(function (c, req, res, _, __, orig) { return tslib_1.__awaiter(_this, void 0, void 0, function () {
459
459
  var _a, _b, _c;
@@ -792,6 +792,17 @@ var RemultServerImplementation = /** @class */ (function () {
792
792
  return secureBase(condition, def, item);
793
793
  };
794
794
  var apiPath = (spec.paths[this_2.options.rootPath + '/' + key] = {});
795
+ var itemInBody = {
796
+ requestBody: {
797
+ content: {
798
+ 'application/json': {
799
+ schema: {
800
+ $ref: '#/components/schemas/' + mutationKey,
801
+ },
802
+ },
803
+ },
804
+ },
805
+ };
795
806
  var apiPathWithId = (spec.paths[this_2.options.rootPath + '/' + key + '/{id}'] = {});
796
807
  //https://github.com/2fd/open-api.d.ts
797
808
  apiPath.get = secure(meta.options.allowApiRead, true, {
@@ -843,6 +854,68 @@ var RemultServerImplementation = /** @class */ (function () {
843
854
  },
844
855
  },
845
856
  });
857
+ apiPath.delete = secure(meta.options.allowApiDelete, true, {
858
+ description: 'deletes row of ' +
859
+ key +
860
+ '. supports filter operators. For more info on filtering [see this article](https://remult.dev/docs/rest-api.html#filter)',
861
+ parameters: tslib_1.__spreadArray([], tslib_1.__read(parameters), false),
862
+ responses: {
863
+ '400': {
864
+ description: 'Error: Bad Request',
865
+ content: {
866
+ 'application/json': {
867
+ schema: {
868
+ $ref: '#/components/schemas/InvalidResponse',
869
+ },
870
+ },
871
+ },
872
+ },
873
+ '200': {
874
+ description: 'returns the number of deleted rows ' + key,
875
+ content: {
876
+ 'application/json': {
877
+ schema: {
878
+ type: 'object',
879
+ properties: {
880
+ deleted: {
881
+ type: 'number',
882
+ },
883
+ },
884
+ },
885
+ },
886
+ },
887
+ },
888
+ },
889
+ });
890
+ apiPath.put = secure(meta.options.allowApiDelete, true, tslib_1.__assign(tslib_1.__assign({ description: 'updates row of ' +
891
+ key +
892
+ '. supports filter operators. For more info on filtering [see this article](https://remult.dev/docs/rest-api.html#filter)', parameters: tslib_1.__spreadArray([], tslib_1.__read(parameters), false) }, itemInBody), { responses: {
893
+ '400': {
894
+ description: 'Error: Bad Request',
895
+ content: {
896
+ 'application/json': {
897
+ schema: {
898
+ $ref: '#/components/schemas/InvalidResponse',
899
+ },
900
+ },
901
+ },
902
+ },
903
+ '200': {
904
+ description: 'returns the number of updated rows ' + key,
905
+ content: {
906
+ 'application/json': {
907
+ schema: {
908
+ type: 'object',
909
+ properties: {
910
+ updated: {
911
+ type: 'number',
912
+ },
913
+ },
914
+ },
915
+ },
916
+ },
917
+ },
918
+ } }));
846
919
  var idParameter = {
847
920
  name: 'id',
848
921
  in: 'path',
@@ -850,17 +923,6 @@ var RemultServerImplementation = /** @class */ (function () {
850
923
  required: true,
851
924
  schema: { type: 'string' },
852
925
  };
853
- var itemInBody = {
854
- requestBody: {
855
- content: {
856
- 'application/json': {
857
- schema: {
858
- $ref: '#/components/schemas/' + mutationKey,
859
- },
860
- },
861
- },
862
- },
863
- };
864
926
  apiPath.post = secure(meta.options.allowApiInsert, false, tslib_1.__assign(tslib_1.__assign({
865
927
  //"summary": "insert a " + key,
866
928
  //"description": "insert a " + key,
@@ -28,11 +28,17 @@ var CompoundIdField = /** @class */ (function () {
28
28
  return Promise.resolve('');
29
29
  };
30
30
  CompoundIdField.prototype.getId = function (instance) {
31
+ var get = function (field) {
32
+ return instance[field.key];
33
+ };
34
+ if (typeof instance === 'function') {
35
+ get = instance;
36
+ }
31
37
  var r = '';
32
38
  this.fields.forEach(function (c) {
33
39
  if (r.length > 0)
34
40
  r += ',';
35
- r += instance[c.key];
41
+ r += c.valueConverter.toJson(get(c));
36
42
  });
37
43
  return r;
38
44
  };
@@ -48,7 +54,7 @@ var CompoundIdField = /** @class */ (function () {
48
54
  var val = value.toString();
49
55
  var id = val.split(',');
50
56
  this.fields.forEach(function (c, i) {
51
- result[c.key] = id[i];
57
+ result[c.key] = c.valueConverter.fromJson(id[i]);
52
58
  });
53
59
  return result;
54
60
  };