@opra/sqb 0.33.13 → 1.0.0-alpha.1

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 (43) hide show
  1. package/cjs/{transform-filter.js → adapter-utils/parse-filter.js} +37 -12
  2. package/cjs/augmentation/datatype-factory.augmentation.js +75 -0
  3. package/cjs/augmentation/mixin-type.augmentation.js +5 -3
  4. package/cjs/index.js +3 -4
  5. package/cjs/sqb-adapter.js +66 -100
  6. package/cjs/sqb-collection-service.js +297 -0
  7. package/cjs/sqb-entity-service.js +444 -25
  8. package/cjs/sqb-singleton-service.js +180 -0
  9. package/esm/{transform-filter.js → adapter-utils/parse-filter.js} +36 -11
  10. package/esm/augmentation/datatype-factory.augmentation.js +73 -0
  11. package/esm/augmentation/mapped-type.augmentation.js +1 -1
  12. package/esm/augmentation/mixin-type.augmentation.js +6 -4
  13. package/esm/index.js +3 -4
  14. package/esm/sqb-adapter.js +66 -100
  15. package/esm/sqb-collection-service.js +293 -0
  16. package/esm/sqb-entity-service.js +444 -25
  17. package/esm/sqb-singleton-service.js +176 -0
  18. package/package.json +9 -8
  19. package/types/adapter-utils/parse-filter.d.ts +10 -0
  20. package/types/index.d.ts +3 -4
  21. package/types/sqb-adapter.d.ts +10 -8
  22. package/types/sqb-collection-service.d.ts +233 -0
  23. package/types/sqb-entity-service.d.ts +418 -18
  24. package/types/sqb-singleton-service.d.ts +137 -0
  25. package/cjs/augmentation/api-document-factory.augmentation.js +0 -20
  26. package/cjs/augmentation/type-document-factory.augmentation.js +0 -99
  27. package/cjs/sqb-collection.js +0 -80
  28. package/cjs/sqb-entity-service-base.js +0 -170
  29. package/cjs/sqb-singleton.js +0 -44
  30. package/cjs/transform-key-values.js +0 -14
  31. package/esm/augmentation/api-document-factory.augmentation.js +0 -18
  32. package/esm/augmentation/type-document-factory.augmentation.js +0 -97
  33. package/esm/sqb-collection.js +0 -76
  34. package/esm/sqb-entity-service-base.js +0 -166
  35. package/esm/sqb-singleton.js +0 -40
  36. package/esm/transform-key-values.js +0 -11
  37. package/types/augmentation/type-document-factory.augmentation.d.ts +0 -1
  38. package/types/sqb-collection.d.ts +0 -31
  39. package/types/sqb-entity-service-base.d.ts +0 -31
  40. package/types/sqb-singleton.d.ts +0 -18
  41. package/types/transform-filter.d.ts +0 -3
  42. package/types/transform-key-values.d.ts +0 -3
  43. /package/types/augmentation/{api-document-factory.augmentation.d.ts → datatype-factory.augmentation.d.ts} +0 -0
@@ -4,13 +4,39 @@ const tslib_1 = require("tslib");
4
4
  require("@opra/core");
5
5
  const common_1 = require("@opra/common");
6
6
  const sqb = tslib_1.__importStar(require("@sqb/builder"));
7
- function transformFilter(ast) {
7
+ /**
8
+ * Prepare the SQB filter based on the provided filters and options.
9
+ *
10
+ * @param {SQBAdapter.FilterInput|SQBAdapter.FilterInput[]} filters - The filter(s) to be applied.
11
+ *
12
+ * @returns {Expression} - The prepared SQB Expression.
13
+ */
14
+ function parseFilter(filters) {
15
+ const filtersArray = Array.isArray(filters) ? filters : [filters];
16
+ if (!filtersArray.length)
17
+ return undefined;
18
+ const arr = [];
19
+ for (const filter of filtersArray) {
20
+ if (!filter)
21
+ continue;
22
+ let ast;
23
+ if (typeof filter === 'string')
24
+ ast = prepareFilterAst(common_1.OpraFilter.parse(filter));
25
+ else if (filter instanceof common_1.OpraFilter.Expression)
26
+ ast = prepareFilterAst(filter);
27
+ else
28
+ ast = filter;
29
+ if (ast)
30
+ arr.push(ast);
31
+ }
32
+ return arr.length > 1 ? sqb.And(...arr) : arr[0];
33
+ }
34
+ exports.default = parseFilter;
35
+ function prepareFilterAst(ast) {
8
36
  if (!ast)
9
37
  return;
10
- if (ast instanceof common_1.OpraFilter.QualifiedIdentifier) {
11
- return sqb.Field(ast.value);
12
- }
13
- if (ast instanceof common_1.OpraFilter.NumberLiteral ||
38
+ if (ast instanceof common_1.OpraFilter.QualifiedIdentifier ||
39
+ ast instanceof common_1.OpraFilter.NumberLiteral ||
14
40
  ast instanceof common_1.OpraFilter.StringLiteral ||
15
41
  ast instanceof common_1.OpraFilter.BooleanLiteral ||
16
42
  ast instanceof common_1.OpraFilter.NullLiteral ||
@@ -19,22 +45,22 @@ function transformFilter(ast) {
19
45
  return ast.value;
20
46
  }
21
47
  if (ast instanceof common_1.OpraFilter.ArrayExpression) {
22
- return ast.items.map(transformFilter);
48
+ return ast.items.map(prepareFilterAst);
23
49
  }
24
50
  if (ast instanceof common_1.OpraFilter.NegativeExpression) {
25
- return sqb.Not(transformFilter(ast.expression));
51
+ return sqb.Not(prepareFilterAst(ast.expression));
26
52
  }
27
53
  if (ast instanceof common_1.OpraFilter.LogicalExpression) {
28
54
  if (ast.op === 'or')
29
- return sqb.Or(...ast.items.map(transformFilter));
30
- return sqb.And(...ast.items.map(transformFilter));
55
+ return sqb.Or(...ast.items.map(prepareFilterAst));
56
+ return sqb.And(...ast.items.map(prepareFilterAst));
31
57
  }
32
58
  if (ast instanceof common_1.OpraFilter.ParenthesizedExpression) {
33
- return transformFilter(ast.expression);
59
+ return prepareFilterAst(ast.expression);
34
60
  }
35
61
  if (ast instanceof common_1.OpraFilter.ComparisonExpression) {
36
62
  const left = String(ast.left);
37
- const right = transformFilter(ast.right);
63
+ const right = prepareFilterAst(ast.right);
38
64
  switch (ast.op) {
39
65
  case '=':
40
66
  return sqb.Eq(left, right);
@@ -66,4 +92,3 @@ function transformFilter(ast) {
66
92
  }
67
93
  throw new Error(`${ast.kind} is not implemented yet`);
68
94
  }
69
- exports.default = transformFilter;
@@ -0,0 +1,75 @@
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
+ var DataTypeFactory = common_1.classes.DataTypeFactory;
6
+ const _prepareComplexTypeArgs = DataTypeFactory._prepareComplexTypeArgs;
7
+ DataTypeFactory._prepareComplexTypeArgs = async function (context, owner, initArgs, metadata) {
8
+ let sqbMeta;
9
+ if (initArgs.ctor && metadata.fields && (sqbMeta = connect_1.EntityMetadata.get(initArgs.ctor))) {
10
+ metadata = (0, common_1.cloneObject)(metadata);
11
+ for (const [fieldName, fieldSchema] of Object.entries(metadata.fields)) {
12
+ const sqbField = sqbMeta && connect_1.EntityMetadata.getField(sqbMeta, fieldName);
13
+ if (!sqbField)
14
+ continue;
15
+ /** Copy type information from sqb metadata to opra */
16
+ if (!fieldSchema.type || fieldSchema.type === Object) {
17
+ if ((0, connect_1.isAssociationField)(sqbField)) {
18
+ if (!fieldSchema.type) {
19
+ const trg = await sqbField.association.resolveTarget();
20
+ if (trg?.ctor)
21
+ fieldSchema.type = trg.ctor;
22
+ }
23
+ }
24
+ else if ((0, connect_1.isColumnField)(sqbField)) {
25
+ fieldSchema.type = sqbField.enum || sqbField.type;
26
+ }
27
+ }
28
+ if ((0, connect_1.isColumnField)(sqbField)) {
29
+ const hasNoType = !fieldSchema.type || fieldSchema.type === Object;
30
+ switch (sqbField.dataType) {
31
+ case connect_1.DataType.INTEGER:
32
+ case connect_1.DataType.SMALLINT:
33
+ if (hasNoType || fieldSchema.type === Number)
34
+ fieldSchema.type = 'integer';
35
+ break;
36
+ case connect_1.DataType.GUID:
37
+ if (hasNoType || fieldSchema.type === String)
38
+ fieldSchema.type = 'uuid';
39
+ break;
40
+ case connect_1.DataType.DATE:
41
+ if (fieldSchema.type === String)
42
+ fieldSchema.type = 'datestring';
43
+ else if (hasNoType || fieldSchema.type === Date)
44
+ fieldSchema.type = 'date';
45
+ break;
46
+ case connect_1.DataType.TIMESTAMP:
47
+ if (fieldSchema.type === String)
48
+ fieldSchema.type = 'datetimestring';
49
+ else if (hasNoType || fieldSchema.type === Date)
50
+ fieldSchema.type = 'datetime';
51
+ break;
52
+ case connect_1.DataType.TIMESTAMPTZ:
53
+ if (fieldSchema.type === Date)
54
+ fieldSchema.type = 'datetime';
55
+ else if (hasNoType || fieldSchema.type === String)
56
+ fieldSchema.type = 'datetimestring';
57
+ break;
58
+ case connect_1.DataType.TIME:
59
+ if (hasNoType || fieldSchema.type === String)
60
+ fieldSchema.type = 'time';
61
+ break;
62
+ }
63
+ }
64
+ if ((0, connect_1.isAssociationField)(sqbField)) {
65
+ if (sqbField.association.returnsMany())
66
+ fieldSchema.isArray = true;
67
+ if (!fieldSchema.hasOwnProperty('exclusive'))
68
+ fieldSchema.exclusive = true;
69
+ }
70
+ if (!fieldSchema.hasOwnProperty('exclusive') && sqbField.hasOwnProperty('exclusive'))
71
+ fieldSchema.exclusive = sqbField.exclusive;
72
+ }
73
+ }
74
+ return _prepareComplexTypeArgs.apply(DataTypeFactory, [context, owner, initArgs, metadata]);
75
+ };
@@ -2,8 +2,10 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const common_1 = require("@opra/common");
4
4
  const connect_1 = require("@sqb/connect");
5
- const _applyMixin = common_1.MixinType._applyMixin;
6
- common_1.MixinType._applyMixin = function (target, ...sources) {
7
- _applyMixin.call(null, target, ...sources);
5
+ const oldDecorator = common_1.MixinType[common_1.DECORATOR];
6
+ common_1.MixinType[common_1.DECORATOR] = function (...sources) {
7
+ sources = sources.filter(x => typeof x === 'function');
8
+ const target = oldDecorator(...sources);
8
9
  connect_1.Entity.mixin(target, ...sources);
10
+ return target;
9
11
  };
package/cjs/index.js CHANGED
@@ -1,11 +1,10 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const tslib_1 = require("tslib");
4
- require("./augmentation/type-document-factory.augmentation.js");
5
- require("./augmentation/api-document-factory.augmentation.js");
4
+ require("./augmentation/datatype-factory.augmentation.js");
6
5
  require("./augmentation/mapped-type.augmentation.js");
7
6
  require("./augmentation/mixin-type.augmentation.js");
8
7
  tslib_1.__exportStar(require("./sqb-adapter.js"), exports);
9
- tslib_1.__exportStar(require("./sqb-collection.js"), exports);
8
+ tslib_1.__exportStar(require("./sqb-collection-service.js"), exports);
10
9
  tslib_1.__exportStar(require("./sqb-entity-service.js"), exports);
11
- tslib_1.__exportStar(require("./sqb-singleton.js"), exports);
10
+ tslib_1.__exportStar(require("./sqb-singleton-service.js"), exports);
@@ -2,112 +2,78 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.SQBAdapter = void 0;
4
4
  const tslib_1 = require("tslib");
5
- const common_1 = require("@opra/common");
6
5
  const connect_1 = require("@sqb/connect");
7
- const transform_filter_js_1 = tslib_1.__importDefault(require("./transform-filter.js"));
8
- const transform_key_values_js_1 = tslib_1.__importDefault(require("./transform-key-values.js"));
6
+ const parse_filter_js_1 = tslib_1.__importDefault(require("./adapter-utils/parse-filter.js"));
9
7
  var SQBAdapter;
10
8
  (function (SQBAdapter) {
11
- SQBAdapter.transformFilter = transform_filter_js_1.default;
12
- SQBAdapter.transformKeyValues = transform_key_values_js_1.default;
13
- function transformRequest(request) {
14
- const { resource } = request;
15
- if (resource instanceof common_1.Collection || resource instanceof common_1.Singleton) {
16
- const { params, endpoint } = request;
17
- let options = {};
18
- const entityMetadata = connect_1.EntityMetadata.get(resource.type.ctor);
9
+ SQBAdapter.parseFilter = parse_filter_js_1.default;
10
+ async function parseRequest(context) {
11
+ const { operation } = context;
12
+ if (operation.composition?.startsWith('Entity.') && operation.compositionOptions?.type) {
13
+ const dataType = context.document.node.getComplexType(operation.compositionOptions?.type);
14
+ const entityMetadata = connect_1.EntityMetadata.get(dataType.ctor);
19
15
  if (!entityMetadata)
20
- throw new Error(`Type class "${resource.type.ctor}" is not an SQB entity`);
21
- if (resource instanceof common_1.Collection) {
22
- const primaryIndex = entityMetadata.indexes.find(x => x.primary);
23
- // Check if resource primary keys are same with entity
24
- const primaryKeys = [...(primaryIndex && primaryIndex.columns) || []];
25
- if (primaryKeys.sort().join() !== [...resource.primaryKey].sort().join())
26
- throw new Error('Resource primaryKey definition differs from SQB Entity primaryKey definition');
27
- }
28
- const operation = endpoint.name;
29
- if (operation === 'create' || operation === 'update' ||
30
- operation === 'get' || operation === 'findMany') {
31
- options.pick = params?.pick;
32
- options.omit = params?.omit;
33
- options.include = params?.include;
34
- }
35
- if (resource instanceof common_1.Collection && params?.filter) {
36
- options.filter = (0, transform_filter_js_1.default)(params.filter);
37
- }
38
- if (operation === 'findMany') {
39
- options.sort = params?.sort;
40
- options.limit = params?.limit;
41
- options.offset = params?.skip;
42
- options.distinct = params?.distinct;
43
- options.count = params?.count;
44
- }
45
- options = (0, common_1.omitNullish)(options);
46
- if (operation === 'create') {
47
- return {
48
- method: 'create',
49
- data: request.data,
50
- options,
51
- args: [request.data, options]
52
- };
53
- }
54
- if (operation === 'deleteMany' || (operation === 'delete' && resource instanceof common_1.Singleton)) {
55
- return {
56
- method: 'deleteMany',
57
- options,
58
- args: [options]
59
- };
60
- }
61
- if (operation === 'delete') {
62
- return {
63
- method: 'delete',
64
- key: request.key,
65
- options,
66
- args: [request.key, options]
67
- };
68
- }
69
- if (operation === 'get') {
70
- if (resource instanceof common_1.Singleton)
71
- return {
72
- method: 'findOne',
73
- options,
74
- args: [options]
16
+ throw new Error(`Type class "${dataType.ctor}" is not an SQB entity`);
17
+ const { compositionOptions } = operation;
18
+ switch (operation.composition) {
19
+ case 'Entity.Create': {
20
+ const data = await context.getBody();
21
+ const options = {
22
+ projection: context.queryParams.projection,
75
23
  };
76
- return {
77
- method: 'find',
78
- key: request.key,
79
- options,
80
- args: [request.key, options]
81
- };
82
- }
83
- if (operation === 'findMany') {
84
- const out = {
85
- method: 'findMany',
86
- options,
87
- args: [options]
88
- };
89
- out.count = params?.count;
90
- return out;
91
- }
92
- if (operation === 'updateMany' || (operation === 'update' && resource instanceof common_1.Singleton)) {
93
- return {
94
- method: 'updateMany',
95
- data: request.data,
96
- options,
97
- args: [request.data, options]
98
- };
99
- }
100
- if (operation === 'update') {
101
- return {
102
- method: 'update',
103
- key: request.key,
104
- data: request.data,
105
- options,
106
- args: [request.key, request.data, options]
107
- };
24
+ return { method: 'create', data, options };
25
+ }
26
+ case 'Entity.Delete': {
27
+ const key = context.pathParams[compositionOptions.keyParameter];
28
+ const options = {
29
+ filter: SQBAdapter.parseFilter(context.queryParams.filter),
30
+ };
31
+ return { method: 'delete', key, options };
32
+ }
33
+ case 'Entity.DeleteMany': {
34
+ const options = {
35
+ filter: SQBAdapter.parseFilter(context.queryParams.filter),
36
+ };
37
+ return { method: 'deleteMany', options };
38
+ }
39
+ case 'Entity.FindMany': {
40
+ const options = {
41
+ count: context.queryParams.count,
42
+ filter: SQBAdapter.parseFilter(context.queryParams.filter),
43
+ limit: context.queryParams.limit,
44
+ offset: context.queryParams.skip,
45
+ projection: context.queryParams.projection,
46
+ sort: context.queryParams.sort,
47
+ };
48
+ return { method: 'findMany', options };
49
+ }
50
+ case 'Entity.Get': {
51
+ const key = context.pathParams[compositionOptions.keyParameter];
52
+ const options = {
53
+ projection: context.queryParams.projection,
54
+ filter: SQBAdapter.parseFilter(context.queryParams.filter),
55
+ };
56
+ return { method: 'get', key, options };
57
+ }
58
+ case 'Entity.Update': {
59
+ const data = await context.getBody();
60
+ const key = context.pathParams[compositionOptions.keyParameter];
61
+ const options = {
62
+ projection: context.queryParams.projection,
63
+ filter: SQBAdapter.parseFilter(context.queryParams.filter),
64
+ };
65
+ return { method: 'update', key, data, options };
66
+ }
67
+ case 'Entity.UpdateMany': {
68
+ const data = await context.getBody();
69
+ const options = {
70
+ filter: SQBAdapter.parseFilter(context.queryParams.filter),
71
+ };
72
+ return { method: 'updateMany', data, options };
73
+ }
108
74
  }
109
75
  }
110
- throw new Error(`Unimplemented request method "${request.operation}"`);
76
+ throw new Error(`This operation is not compatible to SQB Adapter`);
111
77
  }
112
- SQBAdapter.transformRequest = transformRequest;
78
+ SQBAdapter.parseRequest = parseRequest;
113
79
  })(SQBAdapter || (exports.SQBAdapter = SQBAdapter = {}));
@@ -0,0 +1,297 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SqbCollectionService = void 0;
4
+ const common_1 = require("@opra/common");
5
+ const sqb_adapter_js_1 = require("./sqb-adapter.js");
6
+ const sqb_entity_service_js_1 = require("./sqb-entity-service.js");
7
+ /**
8
+ * @class SqbCollectionService
9
+ * @template T - The data type class type of the resource
10
+ */
11
+ class SqbCollectionService extends sqb_entity_service_js_1.SqbEntityService {
12
+ /**
13
+ * Constructs a new instance
14
+ *
15
+ * @param {Type | string} dataType - The data type of the array elements.
16
+ * @param {SqbCollectionService.Options} [options] - The options for the array service.
17
+ * @constructor
18
+ */
19
+ constructor(dataType, options) {
20
+ super(dataType, options);
21
+ this.defaultLimit = options?.defaultLimit || 100;
22
+ }
23
+ /**
24
+ * Asserts the existence of a resource with the given ID.
25
+ * Throws a ResourceNotFoundError if the resource does not exist.
26
+ *
27
+ * @param {SQBAdapter.IdOrIds} id - The ID of the resource to assert.
28
+ * @param {SqbCollectionService.ExistsOptions} [options] - Optional options for checking the existence.
29
+ * @returns {Promise<void>} - A Promise that resolves when the resource exists.
30
+ * @throws {ResourceNotAvailableError} - If the resource does not exist.
31
+ */
32
+ async assert(id, options) {
33
+ if (!(await this.exists(id, options)))
34
+ throw new common_1.ResourceNotAvailableError(this.getResourceName(), id);
35
+ }
36
+ /**
37
+ * Creates a new resource
38
+ *
39
+ * @param {PartialDTO<T>} input - The input data
40
+ * @param {SqbCollectionService.CreateOptions} [options] - The options object
41
+ * @returns {Promise<PartialDTO<T>>} A promise that resolves to the created resource
42
+ * @throws {Error} if an unknown error occurs while creating the resource
43
+ */
44
+ async create(input, options) {
45
+ const info = {
46
+ crud: 'create',
47
+ method: 'create',
48
+ byId: false,
49
+ input,
50
+ options,
51
+ };
52
+ return this._intercept(() => this._create(input, options), info);
53
+ }
54
+ /**
55
+ * Returns the count of records based on the provided options
56
+ *
57
+ * @param {SqbCollectionService.CountOptions} options - The options for the count operation.
58
+ * @return {Promise<number>} - A promise that resolves to the count of records
59
+ */
60
+ async count(options) {
61
+ const info = {
62
+ crud: 'read',
63
+ method: 'count',
64
+ byId: false,
65
+ options,
66
+ };
67
+ return this._intercept(async () => {
68
+ const filter = sqb_adapter_js_1.SQBAdapter.parseFilter([await this._getCommonFilter(info), options?.filter]);
69
+ return this._count({ ...options, filter });
70
+ }, info);
71
+ }
72
+ /**
73
+ * Deletes a record from the collection.
74
+ *
75
+ * @param {SQBAdapter.IdOrIds} id - The ID of the document to delete.
76
+ * @param {SqbCollectionService.DeleteOptions} [options] - Optional delete options.
77
+ * @return {Promise<number>} - A Promise that resolves to the number of documents deleted.
78
+ */
79
+ async delete(id, options) {
80
+ const info = {
81
+ crud: 'delete',
82
+ method: 'delete',
83
+ byId: true,
84
+ documentId: id,
85
+ options,
86
+ };
87
+ return this._intercept(async () => {
88
+ const filter = sqb_adapter_js_1.SQBAdapter.parseFilter([await this._getCommonFilter(info), options?.filter]);
89
+ return this._delete(id, { ...options, filter });
90
+ }, info);
91
+ }
92
+ /**
93
+ * Deletes multiple documents from the collection that meet the specified filter criteria.
94
+ *
95
+ * @param {SqbCollectionService.DeleteManyOptions} options - The options for the delete operation.
96
+ * @return {Promise<number>} - A promise that resolves to the number of documents deleted.
97
+ */
98
+ async deleteMany(options) {
99
+ const info = {
100
+ crud: 'delete',
101
+ method: 'deleteMany',
102
+ byId: false,
103
+ options,
104
+ };
105
+ return this._intercept(async () => {
106
+ const filter = sqb_adapter_js_1.SQBAdapter.parseFilter([await this._getCommonFilter(info), options?.filter]);
107
+ return this._deleteMany({ ...options, filter });
108
+ }, info);
109
+ }
110
+ /**
111
+ * Checks if a record with the given id exists.
112
+ *
113
+ * @param {SQBAdapter.IdOrIds} id - The id of the object to check.
114
+ * @param {SqbCollectionService.ExistsOptions} [options] - The options for the query (optional).
115
+ * @return {Promise<boolean>} - A Promise that resolves to a boolean indicating whether the record exists or not.
116
+ */
117
+ async exists(id, options) {
118
+ const info = {
119
+ crud: 'read',
120
+ method: 'exists',
121
+ byId: true,
122
+ documentId: id,
123
+ options,
124
+ };
125
+ return this._intercept(async () => {
126
+ const filter = sqb_adapter_js_1.SQBAdapter.parseFilter([await this._getCommonFilter(info), options?.filter]);
127
+ return this._exists(id, { ...options, filter });
128
+ }, info);
129
+ }
130
+ /**
131
+ * Checks if a record with the given arguments exists.
132
+ *
133
+ * @param {SqbCollectionService.ExistsOneOptions} [options] - The options for the query (optional).
134
+ * @return {Promise<boolean>} - A Promise that resolves to a boolean indicating whether the record exists or not.
135
+ */
136
+ async existsOne(options) {
137
+ const info = {
138
+ crud: 'read',
139
+ method: 'existsOne',
140
+ byId: false,
141
+ options,
142
+ };
143
+ return this._intercept(async () => {
144
+ const filter = sqb_adapter_js_1.SQBAdapter.parseFilter([await this._getCommonFilter(info), options?.filter]);
145
+ return this._existsOne({ ...options, filter });
146
+ }, info);
147
+ }
148
+ /**
149
+ * Finds a record by ID.
150
+ *
151
+ * @param {SQBAdapter.Id} id - The ID of the record.
152
+ * @param {SqbCollectionService.FindOneOptions} [options] - The options for the find query.
153
+ * @return {Promise<PartialDTO<T | undefined>>} - A promise resolving to the found document, or undefined if not found.
154
+ */
155
+ async findById(id, options) {
156
+ const info = {
157
+ crud: 'read',
158
+ method: 'findById',
159
+ byId: true,
160
+ documentId: id,
161
+ options,
162
+ };
163
+ return this._intercept(async () => {
164
+ const documentFilter = await this._getCommonFilter(info);
165
+ const filter = sqb_adapter_js_1.SQBAdapter.parseFilter([documentFilter, options?.filter]);
166
+ return this._findById(id, { ...options, filter });
167
+ }, info);
168
+ }
169
+ /**
170
+ * Finds a record in the collection that matches the specified options.
171
+ *
172
+ * @param {SqbCollectionService.FindOneOptions} options - The options for the query.
173
+ * @return {Promise<PartialDTO<T> | undefined>} A promise that resolves with the found document or undefined if no document is found.
174
+ */
175
+ async findOne(options) {
176
+ const info = {
177
+ crud: 'read',
178
+ method: 'findOne',
179
+ byId: false,
180
+ options,
181
+ };
182
+ return this._intercept(async () => {
183
+ const filter = sqb_adapter_js_1.SQBAdapter.parseFilter([await this._getCommonFilter(info), options?.filter]);
184
+ return this._findOne({ ...options, filter });
185
+ }, info);
186
+ }
187
+ /**
188
+ * Finds multiple records in collection.
189
+ *
190
+ * @param {SqbCollectionService.FindManyOptions} options - The options for the find operation.
191
+ * @return A Promise that resolves to an array of partial outputs of type T.
192
+ */
193
+ async findMany(options) {
194
+ const info = {
195
+ crud: 'read',
196
+ method: 'findMany',
197
+ byId: false,
198
+ options,
199
+ };
200
+ return this._intercept(async () => {
201
+ const filter = sqb_adapter_js_1.SQBAdapter.parseFilter([await this._getCommonFilter(info), options?.filter]);
202
+ return this._findMany({ ...options, filter });
203
+ }, info);
204
+ }
205
+ /**
206
+ * Finds multiple records in the collection and returns both records (max limit)
207
+ * and total count that matched the given criteria
208
+ *
209
+ * @param {SqbCollectionService.FindManyOptions} options - The options for the find operation.
210
+ * @return A Promise that resolves to an array of partial outputs of type T and total count.
211
+ */
212
+ async findManyWithCount(options) {
213
+ const [items, count] = await Promise.all([this.findMany(options), this.count(options)]);
214
+ return { count, items };
215
+ }
216
+ /**
217
+ * Retrieves a records from the collection by its ID. Throws error if not found.
218
+ *
219
+ * @param {SQBAdapter.Id} id - The ID of the document to retrieve.
220
+ * @param {SqbCollectionService.FindOneOptions} [options] - Optional options for the findOne operation.
221
+ * @returns {Promise<PartialDTO<T>>} - A promise that resolves to the retrieved document,
222
+ * or rejects with a ResourceNotFoundError if the document does not exist.
223
+ * @throws {ResourceNotAvailableError} - If the document with the specified ID does not exist.
224
+ */
225
+ async get(id, options) {
226
+ const out = await this.findById(id, options);
227
+ if (!out)
228
+ throw new common_1.ResourceNotAvailableError(this.getResourceName(), id);
229
+ return out;
230
+ }
231
+ /**
232
+ * Updates a record with the given id in the collection.
233
+ *
234
+ * @param {SQBAdapter.IdOrIds} id - The id of the document to update.
235
+ * @param {PatchDTO<T>} input - The partial input object containing the fields to update.
236
+ * @param {SqbCollectionService.UpdateOptions} [options] - The options for the update operation.
237
+ * @returns {Promise<PartialDTO<T> | undefined>} A promise that resolves to the updated document or
238
+ * undefined if the document was not found.
239
+ */
240
+ async update(id, input, options) {
241
+ const info = {
242
+ crud: 'update',
243
+ method: 'update',
244
+ documentId: id,
245
+ byId: true,
246
+ input,
247
+ options,
248
+ };
249
+ return this._intercept(async () => {
250
+ const filter = sqb_adapter_js_1.SQBAdapter.parseFilter([await this._getCommonFilter(info), options?.filter]);
251
+ return this._update(id, input, { ...options, filter });
252
+ }, info);
253
+ }
254
+ /**
255
+ * Updates a record in the collection with the specified ID and returns updated record count
256
+ *
257
+ * @param {any} id - The ID of the document to update.
258
+ * @param {PatchDTO<T>} input - The partial input data to update the document with.
259
+ * @param {SqbCollectionService.UpdateOptions} options - The options for updating the document.
260
+ * @returns {Promise<number>} - A promise that resolves to the number of documents modified.
261
+ */
262
+ async updateOnly(id, input, options) {
263
+ const info = {
264
+ crud: 'update',
265
+ method: 'update',
266
+ documentId: id,
267
+ byId: true,
268
+ input,
269
+ options,
270
+ };
271
+ return this._intercept(async () => {
272
+ const filter = sqb_adapter_js_1.SQBAdapter.parseFilter([await this._getCommonFilter(info), options?.filter]);
273
+ return this._updateOnly(id, input, { ...options, filter });
274
+ }, info);
275
+ }
276
+ /**
277
+ * Updates multiple records in the collection based on the specified input and options.
278
+ *
279
+ * @param {PatchDTO<T>} input - The partial input to update the documents with.
280
+ * @param {SqbCollectionService.UpdateManyOptions} options - The options for updating the documents.
281
+ * @return {Promise<number>} - A promise that resolves to the number of documents matched and modified.
282
+ */
283
+ async updateMany(input, options) {
284
+ const info = {
285
+ crud: 'update',
286
+ method: 'updateMany',
287
+ byId: false,
288
+ input,
289
+ options,
290
+ };
291
+ return this._intercept(async () => {
292
+ const filter = sqb_adapter_js_1.SQBAdapter.parseFilter([await this._getCommonFilter(info), options?.filter]);
293
+ return this._updateMany(input, { ...options, filter });
294
+ }, info);
295
+ }
296
+ }
297
+ exports.SqbCollectionService = SqbCollectionService;