@opra/core 0.26.4 → 0.27.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.
@@ -1,7 +1,7 @@
1
1
  import path from 'path';
2
2
  import { pascalCase } from 'putil-varhelpers';
3
3
  import { AsyncEventEmitter } from 'strict-typed-events';
4
- import { Container, CrudResource, ForbiddenError, getStackFileName, I18n, Resource, translate } from '@opra/common';
4
+ import { BadRequestError, Container, CrudResource, ForbiddenError, getStackFileName, I18n, Resource, translate } from '@opra/common';
5
5
  import { Logger } from './services/logger.js';
6
6
  const resourceInitialized = Symbol.for('opra.resource.initialized');
7
7
  /**
@@ -98,20 +98,36 @@ export class PlatformAdapterHost extends AsyncEventEmitter {
98
98
  }
99
99
  return controller;
100
100
  }
101
- async getOperationHandler(resource, operationOrAction) {
101
+ async getActionHandler(resource, name) {
102
102
  resource = typeof resource === 'object' && resource instanceof Resource
103
103
  ? resource
104
104
  : this.api.getResource(resource);
105
105
  const controller = await this.getController(resource);
106
- const endpoint = (resource instanceof CrudResource && resource.operations.get(operationOrAction)) ||
107
- resource.actions.get(operationOrAction);
106
+ const endpoint = resource.actions.get(name);
107
+ if (endpoint) {
108
+ const handler = typeof controller[endpoint.name] === 'function' ? controller[endpoint.name] : undefined;
109
+ if (handler)
110
+ return { controller, endpoint, handler };
111
+ }
112
+ throw new BadRequestError({
113
+ message: translate('ACTION_NOT_FOUND', { resource: resource.name, action: name }, `The {{resource}} resource doesn't have an action named '{{action}}'`),
114
+ severity: 'error',
115
+ code: 'ACTION_NOT_FOUND'
116
+ });
117
+ }
118
+ async getOperationHandler(resource, name) {
119
+ resource = typeof resource === 'object' && resource instanceof Resource
120
+ ? resource
121
+ : this.api.getResource(resource);
122
+ const controller = await this.getController(resource);
123
+ const endpoint = resource instanceof CrudResource && resource.operations.get(name);
108
124
  if (endpoint) {
109
125
  const handler = typeof controller[endpoint.name] === 'function' ? controller[endpoint.name] : undefined;
110
126
  if (handler)
111
127
  return { controller, endpoint, handler };
112
128
  }
113
129
  throw new ForbiddenError({
114
- message: translate('OPERATION_FORBIDDEN', { resource: resource.name, endpoint: operationOrAction }, `'{{resource}}' does not accept '{{endpoint}}' operations`),
130
+ message: translate('OPERATION_FORBIDDEN', { resource: resource.name, operation: name }, `'The {{resource}} resource does not accept '{{operation}}' operations`),
115
131
  severity: 'error',
116
132
  code: 'OPERATION_FORBIDDEN'
117
133
  });
@@ -3,7 +3,7 @@ export var RequestContext;
3
3
  function from(executionContext, request, response) {
4
4
  const out = {
5
5
  request,
6
- response,
6
+ response
7
7
  };
8
8
  Object.setPrototypeOf(out, executionContext);
9
9
  return out;
@@ -12,7 +12,8 @@
12
12
  "RESPONSE_VALIDATION": "Response validation failed",
13
13
  "RESOURCE_NOT_FOUND": "Resource not found",
14
14
  "RESOURCE_CONFLICT": "There is already an other {{resource}} resource with same field values ({{fields}})",
15
- "OPERATION_FORBIDDEN": "The {{resource}} endpoint does not accept '{{endpoint}}' operations",
15
+ "OPERATION_FORBIDDEN": "The {{resource}} resource does not accept '{{operation}}' operations",
16
+ "ACTION_NOT_FOUND": "The {{resource}} resource doesn't have an action named '{{action}}'",
16
17
  "UNKNOWN_FIELD": "Unknown field '{{field}}'",
17
18
  "UNACCEPTED_SORT_FIELD": "Field '{{field}}' is not available for sort operation",
18
19
  "UNACCEPTED_FILTER_FIELD": "Field '{{field}}' is not available for filter operation",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@opra/core",
3
- "version": "0.26.4",
3
+ "version": "0.27.0",
4
4
  "description": "Opra schema package",
5
5
  "author": "Panates",
6
6
  "license": "MIT",
@@ -27,14 +27,14 @@
27
27
  "clean:cover": "rimraf ../../coverage/core"
28
28
  },
29
29
  "dependencies": {
30
- "@opra/common": "^0.26.4",
30
+ "@opra/common": "^0.27.0",
31
31
  "accepts": "^1.3.8",
32
32
  "content-disposition": "^0.5.4",
33
33
  "content-type": "^1.0.5",
34
34
  "cookie": "^0.5.0",
35
35
  "cookie-signature": "^1.2.1",
36
36
  "encodeurl": "^1.0.2",
37
- "formidable": "^3.5.0",
37
+ "formidable": "^3.5.1",
38
38
  "fresh": "^0.5.2",
39
39
  "mime-types": "^2.1.35",
40
40
  "power-tasks": "^1.7.2",
@@ -56,7 +56,7 @@
56
56
  "@types/cookie": "^0.5.2",
57
57
  "@types/cookie-signature": "^1.1.0",
58
58
  "@types/encodeurl": "^1.0.0",
59
- "@types/express": "^4.17.18",
59
+ "@types/express": "^4.17.19",
60
60
  "@types/formidable": "^3.4.3",
61
61
  "@types/fresh": "^0.5.0",
62
62
  "@types/mime-types": "^2.1.2",
@@ -1,19 +1,21 @@
1
- import type { PartialOutput } from '@opra/common';
1
+ import { StrictOmit } from 'ts-gems';
2
+ import type { Action as _Action, Operation as _Operation, PartialOutput } from '@opra/common';
2
3
  import type { Request as _Request } from '../request.js';
3
4
  import type { RequestContext } from '../request-context';
4
5
  declare module "@opra/common" {
5
6
  namespace Collection {
6
7
  namespace Action {
7
- interface Request extends _Request {
8
- operation: 'action';
9
- action: string;
8
+ interface Request extends StrictOmit<_Request, 'endpoint'> {
9
+ endpoint: _Action;
10
10
  }
11
11
  interface Context extends Resource.Context {
12
12
  }
13
13
  }
14
14
  namespace Create {
15
- interface Request extends _Request {
16
- operation: 'create';
15
+ interface Request extends StrictOmit<_Request, 'endpoint'> {
16
+ endpoint: _Operation & {
17
+ name: 'create';
18
+ };
17
19
  data: any;
18
20
  params: {
19
21
  pick?: string[];
@@ -27,8 +29,10 @@ declare module "@opra/common" {
27
29
  }
28
30
  }
29
31
  namespace Delete {
30
- interface Request extends _Request {
31
- operation: 'delete';
32
+ interface Request extends StrictOmit<_Request, 'endpoint'> {
33
+ endpoint: _Operation & {
34
+ name: 'delete';
35
+ };
32
36
  key: any;
33
37
  }
34
38
  interface Context extends RequestContext {
@@ -36,8 +40,10 @@ declare module "@opra/common" {
36
40
  }
37
41
  }
38
42
  namespace DeleteMany {
39
- interface Request extends _Request {
40
- operation: 'deleteMany';
43
+ interface Request extends StrictOmit<_Request, 'endpoint'> {
44
+ endpoint: _Operation & {
45
+ name: 'deleteMany';
46
+ };
41
47
  params: {
42
48
  filter?: any;
43
49
  [key: string]: any;
@@ -48,8 +54,10 @@ declare module "@opra/common" {
48
54
  }
49
55
  }
50
56
  namespace FindMany {
51
- interface Request extends _Request {
52
- operation: 'findMany';
57
+ interface Request extends StrictOmit<_Request, 'endpoint'> {
58
+ endpoint: _Operation & {
59
+ name: 'findMany';
60
+ };
53
61
  params: {
54
62
  filter?: any;
55
63
  pick?: string[];
@@ -68,8 +76,10 @@ declare module "@opra/common" {
68
76
  }
69
77
  }
70
78
  namespace Get {
71
- interface Request extends _Request {
72
- operation: 'get';
79
+ interface Request extends StrictOmit<_Request, 'endpoint'> {
80
+ endpoint: _Operation & {
81
+ name: 'get';
82
+ };
73
83
  key: any;
74
84
  params: {
75
85
  pick?: string[];
@@ -83,8 +93,10 @@ declare module "@opra/common" {
83
93
  }
84
94
  }
85
95
  namespace Update {
86
- interface Request extends _Request {
87
- operation: 'update';
96
+ interface Request extends StrictOmit<_Request, 'endpoint'> {
97
+ endpoint: _Operation & {
98
+ name: 'update';
99
+ };
88
100
  key: any;
89
101
  data: any;
90
102
  params: {
@@ -99,8 +111,10 @@ declare module "@opra/common" {
99
111
  }
100
112
  }
101
113
  namespace UpdateMany {
102
- interface Request extends _Request {
103
- operation: 'updateMany';
114
+ interface Request extends StrictOmit<_Request, 'endpoint'> {
115
+ endpoint: _Operation & {
116
+ name: 'updateMany';
117
+ };
104
118
  data: any;
105
119
  params: {
106
120
  filter?: any;
@@ -1,10 +1,11 @@
1
+ import { StrictOmit } from 'ts-gems';
2
+ import { Action as _Action } from '@opra/common';
1
3
  import type { Request as _Request } from '../request.js';
2
4
  declare module "@opra/common" {
3
5
  namespace Container {
4
6
  namespace Action {
5
- interface Request extends _Request {
6
- operation: 'action';
7
- action: string;
7
+ interface Request extends StrictOmit<_Request, 'endpoint'> {
8
+ endpoint: _Action;
8
9
  }
9
10
  interface Context extends Resource.Context {
10
11
  }
@@ -1,19 +1,21 @@
1
- import type { PartialOutput } from '@opra/common';
1
+ import { StrictOmit } from 'ts-gems';
2
+ import type { Action as _Action, Operation as _Operation, PartialOutput } from '@opra/common';
2
3
  import type { Request as _Request } from '../request.js';
3
4
  import type { RequestContext } from '../request-context.js';
4
5
  declare module "@opra/common" {
5
6
  namespace Singleton {
6
7
  namespace Action {
7
- interface Request extends _Request {
8
- operation: 'action';
9
- action: string;
8
+ interface Request extends StrictOmit<_Request, 'endpoint'> {
9
+ endpoint: _Action;
10
10
  }
11
11
  interface Context extends Resource.Context {
12
12
  }
13
13
  }
14
14
  namespace Create {
15
- interface Request extends _Request {
16
- operation: 'create';
15
+ interface Request extends StrictOmit<_Request, 'endpoint'> {
16
+ endpoint: _Operation & {
17
+ name: 'create';
18
+ };
17
19
  data: any;
18
20
  params: {
19
21
  pick?: string[];
@@ -26,16 +28,20 @@ declare module "@opra/common" {
26
28
  }
27
29
  }
28
30
  namespace Delete {
29
- interface Request extends _Request {
30
- operation: 'delete';
31
+ interface Request extends StrictOmit<_Request, 'endpoint'> {
32
+ endpoint: _Operation & {
33
+ name: 'delete';
34
+ };
31
35
  }
32
36
  interface Context extends RequestContext {
33
37
  request: Request;
34
38
  }
35
39
  }
36
40
  namespace Get {
37
- interface Request extends _Request {
38
- operation: 'get';
41
+ interface Request extends StrictOmit<_Request, 'endpoint'> {
42
+ endpoint: _Operation & {
43
+ name: 'get';
44
+ };
39
45
  params: {
40
46
  pick?: string[];
41
47
  omit?: string[];
@@ -47,8 +53,10 @@ declare module "@opra/common" {
47
53
  }
48
54
  }
49
55
  namespace Update {
50
- interface Request extends _Request {
51
- operation: 'update';
56
+ interface Request extends StrictOmit<_Request, 'endpoint'> {
57
+ endpoint: _Operation & {
58
+ name: 'update';
59
+ };
52
60
  data: any;
53
61
  params: {
54
62
  pick?: string[];
@@ -1,19 +1,22 @@
1
+ import { StrictOmit } from 'ts-gems';
2
+ import type { Action as _Action, Operation as _Operation } from '@opra/common';
1
3
  import type { MultipartIterator } from '../http/helpers/multipart-helper';
2
4
  import type { Request as _Request } from '../request.js';
3
5
  import type { RequestContext } from '../request-context.js';
4
6
  declare module "@opra/common" {
5
7
  namespace Storage {
6
8
  namespace Action {
7
- interface Request extends _Request {
8
- operation: 'action';
9
- action: string;
9
+ interface Request extends StrictOmit<_Request, 'endpoint'> {
10
+ endpoint: _Action;
10
11
  }
11
12
  interface Context extends Resource.Context {
12
13
  }
13
14
  }
14
15
  namespace Delete {
15
- interface Request extends _Request {
16
- operation: 'delete';
16
+ interface Request extends StrictOmit<_Request, 'endpoint'> {
17
+ endpoint: _Operation & {
18
+ name: 'delete';
19
+ };
17
20
  path?: string;
18
21
  }
19
22
  interface Context extends RequestContext {
@@ -21,8 +24,10 @@ declare module "@opra/common" {
21
24
  }
22
25
  }
23
26
  namespace Get {
24
- interface Request extends _Request {
25
- operation: 'get';
27
+ interface Request extends StrictOmit<_Request, 'endpoint'> {
28
+ endpoint: _Operation & {
29
+ name: 'get';
30
+ };
26
31
  path?: string;
27
32
  }
28
33
  interface Context extends RequestContext {
@@ -30,8 +35,10 @@ declare module "@opra/common" {
30
35
  }
31
36
  }
32
37
  namespace Post {
33
- interface Request extends _Request {
34
- operation: 'post';
38
+ interface Request extends StrictOmit<_Request, 'endpoint'> {
39
+ endpoint: _Operation & {
40
+ name: 'post';
41
+ };
35
42
  path?: string;
36
43
  parts: MultipartIterator;
37
44
  }
@@ -4,7 +4,6 @@ import type { Protocol } from './platform-adapter.js';
4
4
  export interface ExecutionContext {
5
5
  readonly protocol: Protocol;
6
6
  readonly platform: string;
7
- errors: Error[];
8
7
  switchToHttp(): HttpMessageContext;
9
8
  switchToWs(): WsMessageContext;
10
9
  switchToRpc(): RpcMessageContext;
@@ -11,7 +11,6 @@ export declare class ExecutionContextHost extends AsyncEventEmitter implements E
11
11
  readonly http?: HttpMessageContext;
12
12
  readonly ws?: WsMessageContext;
13
13
  readonly rpc?: RpcMessageContext;
14
- errors: Error[];
15
14
  constructor(api: ApiDocument, platform: string, protocol: {
16
15
  http?: {
17
16
  incoming: HttpServerRequest;
@@ -1,4 +1,4 @@
1
- import { Collection, OpraURLPath, OpraURLPathComponent, Parameter, Resource, Singleton, Storage } from '@opra/common';
1
+ import { Collection, OpraURLPath, Parameter, Resource, Singleton, Storage } from '@opra/common';
2
2
  import { ExecutionContext } from '../execution-context.js';
3
3
  import { PlatformAdapterHost } from '../platform-adapter.host.js';
4
4
  import type { Protocol } from '../platform-adapter.js';
@@ -26,9 +26,9 @@ export declare abstract class HttpAdapterHost extends PlatformAdapterHost {
26
26
  protected _parseRequestAction(executionContext: ExecutionContext, resource: Resource, urlPath: OpraURLPath, searchParams: URLSearchParams): Promise<RequestHost>;
27
27
  protected _parseRequestCollection(executionContext: ExecutionContext, resource: Collection, urlPath: OpraURLPath, searchParams: URLSearchParams): Promise<RequestHost>;
28
28
  protected _parseRequestSingleton(executionContext: ExecutionContext, resource: Singleton, urlPath: OpraURLPath, searchParams?: URLSearchParams): Promise<RequestHost>;
29
- protected _parseRequestStorage(executionContext: ExecutionContext, resource: Storage, urlPath: OpraURLPath, searchParams: URLSearchParams): Promise<RequestHost>;
30
- protected parseParameters(paramDefs: Map<string, Parameter>, pathComponent: OpraURLPathComponent, searchParams?: URLSearchParams): Record<string, any>;
29
+ protected _parseRequestStorage(executionContext: ExecutionContext, resource: Storage, searchParams: URLSearchParams): Promise<RequestHost>;
30
+ protected parseParameters(paramDefs: Map<string, Parameter>, searchParams?: URLSearchParams): Record<string, any>;
31
31
  protected executeRequest(context: RequestContext): Promise<void>;
32
32
  sendResponse(context: RequestContext): Promise<void>;
33
- protected handleError(context: ExecutionContext): Promise<void>;
33
+ protected sendErrorResponse(context: ExecutionContext, errors: any[]): Promise<void>;
34
34
  }
@@ -1,5 +1,5 @@
1
1
  import { AsyncEventEmitter } from 'strict-typed-events';
2
- import { ApiDocument, Endpoint, I18n, Resource } from '@opra/common';
2
+ import { Action, ApiDocument, I18n, Operation, Resource } from '@opra/common';
3
3
  import { ExecutionContext } from './execution-context.js';
4
4
  import { Interceptor } from './interfaces/interceptor.interface.js';
5
5
  import type { PlatformAdapter, Protocol } from './platform-adapter.js';
@@ -27,8 +27,13 @@ export declare abstract class PlatformAdapterHost extends AsyncEventEmitter impl
27
27
  */
28
28
  protected init(api: ApiDocument, options?: PlatformAdapter.Options): Promise<void>;
29
29
  getController(resource: Resource | string): Promise<any>;
30
- getOperationHandler(resource: Resource | string, operationOrAction: string): Promise<{
31
- endpoint: Endpoint;
30
+ getActionHandler(resource: Resource | string, name: string): Promise<{
31
+ endpoint: Action;
32
+ controller: any;
33
+ handler: Function;
34
+ }>;
35
+ getOperationHandler(resource: Resource | string, name: string): Promise<{
36
+ endpoint: Operation;
32
37
  controller: any;
33
38
  handler: Function;
34
39
  }>;
@@ -1,11 +1,9 @@
1
- import { Endpoint, Resource } from '@opra/common';
1
+ import { Action, Operation, Resource } from '@opra/common';
2
2
  import { HttpServerRequest } from './http/http-server-request.js';
3
3
  export interface Request {
4
4
  resource: Resource;
5
- endpoint: Endpoint;
6
- operation: string;
5
+ endpoint: Action | Operation;
7
6
  key?: any;
8
- action?: string;
9
7
  controller: Object;
10
8
  handler: Function;
11
9
  contentId?: string;
@@ -1,5 +1,6 @@
1
1
  import type { PartialSome, StrictOmit } from 'ts-gems';
2
2
  import type { Resource } from '@opra/common';
3
+ import { Action, Operation } from '@opra/common';
3
4
  import type { HttpServerRequest } from './http/http-server-request.js';
4
5
  import type { Request } from './request.js';
5
6
  export declare namespace RequestHost {
@@ -14,6 +15,7 @@ export interface RequestHost extends Request {
14
15
  }
15
16
  export declare class RequestHost implements Request {
16
17
  controller: any;
18
+ endpoint: Action | Operation;
17
19
  http?: HttpServerRequest;
18
20
  key?: any;
19
21
  params: Record<string, any>;
@@ -15,7 +15,7 @@ export interface Response {
15
15
  /**
16
16
  * Total count of matched entities. (Used in "search" endpoint with "count" option
17
17
  */
18
- count?: number;
18
+ totalMatches?: number;
19
19
  switchToHttp(): HttpServerResponse;
20
20
  switchToWs(): never;
21
21
  switchToRpc(): never;