@opra/common 0.28.1 → 0.29.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 (49) hide show
  1. package/browser.js +200 -100
  2. package/cjs/document/data-type/complex-type-class.js +36 -13
  3. package/cjs/document/factory/api-document-factory.js +26 -3
  4. package/cjs/document/factory/type-document-factory.js +6 -3
  5. package/cjs/document/index.js +1 -1
  6. package/cjs/document/resource/collection-class.js +31 -27
  7. package/cjs/document/resource/collection-decorator.js +61 -33
  8. package/cjs/document/resource/{operation-decorator.js → crud-operation-decorator.js} +3 -2
  9. package/cjs/document/resource/crud-operation.js +49 -0
  10. package/cjs/document/resource/crud-resource.js +2 -2
  11. package/cjs/document/resource/endpoint.js +11 -3
  12. package/cjs/document/resource/singleton-class.js +20 -15
  13. package/cjs/document/resource/storage-decorator.js +10 -10
  14. package/esm/document/data-type/complex-type-class.js +36 -13
  15. package/esm/document/factory/api-document-factory.js +26 -3
  16. package/esm/document/factory/type-document-factory.js +6 -3
  17. package/esm/document/index.js +1 -1
  18. package/esm/document/resource/collection-class.js +31 -27
  19. package/esm/document/resource/collection-decorator.js +54 -26
  20. package/esm/document/resource/{operation-decorator.js → crud-operation-decorator.js} +3 -2
  21. package/esm/document/resource/crud-operation.js +44 -0
  22. package/esm/document/resource/crud-resource.js +2 -2
  23. package/esm/document/resource/endpoint.js +11 -3
  24. package/esm/document/resource/singleton-class.js +20 -15
  25. package/esm/document/resource/storage-decorator.js +7 -7
  26. package/package.json +3 -2
  27. package/types/document/data-type/complex-type-class.d.ts +1 -1
  28. package/types/document/data-type/complex-type.d.ts +7 -3
  29. package/types/document/data-type/data-type.d.ts +3 -0
  30. package/types/document/data-type/field-class.d.ts +0 -2
  31. package/types/document/index.d.ts +1 -1
  32. package/types/document/resource/collection-class.d.ts +0 -9
  33. package/types/document/resource/collection-decorator.d.ts +12 -0
  34. package/types/document/resource/crud-operation-decorator.d.ts +6 -0
  35. package/types/document/resource/{operation.d.ts → crud-operation.d.ts} +12 -4
  36. package/types/document/resource/crud-resource.d.ts +3 -3
  37. package/types/document/resource/endpoint.d.ts +1 -1
  38. package/types/document/resource/resource-decorator.d.ts +3 -2
  39. package/types/document/resource/resource.d.ts +2 -2
  40. package/types/document/resource/singleton-class.d.ts +5 -5
  41. package/types/document/resource/singleton-decorator.d.ts +6 -0
  42. package/types/document/resource/storage-class.d.ts +4 -4
  43. package/types/schema/data-type/complex-type.interface.d.ts +1 -1
  44. package/types/schema/resource/collection.interface.d.ts +7 -7
  45. package/types/schema/resource/endpoint.interface.d.ts +2 -1
  46. package/types/schema/resource/singleton.interface.d.ts +0 -2
  47. package/cjs/document/resource/operation.js +0 -25
  48. package/esm/document/resource/operation.js +0 -20
  49. package/types/document/resource/operation-decorator.d.ts +0 -6
@@ -16,16 +16,18 @@ class SingletonClass extends crud_resource_js_1.CrudResource {
16
16
  endpoint.defineParameter('include', { type: 'string', isArray: true, isBuiltin: true });
17
17
  endpoint.decodeInput = this.type.generateCodec('decode', {
18
18
  partial: true,
19
- pick: endpoint.inputPickFields,
20
- omit: endpoint.inputOmitFields,
21
- operation: 'write'
19
+ pick: endpoint.options.inputPickFields,
20
+ omit: endpoint.options.inputOmitFields,
21
+ operation: 'write',
22
+ overwriteFields: endpoint.inputOverwriteFields
22
23
  });
23
24
  endpoint.returnType = this.type;
24
25
  endpoint.encodeReturning = endpoint.returnType.generateCodec('encode', {
25
26
  partial: true,
26
- pick: endpoint.outputPickFields,
27
- omit: endpoint.outputOmitFields,
28
- operation: 'read'
27
+ pick: endpoint.options.outputPickFields,
28
+ omit: endpoint.options.outputOmitFields,
29
+ operation: 'read',
30
+ overwriteFields: endpoint.outputOverwriteFields
29
31
  });
30
32
  }
31
33
  // ------------------
@@ -37,9 +39,10 @@ class SingletonClass extends crud_resource_js_1.CrudResource {
37
39
  endpoint.returnType = this.type;
38
40
  endpoint.encodeReturning = endpoint.returnType.generateCodec('encode', {
39
41
  partial: true,
40
- pick: endpoint.outputPickFields,
41
- omit: endpoint.outputOmitFields,
42
- operation: 'read'
42
+ pick: endpoint.options.outputPickFields,
43
+ omit: endpoint.options.outputOmitFields,
44
+ operation: 'read',
45
+ overwriteFields: endpoint.outputOverwriteFields
43
46
  });
44
47
  }
45
48
  // ------------------
@@ -49,16 +52,18 @@ class SingletonClass extends crud_resource_js_1.CrudResource {
49
52
  endpoint.defineParameter('omit', { type: 'string', isArray: true, isBuiltin: true });
50
53
  endpoint.defineParameter('include', { type: 'string', isArray: true, isBuiltin: true });
51
54
  endpoint.decodeInput = this.type.generateCodec('decode', {
52
- pick: endpoint.inputPickFields,
53
- omit: endpoint.inputOmitFields,
54
- operation: 'write'
55
+ pick: endpoint.options.inputPickFields,
56
+ omit: endpoint.options.inputOmitFields,
57
+ operation: 'write',
58
+ overwriteFields: endpoint.inputOverwriteFields
55
59
  });
56
60
  endpoint.returnType = this.type;
57
61
  endpoint.encodeReturning = endpoint.returnType.generateCodec('encode', {
58
62
  partial: true,
59
- pick: endpoint.outputPickFields,
60
- omit: endpoint.outputOmitFields,
61
- operation: 'read'
63
+ pick: endpoint.options.outputPickFields,
64
+ omit: endpoint.options.outputOmitFields,
65
+ operation: 'read',
66
+ overwriteFields: endpoint.outputOverwriteFields
62
67
  });
63
68
  }
64
69
  }
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.StorageDecorator = void 0;
4
4
  const index_js_1 = require("../../schema/index.js");
5
5
  const action_decorator_js_1 = require("./action-decorator.js");
6
- const operation_decorator_js_1 = require("./operation-decorator.js");
6
+ const crud_operation_decorator_js_1 = require("./crud-operation-decorator.js");
7
7
  const resource_decorator_js_1 = require("./resource-decorator.js");
8
8
  const operationProperties = ['delete', 'get', 'post'];
9
9
  function StorageDecorator(options) {
@@ -25,39 +25,39 @@ Object.assign(StorageDecorator, resource_decorator_js_1.ResourceDecorator);
25
25
  StorageDecorator.Action = Action;
26
26
  function Delete(options) {
27
27
  const list = [];
28
- return (0, operation_decorator_js_1.createOperationDecorator)('delete', options, list);
28
+ return (0, crud_operation_decorator_js_1.createOperationDecorator)('delete', options, list);
29
29
  }
30
30
  StorageDecorator.Delete = Delete;
31
31
  function Get(options) {
32
32
  const list = [];
33
- return (0, operation_decorator_js_1.createOperationDecorator)('get', options, list);
33
+ return (0, crud_operation_decorator_js_1.createOperationDecorator)('get', options, list);
34
34
  }
35
35
  StorageDecorator.Get = Get;
36
36
  function Post(options) {
37
37
  const list = [];
38
- const decorator = (0, operation_decorator_js_1.createOperationDecorator)('post', options, list);
38
+ const decorator = (0, crud_operation_decorator_js_1.createOperationDecorator)('post', options, list);
39
39
  decorator.MaxFields = (amount) => {
40
- list.push(operationMeta => operationMeta.maxFields = amount);
40
+ list.push(operationMeta => operationMeta.options.maxFields = amount);
41
41
  return decorator;
42
42
  };
43
43
  decorator.MaxFieldSize = (amount) => {
44
- list.push(operationMeta => operationMeta.maxFieldsSize = amount);
44
+ list.push(operationMeta => operationMeta.options.maxFieldsSize = amount);
45
45
  return decorator;
46
46
  };
47
47
  decorator.MaxFiles = (amount) => {
48
- list.push(operationMeta => operationMeta.maxFiles = amount);
48
+ list.push(operationMeta => operationMeta.options.maxFiles = amount);
49
49
  return decorator;
50
50
  };
51
51
  decorator.MaxFileSize = (sizeInBytes) => {
52
- list.push(operationMeta => operationMeta.maxFileSize = sizeInBytes);
52
+ list.push(operationMeta => operationMeta.options.maxFileSize = sizeInBytes);
53
53
  return decorator;
54
54
  };
55
55
  decorator.MaxTotalFileSize = (sizeInBytes) => {
56
- list.push(operationMeta => operationMeta.maxTotalFileSize = sizeInBytes);
56
+ list.push(operationMeta => operationMeta.options.maxTotalFileSize = sizeInBytes);
57
57
  return decorator;
58
58
  };
59
59
  decorator.MinFileSize = (sizeInBytes) => {
60
- list.push(operationMeta => operationMeta.minFileSize = sizeInBytes);
60
+ list.push(operationMeta => operationMeta.options.minFileSize = sizeInBytes);
61
61
  return decorator;
62
62
  };
63
63
  return decorator;
@@ -11,6 +11,7 @@ export class ComplexTypeClass extends DataType {
11
11
  constructor(document, init) {
12
12
  super(document, init);
13
13
  this.kind = OpraSchema.ComplexType.Kind;
14
+ this.fields = new ResponsiveMap();
14
15
  const own = this.own = {};
15
16
  own.ctor = init.ctor;
16
17
  if (init.base) {
@@ -29,7 +30,6 @@ export class ComplexTypeClass extends DataType {
29
30
  this.additionalFields = true;
30
31
  else if (this.base?.additionalFields === 'error' && !this.additionalFields)
31
32
  this.additionalFields = 'error';
32
- this.fields = new ResponsiveMap();
33
33
  if (this.base) {
34
34
  if (this.base.fields)
35
35
  for (const [k, el] of this.base.fields.entries()) {
@@ -130,7 +130,11 @@ export class ComplexTypeClass extends DataType {
130
130
  base: this.base ?
131
131
  (this.base.name ? this.base.name : this.base.exportSchema(options)) : undefined,
132
132
  abstract: this.abstract,
133
- additionalFields: this.own.additionalFields
133
+ additionalFields: this.own.additionalFields instanceof DataType
134
+ ? (this.own.additionalFields.name
135
+ ? this.own.additionalFields.name
136
+ : this.own.additionalFields.exportSchema(options))
137
+ : this.own.additionalFields
134
138
  }));
135
139
  if (this.own.fields.size) {
136
140
  const fields = out.fields = {};
@@ -154,9 +158,12 @@ export class ComplexTypeClass extends DataType {
154
158
  }
155
159
  generateCodec(codec, options) {
156
160
  const schema = this._generateCodecSchema(codec, options);
161
+ const additionalFields = this.additionalFields instanceof DataType
162
+ ? this.additionalFields.generateCodec(codec, options)
163
+ : this.additionalFields;
157
164
  return vg.isObject(schema, {
158
165
  ctor: this.ctor,
159
- additionalFields: this.additionalFields ?? false,
166
+ additionalFields,
160
167
  name: this.name,
161
168
  caseInSensitive: !options?.caseSensitive
162
169
  });
@@ -165,20 +172,36 @@ export class ComplexTypeClass extends DataType {
165
172
  const schema = {};
166
173
  const pickOption = (options?.pick || []).map(x => x.toLowerCase());
167
174
  const omitOption = (options?.omit || []).map(x => x.toLowerCase());
168
- for (const f of this.fields.values()) {
169
- const nameLower = f.name.toLowerCase();
170
- if (omitOption.find(x => x === nameLower))
175
+ const dedupedFieldNames = (options?.overwriteFields
176
+ ? Array.from(new Set([...this.fields.keys(), ...options?.overwriteFields.keys()]))
177
+ : Array.from(this.fields.keys())).map(x => x.toLocaleString());
178
+ for (const nameLower of dedupedFieldNames) {
179
+ const overwriteField = options?.overwriteFields?.get(nameLower);
180
+ const field = this.fields.get(nameLower);
181
+ /* istanbul ignore next */
182
+ if (!(field || overwriteField))
171
183
  continue;
172
- if (pickOption.length && !pickOption.find(x => x === nameLower || x.startsWith(nameLower + '.')))
184
+ if (!overwriteField &&
185
+ (omitOption.find(x => x === nameLower) ||
186
+ (pickOption.length && !pickOption.find(x => x === nameLower || x.startsWith(nameLower + '.')))))
173
187
  continue;
188
+ let f;
189
+ if (overwriteField) {
190
+ f = { ...overwriteField };
191
+ Object.setPrototypeOf(f, field || ApiField.prototype);
192
+ }
193
+ else
194
+ f = field;
174
195
  schema[f.name] = f.generateCodec(codec, {
175
196
  ...options,
176
- pick: pickOption
177
- .filter(x => x.startsWith(nameLower + '.'))
178
- .map(x => x.substring(x.indexOf('.') + 1)),
179
- omit: omitOption
180
- .filter(x => x.startsWith(nameLower + '.'))
181
- .map(x => x.substring(x.indexOf('.') + 1)),
197
+ pick: overwriteField ? [] :
198
+ pickOption
199
+ .filter(x => x.startsWith(nameLower + '.'))
200
+ .map(x => x.substring(x.indexOf('.') + 1)),
201
+ omit: overwriteField ? [] :
202
+ omitOption
203
+ .filter(x => x.startsWith(nameLower + '.'))
204
+ .map(x => x.substring(x.indexOf('.') + 1)),
182
205
  });
183
206
  }
184
207
  return schema;
@@ -159,9 +159,9 @@ export class ApiDocumentFactory extends TypeDocumentFactory {
159
159
  return;
160
160
  const output = {};
161
161
  for (const [kA, oA] of Object.entries(source)) {
162
- let parameters;
162
+ const o = output[kA] = { ...oA };
163
163
  if (oA.parameters) {
164
- parameters = {};
164
+ const parameters = o.parameters = {};
165
165
  for (const [kP, oP] of Object.entries(oA.parameters)) {
166
166
  if (oP.enum) {
167
167
  oP.type = EnumType(oP.enum, { name: kP + 'Enum' });
@@ -172,7 +172,30 @@ export class ApiDocumentFactory extends TypeDocumentFactory {
172
172
  };
173
173
  }
174
174
  }
175
- output[kA] = { ...oA, parameters };
175
+ if (oA.options?.inputOverwriteFields) {
176
+ const inputOverwriteFields = {};
177
+ for (const [kP, oP] of Object.entries(oA.options.inputOverwriteFields)) {
178
+ if (oP.enum) {
179
+ oP.type = EnumType(oP.enum, { name: kP + 'Enum' });
180
+ }
181
+ inputOverwriteFields[kP] = { ...oP, };
182
+ if (oP.type)
183
+ inputOverwriteFields[kP].type = await this.importDataType(oP.type);
184
+ }
185
+ o.options.inputOverwriteFields = inputOverwriteFields;
186
+ }
187
+ if (oA.options?.outputOverwriteFields) {
188
+ const outputOverwriteFields = {};
189
+ for (const [kP, oP] of Object.entries(oA.options.outputOverwriteFields)) {
190
+ if (oP.enum) {
191
+ oP.type = EnumType(oP.enum, { name: kP + 'Enum' });
192
+ }
193
+ outputOverwriteFields[kP] = { ...oP };
194
+ if (oP.type)
195
+ outputOverwriteFields[kP].type = await this.importDataType(oP.type);
196
+ }
197
+ o.options.outputOverwriteFields = outputOverwriteFields;
198
+ }
176
199
  }
177
200
  return output;
178
201
  };
@@ -139,7 +139,7 @@ export class TypeDocumentFactory {
139
139
  return dataType;
140
140
  throw new TypeError(`Class "${thunk.name}" doesn't have a valid DataType metadata`);
141
141
  }
142
- name = metadata.name;
142
+ name = metadata.anonymous ? undefined : metadata.name;
143
143
  initArguments = cloneObject(metadata);
144
144
  ctor = thunk;
145
145
  }
@@ -154,7 +154,7 @@ export class TypeDocumentFactory {
154
154
  const metadata = thunk[DATATYPE_METADATA];
155
155
  if (!metadata)
156
156
  throw new TypeError(`No EnumType metadata found for object ${JSON.stringify(thunk).substring(0, 20)}...`);
157
- name = metadata.name;
157
+ name = metadata.anonymous ? undefined : metadata.name;
158
158
  initArguments = cloneObject(metadata);
159
159
  initArguments.enumObject = thunk;
160
160
  }
@@ -186,8 +186,11 @@ export class TypeDocumentFactory {
186
186
  if (name)
187
187
  this.document.types.set(name, instance);
188
188
  await this.prepareDataTypeInitArguments(initArguments, ctor);
189
- if (initArguments.kind === 'ComplexType')
189
+ if (initArguments.kind === 'ComplexType') {
190
+ if (typeof initArguments.additionalFields === 'function')
191
+ initArguments.additionalFields = await this.importDataType(initArguments.additionalFields);
190
192
  ComplexType.apply(instance, [this.document, initArguments]);
193
+ }
191
194
  else if (initArguments.kind === 'SimpleType')
192
195
  SimpleType.apply(instance, [this.document, initArguments]);
193
196
  else if (initArguments.kind === 'EnumType')
@@ -16,7 +16,7 @@ export * from './resource/collection.js';
16
16
  export * from './resource/container.js';
17
17
  export * from './resource/crud-resource.js';
18
18
  export * from './resource/endpoint.js';
19
- export * from './resource/operation.js';
19
+ export * from './resource/crud-operation.js';
20
20
  export * from './resource/parameter.js';
21
21
  export * from './resource/resource.js';
22
22
  export * from './resource/singleton.js';
@@ -30,16 +30,18 @@ export class CollectionClass extends CrudResource {
30
30
  endpoint.defineParameter('include', { type: 'string', isArray: true, isBuiltin: true });
31
31
  endpoint.decodeInput = this.type.generateCodec('decode', {
32
32
  partial: true,
33
- pick: endpoint.inputPickFields,
34
- omit: endpoint.inputOmitFields,
35
- operation: 'write'
33
+ pick: endpoint.options.inputPickFields,
34
+ omit: endpoint.options.inputOmitFields,
35
+ operation: 'write',
36
+ overwriteFields: endpoint.inputOverwriteFields
36
37
  });
37
38
  endpoint.returnType = this.type;
38
39
  endpoint.encodeReturning = endpoint.returnType.generateCodec('encode', {
39
40
  partial: true,
40
- pick: endpoint.outputPickFields,
41
- omit: endpoint.outputOmitFields,
42
- operation: 'read'
41
+ pick: endpoint.options.outputPickFields,
42
+ omit: endpoint.options.outputOmitFields,
43
+ operation: 'read',
44
+ overwriteFields: endpoint.outputOverwriteFields
43
45
  });
44
46
  }
45
47
  // ------------------
@@ -58,9 +60,10 @@ export class CollectionClass extends CrudResource {
58
60
  endpoint.returnType = this.type;
59
61
  endpoint.encodeReturning = endpoint.returnType.generateCodec('encode', {
60
62
  partial: true,
61
- pick: endpoint.outputPickFields,
62
- omit: endpoint.outputOmitFields,
63
- operation: 'read'
63
+ pick: endpoint.options.outputPickFields,
64
+ omit: endpoint.options.outputOmitFields,
65
+ operation: 'read',
66
+ overwriteFields: endpoint.outputOverwriteFields
64
67
  });
65
68
  }
66
69
  // ------------------
@@ -79,9 +82,10 @@ export class CollectionClass extends CrudResource {
79
82
  endpoint.returnType = this.type;
80
83
  endpoint.encodeReturning = vg.isArray(this.type.generateCodec('encode', {
81
84
  partial: true,
82
- pick: endpoint.outputPickFields,
83
- omit: endpoint.outputOmitFields,
84
- operation: 'read'
85
+ pick: endpoint.options.outputPickFields,
86
+ omit: endpoint.options.outputOmitFields,
87
+ operation: 'read',
88
+ overwriteFields: endpoint.outputOverwriteFields
85
89
  }));
86
90
  }
87
91
  // ------------------
@@ -92,16 +96,18 @@ export class CollectionClass extends CrudResource {
92
96
  endpoint.defineParameter('omit', { type: 'string', isArray: true, isBuiltin: true });
93
97
  endpoint.defineParameter('include', { type: 'string', isArray: true, isBuiltin: true });
94
98
  endpoint.decodeInput = this.type.generateCodec('decode', {
95
- pick: endpoint.inputPickFields,
96
- omit: endpoint.inputOmitFields,
97
- operation: 'write'
99
+ pick: endpoint.options.inputPickFields,
100
+ omit: endpoint.options.inputOmitFields,
101
+ operation: 'write',
102
+ overwriteFields: endpoint.inputOverwriteFields
98
103
  });
99
104
  endpoint.returnType = this.type;
100
105
  endpoint.encodeReturning = endpoint.returnType.generateCodec('encode', {
101
106
  partial: true,
102
- pick: endpoint.outputPickFields,
103
- omit: endpoint.outputOmitFields,
104
- operation: 'read'
107
+ pick: endpoint.options.outputPickFields,
108
+ omit: endpoint.options.outputOmitFields,
109
+ operation: 'read',
110
+ overwriteFields: endpoint.outputOverwriteFields
105
111
  });
106
112
  }
107
113
  // ------------------
@@ -110,15 +116,13 @@ export class CollectionClass extends CrudResource {
110
116
  // endpoint.defineParameter('metadata', {enum: MetadataMode, isBuiltin: true, default: 'minimal'});
111
117
  endpoint.defineParameter('filter', { type: 'string', isBuiltin: true });
112
118
  endpoint.decodeInput = this.type.generateCodec('decode', {
113
- pick: endpoint.inputPickFields,
114
- omit: endpoint.inputOmitFields,
115
- operation: 'write'
119
+ pick: endpoint.options.inputPickFields,
120
+ omit: endpoint.options.inputOmitFields,
121
+ operation: 'write',
122
+ overwriteFields: endpoint.inputOverwriteFields
116
123
  });
117
124
  }
118
125
  }
119
- getOperation(name) {
120
- return super.getOperation(name);
121
- }
122
126
  exportSchema(options) {
123
127
  return {
124
128
  ...super.exportSchema(options),
@@ -170,7 +174,7 @@ export class CollectionClass extends CrudResource {
170
174
  if (!normalized)
171
175
  return;
172
176
  const findManyOp = this.getOperation('findMany');
173
- const sortFields = findManyOp && findManyOp.sortFields;
177
+ const sortFields = findManyOp && findManyOp.options.sortFields;
174
178
  (Array.isArray(normalized) ? normalized : [normalized]).forEach(field => {
175
179
  if (!sortFields?.find(x => x === field))
176
180
  throw new BadRequestError({
@@ -190,7 +194,7 @@ export class CollectionClass extends CrudResource {
190
194
  // Check if filtering accepted for given field
191
195
  const findManyOp = this.getOperation('findMany');
192
196
  const fieldLower = ast.left.value.toLowerCase();
193
- const filterDef = (findManyOp && findManyOp.filters || [])
197
+ const filterDef = (findManyOp && findManyOp.options.filters || [])
194
198
  .find(f => f.field.toLowerCase() === fieldLower);
195
199
  if (!filterDef) {
196
200
  throw new BadRequestError({
@@ -198,7 +202,7 @@ export class CollectionClass extends CrudResource {
198
202
  });
199
203
  }
200
204
  // Check if filtering endpoint accepted for given field
201
- if (!filterDef.operators?.includes(ast.op))
205
+ if (filterDef.operators && !filterDef.operators.includes(ast.op))
202
206
  throw new BadRequestError({
203
207
  message: translate('error:UNACCEPTED_FILTER_OPERATION', { field: ast.left.value }),
204
208
  });
@@ -1,7 +1,7 @@
1
1
  import { omitUndefined } from '../../helpers/index.js';
2
2
  import { OpraSchema } from '../../schema/index.js';
3
3
  import { createActionDecorator } from './action-decorator.js';
4
- import { createOperationDecorator } from './operation-decorator.js';
4
+ import { createOperationDecorator } from './crud-operation-decorator.js';
5
5
  import { ResourceDecorator } from './resource-decorator.js';
6
6
  const operationProperties = ['create', 'delete', 'deleteMany', 'get', 'findMany', 'update', 'updateMany'];
7
7
  export function CollectionDecorator(type, options) {
@@ -24,23 +24,31 @@ Object.assign(CollectionDecorator, ResourceDecorator);
24
24
  const list = [];
25
25
  const decorator = createOperationDecorator('create', options, list);
26
26
  decorator.InputMaxContentSize = (sizeInBytes) => {
27
- list.push(operationMeta => operationMeta.inputMaxContentSize = sizeInBytes);
27
+ list.push(operationMeta => operationMeta.options.inputMaxContentSize = sizeInBytes);
28
28
  return decorator;
29
29
  };
30
30
  decorator.InputPickFields = (...fields) => {
31
- list.push(operationMeta => operationMeta.inputPickFields = fields);
31
+ list.push(operationMeta => operationMeta.options.inputPickFields = fields);
32
32
  return decorator;
33
33
  };
34
34
  decorator.InputOmitFields = (...fields) => {
35
- list.push(operationMeta => operationMeta.inputOmitFields = fields);
35
+ list.push(operationMeta => operationMeta.options.inputOmitFields = fields);
36
+ return decorator;
37
+ };
38
+ decorator.InputOverwriteFields = (fields) => {
39
+ list.push(operationMeta => operationMeta.options.inputOverwriteFields = fields);
36
40
  return decorator;
37
41
  };
38
42
  decorator.OutputPickFields = (...fields) => {
39
- list.push(operationMeta => operationMeta.outputPickFields = fields);
43
+ list.push(operationMeta => operationMeta.options.outputPickFields = fields);
40
44
  return decorator;
41
45
  };
42
46
  decorator.OutputOmitFields = (...fields) => {
43
- list.push(operationMeta => operationMeta.outputOmitFields = fields);
47
+ list.push(operationMeta => operationMeta.options.outputOmitFields = fields);
48
+ return decorator;
49
+ };
50
+ decorator.OutputOverwriteFields = (fields) => {
51
+ list.push(operationMeta => operationMeta.options.outputOverwriteFields = fields);
44
52
  return decorator;
45
53
  };
46
54
  return decorator;
@@ -58,8 +66,8 @@ Object.assign(CollectionDecorator, ResourceDecorator);
58
66
  if (typeof operators === 'string')
59
67
  operators = operators.split(/\s*[,| ]\s*/);
60
68
  list.push(operationMeta => {
61
- operationMeta.filters = operationMeta.filters || [];
62
- operationMeta.filters.push(omitUndefined({ field, operators, notes }));
69
+ operationMeta.options.filters = operationMeta.options.filters || [];
70
+ operationMeta.options.filters.push(omitUndefined({ field, operators, notes }));
63
71
  });
64
72
  return decorator;
65
73
  };
@@ -70,11 +78,15 @@ Object.assign(CollectionDecorator, ResourceDecorator);
70
78
  const list = [];
71
79
  const decorator = createOperationDecorator('get', options, list);
72
80
  decorator.OutputPickFields = (...fields) => {
73
- list.push(operationMeta => operationMeta.outputPickFields = fields);
81
+ list.push(operationMeta => operationMeta.options.outputPickFields = fields);
74
82
  return decorator;
75
83
  };
76
84
  decorator.OutputOmitFields = (...fields) => {
77
- list.push(operationMeta => operationMeta.outputOmitFields = fields);
85
+ list.push(operationMeta => operationMeta.options.outputOmitFields = fields);
86
+ return decorator;
87
+ };
88
+ decorator.OutputOverwriteFields = (fields) => {
89
+ list.push(operationMeta => operationMeta.options.outputOverwriteFields = fields);
78
90
  return decorator;
79
91
  };
80
92
  return decorator;
@@ -84,28 +96,32 @@ Object.assign(CollectionDecorator, ResourceDecorator);
84
96
  const list = [];
85
97
  const decorator = createOperationDecorator('findMany', options, list);
86
98
  decorator.SortFields = (...fields) => {
87
- list.push(operationMeta => operationMeta.sortFields = fields);
99
+ list.push(operationMeta => operationMeta.options.sortFields = fields);
88
100
  return decorator;
89
101
  };
90
102
  decorator.DefaultSort = (...fields) => {
91
- list.push(operationMeta => operationMeta.defaultSort = fields);
103
+ list.push(operationMeta => operationMeta.options.defaultSort = fields);
92
104
  return decorator;
93
105
  };
94
106
  decorator.Filter = (field, operators, notes) => {
95
107
  if (typeof operators === 'string')
96
108
  operators = operators.split(/\s*[,| ]\s*/);
97
109
  list.push(operationMeta => {
98
- operationMeta.filters = operationMeta.filters || [];
99
- operationMeta.filters.push(omitUndefined({ field, operators, notes }));
110
+ operationMeta.options.filters = operationMeta.options.filters || [];
111
+ operationMeta.options.filters.push(omitUndefined({ field, operators, notes }));
100
112
  });
101
113
  return decorator;
102
114
  };
103
115
  decorator.OutputPickFields = (...fields) => {
104
- list.push(operationMeta => operationMeta.outputPickFields = fields);
116
+ list.push(operationMeta => operationMeta.options.outputPickFields = fields);
105
117
  return decorator;
106
118
  };
107
119
  decorator.OutputOmitFields = (...fields) => {
108
- list.push(operationMeta => operationMeta.outputOmitFields = fields);
120
+ list.push(operationMeta => operationMeta.options.outputOmitFields = fields);
121
+ return decorator;
122
+ };
123
+ decorator.OutputOverwriteFields = (fields) => {
124
+ list.push(operationMeta => operationMeta.options.outputOverwriteFields = fields);
109
125
  return decorator;
110
126
  };
111
127
  return decorator;
@@ -120,23 +136,31 @@ Object.assign(CollectionDecorator, ResourceDecorator);
120
136
  const list = [];
121
137
  const decorator = createOperationDecorator('update', options, list);
122
138
  decorator.InputMaxContentSize = (sizeInBytes) => {
123
- list.push(operationMeta => operationMeta.inputMaxContentSize = sizeInBytes);
139
+ list.push(operationMeta => operationMeta.options.inputMaxContentSize = sizeInBytes);
124
140
  return decorator;
125
141
  };
126
142
  decorator.InputPickFields = (...fields) => {
127
- list.push(operationMeta => operationMeta.inputPickFields = fields);
143
+ list.push(operationMeta => operationMeta.options.inputPickFields = fields);
128
144
  return decorator;
129
145
  };
130
146
  decorator.InputOmitFields = (...fields) => {
131
- list.push(operationMeta => operationMeta.inputOmitFields = fields);
147
+ list.push(operationMeta => operationMeta.options.inputOmitFields = fields);
148
+ return decorator;
149
+ };
150
+ decorator.InputOverwriteFields = (fields) => {
151
+ list.push(operationMeta => operationMeta.options.inputOverwriteFields = fields);
132
152
  return decorator;
133
153
  };
134
154
  decorator.OutputPickFields = (...fields) => {
135
- list.push(operationMeta => operationMeta.outputPickFields = fields);
155
+ list.push(operationMeta => operationMeta.options.outputPickFields = fields);
136
156
  return decorator;
137
157
  };
138
158
  decorator.OutputOmitFields = (...fields) => {
139
- list.push(operationMeta => operationMeta.outputOmitFields = fields);
159
+ list.push(operationMeta => operationMeta.options.outputOmitFields = fields);
160
+ return decorator;
161
+ };
162
+ decorator.OutputOverwriteFields = (fields) => {
163
+ list.push(operationMeta => operationMeta.options.outputOverwriteFields = fields);
140
164
  return decorator;
141
165
  };
142
166
  return decorator;
@@ -152,23 +176,27 @@ Object.assign(CollectionDecorator, ResourceDecorator);
152
176
  const options = typeof arg0 === 'string' ? { description: arg0 } : { ...arg0 };
153
177
  const decorator = createOperationDecorator('updateMany', options, list);
154
178
  decorator.InputMaxContentSize = (sizeInBytes) => {
155
- list.push(operationMeta => operationMeta.inputMaxContentSize = sizeInBytes);
179
+ list.push(operationMeta => operationMeta.options.inputMaxContentSize = sizeInBytes);
156
180
  return decorator;
157
181
  };
158
182
  decorator.InputPickFields = (...fields) => {
159
- list.push(operationMeta => operationMeta.inputPickFields = fields);
183
+ list.push(operationMeta => operationMeta.options.inputPickFields = fields);
160
184
  return decorator;
161
185
  };
162
186
  decorator.InputOmitFields = (...fields) => {
163
- list.push(operationMeta => operationMeta.inputOmitFields = fields);
187
+ list.push(operationMeta => operationMeta.options.inputOmitFields = fields);
188
+ return decorator;
189
+ };
190
+ decorator.InputOverwriteFields = (fields) => {
191
+ list.push(operationMeta => operationMeta.options.inputOverwriteFields = fields);
164
192
  return decorator;
165
193
  };
166
194
  decorator.Filter = (field, operators, notes) => {
167
195
  if (typeof operators === 'string')
168
196
  operators = operators.split(/\s*[,| ]\s*/);
169
197
  list.push(operationMeta => {
170
- operationMeta.filters = operationMeta.filters || [];
171
- operationMeta.filters.push(omitUndefined({ field, operators, notes }));
198
+ operationMeta.options.filters = operationMeta.options.filters || [];
199
+ operationMeta.options.filters.push(omitUndefined({ field, operators, notes }));
172
200
  });
173
201
  return decorator;
174
202
  };
@@ -1,11 +1,12 @@
1
1
  import { RESOURCE_METADATA } from '../constants.js';
2
- export function createOperationDecorator(operation, options, list) {
2
+ export function createOperationDecorator(operation, init, list) {
3
3
  const decorator = ((target, propertyKey) => {
4
4
  if (propertyKey !== operation)
5
5
  throw new TypeError(`Name of the handler name should be '${operation}'`);
6
6
  const resourceMetadata = (Reflect.getOwnMetadata(RESOURCE_METADATA, target.constructor) || {});
7
7
  resourceMetadata.operations = resourceMetadata.operations || {};
8
- const operationMeta = { ...options };
8
+ const operationMeta = { ...init };
9
+ operationMeta.options = operationMeta.options || {};
9
10
  resourceMetadata.operations[operation] = operationMeta;
10
11
  for (const fn of list)
11
12
  fn(operationMeta, target, propertyKey);