@opra/core 0.0.13 → 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/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} +21 -18
- package/cjs/implementation/{adapter/express-adapter.js → express-adapter.js} +0 -0
- package/cjs/implementation/{adapter/http-adapter.js → http-adapter.js} +26 -24
- 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 +10 -10
- package/cjs/services/json-data-service.js +11 -5
- 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/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 -5
- package/esm/implementation/{adapter/adapter.js → adapter.js} +18 -15
- 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 -7
- package/esm/implementation/{adapter/http-adapter.js → http-adapter.js} +25 -23
- 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 +25 -26
- package/esm/interfaces/query.interface.js +10 -10
- package/esm/services/json-data-service.d.ts +2 -2
- package/esm/services/json-data-service.js +11 -5
- package/esm/types.d.ts +1 -8
- package/esm/utils/create-i18n.d.ts +1 -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/package.json +6 -6
- package/cjs/constants.js +0 -6
- package/cjs/decorators/api-entity-resource.decorator.js +0 -24
- package/cjs/decorators/api-resolver.decorator.js +0 -13
- package/cjs/implementation/data-type/complex-type.js +0 -53
- package/cjs/implementation/data-type/data-type.js +0 -47
- package/cjs/implementation/data-type/entity-type.js +0 -34
- package/cjs/implementation/data-type/simple-type.js +0 -30
- package/cjs/implementation/opra-document.js +0 -112
- package/cjs/implementation/opra-service.js +0 -81
- package/cjs/implementation/resource/container-resource-handler.js +0 -30
- package/cjs/implementation/resource/entity-resource-handler.js +0 -103
- package/cjs/implementation/resource/resource-handler.js +0 -45
- package/cjs/implementation/schema-generator.js +0 -184
- package/cjs/interfaces/metadata/api-resolver.metadata.js +0 -2
- package/cjs/interfaces/metadata/opra-schema.metadata.js +0 -11
- 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 -3
- package/esm/constants.js +0 -3
- package/esm/decorators/api-entity-resource.decorator.d.ts +0 -5
- package/esm/decorators/api-entity-resource.decorator.js +0 -19
- package/esm/decorators/api-resolver.decorator.d.ts +0 -2
- package/esm/decorators/api-resolver.decorator.js +0 -9
- package/esm/implementation/data-type/complex-type.d.ts +0 -19
- package/esm/implementation/data-type/complex-type.js +0 -48
- package/esm/implementation/data-type/data-type.d.ts +0 -17
- package/esm/implementation/data-type/data-type.js +0 -43
- 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 -107
- package/esm/implementation/opra-service.d.ts +0 -20
- package/esm/implementation/opra-service.js +0 -76
- 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 -98
- package/esm/implementation/resource/resource-handler.d.ts +0 -15
- package/esm/implementation/resource/resource-handler.js +0 -40
- package/esm/implementation/schema-generator.d.ts +0 -21
- package/esm/implementation/schema-generator.js +0 -180
- package/esm/interfaces/metadata/api-resolver.metadata.d.ts +0 -3
- package/esm/interfaces/metadata/api-resolver.metadata.js +0 -1
- package/esm/interfaces/metadata/opra-schema.metadata.d.ts +0 -7
- package/esm/interfaces/metadata/opra-schema.metadata.js +0 -10
- 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
|
@@ -8,7 +8,8 @@ exports.HttpHeaders = void 0;
|
|
|
8
8
|
var HttpHeaders;
|
|
9
9
|
(function (HttpHeaders) {
|
|
10
10
|
/* *** Custom Headers *** */
|
|
11
|
-
HttpHeaders["X_Opra_Version"] = "X-
|
|
11
|
+
HttpHeaders["X_Opra_Version"] = "X-OPRA-Version";
|
|
12
|
+
HttpHeaders["X_Opra_Schema"] = "X-OPRA-Schema";
|
|
12
13
|
/* *** Authentication *** */
|
|
13
14
|
/**
|
|
14
15
|
* Defines the authentication method that should be used to access a resource.
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.entityResourceExecute = void 0;
|
|
4
|
+
const i18n_1 = require("@opra/i18n");
|
|
5
|
+
const schema_1 = require("@opra/schema");
|
|
6
|
+
const index_js_1 = require("../../enums/index.js");
|
|
7
|
+
const index_js_2 = require("../../exception/index.js");
|
|
8
|
+
const query_interface_js_1 = require("../../interfaces/query.interface.js");
|
|
9
|
+
async function entityResourceExecute(service, resource, context) {
|
|
10
|
+
const { query } = context;
|
|
11
|
+
if (query_interface_js_1.OpraQuery.isSearchQuery(query)) {
|
|
12
|
+
const promises = [];
|
|
13
|
+
let search;
|
|
14
|
+
let count;
|
|
15
|
+
promises.push(executeFn(service, resource, context, query.queryType)
|
|
16
|
+
.then(v => search = v));
|
|
17
|
+
if (query.count) {
|
|
18
|
+
promises.push(executeFn(service, resource, context, 'count')
|
|
19
|
+
.then(v => count = v));
|
|
20
|
+
}
|
|
21
|
+
await Promise.all(promises);
|
|
22
|
+
context.response.value = {
|
|
23
|
+
...search,
|
|
24
|
+
...count
|
|
25
|
+
};
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
context.response.value = await executeFn(service, resource, context, query.queryType);
|
|
29
|
+
}
|
|
30
|
+
exports.entityResourceExecute = entityResourceExecute;
|
|
31
|
+
async function executeFn(service, resource, context, queryType) {
|
|
32
|
+
const resolverInfo = resource.metadata.methods?.[queryType];
|
|
33
|
+
if (!resolverInfo.handler)
|
|
34
|
+
throw new index_js_2.ForbiddenError({
|
|
35
|
+
message: (0, i18n_1.translate)('RESOLVER_FORBIDDEN', { queryType }),
|
|
36
|
+
severity: 'error',
|
|
37
|
+
code: 'RESOLVER_FORBIDDEN'
|
|
38
|
+
});
|
|
39
|
+
let result = await resolverInfo.handler(context);
|
|
40
|
+
switch (queryType) {
|
|
41
|
+
case 'search':
|
|
42
|
+
context.response.headers.set(index_js_1.HttpHeaders.X_Opra_Schema, '/$schema/types/' + resource.dataType.name);
|
|
43
|
+
return {
|
|
44
|
+
items: Array.isArray(result) ? result : (context.response.value ? [result] : [])
|
|
45
|
+
};
|
|
46
|
+
case 'get':
|
|
47
|
+
case 'update':
|
|
48
|
+
if (!result) {
|
|
49
|
+
const query = context.query;
|
|
50
|
+
throw new index_js_2.ResourceNotFoundError(resource.name, query.keyValue);
|
|
51
|
+
}
|
|
52
|
+
break;
|
|
53
|
+
case 'count':
|
|
54
|
+
return { count: result || 0 };
|
|
55
|
+
case 'delete':
|
|
56
|
+
case 'deleteMany':
|
|
57
|
+
case 'updateMany':
|
|
58
|
+
let affectedRecords;
|
|
59
|
+
if (typeof result === 'number')
|
|
60
|
+
affectedRecords = result;
|
|
61
|
+
if (typeof result === 'boolean')
|
|
62
|
+
affectedRecords = result ? 1 : 0;
|
|
63
|
+
if (typeof result === 'object')
|
|
64
|
+
affectedRecords = result.affectedRows || result.affectedRecords;
|
|
65
|
+
return { affectedRecords };
|
|
66
|
+
}
|
|
67
|
+
if (!result)
|
|
68
|
+
return;
|
|
69
|
+
result = Array.isArray(result) ? result[0] : result;
|
|
70
|
+
let dataType = resource.dataType;
|
|
71
|
+
if (context.resultPath) {
|
|
72
|
+
const pathArray = context.resultPath.split('.');
|
|
73
|
+
for (const field of pathArray) {
|
|
74
|
+
const prop = dataType instanceof schema_1.ComplexType ? dataType.fields.get(field) : undefined;
|
|
75
|
+
dataType = prop && prop.type ? service.types.get(prop.type) : undefined;
|
|
76
|
+
result = result && typeof result === 'object' && result[field];
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
if (queryType === 'create')
|
|
80
|
+
context.response.status = 201;
|
|
81
|
+
if (dataType)
|
|
82
|
+
context.response.headers.set(index_js_1.HttpHeaders.X_Opra_Schema, '/$schema/types/' + dataType.name);
|
|
83
|
+
return result;
|
|
84
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.resourceExecute = void 0;
|
|
4
|
+
const schema_1 = require("@opra/schema");
|
|
5
|
+
const entity_resource_execute_util_js_1 = require("./entity-resource-execute.util.js");
|
|
6
|
+
async function resourceExecute(service, resource, context) {
|
|
7
|
+
if (resource instanceof schema_1.EntityResource)
|
|
8
|
+
return await (0, entity_resource_execute_util_js_1.entityResourceExecute)(service, resource, context);
|
|
9
|
+
throw new Error(`Executing "${resource.kind}" has not been implemented yet`);
|
|
10
|
+
}
|
|
11
|
+
exports.resourceExecute = resourceExecute;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.resourcePrepare = void 0;
|
|
4
|
+
async function resourcePrepare(resource, context) {
|
|
5
|
+
const { query } = context;
|
|
6
|
+
const fn = resource.metadata['pre_' + query.queryType];
|
|
7
|
+
if (fn && typeof fn === 'function') {
|
|
8
|
+
await fn(context);
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
exports.resourcePrepare = resourcePrepare;
|
|
@@ -3,9 +3,12 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.OpraAdapter = void 0;
|
|
4
4
|
const strict_typed_events_1 = require("strict-typed-events");
|
|
5
5
|
const i18n_1 = require("@opra/i18n");
|
|
6
|
-
const index_js_1 = require("
|
|
7
|
-
const
|
|
8
|
-
const
|
|
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 create_i18n_js_1 = require("../utils/create-i18n.js");
|
|
10
|
+
const resource_execute_util_js_1 = require("./adapter-utils/resource-execute.util.js");
|
|
11
|
+
const resource_prepare_util_js_1 = require("./adapter-utils/resource-prepare.util.js");
|
|
9
12
|
class OpraAdapter {
|
|
10
13
|
service;
|
|
11
14
|
i18n;
|
|
@@ -37,24 +40,24 @@ class OpraAdapter {
|
|
|
37
40
|
// If previous request in bucket had an error and executed an update
|
|
38
41
|
// we do not execute next requests
|
|
39
42
|
if (stop) {
|
|
40
|
-
context.response.errors.push(new
|
|
43
|
+
context.response.errors.push(new index_js_2.FailedDependencyError());
|
|
41
44
|
continue;
|
|
42
45
|
}
|
|
43
46
|
try {
|
|
44
47
|
const promise = (async () => {
|
|
45
|
-
if (context.query.queryType === '
|
|
46
|
-
await this.
|
|
48
|
+
if (context.query.queryType === 'schema') {
|
|
49
|
+
await this._getSchemaExecute(context);
|
|
47
50
|
return;
|
|
48
51
|
}
|
|
49
52
|
const resource = context.query.resource;
|
|
50
|
-
await
|
|
53
|
+
await (0, resource_prepare_util_js_1.resourcePrepare)(resource, context);
|
|
51
54
|
if (this.userContextResolver && !userContext)
|
|
52
55
|
userContext = this.userContextResolver({
|
|
53
56
|
executionContext,
|
|
54
57
|
isBatch: this.isBatch(executionContext)
|
|
55
58
|
});
|
|
56
59
|
context.userContext = userContext;
|
|
57
|
-
await
|
|
60
|
+
await (0, resource_execute_util_js_1.resourceExecute)(this.service, resource, context);
|
|
58
61
|
})().catch(e => {
|
|
59
62
|
context.response.errors.push(e);
|
|
60
63
|
});
|
|
@@ -95,31 +98,31 @@ class OpraAdapter {
|
|
|
95
98
|
}
|
|
96
99
|
}
|
|
97
100
|
}
|
|
98
|
-
async
|
|
101
|
+
async _getSchemaExecute(ctx) {
|
|
99
102
|
const query = ctx.query;
|
|
100
103
|
let out;
|
|
101
104
|
if (query.resourcePath.length > 2)
|
|
102
|
-
throw new
|
|
105
|
+
throw new index_js_2.BadRequestError();
|
|
103
106
|
if (query.resourcePath?.length) {
|
|
104
107
|
if (query.resourcePath[0] === 'resources') {
|
|
105
108
|
const resource = this.service.getResource(query.resourcePath[1]);
|
|
106
|
-
out = resource.
|
|
109
|
+
out = resource.getSchema(true);
|
|
107
110
|
query.resourcePath[1] = resource.name;
|
|
111
|
+
ctx.response.headers.set(index_js_1.HttpHeaders.X_Opra_Schema, 'http://www.oprajs.com/reference/v1/schema#' + resource.kind);
|
|
108
112
|
}
|
|
109
113
|
else if (query.resourcePath[0] === 'types') {
|
|
110
114
|
const dataType = this.service.getDataType(query.resourcePath[1]);
|
|
111
|
-
out = dataType.
|
|
115
|
+
out = dataType.getSchema(true);
|
|
112
116
|
query.resourcePath[1] = dataType.name;
|
|
117
|
+
ctx.response.headers.set(index_js_1.HttpHeaders.X_Opra_Schema, 'http://www.oprajs.com/reference/v1/schema#' + dataType.kind);
|
|
113
118
|
}
|
|
114
119
|
else
|
|
115
|
-
throw new
|
|
116
|
-
ctx.response.value =
|
|
117
|
-
'@opra:metadata': '/$metadata/' + query.resourcePath.join('/'),
|
|
118
|
-
...out
|
|
119
|
-
};
|
|
120
|
+
throw new index_js_2.BadRequestError();
|
|
121
|
+
ctx.response.value = out;
|
|
120
122
|
return;
|
|
121
123
|
}
|
|
122
|
-
ctx.response.
|
|
124
|
+
ctx.response.headers.set(index_js_1.HttpHeaders.X_Opra_Schema, 'http://www.oprajs.com/reference/v1/schema');
|
|
125
|
+
ctx.response.value = this.service.getSchema(true);
|
|
123
126
|
}
|
|
124
127
|
static async initI18n(options) {
|
|
125
128
|
if (options?.i18n instanceof i18n_1.I18n)
|
|
File without changes
|
|
@@ -1,18 +1,14 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.OpraHttpAdapter = void 0;
|
|
4
|
+
const schema_1 = require("@opra/schema");
|
|
4
5
|
const url_1 = require("@opra/url");
|
|
5
|
-
const
|
|
6
|
-
const
|
|
7
|
-
const
|
|
8
|
-
const
|
|
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");
|
|
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");
|
|
15
10
|
const adapter_js_1 = require("./adapter.js");
|
|
11
|
+
const query_context_js_1 = require("./query-context.js");
|
|
16
12
|
class OpraHttpAdapter extends adapter_js_1.OpraAdapter {
|
|
17
13
|
prepareRequests(executionContext) {
|
|
18
14
|
const req = executionContext.getRequestWrapper();
|
|
@@ -22,7 +18,7 @@ class OpraHttpAdapter extends adapter_js_1.OpraAdapter {
|
|
|
22
18
|
}
|
|
23
19
|
const url = new url_1.OpraURL(req.getUrl());
|
|
24
20
|
return [
|
|
25
|
-
this.prepareRequest(executionContext, url, req.getMethod(),
|
|
21
|
+
this.prepareRequest(executionContext, url, req.getMethod(), new schema_1.ResponsiveMap(req.getHeaders()), req.getBody())
|
|
26
22
|
];
|
|
27
23
|
}
|
|
28
24
|
prepareRequest(executionContext, url, method, headers, body) {
|
|
@@ -44,7 +40,7 @@ class OpraHttpAdapter extends adapter_js_1.OpraAdapter {
|
|
|
44
40
|
continueOnError: query.operation === 'read'
|
|
45
41
|
});
|
|
46
42
|
}
|
|
47
|
-
|
|
43
|
+
buildGetSchemaQuery(url) {
|
|
48
44
|
const pathLen = url.path.size;
|
|
49
45
|
const resourcePath = [];
|
|
50
46
|
let pathIndex = 0;
|
|
@@ -52,7 +48,7 @@ class OpraHttpAdapter extends adapter_js_1.OpraAdapter {
|
|
|
52
48
|
const p = url.path.get(pathIndex++);
|
|
53
49
|
if (p.key)
|
|
54
50
|
throw new index_js_2.BadRequestError();
|
|
55
|
-
if (p.resource !== '$
|
|
51
|
+
if (p.resource !== '$schema') {
|
|
56
52
|
if (pathIndex === 1)
|
|
57
53
|
resourcePath.push('resources');
|
|
58
54
|
resourcePath.push(p.resource);
|
|
@@ -63,7 +59,7 @@ class OpraHttpAdapter extends adapter_js_1.OpraAdapter {
|
|
|
63
59
|
omit: url.searchParams.get('$omit'),
|
|
64
60
|
include: url.searchParams.get('$include'),
|
|
65
61
|
};
|
|
66
|
-
return query_interface_js_1.OpraQuery.
|
|
62
|
+
return query_interface_js_1.OpraQuery.forGetSchema(resourcePath, opts);
|
|
67
63
|
}
|
|
68
64
|
buildQuery(url, method, body) {
|
|
69
65
|
let container = this.service;
|
|
@@ -72,10 +68,10 @@ class OpraHttpAdapter extends adapter_js_1.OpraAdapter {
|
|
|
72
68
|
// Check if requesting metadata
|
|
73
69
|
for (let i = 0; i < pathLen; i++) {
|
|
74
70
|
const p = url.path.get(i);
|
|
75
|
-
if (p.resource === '$
|
|
71
|
+
if (p.resource === '$schema') {
|
|
76
72
|
if (method !== 'GET')
|
|
77
73
|
return;
|
|
78
|
-
return this.
|
|
74
|
+
return this.buildGetSchemaQuery(url);
|
|
79
75
|
}
|
|
80
76
|
}
|
|
81
77
|
let pathIndex = 0;
|
|
@@ -83,12 +79,12 @@ class OpraHttpAdapter extends adapter_js_1.OpraAdapter {
|
|
|
83
79
|
let p = url.path.get(pathIndex++);
|
|
84
80
|
const resource = container.getResource(p.resource);
|
|
85
81
|
// Move through path directories (containers)
|
|
86
|
-
if (resource instanceof
|
|
82
|
+
if (resource instanceof schema_1.ContainerResource) {
|
|
87
83
|
container = resource;
|
|
88
84
|
continue;
|
|
89
85
|
}
|
|
90
86
|
method = method.toUpperCase();
|
|
91
|
-
if (resource instanceof
|
|
87
|
+
if (resource instanceof schema_1.EntityResource) {
|
|
92
88
|
const scope = p.key ? 'instance' : 'collection';
|
|
93
89
|
if (pathIndex < pathLen && !(method === 'GET' && scope === 'instance'))
|
|
94
90
|
return;
|
|
@@ -121,11 +117,11 @@ class OpraHttpAdapter extends adapter_js_1.OpraAdapter {
|
|
|
121
117
|
const dataType = nested
|
|
122
118
|
? this.service.getDataType(nested.property.type || 'string')
|
|
123
119
|
: query.resource.dataType;
|
|
124
|
-
if (!(dataType instanceof
|
|
125
|
-
throw new Error(`"${path}" is not a ComplexType and has no
|
|
120
|
+
if (!(dataType instanceof schema_1.ComplexType))
|
|
121
|
+
throw new Error(`"${path}" is not a ComplexType and has no fields.`);
|
|
126
122
|
p = url.path.get(pathIndex++);
|
|
127
123
|
path += '.' + p.resource;
|
|
128
|
-
const prop = dataType.
|
|
124
|
+
const prop = dataType.fields.get(p.resource);
|
|
129
125
|
if (!prop)
|
|
130
126
|
throw new index_js_2.NotFoundError({ message: `Invalid or unknown resource path (${path})` });
|
|
131
127
|
const q = query_interface_js_1.OpraQuery.forGetProperty(prop);
|
|
@@ -212,7 +208,7 @@ class OpraHttpAdapter extends adapter_js_1.OpraAdapter {
|
|
|
212
208
|
resp.setHeader(index_js_1.HttpHeaders.Cache_Control, 'no-cache');
|
|
213
209
|
resp.setHeader(index_js_1.HttpHeaders.Pragma, 'no-cache');
|
|
214
210
|
resp.setHeader(index_js_1.HttpHeaders.Expires, '-1');
|
|
215
|
-
resp.setHeader(index_js_1.HttpHeaders.X_Opra_Version,
|
|
211
|
+
resp.setHeader(index_js_1.HttpHeaders.X_Opra_Version, schema_1.OpraSchema.Version);
|
|
216
212
|
if (out.headers) {
|
|
217
213
|
for (const [k, v] of Object.entries(out.headers)) {
|
|
218
214
|
resp.setHeader(k, v);
|
|
@@ -244,10 +240,16 @@ class OpraHttpAdapter extends adapter_js_1.OpraAdapter {
|
|
|
244
240
|
delete body.errors;
|
|
245
241
|
status = status || (query.operation === 'create' ? index_js_1.HttpStatus.CREATED : index_js_1.HttpStatus.OK);
|
|
246
242
|
}
|
|
243
|
+
// Convert headers map to object
|
|
244
|
+
const headers = Array.from(ctx.response.headers.keys()).map(k => k.toLowerCase()).sort()
|
|
245
|
+
.reduce((a, k) => {
|
|
246
|
+
a[k] = ctx.response.headers.get(k);
|
|
247
|
+
return a;
|
|
248
|
+
}, {});
|
|
247
249
|
body = this.i18n.deep(body);
|
|
248
250
|
return {
|
|
249
251
|
status,
|
|
250
|
-
headers
|
|
252
|
+
headers,
|
|
251
253
|
body
|
|
252
254
|
};
|
|
253
255
|
}
|
|
@@ -258,7 +260,7 @@ class OpraHttpAdapter extends adapter_js_1.OpraAdapter {
|
|
|
258
260
|
resp.setHeader(index_js_1.HttpHeaders.Cache_Control, 'no-cache');
|
|
259
261
|
resp.setHeader(index_js_1.HttpHeaders.Pragma, 'no-cache');
|
|
260
262
|
resp.setHeader(index_js_1.HttpHeaders.Expires, '-1');
|
|
261
|
-
resp.setHeader(index_js_1.HttpHeaders.X_Opra_Version,
|
|
263
|
+
resp.setHeader(index_js_1.HttpHeaders.X_Opra_Version, schema_1.OpraSchema.Version);
|
|
262
264
|
resp.send(JSON.stringify(error.response));
|
|
263
265
|
}
|
|
264
266
|
}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.QueryResponse = exports.QueryContext = void 0;
|
|
4
|
+
const schema_1 = require("@opra/schema");
|
|
4
5
|
const url_1 = require("@opra/url");
|
|
5
|
-
const
|
|
6
|
+
const index_js_1 = require("../enums/index.js");
|
|
6
7
|
class QueryContext {
|
|
7
8
|
service;
|
|
8
9
|
executionContext;
|
|
@@ -18,7 +19,7 @@ class QueryContext {
|
|
|
18
19
|
Object.assign(this, args);
|
|
19
20
|
this.response = new QueryResponse();
|
|
20
21
|
this.params = this.params || new url_1.OpraURLSearchParams();
|
|
21
|
-
this.headers = this.headers ||
|
|
22
|
+
this.headers = this.headers || new schema_1.ResponsiveMap();
|
|
22
23
|
this.resultPath = this.resultPath || '';
|
|
23
24
|
}
|
|
24
25
|
get type() {
|
|
@@ -32,7 +33,7 @@ class QueryContext {
|
|
|
32
33
|
}
|
|
33
34
|
exports.QueryContext = QueryContext;
|
|
34
35
|
class QueryResponse {
|
|
35
|
-
headers
|
|
36
|
+
headers;
|
|
36
37
|
errors = [];
|
|
37
38
|
status;
|
|
38
39
|
value;
|
|
@@ -40,6 +41,7 @@ class QueryResponse {
|
|
|
40
41
|
constructor(args) {
|
|
41
42
|
if (args)
|
|
42
43
|
Object.assign(this, args);
|
|
44
|
+
this.headers = new schema_1.ResponsiveMap(undefined, Array.from(Object.values(index_js_1.HttpHeaders)));
|
|
43
45
|
}
|
|
44
46
|
}
|
|
45
47
|
exports.QueryResponse = QueryResponse;
|
package/cjs/index.js
CHANGED
|
@@ -2,25 +2,15 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
const tslib_1 = require("tslib");
|
|
4
4
|
require("reflect-metadata");
|
|
5
|
-
tslib_1.__exportStar(require("./constants.js"), exports);
|
|
6
5
|
tslib_1.__exportStar(require("./types.js"), exports);
|
|
7
6
|
tslib_1.__exportStar(require("./enums/index.js"), exports);
|
|
8
7
|
tslib_1.__exportStar(require("./exception/index.js"), exports);
|
|
9
|
-
tslib_1.__exportStar(require("./decorators/api-entity-resource.decorator.js"), exports);
|
|
10
8
|
tslib_1.__exportStar(require("./interfaces/execution-context.interface.js"), exports);
|
|
11
9
|
tslib_1.__exportStar(require("./interfaces/query.interface.js"), exports);
|
|
12
|
-
tslib_1.__exportStar(require("./interfaces/
|
|
10
|
+
tslib_1.__exportStar(require("./interfaces/entity-service.interface.js"), exports);
|
|
13
11
|
tslib_1.__exportStar(require("./implementation/query-context.js"), exports);
|
|
14
|
-
tslib_1.__exportStar(require("./implementation/
|
|
15
|
-
tslib_1.__exportStar(require("./implementation/
|
|
16
|
-
tslib_1.__exportStar(require("./implementation/
|
|
17
|
-
tslib_1.__exportStar(require("./
|
|
18
|
-
tslib_1.__exportStar(require("./implementation/adapter/http-adapter.js"), exports);
|
|
19
|
-
tslib_1.__exportStar(require("./implementation/adapter/express-adapter.js"), exports);
|
|
20
|
-
tslib_1.__exportStar(require("./implementation/data-type/data-type.js"), exports);
|
|
21
|
-
tslib_1.__exportStar(require("./implementation/data-type/complex-type.js"), exports);
|
|
22
|
-
tslib_1.__exportStar(require("./implementation/data-type/simple-type.js"), exports);
|
|
23
|
-
tslib_1.__exportStar(require("./implementation/resource/resource-handler.js"), exports);
|
|
24
|
-
tslib_1.__exportStar(require("./implementation/resource/entity-resource-handler.js"), exports);
|
|
25
|
-
tslib_1.__exportStar(require("./services/entity-resource-controller.js"), exports);
|
|
12
|
+
tslib_1.__exportStar(require("./implementation/adapter.js"), exports);
|
|
13
|
+
tslib_1.__exportStar(require("./implementation/http-adapter.js"), exports);
|
|
14
|
+
tslib_1.__exportStar(require("./implementation/express-adapter.js"), exports);
|
|
15
|
+
tslib_1.__exportStar(require("./services/data-service.js"), exports);
|
|
26
16
|
tslib_1.__exportStar(require("./services/json-data-service.js"), exports);
|
package/cjs/{services/entity-resource-controller.js → interfaces/entity-service.interface.js}
RENAMED
|
File without changes
|
|
@@ -3,8 +3,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.OpraQuery = void 0;
|
|
4
4
|
const tslib_1 = require("tslib");
|
|
5
5
|
const lodash_1 = tslib_1.__importDefault(require("lodash"));
|
|
6
|
-
const
|
|
7
|
-
const
|
|
6
|
+
const schema_1 = require("@opra/schema");
|
|
7
|
+
const path_to_tree_js_1 = require("../utils/path-to-tree.js");
|
|
8
8
|
var OpraQuery;
|
|
9
9
|
(function (OpraQuery) {
|
|
10
10
|
function forCreate(resource, values, options) {
|
|
@@ -25,7 +25,7 @@ var OpraQuery;
|
|
|
25
25
|
return out;
|
|
26
26
|
}
|
|
27
27
|
OpraQuery.forCreate = forCreate;
|
|
28
|
-
function
|
|
28
|
+
function forGetSchema(resourcePath, options) {
|
|
29
29
|
// if (options?.pick)
|
|
30
30
|
// options.pick = normalizePick(resource, options.pick);
|
|
31
31
|
// if (options?.omit)
|
|
@@ -33,7 +33,7 @@ var OpraQuery;
|
|
|
33
33
|
// if (options?.include)
|
|
34
34
|
// options.include = normalizePick(resource, options.include);
|
|
35
35
|
const out = {
|
|
36
|
-
queryType: '
|
|
36
|
+
queryType: 'schema',
|
|
37
37
|
scope: 'instance',
|
|
38
38
|
resourcePath,
|
|
39
39
|
operation: 'read',
|
|
@@ -41,7 +41,7 @@ var OpraQuery;
|
|
|
41
41
|
Object.assign(out, lodash_1.default.omit(options, Object.keys(out)));
|
|
42
42
|
return out;
|
|
43
43
|
}
|
|
44
|
-
OpraQuery.
|
|
44
|
+
OpraQuery.forGetSchema = forGetSchema;
|
|
45
45
|
function forGetEntity(resource, key, options) {
|
|
46
46
|
if (options?.pick)
|
|
47
47
|
options.pick = normalizePick(resource, options.pick);
|
|
@@ -168,19 +168,19 @@ function checkKeyFields(resource, key) {
|
|
|
168
168
|
throw new Error(`"${resource.name}" has no primary key`);
|
|
169
169
|
}
|
|
170
170
|
function normalizePick(resource, fields) {
|
|
171
|
-
const fieldsTree = (0,
|
|
171
|
+
const fieldsTree = (0, path_to_tree_js_1.pathToTree)(fields) || {};
|
|
172
172
|
return _normalizeFieldsList([], resource.service, resource, resource.dataType, fieldsTree, '', {
|
|
173
|
-
|
|
173
|
+
additionalFields: true
|
|
174
174
|
});
|
|
175
175
|
}
|
|
176
176
|
function _normalizeFieldsList(target, service, resource, dataType, node, parentPath = '', options) {
|
|
177
177
|
let curPath = '';
|
|
178
178
|
for (const k of Object.keys(node)) {
|
|
179
179
|
const nodeVal = node[k];
|
|
180
|
-
const prop = dataType?.
|
|
180
|
+
const prop = dataType?.fields.get(k);
|
|
181
181
|
if (!prop) {
|
|
182
182
|
curPath = parentPath ? parentPath + '.' + k : k;
|
|
183
|
-
if (!options?.
|
|
183
|
+
if (!options?.additionalFields || (dataType && !dataType.additionalFields))
|
|
184
184
|
throw new TypeError(`Unknown field path "${resource.name + '.' + curPath}"`);
|
|
185
185
|
if (typeof nodeVal === 'object')
|
|
186
186
|
_normalizeFieldsList(target, service, resource, undefined, nodeVal, curPath, options);
|
|
@@ -191,7 +191,7 @@ function _normalizeFieldsList(target, service, resource, dataType, node, parentP
|
|
|
191
191
|
curPath = parentPath ? parentPath + '.' + prop.name : prop.name;
|
|
192
192
|
const propType = service.getDataType(prop.type || 'string');
|
|
193
193
|
if (typeof nodeVal === 'object') {
|
|
194
|
-
if (!(propType instanceof
|
|
194
|
+
if (!(propType && propType instanceof schema_1.ComplexType))
|
|
195
195
|
throw new TypeError(`"${curPath}" is not a complex type and has no sub fields`);
|
|
196
196
|
if (target.findIndex(x => x === parentPath) >= 0)
|
|
197
197
|
continue;
|
|
@@ -29,7 +29,7 @@ class JsonDataService {
|
|
|
29
29
|
get(keyValue, options) {
|
|
30
30
|
const primaryKey = this.primaryKey;
|
|
31
31
|
let v = this.data.find(x => '' + x[primaryKey] === '' + keyValue);
|
|
32
|
-
v = JsonDataService.
|
|
32
|
+
v = JsonDataService.filterFields(v, options?.pick, options?.omit, options?.include);
|
|
33
33
|
return v;
|
|
34
34
|
}
|
|
35
35
|
count(options) {
|
|
@@ -44,20 +44,20 @@ class JsonDataService {
|
|
|
44
44
|
}
|
|
45
45
|
else
|
|
46
46
|
out = this.data;
|
|
47
|
-
return out.map(v => JsonDataService.
|
|
47
|
+
return out.map(v => JsonDataService.filterFields(v, options?.pick, options?.omit, options?.include));
|
|
48
48
|
}
|
|
49
49
|
create(data, options) {
|
|
50
50
|
if (this.get(data[this.primaryKey]))
|
|
51
51
|
throw new index_js_1.ResourceConflictError(this.resourceName, this.primaryKey);
|
|
52
52
|
this.data.push(data);
|
|
53
|
-
return JsonDataService.
|
|
53
|
+
return JsonDataService.filterFields(data, options?.pick, options?.omit, options?.include);
|
|
54
54
|
}
|
|
55
55
|
update(keyValue, data, options) {
|
|
56
56
|
const primaryKey = this.primaryKey;
|
|
57
57
|
const i = this.data.findIndex(x => '' + x[primaryKey] === '' + keyValue);
|
|
58
58
|
if (i >= 0) {
|
|
59
59
|
data = Object.assign(this.data[i], data);
|
|
60
|
-
return JsonDataService.
|
|
60
|
+
return JsonDataService.filterFields(data, options?.pick, options?.omit, options?.include);
|
|
61
61
|
}
|
|
62
62
|
}
|
|
63
63
|
updateMany(data, options) {
|
|
@@ -81,7 +81,13 @@ class JsonDataService {
|
|
|
81
81
|
this.data = this.data.filter(x => !items.includes(x));
|
|
82
82
|
return items.length;
|
|
83
83
|
}
|
|
84
|
-
static
|
|
84
|
+
static filterFields(obj,
|
|
85
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
86
|
+
pick,
|
|
87
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
88
|
+
omit,
|
|
89
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
90
|
+
include) {
|
|
85
91
|
if (!obj)
|
|
86
92
|
return;
|
|
87
93
|
return obj;
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.pathToTree = void 0;
|
|
4
4
|
const dotPattern = /^([^.]+)\.(.*)$/;
|
|
5
|
-
function
|
|
5
|
+
function pathToTree(arr) {
|
|
6
6
|
if (!arr.length)
|
|
7
7
|
return;
|
|
8
8
|
return _stringPathToObjectTree(arr, {});
|
|
9
9
|
}
|
|
10
|
-
exports.
|
|
10
|
+
exports.pathToTree = pathToTree;
|
|
11
11
|
function _stringPathToObjectTree(arr, target) {
|
|
12
12
|
for (const k of arr) {
|
|
13
13
|
const m = dotPattern.exec(k);
|
|
@@ -2,7 +2,8 @@
|
|
|
2
2
|
* https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers#controls
|
|
3
3
|
*/
|
|
4
4
|
export declare enum HttpHeaders {
|
|
5
|
-
X_Opra_Version = "X-
|
|
5
|
+
X_Opra_Version = "X-OPRA-Version",
|
|
6
|
+
X_Opra_Schema = "X-OPRA-Schema",
|
|
6
7
|
/**
|
|
7
8
|
* Defines the authentication method that should be used to access a resource.
|
|
8
9
|
*/
|
|
@@ -5,7 +5,8 @@
|
|
|
5
5
|
export var HttpHeaders;
|
|
6
6
|
(function (HttpHeaders) {
|
|
7
7
|
/* *** Custom Headers *** */
|
|
8
|
-
HttpHeaders["X_Opra_Version"] = "X-
|
|
8
|
+
HttpHeaders["X_Opra_Version"] = "X-OPRA-Version";
|
|
9
|
+
HttpHeaders["X_Opra_Schema"] = "X-OPRA-Schema";
|
|
9
10
|
/* *** Authentication *** */
|
|
10
11
|
/**
|
|
11
12
|
* Defines the authentication method that should be used to access a resource.
|