@opra/common 1.0.0-alpha.1 → 1.0.0-alpha.2
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/package.json +1 -1
- package/cjs/document/data-type/decorators/api-field-decorator.js +0 -26
- package/cjs/document/data-type/decorators/complex-type.decorator.js +0 -33
- package/cjs/document/data-type/decorators/simple-type.decorator.js +0 -67
- package/cjs/document/http/decorators/http-controller.decorator.js +0 -117
- package/cjs/document/http/decorators/http-operation-entity.decorator.js +0 -461
- package/cjs/document/http/decorators/http-operation.decorator.js +0 -183
- package/cjs/helpers/is-url-string.js +0 -12
- package/cjs/http/opra-url-path.js +0 -266
- package/cjs/http/opra-url.js +0 -253
- package/esm/document/data-type/decorators/api-field-decorator.js +0 -22
- package/esm/document/data-type/decorators/complex-type.decorator.js +0 -28
- package/esm/document/data-type/decorators/simple-type.decorator.js +0 -61
- package/esm/document/http/decorators/http-controller.decorator.js +0 -112
- package/esm/document/http/decorators/http-operation-entity.decorator.js +0 -459
- package/esm/document/http/decorators/http-operation.decorator.js +0 -178
- package/esm/helpers/is-url-string.js +0 -7
- package/esm/http/opra-url-path.js +0 -260
- package/esm/http/opra-url.js +0 -249
- package/types/document/data-type/decorators/api-field-decorator.d.ts +0 -5
- package/types/document/data-type/decorators/complex-type.decorator.d.ts +0 -2
- package/types/document/data-type/decorators/simple-type.decorator.d.ts +0 -20
- package/types/document/http/decorators/http-controller.decorator.d.ts +0 -14
- package/types/document/http/decorators/http-operation-entity.decorator.d.ts +0 -100
- package/types/document/http/decorators/http-operation.decorator.d.ts +0 -30
- package/types/helpers/is-url-string.d.ts +0 -2
- package/types/http/opra-url-path.d.ts +0 -55
- package/types/http/opra-url.d.ts +0 -66
|
@@ -1,112 +0,0 @@
|
|
|
1
|
-
import omit from 'lodash.omit';
|
|
2
|
-
import merge from 'putil-merge';
|
|
3
|
-
import { OpraSchema } from '../../../schema/index.js';
|
|
4
|
-
import { HTTP_CONTROLLER_METADATA } from '../../constants.js';
|
|
5
|
-
const CLASS_NAME_PATTERN = /^(.*)(Collection|Singleton|Resource|Controller)$/;
|
|
6
|
-
export function HttpControllerDecoratorFactory(options) {
|
|
7
|
-
const decoratorChain = [];
|
|
8
|
-
/**
|
|
9
|
-
*
|
|
10
|
-
*/
|
|
11
|
-
const decorator = function (target) {
|
|
12
|
-
let name = options?.name;
|
|
13
|
-
if (!name)
|
|
14
|
-
name = CLASS_NAME_PATTERN.exec(target.name)?.[1] || target.name;
|
|
15
|
-
const metadata = {};
|
|
16
|
-
const baseMetadata = Reflect.getOwnMetadata(HTTP_CONTROLLER_METADATA, Object.getPrototypeOf(target));
|
|
17
|
-
if (baseMetadata)
|
|
18
|
-
merge(metadata, baseMetadata, { deep: true });
|
|
19
|
-
const oldMetadata = Reflect.getOwnMetadata(HTTP_CONTROLLER_METADATA, target);
|
|
20
|
-
if (oldMetadata)
|
|
21
|
-
merge(metadata, oldMetadata, { deep: true });
|
|
22
|
-
merge(metadata, {
|
|
23
|
-
kind: OpraSchema.HttpController.Kind,
|
|
24
|
-
name,
|
|
25
|
-
path: name,
|
|
26
|
-
...omit(options, ['kind', 'name', 'instance', 'endpoints', 'key']),
|
|
27
|
-
}, { deep: true });
|
|
28
|
-
Reflect.defineMetadata(HTTP_CONTROLLER_METADATA, metadata, target);
|
|
29
|
-
for (const fn of decoratorChain)
|
|
30
|
-
fn(metadata);
|
|
31
|
-
Reflect.defineMetadata(HTTP_CONTROLLER_METADATA, metadata, target);
|
|
32
|
-
};
|
|
33
|
-
/**
|
|
34
|
-
*
|
|
35
|
-
*/
|
|
36
|
-
decorator.Cookie = (name, arg1) => {
|
|
37
|
-
decoratorChain.push((meta) => {
|
|
38
|
-
const paramMeta = typeof arg1 === 'string' || typeof arg1 === 'function'
|
|
39
|
-
? {
|
|
40
|
-
name,
|
|
41
|
-
location: 'cookie',
|
|
42
|
-
type: arg1,
|
|
43
|
-
}
|
|
44
|
-
: { ...arg1, name, location: 'cookie' };
|
|
45
|
-
meta.parameters = meta.parameters || [];
|
|
46
|
-
meta.parameters.push(paramMeta);
|
|
47
|
-
});
|
|
48
|
-
return decorator;
|
|
49
|
-
};
|
|
50
|
-
/**
|
|
51
|
-
*
|
|
52
|
-
*/
|
|
53
|
-
decorator.Header = (name, arg1) => {
|
|
54
|
-
decoratorChain.push((meta) => {
|
|
55
|
-
const paramMeta = typeof arg1 === 'string' || typeof arg1 === 'function'
|
|
56
|
-
? {
|
|
57
|
-
name,
|
|
58
|
-
location: 'header',
|
|
59
|
-
type: arg1,
|
|
60
|
-
}
|
|
61
|
-
: { ...arg1, name, location: 'header' };
|
|
62
|
-
meta.parameters = meta.parameters || [];
|
|
63
|
-
meta.parameters.push(paramMeta);
|
|
64
|
-
});
|
|
65
|
-
return decorator;
|
|
66
|
-
};
|
|
67
|
-
/**
|
|
68
|
-
*
|
|
69
|
-
*/
|
|
70
|
-
decorator.QueryParam = (name, arg1) => {
|
|
71
|
-
decoratorChain.push((meta) => {
|
|
72
|
-
const paramMeta = typeof arg1 === 'string' || typeof arg1 === 'function'
|
|
73
|
-
? {
|
|
74
|
-
name,
|
|
75
|
-
location: 'query',
|
|
76
|
-
type: arg1,
|
|
77
|
-
}
|
|
78
|
-
: { ...arg1, name, location: 'query' };
|
|
79
|
-
meta.parameters = meta.parameters || [];
|
|
80
|
-
meta.parameters.push(paramMeta);
|
|
81
|
-
});
|
|
82
|
-
return decorator;
|
|
83
|
-
};
|
|
84
|
-
/**
|
|
85
|
-
*
|
|
86
|
-
*/
|
|
87
|
-
decorator.PathParam = (name, arg1) => {
|
|
88
|
-
decoratorChain.push((meta) => {
|
|
89
|
-
const paramMeta = typeof arg1 === 'string' || typeof arg1 === 'function'
|
|
90
|
-
? {
|
|
91
|
-
name,
|
|
92
|
-
location: 'path',
|
|
93
|
-
type: arg1,
|
|
94
|
-
}
|
|
95
|
-
: { ...arg1, name, location: 'path' };
|
|
96
|
-
meta.parameters = meta.parameters || [];
|
|
97
|
-
meta.parameters.push(paramMeta);
|
|
98
|
-
});
|
|
99
|
-
return decorator;
|
|
100
|
-
};
|
|
101
|
-
/**
|
|
102
|
-
*
|
|
103
|
-
*/
|
|
104
|
-
decorator.UseType = (...type) => {
|
|
105
|
-
decoratorChain.push((meta) => {
|
|
106
|
-
meta.types = meta.types || [];
|
|
107
|
-
meta.types.push(...type);
|
|
108
|
-
});
|
|
109
|
-
return decorator;
|
|
110
|
-
};
|
|
111
|
-
return decorator;
|
|
112
|
-
}
|
|
@@ -1,459 +0,0 @@
|
|
|
1
|
-
import { FilterRules } from '../../../filter/filter-rules.js';
|
|
2
|
-
import { omitUndefined } from '../../../helpers/index.js';
|
|
3
|
-
import { HttpStatusCode, MimeTypes } from '../../../http/index.js';
|
|
4
|
-
import { DATATYPE_METADATA } from '../../constants.js';
|
|
5
|
-
import { FieldPathType, FilterType } from '../../data-type/extended-types/index.js';
|
|
6
|
-
import { IntegerType } from '../../data-type/primitive-types/index.js';
|
|
7
|
-
import { HttpOperation } from '../http-operation.js';
|
|
8
|
-
import { HttpOperationDecoratorFactory } from './http-operation.decorator.js';
|
|
9
|
-
/** Implementation **/
|
|
10
|
-
HttpOperation.Entity = {};
|
|
11
|
-
/**
|
|
12
|
-
* HttpOperation.Entity.Create
|
|
13
|
-
*/
|
|
14
|
-
HttpOperation.Entity.Create = function (arg0, arg1) {
|
|
15
|
-
let args;
|
|
16
|
-
if (typeof arg0 === 'object' && !arg0[DATATYPE_METADATA]) {
|
|
17
|
-
args = arg0;
|
|
18
|
-
}
|
|
19
|
-
else
|
|
20
|
-
args = { ...arg1, type: arg0 };
|
|
21
|
-
/** Initialize the decorator and the chain */
|
|
22
|
-
const decoratorChain = [];
|
|
23
|
-
const decorator = HttpOperationDecoratorFactory(decoratorChain, omitUndefined({
|
|
24
|
-
description: args.description,
|
|
25
|
-
method: 'POST',
|
|
26
|
-
composition: 'Entity.Create',
|
|
27
|
-
requestBody: {
|
|
28
|
-
immediateFetch: true,
|
|
29
|
-
...args.requestBody,
|
|
30
|
-
required: true,
|
|
31
|
-
},
|
|
32
|
-
}));
|
|
33
|
-
decorator
|
|
34
|
-
.QueryParam('projection', {
|
|
35
|
-
description: 'Determines fields projection',
|
|
36
|
-
type: new FieldPathType({
|
|
37
|
-
dataType: args.type,
|
|
38
|
-
allowSigns: 'each',
|
|
39
|
-
}),
|
|
40
|
-
isArray: true,
|
|
41
|
-
arraySeparator: ',',
|
|
42
|
-
})
|
|
43
|
-
.RequestContent(args.requestBody?.type || args.type)
|
|
44
|
-
.Response(HttpStatusCode.CREATED, {
|
|
45
|
-
description: 'Operation is successful. Returns OperationResult with "payload" field that contains the created resource.',
|
|
46
|
-
contentType: MimeTypes.opra_response_json,
|
|
47
|
-
type: args.type,
|
|
48
|
-
partial: 'deep',
|
|
49
|
-
})
|
|
50
|
-
.Response(HttpStatusCode.UNPROCESSABLE_ENTITY, {
|
|
51
|
-
description: 'The request was well-formed but was unable to process operation due to one or many errors.',
|
|
52
|
-
contentType: MimeTypes.opra_response_json,
|
|
53
|
-
});
|
|
54
|
-
if (typeof args.type === 'function')
|
|
55
|
-
decorator.UseType(args.type);
|
|
56
|
-
decoratorChain.push((operationMeta) => {
|
|
57
|
-
const compositionOptions = (operationMeta.compositionOptions = operationMeta.compositionOptions || {});
|
|
58
|
-
compositionOptions.type = getDataTypeName(args.type);
|
|
59
|
-
});
|
|
60
|
-
return decorator;
|
|
61
|
-
};
|
|
62
|
-
/**
|
|
63
|
-
* HttpOperation.Entity.Delete
|
|
64
|
-
*/
|
|
65
|
-
HttpOperation.Entity.Delete = function (arg0, arg1) {
|
|
66
|
-
let args;
|
|
67
|
-
if (typeof arg0 === 'object' && !arg0[DATATYPE_METADATA]) {
|
|
68
|
-
args = arg0;
|
|
69
|
-
}
|
|
70
|
-
else
|
|
71
|
-
args = { ...arg1, type: arg0 };
|
|
72
|
-
/** Initialize the decorator and the chain */
|
|
73
|
-
const decoratorChain = [];
|
|
74
|
-
const decorator = HttpOperationDecoratorFactory(decoratorChain, omitUndefined({
|
|
75
|
-
description: args.description,
|
|
76
|
-
method: 'DELETE',
|
|
77
|
-
composition: 'Entity.Delete',
|
|
78
|
-
}));
|
|
79
|
-
decorator
|
|
80
|
-
.Response(HttpStatusCode.OK, {
|
|
81
|
-
description: 'Operation is successful. Returns OperationResult with "affected" field.',
|
|
82
|
-
contentType: MimeTypes.opra_response_json,
|
|
83
|
-
})
|
|
84
|
-
.Response(HttpStatusCode.UNPROCESSABLE_ENTITY, {
|
|
85
|
-
description: 'The request was well-formed but was unable to process operation due to one or many errors.',
|
|
86
|
-
contentType: MimeTypes.opra_response_json,
|
|
87
|
-
});
|
|
88
|
-
if (typeof args.type === 'function')
|
|
89
|
-
decorator.UseType(args.type);
|
|
90
|
-
/**
|
|
91
|
-
*
|
|
92
|
-
*/
|
|
93
|
-
decorator.KeyParam = (name, prmOptions) => {
|
|
94
|
-
decorator.PathParam(name, prmOptions);
|
|
95
|
-
decoratorChain.push((meta) => {
|
|
96
|
-
meta.path = (meta.path || '') + '@:' + name;
|
|
97
|
-
meta.compositionOptions = meta.compositionOptions || {};
|
|
98
|
-
meta.compositionOptions.keyParameter = name;
|
|
99
|
-
});
|
|
100
|
-
return decorator;
|
|
101
|
-
};
|
|
102
|
-
decoratorChain.push((operationMeta) => {
|
|
103
|
-
const compositionOptions = (operationMeta.compositionOptions = operationMeta.compositionOptions || {});
|
|
104
|
-
compositionOptions.type = getDataTypeName(args.type);
|
|
105
|
-
});
|
|
106
|
-
return decorator;
|
|
107
|
-
};
|
|
108
|
-
/**
|
|
109
|
-
* HttpOperation.Entity.DeleteMany
|
|
110
|
-
*/
|
|
111
|
-
HttpOperation.Entity.DeleteMany = function (arg0, arg1) {
|
|
112
|
-
let args;
|
|
113
|
-
if (typeof arg0 === 'object' && !arg0[DATATYPE_METADATA]) {
|
|
114
|
-
args = arg0;
|
|
115
|
-
}
|
|
116
|
-
else
|
|
117
|
-
args = { ...arg1, type: arg0 };
|
|
118
|
-
/** Initialize the decorator and the chain */
|
|
119
|
-
const decoratorChain = [];
|
|
120
|
-
const filterRules = new FilterRules();
|
|
121
|
-
const filterType = new FilterType({ dataType: args.type });
|
|
122
|
-
filterType.rules = {};
|
|
123
|
-
const decorator = HttpOperationDecoratorFactory(decoratorChain, omitUndefined({
|
|
124
|
-
description: args.description,
|
|
125
|
-
method: 'DELETE',
|
|
126
|
-
composition: 'Entity.DeleteMany',
|
|
127
|
-
}));
|
|
128
|
-
decorator
|
|
129
|
-
.Response(HttpStatusCode.OK, {
|
|
130
|
-
description: 'Operation is successful. Returns OperationResult with "affected" field.',
|
|
131
|
-
contentType: MimeTypes.opra_response_json,
|
|
132
|
-
})
|
|
133
|
-
.Response(HttpStatusCode.UNPROCESSABLE_ENTITY, {
|
|
134
|
-
description: 'The request was well-formed but was unable to process operation due to one or many errors.',
|
|
135
|
-
contentType: MimeTypes.opra_response_json,
|
|
136
|
-
})
|
|
137
|
-
.QueryParam('filter', {
|
|
138
|
-
type: filterType,
|
|
139
|
-
description: 'Determines filter fields',
|
|
140
|
-
});
|
|
141
|
-
if (typeof args.type === 'function')
|
|
142
|
-
decorator.UseType(args.type);
|
|
143
|
-
decoratorChain.push((operationMeta) => {
|
|
144
|
-
const compositionOptions = (operationMeta.compositionOptions = operationMeta.compositionOptions || {});
|
|
145
|
-
compositionOptions.type = getDataTypeName(args.type);
|
|
146
|
-
});
|
|
147
|
-
decorator.Filter = (field, operators, description) => {
|
|
148
|
-
decoratorChain.push(() => {
|
|
149
|
-
filterRules.set(field, { operators, description });
|
|
150
|
-
filterType.rules = filterRules.toJSON();
|
|
151
|
-
});
|
|
152
|
-
return decorator;
|
|
153
|
-
};
|
|
154
|
-
return decorator;
|
|
155
|
-
};
|
|
156
|
-
/**
|
|
157
|
-
* HttpOperation.Entity.FindMany
|
|
158
|
-
*/
|
|
159
|
-
HttpOperation.Entity.FindMany = function (arg0, arg1) {
|
|
160
|
-
let args;
|
|
161
|
-
if (typeof arg0 === 'object' && !arg0[DATATYPE_METADATA]) {
|
|
162
|
-
args = arg0;
|
|
163
|
-
}
|
|
164
|
-
else
|
|
165
|
-
args = { ...arg1, type: arg0 };
|
|
166
|
-
/** Initialize the decorator and the chain */
|
|
167
|
-
const decoratorChain = [];
|
|
168
|
-
const filterRules = new FilterRules();
|
|
169
|
-
const filterType = new FilterType({ dataType: args.type });
|
|
170
|
-
filterType.rules = {};
|
|
171
|
-
const decorator = HttpOperationDecoratorFactory(decoratorChain, omitUndefined({
|
|
172
|
-
description: args.description,
|
|
173
|
-
method: 'GET',
|
|
174
|
-
composition: 'Entity.FindMany',
|
|
175
|
-
}));
|
|
176
|
-
decorator
|
|
177
|
-
.Response(HttpStatusCode.OK, {
|
|
178
|
-
description: 'Operation is successful. Returns OperationResult with "payload" field that contains list of resources.',
|
|
179
|
-
contentType: MimeTypes.opra_response_json,
|
|
180
|
-
type: args.type,
|
|
181
|
-
partial: 'deep',
|
|
182
|
-
isArray: true,
|
|
183
|
-
})
|
|
184
|
-
.Response(HttpStatusCode.UNPROCESSABLE_ENTITY, {
|
|
185
|
-
description: 'The request was well-formed but was unable to process operation due to one or many errors.',
|
|
186
|
-
contentType: MimeTypes.opra_response_json,
|
|
187
|
-
})
|
|
188
|
-
.QueryParam('limit', {
|
|
189
|
-
description: 'Determines number of returning instances',
|
|
190
|
-
type: new IntegerType({ minValue: 1 }),
|
|
191
|
-
})
|
|
192
|
-
.QueryParam('skip', {
|
|
193
|
-
description: 'Determines number of returning instances',
|
|
194
|
-
type: new IntegerType({ minValue: 1 }),
|
|
195
|
-
})
|
|
196
|
-
.QueryParam('count', {
|
|
197
|
-
description: 'Counts all matching instances if enabled',
|
|
198
|
-
type: Boolean,
|
|
199
|
-
})
|
|
200
|
-
.QueryParam('projection', {
|
|
201
|
-
description: 'Determines fields projection',
|
|
202
|
-
type: new FieldPathType({
|
|
203
|
-
dataType: args.type,
|
|
204
|
-
allowSigns: 'each',
|
|
205
|
-
}),
|
|
206
|
-
isArray: true,
|
|
207
|
-
arraySeparator: ',',
|
|
208
|
-
})
|
|
209
|
-
.QueryParam('filter', {
|
|
210
|
-
type: filterType,
|
|
211
|
-
description: 'Determines filter fields',
|
|
212
|
-
})
|
|
213
|
-
.QueryParam('sort', {
|
|
214
|
-
description: 'Determines sort fields',
|
|
215
|
-
type: new FieldPathType({
|
|
216
|
-
dataType: args.type,
|
|
217
|
-
allowSigns: 'first',
|
|
218
|
-
}),
|
|
219
|
-
isArray: true,
|
|
220
|
-
arraySeparator: ',',
|
|
221
|
-
});
|
|
222
|
-
if (typeof args.type === 'function')
|
|
223
|
-
decorator.UseType(args.type);
|
|
224
|
-
decoratorChain.push((operationMeta) => {
|
|
225
|
-
const compositionOptions = (operationMeta.compositionOptions = operationMeta.compositionOptions || {});
|
|
226
|
-
compositionOptions.type = getDataTypeName(args.type);
|
|
227
|
-
});
|
|
228
|
-
decorator.DefaultSort = (...fields) => {
|
|
229
|
-
decoratorChain.push((operationMeta) => {
|
|
230
|
-
const compositionOptions = (operationMeta.compositionOptions = operationMeta.compositionOptions || {});
|
|
231
|
-
compositionOptions.defaultSort = fields;
|
|
232
|
-
});
|
|
233
|
-
return decorator;
|
|
234
|
-
};
|
|
235
|
-
decorator.SortFields = (...fields) => {
|
|
236
|
-
decoratorChain.push((operationMeta) => {
|
|
237
|
-
const compositionOptions = (operationMeta.compositionOptions = operationMeta.compositionOptions || {});
|
|
238
|
-
compositionOptions.sortFields = fields;
|
|
239
|
-
});
|
|
240
|
-
return decorator;
|
|
241
|
-
};
|
|
242
|
-
decorator.Filter = (field, operators, description) => {
|
|
243
|
-
decoratorChain.push(() => {
|
|
244
|
-
filterRules.set(field, { operators, description });
|
|
245
|
-
filterType.rules = filterRules.toJSON();
|
|
246
|
-
});
|
|
247
|
-
return decorator;
|
|
248
|
-
};
|
|
249
|
-
return decorator;
|
|
250
|
-
};
|
|
251
|
-
/**
|
|
252
|
-
* HttpOperation.Entity.Get
|
|
253
|
-
*/
|
|
254
|
-
HttpOperation.Entity.Get = function (arg0, arg1) {
|
|
255
|
-
let args;
|
|
256
|
-
if (typeof arg0 === 'object' && !arg0[DATATYPE_METADATA]) {
|
|
257
|
-
args = arg0;
|
|
258
|
-
}
|
|
259
|
-
else
|
|
260
|
-
args = { ...arg1, type: arg0 };
|
|
261
|
-
/** Initialize the decorator and the chain */
|
|
262
|
-
const decoratorChain = [];
|
|
263
|
-
const decorator = HttpOperationDecoratorFactory(decoratorChain, omitUndefined({
|
|
264
|
-
description: args.description,
|
|
265
|
-
method: 'GET',
|
|
266
|
-
composition: 'Entity.Get',
|
|
267
|
-
}));
|
|
268
|
-
decorator
|
|
269
|
-
.QueryParam('projection', {
|
|
270
|
-
description: 'Determines fields projection',
|
|
271
|
-
type: new FieldPathType({
|
|
272
|
-
dataType: args.type,
|
|
273
|
-
allowSigns: 'each',
|
|
274
|
-
}),
|
|
275
|
-
isArray: true,
|
|
276
|
-
arraySeparator: ',',
|
|
277
|
-
})
|
|
278
|
-
.Response(HttpStatusCode.OK, {
|
|
279
|
-
description: 'Operation is successful. Returns OperationResult with "payload" field that contains the resource asked for.',
|
|
280
|
-
contentType: MimeTypes.opra_response_json,
|
|
281
|
-
type: args.type,
|
|
282
|
-
partial: 'deep',
|
|
283
|
-
})
|
|
284
|
-
.Response(HttpStatusCode.NO_CONTENT, {
|
|
285
|
-
description: 'Operation is successful but no resource found',
|
|
286
|
-
})
|
|
287
|
-
.Response(HttpStatusCode.UNPROCESSABLE_ENTITY, {
|
|
288
|
-
description: 'The request was well-formed but was unable to process operation due to one or many errors.',
|
|
289
|
-
contentType: MimeTypes.opra_response_json,
|
|
290
|
-
});
|
|
291
|
-
if (typeof args.type === 'function')
|
|
292
|
-
decorator.UseType(args.type);
|
|
293
|
-
/**
|
|
294
|
-
*
|
|
295
|
-
*/
|
|
296
|
-
decorator.KeyParam = (name, prmOptions) => {
|
|
297
|
-
decorator.PathParam(name, prmOptions);
|
|
298
|
-
decoratorChain.push((meta) => {
|
|
299
|
-
meta.path = (meta.path || '') + '@:' + name;
|
|
300
|
-
meta.compositionOptions = meta.compositionOptions || {};
|
|
301
|
-
meta.compositionOptions.keyParameter = name;
|
|
302
|
-
});
|
|
303
|
-
return decorator;
|
|
304
|
-
};
|
|
305
|
-
decoratorChain.push((operationMeta) => {
|
|
306
|
-
const compositionOptions = (operationMeta.compositionOptions = operationMeta.compositionOptions || {});
|
|
307
|
-
compositionOptions.type = getDataTypeName(args.type);
|
|
308
|
-
});
|
|
309
|
-
return decorator;
|
|
310
|
-
};
|
|
311
|
-
/**
|
|
312
|
-
* HttpOperation.Entity.UpdateMany
|
|
313
|
-
*/
|
|
314
|
-
HttpOperation.Entity.UpdateMany = function (arg0, arg1) {
|
|
315
|
-
let args;
|
|
316
|
-
if (typeof arg0 === 'object' && !arg0[DATATYPE_METADATA]) {
|
|
317
|
-
args = arg0;
|
|
318
|
-
}
|
|
319
|
-
else
|
|
320
|
-
args = { ...arg1, type: arg0 };
|
|
321
|
-
/** Initialize the decorator and the chain */
|
|
322
|
-
const decoratorChain = [];
|
|
323
|
-
const filterType = new FilterType({ dataType: args.type });
|
|
324
|
-
filterType.rules = {};
|
|
325
|
-
const filterRules = new FilterRules();
|
|
326
|
-
const decorator = HttpOperationDecoratorFactory(decoratorChain, omitUndefined({
|
|
327
|
-
description: args.description,
|
|
328
|
-
method: 'PATCH',
|
|
329
|
-
composition: 'Entity.UpdateMany',
|
|
330
|
-
requestBody: {
|
|
331
|
-
immediateFetch: true,
|
|
332
|
-
partial: 'deep',
|
|
333
|
-
...args.requestBody,
|
|
334
|
-
required: true,
|
|
335
|
-
},
|
|
336
|
-
}));
|
|
337
|
-
decorator.RequestContent(args.requestBody?.type || args.type);
|
|
338
|
-
if (typeof args.type === 'function')
|
|
339
|
-
decorator.UseType(args.type);
|
|
340
|
-
decorator
|
|
341
|
-
.Response(HttpStatusCode.OK, {
|
|
342
|
-
description: 'Operation is successful. Returns OperationResult with "affected" field.',
|
|
343
|
-
contentType: MimeTypes.opra_response_json,
|
|
344
|
-
})
|
|
345
|
-
.Response(HttpStatusCode.UNPROCESSABLE_ENTITY, {
|
|
346
|
-
description: 'The request was well-formed but was unable to process operation due to one or many errors.',
|
|
347
|
-
contentType: MimeTypes.opra_response_json,
|
|
348
|
-
})
|
|
349
|
-
.QueryParam('filter', {
|
|
350
|
-
type: filterType,
|
|
351
|
-
description: 'Determines filter fields',
|
|
352
|
-
});
|
|
353
|
-
decoratorChain.push((operationMeta) => {
|
|
354
|
-
const compositionOptions = (operationMeta.compositionOptions = operationMeta.compositionOptions || {});
|
|
355
|
-
compositionOptions.type = getDataTypeName(args.type);
|
|
356
|
-
});
|
|
357
|
-
decorator.Filter = (field, operators, description) => {
|
|
358
|
-
decoratorChain.push(() => {
|
|
359
|
-
filterRules.set(field, { operators, description });
|
|
360
|
-
filterType.rules = filterRules.toJSON();
|
|
361
|
-
});
|
|
362
|
-
return decorator;
|
|
363
|
-
};
|
|
364
|
-
return decorator;
|
|
365
|
-
};
|
|
366
|
-
/**
|
|
367
|
-
* HttpOperation.Entity.Update
|
|
368
|
-
*/
|
|
369
|
-
HttpOperation.Entity.Update = function (arg0, arg1) {
|
|
370
|
-
let args;
|
|
371
|
-
if (typeof arg0 === 'object' && !arg0[DATATYPE_METADATA]) {
|
|
372
|
-
args = arg0;
|
|
373
|
-
}
|
|
374
|
-
else
|
|
375
|
-
args = { ...arg1, type: arg0 };
|
|
376
|
-
/** Initialize the decorator and the chain */
|
|
377
|
-
const decoratorChain = [];
|
|
378
|
-
const filterRules = new FilterRules();
|
|
379
|
-
const filterType = new FilterType({ dataType: args.type });
|
|
380
|
-
filterType.rules = {};
|
|
381
|
-
const decorator = HttpOperationDecoratorFactory(decoratorChain, omitUndefined({
|
|
382
|
-
description: args.description,
|
|
383
|
-
method: 'PATCH',
|
|
384
|
-
composition: 'Entity.Update',
|
|
385
|
-
requestBody: {
|
|
386
|
-
partial: 'deep',
|
|
387
|
-
...args.requestBody,
|
|
388
|
-
required: true,
|
|
389
|
-
},
|
|
390
|
-
}));
|
|
391
|
-
decorator
|
|
392
|
-
.QueryParam('projection', {
|
|
393
|
-
description: 'Determines fields projection',
|
|
394
|
-
type: new FieldPathType({
|
|
395
|
-
dataType: args.type,
|
|
396
|
-
allowSigns: 'each',
|
|
397
|
-
}),
|
|
398
|
-
isArray: true,
|
|
399
|
-
arraySeparator: ',',
|
|
400
|
-
})
|
|
401
|
-
.QueryParam('filter', {
|
|
402
|
-
type: filterType,
|
|
403
|
-
description: 'Determines filter fields',
|
|
404
|
-
})
|
|
405
|
-
.RequestContent(args.requestBody?.type || args.type)
|
|
406
|
-
.Response(HttpStatusCode.OK, {
|
|
407
|
-
description: 'Operation is successful. Returns OperationResult with "payload" field that contains updated resource.',
|
|
408
|
-
contentType: MimeTypes.opra_response_json,
|
|
409
|
-
type: args.type,
|
|
410
|
-
partial: 'deep',
|
|
411
|
-
})
|
|
412
|
-
.Response(HttpStatusCode.NO_CONTENT, {
|
|
413
|
-
description: 'Operation is successful but no resource found',
|
|
414
|
-
})
|
|
415
|
-
.Response(HttpStatusCode.UNPROCESSABLE_ENTITY, {
|
|
416
|
-
description: 'The request was well-formed but was unable to process operation due to one or many errors.',
|
|
417
|
-
contentType: MimeTypes.opra_response_json,
|
|
418
|
-
});
|
|
419
|
-
if (typeof args.type === 'function')
|
|
420
|
-
decorator.UseType(args.type);
|
|
421
|
-
/**
|
|
422
|
-
*
|
|
423
|
-
*/
|
|
424
|
-
decorator.KeyParam = (name, prmOptions) => {
|
|
425
|
-
decorator.PathParam(name, prmOptions);
|
|
426
|
-
decoratorChain.push((meta) => {
|
|
427
|
-
meta.path = (meta.path || '') + '@:' + name;
|
|
428
|
-
meta.compositionOptions = meta.compositionOptions || {};
|
|
429
|
-
meta.compositionOptions.keyParameter = name;
|
|
430
|
-
});
|
|
431
|
-
return decorator;
|
|
432
|
-
};
|
|
433
|
-
decoratorChain.push((operationMeta) => {
|
|
434
|
-
const compositionOptions = (operationMeta.compositionOptions = operationMeta.compositionOptions || {});
|
|
435
|
-
compositionOptions.type = getDataTypeName(args.type);
|
|
436
|
-
});
|
|
437
|
-
decorator.Filter = (field, operators, description) => {
|
|
438
|
-
decoratorChain.push(() => {
|
|
439
|
-
filterRules.set(field, { operators, description });
|
|
440
|
-
filterType.rules = filterRules.toJSON();
|
|
441
|
-
});
|
|
442
|
-
return decorator;
|
|
443
|
-
};
|
|
444
|
-
return decorator;
|
|
445
|
-
};
|
|
446
|
-
/**
|
|
447
|
-
*
|
|
448
|
-
* @param typ
|
|
449
|
-
*/
|
|
450
|
-
function getDataTypeName(typ) {
|
|
451
|
-
if (typeof typ === 'string')
|
|
452
|
-
return typ;
|
|
453
|
-
const metadata = Reflect.getMetadata(DATATYPE_METADATA, typ);
|
|
454
|
-
if (!metadata)
|
|
455
|
-
throw new TypeError(`Type (${typ}) is not decorated with any datatype decorators`);
|
|
456
|
-
if (metadata?.name)
|
|
457
|
-
return metadata.name;
|
|
458
|
-
throw new TypeError(`You should provide named data type but embedded one found`);
|
|
459
|
-
}
|