@opra/core 0.3.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. package/cjs/adapter/adapter.js +319 -0
  2. package/cjs/{implementation → adapter}/express-adapter.js +3 -6
  3. package/cjs/adapter/http-adapter.js +242 -0
  4. package/cjs/adapter/metadata-resource.js +23 -0
  5. package/cjs/{implementation → adapter}/query-context.js +1 -1
  6. package/cjs/enums/http-headers.enum.js +1 -1
  7. package/cjs/{implementation → helpers}/headers-map.js +2 -2
  8. package/cjs/index.js +6 -5
  9. package/cjs/interfaces/resource.interface.js +2 -0
  10. package/cjs/services/json-collection-service.js +14 -14
  11. package/cjs/services/json-singleton-service.js +97 -0
  12. package/esm/{implementation → adapter}/adapter.d.ts +17 -9
  13. package/esm/adapter/adapter.js +315 -0
  14. package/esm/{implementation → adapter}/express-adapter.d.ts +2 -2
  15. package/esm/{implementation → adapter}/express-adapter.js +3 -6
  16. package/esm/{implementation → adapter}/http-adapter.d.ts +2 -3
  17. package/esm/adapter/http-adapter.js +238 -0
  18. package/esm/adapter/metadata-resource.d.ts +8 -0
  19. package/esm/adapter/metadata-resource.js +20 -0
  20. package/esm/{implementation → adapter}/query-context.d.ts +6 -6
  21. package/esm/{implementation → adapter}/query-context.js +1 -1
  22. package/esm/enums/http-headers.enum.d.ts +1 -1
  23. package/esm/enums/http-headers.enum.js +1 -1
  24. package/esm/{implementation → helpers}/headers-map.d.ts +1 -1
  25. package/esm/{implementation → helpers}/headers-map.js +1 -1
  26. package/esm/index.d.ts +6 -5
  27. package/esm/index.js +6 -5
  28. package/esm/interfaces/resource.interface.d.ts +22 -0
  29. package/esm/interfaces/resource.interface.js +1 -0
  30. package/esm/services/json-collection-service.d.ts +11 -12
  31. package/esm/services/json-collection-service.js +15 -15
  32. package/esm/services/json-singleton-service.d.ts +39 -0
  33. package/esm/services/json-singleton-service.js +92 -0
  34. package/esm/types.d.ts +2 -8
  35. package/esm/utils/create-i18n.d.ts +1 -1
  36. package/package.json +15 -13
  37. package/cjs/implementation/adapter-utils/entity-resource-execute.util.js +0 -86
  38. package/cjs/implementation/adapter-utils/resource-execute.util.js +0 -11
  39. package/cjs/implementation/adapter-utils/resource-prepare.util.js +0 -11
  40. package/cjs/implementation/adapter.js +0 -130
  41. package/cjs/implementation/http-adapter.js +0 -253
  42. package/cjs/interfaces/entity-service.interface.js +0 -30
  43. package/esm/implementation/adapter-utils/entity-resource-execute.util.d.ts +0 -3
  44. package/esm/implementation/adapter-utils/entity-resource-execute.util.js +0 -82
  45. package/esm/implementation/adapter-utils/resource-execute.util.d.ts +0 -3
  46. package/esm/implementation/adapter-utils/resource-execute.util.js +0 -7
  47. package/esm/implementation/adapter-utils/resource-prepare.util.d.ts +0 -3
  48. package/esm/implementation/adapter-utils/resource-prepare.util.js +0 -7
  49. package/esm/implementation/adapter.js +0 -126
  50. package/esm/implementation/http-adapter.js +0 -249
  51. package/esm/interfaces/entity-service.interface.d.ts +0 -19
  52. package/esm/interfaces/entity-service.interface.js +0 -26
@@ -1,30 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.EntityResourceController = void 0;
4
- class EntityResourceController {
5
- async search(ctx) {
6
- return (await this.getService(ctx)).processRequest(ctx);
7
- }
8
- async get(ctx) {
9
- return (await this.getService(ctx)).processRequest(ctx);
10
- }
11
- async count(ctx) {
12
- return (await this.getService(ctx)).processRequest(ctx);
13
- }
14
- async create(ctx) {
15
- return (await this.getService(ctx)).processRequest(ctx);
16
- }
17
- async update(ctx) {
18
- return (await this.getService(ctx)).processRequest(ctx);
19
- }
20
- async updateMany(ctx) {
21
- return (await this.getService(ctx)).processRequest(ctx);
22
- }
23
- async delete(ctx) {
24
- return (await this.getService(ctx)).processRequest(ctx);
25
- }
26
- async deleteMany(ctx) {
27
- return (await this.getService(ctx)).processRequest(ctx);
28
- }
29
- }
30
- exports.EntityResourceController = EntityResourceController;
@@ -1,3 +0,0 @@
1
- import { EntityResource, OpraApi } from '@opra/schema';
2
- import { QueryContext } from '../query-context.js';
3
- export declare function entityResourceExecute(service: OpraApi, resource: EntityResource, context: QueryContext): Promise<void>;
@@ -1,82 +0,0 @@
1
- import { ForbiddenError, ResourceNotFoundError } from '@opra/exception';
2
- import { translate } from '@opra/i18n';
3
- import { ComplexType, OpraCountCollectionQuery } from '@opra/schema';
4
- import { HttpHeaders } from '../../enums/index.js';
5
- export async function entityResourceExecute(service, resource, context) {
6
- const { query } = context;
7
- if (query.kind === 'SearchCollectionQuery') {
8
- const promises = [];
9
- let search;
10
- promises.push(executeFn(service, resource, context)
11
- .then(v => search = v));
12
- if (query.count && resource.metadata.methods.count) {
13
- const ctx = {
14
- query: new OpraCountCollectionQuery(query.resource, { filter: query.filter }),
15
- resultPath: ''
16
- };
17
- Object.setPrototypeOf(ctx, context);
18
- promises.push(executeFn(service, resource, ctx));
19
- }
20
- await Promise.all(promises);
21
- context.response = search;
22
- return;
23
- }
24
- context.response = await executeFn(service, resource, context);
25
- }
26
- async function executeFn(service, resource, context) {
27
- const method = context.query.method;
28
- const resolverInfo = resource.metadata.methods?.[method];
29
- if (!(resolverInfo && resolverInfo.handler))
30
- throw new ForbiddenError({
31
- message: translate('RESOLVER_FORBIDDEN', { method }, `The resource endpoint does not accept '{{method}}' operations`),
32
- severity: 'error',
33
- code: 'RESOLVER_FORBIDDEN'
34
- });
35
- let result = await resolverInfo.handler(context);
36
- switch (method) {
37
- case 'search':
38
- const items = Array.isArray(result) ? result : (context.response ? [result] : []);
39
- context.responseHeaders.set(HttpHeaders.X_Opra_Schema, resource.dataType.name);
40
- return items;
41
- case 'get':
42
- case 'update':
43
- if (!result) {
44
- const query = context.query;
45
- throw new ResourceNotFoundError(resource.name, query.keyValue);
46
- }
47
- break;
48
- case 'count':
49
- context.responseHeaders.set(HttpHeaders.X_Opra_Count, result);
50
- return;
51
- case 'delete':
52
- case 'deleteMany':
53
- case 'updateMany':
54
- let affected;
55
- if (typeof result === 'number')
56
- affected = result;
57
- if (typeof result === 'boolean')
58
- affected = result ? 1 : 0;
59
- if (typeof result === 'object')
60
- affected = result.affectedRows || result.affected;
61
- return {
62
- operation: context.query.method,
63
- affected
64
- };
65
- }
66
- if (!result)
67
- return;
68
- result = Array.isArray(result) ? result[0] : result;
69
- let dataType = resource.dataType;
70
- if (context.resultPath) {
71
- const pathArray = context.resultPath.split('.');
72
- for (const field of pathArray) {
73
- const prop = dataType instanceof ComplexType ? dataType.fields.get(field) : undefined;
74
- dataType = prop && prop.type ? service.types.get(prop.type) : undefined;
75
- result = result && typeof result === 'object' && result[field];
76
- }
77
- }
78
- if (method === 'create')
79
- context.status = 201;
80
- context.responseHeaders.set(HttpHeaders.X_Opra_Schema, resource.dataType.name);
81
- return result;
82
- }
@@ -1,3 +0,0 @@
1
- import { OpraApi, OpraResource } from '@opra/schema';
2
- import { QueryContext } from '../query-context.js';
3
- export declare function resourceExecute(service: OpraApi, resource: OpraResource, context: QueryContext): Promise<void>;
@@ -1,7 +0,0 @@
1
- import { EntityResource } from '@opra/schema';
2
- import { entityResourceExecute } from './entity-resource-execute.util.js';
3
- export async function resourceExecute(service, resource, context) {
4
- if (resource instanceof EntityResource)
5
- return await entityResourceExecute(service, resource, context);
6
- throw new Error(`Executing "${resource.kind}" has not been implemented yet`);
7
- }
@@ -1,3 +0,0 @@
1
- import { OpraResource } from '@opra/schema';
2
- import { QueryContext } from '../query-context.js';
3
- export declare function resourcePrepare(resource: OpraResource, context: QueryContext): Promise<void>;
@@ -1,7 +0,0 @@
1
- export async function resourcePrepare(resource, context) {
2
- const { query } = context;
3
- const fn = resource.metadata['pre_' + query.method];
4
- if (fn && typeof fn === 'function') {
5
- await fn(context);
6
- }
7
- }
@@ -1,126 +0,0 @@
1
- import { AsyncEventEmitter } from 'strict-typed-events';
2
- import { BadRequestError, FailedDependencyError, wrapException } from '@opra/exception';
3
- import { I18n } from '@opra/i18n';
4
- import { createI18n } from '../utils/create-i18n.js';
5
- import { resourceExecute } from './adapter-utils/resource-execute.util.js';
6
- import { resourcePrepare } from './adapter-utils/resource-prepare.util.js';
7
- export class OpraAdapter {
8
- service;
9
- i18n;
10
- userContextResolver;
11
- constructor(service, options) {
12
- this.service = service;
13
- this.i18n = options?.i18n || I18n.defaultInstance;
14
- this.userContextResolver = options?.userContext;
15
- }
16
- async handler(executionContext) {
17
- if (!this.i18n.isInitialized)
18
- await this.i18n.init();
19
- let queryContexts;
20
- let userContext;
21
- let failed = false;
22
- try {
23
- queryContexts = this.prepareRequests(executionContext);
24
- let stop = false;
25
- // Read requests can be executed simultaneously, write request should be executed one by one
26
- let promises;
27
- let exclusive = false;
28
- for (const context of queryContexts) {
29
- exclusive = exclusive || context.query.operation !== 'read';
30
- // Wait previous read requests before executing update request
31
- if (exclusive && promises) {
32
- await Promise.allSettled(promises);
33
- promises = undefined;
34
- }
35
- // If previous request in bucket had an error and executed an update
36
- // we do not execute next requests
37
- if (stop) {
38
- context.errors.push(new FailedDependencyError());
39
- continue;
40
- }
41
- try {
42
- const promise = (async () => {
43
- if (context.query.method === 'metadata') {
44
- await this._getSchemaExecute(context);
45
- return;
46
- }
47
- const resource = context.query.resource;
48
- await resourcePrepare(resource, context);
49
- if (this.userContextResolver && !userContext)
50
- userContext = this.userContextResolver({
51
- executionContext,
52
- isBatch: this.isBatch(executionContext)
53
- });
54
- context.userContext = userContext;
55
- await resourceExecute(this.service, resource, context);
56
- })().catch(e => {
57
- context.errors.push(e);
58
- });
59
- if (exclusive)
60
- await promise;
61
- else {
62
- promises = promises || [];
63
- promises.push(promise);
64
- }
65
- // todo execute sub property queries
66
- }
67
- catch (e) {
68
- context.errors.unshift(e);
69
- }
70
- if (context.errors.length) {
71
- // noinspection SuspiciousTypeOfGuard
72
- context.errors = context.errors.map(e => wrapException(e));
73
- if (exclusive)
74
- stop = stop || !!context.errors.find(e => !(e.issue.severity === 'warning' || e.issue.severity === 'info'));
75
- }
76
- }
77
- if (promises)
78
- await Promise.allSettled(promises);
79
- await this.sendResponse(executionContext, queryContexts);
80
- }
81
- catch (e) {
82
- failed = true;
83
- const error = wrapException(e);
84
- await this.sendError(executionContext, error);
85
- }
86
- finally {
87
- if (executionContext instanceof AsyncEventEmitter) {
88
- await executionContext
89
- .emitAsyncSerial('finish', {
90
- userContext,
91
- failed
92
- }).catch();
93
- }
94
- }
95
- }
96
- async _getSchemaExecute(ctx) {
97
- const query = ctx.query;
98
- let out;
99
- if (query.resourcePath && query.resourcePath.length > 2)
100
- throw new BadRequestError();
101
- if (query.resourcePath?.length) {
102
- if (query.resourcePath[0] === 'resources') {
103
- const resource = this.service.getResource(query.resourcePath[1]);
104
- out = resource.getSchema(true);
105
- query.resourcePath[1] = resource.name;
106
- }
107
- else if (query.resourcePath[0] === 'types') {
108
- const dataType = this.service.getDataType(query.resourcePath[1]);
109
- out = dataType.getSchema(true);
110
- query.resourcePath[1] = dataType.name;
111
- }
112
- else
113
- throw new BadRequestError();
114
- ctx.response = out;
115
- return;
116
- }
117
- ctx.response = this.service.getSchema(true);
118
- }
119
- static async initI18n(options) {
120
- if (options?.i18n instanceof I18n)
121
- return options.i18n;
122
- if (typeof options?.i18n === 'function')
123
- return options.i18n();
124
- return createI18n(options?.i18n);
125
- }
126
- }
@@ -1,249 +0,0 @@
1
- import { BadRequestError, InternalServerError, IssueSeverity, MethodNotAllowedError, NotFoundError, OpraException, wrapException } from '@opra/exception';
2
- import { ComplexType, ContainerResource, EntityResource, OpraCreateInstanceQuery, OpraDeleteCollectionQuery, OpraDeleteInstanceQuery, OpraGetFieldQuery, OpraGetInstanceQuery, OpraGetMetadataQuery, OpraSchema, OpraSearchCollectionQuery, OpraUpdateCollectionQuery, OpraUpdateInstanceQuery, } from '@opra/schema';
3
- import { OpraURL } from '@opra/url';
4
- import { HttpHeaders, HttpStatus } from '../enums/index.js';
5
- import { OpraAdapter } from './adapter.js';
6
- import { HeadersMap } from './headers-map.js';
7
- import { QueryContext } from './query-context.js';
8
- export class OpraHttpAdapter extends OpraAdapter {
9
- prepareRequests(executionContext) {
10
- const req = executionContext.getRequestWrapper();
11
- // todo implement batch requests
12
- if (this.isBatch(executionContext)) {
13
- throw new Error('not implemented yet');
14
- }
15
- const url = new OpraURL(req.getUrl());
16
- return [
17
- this.prepareRequest(executionContext, url, req.getMethod(), new HeadersMap(req.getHeaders()), req.getBody())
18
- ];
19
- }
20
- prepareRequest(executionContext, url, method, headers, body) {
21
- if (!url.path.size)
22
- throw new BadRequestError();
23
- if (method !== 'GET' && url.path.size > 1)
24
- throw new BadRequestError();
25
- const query = this.buildQuery(url, method, body);
26
- if (!query)
27
- throw new MethodNotAllowedError({
28
- message: `Method "${method}" is not allowed by target endpoint`
29
- });
30
- return new QueryContext({
31
- service: this.service,
32
- executionContext,
33
- query,
34
- headers: new HeadersMap(),
35
- params: url.searchParams,
36
- continueOnError: query.operation === 'read'
37
- });
38
- }
39
- buildGGetMetadataQuery(url) {
40
- const pathLen = url.path.size;
41
- const resourcePath = [];
42
- let pathIndex = 0;
43
- while (pathIndex < pathLen) {
44
- const p = url.path.get(pathIndex++);
45
- if (p.key)
46
- throw new BadRequestError();
47
- if (p.resource !== '$metadata') {
48
- if (pathIndex === 1)
49
- resourcePath.push('resources');
50
- resourcePath.push(p.resource);
51
- }
52
- }
53
- const opts = {
54
- pick: url.searchParams.get('$pick'),
55
- omit: url.searchParams.get('$omit'),
56
- include: url.searchParams.get('$include'),
57
- resourcePath
58
- };
59
- return new OpraGetMetadataQuery(opts);
60
- }
61
- buildQuery(url, method, body) {
62
- let container = this.service;
63
- try {
64
- const pathLen = url.path.size;
65
- // Check if requesting metadata
66
- for (let i = 0; i < pathLen; i++) {
67
- const p = url.path.get(i);
68
- if (p.resource === '$metadata') {
69
- if (method !== 'GET')
70
- return;
71
- return this.buildGGetMetadataQuery(url);
72
- }
73
- }
74
- let pathIndex = 0;
75
- while (pathIndex < pathLen) {
76
- let p = url.path.get(pathIndex++);
77
- const resource = container.getResource(p.resource);
78
- // Move through path directories (containers)
79
- if (resource instanceof ContainerResource) {
80
- container = resource;
81
- continue;
82
- }
83
- method = method.toUpperCase();
84
- if (resource instanceof EntityResource) {
85
- const scope = p.key ? 'instance' : 'collection';
86
- if (pathIndex < pathLen && !(method === 'GET' && scope === 'instance'))
87
- return;
88
- let query;
89
- switch (method) {
90
- case 'GET': {
91
- if (scope === 'collection') {
92
- query = new OpraSearchCollectionQuery(resource, {
93
- filter: url.searchParams.get('$filter'),
94
- limit: url.searchParams.get('$limit'),
95
- skip: url.searchParams.get('$skip'),
96
- distinct: url.searchParams.get('$distinct'),
97
- count: url.searchParams.get('$count'),
98
- sort: url.searchParams.get('$sort'),
99
- pick: url.searchParams.get('$pick'),
100
- omit: url.searchParams.get('$omit'),
101
- include: url.searchParams.get('$include'),
102
- });
103
- }
104
- else {
105
- query = new OpraGetInstanceQuery(resource, p.key, {
106
- pick: url.searchParams.get('$pick'),
107
- omit: url.searchParams.get('$omit'),
108
- include: url.searchParams.get('$include')
109
- });
110
- // Move through properties
111
- let dataType = resource.dataType;
112
- const curPath = [];
113
- let parent = query;
114
- while (pathIndex < pathLen) {
115
- if (!(dataType instanceof ComplexType))
116
- throw new TypeError(`"${resource.name}.${curPath.join()}" is not a ComplexType and has no fields.`);
117
- p = url.path.get(pathIndex++);
118
- curPath.push(p.resource);
119
- const field = dataType.getField(p.resource);
120
- parent.nested = new OpraGetFieldQuery(parent, field.name);
121
- parent = parent.nested;
122
- dataType = parent.dataType;
123
- }
124
- }
125
- break;
126
- }
127
- case 'DELETE': {
128
- query = scope === 'collection'
129
- ? new OpraDeleteCollectionQuery(resource, {
130
- filter: url.searchParams.get('$filter'),
131
- })
132
- : new OpraDeleteInstanceQuery(resource, p.key);
133
- break;
134
- }
135
- case 'POST': {
136
- if (scope === 'collection') {
137
- query = new OpraCreateInstanceQuery(resource, body, {
138
- pick: url.searchParams.get('$pick'),
139
- omit: url.searchParams.get('$omit'),
140
- include: url.searchParams.get('$include')
141
- });
142
- }
143
- break;
144
- }
145
- case 'PATCH': {
146
- query = scope === 'collection'
147
- ? new OpraUpdateCollectionQuery(resource, body, {
148
- filter: url.searchParams.get('$filter')
149
- })
150
- : new OpraUpdateInstanceQuery(resource, p.key, body, {
151
- pick: url.searchParams.get('$pick'),
152
- omit: url.searchParams.get('$omit'),
153
- include: url.searchParams.get('$include')
154
- });
155
- break;
156
- }
157
- }
158
- return query;
159
- }
160
- }
161
- throw new InternalServerError();
162
- }
163
- catch (e) {
164
- if (e instanceof OpraException)
165
- throw e;
166
- throw new BadRequestError(e);
167
- }
168
- }
169
- async sendResponse(executionContext, queryContexts) {
170
- const outputPackets = [];
171
- for (const ctx of queryContexts) {
172
- const v = this.createOutput(ctx);
173
- outputPackets.push(v);
174
- }
175
- if (this.isBatch(executionContext)) {
176
- // this.writeError([], new InternalServerError({message: 'Not implemented yet'}));
177
- return;
178
- }
179
- if (!outputPackets.length)
180
- return this.sendError(executionContext, new NotFoundError());
181
- const out = outputPackets[0];
182
- const resp = executionContext.getResponseWrapper();
183
- resp.setStatus(out.status);
184
- resp.setHeader(HttpHeaders.Content_Type, 'application/opra+json');
185
- resp.setHeader(HttpHeaders.Cache_Control, 'no-cache');
186
- resp.setHeader(HttpHeaders.Pragma, 'no-cache');
187
- resp.setHeader(HttpHeaders.Expires, '-1');
188
- resp.setHeader(HttpHeaders.X_Opra_Version, OpraSchema.Version);
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 body;
203
- let status = ctx.status || 0;
204
- const errors = ctx.errors.map(e => wrapException(e));
205
- if (errors && errors.length) {
206
- // Sort errors from fatal to info
207
- errors.sort((a, b) => {
208
- const i = IssueSeverity.Keys.indexOf(a.issue.severity) - IssueSeverity.Keys.indexOf(b.issue.severity);
209
- if (i === 0)
210
- return b.status - a.status;
211
- return i;
212
- });
213
- if (!status || status < HttpStatus.BAD_REQUEST) {
214
- status = errors[0].status;
215
- if (status < HttpStatus.BAD_REQUEST)
216
- status = HttpStatus.INTERNAL_SERVER_ERROR;
217
- }
218
- body = {
219
- operation: ctx.query.method,
220
- errors: errors.map(e => e.issue)
221
- };
222
- }
223
- else {
224
- body = ctx.response;
225
- status = status || (query.operation === 'create' ? HttpStatus.CREATED : HttpStatus.OK);
226
- }
227
- body = this.i18n.deep(body);
228
- return {
229
- status,
230
- headers: ctx.responseHeaders.toObject(),
231
- body
232
- };
233
- }
234
- async sendError(executionContext, error) {
235
- const resp = executionContext.getResponseWrapper();
236
- resp.setStatus(error.status || 500);
237
- resp.setHeader(HttpHeaders.Content_Type, 'application/json');
238
- resp.setHeader(HttpHeaders.Cache_Control, 'no-cache');
239
- resp.setHeader(HttpHeaders.Pragma, 'no-cache');
240
- resp.setHeader(HttpHeaders.Expires, '-1');
241
- resp.setHeader(HttpHeaders.X_Opra_Version, OpraSchema.Version);
242
- const issue = this.i18n.deep(error.issue);
243
- const body = {
244
- operation: 'unknown',
245
- errors: [issue]
246
- };
247
- resp.send(JSON.stringify(body));
248
- }
249
- }
@@ -1,19 +0,0 @@
1
- import { Maybe } from 'ts-gems';
2
- import { IResource, OpraResource } from '@opra/schema';
3
- import { EntityOutput } from '@sqb/connect';
4
- import { QueryContext } from '../implementation/query-context.js';
5
- export interface IEntityService {
6
- processRequest(ctx: QueryContext): any;
7
- }
8
- export declare abstract class EntityResourceController<T, TOutput = EntityOutput<T>> implements IResource {
9
- search(ctx: QueryContext): Promise<TOutput[]>;
10
- get(ctx: QueryContext): Promise<Maybe<TOutput>>;
11
- count(ctx: QueryContext): Promise<number>;
12
- create(ctx: QueryContext): Promise<TOutput>;
13
- update(ctx: QueryContext): Promise<Maybe<TOutput>>;
14
- updateMany(ctx: QueryContext): Promise<Maybe<number>>;
15
- delete(ctx: QueryContext): Promise<Maybe<boolean | number>>;
16
- deleteMany(ctx: QueryContext): Promise<Maybe<number>>;
17
- init?(service: OpraResource): void | Promise<void>;
18
- abstract getService(ctx: QueryContext): IEntityService | Promise<IEntityService>;
19
- }
@@ -1,26 +0,0 @@
1
- export class EntityResourceController {
2
- async search(ctx) {
3
- return (await this.getService(ctx)).processRequest(ctx);
4
- }
5
- async get(ctx) {
6
- return (await this.getService(ctx)).processRequest(ctx);
7
- }
8
- async count(ctx) {
9
- return (await this.getService(ctx)).processRequest(ctx);
10
- }
11
- async create(ctx) {
12
- return (await this.getService(ctx)).processRequest(ctx);
13
- }
14
- async update(ctx) {
15
- return (await this.getService(ctx)).processRequest(ctx);
16
- }
17
- async updateMany(ctx) {
18
- return (await this.getService(ctx)).processRequest(ctx);
19
- }
20
- async delete(ctx) {
21
- return (await this.getService(ctx)).processRequest(ctx);
22
- }
23
- async deleteMany(ctx) {
24
- return (await this.getService(ctx)).processRequest(ctx);
25
- }
26
- }