@xoxno/types 1.0.76 → 1.0.78
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/dist/index.d.ts +5489 -257
- package/dist/index.js +0 -1
- package/package.json +4 -2
- package/dist/cosmos-db/cosmos-db-query.d.ts +0 -81
- package/dist/cosmos-db/cosmos-db-query.js +0 -435
package/dist/index.js
CHANGED
|
@@ -33,7 +33,6 @@ __exportStar(require("./common/tokenPayent"), exports);
|
|
|
33
33
|
__exportStar(require("./cosmos-db/cosmos-db-container.enum"), exports);
|
|
34
34
|
__exportStar(require("./cosmos-db/cosmos-db-generic-filter"), exports);
|
|
35
35
|
__exportStar(require("./cosmos-db/cosmos-db-paginated-response.dto"), exports);
|
|
36
|
-
__exportStar(require("./cosmos-db/cosmos-db-query"), exports);
|
|
37
36
|
__exportStar(require("./cosmos-db/documents/activity/nft-activity.doc"), exports);
|
|
38
37
|
__exportStar(require("./cosmos-db/documents/chat/block-user.dto"), exports);
|
|
39
38
|
__exportStar(require("./cosmos-db/documents/chat/chat-data-type.enum"), exports);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xoxno/types",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.78",
|
|
4
4
|
"description": "Shared types and utilities for XOXNO API.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
"dist"
|
|
9
9
|
],
|
|
10
10
|
"scripts": {
|
|
11
|
-
"build": "node generate-barrel.mjs && eslint 'src/index.ts' --fix && tsc",
|
|
11
|
+
"build": "node generate-barrel.mjs && eslint 'src/index.ts' --fix && tsc && rollup -c && node strip-types.js",
|
|
12
12
|
"build:watch": "tsc --watch",
|
|
13
13
|
"prepublishOnly": "npm run build",
|
|
14
14
|
"lint": "eslint 'src/**/*.ts'",
|
|
@@ -41,6 +41,8 @@
|
|
|
41
41
|
"eslint-config-prettier": "^10.1.5",
|
|
42
42
|
"eslint-plugin-prettier": "^5.5.1",
|
|
43
43
|
"prettier": "^3.6.2",
|
|
44
|
+
"rollup": "^4.45.1",
|
|
45
|
+
"rollup-plugin-dts": "^6.2.1",
|
|
44
46
|
"typescript": "^5.8.3",
|
|
45
47
|
"typescript-eslint": "^8.35.1"
|
|
46
48
|
},
|
|
@@ -1,81 +0,0 @@
|
|
|
1
|
-
import { SqlQuerySpec } from '@azure/cosmos';
|
|
2
|
-
import { CosmosDbGenericFilter } from './cosmos-db-generic-filter';
|
|
3
|
-
import { NftMetadataAttributes } from './documents/token/nft-metadata-attributes';
|
|
4
|
-
export declare enum QueryConditionOperator {
|
|
5
|
-
EQUAL = "EQUAL",
|
|
6
|
-
NOT_EQUAL = "NOT_EQUAL",
|
|
7
|
-
GREATER_THAN = "GREATER_THAN",
|
|
8
|
-
LESS_THAN = "LESS_THAN",
|
|
9
|
-
GREATER_THAN_OR_EQUAL = "GREATER_THAN_OR_EQUAL",
|
|
10
|
-
LESS_THAN_OR_EQUAL = "LESS_THAN_OR_EQUAL",
|
|
11
|
-
IN = "IN",
|
|
12
|
-
NOT_IN = "NOT_IN"
|
|
13
|
-
}
|
|
14
|
-
export declare enum QueryLogicalOperator {
|
|
15
|
-
AND = "AND",
|
|
16
|
-
OR = "OR"
|
|
17
|
-
}
|
|
18
|
-
export declare enum QueryOrderDirection {
|
|
19
|
-
ASC = "asc",
|
|
20
|
-
DESC = "desc"
|
|
21
|
-
}
|
|
22
|
-
export interface QueryCondition {
|
|
23
|
-
field: string;
|
|
24
|
-
value: string | number | boolean | string[] | number[];
|
|
25
|
-
operator: QueryConditionOperator;
|
|
26
|
-
logicalOperator?: QueryLogicalOperator;
|
|
27
|
-
}
|
|
28
|
-
export interface QueryCustomCondition {
|
|
29
|
-
condition: string;
|
|
30
|
-
logicalOperator?: QueryLogicalOperator;
|
|
31
|
-
parameters?: {
|
|
32
|
-
[key: string]: string | number | boolean | string[] | number[];
|
|
33
|
-
};
|
|
34
|
-
}
|
|
35
|
-
export interface CosmosDbQuery {
|
|
36
|
-
selectFields?: string[];
|
|
37
|
-
conditions: QueryCondition[];
|
|
38
|
-
groupedConditions?: QueryConditionGroup[];
|
|
39
|
-
customConditions?: QueryCustomCondition[];
|
|
40
|
-
orderBy?: {
|
|
41
|
-
field: string;
|
|
42
|
-
direction: QueryOrderDirection;
|
|
43
|
-
};
|
|
44
|
-
skip?: number;
|
|
45
|
-
top?: number;
|
|
46
|
-
}
|
|
47
|
-
export interface QueryConditionGroup {
|
|
48
|
-
conditions: QueryCondition[];
|
|
49
|
-
logicalOperator: QueryLogicalOperator;
|
|
50
|
-
}
|
|
51
|
-
export declare class CosmosDbQueryBuilder {
|
|
52
|
-
private query;
|
|
53
|
-
private parameters;
|
|
54
|
-
private isCountQuery;
|
|
55
|
-
constructor();
|
|
56
|
-
where(field: string, value: string | number | boolean | string[] | number[], operator: QueryConditionOperator, logicalOperator?: QueryLogicalOperator): CosmosDbQueryBuilder;
|
|
57
|
-
whereCustom(condition: string, logicalOperator?: QueryLogicalOperator, parameters?: Record<string, string | number | boolean | string[] | number[]>): CosmosDbQueryBuilder;
|
|
58
|
-
whereRange(field: string, lower: number, upper: number, logicalOperator?: QueryLogicalOperator): CosmosDbQueryBuilder;
|
|
59
|
-
whereGroup(conditions: QueryCondition[], logicalOperator?: QueryLogicalOperator): CosmosDbQueryBuilder;
|
|
60
|
-
orderBy(field: string, direction: QueryOrderDirection): CosmosDbQueryBuilder;
|
|
61
|
-
setOffset(offset: number): CosmosDbQueryBuilder;
|
|
62
|
-
setLimit(limit: number): CosmosDbQueryBuilder;
|
|
63
|
-
selectFields(fields: (string | number | symbol)[]): CosmosDbQueryBuilder;
|
|
64
|
-
count(): this;
|
|
65
|
-
buildSqlQuery(applyPagination?: boolean): SqlQuerySpec;
|
|
66
|
-
private buildCustomProjection;
|
|
67
|
-
private getSqlOperator;
|
|
68
|
-
fromFilter<T>(filter: CosmosDbGenericFilter<T>): CosmosDbQueryBuilder;
|
|
69
|
-
getMintProfilePricesQueryAndParams(mintToken: string[]): {
|
|
70
|
-
filterString: string;
|
|
71
|
-
parameters: Record<string, string>;
|
|
72
|
-
};
|
|
73
|
-
getAttributesQueryAndParams(key: string, attributes: NftMetadataAttributes[], traitLogicalOperator?: QueryLogicalOperator): {
|
|
74
|
-
filterString: string;
|
|
75
|
-
parameters: Record<string, string>;
|
|
76
|
-
};
|
|
77
|
-
groupAttributesByTrait(attributes: NftMetadataAttributes[]): {
|
|
78
|
-
trait_type: string;
|
|
79
|
-
values: string[];
|
|
80
|
-
}[];
|
|
81
|
-
}
|
|
@@ -1,435 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.CosmosDbQueryBuilder = exports.QueryOrderDirection = exports.QueryLogicalOperator = exports.QueryConditionOperator = void 0;
|
|
4
|
-
const enums_1 = require("../common/enums");
|
|
5
|
-
var QueryConditionOperator;
|
|
6
|
-
(function (QueryConditionOperator) {
|
|
7
|
-
QueryConditionOperator["EQUAL"] = "EQUAL";
|
|
8
|
-
QueryConditionOperator["NOT_EQUAL"] = "NOT_EQUAL";
|
|
9
|
-
QueryConditionOperator["GREATER_THAN"] = "GREATER_THAN";
|
|
10
|
-
QueryConditionOperator["LESS_THAN"] = "LESS_THAN";
|
|
11
|
-
QueryConditionOperator["GREATER_THAN_OR_EQUAL"] = "GREATER_THAN_OR_EQUAL";
|
|
12
|
-
QueryConditionOperator["LESS_THAN_OR_EQUAL"] = "LESS_THAN_OR_EQUAL";
|
|
13
|
-
QueryConditionOperator["IN"] = "IN";
|
|
14
|
-
QueryConditionOperator["NOT_IN"] = "NOT_IN";
|
|
15
|
-
})(QueryConditionOperator || (exports.QueryConditionOperator = QueryConditionOperator = {}));
|
|
16
|
-
var QueryLogicalOperator;
|
|
17
|
-
(function (QueryLogicalOperator) {
|
|
18
|
-
QueryLogicalOperator["AND"] = "AND";
|
|
19
|
-
QueryLogicalOperator["OR"] = "OR";
|
|
20
|
-
})(QueryLogicalOperator || (exports.QueryLogicalOperator = QueryLogicalOperator = {}));
|
|
21
|
-
var QueryOrderDirection;
|
|
22
|
-
(function (QueryOrderDirection) {
|
|
23
|
-
QueryOrderDirection["ASC"] = "asc";
|
|
24
|
-
QueryOrderDirection["DESC"] = "desc";
|
|
25
|
-
})(QueryOrderDirection || (exports.QueryOrderDirection = QueryOrderDirection = {}));
|
|
26
|
-
class CosmosDbQueryBuilder {
|
|
27
|
-
constructor() {
|
|
28
|
-
this.parameters = {};
|
|
29
|
-
this.isCountQuery = false;
|
|
30
|
-
this.query = {
|
|
31
|
-
conditions: [],
|
|
32
|
-
groupedConditions: [],
|
|
33
|
-
customConditions: [],
|
|
34
|
-
};
|
|
35
|
-
}
|
|
36
|
-
where(field, value, operator, logicalOperator = QueryLogicalOperator.AND) {
|
|
37
|
-
this.query.conditions.push({ field, value, operator, logicalOperator });
|
|
38
|
-
return this;
|
|
39
|
-
}
|
|
40
|
-
whereCustom(condition, logicalOperator = QueryLogicalOperator.AND, parameters = {}) {
|
|
41
|
-
if (!this.query.customConditions) {
|
|
42
|
-
this.query.customConditions = [];
|
|
43
|
-
}
|
|
44
|
-
this.query.customConditions.push({
|
|
45
|
-
condition,
|
|
46
|
-
logicalOperator,
|
|
47
|
-
parameters,
|
|
48
|
-
});
|
|
49
|
-
return this;
|
|
50
|
-
}
|
|
51
|
-
whereRange(field, lower, upper, logicalOperator = QueryLogicalOperator.AND) {
|
|
52
|
-
field = field.replace('Range', '');
|
|
53
|
-
this.query.conditions.push({
|
|
54
|
-
field,
|
|
55
|
-
value: lower,
|
|
56
|
-
operator: QueryConditionOperator.GREATER_THAN_OR_EQUAL,
|
|
57
|
-
logicalOperator,
|
|
58
|
-
});
|
|
59
|
-
this.query.conditions.push({
|
|
60
|
-
field,
|
|
61
|
-
value: upper,
|
|
62
|
-
operator: QueryConditionOperator.LESS_THAN_OR_EQUAL,
|
|
63
|
-
logicalOperator,
|
|
64
|
-
});
|
|
65
|
-
return this;
|
|
66
|
-
}
|
|
67
|
-
whereGroup(conditions, logicalOperator = QueryLogicalOperator.AND) {
|
|
68
|
-
this.query.groupedConditions = this.query.groupedConditions || [];
|
|
69
|
-
this.query.groupedConditions.push({ conditions, logicalOperator });
|
|
70
|
-
return this;
|
|
71
|
-
}
|
|
72
|
-
orderBy(field, direction) {
|
|
73
|
-
this.query.orderBy = { field, direction };
|
|
74
|
-
return this;
|
|
75
|
-
}
|
|
76
|
-
setOffset(offset) {
|
|
77
|
-
this.query.skip = offset;
|
|
78
|
-
return this;
|
|
79
|
-
}
|
|
80
|
-
setLimit(limit) {
|
|
81
|
-
// if (limit > 100) {
|
|
82
|
-
// throw new Error('Limit cannot be greater than 100');
|
|
83
|
-
// }
|
|
84
|
-
// think about how to handle this to protect external calls
|
|
85
|
-
// at the same time allow internal calls to have higher limits
|
|
86
|
-
this.query.top = limit;
|
|
87
|
-
return this;
|
|
88
|
-
}
|
|
89
|
-
selectFields(fields) {
|
|
90
|
-
this.query.selectFields = fields;
|
|
91
|
-
return this;
|
|
92
|
-
}
|
|
93
|
-
count() {
|
|
94
|
-
this.isCountQuery = true;
|
|
95
|
-
return this;
|
|
96
|
-
}
|
|
97
|
-
buildSqlQuery(applyPagination = true) {
|
|
98
|
-
let sqlQuery = 'SELECT * FROM c';
|
|
99
|
-
let paramIndex = 0;
|
|
100
|
-
if (this.isCountQuery) {
|
|
101
|
-
sqlQuery = 'SELECT VALUE COUNT(1) FROM c';
|
|
102
|
-
}
|
|
103
|
-
else if (this.query.selectFields) {
|
|
104
|
-
const dynamicProjection = this.buildCustomProjection(this.query.selectFields);
|
|
105
|
-
sqlQuery = sqlQuery.replace('SELECT *', `SELECT VALUE ${dynamicProjection}`);
|
|
106
|
-
}
|
|
107
|
-
if (this.query.conditions.length > 0) {
|
|
108
|
-
sqlQuery += ' WHERE';
|
|
109
|
-
for (const condition of this.query.conditions) {
|
|
110
|
-
// 'from' is a reserved word in Cosmos DB, so we need to use bracket notation
|
|
111
|
-
if (condition.field === 'from') {
|
|
112
|
-
condition.field = `['from']`;
|
|
113
|
-
}
|
|
114
|
-
// we use IN operator for arrays and = for single values
|
|
115
|
-
if (condition.operator === QueryConditionOperator.IN) {
|
|
116
|
-
// If the value is an array with a single element, use the equal operator
|
|
117
|
-
if (Array.isArray(condition.value) && condition.value.length === 1) {
|
|
118
|
-
sqlQuery += ` c.${condition.field} = @p${paramIndex}`;
|
|
119
|
-
}
|
|
120
|
-
else {
|
|
121
|
-
sqlQuery += ` ARRAY_CONTAINS(@p${paramIndex}, c.${condition.field})`;
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
else if (condition.operator === QueryConditionOperator.NOT_IN) {
|
|
125
|
-
// If the value is an array with a single element, use the not equal operator
|
|
126
|
-
if (Array.isArray(condition.value) && condition.value.length === 1) {
|
|
127
|
-
sqlQuery += ` c.${condition.field} != @p${paramIndex}`;
|
|
128
|
-
}
|
|
129
|
-
else {
|
|
130
|
-
sqlQuery += ` NOT ARRAY_CONTAINS(@p${paramIndex}, c.${condition.field})`;
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
else {
|
|
134
|
-
sqlQuery += ` c.${condition.field} ${this.getSqlOperator(condition.operator)} @p${paramIndex}`;
|
|
135
|
-
}
|
|
136
|
-
if (condition !== this.query.conditions[this.query.conditions.length - 1]) {
|
|
137
|
-
sqlQuery += ` ${condition.logicalOperator}`;
|
|
138
|
-
}
|
|
139
|
-
// If the value is an array with a single element, use the equal operator
|
|
140
|
-
if (Array.isArray(condition.value) && condition.value.length === 1) {
|
|
141
|
-
this.parameters[`@p${paramIndex}`] = condition.value[0];
|
|
142
|
-
}
|
|
143
|
-
else {
|
|
144
|
-
this.parameters[`@p${paramIndex}`] = condition.value;
|
|
145
|
-
}
|
|
146
|
-
paramIndex++;
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
if (this.query.groupedConditions &&
|
|
150
|
-
this.query.groupedConditions.length > 0) {
|
|
151
|
-
let groupedConditionsSql = '';
|
|
152
|
-
for (const groupedCondition of this.query.groupedConditions) {
|
|
153
|
-
let groupSql = '';
|
|
154
|
-
for (const condition of groupedCondition.conditions) {
|
|
155
|
-
if (condition.operator === QueryConditionOperator.IN) {
|
|
156
|
-
groupSql += ` ARRAY_CONTAINS(@p${paramIndex}, c.${condition.field})`;
|
|
157
|
-
}
|
|
158
|
-
else {
|
|
159
|
-
groupSql += ` c.${condition.field} ${this.getSqlOperator(condition.operator)} @p${paramIndex} `;
|
|
160
|
-
}
|
|
161
|
-
if (condition !==
|
|
162
|
-
groupedCondition.conditions[groupedCondition.conditions.length - 1]) {
|
|
163
|
-
groupSql += ` ${condition.logicalOperator}`;
|
|
164
|
-
}
|
|
165
|
-
this.parameters[`@p${paramIndex}`] = condition.value;
|
|
166
|
-
paramIndex++;
|
|
167
|
-
}
|
|
168
|
-
groupedConditionsSql += ` (${groupSql})`;
|
|
169
|
-
if (groupedCondition !==
|
|
170
|
-
this.query.groupedConditions[this.query.groupedConditions.length - 1]) {
|
|
171
|
-
groupedConditionsSql += ` ${groupedCondition.logicalOperator}`;
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
|
-
if (groupedConditionsSql !== '') {
|
|
175
|
-
sqlQuery += ` AND${groupedConditionsSql}`;
|
|
176
|
-
}
|
|
177
|
-
}
|
|
178
|
-
if (this.query.customConditions) {
|
|
179
|
-
// If there are already conditions in the query, add an AND operator
|
|
180
|
-
if (this.query.conditions.length > 0 ||
|
|
181
|
-
(this.query.groupedConditions &&
|
|
182
|
-
this.query.groupedConditions.length > 0)) {
|
|
183
|
-
sqlQuery += ' AND';
|
|
184
|
-
}
|
|
185
|
-
else {
|
|
186
|
-
sqlQuery += ' WHERE';
|
|
187
|
-
}
|
|
188
|
-
for (const customCondition of this.query.customConditions) {
|
|
189
|
-
sqlQuery += ` ${customCondition.condition}`;
|
|
190
|
-
// If this isn't the last custom condition, add the logical operator
|
|
191
|
-
if (customCondition !==
|
|
192
|
-
this.query.customConditions[this.query.customConditions.length - 1]) {
|
|
193
|
-
sqlQuery += ` ${customCondition.logicalOperator}`;
|
|
194
|
-
}
|
|
195
|
-
// Add the custom condition's parameters to this.parameters
|
|
196
|
-
if (customCondition.parameters) {
|
|
197
|
-
for (const [key, value] of Object.entries(customCondition.parameters)) {
|
|
198
|
-
this.parameters[key] = value;
|
|
199
|
-
}
|
|
200
|
-
}
|
|
201
|
-
}
|
|
202
|
-
}
|
|
203
|
-
if (this.query.orderBy) {
|
|
204
|
-
sqlQuery += ` ORDER BY c.${this.query.orderBy.field} ${this.query.orderBy.direction}`;
|
|
205
|
-
}
|
|
206
|
-
// Default values
|
|
207
|
-
const defaultOffset = 0;
|
|
208
|
-
const defaultLimit = 25;
|
|
209
|
-
if (this.query.skip !== undefined || this.query.top !== undefined) {
|
|
210
|
-
const offset = this.query.skip !== undefined ? this.query.skip : defaultOffset;
|
|
211
|
-
const limit = this.query.top !== undefined ? this.query.top : defaultLimit;
|
|
212
|
-
if (applyPagination) {
|
|
213
|
-
sqlQuery += ` OFFSET ${offset} LIMIT ${limit}`;
|
|
214
|
-
}
|
|
215
|
-
}
|
|
216
|
-
const parameters = Object.entries(this.parameters).map(([name, value]) => ({ name, value }));
|
|
217
|
-
sqlQuery = sqlQuery.replace(/\.\[/g, '[');
|
|
218
|
-
return { query: sqlQuery, parameters };
|
|
219
|
-
}
|
|
220
|
-
buildCustomProjection(selectClauses) {
|
|
221
|
-
const result = {};
|
|
222
|
-
for (const str of selectClauses) {
|
|
223
|
-
const parts = str.split('.');
|
|
224
|
-
let currentObject = result;
|
|
225
|
-
for (let i = 0; i < parts.length; i++) {
|
|
226
|
-
const part = parts[i];
|
|
227
|
-
if (i === parts.length - 1) {
|
|
228
|
-
// If it's the last part, it's a property with the modified value
|
|
229
|
-
currentObject[part] = 'c.' + str;
|
|
230
|
-
}
|
|
231
|
-
else {
|
|
232
|
-
// If it's not the last part, create an object if it doesn't exist
|
|
233
|
-
if (!currentObject[part] || typeof currentObject[part] !== 'object') {
|
|
234
|
-
currentObject[part] = {};
|
|
235
|
-
}
|
|
236
|
-
currentObject = currentObject[part];
|
|
237
|
-
}
|
|
238
|
-
}
|
|
239
|
-
}
|
|
240
|
-
return JSON.stringify(result).replace(/"/g, '');
|
|
241
|
-
}
|
|
242
|
-
getSqlOperator(operator) {
|
|
243
|
-
switch (operator) {
|
|
244
|
-
case QueryConditionOperator.EQUAL:
|
|
245
|
-
return '=';
|
|
246
|
-
case QueryConditionOperator.NOT_EQUAL:
|
|
247
|
-
return '!=';
|
|
248
|
-
case QueryConditionOperator.GREATER_THAN:
|
|
249
|
-
return '>';
|
|
250
|
-
case QueryConditionOperator.LESS_THAN:
|
|
251
|
-
return '<';
|
|
252
|
-
case QueryConditionOperator.GREATER_THAN_OR_EQUAL:
|
|
253
|
-
return '>=';
|
|
254
|
-
case QueryConditionOperator.LESS_THAN_OR_EQUAL:
|
|
255
|
-
return '<=';
|
|
256
|
-
case QueryConditionOperator.IN:
|
|
257
|
-
return 'IN';
|
|
258
|
-
case QueryConditionOperator.NOT_IN:
|
|
259
|
-
return 'NOT IN';
|
|
260
|
-
default:
|
|
261
|
-
throw new Error(`Unsupported operator: ${operator}`);
|
|
262
|
-
}
|
|
263
|
-
}
|
|
264
|
-
fromFilter(filter) {
|
|
265
|
-
const defaultMin = 0;
|
|
266
|
-
const defaultMax = Number.MAX_SAFE_INTEGER;
|
|
267
|
-
const handleFilter = (key, value) => {
|
|
268
|
-
if (Array.isArray(value) && value.length > 0) {
|
|
269
|
-
// check if the array is a RangeFilter
|
|
270
|
-
// check with endsWith to support nested properties
|
|
271
|
-
if (key.endsWith('range')) {
|
|
272
|
-
for (const rangeFilter of value) {
|
|
273
|
-
const min = rangeFilter.min !== undefined ? rangeFilter.min : defaultMin;
|
|
274
|
-
const max = rangeFilter.max !== undefined ? rangeFilter.max : defaultMax;
|
|
275
|
-
// check if the range filter is nested
|
|
276
|
-
// if it is, replace the field with the nested field
|
|
277
|
-
if (key.endsWith('.range')) {
|
|
278
|
-
rangeFilter.field = key.replace('.range', `.${rangeFilter.field}`);
|
|
279
|
-
}
|
|
280
|
-
this.whereRange(rangeFilter.field, min, max);
|
|
281
|
-
}
|
|
282
|
-
}
|
|
283
|
-
else if (key.endsWith('attributes')) {
|
|
284
|
-
let traitLogicalOperator = QueryLogicalOperator.AND;
|
|
285
|
-
if (key === 'attributes') {
|
|
286
|
-
traitLogicalOperator = QueryLogicalOperator.OR;
|
|
287
|
-
}
|
|
288
|
-
const { filterString, parameters } = this.getAttributesQueryAndParams(key, value, traitLogicalOperator);
|
|
289
|
-
this.whereCustom(filterString, QueryLogicalOperator.AND, parameters);
|
|
290
|
-
}
|
|
291
|
-
else if (key === 'activityAddress') {
|
|
292
|
-
// // used for nft activity to filter by from or to
|
|
293
|
-
if (value.length > 1) {
|
|
294
|
-
this.whereCustom(`(ARRAY_CONTAINS(@activityAddress, c.to) OR ARRAY_CONTAINS(@activityAddress, c['from']))`, QueryLogicalOperator.AND, { '@activityAddress': value });
|
|
295
|
-
}
|
|
296
|
-
else {
|
|
297
|
-
this.whereCustom(`(c.to = @activityAddress OR c['from'] = @activityAddress)`, QueryLogicalOperator.AND, { '@activityAddress': value[0] });
|
|
298
|
-
}
|
|
299
|
-
}
|
|
300
|
-
else if (key === 'mintToken') {
|
|
301
|
-
// used for mint profile to filter specific mint tokens
|
|
302
|
-
const { filterString, parameters } = this.getMintProfilePricesQueryAndParams(value);
|
|
303
|
-
this.whereCustom(filterString, QueryLogicalOperator.AND, parameters);
|
|
304
|
-
}
|
|
305
|
-
else {
|
|
306
|
-
this.where(key, value, QueryConditionOperator.IN);
|
|
307
|
-
}
|
|
308
|
-
}
|
|
309
|
-
else if (typeof value === 'boolean' ||
|
|
310
|
-
typeof value === 'string' ||
|
|
311
|
-
typeof value === 'number') {
|
|
312
|
-
// handle special filter cases
|
|
313
|
-
switch (key) {
|
|
314
|
-
// filter for collection offers docs
|
|
315
|
-
case 'withAttributes':
|
|
316
|
-
if (value === true) {
|
|
317
|
-
this.whereCustom('ARRAY_LENGTH(c.attributes) > 0');
|
|
318
|
-
}
|
|
319
|
-
else {
|
|
320
|
-
this.whereCustom('ARRAY_LENGTH(c.attributes) = 0');
|
|
321
|
-
}
|
|
322
|
-
break;
|
|
323
|
-
// filter for nft docs
|
|
324
|
-
case 'activeAuction':
|
|
325
|
-
if (value === true) {
|
|
326
|
-
this.whereCustom(`(c.saleInfo.deadline = 0 OR c.saleInfo.deadline > ${Math.floor(Date.now() / 1000)})`);
|
|
327
|
-
}
|
|
328
|
-
else {
|
|
329
|
-
this.whereCustom(`(c.saleInfo.deadline != 0 AND c.saleInfo.deadline <= ${Math.floor(Date.now() / 1000)})`);
|
|
330
|
-
}
|
|
331
|
-
break;
|
|
332
|
-
// special case to filter out SFTs that are on sale(as duplicates of the original SFTs)
|
|
333
|
-
case 'sftOriginalDoc':
|
|
334
|
-
if (value === true) {
|
|
335
|
-
this.whereCustom(`(c.type = '${enums_1.EsdtTokenType.NonFungibleESDT}' OR (c.cp_staked = false AND c.onSale = false AND (c.type = '${enums_1.EsdtTokenType.SemiFungibleESDT}' OR c.type = '${enums_1.EsdtTokenType.MetaESDT}')))`);
|
|
336
|
-
}
|
|
337
|
-
break;
|
|
338
|
-
// filter for mint profile docs
|
|
339
|
-
case 'activeMint':
|
|
340
|
-
if (value === true) {
|
|
341
|
-
this.whereCustom(`(c.endTime = 0 OR c.endTime > ${Math.floor(Date.now() / 1000)})`);
|
|
342
|
-
}
|
|
343
|
-
else {
|
|
344
|
-
this.whereCustom(`(c.endTime != 0 AND c.endTime <= ${Math.floor(Date.now() / 1000)})`);
|
|
345
|
-
}
|
|
346
|
-
break;
|
|
347
|
-
// special case to filter out markets that have debt ceiling reached
|
|
348
|
-
case 'isDebtCeilingReached':
|
|
349
|
-
if (value === true) {
|
|
350
|
-
this.whereCustom(`(c.debtCeilingShort >= c.maxDebtUsdShort)`);
|
|
351
|
-
}
|
|
352
|
-
else if (value === false) {
|
|
353
|
-
this.whereCustom(`(c.debtCeilingShort < c.maxDebtUsdShort)`);
|
|
354
|
-
}
|
|
355
|
-
break;
|
|
356
|
-
default:
|
|
357
|
-
this.where(key, value, QueryConditionOperator.EQUAL);
|
|
358
|
-
break;
|
|
359
|
-
}
|
|
360
|
-
}
|
|
361
|
-
else if (typeof value === 'object' && value !== null) {
|
|
362
|
-
// Handle nested properties
|
|
363
|
-
for (const [nestedKey, nestedValue] of Object.entries(value)) {
|
|
364
|
-
handleFilter(`${key}.${nestedKey}`, nestedValue);
|
|
365
|
-
}
|
|
366
|
-
}
|
|
367
|
-
};
|
|
368
|
-
for (const [key, value] of Object.entries(filter.filters)) {
|
|
369
|
-
handleFilter(key, value);
|
|
370
|
-
}
|
|
371
|
-
if (filter.includeCount === true) {
|
|
372
|
-
this.count();
|
|
373
|
-
}
|
|
374
|
-
else {
|
|
375
|
-
if (filter.select && filter.select.length > 0) {
|
|
376
|
-
this.selectFields(filter.select);
|
|
377
|
-
}
|
|
378
|
-
if (filter.orderBy && filter.orderBy.length > 0) {
|
|
379
|
-
for (const order of filter.orderBy) {
|
|
380
|
-
const [field, direction] = order.split(' ');
|
|
381
|
-
this.orderBy(field, direction);
|
|
382
|
-
}
|
|
383
|
-
}
|
|
384
|
-
this.setOffset(filter.skip ?? 0);
|
|
385
|
-
this.setLimit(filter.top ?? 25);
|
|
386
|
-
}
|
|
387
|
-
return this;
|
|
388
|
-
}
|
|
389
|
-
getMintProfilePricesQueryAndParams(mintToken) {
|
|
390
|
-
const pricesFilter = [];
|
|
391
|
-
const parameters = {};
|
|
392
|
-
mintToken.forEach((token, index) => {
|
|
393
|
-
pricesFilter.push(`ARRAY_CONTAINS(c.prices, ({'tokenIdentifier': @tokenIdentifier${index}}), true)`);
|
|
394
|
-
parameters[`@tokenIdentifier${index}`] = token;
|
|
395
|
-
});
|
|
396
|
-
const filterString = `(${pricesFilter.join(' OR ')})`;
|
|
397
|
-
return { filterString, parameters };
|
|
398
|
-
}
|
|
399
|
-
getAttributesQueryAndParams(key, attributes, traitLogicalOperator = QueryLogicalOperator.AND) {
|
|
400
|
-
const groupedByTrait = this.groupAttributesByTrait(attributes);
|
|
401
|
-
const attributesFilters = [];
|
|
402
|
-
const parameters = {};
|
|
403
|
-
groupedByTrait.forEach((pair, traitIndex) => {
|
|
404
|
-
const { trait_type, values } = pair;
|
|
405
|
-
const valuesFilter = [];
|
|
406
|
-
values.forEach((value, valueIndex) => {
|
|
407
|
-
valuesFilter.push(`ARRAY_CONTAINS(c.${key}, ({'trait_type': @trait${traitIndex}, 'value': @trait${traitIndex}value${valueIndex}}), true)`);
|
|
408
|
-
parameters[`@trait${traitIndex}`] = trait_type;
|
|
409
|
-
parameters[`@trait${traitIndex}value${valueIndex}`] = value;
|
|
410
|
-
});
|
|
411
|
-
attributesFilters.push(`(${valuesFilter.join(' OR ')})`);
|
|
412
|
-
});
|
|
413
|
-
const filterString = `(${attributesFilters.join(` ${traitLogicalOperator} `)})`;
|
|
414
|
-
return { filterString, parameters };
|
|
415
|
-
}
|
|
416
|
-
groupAttributesByTrait(attributes) {
|
|
417
|
-
return attributes.reduce((accumulator, current) => {
|
|
418
|
-
// Find the index of the object with the same trait_type
|
|
419
|
-
const index = accumulator.findIndex((item) => item.trait_type === current.trait_type);
|
|
420
|
-
if (index >= 0) {
|
|
421
|
-
// If found, append the current value to the values array of the found object
|
|
422
|
-
accumulator[index].values.push(current.value);
|
|
423
|
-
}
|
|
424
|
-
else {
|
|
425
|
-
// If not found, create a new object and add it to the accumulator
|
|
426
|
-
accumulator.push({
|
|
427
|
-
trait_type: current.trait_type,
|
|
428
|
-
values: [current.value],
|
|
429
|
-
});
|
|
430
|
-
}
|
|
431
|
-
return accumulator;
|
|
432
|
-
}, []);
|
|
433
|
-
}
|
|
434
|
-
}
|
|
435
|
-
exports.CosmosDbQueryBuilder = CosmosDbQueryBuilder;
|