@opra/core 0.0.12 → 0.1.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.
- package/cjs/enums/http-headers.enum.js +2 -1
- package/cjs/exception/http-errors/not-acceptable.error.js +26 -0
- package/cjs/exception/index.js +2 -0
- package/cjs/exception/resource-errors/resource-not-found.error.js +19 -0
- package/cjs/implementation/adapter-utils/entity-resource-execute.util.js +84 -0
- package/cjs/implementation/adapter-utils/resource-execute.util.js +11 -0
- package/cjs/implementation/adapter-utils/resource-prepare.util.js +11 -0
- package/cjs/implementation/{adapter/adapter.js → adapter.js} +40 -7
- package/cjs/implementation/{adapter/express-adapter.js → express-adapter.js} +0 -0
- package/cjs/implementation/http-adapter.js +267 -0
- package/cjs/implementation/query-context.js +5 -3
- package/cjs/index.js +5 -15
- package/cjs/{services/entity-resource-controller.js → interfaces/entity-service.interface.js} +0 -0
- package/cjs/interfaces/query.interface.js +26 -9
- package/cjs/services/json-data-service.js +241 -4
- package/cjs/utils/create-i18n.js +1 -1
- package/cjs/utils/get-caller-file.util.js +6 -1
- package/cjs/utils/{string-path-to-object-tree.js → path-to-tree.js} +3 -3
- package/esm/enums/http-headers.enum.d.ts +2 -1
- package/esm/enums/http-headers.enum.js +2 -1
- package/esm/exception/http-errors/not-acceptable.error.d.ts +10 -0
- package/esm/exception/http-errors/not-acceptable.error.js +22 -0
- package/esm/exception/index.d.ts +2 -0
- package/esm/exception/index.js +2 -0
- package/esm/exception/resource-errors/resource-not-found.error.d.ts +4 -0
- package/esm/exception/resource-errors/resource-not-found.error.js +15 -0
- package/esm/implementation/adapter-utils/entity-resource-execute.util.d.ts +3 -0
- package/esm/implementation/adapter-utils/entity-resource-execute.util.js +80 -0
- package/esm/implementation/adapter-utils/resource-execute.util.d.ts +3 -0
- package/esm/implementation/adapter-utils/resource-execute.util.js +7 -0
- package/esm/implementation/adapter-utils/resource-prepare.util.d.ts +3 -0
- package/esm/implementation/adapter-utils/resource-prepare.util.js +7 -0
- package/esm/implementation/{adapter/adapter.d.ts → adapter.d.ts} +5 -9
- package/esm/implementation/{adapter/adapter.js → adapter.js} +39 -6
- package/esm/implementation/{adapter/express-adapter.d.ts → express-adapter.d.ts} +2 -2
- package/esm/implementation/{adapter/express-adapter.js → express-adapter.js} +0 -0
- package/esm/implementation/{adapter/http-adapter.d.ts → http-adapter.d.ts} +6 -6
- package/esm/implementation/http-adapter.js +263 -0
- package/esm/implementation/query-context.d.ts +3 -4
- package/esm/implementation/query-context.js +5 -3
- package/esm/index.d.ts +5 -15
- package/esm/index.js +5 -15
- package/esm/{services/entity-resource-controller.d.ts → interfaces/entity-service.interface.d.ts} +0 -0
- package/esm/{services/entity-resource-controller.js → interfaces/entity-service.interface.js} +0 -0
- package/esm/interfaces/query.interface.d.ts +31 -25
- package/esm/interfaces/query.interface.js +26 -9
- package/esm/services/json-data-service.d.ts +66 -7
- package/esm/services/json-data-service.js +241 -4
- package/esm/types.d.ts +10 -8
- package/esm/utils/create-i18n.d.ts +1 -1
- package/esm/utils/create-i18n.js +1 -1
- package/esm/utils/get-caller-file.util.d.ts +1 -1
- package/esm/utils/get-caller-file.util.js +6 -1
- package/esm/utils/path-to-tree.d.ts +4 -0
- package/esm/utils/{string-path-to-object-tree.js → path-to-tree.js} +1 -1
- package/i18n/en/error.json +3 -0
- package/package.json +6 -7
- package/cjs/constants.js +0 -5
- package/cjs/decorators/entity-resource.decorator.js +0 -24
- package/cjs/implementation/adapter/http-adapter.js +0 -238
- package/cjs/implementation/data-type/complex-type.js +0 -39
- package/cjs/implementation/data-type/data-type.js +0 -35
- package/cjs/implementation/data-type/entity-type.js +0 -33
- package/cjs/implementation/data-type/simple-type.js +0 -30
- package/cjs/implementation/opra-document.js +0 -116
- package/cjs/implementation/opra-service.js +0 -59
- package/cjs/implementation/resource/container-resource-handler.js +0 -30
- package/cjs/implementation/resource/entity-resource-handler.js +0 -80
- package/cjs/implementation/resource/resource-handler.js +0 -31
- package/cjs/implementation/schema-generator.js +0 -163
- package/cjs/interfaces/opra-schema.metadata.js +0 -2
- package/cjs/interfaces/resource-container.interface.js +0 -2
- package/cjs/utils/class-utils.js +0 -37
- package/cjs/utils/headers.js +0 -58
- package/cjs/utils/internal-data-types.js +0 -81
- package/cjs/utils/responsive-object.js +0 -49
- package/cjs/utils/terminal-utils.js +0 -7
- package/esm/constants.d.ts +0 -2
- package/esm/constants.js +0 -2
- package/esm/decorators/entity-resource.decorator.d.ts +0 -5
- package/esm/decorators/entity-resource.decorator.js +0 -19
- package/esm/implementation/adapter/http-adapter.js +0 -234
- package/esm/implementation/data-type/complex-type.d.ts +0 -18
- package/esm/implementation/data-type/complex-type.js +0 -35
- package/esm/implementation/data-type/data-type.d.ts +0 -15
- package/esm/implementation/data-type/data-type.js +0 -31
- package/esm/implementation/data-type/entity-type.d.ts +0 -10
- package/esm/implementation/data-type/entity-type.js +0 -29
- package/esm/implementation/data-type/simple-type.d.ts +0 -15
- package/esm/implementation/data-type/simple-type.js +0 -26
- package/esm/implementation/opra-document.d.ts +0 -26
- package/esm/implementation/opra-document.js +0 -111
- package/esm/implementation/opra-service.d.ts +0 -19
- package/esm/implementation/opra-service.js +0 -55
- package/esm/implementation/resource/container-resource-handler.d.ts +0 -14
- package/esm/implementation/resource/container-resource-handler.js +0 -26
- package/esm/implementation/resource/entity-resource-handler.d.ts +0 -18
- package/esm/implementation/resource/entity-resource-handler.js +0 -75
- package/esm/implementation/resource/resource-handler.d.ts +0 -15
- package/esm/implementation/resource/resource-handler.js +0 -27
- package/esm/implementation/schema-generator.d.ts +0 -21
- package/esm/implementation/schema-generator.js +0 -159
- package/esm/interfaces/opra-schema.metadata.d.ts +0 -14
- package/esm/interfaces/opra-schema.metadata.js +0 -1
- package/esm/interfaces/resource-container.interface.d.ts +0 -6
- package/esm/interfaces/resource-container.interface.js +0 -1
- package/esm/utils/class-utils.d.ts +0 -6
- package/esm/utils/class-utils.js +0 -30
- package/esm/utils/headers.d.ts +0 -9
- package/esm/utils/headers.js +0 -55
- package/esm/utils/internal-data-types.d.ts +0 -5
- package/esm/utils/internal-data-types.js +0 -78
- package/esm/utils/responsive-object.d.ts +0 -3
- package/esm/utils/responsive-object.js +0 -45
- package/esm/utils/string-path-to-object-tree.d.ts +0 -4
- package/esm/utils/terminal-utils.d.ts +0 -4
- package/esm/utils/terminal-utils.js +0 -4
|
@@ -1,238 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.OpraHttpAdapter = void 0;
|
|
4
|
-
const url_1 = require("@opra/url");
|
|
5
|
-
const constants_js_1 = require("../../constants.js");
|
|
6
|
-
const index_js_1 = require("../../enums/index.js");
|
|
7
|
-
const index_js_2 = require("../../exception/index.js");
|
|
8
|
-
const wrap_error_js_1 = require("../../exception/wrap-error.js");
|
|
9
|
-
const query_interface_js_1 = require("../../interfaces/query.interface.js");
|
|
10
|
-
const headers_js_1 = require("../../utils/headers.js");
|
|
11
|
-
const complex_type_js_1 = require("../data-type/complex-type.js");
|
|
12
|
-
const query_context_js_1 = require("../query-context.js");
|
|
13
|
-
const container_resource_handler_js_1 = require("../resource/container-resource-handler.js");
|
|
14
|
-
const entity_resource_handler_js_1 = require("../resource/entity-resource-handler.js");
|
|
15
|
-
const adapter_js_1 = require("./adapter.js");
|
|
16
|
-
class OpraHttpAdapter extends adapter_js_1.OpraAdapter {
|
|
17
|
-
prepareRequests(executionContext) {
|
|
18
|
-
const req = executionContext.getRequestWrapper();
|
|
19
|
-
// todo implement batch requests
|
|
20
|
-
if (this.isBatch(executionContext)) {
|
|
21
|
-
throw new Error('not implemented yet');
|
|
22
|
-
}
|
|
23
|
-
const url = new url_1.OpraURL(req.getUrl());
|
|
24
|
-
return [
|
|
25
|
-
this.prepareRequest(executionContext, url, req.getMethod(), headers_js_1.Headers.from(req.getHeaders()), req.getBody())
|
|
26
|
-
];
|
|
27
|
-
}
|
|
28
|
-
prepareRequest(executionContext, url, method, headers, body) {
|
|
29
|
-
if (!url.path.size)
|
|
30
|
-
throw new index_js_2.BadRequestError();
|
|
31
|
-
if (method !== 'GET' && url.path.size > 1)
|
|
32
|
-
throw new index_js_2.BadRequestError();
|
|
33
|
-
const query = this.buildQuery(url, method, body);
|
|
34
|
-
if (!query)
|
|
35
|
-
throw new index_js_2.MethodNotAllowedError({
|
|
36
|
-
message: `Method "${method}" is not allowed by target resource`
|
|
37
|
-
});
|
|
38
|
-
return new query_context_js_1.QueryContext({
|
|
39
|
-
service: this.service,
|
|
40
|
-
executionContext,
|
|
41
|
-
query,
|
|
42
|
-
headers,
|
|
43
|
-
params: url.searchParams,
|
|
44
|
-
continueOnError: query.operation === 'read'
|
|
45
|
-
});
|
|
46
|
-
}
|
|
47
|
-
buildQuery(url, method, body) {
|
|
48
|
-
let container = this.service;
|
|
49
|
-
try {
|
|
50
|
-
let pathIndex = 0;
|
|
51
|
-
const pathLen = url.path.size;
|
|
52
|
-
while (pathIndex < pathLen) {
|
|
53
|
-
let p = url.path.get(pathIndex++);
|
|
54
|
-
const resource = container.getResource(p.resource);
|
|
55
|
-
// Move through path directories (containers)
|
|
56
|
-
if (resource instanceof container_resource_handler_js_1.ContainerResourceHandler) {
|
|
57
|
-
container = resource;
|
|
58
|
-
}
|
|
59
|
-
else {
|
|
60
|
-
method = method.toUpperCase();
|
|
61
|
-
if (resource instanceof entity_resource_handler_js_1.EntityResourceHandler) {
|
|
62
|
-
const scope = p.key ? 'instance' : 'collection';
|
|
63
|
-
if (pathIndex < pathLen && !(method === 'GET' && scope === 'instance'))
|
|
64
|
-
return;
|
|
65
|
-
let query;
|
|
66
|
-
switch (method) {
|
|
67
|
-
case 'GET': {
|
|
68
|
-
if (scope === 'collection') {
|
|
69
|
-
query = query_interface_js_1.OpraQuery.forSearch(resource, {
|
|
70
|
-
filter: url.searchParams.get('$filter'),
|
|
71
|
-
limit: url.searchParams.get('$limit'),
|
|
72
|
-
skip: url.searchParams.get('$skip'),
|
|
73
|
-
distinct: url.searchParams.get('$distinct'),
|
|
74
|
-
count: url.searchParams.get('$count'),
|
|
75
|
-
sort: url.searchParams.get('$sort'),
|
|
76
|
-
pick: url.searchParams.get('$pick'),
|
|
77
|
-
omit: url.searchParams.get('$omit'),
|
|
78
|
-
include: url.searchParams.get('$include'),
|
|
79
|
-
});
|
|
80
|
-
}
|
|
81
|
-
else {
|
|
82
|
-
query = query_interface_js_1.OpraQuery.forGet(resource, p.key, {
|
|
83
|
-
pick: url.searchParams.get('$pick'),
|
|
84
|
-
omit: url.searchParams.get('$omit'),
|
|
85
|
-
include: url.searchParams.get('$include')
|
|
86
|
-
});
|
|
87
|
-
// Move through properties
|
|
88
|
-
let nested;
|
|
89
|
-
let path = resource.name;
|
|
90
|
-
while (pathIndex < pathLen) {
|
|
91
|
-
const dataType = nested
|
|
92
|
-
? this.service.getDataType(nested.property.type || 'string')
|
|
93
|
-
: query.resource.dataType;
|
|
94
|
-
if (!(dataType instanceof complex_type_js_1.ComplexType))
|
|
95
|
-
throw new Error(`"${path}" is not a ComplexType and has no properties.`);
|
|
96
|
-
p = url.path.get(pathIndex++);
|
|
97
|
-
path += '.' + p.resource;
|
|
98
|
-
const prop = dataType.properties?.[p.resource];
|
|
99
|
-
if (!prop)
|
|
100
|
-
throw new index_js_2.NotFoundError({ message: `Invalid or unknown resource path (${path})` });
|
|
101
|
-
const q = query_interface_js_1.OpraQuery.forGetProperty(prop);
|
|
102
|
-
if (nested) {
|
|
103
|
-
nested.nested = q;
|
|
104
|
-
}
|
|
105
|
-
else {
|
|
106
|
-
query.nested = q;
|
|
107
|
-
}
|
|
108
|
-
nested = q;
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
break;
|
|
112
|
-
}
|
|
113
|
-
case 'DELETE': {
|
|
114
|
-
if (scope === 'collection') {
|
|
115
|
-
query = query_interface_js_1.OpraQuery.forDeleteMany(resource, {
|
|
116
|
-
filter: url.searchParams.get('$filter'),
|
|
117
|
-
});
|
|
118
|
-
}
|
|
119
|
-
else {
|
|
120
|
-
query = query_interface_js_1.OpraQuery.forDelete(resource, p.key);
|
|
121
|
-
}
|
|
122
|
-
break;
|
|
123
|
-
}
|
|
124
|
-
case 'POST': {
|
|
125
|
-
if (scope === 'collection') {
|
|
126
|
-
query = query_interface_js_1.OpraQuery.forCreate(resource, body, {
|
|
127
|
-
pick: url.searchParams.get('$pick'),
|
|
128
|
-
omit: url.searchParams.get('$omit'),
|
|
129
|
-
include: url.searchParams.get('$include')
|
|
130
|
-
});
|
|
131
|
-
}
|
|
132
|
-
break;
|
|
133
|
-
}
|
|
134
|
-
case 'PATCH': {
|
|
135
|
-
if (scope === 'collection') {
|
|
136
|
-
query = query_interface_js_1.OpraQuery.forUpdateMany(resource, body, {
|
|
137
|
-
filter: url.searchParams.get('$filter')
|
|
138
|
-
});
|
|
139
|
-
}
|
|
140
|
-
else {
|
|
141
|
-
query = query_interface_js_1.OpraQuery.forUpdate(resource, p.key, body, {
|
|
142
|
-
pick: url.searchParams.get('$pick'),
|
|
143
|
-
omit: url.searchParams.get('$omit'),
|
|
144
|
-
include: url.searchParams.get('$include')
|
|
145
|
-
});
|
|
146
|
-
}
|
|
147
|
-
break;
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
return query;
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
throw new index_js_2.InternalServerError();
|
|
155
|
-
}
|
|
156
|
-
catch (e) {
|
|
157
|
-
if (e instanceof index_js_2.ApiException)
|
|
158
|
-
throw e;
|
|
159
|
-
throw new index_js_2.BadRequestError({ message: e.message });
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
|
-
async sendResponse(executionContext, queryContexts) {
|
|
163
|
-
const outputPackets = [];
|
|
164
|
-
for (const ctx of queryContexts) {
|
|
165
|
-
const v = this.createOutput(ctx);
|
|
166
|
-
outputPackets.push(v);
|
|
167
|
-
}
|
|
168
|
-
if (this.isBatch(executionContext)) {
|
|
169
|
-
// this.writeError([], new InternalServerError({message: 'Not implemented yet'}));
|
|
170
|
-
return;
|
|
171
|
-
}
|
|
172
|
-
if (!outputPackets.length) {
|
|
173
|
-
const err = new index_js_2.NotFoundError();
|
|
174
|
-
outputPackets.push({
|
|
175
|
-
status: err.status,
|
|
176
|
-
body: {
|
|
177
|
-
errors: [err.response]
|
|
178
|
-
}
|
|
179
|
-
});
|
|
180
|
-
}
|
|
181
|
-
const out = outputPackets[0];
|
|
182
|
-
const resp = executionContext.getResponseWrapper();
|
|
183
|
-
resp.setStatus(out.status);
|
|
184
|
-
resp.setHeader(index_js_1.HttpHeaders.Content_Type, 'application/json');
|
|
185
|
-
resp.setHeader(index_js_1.HttpHeaders.Cache_Control, 'no-cache');
|
|
186
|
-
resp.setHeader(index_js_1.HttpHeaders.Pragma, 'no-cache');
|
|
187
|
-
resp.setHeader(index_js_1.HttpHeaders.Expires, '-1');
|
|
188
|
-
resp.setHeader(index_js_1.HttpHeaders.X_Opra_Version, constants_js_1.OpraVersion);
|
|
189
|
-
if (out.headers) {
|
|
190
|
-
for (const [k, v] of Object.entries(out.headers)) {
|
|
191
|
-
resp.setHeader(k, v);
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
resp.send(JSON.stringify(out.body));
|
|
195
|
-
}
|
|
196
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
197
|
-
isBatch(executionContext) {
|
|
198
|
-
return false;
|
|
199
|
-
}
|
|
200
|
-
createOutput(ctx) {
|
|
201
|
-
const { query } = ctx;
|
|
202
|
-
let status = ctx.response.status;
|
|
203
|
-
let body = ctx.response.value || {};
|
|
204
|
-
const errors = ctx.response.errors?.map(e => (0, wrap_error_js_1.wrapError)(e));
|
|
205
|
-
if (errors && errors.length) {
|
|
206
|
-
if (!status || status < 400) {
|
|
207
|
-
status = 0;
|
|
208
|
-
for (const e of errors) {
|
|
209
|
-
status = Math.max(status, e.status || status);
|
|
210
|
-
}
|
|
211
|
-
if (status < index_js_1.HttpStatus.BAD_REQUEST)
|
|
212
|
-
status = index_js_1.HttpStatus.INTERNAL_SERVER_ERROR;
|
|
213
|
-
}
|
|
214
|
-
body.errors = errors.map(e => e.response);
|
|
215
|
-
}
|
|
216
|
-
else {
|
|
217
|
-
delete body.errors;
|
|
218
|
-
status = status || (query.operation === 'create' ? index_js_1.HttpStatus.CREATED : index_js_1.HttpStatus.OK);
|
|
219
|
-
}
|
|
220
|
-
body = this.i18n.deep(body);
|
|
221
|
-
return {
|
|
222
|
-
status,
|
|
223
|
-
headers: ctx.response.headers,
|
|
224
|
-
body
|
|
225
|
-
};
|
|
226
|
-
}
|
|
227
|
-
async sendError(executionContext, error) {
|
|
228
|
-
const resp = executionContext.getResponseWrapper();
|
|
229
|
-
resp.setStatus(error.status || 500);
|
|
230
|
-
resp.setHeader(index_js_1.HttpHeaders.Content_Type, 'application/json');
|
|
231
|
-
resp.setHeader(index_js_1.HttpHeaders.Cache_Control, 'no-cache');
|
|
232
|
-
resp.setHeader(index_js_1.HttpHeaders.Pragma, 'no-cache');
|
|
233
|
-
resp.setHeader(index_js_1.HttpHeaders.Expires, '-1');
|
|
234
|
-
resp.setHeader(index_js_1.HttpHeaders.X_Opra_Version, constants_js_1.OpraVersion);
|
|
235
|
-
resp.send(JSON.stringify(error.response));
|
|
236
|
-
}
|
|
237
|
-
}
|
|
238
|
-
exports.OpraHttpAdapter = OpraHttpAdapter;
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.ComplexType = void 0;
|
|
4
|
-
const responsive_object_js_1 = require("../../utils/responsive-object.js");
|
|
5
|
-
const terminal_utils_js_1 = require("../../utils/terminal-utils.js");
|
|
6
|
-
const data_type_js_1 = require("./data-type.js");
|
|
7
|
-
class ComplexType extends data_type_js_1.DataType {
|
|
8
|
-
ownProperties;
|
|
9
|
-
properties;
|
|
10
|
-
constructor(owner, args, base) {
|
|
11
|
-
super(owner, {
|
|
12
|
-
kind: 'ComplexType',
|
|
13
|
-
...args
|
|
14
|
-
}, base);
|
|
15
|
-
this.ownProperties = args?.properties && (0, responsive_object_js_1.Responsive)(args.properties);
|
|
16
|
-
this.properties = (base?.properties || this.ownProperties) &&
|
|
17
|
-
(0, responsive_object_js_1.Responsive)({ ...base?.properties, ...this.ownProperties });
|
|
18
|
-
}
|
|
19
|
-
get abstract() {
|
|
20
|
-
return !!this._args.abstract;
|
|
21
|
-
}
|
|
22
|
-
get additionalProperties() {
|
|
23
|
-
return this._args.additionalProperties;
|
|
24
|
-
}
|
|
25
|
-
getProperty(name) {
|
|
26
|
-
const t = this.properties?.[name];
|
|
27
|
-
if (!t)
|
|
28
|
-
throw new Error(`"${this.name}" type has no property named "${name}"`);
|
|
29
|
-
return t;
|
|
30
|
-
}
|
|
31
|
-
toString() {
|
|
32
|
-
return `[${Object.getPrototypeOf(this).constructor.name} ${this.name}]`;
|
|
33
|
-
}
|
|
34
|
-
[terminal_utils_js_1.nodeInspectCustom]() {
|
|
35
|
-
return `[${terminal_utils_js_1.colorFgYellow + Object.getPrototypeOf(this).constructor.name + terminal_utils_js_1.colorReset}` +
|
|
36
|
-
` ${terminal_utils_js_1.colorFgMagenta + this.name + terminal_utils_js_1.colorReset}]`;
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
exports.ComplexType = ComplexType;
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.DataType = void 0;
|
|
4
|
-
class DataType {
|
|
5
|
-
_owner;
|
|
6
|
-
_args;
|
|
7
|
-
base;
|
|
8
|
-
constructor(owner, args, base) {
|
|
9
|
-
this._args = { ...args };
|
|
10
|
-
this._owner = owner;
|
|
11
|
-
if (base) {
|
|
12
|
-
this.base = base;
|
|
13
|
-
Object.setPrototypeOf(this._args, base._args);
|
|
14
|
-
}
|
|
15
|
-
}
|
|
16
|
-
get owner() {
|
|
17
|
-
return this._owner;
|
|
18
|
-
}
|
|
19
|
-
get kind() {
|
|
20
|
-
return this._args.kind;
|
|
21
|
-
}
|
|
22
|
-
get name() {
|
|
23
|
-
return this._args.name;
|
|
24
|
-
}
|
|
25
|
-
get description() {
|
|
26
|
-
return this._args.description;
|
|
27
|
-
}
|
|
28
|
-
get ctor() {
|
|
29
|
-
return this._args.ctor;
|
|
30
|
-
}
|
|
31
|
-
is(typeName) {
|
|
32
|
-
return this.name === typeName || !!(this.base && this.base.is(typeName));
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
exports.DataType = DataType;
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.EntityType = void 0;
|
|
4
|
-
const optionals_1 = require("@opra/optionals");
|
|
5
|
-
const complex_type_js_1 = require("./complex-type.js");
|
|
6
|
-
class EntityType extends complex_type_js_1.ComplexType {
|
|
7
|
-
constructor(owner, args, base) {
|
|
8
|
-
super(owner, {
|
|
9
|
-
...args
|
|
10
|
-
}, base);
|
|
11
|
-
this._args.kind = 'EntityType';
|
|
12
|
-
// Try to determine primary key info from SQB
|
|
13
|
-
if (args.ctor) {
|
|
14
|
-
const sqbEntity = optionals_1.SqbConnect.EntityMetadata.get(args.ctor);
|
|
15
|
-
if (sqbEntity?.indexes) {
|
|
16
|
-
const primaryIndex = sqbEntity.indexes.find(x => x.primary);
|
|
17
|
-
if (primaryIndex) {
|
|
18
|
-
if (primaryIndex.columns.length > 1)
|
|
19
|
-
throw new TypeError(`Multi-key indexes is not implemented yet`);
|
|
20
|
-
this._args.primaryKey = primaryIndex.columns[0];
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
if (!this.primaryKey)
|
|
25
|
-
throw new TypeError(`You must provide primaryKey fo "${this.name}" entity`);
|
|
26
|
-
if (!this.getProperty(this.primaryKey))
|
|
27
|
-
throw new TypeError(`"${this.name}" entity has no such property named "${this.primaryKey}" which defined as primary key`);
|
|
28
|
-
}
|
|
29
|
-
get primaryKey() {
|
|
30
|
-
return this._args.primaryKey;
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
exports.EntityType = EntityType;
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.SimpleType = void 0;
|
|
4
|
-
const terminal_utils_js_1 = require("../../utils/terminal-utils.js");
|
|
5
|
-
const data_type_js_1 = require("./data-type.js");
|
|
6
|
-
class SimpleType extends data_type_js_1.DataType {
|
|
7
|
-
constructor(owner, args, base) {
|
|
8
|
-
super(owner, {
|
|
9
|
-
kind: 'SimpleType',
|
|
10
|
-
...args
|
|
11
|
-
}, base);
|
|
12
|
-
}
|
|
13
|
-
get type() {
|
|
14
|
-
return this._args.type;
|
|
15
|
-
}
|
|
16
|
-
get format() {
|
|
17
|
-
return this._args.format;
|
|
18
|
-
}
|
|
19
|
-
get default() {
|
|
20
|
-
return this._args.default;
|
|
21
|
-
}
|
|
22
|
-
toString() {
|
|
23
|
-
return `[${Object.getPrototypeOf(this).constructor.name} ${this.name}]`;
|
|
24
|
-
}
|
|
25
|
-
[terminal_utils_js_1.nodeInspectCustom]() {
|
|
26
|
-
return `[${terminal_utils_js_1.colorFgYellow + Object.getPrototypeOf(this).constructor.name + terminal_utils_js_1.colorReset}` +
|
|
27
|
-
` ${terminal_utils_js_1.colorFgMagenta + this.name + terminal_utils_js_1.colorReset}]`;
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
exports.SimpleType = SimpleType;
|
|
@@ -1,116 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.OpraDocument = void 0;
|
|
4
|
-
const tslib_1 = require("tslib");
|
|
5
|
-
const lodash_1 = tslib_1.__importDefault(require("lodash"));
|
|
6
|
-
const schema_1 = require("@opra/schema");
|
|
7
|
-
const internal_data_types_js_1 = require("../utils/internal-data-types.js");
|
|
8
|
-
const responsive_object_js_1 = require("../utils/responsive-object.js");
|
|
9
|
-
const terminal_utils_js_1 = require("../utils/terminal-utils.js");
|
|
10
|
-
const complex_type_js_1 = require("./data-type/complex-type.js");
|
|
11
|
-
const entity_type_js_1 = require("./data-type/entity-type.js");
|
|
12
|
-
const simple_type_js_1 = require("./data-type/simple-type.js");
|
|
13
|
-
const schema_generator_js_1 = require("./schema-generator.js");
|
|
14
|
-
class OpraDocument {
|
|
15
|
-
_args;
|
|
16
|
-
_types = (0, responsive_object_js_1.Responsive)();
|
|
17
|
-
constructor(schema) {
|
|
18
|
-
this._args = lodash_1.default.omit(schema, 'types');
|
|
19
|
-
if (schema.types)
|
|
20
|
-
this._addDataTypes(schema.types);
|
|
21
|
-
}
|
|
22
|
-
get name() {
|
|
23
|
-
return this._args.info?.title || '';
|
|
24
|
-
}
|
|
25
|
-
get info() {
|
|
26
|
-
return this._args.info;
|
|
27
|
-
}
|
|
28
|
-
get types() {
|
|
29
|
-
return this._types;
|
|
30
|
-
}
|
|
31
|
-
getDataType(name) {
|
|
32
|
-
const t = this.types[name];
|
|
33
|
-
if (!t)
|
|
34
|
-
throw new Error(`Data type "${name}" does not exists`);
|
|
35
|
-
return t;
|
|
36
|
-
}
|
|
37
|
-
getComplexDataType(name) {
|
|
38
|
-
const t = this.getDataType(name);
|
|
39
|
-
if (!(t instanceof complex_type_js_1.ComplexType))
|
|
40
|
-
throw new Error(`Data type "${name}" is not a ComplexType`);
|
|
41
|
-
return t;
|
|
42
|
-
}
|
|
43
|
-
getEntityDataType(name) {
|
|
44
|
-
const t = this.getDataType(name);
|
|
45
|
-
if (!(t instanceof entity_type_js_1.EntityType))
|
|
46
|
-
throw new Error(`Data type "${name}" is not an EntityType`);
|
|
47
|
-
return t;
|
|
48
|
-
}
|
|
49
|
-
getSimpleDataType(name) {
|
|
50
|
-
const t = this.getDataType(name);
|
|
51
|
-
if (!(t instanceof simple_type_js_1.SimpleType))
|
|
52
|
-
throw new Error(`Data type "${name}" is not a SimpleType`);
|
|
53
|
-
return t;
|
|
54
|
-
}
|
|
55
|
-
toString() {
|
|
56
|
-
return `[${Object.getPrototypeOf(this).constructor.name} ${this.name}]`;
|
|
57
|
-
}
|
|
58
|
-
[terminal_utils_js_1.nodeInspectCustom]() {
|
|
59
|
-
return `[${terminal_utils_js_1.colorFgYellow + Object.getPrototypeOf(this).constructor.name + terminal_utils_js_1.colorReset}` +
|
|
60
|
-
` ${terminal_utils_js_1.colorFgMagenta + this.name + terminal_utils_js_1.colorReset}]`;
|
|
61
|
-
}
|
|
62
|
-
static async create(args) {
|
|
63
|
-
const schema = await schema_generator_js_1.SchemaGenerator.generateDocumentSchema(args);
|
|
64
|
-
return new OpraDocument(schema);
|
|
65
|
-
}
|
|
66
|
-
_addDataTypes(dataTypes) {
|
|
67
|
-
const recursiveSet = new Set();
|
|
68
|
-
const nameSet = new Set(dataTypes.map(x => x.name));
|
|
69
|
-
const processDataType = (schema) => {
|
|
70
|
-
if ((!internal_data_types_js_1.internalDataTypes.has(schema.name) && !nameSet.has(schema.name)) || this.types[schema.name])
|
|
71
|
-
return;
|
|
72
|
-
if (recursiveSet.has(schema.name))
|
|
73
|
-
throw new TypeError(`Recursive dependency detected. ${Array.from(recursiveSet).join('>')}`);
|
|
74
|
-
recursiveSet.add(schema.name);
|
|
75
|
-
let baseType;
|
|
76
|
-
if (schema.base) {
|
|
77
|
-
if (!this.types[schema.base]) {
|
|
78
|
-
const baseSchema = dataTypes.find(dt => dt.name.toLowerCase() === schema.base?.toLowerCase()) ||
|
|
79
|
-
internal_data_types_js_1.internalDataTypes.get(schema.base.toLowerCase());
|
|
80
|
-
if (!baseSchema)
|
|
81
|
-
throw new TypeError(`Base schema (${schema.base}) of data type "${schema.name}" does not exists`);
|
|
82
|
-
baseType = processDataType(baseSchema);
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
let dataType;
|
|
86
|
-
if (schema_1.OpraSchema.isSimpleType(schema)) {
|
|
87
|
-
if (baseType && !(baseType instanceof simple_type_js_1.SimpleType))
|
|
88
|
-
throw new TypeError(`Can't extend a SimpleType (${schema.name}) from a ComplexType "${baseType.name}"`);
|
|
89
|
-
dataType = new simple_type_js_1.SimpleType(this, schema, baseType);
|
|
90
|
-
}
|
|
91
|
-
else if (schema_1.OpraSchema.isComplexType(schema)) {
|
|
92
|
-
if (baseType && !(baseType instanceof complex_type_js_1.ComplexType))
|
|
93
|
-
throw new TypeError(`Can't extend a ComplexType (${schema.name}) from a SimpleType "${baseType.name}"`);
|
|
94
|
-
dataType = new complex_type_js_1.ComplexType(this, schema, baseType);
|
|
95
|
-
}
|
|
96
|
-
else if (schema_1.OpraSchema.isEntityType(schema)) {
|
|
97
|
-
if (baseType && !(baseType instanceof complex_type_js_1.ComplexType))
|
|
98
|
-
throw new TypeError(`Can't extend an EntityType (${schema.name}) from a SimpleType "${baseType.name}"`);
|
|
99
|
-
dataType = new entity_type_js_1.EntityType(this, schema, baseType);
|
|
100
|
-
}
|
|
101
|
-
else
|
|
102
|
-
throw new TypeError(`Invalid data type schema`);
|
|
103
|
-
nameSet.delete(schema.name);
|
|
104
|
-
this.types[dataType.name] = dataType;
|
|
105
|
-
recursiveSet.delete(schema.name);
|
|
106
|
-
return dataType;
|
|
107
|
-
};
|
|
108
|
-
dataTypes.forEach(dataType => processDataType(dataType));
|
|
109
|
-
// Sort data types by name
|
|
110
|
-
const newTypes = (0, responsive_object_js_1.Responsive)();
|
|
111
|
-
Object.keys(this.types).sort()
|
|
112
|
-
.forEach(name => newTypes[name] = this.types[name]);
|
|
113
|
-
this._types = newTypes;
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
exports.OpraDocument = OpraDocument;
|
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.OpraService = void 0;
|
|
4
|
-
const schema_1 = require("@opra/schema");
|
|
5
|
-
const responsive_object_js_1 = require("../utils/responsive-object.js");
|
|
6
|
-
const entity_type_js_1 = require("./data-type/entity-type.js");
|
|
7
|
-
const opra_document_js_1 = require("./opra-document.js");
|
|
8
|
-
const entity_resource_handler_js_1 = require("./resource/entity-resource-handler.js");
|
|
9
|
-
const schema_generator_js_1 = require("./schema-generator.js");
|
|
10
|
-
class OpraService extends opra_document_js_1.OpraDocument {
|
|
11
|
-
_resources = (0, responsive_object_js_1.Responsive)();
|
|
12
|
-
constructor(schema) {
|
|
13
|
-
super(schema);
|
|
14
|
-
if (schema.resources)
|
|
15
|
-
this._addResources(schema.resources);
|
|
16
|
-
}
|
|
17
|
-
get resources() {
|
|
18
|
-
return this._resources;
|
|
19
|
-
}
|
|
20
|
-
get servers() {
|
|
21
|
-
return this._args.servers;
|
|
22
|
-
}
|
|
23
|
-
getResource(name) {
|
|
24
|
-
const t = this.resources[name];
|
|
25
|
-
if (!t)
|
|
26
|
-
throw new Error(`Resource "${name}" does not exists`);
|
|
27
|
-
return t;
|
|
28
|
-
}
|
|
29
|
-
getEntityResource(name) {
|
|
30
|
-
const t = this.getResource(name);
|
|
31
|
-
if (!(t instanceof entity_resource_handler_js_1.EntityResourceHandler))
|
|
32
|
-
throw new Error(`"${name}" is not an EntityResource`);
|
|
33
|
-
return t;
|
|
34
|
-
}
|
|
35
|
-
_addResources(resources) {
|
|
36
|
-
for (const r of resources) {
|
|
37
|
-
if (schema_1.OpraSchema.isEntityResource(r)) {
|
|
38
|
-
const dataType = this.getDataType(r.type);
|
|
39
|
-
if (!dataType)
|
|
40
|
-
throw new TypeError(`Datatype "${r.type}" declared in EntityResource (${r.name}) does not exists`);
|
|
41
|
-
if (!(dataType instanceof entity_type_js_1.EntityType))
|
|
42
|
-
throw new TypeError(`${r.type} is not an EntityType`);
|
|
43
|
-
this.resources[r.name] = new entity_resource_handler_js_1.EntityResourceHandler({ ...r, service: this, dataType });
|
|
44
|
-
}
|
|
45
|
-
else
|
|
46
|
-
throw new TypeError(`Unknown resource kind (${r.kind})`);
|
|
47
|
-
}
|
|
48
|
-
// Sort data types by name
|
|
49
|
-
const newResources = (0, responsive_object_js_1.Responsive)();
|
|
50
|
-
Object.keys(this.resources).sort()
|
|
51
|
-
.forEach(name => newResources[name] = this.resources[name]);
|
|
52
|
-
this._resources = newResources;
|
|
53
|
-
}
|
|
54
|
-
static async create(args) {
|
|
55
|
-
const schema = await schema_generator_js_1.SchemaGenerator.generateServiceSchema(args);
|
|
56
|
-
return new OpraService(schema);
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
exports.OpraService = OpraService;
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.ContainerResourceHandler = void 0;
|
|
4
|
-
const entity_resource_handler_js_1 = require("./entity-resource-handler.js");
|
|
5
|
-
const resource_handler_js_1 = require("./resource-handler.js");
|
|
6
|
-
class ContainerResourceHandler extends resource_handler_js_1.ResourceHandler {
|
|
7
|
-
constructor(args) {
|
|
8
|
-
super({
|
|
9
|
-
kind: 'ContainerResource',
|
|
10
|
-
...args
|
|
11
|
-
});
|
|
12
|
-
}
|
|
13
|
-
getResource(name) {
|
|
14
|
-
const t = this._args.resources[name];
|
|
15
|
-
if (!t)
|
|
16
|
-
throw new Error(`Resource "${name}" does not exists`);
|
|
17
|
-
return t;
|
|
18
|
-
}
|
|
19
|
-
getEntityResource(name) {
|
|
20
|
-
const t = this.getResource(name);
|
|
21
|
-
if (!(t instanceof entity_resource_handler_js_1.EntityResourceHandler))
|
|
22
|
-
throw new Error(`"${name}" is not an EntityResource`);
|
|
23
|
-
return t;
|
|
24
|
-
}
|
|
25
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
26
|
-
execute(ctx) {
|
|
27
|
-
return Promise.resolve(undefined);
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
exports.ContainerResourceHandler = ContainerResourceHandler;
|
|
@@ -1,80 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.EntityResourceHandler = void 0;
|
|
4
|
-
const tslib_1 = require("tslib");
|
|
5
|
-
const lodash_1 = tslib_1.__importDefault(require("lodash"));
|
|
6
|
-
const query_interface_js_1 = require("../../interfaces/query.interface.js");
|
|
7
|
-
const entity_type_js_1 = require("../data-type/entity-type.js");
|
|
8
|
-
const resource_handler_js_1 = require("./resource-handler.js");
|
|
9
|
-
var isSearchQuery = query_interface_js_1.OpraQuery.isSearchQuery;
|
|
10
|
-
const index_js_1 = require("../../exception/index.js");
|
|
11
|
-
class EntityResourceHandler extends resource_handler_js_1.ResourceHandler {
|
|
12
|
-
service;
|
|
13
|
-
dataType;
|
|
14
|
-
constructor(args) {
|
|
15
|
-
super({
|
|
16
|
-
kind: 'EntityResource',
|
|
17
|
-
...lodash_1.default.omit(args, ['dataType', 'service'])
|
|
18
|
-
});
|
|
19
|
-
this.dataType = args.dataType;
|
|
20
|
-
this.service = args.service;
|
|
21
|
-
// noinspection SuspiciousTypeOfGuard
|
|
22
|
-
if (!(args.dataType instanceof entity_type_js_1.EntityType))
|
|
23
|
-
throw new TypeError(`You should provide an EntityType for EntityResourceController`);
|
|
24
|
-
}
|
|
25
|
-
async execute(ctx) {
|
|
26
|
-
const { query } = ctx;
|
|
27
|
-
if (isSearchQuery(query)) {
|
|
28
|
-
const promises = [];
|
|
29
|
-
let search;
|
|
30
|
-
let count;
|
|
31
|
-
promises.push(this._executeFn(ctx, query.queryType)
|
|
32
|
-
.then(v => search = v));
|
|
33
|
-
if (query.count) {
|
|
34
|
-
promises.push(this._executeFn(ctx, 'count')
|
|
35
|
-
.then(v => count = v));
|
|
36
|
-
}
|
|
37
|
-
await Promise.all(promises);
|
|
38
|
-
ctx.response.value = {
|
|
39
|
-
...search,
|
|
40
|
-
...count
|
|
41
|
-
};
|
|
42
|
-
return;
|
|
43
|
-
}
|
|
44
|
-
ctx.response.value = await this._executeFn(ctx, query.queryType);
|
|
45
|
-
}
|
|
46
|
-
async _executeFn(ctx, fnName) {
|
|
47
|
-
const fn = this._args[fnName];
|
|
48
|
-
let result = typeof fn === 'function' ? (await fn(ctx)) : undefined;
|
|
49
|
-
switch (fnName) {
|
|
50
|
-
case 'search':
|
|
51
|
-
return { items: Array.isArray(result) ? result : (ctx.response.value ? [result] : []) };
|
|
52
|
-
case 'count':
|
|
53
|
-
return { count: result || 0 };
|
|
54
|
-
case 'delete':
|
|
55
|
-
case 'deleteMany':
|
|
56
|
-
case 'updateMany':
|
|
57
|
-
let affectedRecords;
|
|
58
|
-
if (typeof result === 'number')
|
|
59
|
-
affectedRecords = result;
|
|
60
|
-
if (typeof result === 'boolean')
|
|
61
|
-
affectedRecords = result ? 1 : 0;
|
|
62
|
-
if (typeof result === 'object')
|
|
63
|
-
affectedRecords = result.affectedRows || result.affectedRecords;
|
|
64
|
-
return { affectedRecords };
|
|
65
|
-
}
|
|
66
|
-
result = Array.isArray(result) ? result[0] : result;
|
|
67
|
-
if (!result)
|
|
68
|
-
throw new index_js_1.UnprocessableEntityError();
|
|
69
|
-
if (ctx.resultPath) {
|
|
70
|
-
const pathArray = ctx.resultPath.split('.');
|
|
71
|
-
for (const property of pathArray) {
|
|
72
|
-
result = result && typeof result === 'object' && result[property];
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
if (fnName === 'create')
|
|
76
|
-
ctx.response.status = 201;
|
|
77
|
-
return result;
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
exports.EntityResourceHandler = EntityResourceHandler;
|