@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.
- package/browser.js +353 -219
- package/cjs/document/data-type/complex-type-class.js +23 -5
- package/cjs/document/data-type/enum-type-class.js +4 -0
- package/cjs/document/data-type/mapped-type-class.js +0 -1
- package/cjs/document/factory/type-document-factory.js +19 -21
- package/cjs/document/index.js +8 -4
- package/cjs/document/resource/action-decorator.js +6 -0
- package/cjs/document/resource/action.js +33 -0
- package/cjs/document/resource/collection-class.js +31 -25
- package/cjs/document/resource/crud-resource.js +2 -2
- package/cjs/document/resource/endpoint.js +4 -4
- package/cjs/document/resource/enums/metadata-mode.enum.js +19 -0
- package/cjs/document/resource/operation.js +25 -0
- package/cjs/document/resource/resource.js +9 -6
- package/cjs/document/resource/singleton-class.js +16 -16
- package/cjs/document/resource/types/operation-result.type.js +44 -0
- package/cjs/document/type-document.js +61 -52
- package/cjs/helpers/object-utils.js +2 -2
- package/cjs/schema/opra-schema.ns.js +1 -0
- package/cjs/schema/resource/action.interface.js +2 -0
- package/esm/document/data-type/complex-type-class.js +23 -5
- package/esm/document/data-type/enum-type-class.js +4 -0
- package/esm/document/data-type/mapped-type-class.js +0 -1
- package/esm/document/factory/type-document-factory.js +19 -21
- package/esm/document/index.js +8 -4
- package/esm/document/resource/action-decorator.js +6 -0
- package/esm/document/resource/action.js +28 -0
- package/esm/document/resource/collection-class.js +31 -25
- package/esm/document/resource/crud-resource.js +2 -2
- package/esm/document/resource/endpoint.js +4 -3
- package/esm/document/resource/enums/metadata-mode.enum.js +16 -0
- package/esm/document/resource/operation.js +20 -0
- package/esm/document/resource/resource.js +9 -6
- package/esm/document/resource/singleton-class.js +16 -16
- package/esm/document/resource/types/operation-result.type.js +41 -0
- package/esm/document/type-document.js +61 -52
- package/esm/helpers/object-utils.js +2 -2
- package/esm/schema/opra-schema.ns.js +1 -0
- package/esm/schema/resource/action.interface.js +1 -0
- package/package.json +2 -2
- package/types/document/data-type/complex-type-class.d.ts +2 -1
- package/types/document/data-type/enum-type-class.d.ts +1 -0
- package/types/document/data-type/enum-type.d.ts +2 -2
- package/types/document/data-type/mapped-type-class.d.ts +1 -1
- package/types/document/data-type/simple-type-class.d.ts +1 -2
- package/types/document/data-type/union-type-class.d.ts +1 -1
- package/types/document/index.d.ts +8 -4
- package/types/document/resource/action-decorator.d.ts +4 -2
- package/types/document/resource/action.d.ts +30 -0
- package/types/document/resource/collection-class.d.ts +8 -8
- package/types/document/resource/collection-decorator.d.ts +18 -18
- package/types/document/resource/container-decorator.d.ts +4 -4
- package/types/document/resource/crud-resource.d.ts +3 -3
- package/types/document/resource/endpoint.d.ts +7 -11
- package/types/document/resource/enums/metadata-mode.enum.d.ts +5 -0
- package/types/document/resource/operation-decorator.d.ts +1 -1
- package/types/document/resource/operation.d.ts +25 -0
- package/types/document/resource/resource-decorator.d.ts +12 -5
- package/types/document/resource/resource.d.ts +6 -5
- package/types/document/resource/singleton-class.d.ts +5 -5
- package/types/document/resource/singleton-decorator.d.ts +12 -12
- package/types/document/resource/storage-class.d.ts +4 -4
- package/types/document/resource/storage-decorator.d.ts +10 -10
- package/types/document/resource/types/operation-result.type.d.ts +14 -0
- package/types/document/type-document.d.ts +14 -3
- package/types/schema/data-type/complex-type.interface.d.ts +3 -2
- package/types/schema/data-type/data-type.interface.d.ts +2 -2
- package/types/schema/data-type/enum-type.interface.d.ts +3 -1
- package/types/schema/data-type/simple-type.interface.d.ts +3 -1
- package/types/schema/opra-schema.ns.d.ts +1 -0
- package/types/schema/resource/action.interface.d.ts +6 -0
- package/types/schema/resource/container.interface.d.ts +0 -2
- 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.
|
|
15
|
-
this.
|
|
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.
|
|
56
|
-
: this.
|
|
44
|
+
? this._typeIndex.get(arg0.toLowerCase())
|
|
45
|
+
: this._typeIndex.get(arg0);
|
|
57
46
|
if (t)
|
|
58
47
|
return t;
|
|
59
|
-
//
|
|
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
|
-
|
|
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.
|
|
85
|
-
for (const
|
|
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
|
-
|
|
105
|
+
else {
|
|
101
106
|
const types = Array.from(this.types.values()).reverse();
|
|
102
107
|
for (const dt of types) {
|
|
103
|
-
if (dt
|
|
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.
|
|
111
|
-
for (const
|
|
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 (
|
|
126
|
-
|
|
127
|
-
if (
|
|
128
|
-
|
|
129
|
-
|
|
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.
|
|
192
|
-
this.
|
|
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:
|
|
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);
|
|
@@ -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 = {};
|
|
@@ -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('
|
|
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
|
-
|
|
130
|
+
thunk = this.typeQueue.get(name);
|
|
131
131
|
}
|
|
132
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
158
|
-
|
|
159
|
-
return dataType;
|
|
160
|
-
schema = cloneObject(metadata);
|
|
158
|
+
initArguments = cloneObject(metadata);
|
|
159
|
+
initArguments.enumObject = thunk;
|
|
161
160
|
}
|
|
162
161
|
}
|
|
163
|
-
ctor = ctor ?? (
|
|
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 (!
|
|
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(
|
|
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(
|
|
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
|
}
|
package/esm/document/index.js
CHANGED
|
@@ -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/
|
|
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/
|
|
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.
|
|
28
|
-
endpoint.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
83
|
-
endpoint.
|
|
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.
|
|
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.
|
|
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 {
|
|
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
|
|
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
|
+
});
|