@opra/sqb 0.25.4 → 0.26.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/cjs/augmentation/api-document-factory.augmentation.js +20 -0
- package/cjs/augmentation/type-document-factory.augmentation.js +99 -0
- package/cjs/index.js +2 -1
- package/cjs/sqb-adapter.js +12 -12
- package/esm/augmentation/api-document-factory.augmentation.js +18 -0
- package/esm/augmentation/type-document-factory.augmentation.js +97 -0
- package/esm/index.js +2 -1
- package/esm/sqb-adapter.js +12 -12
- package/package.json +3 -3
- package/types/augmentation/type-document-factory.augmentation.d.ts +1 -0
- package/types/index.d.ts +2 -1
- package/types/sqb-collection.d.ts +9 -9
- package/types/sqb-entity-service.d.ts +3 -3
- package/types/sqb-singleton.d.ts +6 -6
- package/cjs/augmentation/document-factory.augmentation.js +0 -116
- package/esm/augmentation/document-factory.augmentation.js +0 -114
- /package/types/augmentation/{document-factory.augmentation.d.ts → api-document-factory.augmentation.d.ts} +0 -0
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const common_1 = require("@opra/common");
|
|
4
|
+
const connect_1 = require("@sqb/connect");
|
|
5
|
+
// @ts-ignore
|
|
6
|
+
const _createResource = common_1.ApiDocumentFactory.prototype.createResource;
|
|
7
|
+
// @ts-ignore
|
|
8
|
+
common_1.ApiDocumentFactory.prototype.createResource = function (container, initArguments) {
|
|
9
|
+
// Determine primaryKey if not defined
|
|
10
|
+
if (initArguments.kind === 'Collection' && !initArguments.primaryKey && initArguments.type.ctor) {
|
|
11
|
+
const entityMetadata = connect_1.EntityMetadata.get(initArguments.type.ctor);
|
|
12
|
+
if (entityMetadata?.indexes) {
|
|
13
|
+
const primaryIndex = entityMetadata.indexes.find(x => x.primary);
|
|
14
|
+
if (primaryIndex) {
|
|
15
|
+
initArguments.primaryKey = primaryIndex.columns;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
return _createResource.call(this, container, initArguments);
|
|
20
|
+
};
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const common_1 = require("@opra/common");
|
|
4
|
+
const connect_1 = require("@sqb/connect");
|
|
5
|
+
// @ts-ignore
|
|
6
|
+
const _prepareDataTypeInitArguments = common_1.TypeDocumentFactory.prototype.prepareDataTypeInitArguments;
|
|
7
|
+
// @ts-ignore
|
|
8
|
+
common_1.TypeDocumentFactory.prototype.prepareDataTypeInitArguments = async function (schema, ctor) {
|
|
9
|
+
if (ctor && schema.kind === 'ComplexType' && schema.fields) {
|
|
10
|
+
const sqbMeta = connect_1.EntityMetadata.get(ctor);
|
|
11
|
+
for (const [fieldName, fieldSchema] of Object.entries(schema.fields)) {
|
|
12
|
+
const sqbField = sqbMeta && connect_1.EntityMetadata.getField(sqbMeta, fieldName);
|
|
13
|
+
if (!sqbField)
|
|
14
|
+
continue;
|
|
15
|
+
const detectType = !fieldSchema.type;
|
|
16
|
+
if ((0, connect_1.isAssociationField)(sqbField)) {
|
|
17
|
+
if (!fieldSchema.type) {
|
|
18
|
+
const trg = await sqbField.association.resolveTarget();
|
|
19
|
+
if (trg) {
|
|
20
|
+
fieldSchema.type = await this.importDataType(trg.ctor);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
else if (sqbField.kind === 'column') {
|
|
25
|
+
if (typeof sqbField.enum === 'object')
|
|
26
|
+
fieldSchema.enum = sqbField.enum;
|
|
27
|
+
if (fieldSchema.required == null && sqbField.notNull)
|
|
28
|
+
fieldSchema.required = true;
|
|
29
|
+
if (sqbField.type && Reflect.hasMetadata(common_1.DATATYPE_METADATA, sqbField.type)) {
|
|
30
|
+
fieldSchema.type = sqbField.type;
|
|
31
|
+
}
|
|
32
|
+
switch (sqbField.dataType) {
|
|
33
|
+
case connect_1.DataType.GUID:
|
|
34
|
+
if (!fieldSchema.type || (detectType && fieldSchema.type === 'string'))
|
|
35
|
+
fieldSchema.type = 'uuid';
|
|
36
|
+
break;
|
|
37
|
+
case connect_1.DataType.JSON:
|
|
38
|
+
if (!fieldSchema.type || (detectType && fieldSchema.type === 'any'))
|
|
39
|
+
fieldSchema.type = 'object';
|
|
40
|
+
break;
|
|
41
|
+
case connect_1.DataType.INTEGER:
|
|
42
|
+
case connect_1.DataType.SMALLINT:
|
|
43
|
+
if (!fieldSchema.type || (detectType && fieldSchema.type === 'number'))
|
|
44
|
+
fieldSchema.type = 'integer';
|
|
45
|
+
break;
|
|
46
|
+
case connect_1.DataType.BIGINT:
|
|
47
|
+
if (!fieldSchema.type || (detectType && fieldSchema.type === 'number'))
|
|
48
|
+
fieldSchema.type = 'bigint';
|
|
49
|
+
break;
|
|
50
|
+
case connect_1.DataType.DATE:
|
|
51
|
+
if (!fieldSchema.type || (detectType && (fieldSchema.type === 'timestamp' || fieldSchema.type === 'string')))
|
|
52
|
+
fieldSchema.type = 'date';
|
|
53
|
+
break;
|
|
54
|
+
case connect_1.DataType.TIMESTAMPTZ:
|
|
55
|
+
if (!fieldSchema.type || (detectType && (fieldSchema.type === 'timestamp' || fieldSchema.type === 'string')))
|
|
56
|
+
fieldSchema.type = 'timestamptz';
|
|
57
|
+
break;
|
|
58
|
+
case connect_1.DataType.TIME:
|
|
59
|
+
if (!fieldSchema.type || (detectType && (fieldSchema.type === 'timestamp' || fieldSchema.type === 'string')))
|
|
60
|
+
fieldSchema.type = 'time';
|
|
61
|
+
break;
|
|
62
|
+
case connect_1.DataType.BINARY:
|
|
63
|
+
if (!fieldSchema.type || (detectType && fieldSchema.type === 'string'))
|
|
64
|
+
fieldSchema.type = 'base64';
|
|
65
|
+
break;
|
|
66
|
+
}
|
|
67
|
+
if (!fieldSchema.type) {
|
|
68
|
+
switch (sqbField.dataType) {
|
|
69
|
+
case connect_1.DataType.BOOL:
|
|
70
|
+
fieldSchema.type = 'boolean';
|
|
71
|
+
break;
|
|
72
|
+
case connect_1.DataType.CHAR:
|
|
73
|
+
case connect_1.DataType.VARCHAR:
|
|
74
|
+
case connect_1.DataType.TEXT:
|
|
75
|
+
fieldSchema.type = 'string';
|
|
76
|
+
break;
|
|
77
|
+
case connect_1.DataType.FLOAT:
|
|
78
|
+
case connect_1.DataType.DOUBLE:
|
|
79
|
+
case connect_1.DataType.NUMBER:
|
|
80
|
+
fieldSchema.type = 'number';
|
|
81
|
+
break;
|
|
82
|
+
case connect_1.DataType.TIMESTAMP:
|
|
83
|
+
fieldSchema.type = 'timestamp';
|
|
84
|
+
break;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
if (sqbField.notNull && fieldSchema.required === undefined)
|
|
88
|
+
fieldSchema.required = sqbField.notNull;
|
|
89
|
+
if (sqbField.exclusive && fieldSchema.exclusive === undefined)
|
|
90
|
+
fieldSchema.exclusive = sqbField.exclusive;
|
|
91
|
+
if (sqbField.default !== undefined && fieldSchema.default === undefined)
|
|
92
|
+
fieldSchema.default = sqbField.default;
|
|
93
|
+
}
|
|
94
|
+
if (sqbField.exclusive && fieldSchema.exclusive === undefined)
|
|
95
|
+
fieldSchema.exclusive = sqbField.exclusive;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
return await _prepareDataTypeInitArguments.call(this, schema, ctor);
|
|
99
|
+
};
|
package/cjs/index.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
const tslib_1 = require("tslib");
|
|
4
|
-
require("./augmentation/document-factory.augmentation.js");
|
|
4
|
+
require("./augmentation/type-document-factory.augmentation.js");
|
|
5
|
+
require("./augmentation/api-document-factory.augmentation.js");
|
|
5
6
|
require("./augmentation/mapped-type.augmentation.js");
|
|
6
7
|
require("./augmentation/union-type.augmentation.js");
|
|
7
8
|
tslib_1.__exportStar(require("./sqb-adapter.js"), exports);
|
package/cjs/sqb-adapter.js
CHANGED
|
@@ -15,7 +15,7 @@ var SQBAdapter;
|
|
|
15
15
|
function transformRequest(request) {
|
|
16
16
|
const { resource } = request;
|
|
17
17
|
if (resource instanceof common_1.Collection || resource instanceof common_1.Singleton) {
|
|
18
|
-
const { params,
|
|
18
|
+
const { params, operation } = request;
|
|
19
19
|
let options = {};
|
|
20
20
|
const entityMetadata = connect_1.EntityMetadata.get(resource.type.ctor);
|
|
21
21
|
if (!entityMetadata)
|
|
@@ -27,8 +27,8 @@ var SQBAdapter;
|
|
|
27
27
|
if (primaryKeys.sort().join() !== [...resource.primaryKey].sort().join())
|
|
28
28
|
throw new Error('Resource primaryKey definition differs from SQB Entity primaryKey definition');
|
|
29
29
|
}
|
|
30
|
-
if (
|
|
31
|
-
|
|
30
|
+
if (operation === 'create' || operation === 'update' ||
|
|
31
|
+
operation === 'get' || operation === 'findMany') {
|
|
32
32
|
options.pick = params?.pick;
|
|
33
33
|
options.omit = params?.omit;
|
|
34
34
|
options.include = params?.include;
|
|
@@ -36,7 +36,7 @@ var SQBAdapter;
|
|
|
36
36
|
if (resource instanceof common_1.Collection && params?.filter) {
|
|
37
37
|
options.filter = (0, transform_filter_js_1.default)(params.filter);
|
|
38
38
|
}
|
|
39
|
-
if (
|
|
39
|
+
if (operation === 'findMany') {
|
|
40
40
|
options.sort = params?.sort;
|
|
41
41
|
options.limit = params?.limit;
|
|
42
42
|
options.offset = params?.skip;
|
|
@@ -44,7 +44,7 @@ var SQBAdapter;
|
|
|
44
44
|
options.count = params?.count;
|
|
45
45
|
}
|
|
46
46
|
options = (0, lodash_omitby_1.default)(options, lodash_isnil_1.default);
|
|
47
|
-
if (
|
|
47
|
+
if (operation === 'create') {
|
|
48
48
|
return {
|
|
49
49
|
method: 'create',
|
|
50
50
|
data: request.data,
|
|
@@ -52,14 +52,14 @@ var SQBAdapter;
|
|
|
52
52
|
args: [request.data, options]
|
|
53
53
|
};
|
|
54
54
|
}
|
|
55
|
-
if (
|
|
55
|
+
if (operation === 'deleteMany' || (operation === 'delete' && resource instanceof common_1.Singleton)) {
|
|
56
56
|
return {
|
|
57
57
|
method: 'deleteMany',
|
|
58
58
|
options,
|
|
59
59
|
args: [options]
|
|
60
60
|
};
|
|
61
61
|
}
|
|
62
|
-
if (
|
|
62
|
+
if (operation === 'delete') {
|
|
63
63
|
return {
|
|
64
64
|
method: 'delete',
|
|
65
65
|
key: request.key,
|
|
@@ -67,7 +67,7 @@ var SQBAdapter;
|
|
|
67
67
|
args: [request.key, options]
|
|
68
68
|
};
|
|
69
69
|
}
|
|
70
|
-
if (
|
|
70
|
+
if (operation === 'get') {
|
|
71
71
|
if (resource instanceof common_1.Singleton)
|
|
72
72
|
return {
|
|
73
73
|
method: 'findOne',
|
|
@@ -81,7 +81,7 @@ var SQBAdapter;
|
|
|
81
81
|
args: [request.key, options]
|
|
82
82
|
};
|
|
83
83
|
}
|
|
84
|
-
if (
|
|
84
|
+
if (operation === 'findMany') {
|
|
85
85
|
const out = {
|
|
86
86
|
method: 'findMany',
|
|
87
87
|
options,
|
|
@@ -90,7 +90,7 @@ var SQBAdapter;
|
|
|
90
90
|
out.count = params?.count;
|
|
91
91
|
return out;
|
|
92
92
|
}
|
|
93
|
-
if (
|
|
93
|
+
if (operation === 'updateMany' || (operation === 'update' && resource instanceof common_1.Singleton)) {
|
|
94
94
|
return {
|
|
95
95
|
method: 'updateMany',
|
|
96
96
|
data: request.data,
|
|
@@ -98,7 +98,7 @@ var SQBAdapter;
|
|
|
98
98
|
args: [request.data, options]
|
|
99
99
|
};
|
|
100
100
|
}
|
|
101
|
-
if (
|
|
101
|
+
if (operation === 'update') {
|
|
102
102
|
return {
|
|
103
103
|
method: 'update',
|
|
104
104
|
key: request.key,
|
|
@@ -108,7 +108,7 @@ var SQBAdapter;
|
|
|
108
108
|
};
|
|
109
109
|
}
|
|
110
110
|
}
|
|
111
|
-
throw new Error(`Unimplemented request method "${request.
|
|
111
|
+
throw new Error(`Unimplemented request method "${request.operation}"`);
|
|
112
112
|
}
|
|
113
113
|
SQBAdapter.transformRequest = transformRequest;
|
|
114
114
|
})(SQBAdapter || (exports.SQBAdapter = SQBAdapter = {}));
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { ApiDocumentFactory } from '@opra/common';
|
|
2
|
+
import { EntityMetadata } from '@sqb/connect';
|
|
3
|
+
// @ts-ignore
|
|
4
|
+
const _createResource = ApiDocumentFactory.prototype.createResource;
|
|
5
|
+
// @ts-ignore
|
|
6
|
+
ApiDocumentFactory.prototype.createResource = function (container, initArguments) {
|
|
7
|
+
// Determine primaryKey if not defined
|
|
8
|
+
if (initArguments.kind === 'Collection' && !initArguments.primaryKey && initArguments.type.ctor) {
|
|
9
|
+
const entityMetadata = EntityMetadata.get(initArguments.type.ctor);
|
|
10
|
+
if (entityMetadata?.indexes) {
|
|
11
|
+
const primaryIndex = entityMetadata.indexes.find(x => x.primary);
|
|
12
|
+
if (primaryIndex) {
|
|
13
|
+
initArguments.primaryKey = primaryIndex.columns;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
return _createResource.call(this, container, initArguments);
|
|
18
|
+
};
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { DATATYPE_METADATA, TypeDocumentFactory } from "@opra/common";
|
|
2
|
+
import { DataType as SqbDataType, EntityMetadata, isAssociationField } from '@sqb/connect';
|
|
3
|
+
// @ts-ignore
|
|
4
|
+
const _prepareDataTypeInitArguments = TypeDocumentFactory.prototype.prepareDataTypeInitArguments;
|
|
5
|
+
// @ts-ignore
|
|
6
|
+
TypeDocumentFactory.prototype.prepareDataTypeInitArguments = async function (schema, ctor) {
|
|
7
|
+
if (ctor && schema.kind === 'ComplexType' && schema.fields) {
|
|
8
|
+
const sqbMeta = EntityMetadata.get(ctor);
|
|
9
|
+
for (const [fieldName, fieldSchema] of Object.entries(schema.fields)) {
|
|
10
|
+
const sqbField = sqbMeta && EntityMetadata.getField(sqbMeta, fieldName);
|
|
11
|
+
if (!sqbField)
|
|
12
|
+
continue;
|
|
13
|
+
const detectType = !fieldSchema.type;
|
|
14
|
+
if (isAssociationField(sqbField)) {
|
|
15
|
+
if (!fieldSchema.type) {
|
|
16
|
+
const trg = await sqbField.association.resolveTarget();
|
|
17
|
+
if (trg) {
|
|
18
|
+
fieldSchema.type = await this.importDataType(trg.ctor);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
else if (sqbField.kind === 'column') {
|
|
23
|
+
if (typeof sqbField.enum === 'object')
|
|
24
|
+
fieldSchema.enum = sqbField.enum;
|
|
25
|
+
if (fieldSchema.required == null && sqbField.notNull)
|
|
26
|
+
fieldSchema.required = true;
|
|
27
|
+
if (sqbField.type && Reflect.hasMetadata(DATATYPE_METADATA, sqbField.type)) {
|
|
28
|
+
fieldSchema.type = sqbField.type;
|
|
29
|
+
}
|
|
30
|
+
switch (sqbField.dataType) {
|
|
31
|
+
case SqbDataType.GUID:
|
|
32
|
+
if (!fieldSchema.type || (detectType && fieldSchema.type === 'string'))
|
|
33
|
+
fieldSchema.type = 'uuid';
|
|
34
|
+
break;
|
|
35
|
+
case SqbDataType.JSON:
|
|
36
|
+
if (!fieldSchema.type || (detectType && fieldSchema.type === 'any'))
|
|
37
|
+
fieldSchema.type = 'object';
|
|
38
|
+
break;
|
|
39
|
+
case SqbDataType.INTEGER:
|
|
40
|
+
case SqbDataType.SMALLINT:
|
|
41
|
+
if (!fieldSchema.type || (detectType && fieldSchema.type === 'number'))
|
|
42
|
+
fieldSchema.type = 'integer';
|
|
43
|
+
break;
|
|
44
|
+
case SqbDataType.BIGINT:
|
|
45
|
+
if (!fieldSchema.type || (detectType && fieldSchema.type === 'number'))
|
|
46
|
+
fieldSchema.type = 'bigint';
|
|
47
|
+
break;
|
|
48
|
+
case SqbDataType.DATE:
|
|
49
|
+
if (!fieldSchema.type || (detectType && (fieldSchema.type === 'timestamp' || fieldSchema.type === 'string')))
|
|
50
|
+
fieldSchema.type = 'date';
|
|
51
|
+
break;
|
|
52
|
+
case SqbDataType.TIMESTAMPTZ:
|
|
53
|
+
if (!fieldSchema.type || (detectType && (fieldSchema.type === 'timestamp' || fieldSchema.type === 'string')))
|
|
54
|
+
fieldSchema.type = 'timestamptz';
|
|
55
|
+
break;
|
|
56
|
+
case SqbDataType.TIME:
|
|
57
|
+
if (!fieldSchema.type || (detectType && (fieldSchema.type === 'timestamp' || fieldSchema.type === 'string')))
|
|
58
|
+
fieldSchema.type = 'time';
|
|
59
|
+
break;
|
|
60
|
+
case SqbDataType.BINARY:
|
|
61
|
+
if (!fieldSchema.type || (detectType && fieldSchema.type === 'string'))
|
|
62
|
+
fieldSchema.type = 'base64';
|
|
63
|
+
break;
|
|
64
|
+
}
|
|
65
|
+
if (!fieldSchema.type) {
|
|
66
|
+
switch (sqbField.dataType) {
|
|
67
|
+
case SqbDataType.BOOL:
|
|
68
|
+
fieldSchema.type = 'boolean';
|
|
69
|
+
break;
|
|
70
|
+
case SqbDataType.CHAR:
|
|
71
|
+
case SqbDataType.VARCHAR:
|
|
72
|
+
case SqbDataType.TEXT:
|
|
73
|
+
fieldSchema.type = 'string';
|
|
74
|
+
break;
|
|
75
|
+
case SqbDataType.FLOAT:
|
|
76
|
+
case SqbDataType.DOUBLE:
|
|
77
|
+
case SqbDataType.NUMBER:
|
|
78
|
+
fieldSchema.type = 'number';
|
|
79
|
+
break;
|
|
80
|
+
case SqbDataType.TIMESTAMP:
|
|
81
|
+
fieldSchema.type = 'timestamp';
|
|
82
|
+
break;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
if (sqbField.notNull && fieldSchema.required === undefined)
|
|
86
|
+
fieldSchema.required = sqbField.notNull;
|
|
87
|
+
if (sqbField.exclusive && fieldSchema.exclusive === undefined)
|
|
88
|
+
fieldSchema.exclusive = sqbField.exclusive;
|
|
89
|
+
if (sqbField.default !== undefined && fieldSchema.default === undefined)
|
|
90
|
+
fieldSchema.default = sqbField.default;
|
|
91
|
+
}
|
|
92
|
+
if (sqbField.exclusive && fieldSchema.exclusive === undefined)
|
|
93
|
+
fieldSchema.exclusive = sqbField.exclusive;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
return await _prepareDataTypeInitArguments.call(this, schema, ctor);
|
|
97
|
+
};
|
package/esm/index.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import './augmentation/document-factory.augmentation.js';
|
|
1
|
+
import './augmentation/type-document-factory.augmentation.js';
|
|
2
|
+
import './augmentation/api-document-factory.augmentation.js';
|
|
2
3
|
import './augmentation/mapped-type.augmentation.js';
|
|
3
4
|
import './augmentation/union-type.augmentation.js';
|
|
4
5
|
export * from './sqb-adapter.js';
|
package/esm/sqb-adapter.js
CHANGED
|
@@ -11,7 +11,7 @@ export var SQBAdapter;
|
|
|
11
11
|
function transformRequest(request) {
|
|
12
12
|
const { resource } = request;
|
|
13
13
|
if (resource instanceof Collection || resource instanceof Singleton) {
|
|
14
|
-
const { params,
|
|
14
|
+
const { params, operation } = request;
|
|
15
15
|
let options = {};
|
|
16
16
|
const entityMetadata = EntityMetadata.get(resource.type.ctor);
|
|
17
17
|
if (!entityMetadata)
|
|
@@ -23,8 +23,8 @@ export var SQBAdapter;
|
|
|
23
23
|
if (primaryKeys.sort().join() !== [...resource.primaryKey].sort().join())
|
|
24
24
|
throw new Error('Resource primaryKey definition differs from SQB Entity primaryKey definition');
|
|
25
25
|
}
|
|
26
|
-
if (
|
|
27
|
-
|
|
26
|
+
if (operation === 'create' || operation === 'update' ||
|
|
27
|
+
operation === 'get' || operation === 'findMany') {
|
|
28
28
|
options.pick = params?.pick;
|
|
29
29
|
options.omit = params?.omit;
|
|
30
30
|
options.include = params?.include;
|
|
@@ -32,7 +32,7 @@ export var SQBAdapter;
|
|
|
32
32
|
if (resource instanceof Collection && params?.filter) {
|
|
33
33
|
options.filter = _transformFilter(params.filter);
|
|
34
34
|
}
|
|
35
|
-
if (
|
|
35
|
+
if (operation === 'findMany') {
|
|
36
36
|
options.sort = params?.sort;
|
|
37
37
|
options.limit = params?.limit;
|
|
38
38
|
options.offset = params?.skip;
|
|
@@ -40,7 +40,7 @@ export var SQBAdapter;
|
|
|
40
40
|
options.count = params?.count;
|
|
41
41
|
}
|
|
42
42
|
options = omitBy(options, isNil);
|
|
43
|
-
if (
|
|
43
|
+
if (operation === 'create') {
|
|
44
44
|
return {
|
|
45
45
|
method: 'create',
|
|
46
46
|
data: request.data,
|
|
@@ -48,14 +48,14 @@ export var SQBAdapter;
|
|
|
48
48
|
args: [request.data, options]
|
|
49
49
|
};
|
|
50
50
|
}
|
|
51
|
-
if (
|
|
51
|
+
if (operation === 'deleteMany' || (operation === 'delete' && resource instanceof Singleton)) {
|
|
52
52
|
return {
|
|
53
53
|
method: 'deleteMany',
|
|
54
54
|
options,
|
|
55
55
|
args: [options]
|
|
56
56
|
};
|
|
57
57
|
}
|
|
58
|
-
if (
|
|
58
|
+
if (operation === 'delete') {
|
|
59
59
|
return {
|
|
60
60
|
method: 'delete',
|
|
61
61
|
key: request.key,
|
|
@@ -63,7 +63,7 @@ export var SQBAdapter;
|
|
|
63
63
|
args: [request.key, options]
|
|
64
64
|
};
|
|
65
65
|
}
|
|
66
|
-
if (
|
|
66
|
+
if (operation === 'get') {
|
|
67
67
|
if (resource instanceof Singleton)
|
|
68
68
|
return {
|
|
69
69
|
method: 'findOne',
|
|
@@ -77,7 +77,7 @@ export var SQBAdapter;
|
|
|
77
77
|
args: [request.key, options]
|
|
78
78
|
};
|
|
79
79
|
}
|
|
80
|
-
if (
|
|
80
|
+
if (operation === 'findMany') {
|
|
81
81
|
const out = {
|
|
82
82
|
method: 'findMany',
|
|
83
83
|
options,
|
|
@@ -86,7 +86,7 @@ export var SQBAdapter;
|
|
|
86
86
|
out.count = params?.count;
|
|
87
87
|
return out;
|
|
88
88
|
}
|
|
89
|
-
if (
|
|
89
|
+
if (operation === 'updateMany' || (operation === 'update' && resource instanceof Singleton)) {
|
|
90
90
|
return {
|
|
91
91
|
method: 'updateMany',
|
|
92
92
|
data: request.data,
|
|
@@ -94,7 +94,7 @@ export var SQBAdapter;
|
|
|
94
94
|
args: [request.data, options]
|
|
95
95
|
};
|
|
96
96
|
}
|
|
97
|
-
if (
|
|
97
|
+
if (operation === 'update') {
|
|
98
98
|
return {
|
|
99
99
|
method: 'update',
|
|
100
100
|
key: request.key,
|
|
@@ -104,7 +104,7 @@ export var SQBAdapter;
|
|
|
104
104
|
};
|
|
105
105
|
}
|
|
106
106
|
}
|
|
107
|
-
throw new Error(`Unimplemented request method "${request.
|
|
107
|
+
throw new Error(`Unimplemented request method "${request.operation}"`);
|
|
108
108
|
}
|
|
109
109
|
SQBAdapter.transformRequest = transformRequest;
|
|
110
110
|
})(SQBAdapter || (SQBAdapter = {}));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@opra/sqb",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.26.0",
|
|
4
4
|
"description": "Opra SQB adapter package",
|
|
5
5
|
"author": "Panates",
|
|
6
6
|
"license": "MIT",
|
|
@@ -34,10 +34,10 @@
|
|
|
34
34
|
"@sqb/connect": "^4.9.1",
|
|
35
35
|
"@sqb/postgres": "^4.9.1",
|
|
36
36
|
"postgresql-client": "^2.7.1",
|
|
37
|
-
"ts-gems": "^2.
|
|
37
|
+
"ts-gems": "^2.5.0"
|
|
38
38
|
},
|
|
39
39
|
"peerDependencies": {
|
|
40
|
-
"@opra/core": "^0.
|
|
40
|
+
"@opra/core": "^0.26.0",
|
|
41
41
|
"@sqb/connect": ">= 4.9.0"
|
|
42
42
|
},
|
|
43
43
|
"type": "module",
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/types/index.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import './augmentation/document-factory.augmentation.js';
|
|
1
|
+
import './augmentation/type-document-factory.augmentation.js';
|
|
2
|
+
import './augmentation/api-document-factory.augmentation.js';
|
|
2
3
|
import './augmentation/mapped-type.augmentation.js';
|
|
3
4
|
import './augmentation/union-type.augmentation.js';
|
|
4
5
|
export * from './sqb-adapter.js';
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Maybe } from 'ts-gems';
|
|
2
2
|
import { PartialOutput } from '@opra/common';
|
|
3
|
-
import {
|
|
3
|
+
import { RequestContext } from '@opra/core';
|
|
4
4
|
import { SqbEntityService } from './sqb-entity-service.js';
|
|
5
5
|
export declare namespace SqbCollection {
|
|
6
6
|
interface Options {
|
|
@@ -10,12 +10,12 @@ export declare namespace SqbCollection {
|
|
|
10
10
|
export declare abstract class SqbCollection<T, TOutput = PartialOutput<T>> {
|
|
11
11
|
defaultLimit?: number;
|
|
12
12
|
constructor(options?: SqbCollection.Options);
|
|
13
|
-
create(ctx:
|
|
14
|
-
delete(ctx:
|
|
15
|
-
deleteMany(ctx:
|
|
16
|
-
get(ctx:
|
|
17
|
-
update(ctx:
|
|
18
|
-
updateMany(ctx:
|
|
19
|
-
findMany(ctx:
|
|
20
|
-
abstract getService(ctx:
|
|
13
|
+
create(ctx: RequestContext): Promise<TOutput>;
|
|
14
|
+
delete(ctx: RequestContext): Promise<boolean>;
|
|
15
|
+
deleteMany(ctx: RequestContext): Promise<number>;
|
|
16
|
+
get(ctx: RequestContext): Promise<Maybe<TOutput>>;
|
|
17
|
+
update(ctx: RequestContext): Promise<Maybe<TOutput>>;
|
|
18
|
+
updateMany(ctx: RequestContext): Promise<number>;
|
|
19
|
+
findMany(ctx: RequestContext): Promise<TOutput[]>;
|
|
20
|
+
abstract getService(ctx: RequestContext): SqbEntityService<T, TOutput> | Promise<SqbEntityService<T, TOutput>>;
|
|
21
21
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Maybe, Type } from 'ts-gems';
|
|
2
|
-
import {
|
|
2
|
+
import { PartialInput, PartialOutput, RequestContext } from '@opra/core';
|
|
3
3
|
import { EntityInput, Repository, SqbClient, SqbConnection } from '@sqb/connect';
|
|
4
4
|
export declare namespace SqbEntityService {
|
|
5
5
|
interface Options {
|
|
@@ -9,7 +9,7 @@ export declare namespace SqbEntityService {
|
|
|
9
9
|
}
|
|
10
10
|
export declare class SqbEntityService<T, TOutput = PartialOutput<T>> {
|
|
11
11
|
readonly typeClass: Type<T>;
|
|
12
|
-
context:
|
|
12
|
+
context: RequestContext;
|
|
13
13
|
defaultLimit: number;
|
|
14
14
|
db?: SqbClient | SqbConnection;
|
|
15
15
|
constructor(typeClass: Type<T>, options?: SqbEntityService.Options);
|
|
@@ -23,7 +23,7 @@ export declare class SqbEntityService<T, TOutput = PartialOutput<T>> {
|
|
|
23
23
|
exists(options?: Repository.ExistsOptions): Promise<boolean>;
|
|
24
24
|
update(keyValue: any, data: EntityInput<T>, options?: Repository.UpdateOptions): Promise<Maybe<TOutput>>;
|
|
25
25
|
updateMany(data: PartialInput<T>, options?: Repository.UpdateManyOptions): Promise<number>;
|
|
26
|
-
with(context:
|
|
26
|
+
with(context: RequestContext, db?: SqbClient | SqbConnection): SqbEntityService<T, TOutput>;
|
|
27
27
|
protected _onError(error: unknown): Promise<void>;
|
|
28
28
|
protected getConnection(): SqbConnection | SqbClient | Promise<SqbConnection | SqbClient>;
|
|
29
29
|
protected onError?(error: unknown): void | Promise<void>;
|
package/types/sqb-singleton.d.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { Maybe } from 'ts-gems';
|
|
2
2
|
import { PartialOutput } from '@opra/common';
|
|
3
|
-
import {
|
|
3
|
+
import { RequestContext } from '@opra/core';
|
|
4
4
|
import { SqbEntityService } from './sqb-entity-service.js';
|
|
5
5
|
export declare abstract class SqbSingleton<T> {
|
|
6
|
-
create(ctx:
|
|
7
|
-
delete(ctx:
|
|
8
|
-
get(ctx:
|
|
9
|
-
update(ctx:
|
|
10
|
-
abstract getService(req:
|
|
6
|
+
create(ctx: RequestContext): Promise<PartialOutput<T>>;
|
|
7
|
+
delete(ctx: RequestContext): Promise<boolean>;
|
|
8
|
+
get(ctx: RequestContext): Promise<Maybe<PartialOutput<T>>>;
|
|
9
|
+
update(ctx: RequestContext): Promise<Maybe<PartialOutput<T>>>;
|
|
10
|
+
abstract getService(req: RequestContext): SqbEntityService<T> | Promise<SqbEntityService<T>>;
|
|
11
11
|
}
|
|
@@ -1,116 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
const common_1 = require("@opra/common");
|
|
4
|
-
const connect_1 = require("@sqb/connect");
|
|
5
|
-
// @ts-ignore
|
|
6
|
-
const _extractFieldSchema = common_1.DocumentFactory.prototype.extractFieldSchema;
|
|
7
|
-
// @ts-ignore
|
|
8
|
-
common_1.DocumentFactory.prototype.extractFieldSchema = async function (target, ctor, metadata, name) {
|
|
9
|
-
await _extractFieldSchema.call(this, target, ctor, metadata, name);
|
|
10
|
-
const sqbMeta = connect_1.EntityMetadata.get(ctor);
|
|
11
|
-
const sqbField = sqbMeta && connect_1.EntityMetadata.getField(sqbMeta, name);
|
|
12
|
-
if (!sqbField)
|
|
13
|
-
return;
|
|
14
|
-
const detectType = !metadata.type;
|
|
15
|
-
if ((0, connect_1.isAssociationField)(sqbField)) {
|
|
16
|
-
if (!sqbField.association.returnsMany())
|
|
17
|
-
delete target.isArray;
|
|
18
|
-
if (!target.type) {
|
|
19
|
-
const trg = await sqbField.association.resolveTarget();
|
|
20
|
-
if (trg) {
|
|
21
|
-
// @ts-ignore
|
|
22
|
-
target.type = await this.importTypeClass(trg.ctor);
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
else if (sqbField.kind === 'column') {
|
|
27
|
-
if (typeof sqbField.enum === 'object')
|
|
28
|
-
metadata.enum = sqbField.enum;
|
|
29
|
-
if (target.required == null && sqbField.notNull)
|
|
30
|
-
target.required = true;
|
|
31
|
-
if (sqbField.type && Reflect.hasMetadata(common_1.DATATYPE_METADATA, sqbField.type)) {
|
|
32
|
-
target.type = sqbField.type;
|
|
33
|
-
}
|
|
34
|
-
switch (sqbField.dataType) {
|
|
35
|
-
case connect_1.DataType.GUID:
|
|
36
|
-
if (!target.type || (detectType && target.type === 'string'))
|
|
37
|
-
target.type = 'uuid';
|
|
38
|
-
break;
|
|
39
|
-
case connect_1.DataType.JSON:
|
|
40
|
-
if (!target.type || (detectType && target.type === 'any'))
|
|
41
|
-
target.type = 'object';
|
|
42
|
-
break;
|
|
43
|
-
case connect_1.DataType.INTEGER:
|
|
44
|
-
case connect_1.DataType.SMALLINT:
|
|
45
|
-
if (!target.type || (detectType && target.type === 'number'))
|
|
46
|
-
target.type = 'integer';
|
|
47
|
-
break;
|
|
48
|
-
case connect_1.DataType.BIGINT:
|
|
49
|
-
if (!target.type || (detectType && target.type === 'number'))
|
|
50
|
-
target.type = 'bigint';
|
|
51
|
-
break;
|
|
52
|
-
case connect_1.DataType.DATE:
|
|
53
|
-
if (!target.type || (detectType && (target.type === 'timestamp' || target.type === 'string')))
|
|
54
|
-
target.type = 'date';
|
|
55
|
-
break;
|
|
56
|
-
case connect_1.DataType.TIMESTAMPTZ:
|
|
57
|
-
if (!target.type || (detectType && (target.type === 'timestamp' || target.type === 'string')))
|
|
58
|
-
target.type = 'timestamptz';
|
|
59
|
-
break;
|
|
60
|
-
case connect_1.DataType.TIME:
|
|
61
|
-
if (!target.type || (detectType && (target.type === 'timestamp' || target.type === 'string')))
|
|
62
|
-
target.type = 'time';
|
|
63
|
-
break;
|
|
64
|
-
case connect_1.DataType.BINARY:
|
|
65
|
-
if (!target.type || (detectType && target.type === 'string'))
|
|
66
|
-
target.type = 'base64';
|
|
67
|
-
break;
|
|
68
|
-
}
|
|
69
|
-
if (!target.type) {
|
|
70
|
-
switch (sqbField.dataType) {
|
|
71
|
-
case connect_1.DataType.BOOL:
|
|
72
|
-
target.type = 'boolean';
|
|
73
|
-
break;
|
|
74
|
-
case connect_1.DataType.CHAR:
|
|
75
|
-
case connect_1.DataType.VARCHAR:
|
|
76
|
-
case connect_1.DataType.TEXT:
|
|
77
|
-
target.type = 'string';
|
|
78
|
-
break;
|
|
79
|
-
case connect_1.DataType.FLOAT:
|
|
80
|
-
case connect_1.DataType.DOUBLE:
|
|
81
|
-
case connect_1.DataType.NUMBER:
|
|
82
|
-
target.type = 'number';
|
|
83
|
-
break;
|
|
84
|
-
case connect_1.DataType.TIMESTAMP:
|
|
85
|
-
target.type = 'timestamp';
|
|
86
|
-
break;
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
if (sqbField.notNull && target.required === undefined)
|
|
90
|
-
target.required = sqbField.notNull;
|
|
91
|
-
if (sqbField.exclusive && target.exclusive === undefined)
|
|
92
|
-
target.exclusive = sqbField.exclusive;
|
|
93
|
-
if (sqbField.default !== undefined && target.default === undefined)
|
|
94
|
-
target.default = sqbField.default;
|
|
95
|
-
}
|
|
96
|
-
if (sqbField.exclusive && target.exclusive === undefined)
|
|
97
|
-
target.exclusive = sqbField.exclusive;
|
|
98
|
-
};
|
|
99
|
-
// @ts-ignore
|
|
100
|
-
const _extractCollectionSchema = common_1.DocumentFactory.prototype.extractCollectionSchema;
|
|
101
|
-
// @ts-ignore
|
|
102
|
-
common_1.DocumentFactory.prototype.extractCollectionSchema = async function (schema, ctor, metadata, controller) {
|
|
103
|
-
const { document } = this;
|
|
104
|
-
const dataType = document.getComplexType(schema.type);
|
|
105
|
-
// Determine primaryKey if not defined
|
|
106
|
-
if (!schema.primaryKey && dataType.ctor) {
|
|
107
|
-
const entityMetadata = connect_1.EntityMetadata.get(dataType.ctor);
|
|
108
|
-
if (entityMetadata?.indexes) {
|
|
109
|
-
const primaryIndex = entityMetadata.indexes.find(x => x.primary);
|
|
110
|
-
if (primaryIndex) {
|
|
111
|
-
schema.primaryKey = primaryIndex.columns;
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
return await _extractCollectionSchema.call(this, schema, ctor, metadata, controller);
|
|
116
|
-
};
|
|
@@ -1,114 +0,0 @@
|
|
|
1
|
-
import { DATATYPE_METADATA, DocumentFactory } from "@opra/common";
|
|
2
|
-
import { DataType as SqbDataType, EntityMetadata, isAssociationField } from '@sqb/connect';
|
|
3
|
-
// @ts-ignore
|
|
4
|
-
const _extractFieldSchema = DocumentFactory.prototype.extractFieldSchema;
|
|
5
|
-
// @ts-ignore
|
|
6
|
-
DocumentFactory.prototype.extractFieldSchema = async function (target, ctor, metadata, name) {
|
|
7
|
-
await _extractFieldSchema.call(this, target, ctor, metadata, name);
|
|
8
|
-
const sqbMeta = EntityMetadata.get(ctor);
|
|
9
|
-
const sqbField = sqbMeta && EntityMetadata.getField(sqbMeta, name);
|
|
10
|
-
if (!sqbField)
|
|
11
|
-
return;
|
|
12
|
-
const detectType = !metadata.type;
|
|
13
|
-
if (isAssociationField(sqbField)) {
|
|
14
|
-
if (!sqbField.association.returnsMany())
|
|
15
|
-
delete target.isArray;
|
|
16
|
-
if (!target.type) {
|
|
17
|
-
const trg = await sqbField.association.resolveTarget();
|
|
18
|
-
if (trg) {
|
|
19
|
-
// @ts-ignore
|
|
20
|
-
target.type = await this.importTypeClass(trg.ctor);
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
else if (sqbField.kind === 'column') {
|
|
25
|
-
if (typeof sqbField.enum === 'object')
|
|
26
|
-
metadata.enum = sqbField.enum;
|
|
27
|
-
if (target.required == null && sqbField.notNull)
|
|
28
|
-
target.required = true;
|
|
29
|
-
if (sqbField.type && Reflect.hasMetadata(DATATYPE_METADATA, sqbField.type)) {
|
|
30
|
-
target.type = sqbField.type;
|
|
31
|
-
}
|
|
32
|
-
switch (sqbField.dataType) {
|
|
33
|
-
case SqbDataType.GUID:
|
|
34
|
-
if (!target.type || (detectType && target.type === 'string'))
|
|
35
|
-
target.type = 'uuid';
|
|
36
|
-
break;
|
|
37
|
-
case SqbDataType.JSON:
|
|
38
|
-
if (!target.type || (detectType && target.type === 'any'))
|
|
39
|
-
target.type = 'object';
|
|
40
|
-
break;
|
|
41
|
-
case SqbDataType.INTEGER:
|
|
42
|
-
case SqbDataType.SMALLINT:
|
|
43
|
-
if (!target.type || (detectType && target.type === 'number'))
|
|
44
|
-
target.type = 'integer';
|
|
45
|
-
break;
|
|
46
|
-
case SqbDataType.BIGINT:
|
|
47
|
-
if (!target.type || (detectType && target.type === 'number'))
|
|
48
|
-
target.type = 'bigint';
|
|
49
|
-
break;
|
|
50
|
-
case SqbDataType.DATE:
|
|
51
|
-
if (!target.type || (detectType && (target.type === 'timestamp' || target.type === 'string')))
|
|
52
|
-
target.type = 'date';
|
|
53
|
-
break;
|
|
54
|
-
case SqbDataType.TIMESTAMPTZ:
|
|
55
|
-
if (!target.type || (detectType && (target.type === 'timestamp' || target.type === 'string')))
|
|
56
|
-
target.type = 'timestamptz';
|
|
57
|
-
break;
|
|
58
|
-
case SqbDataType.TIME:
|
|
59
|
-
if (!target.type || (detectType && (target.type === 'timestamp' || target.type === 'string')))
|
|
60
|
-
target.type = 'time';
|
|
61
|
-
break;
|
|
62
|
-
case SqbDataType.BINARY:
|
|
63
|
-
if (!target.type || (detectType && target.type === 'string'))
|
|
64
|
-
target.type = 'base64';
|
|
65
|
-
break;
|
|
66
|
-
}
|
|
67
|
-
if (!target.type) {
|
|
68
|
-
switch (sqbField.dataType) {
|
|
69
|
-
case SqbDataType.BOOL:
|
|
70
|
-
target.type = 'boolean';
|
|
71
|
-
break;
|
|
72
|
-
case SqbDataType.CHAR:
|
|
73
|
-
case SqbDataType.VARCHAR:
|
|
74
|
-
case SqbDataType.TEXT:
|
|
75
|
-
target.type = 'string';
|
|
76
|
-
break;
|
|
77
|
-
case SqbDataType.FLOAT:
|
|
78
|
-
case SqbDataType.DOUBLE:
|
|
79
|
-
case SqbDataType.NUMBER:
|
|
80
|
-
target.type = 'number';
|
|
81
|
-
break;
|
|
82
|
-
case SqbDataType.TIMESTAMP:
|
|
83
|
-
target.type = 'timestamp';
|
|
84
|
-
break;
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
if (sqbField.notNull && target.required === undefined)
|
|
88
|
-
target.required = sqbField.notNull;
|
|
89
|
-
if (sqbField.exclusive && target.exclusive === undefined)
|
|
90
|
-
target.exclusive = sqbField.exclusive;
|
|
91
|
-
if (sqbField.default !== undefined && target.default === undefined)
|
|
92
|
-
target.default = sqbField.default;
|
|
93
|
-
}
|
|
94
|
-
if (sqbField.exclusive && target.exclusive === undefined)
|
|
95
|
-
target.exclusive = sqbField.exclusive;
|
|
96
|
-
};
|
|
97
|
-
// @ts-ignore
|
|
98
|
-
const _extractCollectionSchema = DocumentFactory.prototype.extractCollectionSchema;
|
|
99
|
-
// @ts-ignore
|
|
100
|
-
DocumentFactory.prototype.extractCollectionSchema = async function (schema, ctor, metadata, controller) {
|
|
101
|
-
const { document } = this;
|
|
102
|
-
const dataType = document.getComplexType(schema.type);
|
|
103
|
-
// Determine primaryKey if not defined
|
|
104
|
-
if (!schema.primaryKey && dataType.ctor) {
|
|
105
|
-
const entityMetadata = EntityMetadata.get(dataType.ctor);
|
|
106
|
-
if (entityMetadata?.indexes) {
|
|
107
|
-
const primaryIndex = entityMetadata.indexes.find(x => x.primary);
|
|
108
|
-
if (primaryIndex) {
|
|
109
|
-
schema.primaryKey = primaryIndex.columns;
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
return await _extractCollectionSchema.call(this, schema, ctor, metadata, controller);
|
|
114
|
-
};
|
|
File without changes
|