@opra/common 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.
Files changed (73) hide show
  1. package/browser.js +353 -219
  2. package/cjs/document/data-type/complex-type-class.js +23 -5
  3. package/cjs/document/data-type/enum-type-class.js +4 -0
  4. package/cjs/document/data-type/mapped-type-class.js +0 -1
  5. package/cjs/document/factory/type-document-factory.js +19 -21
  6. package/cjs/document/index.js +8 -4
  7. package/cjs/document/resource/action-decorator.js +6 -0
  8. package/cjs/document/resource/action.js +33 -0
  9. package/cjs/document/resource/collection-class.js +31 -25
  10. package/cjs/document/resource/crud-resource.js +2 -2
  11. package/cjs/document/resource/endpoint.js +4 -4
  12. package/cjs/document/resource/enums/metadata-mode.enum.js +19 -0
  13. package/cjs/document/resource/operation.js +25 -0
  14. package/cjs/document/resource/resource.js +9 -6
  15. package/cjs/document/resource/singleton-class.js +16 -16
  16. package/cjs/document/resource/types/operation-result.type.js +44 -0
  17. package/cjs/document/type-document.js +61 -52
  18. package/cjs/helpers/object-utils.js +2 -2
  19. package/cjs/schema/opra-schema.ns.js +1 -0
  20. package/cjs/schema/resource/action.interface.js +2 -0
  21. package/esm/document/data-type/complex-type-class.js +23 -5
  22. package/esm/document/data-type/enum-type-class.js +4 -0
  23. package/esm/document/data-type/mapped-type-class.js +0 -1
  24. package/esm/document/factory/type-document-factory.js +19 -21
  25. package/esm/document/index.js +8 -4
  26. package/esm/document/resource/action-decorator.js +6 -0
  27. package/esm/document/resource/action.js +28 -0
  28. package/esm/document/resource/collection-class.js +31 -25
  29. package/esm/document/resource/crud-resource.js +2 -2
  30. package/esm/document/resource/endpoint.js +4 -3
  31. package/esm/document/resource/enums/metadata-mode.enum.js +16 -0
  32. package/esm/document/resource/operation.js +20 -0
  33. package/esm/document/resource/resource.js +9 -6
  34. package/esm/document/resource/singleton-class.js +16 -16
  35. package/esm/document/resource/types/operation-result.type.js +41 -0
  36. package/esm/document/type-document.js +61 -52
  37. package/esm/helpers/object-utils.js +2 -2
  38. package/esm/schema/opra-schema.ns.js +1 -0
  39. package/esm/schema/resource/action.interface.js +1 -0
  40. package/package.json +2 -2
  41. package/types/document/data-type/complex-type-class.d.ts +2 -1
  42. package/types/document/data-type/enum-type-class.d.ts +1 -0
  43. package/types/document/data-type/enum-type.d.ts +2 -2
  44. package/types/document/data-type/mapped-type-class.d.ts +1 -1
  45. package/types/document/data-type/simple-type-class.d.ts +1 -2
  46. package/types/document/data-type/union-type-class.d.ts +1 -1
  47. package/types/document/index.d.ts +8 -4
  48. package/types/document/resource/action-decorator.d.ts +4 -2
  49. package/types/document/resource/action.d.ts +30 -0
  50. package/types/document/resource/collection-class.d.ts +8 -8
  51. package/types/document/resource/collection-decorator.d.ts +18 -18
  52. package/types/document/resource/container-decorator.d.ts +4 -4
  53. package/types/document/resource/crud-resource.d.ts +3 -3
  54. package/types/document/resource/endpoint.d.ts +7 -11
  55. package/types/document/resource/enums/metadata-mode.enum.d.ts +5 -0
  56. package/types/document/resource/operation-decorator.d.ts +1 -1
  57. package/types/document/resource/operation.d.ts +25 -0
  58. package/types/document/resource/resource-decorator.d.ts +12 -5
  59. package/types/document/resource/resource.d.ts +6 -5
  60. package/types/document/resource/singleton-class.d.ts +5 -5
  61. package/types/document/resource/singleton-decorator.d.ts +12 -12
  62. package/types/document/resource/storage-class.d.ts +4 -4
  63. package/types/document/resource/storage-decorator.d.ts +10 -10
  64. package/types/document/resource/types/operation-result.type.d.ts +14 -0
  65. package/types/document/type-document.d.ts +14 -3
  66. package/types/schema/data-type/complex-type.interface.d.ts +3 -2
  67. package/types/schema/data-type/data-type.interface.d.ts +2 -2
  68. package/types/schema/data-type/enum-type.interface.d.ts +3 -1
  69. package/types/schema/data-type/simple-type.interface.d.ts +3 -1
  70. package/types/schema/opra-schema.ns.d.ts +1 -0
  71. package/types/schema/resource/action.interface.d.ts +6 -0
  72. package/types/schema/resource/container.interface.d.ts +0 -2
  73. package/types/schema/resource/resource.interface.d.ts +2 -2
@@ -6,13 +6,15 @@ const index_js_2 = require("../helpers/index.js");
6
6
  const index_js_3 = require("../schema/index.js");
7
7
  const constants_js_1 = require("./constants.js");
8
8
  const complex_type_js_1 = require("./data-type/complex-type.js");
9
+ const data_type_js_1 = require("./data-type/data-type.js");
10
+ const enum_type_js_1 = require("./data-type/enum-type.js");
9
11
  const document_base_js_1 = require("./document-base.js");
10
12
  class TypeDocument extends document_base_js_1.DocumentBase {
11
13
  constructor() {
12
14
  super();
13
15
  this._designCtorMap = new Map();
14
- this._typeCache = new index_js_2.ResponsiveMap();
15
- this._typesCacheByCtor = new Map();
16
+ this._typeIndex = new Map();
17
+ this._typeNsMap = new Map();
16
18
  this.references = new index_js_2.ResponsiveMap();
17
19
  this.types = new index_js_2.ResponsiveMap();
18
20
  const BigIntConstructor = Object.getPrototypeOf(BigInt(0)).constructor;
@@ -37,38 +39,45 @@ class TypeDocument extends document_base_js_1.DocumentBase {
37
39
  if (x)
38
40
  arg0 = x;
39
41
  }
40
- let dataType;
41
- let name;
42
- // Determine name
43
- if (typeof arg0 === 'function') {
44
- const metadata = Reflect.getMetadata(constants_js_1.DATATYPE_METADATA, arg0);
45
- name = metadata?.name || arg0.name;
46
- }
47
- else if (typeof arg0 === 'function') {
48
- const metadata = Reflect.getMetadata(constants_js_1.DATATYPE_METADATA, arg0);
49
- name = metadata?.name;
50
- }
51
- else
52
- name = String(arg0);
53
42
  // Try to get instance from cache
54
43
  const t = typeof arg0 === 'string'
55
- ? this._typeCache.get(arg0)
56
- : this._typesCacheByCtor.get(arg0);
44
+ ? this._typeIndex.get(arg0.toLowerCase())
45
+ : this._typeIndex.get(arg0);
57
46
  if (t)
58
47
  return t;
59
- // If cached as null, it means "not found"
48
+ // Determine name
49
+ let name;
50
+ if (typeof arg0 === 'string')
51
+ name = arg0;
52
+ else if (arg0 instanceof data_type_js_1.DataType)
53
+ name = arg0.name || '';
54
+ else {
55
+ const metadata = typeof arg0 === 'function'
56
+ ? Reflect.getMetadata(constants_js_1.DATATYPE_METADATA, arg0) : arg0?.[constants_js_1.DATATYPE_METADATA];
57
+ if (!metadata) {
58
+ /* istanbul ignore next */
59
+ if (!silent)
60
+ throw new TypeError('Invalid argument');
61
+ return;
62
+ }
63
+ name = metadata.name;
64
+ }
65
+ // If cached as null, it means "not found" before
60
66
  if (t === null) {
61
67
  if (silent)
62
68
  return;
63
69
  throw new Error(`Data type "${name}" does not exists`);
64
70
  }
71
+ let dataType;
72
+ let ns = '';
65
73
  if (typeof arg0 === 'string' && arg0) {
66
74
  const m = constants_js_1.NAMESPACE_PATTERN.exec(arg0);
67
75
  if (!m)
68
76
  throw new TypeError(`Invalid data type name "${name}"`);
69
77
  // If given string has namespace pattern (ns:type_name)
70
78
  if (m[2]) {
71
- const ref = this.references.get(m[1]);
79
+ ns = m[1];
80
+ const ref = this.references.get(ns);
72
81
  if (!ref) {
73
82
  if (silent)
74
83
  return;
@@ -81,61 +90,61 @@ class TypeDocument extends document_base_js_1.DocumentBase {
81
90
  dataType = this.types.get(arg0);
82
91
  // if not found, search in references (from last to first)
83
92
  if (!dataType) {
84
- const references = Array.from(this.references.values()).reverse();
85
- for (const ref of references) {
93
+ const references = Array.from(this.references.keys()).reverse();
94
+ for (const refNs of references) {
95
+ const ref = this.references.get(refNs);
86
96
  dataType = ref.getDataType(name, true);
87
- if (dataType)
97
+ if (dataType) {
98
+ ns = refNs;
88
99
  break;
100
+ }
89
101
  }
90
102
  }
91
103
  }
92
- if (dataType) {
93
- this._typeCache.set(arg0, dataType);
94
- return dataType;
95
- }
96
- if (!silent)
97
- throw new index_js_1.NotFoundError(`Data type "${arg0}" does not exists`);
98
- return;
99
104
  }
100
- if (typeof arg0 === 'function') {
105
+ else {
101
106
  const types = Array.from(this.types.values()).reverse();
102
107
  for (const dt of types) {
103
- if (dt instanceof complex_type_js_1.ComplexType && dt.isTypeOf(arg0)) {
108
+ if (dt === arg0 ||
109
+ ((dt instanceof complex_type_js_1.ComplexType || dt instanceof enum_type_js_1.EnumType) && dt.isTypeOf(arg0))) {
104
110
  dataType = dt;
105
111
  break;
106
112
  }
107
113
  }
108
114
  // if not found, search in references (from last to first)
109
115
  if (!dataType) {
110
- const references = Array.from(this.references.values()).reverse();
111
- for (const ref of references) {
116
+ const references = Array.from(this.references.keys()).reverse();
117
+ for (const refNs of references) {
118
+ const ref = this.references.get(refNs);
112
119
  dataType = ref.getDataType(arg0, true);
113
- if (dataType)
120
+ if (dataType) {
121
+ ns = refNs;
114
122
  break;
123
+ }
115
124
  }
116
125
  }
117
- if (dataType)
118
- this._typesCacheByCtor.set(arg0, dataType);
119
- if (dataType)
120
- return dataType;
121
- if (!silent)
122
- throw new Error(`No data type mapping found for class "${name}"`);
123
- return;
124
126
  }
125
- if (typeof arg0 === 'object') {
126
- const metadata = arg0[constants_js_1.DATATYPE_METADATA];
127
- if (metadata && metadata.name) {
128
- dataType = this.getDataType(metadata.name, true);
129
- if (dataType)
130
- return dataType;
131
- if (!silent)
132
- throw new Error(`No data type mapping found for class "${name}"`);
133
- }
127
+ if (dataType) {
128
+ this._typeIndex.set(arg0, dataType);
129
+ if (ns)
130
+ this._typeNsMap.set(dataType, ns);
131
+ return dataType;
134
132
  }
133
+ if (!silent)
134
+ throw new index_js_1.NotFoundError(`Data type "${name}" does not exists`);
135
+ return;
135
136
  /* istanbul ignore next */
136
137
  if (!silent)
137
138
  throw new TypeError('Invalid argument');
138
139
  }
140
+ /**
141
+ *
142
+ */
143
+ getDataTypeNs(arg0, silent) {
144
+ const dt = this.getDataType(arg0, silent);
145
+ if (dt)
146
+ return this._typeNsMap.get(dt);
147
+ }
139
148
  getComplexType(nameOrCtor, silent) {
140
149
  if (nameOrCtor === Object)
141
150
  nameOrCtor = 'object';
@@ -188,8 +197,8 @@ class TypeDocument extends document_base_js_1.DocumentBase {
188
197
  return schema;
189
198
  }
190
199
  invalidate() {
191
- this._typeCache.clear();
192
- this._typesCacheByCtor.clear();
200
+ this._typeIndex.clear();
201
+ this._typeNsMap.clear();
193
202
  }
194
203
  }
195
204
  exports.TypeDocument = TypeDocument;
@@ -4,10 +4,10 @@ exports.omitUndefined = exports.cloneObject = void 0;
4
4
  const tslib_1 = require("tslib");
5
5
  const putil_isplainobject_1 = tslib_1.__importDefault(require("putil-isplainobject"));
6
6
  const putil_merge_1 = tslib_1.__importDefault(require("putil-merge"));
7
+ const constants_js_1 = require("../document/constants.js");
7
8
  function cloneObject(obj, jsonOnly) {
8
9
  return (0, putil_merge_1.default)({}, obj, {
9
- deep: true,
10
- clone: true,
10
+ deep: (v) => (0, putil_isplainobject_1.default)(v) && !v[constants_js_1.DATATYPE_METADATA],
11
11
  filter: (source, key) => {
12
12
  const v = source[key];
13
13
  return v != null &&
@@ -8,6 +8,7 @@ tslib_1.__exportStar(require("./data-type/field.interface.js"), exports);
8
8
  tslib_1.__exportStar(require("./data-type/simple-type.interface.js"), exports);
9
9
  tslib_1.__exportStar(require("./data-type/mapped-type.interface.js"), exports);
10
10
  tslib_1.__exportStar(require("./data-type/union-type.interface.js"), exports);
11
+ tslib_1.__exportStar(require("./resource/action.interface.js"), exports);
11
12
  tslib_1.__exportStar(require("./resource/endpoint.interface.js"), exports);
12
13
  tslib_1.__exportStar(require("./resource/collection.interface.js"), exports);
13
14
  tslib_1.__exportStar(require("./resource/container.interface.js"), exports);
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -153,11 +153,7 @@ export class ComplexTypeClass extends DataType {
153
153
  return false;
154
154
  }
155
155
  generateCodec(codec, options) {
156
- const schema = {};
157
- for (const f of this.fields.values()) {
158
- // todo omit, pick
159
- schema[f.name] = f.generateCodec(codec, options);
160
- }
156
+ const schema = this._generateCodecSchema(codec, options);
161
157
  return vg.isObject(schema, {
162
158
  ctor: this.ctor,
163
159
  additionalFields: this.additionalFields ?? false,
@@ -165,4 +161,26 @@ export class ComplexTypeClass extends DataType {
165
161
  caseInSensitive: !options?.caseSensitive
166
162
  });
167
163
  }
164
+ _generateCodecSchema(codec, options) {
165
+ const schema = {};
166
+ const pickOption = (options?.pick || []).map(x => x.toLowerCase());
167
+ const omitOption = (options?.omit || []).map(x => x.toLowerCase());
168
+ for (const f of this.fields.values()) {
169
+ const nameLower = f.name.toLowerCase();
170
+ if (omitOption.find(x => x === nameLower))
171
+ continue;
172
+ if (pickOption.length && !pickOption.find(x => x === nameLower || x.startsWith(nameLower + '.')))
173
+ continue;
174
+ schema[f.name] = f.generateCodec(codec, {
175
+ ...options,
176
+ pick: pickOption
177
+ .filter(x => x.startsWith(nameLower + '.'))
178
+ .map(x => x.substring(x.indexOf('.') + 1)),
179
+ omit: omitOption
180
+ .filter(x => x.startsWith(nameLower + '.'))
181
+ .map(x => x.substring(x.indexOf('.') + 1)),
182
+ });
183
+ }
184
+ return schema;
185
+ }
168
186
  }
@@ -1,6 +1,7 @@
1
1
  import * as vg from 'valgen';
2
2
  import { omitUndefined } from '../../helpers/index.js';
3
3
  import { OpraSchema } from '../../schema/index.js';
4
+ import { DATATYPE_METADATA } from '../constants.js';
4
5
  import { DataType } from './data-type.js';
5
6
  export class EnumTypeClass extends DataType {
6
7
  constructor(document, init) {
@@ -13,6 +14,9 @@ export class EnumTypeClass extends DataType {
13
14
  this.decode = vg.isEnum(Object.keys(this.values));
14
15
  this.encode = vg.isEnum(Object.keys(this.values));
15
16
  }
17
+ isTypeOf(t) {
18
+ return t[DATATYPE_METADATA] === this.enumObject?.[DATATYPE_METADATA];
19
+ }
16
20
  exportSchema() {
17
21
  const out = super.exportSchema();
18
22
  out.values = {};
@@ -18,7 +18,6 @@ export class MappedTypeClass extends ComplexTypeClass {
18
18
  }
19
19
  }
20
20
  }
21
- // @ts-ignore
22
21
  exportSchema() {
23
22
  const out = super.exportSchema();
24
23
  Object.assign(out, omitUndefined({
@@ -8,6 +8,8 @@ import { EnumType } from '../data-type/enum-type.js';
8
8
  import { MappedType } from '../data-type/mapped-type.js';
9
9
  import { SimpleType } from '../data-type/simple-type.js';
10
10
  import { UnionType } from '../data-type/union-type.js';
11
+ import { MetadataMode } from '../resource/enums/metadata-mode.enum.js';
12
+ import { OperationResult } from '../resource/types/operation-result.type.js';
11
13
  import { TypeDocument } from '../type-document.js';
12
14
  /**
13
15
  * @class TypeDocumentFactory
@@ -43,7 +45,7 @@ export class TypeDocumentFactory {
43
45
  Object.assign(this.document.info, init.info);
44
46
  if (!init?.noBuiltinTypes) {
45
47
  const builtinDocument = await this.createBuiltinTypeDocument();
46
- this.document.references.set('Opra', builtinDocument);
48
+ this.document.references.set('opra', builtinDocument);
47
49
  }
48
50
  if (init.references)
49
51
  await this.addReferences(init.references);
@@ -83,13 +85,10 @@ export class TypeDocumentFactory {
83
85
  async createBuiltinTypeDocument() {
84
86
  const init = {
85
87
  version: OpraSchema.SpecVersion,
88
+ url: 'https://oprajs.com/spec/v1.0',
86
89
  info: {
87
90
  version: OpraSchema.SpecVersion,
88
91
  title: 'Opra built-in types',
89
- contact: [{
90
- url: 'https://github.com/oprajs/opra'
91
- }
92
- ],
93
92
  license: {
94
93
  url: 'https://github.com/oprajs/opra/blob/main/LICENSE',
95
94
  name: 'MIT'
@@ -98,7 +97,8 @@ export class TypeDocumentFactory {
98
97
  types: [AnyType, Base64Type, BigintType, BooleanType,
99
98
  DateType, UuidType, IntegerType, NullType,
100
99
  NumberType, ObjectType, ObjectIdType, StringType,
101
- TimeType, TimestampType
100
+ TimeType, TimestampType,
101
+ OperationResult, MetadataMode,
102
102
  ]
103
103
  };
104
104
  const factory = new TypeDocumentFactory();
@@ -123,13 +123,14 @@ export class TypeDocumentFactory {
123
123
  async importDataType(thunk) {
124
124
  thunk = await resolveThunk(thunk);
125
125
  let name = '';
126
- let schema;
126
+ // let schema: OpraSchema.DataType | undefined;
127
127
  let ctor;
128
128
  if (typeof thunk === 'string') {
129
129
  name = thunk;
130
- schema = this.typeQueue.get(name);
130
+ thunk = this.typeQueue.get(name);
131
131
  }
132
- else if (typeof thunk === 'function') {
132
+ let initArguments;
133
+ if (typeof thunk === 'function') {
133
134
  const metadata = Reflect.getMetadata(DATATYPE_METADATA, thunk);
134
135
  if (!metadata) {
135
136
  // Check if is an internal type class like String, Number etc
@@ -139,14 +140,14 @@ export class TypeDocumentFactory {
139
140
  throw new TypeError(`Class "${thunk.name}" doesn't have a valid DataType metadata`);
140
141
  }
141
142
  name = metadata.name;
142
- schema = metadata;
143
+ initArguments = cloneObject(metadata);
143
144
  ctor = thunk;
144
145
  }
145
146
  else if (typeof thunk === 'object') {
146
147
  if (OpraSchema.isDataType(thunk)) {
147
148
  name = thunk.name;
148
149
  ctor = thunk.ctor || ctor;
149
- schema = thunk;
150
+ initArguments = cloneObject(thunk);
150
151
  }
151
152
  else {
152
153
  // It should be an enum object
@@ -154,13 +155,11 @@ export class TypeDocumentFactory {
154
155
  if (!metadata)
155
156
  throw new TypeError(`No EnumType metadata found for object ${JSON.stringify(thunk).substring(0, 20)}...`);
156
157
  name = metadata.name;
157
- const dataType = this.document.getDataType(name, true);
158
- if (dataType)
159
- return dataType;
160
- schema = cloneObject(metadata);
158
+ initArguments = cloneObject(metadata);
159
+ initArguments.enumObject = thunk;
161
160
  }
162
161
  }
163
- ctor = ctor ?? (schema && (isConstructor(schema.ctor)) ? schema.ctor : undefined);
162
+ ctor = ctor ?? (initArguments && (isConstructor(initArguments.ctor)) ? initArguments.ctor : undefined);
164
163
  if (name) {
165
164
  if (this.circularRefs.has(name.toLowerCase()))
166
165
  throw new TypeError('Circular reference detected');
@@ -179,14 +178,13 @@ export class TypeDocumentFactory {
179
178
  this.circularRefs.set(ctor, 1);
180
179
  }
181
180
  try {
182
- if (!OpraSchema.isDataType(schema))
181
+ if (!initArguments)
183
182
  throw new TypeError(`No DataType schema determined`);
184
183
  // Create an empty DataType instance and add in to document.
185
184
  // This will help us for circular dependent data types
186
- const instance = this.createDataTypeInstance(schema.kind, name);
185
+ const instance = this.createDataTypeInstance(initArguments.kind, name);
187
186
  if (name)
188
187
  this.document.types.set(name, instance);
189
- const initArguments = cloneObject(schema);
190
188
  await this.prepareDataTypeInitArguments(initArguments, ctor);
191
189
  if (initArguments.kind === 'ComplexType')
192
190
  ComplexType.apply(instance, [this.document, initArguments]);
@@ -199,7 +197,7 @@ export class TypeDocumentFactory {
199
197
  else if (initArguments.kind === 'UnionType')
200
198
  UnionType.apply(instance, [this.document, initArguments]);
201
199
  else
202
- throw new TypeError(`Invalid data type schema: ${String(schema)}`);
200
+ throw new TypeError(`Invalid data type schema: ${String(initArguments)}`);
203
201
  return instance;
204
202
  }
205
203
  finally {
@@ -256,7 +254,7 @@ export class TypeDocumentFactory {
256
254
  fieldInit.type = await this.importDataType(enumObject);
257
255
  }
258
256
  else {
259
- const enumMeta = EnumType(enumObject);
257
+ const enumMeta = EnumType(enumObject, { name: '' });
260
258
  fieldInit.type = await this.importDataType({ ...enumMeta, kind: 'EnumType', base: undefined });
261
259
  }
262
260
  }
@@ -11,14 +11,18 @@ export * from './data-type/enum-type.js';
11
11
  export * from './data-type/mapped-type.js';
12
12
  export * from './data-type/simple-type.js';
13
13
  export * from './data-type/union-type.js';
14
- export * from './resource/resource.js';
15
- export * from './resource/crud-resource.js';
14
+ export * from './resource/action.js';
16
15
  export * from './resource/collection.js';
17
16
  export * from './resource/container.js';
18
- export * from './resource/singleton.js';
19
- export * from './resource/storage.js';
17
+ export * from './resource/crud-resource.js';
20
18
  export * from './resource/endpoint.js';
19
+ export * from './resource/operation.js';
21
20
  export * from './resource/parameter.js';
21
+ export * from './resource/resource.js';
22
+ export * from './resource/singleton.js';
23
+ export * from './resource/storage.js';
24
+ export * from './resource/enums/metadata-mode.enum.js';
25
+ export * from './resource/types/operation-result.type.js';
22
26
  export * from './interfaces/collection.interface.js';
23
27
  export * from './interfaces/singleton.interface.js';
24
28
  export * from './interfaces/storage.interface.js';
@@ -19,5 +19,11 @@ export function createActionDecorator(options, bannedProperties, list) {
19
19
  });
20
20
  return decorator;
21
21
  };
22
+ decorator.Returns = (t) => {
23
+ list.push((actionMetadata) => {
24
+ actionMetadata.returnType = t;
25
+ });
26
+ return decorator;
27
+ };
22
28
  return decorator;
23
29
  }
@@ -0,0 +1,28 @@
1
+ import * as vg from 'valgen';
2
+ import { DataType } from '../data-type/data-type.js';
3
+ import { Endpoint } from './endpoint.js';
4
+ /**
5
+ *
6
+ * @class Action
7
+ */
8
+ export class Action extends Endpoint {
9
+ constructor(resource, name, init) {
10
+ super(resource, name, init);
11
+ this.resource = resource;
12
+ this.name = name;
13
+ this.kind = 'action';
14
+ this.encodeReturning = vg.isAny();
15
+ if (init.returnType)
16
+ this.returnType = init.returnType instanceof DataType
17
+ ? init.returnType : this.resource.document.getDataType(init.returnType);
18
+ this.returnMime = init.returnMime;
19
+ }
20
+ exportSchema(options) {
21
+ const schema = super.exportSchema(options);
22
+ if (this.returnType)
23
+ schema.returnType = this.returnType.name ? this.returnType.name : this.returnType.exportSchema(options);
24
+ if (this.returnMime)
25
+ schema.returnMime = this.returnMime;
26
+ return schema;
27
+ }
28
+ }
@@ -24,48 +24,46 @@ export class CollectionClass extends CrudResource {
24
24
  // ------------------
25
25
  let endpoint = this.operations.get('create');
26
26
  if (endpoint) {
27
- endpoint.returnType = this.type;
28
- endpoint.decode = this.type.generateCodec('decode', {
27
+ // endpoint.defineParameter('metadata', {enum: MetadataMode, isBuiltin: true, default: 'minimal'});
28
+ endpoint.defineParameter('pick', { type: 'string', isArray: true, isBuiltin: true });
29
+ endpoint.defineParameter('omit', { type: 'string', isArray: true, isBuiltin: true });
30
+ endpoint.defineParameter('include', { type: 'string', isArray: true, isBuiltin: true });
31
+ endpoint.decodeInput = this.type.generateCodec('decode', {
29
32
  partial: true,
30
33
  pick: endpoint.inputPickFields,
31
34
  omit: endpoint.inputOmitFields,
32
35
  });
33
- endpoint.encode = this.type.generateCodec('encode', {
36
+ endpoint.returnType = this.type;
37
+ endpoint.encodeReturning = endpoint.returnType.generateCodec('encode', {
34
38
  partial: true,
35
39
  pick: endpoint.outputPickFields,
36
40
  omit: endpoint.outputOmitFields,
37
41
  });
38
- endpoint.defineParameter('pick', { type: 'string', isArray: true, isBuiltin: true });
39
- endpoint.defineParameter('omit', { type: 'string', isArray: true, isBuiltin: true });
40
- endpoint.defineParameter('include', { type: 'string', isArray: true, isBuiltin: true });
41
42
  }
42
43
  // ------------------
43
44
  endpoint = this.operations.get('deleteMany');
44
45
  if (endpoint) {
46
+ // endpoint.defineParameter('metadata', {enum: MetadataMode, isBuiltin: true});
45
47
  endpoint.defineParameter('filter', { type: 'string', isBuiltin: true });
46
48
  }
47
49
  // ------------------
48
50
  endpoint = this.operations.get('get');
49
51
  if (endpoint) {
52
+ // endpoint.defineParameter('metadata', {enum: MetadataMode, isBuiltin: true, default: 'minimal'});
53
+ endpoint.defineParameter('pick', { type: 'string', isArray: true, isBuiltin: true });
54
+ endpoint.defineParameter('omit', { type: 'string', isArray: true, isBuiltin: true });
55
+ endpoint.defineParameter('include', { type: 'string', isArray: true, isBuiltin: true });
50
56
  endpoint.returnType = this.type;
51
- endpoint.encode = this.type.generateCodec('encode', {
57
+ endpoint.encodeReturning = endpoint.returnType.generateCodec('encode', {
52
58
  partial: true,
53
59
  pick: endpoint.outputPickFields,
54
60
  omit: endpoint.outputOmitFields,
55
61
  });
56
- endpoint.defineParameter('pick', { type: 'string', isArray: true, isBuiltin: true });
57
- endpoint.defineParameter('omit', { type: 'string', isArray: true, isBuiltin: true });
58
- endpoint.defineParameter('include', { type: 'string', isArray: true, isBuiltin: true });
59
62
  }
60
63
  // ------------------
61
64
  endpoint = this.operations.get('findMany');
62
65
  if (endpoint) {
63
- endpoint.returnType = this.type;
64
- endpoint.encode = vg.isArray(this.type.generateCodec('encode', {
65
- partial: true,
66
- pick: endpoint.outputPickFields,
67
- omit: endpoint.outputOmitFields,
68
- }));
66
+ // endpoint.defineParameter('metadata', {enum: MetadataMode, isBuiltin: true, default: 'minimal'});
69
67
  endpoint.defineParameter('pick', { type: 'string', isArray: true, isBuiltin: true });
70
68
  endpoint.defineParameter('omit', { type: 'string', isArray: true, isBuiltin: true });
71
69
  endpoint.defineParameter('include', { type: 'string', isArray: true, isBuiltin: true });
@@ -75,32 +73,40 @@ export class CollectionClass extends CrudResource {
75
73
  endpoint.defineParameter('skip', { type: 'integer', isBuiltin: true });
76
74
  endpoint.defineParameter('distinct', { type: 'boolean', isBuiltin: true });
77
75
  endpoint.defineParameter('count', { type: 'boolean', isBuiltin: true });
76
+ endpoint.returnType = this.type;
77
+ endpoint.encodeReturning = vg.isArray(this.type.generateCodec('encode', {
78
+ partial: true,
79
+ pick: endpoint.outputPickFields,
80
+ omit: endpoint.outputOmitFields,
81
+ }));
78
82
  }
79
83
  // ------------------
80
84
  endpoint = this.operations.get('update');
81
85
  if (endpoint) {
82
- endpoint.returnType = this.type;
83
- endpoint.decode = this.type.generateCodec('decode', {
86
+ // endpoint.defineParameter('metadata', {enum: MetadataMode, isBuiltin: true, default: 'minimal'});
87
+ endpoint.defineParameter('pick', { type: 'string', isArray: true, isBuiltin: true });
88
+ endpoint.defineParameter('omit', { type: 'string', isArray: true, isBuiltin: true });
89
+ endpoint.defineParameter('include', { type: 'string', isArray: true, isBuiltin: true });
90
+ endpoint.decodeInput = this.type.generateCodec('decode', {
84
91
  pick: endpoint.inputPickFields,
85
92
  omit: endpoint.inputOmitFields,
86
93
  });
87
- endpoint.encode = this.type.generateCodec('encode', {
94
+ endpoint.returnType = this.type;
95
+ endpoint.encodeReturning = endpoint.returnType.generateCodec('encode', {
88
96
  partial: true,
89
97
  pick: endpoint.outputPickFields,
90
98
  omit: endpoint.outputOmitFields,
91
99
  });
92
- endpoint.defineParameter('pick', { type: 'string', isArray: true, isBuiltin: true });
93
- endpoint.defineParameter('omit', { type: 'string', isArray: true, isBuiltin: true });
94
- endpoint.defineParameter('include', { type: 'string', isArray: true, isBuiltin: true });
95
100
  }
96
101
  // ------------------
97
102
  endpoint = this.operations.get('updateMany');
98
103
  if (endpoint) {
99
- endpoint.decode = this.type.generateCodec('decode', {
104
+ // endpoint.defineParameter('metadata', {enum: MetadataMode, isBuiltin: true, default: 'minimal'});
105
+ endpoint.defineParameter('filter', { type: 'string', isBuiltin: true });
106
+ endpoint.decodeInput = this.type.generateCodec('decode', {
100
107
  pick: endpoint.inputPickFields,
101
108
  omit: endpoint.inputOmitFields,
102
109
  });
103
- endpoint.defineParameter('filter', { type: 'string', isBuiltin: true });
104
110
  }
105
111
  }
106
112
  getOperation(name) {
@@ -142,7 +148,7 @@ export class CollectionClass extends CrudResource {
142
148
  value = value[primaryKey];
143
149
  const el = dataType.getField(primaryKey);
144
150
  let result;
145
- if (el.type instanceof SimpleType)
151
+ if (value != null && el.type instanceof SimpleType)
146
152
  result = el.type.decode(value);
147
153
  if (result == null)
148
154
  throw new TypeError(`You must provide value of primary field(s) (${primaryKey})`);
@@ -1,5 +1,5 @@
1
1
  import { ResponsiveMap } from '../../helpers/index.js';
2
- import { Endpoint } from './endpoint.js';
2
+ import { Operation } from './operation.js';
3
3
  import { Resource } from './resource.js';
4
4
  export class CrudResource extends Resource {
5
5
  constructor(parent, init) {
@@ -7,7 +7,7 @@ export class CrudResource extends Resource {
7
7
  this.operations = new ResponsiveMap();
8
8
  if (init.operations) {
9
9
  for (const [name, meta] of Object.entries(init.operations)) {
10
- this.operations.set(name, new Endpoint(this, name, meta));
10
+ this.operations.set(name, new Operation(this, name, meta));
11
11
  }
12
12
  }
13
13
  }
@@ -1,4 +1,3 @@
1
- import * as vg from 'valgen';
2
1
  import { omitUndefined, ResponsiveMap } from '../../helpers/index.js';
3
2
  import { DataType } from '../data-type/data-type.js';
4
3
  import { Parameter } from './parameter.js';
@@ -10,8 +9,6 @@ export class Endpoint {
10
9
  constructor(resource, name, init) {
11
10
  this.resource = resource;
12
11
  this.name = name;
13
- this.decode = vg.isAny();
14
- this.encode = vg.isAny();
15
12
  Object.assign(this, init);
16
13
  this.parameters = new ResponsiveMap();
17
14
  if (init.parameters) {
@@ -20,6 +17,10 @@ export class Endpoint {
20
17
  }
21
18
  }
22
19
  }
20
+ getFullPath(documentPath) {
21
+ return this.resource.getFullPath(documentPath) +
22
+ (this.kind === 'action' ? (documentPath ? '/actions/' : '/') + this.name : '');
23
+ }
23
24
  defineParameter(name, init) {
24
25
  const type = init.type && init.type instanceof DataType
25
26
  ? init.type : this.resource.document.getDataType(init.type || 'any');
@@ -0,0 +1,16 @@
1
+ import { EnumType } from '../../data-type/enum-type.js';
2
+ export var MetadataMode;
3
+ (function (MetadataMode) {
4
+ MetadataMode["none"] = "none";
5
+ MetadataMode["minimal"] = "minimal";
6
+ MetadataMode["full"] = "full";
7
+ })(MetadataMode || (MetadataMode = {}));
8
+ EnumType(MetadataMode, {
9
+ name: 'MetadataMode',
10
+ description: 'Parameter "enumeration" that controls how metadata information sent',
11
+ meanings: {
12
+ 'none': 'Specifies that the service will include NO metadata information in the response',
13
+ 'minimal': 'Specifies that the service will include ALL metadata information in the response',
14
+ 'full': 'Specifies that the service will include MINIMAL metadata information in the response',
15
+ }
16
+ });