@forestadmin-experimental/datasource-cosmos 1.2.1 → 1.3.3
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/array-collection.d.ts +75 -0
- package/dist/array-collection.d.ts.map +1 -0
- package/dist/array-collection.js +510 -0
- package/dist/collection.d.ts +5 -0
- package/dist/collection.d.ts.map +1 -1
- package/dist/collection.js +23 -4
- package/dist/datasource.d.ts.map +1 -1
- package/dist/datasource.js +2 -3
- package/dist/index.d.ts +11 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +185 -14
- package/dist/introspection/container-introspector.d.ts +11 -2
- package/dist/introspection/container-introspector.d.ts.map +1 -1
- package/dist/introspection/container-introspector.js +77 -87
- package/dist/introspection/introspector.d.ts +18 -1
- package/dist/introspection/introspector.d.ts.map +1 -1
- package/dist/introspection/introspector.js +68 -5
- package/dist/model-builder/model.d.ts +1 -0
- package/dist/model-builder/model.d.ts.map +1 -1
- package/dist/model-builder/model.js +16 -11
- package/dist/utils/aggregation-converter.d.ts +1 -1
- package/dist/utils/aggregation-converter.d.ts.map +1 -1
- package/dist/utils/aggregation-converter.js +5 -6
- package/dist/utils/model-to-collection-schema-converter.js +2 -2
- package/dist/utils/query-converter.d.ts.map +1 -1
- package/dist/utils/query-converter.js +9 -3
- package/dist/utils/serializer.d.ts.map +1 -1
- package/dist/utils/serializer.js +6 -8
- package/dist/utils/type-converter.d.ts +11 -3
- package/dist/utils/type-converter.d.ts.map +1 -1
- package/dist/utils/type-converter.js +60 -15
- package/package.json +1 -1
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { CosmosClient } from '@azure/cosmos';
|
|
2
|
+
import { Aggregation, Caller, CollectionSchema, DataSource, Filter, Logger, PaginatedFilter, Projection, RecordData } from '@forestadmin/datasource-toolkit';
|
|
3
|
+
import CosmosCollection from './collection';
|
|
4
|
+
/**
|
|
5
|
+
* ArrayCollection - A virtual collection that exposes array fields from a parent collection
|
|
6
|
+
* as a separate collection with full CRUD support.
|
|
7
|
+
*
|
|
8
|
+
* This allows treating nested arrays (like kycDetails.diligences) as first-class collections
|
|
9
|
+
* while keeping data stored in the parent document.
|
|
10
|
+
*/
|
|
11
|
+
export default class ArrayCollection extends CosmosCollection {
|
|
12
|
+
private parentCollection;
|
|
13
|
+
private arrayFieldPath;
|
|
14
|
+
private parentIdField;
|
|
15
|
+
private virtualizedChildFields;
|
|
16
|
+
constructor(dataSource: DataSource, parentCollection: CosmosCollection, collectionName: string, arrayFieldPath: string, arrayItemSchema: CollectionSchema, logger?: Logger, cosmosClient?: CosmosClient, virtualizedChildFields?: string[]);
|
|
17
|
+
/**
|
|
18
|
+
* Set virtualized child fields (fields that have been converted to virtual collections)
|
|
19
|
+
*/
|
|
20
|
+
setVirtualizedChildFields(fields: string[]): void;
|
|
21
|
+
/**
|
|
22
|
+
* Parse composite ID to get parent ID and array index
|
|
23
|
+
* For nested virtual collections, splits on the LAST ':' to handle multi-level IDs
|
|
24
|
+
* e.g., "uuid:1:2" becomes parentId="uuid:1", index=2
|
|
25
|
+
*/
|
|
26
|
+
private parseCompositeId;
|
|
27
|
+
/**
|
|
28
|
+
* Create composite ID from parent ID and index
|
|
29
|
+
*/
|
|
30
|
+
private createCompositeId;
|
|
31
|
+
/**
|
|
32
|
+
* Get the array field value from a parent record
|
|
33
|
+
*/
|
|
34
|
+
private getArrayFromParent;
|
|
35
|
+
/**
|
|
36
|
+
* Set the array field value in a parent record
|
|
37
|
+
*/
|
|
38
|
+
private setArrayInParent;
|
|
39
|
+
/**
|
|
40
|
+
* List array items from parent collection
|
|
41
|
+
*/
|
|
42
|
+
list(caller: Caller, filter: PaginatedFilter, projection: Projection): Promise<RecordData[]>;
|
|
43
|
+
/**
|
|
44
|
+
* Apply condition tree filtering to items
|
|
45
|
+
*/
|
|
46
|
+
private applyConditionTree;
|
|
47
|
+
/**
|
|
48
|
+
* Check if a record matches a condition
|
|
49
|
+
*/
|
|
50
|
+
private matchesCondition;
|
|
51
|
+
/**
|
|
52
|
+
* Apply sorting to items
|
|
53
|
+
*/
|
|
54
|
+
private applySorting;
|
|
55
|
+
/**
|
|
56
|
+
* Create a new array item
|
|
57
|
+
*/
|
|
58
|
+
create(caller: Caller, data: RecordData[]): Promise<RecordData[]>;
|
|
59
|
+
/**
|
|
60
|
+
* Update array items
|
|
61
|
+
*/
|
|
62
|
+
update(caller: Caller, filter: Filter, patch: RecordData): Promise<void>;
|
|
63
|
+
/**
|
|
64
|
+
* Delete array items
|
|
65
|
+
*/
|
|
66
|
+
delete(caller: Caller, filter: Filter): Promise<void>;
|
|
67
|
+
/**
|
|
68
|
+
* Aggregate - Support Count operations for array collections
|
|
69
|
+
*/
|
|
70
|
+
aggregate(caller: Caller, filter: Filter, aggregation: Aggregation, limit?: number): Promise<Array<{
|
|
71
|
+
value: number;
|
|
72
|
+
group: Record<string, unknown>;
|
|
73
|
+
}>>;
|
|
74
|
+
}
|
|
75
|
+
//# sourceMappingURL=array-collection.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"array-collection.d.ts","sourceRoot":"","sources":["../src/array-collection.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,EACL,WAAW,EACX,MAAM,EACN,gBAAgB,EAIhB,UAAU,EACV,MAAM,EACN,MAAM,EACN,eAAe,EACf,UAAU,EACV,UAAU,EACX,MAAM,iCAAiC,CAAC;AAEzC,OAAO,gBAAgB,MAAM,cAAc,CAAC;AAG5C;;;;;;GAMG;AACH,MAAM,CAAC,OAAO,OAAO,eAAgB,SAAQ,gBAAgB;IAC3D,OAAO,CAAC,gBAAgB,CAAmB;IAC3C,OAAO,CAAC,cAAc,CAAS;IAC/B,OAAO,CAAC,aAAa,CAAS;IAC9B,OAAO,CAAC,sBAAsB,CAAc;gBAG1C,UAAU,EAAE,UAAU,EACtB,gBAAgB,EAAE,gBAAgB,EAClC,cAAc,EAAE,MAAM,EACtB,cAAc,EAAE,MAAM,EACtB,eAAe,EAAE,gBAAgB,EACjC,MAAM,CAAC,EAAE,MAAM,EACf,YAAY,CAAC,EAAE,YAAY,EAC3B,sBAAsB,CAAC,EAAE,MAAM,EAAE;IA6GnC;;OAEG;IACI,yBAAyB,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,IAAI;IAIxD;;;;OAIG;IACH,OAAO,CAAC,gBAAgB;IAaxB;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAIzB;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAwB1B;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAuBxB;;OAEG;IACY,IAAI,CACjB,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,eAAe,EACvB,UAAU,EAAE,UAAU,GACrB,OAAO,CAAC,UAAU,EAAE,CAAC;IA4GxB;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAuC1B;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAuExB;;OAEG;IACH,OAAO,CAAC,YAAY;IAyCpB;;OAEG;IACY,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,EAAE,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC;IAwDhF;;OAEG;IACY,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IA4CvF;;OAEG;IACY,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAqDpE;;OAEG;IACY,SAAS,CACtB,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,WAAW,EACxB,KAAK,CAAC,EAAE,MAAM,GACb,OAAO,CAAC,KAAK,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAAE,CAAC,CAAC;CAsBrE"}
|
|
@@ -0,0 +1,510 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const datasource_toolkit_1 = require("@forestadmin/datasource-toolkit");
|
|
7
|
+
const collection_1 = __importDefault(require("./collection"));
|
|
8
|
+
const model_1 = __importDefault(require("./model-builder/model"));
|
|
9
|
+
/**
|
|
10
|
+
* ArrayCollection - A virtual collection that exposes array fields from a parent collection
|
|
11
|
+
* as a separate collection with full CRUD support.
|
|
12
|
+
*
|
|
13
|
+
* This allows treating nested arrays (like kycDetails.diligences) as first-class collections
|
|
14
|
+
* while keeping data stored in the parent document.
|
|
15
|
+
*/
|
|
16
|
+
class ArrayCollection extends collection_1.default {
|
|
17
|
+
constructor(dataSource, parentCollection, collectionName, arrayFieldPath, arrayItemSchema, logger, cosmosClient, virtualizedChildFields) {
|
|
18
|
+
// Get the parent model to extract Cosmos client info
|
|
19
|
+
const parentModel = parentCollection
|
|
20
|
+
.internalModel;
|
|
21
|
+
logger?.('Debug', `ArrayCollection constructor: parentCollection=${parentCollection?.name}, hasInternalModel=${!!parentModel}`);
|
|
22
|
+
if (!parentModel) {
|
|
23
|
+
throw new Error(`Parent collection model is required. ParentCollection name: ${parentCollection?.name}`);
|
|
24
|
+
}
|
|
25
|
+
// Use provided cosmosClient or get it from parent model
|
|
26
|
+
const clientToUse = cosmosClient || parentModel.getCosmosClient();
|
|
27
|
+
logger?.('Debug', `ArrayCollection: clientToUse=${!!clientToUse}`);
|
|
28
|
+
if (!clientToUse) {
|
|
29
|
+
throw new Error('CosmosClient is required to create ArrayCollection');
|
|
30
|
+
}
|
|
31
|
+
const dbName = parentModel.getDatabaseName();
|
|
32
|
+
const containerName = parentModel.getContainerName();
|
|
33
|
+
const partitionKeyPath = parentModel.getPartitionKeyPath();
|
|
34
|
+
logger?.('Debug', `ArrayCollection: dbName=${dbName}, containerName=${containerName}, ` +
|
|
35
|
+
`partitionKeyPath=${partitionKeyPath}`);
|
|
36
|
+
// Create a minimal model for the array collection
|
|
37
|
+
// This model won't be used for queries since we override all methods
|
|
38
|
+
const dummyModel = new model_1.default(clientToUse, collectionName, dbName, containerName, // Use same container as parent
|
|
39
|
+
partitionKeyPath, {});
|
|
40
|
+
logger?.('Debug', `ArrayCollection: dummyModel created, name=${dummyModel?.name}, isDefined=${!!dummyModel}`);
|
|
41
|
+
super(dataSource, dummyModel, logger, clientToUse);
|
|
42
|
+
this.parentCollection = parentCollection;
|
|
43
|
+
this.arrayFieldPath = arrayFieldPath;
|
|
44
|
+
this.parentIdField = `${parentCollection.name}Id`;
|
|
45
|
+
this.virtualizedChildFields = new Set(virtualizedChildFields || []);
|
|
46
|
+
// Override the collection name
|
|
47
|
+
Object.defineProperty(this, 'name', {
|
|
48
|
+
value: collectionName,
|
|
49
|
+
writable: false,
|
|
50
|
+
});
|
|
51
|
+
// Build schema with composite ID and parent reference
|
|
52
|
+
const newSchema = {
|
|
53
|
+
...arrayItemSchema,
|
|
54
|
+
fields: {
|
|
55
|
+
id: {
|
|
56
|
+
columnType: 'String',
|
|
57
|
+
filterOperators: new Set(['Equal', 'NotEqual', 'In', 'NotIn', 'Present', 'Missing']),
|
|
58
|
+
isPrimaryKey: true,
|
|
59
|
+
isReadOnly: true,
|
|
60
|
+
isSortable: false,
|
|
61
|
+
type: 'Column',
|
|
62
|
+
},
|
|
63
|
+
[this.parentIdField]: {
|
|
64
|
+
columnType: 'String',
|
|
65
|
+
filterOperators: new Set([
|
|
66
|
+
'Equal',
|
|
67
|
+
'NotEqual',
|
|
68
|
+
'In',
|
|
69
|
+
'NotIn',
|
|
70
|
+
'Present',
|
|
71
|
+
'Missing',
|
|
72
|
+
'Like',
|
|
73
|
+
'ILike',
|
|
74
|
+
'Contains',
|
|
75
|
+
'NotContains',
|
|
76
|
+
]),
|
|
77
|
+
isReadOnly: false,
|
|
78
|
+
isSortable: true,
|
|
79
|
+
type: 'Column',
|
|
80
|
+
},
|
|
81
|
+
...arrayItemSchema.fields,
|
|
82
|
+
},
|
|
83
|
+
};
|
|
84
|
+
// Override the read-only schema property
|
|
85
|
+
Object.defineProperty(this, 'schema', {
|
|
86
|
+
value: newSchema,
|
|
87
|
+
writable: false,
|
|
88
|
+
configurable: true,
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Set virtualized child fields (fields that have been converted to virtual collections)
|
|
93
|
+
*/
|
|
94
|
+
setVirtualizedChildFields(fields) {
|
|
95
|
+
this.virtualizedChildFields = new Set(fields);
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Parse composite ID to get parent ID and array index
|
|
99
|
+
* For nested virtual collections, splits on the LAST ':' to handle multi-level IDs
|
|
100
|
+
* e.g., "uuid:1:2" becomes parentId="uuid:1", index=2
|
|
101
|
+
*/
|
|
102
|
+
parseCompositeId(compositeId) {
|
|
103
|
+
const lastColonIndex = compositeId.lastIndexOf(':');
|
|
104
|
+
if (lastColonIndex === -1) {
|
|
105
|
+
throw new Error(`Invalid composite ID format: ${compositeId}`);
|
|
106
|
+
}
|
|
107
|
+
const parentId = compositeId.substring(0, lastColonIndex);
|
|
108
|
+
const indexStr = compositeId.substring(lastColonIndex + 1);
|
|
109
|
+
return { parentId, index: parseInt(indexStr, 10) };
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Create composite ID from parent ID and index
|
|
113
|
+
*/
|
|
114
|
+
createCompositeId(parentId, index) {
|
|
115
|
+
return `${parentId}:${index}`;
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Get the array field value from a parent record
|
|
119
|
+
*/
|
|
120
|
+
getArrayFromParent(parentRecord) {
|
|
121
|
+
// First try the flattened field name (e.g., "kycDetails->diligences")
|
|
122
|
+
// This is how the datasource returns projected fields
|
|
123
|
+
if (parentRecord[this.arrayFieldPath] !== undefined) {
|
|
124
|
+
const value = parentRecord[this.arrayFieldPath];
|
|
125
|
+
return Array.isArray(value) ? value : [];
|
|
126
|
+
}
|
|
127
|
+
// Fall back to nested navigation for cases where data is nested
|
|
128
|
+
const parts = this.arrayFieldPath.split('->');
|
|
129
|
+
let value = parentRecord;
|
|
130
|
+
for (const part of parts) {
|
|
131
|
+
if (value && typeof value === 'object') {
|
|
132
|
+
value = value[part];
|
|
133
|
+
}
|
|
134
|
+
else {
|
|
135
|
+
return [];
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
return Array.isArray(value) ? value : [];
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Set the array field value in a parent record
|
|
142
|
+
*/
|
|
143
|
+
setArrayInParent(parentRecord, newArray) {
|
|
144
|
+
const parts = this.arrayFieldPath.split('->');
|
|
145
|
+
const result = { ...parentRecord };
|
|
146
|
+
let current = result;
|
|
147
|
+
// Navigate to the parent object containing the array
|
|
148
|
+
for (let i = 0; i < parts.length - 1; i += 1) {
|
|
149
|
+
const part = parts[i];
|
|
150
|
+
if (!current[part]) {
|
|
151
|
+
current[part] = {};
|
|
152
|
+
}
|
|
153
|
+
current[part] = { ...current[part] };
|
|
154
|
+
current = current[part];
|
|
155
|
+
}
|
|
156
|
+
// Set the array
|
|
157
|
+
current[parts[parts.length - 1]] = newArray;
|
|
158
|
+
return result;
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* List array items from parent collection
|
|
162
|
+
*/
|
|
163
|
+
async list(caller, filter, projection) {
|
|
164
|
+
// Extract filters
|
|
165
|
+
const conditionTree = filter?.conditionTree;
|
|
166
|
+
let parentFilter;
|
|
167
|
+
let filterByCompositeId;
|
|
168
|
+
if (conditionTree instanceof datasource_toolkit_1.ConditionTreeLeaf) {
|
|
169
|
+
if (conditionTree.field === this.parentIdField) {
|
|
170
|
+
// Filter by parent ID
|
|
171
|
+
parentFilter = new datasource_toolkit_1.PaginatedFilter({
|
|
172
|
+
conditionTree: new datasource_toolkit_1.ConditionTreeLeaf('id', conditionTree.operator, conditionTree.value),
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
else if (conditionTree.field === 'id') {
|
|
176
|
+
// Filter by composite ID (e.g., "parent-id:0")
|
|
177
|
+
// Extract the composite IDs to filter
|
|
178
|
+
if (conditionTree.operator === 'Equal') {
|
|
179
|
+
filterByCompositeId = [conditionTree.value];
|
|
180
|
+
}
|
|
181
|
+
else if (conditionTree.operator === 'In') {
|
|
182
|
+
filterByCompositeId = conditionTree.value;
|
|
183
|
+
}
|
|
184
|
+
// Optimize by only fetching the parent IDs we need
|
|
185
|
+
if (filterByCompositeId) {
|
|
186
|
+
const parentIds = filterByCompositeId.map(cid => this.parseCompositeId(cid).parentId);
|
|
187
|
+
const uniqueParentIds = Array.from(new Set(parentIds));
|
|
188
|
+
if (uniqueParentIds.length === 1) {
|
|
189
|
+
parentFilter = new datasource_toolkit_1.PaginatedFilter({
|
|
190
|
+
conditionTree: new datasource_toolkit_1.ConditionTreeLeaf('id', 'Equal', uniqueParentIds[0]),
|
|
191
|
+
});
|
|
192
|
+
}
|
|
193
|
+
else if (uniqueParentIds.length > 1) {
|
|
194
|
+
parentFilter = new datasource_toolkit_1.PaginatedFilter({
|
|
195
|
+
conditionTree: new datasource_toolkit_1.ConditionTreeLeaf('id', 'In', uniqueParentIds),
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
// Fetch parent records with the array field
|
|
202
|
+
const parentRecords = await this.parentCollection.list(caller, parentFilter || new datasource_toolkit_1.PaginatedFilter({}), new datasource_toolkit_1.Projection('id', this.arrayFieldPath));
|
|
203
|
+
// Flatten array items from all parents
|
|
204
|
+
const arrayItems = [];
|
|
205
|
+
for (const parentRecord of parentRecords) {
|
|
206
|
+
const parentId = parentRecord.id;
|
|
207
|
+
const arrayValues = this.getArrayFromParent(parentRecord);
|
|
208
|
+
arrayValues.forEach((item, index) => {
|
|
209
|
+
// Filter out virtualized child fields (if any are configured)
|
|
210
|
+
// UNLESS they are explicitly requested in the projection
|
|
211
|
+
const filteredItem = { ...item };
|
|
212
|
+
if (this.virtualizedChildFields && this.virtualizedChildFields.size > 0) {
|
|
213
|
+
// Get list of requested fields from projection
|
|
214
|
+
// Projection is array-like, convert to array for checking
|
|
215
|
+
const projectionFields = projection ? Array.from(projection) : [];
|
|
216
|
+
const hasProjection = projectionFields.length > 0;
|
|
217
|
+
for (const field of this.virtualizedChildFields) {
|
|
218
|
+
// Only filter out if:
|
|
219
|
+
// 1. There IS a projection (not requesting all fields), AND
|
|
220
|
+
// 2. The virtualized field is NOT in the projection
|
|
221
|
+
const shouldFilter = hasProjection && !projectionFields.includes(field);
|
|
222
|
+
if (shouldFilter) {
|
|
223
|
+
delete filteredItem[field];
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
arrayItems.push({
|
|
228
|
+
id: this.createCompositeId(parentId, index),
|
|
229
|
+
[this.parentIdField]: parentId,
|
|
230
|
+
...filteredItem,
|
|
231
|
+
});
|
|
232
|
+
});
|
|
233
|
+
}
|
|
234
|
+
// Apply composite ID filter if present
|
|
235
|
+
let filteredItems = arrayItems;
|
|
236
|
+
if (filterByCompositeId) {
|
|
237
|
+
const idSet = new Set(filterByCompositeId);
|
|
238
|
+
filteredItems = arrayItems.filter(item => idSet.has(item.id));
|
|
239
|
+
}
|
|
240
|
+
else if (conditionTree) {
|
|
241
|
+
// Apply general field filtering (for non-ID fields)
|
|
242
|
+
filteredItems = this.applyConditionTree(arrayItems, conditionTree);
|
|
243
|
+
}
|
|
244
|
+
// Apply sorting
|
|
245
|
+
if (filter?.sort && filter.sort.length > 0) {
|
|
246
|
+
filteredItems = this.applySorting(filteredItems, filter.sort);
|
|
247
|
+
}
|
|
248
|
+
// Apply pagination
|
|
249
|
+
const { limit, skip } = filter?.page || { limit: undefined, skip: undefined };
|
|
250
|
+
const start = skip || 0;
|
|
251
|
+
const end = limit ? start + limit : undefined;
|
|
252
|
+
return filteredItems.slice(start, end);
|
|
253
|
+
}
|
|
254
|
+
/**
|
|
255
|
+
* Apply condition tree filtering to items
|
|
256
|
+
*/
|
|
257
|
+
applyConditionTree(items, conditionTree) {
|
|
258
|
+
if (!conditionTree)
|
|
259
|
+
return items;
|
|
260
|
+
// Handle ConditionTreeLeaf (single condition)
|
|
261
|
+
if (conditionTree instanceof datasource_toolkit_1.ConditionTreeLeaf) {
|
|
262
|
+
const { field, operator, value } = conditionTree;
|
|
263
|
+
// Skip ID and parentId filters as they're handled separately
|
|
264
|
+
if (field === 'id' || field === this.parentIdField) {
|
|
265
|
+
return items;
|
|
266
|
+
}
|
|
267
|
+
return items.filter(item => this.matchesCondition(item, field, operator, value));
|
|
268
|
+
}
|
|
269
|
+
// Handle ConditionTreeBranch (AND/OR logic)
|
|
270
|
+
if ('aggregator' in conditionTree && conditionTree.aggregator) {
|
|
271
|
+
const branch = conditionTree;
|
|
272
|
+
const { aggregator, conditions } = branch;
|
|
273
|
+
if (aggregator === 'And') {
|
|
274
|
+
return items.filter(item => conditions.every(cond => this.applyConditionTree([item], cond).length > 0));
|
|
275
|
+
}
|
|
276
|
+
if (aggregator === 'Or') {
|
|
277
|
+
return items.filter(item => conditions.some(cond => this.applyConditionTree([item], cond).length > 0));
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
return items;
|
|
281
|
+
}
|
|
282
|
+
/**
|
|
283
|
+
* Check if a record matches a condition
|
|
284
|
+
*/
|
|
285
|
+
matchesCondition(record, field, operator, value) {
|
|
286
|
+
const fieldValue = record[field];
|
|
287
|
+
switch (operator) {
|
|
288
|
+
case 'Equal':
|
|
289
|
+
return fieldValue === value;
|
|
290
|
+
case 'NotEqual':
|
|
291
|
+
return fieldValue !== value;
|
|
292
|
+
case 'In':
|
|
293
|
+
return Array.isArray(value) && value.includes(fieldValue);
|
|
294
|
+
case 'NotIn':
|
|
295
|
+
return Array.isArray(value) && !value.includes(fieldValue);
|
|
296
|
+
case 'Present':
|
|
297
|
+
return fieldValue !== null && fieldValue !== undefined;
|
|
298
|
+
case 'Missing':
|
|
299
|
+
return fieldValue === null || fieldValue === undefined;
|
|
300
|
+
case 'LessThan':
|
|
301
|
+
return fieldValue < value;
|
|
302
|
+
case 'LessThanOrEqual':
|
|
303
|
+
return fieldValue <= value;
|
|
304
|
+
case 'GreaterThan':
|
|
305
|
+
return fieldValue > value;
|
|
306
|
+
case 'GreaterThanOrEqual':
|
|
307
|
+
return fieldValue >= value;
|
|
308
|
+
case 'Contains':
|
|
309
|
+
return (typeof fieldValue === 'string' && typeof value === 'string' && fieldValue.includes(value));
|
|
310
|
+
case 'NotContains':
|
|
311
|
+
return (typeof fieldValue === 'string' && typeof value === 'string' && !fieldValue.includes(value));
|
|
312
|
+
case 'StartsWith':
|
|
313
|
+
return (typeof fieldValue === 'string' &&
|
|
314
|
+
typeof value === 'string' &&
|
|
315
|
+
fieldValue.startsWith(value));
|
|
316
|
+
case 'EndsWith':
|
|
317
|
+
return (typeof fieldValue === 'string' && typeof value === 'string' && fieldValue.endsWith(value));
|
|
318
|
+
case 'IContains':
|
|
319
|
+
return (typeof fieldValue === 'string' &&
|
|
320
|
+
typeof value === 'string' &&
|
|
321
|
+
fieldValue.toLowerCase().includes(value.toLowerCase()));
|
|
322
|
+
case 'Like':
|
|
323
|
+
case 'ILike':
|
|
324
|
+
// Simple wildcard matching (% for any characters, _ for single character)
|
|
325
|
+
if (typeof fieldValue === 'string' && typeof value === 'string') {
|
|
326
|
+
const pattern = value.replace(/%/g, '.*').replace(/_/g, '.');
|
|
327
|
+
const regex = new RegExp(`^${pattern}$`, operator === 'ILike' ? 'i' : '');
|
|
328
|
+
return regex.test(fieldValue);
|
|
329
|
+
}
|
|
330
|
+
return false;
|
|
331
|
+
default:
|
|
332
|
+
console.warn(`[ArrayCollection] Unsupported operator: ${operator}`);
|
|
333
|
+
return true; // Don't filter out if we don't know the operator
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
/**
|
|
337
|
+
* Apply sorting to items
|
|
338
|
+
*/
|
|
339
|
+
applySorting(items, sort) {
|
|
340
|
+
return [...items].sort((a, b) => {
|
|
341
|
+
for (const { field, ascending } of sort) {
|
|
342
|
+
const aValue = a[field];
|
|
343
|
+
const bValue = b[field];
|
|
344
|
+
// Handle null/undefined - skip to next sort criteria if both are null
|
|
345
|
+
if (aValue == null && bValue == null) {
|
|
346
|
+
// Both null, continue to next sort field
|
|
347
|
+
}
|
|
348
|
+
else if (aValue == null) {
|
|
349
|
+
return ascending ? 1 : -1;
|
|
350
|
+
}
|
|
351
|
+
else if (bValue == null) {
|
|
352
|
+
return ascending ? -1 : 1;
|
|
353
|
+
}
|
|
354
|
+
else {
|
|
355
|
+
// Compare values
|
|
356
|
+
let comparison = 0;
|
|
357
|
+
if (typeof aValue === 'string' && typeof bValue === 'string') {
|
|
358
|
+
comparison = aValue.localeCompare(bValue);
|
|
359
|
+
}
|
|
360
|
+
else if (typeof aValue === 'number' && typeof bValue === 'number') {
|
|
361
|
+
comparison = aValue - bValue;
|
|
362
|
+
}
|
|
363
|
+
else if (aValue instanceof Date && bValue instanceof Date) {
|
|
364
|
+
comparison = aValue.getTime() - bValue.getTime();
|
|
365
|
+
}
|
|
366
|
+
else {
|
|
367
|
+
// Fallback: convert to string and compare
|
|
368
|
+
comparison = String(aValue).localeCompare(String(bValue));
|
|
369
|
+
}
|
|
370
|
+
if (comparison !== 0) {
|
|
371
|
+
return ascending ? comparison : -comparison;
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
return 0;
|
|
376
|
+
});
|
|
377
|
+
}
|
|
378
|
+
/**
|
|
379
|
+
* Create a new array item
|
|
380
|
+
*/
|
|
381
|
+
async create(caller, data) {
|
|
382
|
+
const results = [];
|
|
383
|
+
// Sequential execution required: each array item must be added one at a time to maintain
|
|
384
|
+
// consistent ordering and prevent race conditions when multiple items target the same parent
|
|
385
|
+
for (const item of data) {
|
|
386
|
+
const parentId = item[this.parentIdField];
|
|
387
|
+
if (!parentId) {
|
|
388
|
+
throw new Error(`${this.parentIdField} is required to create array items`);
|
|
389
|
+
}
|
|
390
|
+
// Remove parent ID and composite ID from the item data using destructuring
|
|
391
|
+
const { id: unusedItemId, [this.parentIdField]: unusedParentIdValue, ...itemData } = item;
|
|
392
|
+
void unusedItemId;
|
|
393
|
+
void unusedParentIdValue;
|
|
394
|
+
// Fetch the parent record
|
|
395
|
+
// eslint-disable-next-line no-await-in-loop -- Sequential maintains consistent ordering
|
|
396
|
+
const parentRecords = await this.parentCollection.list(caller, new datasource_toolkit_1.PaginatedFilter({
|
|
397
|
+
conditionTree: new datasource_toolkit_1.ConditionTreeLeaf('id', 'Equal', parentId),
|
|
398
|
+
}), new datasource_toolkit_1.Projection('id', this.arrayFieldPath));
|
|
399
|
+
if (parentRecords.length === 0) {
|
|
400
|
+
throw new Error(`Parent record with id ${parentId} not found`);
|
|
401
|
+
}
|
|
402
|
+
const parentRecord = parentRecords[0];
|
|
403
|
+
const currentArray = this.getArrayFromParent(parentRecord);
|
|
404
|
+
// Add the new item to the array
|
|
405
|
+
const newArray = [...currentArray, itemData];
|
|
406
|
+
const newIndex = currentArray.length;
|
|
407
|
+
// Update the parent record - sequential to prevent conflicts
|
|
408
|
+
// eslint-disable-next-line no-await-in-loop -- Sequential prevents data conflicts
|
|
409
|
+
await this.parentCollection.update(caller, new datasource_toolkit_1.Filter({ conditionTree: new datasource_toolkit_1.ConditionTreeLeaf('id', 'Equal', parentId) }), { [this.arrayFieldPath]: newArray });
|
|
410
|
+
results.push({
|
|
411
|
+
id: this.createCompositeId(parentId, newIndex),
|
|
412
|
+
[this.parentIdField]: parentId,
|
|
413
|
+
...itemData,
|
|
414
|
+
});
|
|
415
|
+
}
|
|
416
|
+
return results;
|
|
417
|
+
}
|
|
418
|
+
/**
|
|
419
|
+
* Update array items
|
|
420
|
+
*/
|
|
421
|
+
async update(caller, filter, patch) {
|
|
422
|
+
// List all records matching the filter
|
|
423
|
+
const records = await this.list(caller, new datasource_toolkit_1.PaginatedFilter(filter), new datasource_toolkit_1.Projection('id'));
|
|
424
|
+
// Sequential execution required: updating array items must be done one at a time
|
|
425
|
+
// to prevent conflicts when multiple updates target the same parent document
|
|
426
|
+
for (const record of records) {
|
|
427
|
+
const { parentId, index } = this.parseCompositeId(record.id);
|
|
428
|
+
// Fetch the parent record
|
|
429
|
+
// eslint-disable-next-line no-await-in-loop -- Sequential prevents data conflicts
|
|
430
|
+
const parentRecords = await this.parentCollection.list(caller, new datasource_toolkit_1.PaginatedFilter({
|
|
431
|
+
conditionTree: new datasource_toolkit_1.ConditionTreeLeaf('id', 'Equal', parentId),
|
|
432
|
+
}), new datasource_toolkit_1.Projection('id', this.arrayFieldPath));
|
|
433
|
+
// Skip if parent not found or item doesn't exist
|
|
434
|
+
if (parentRecords.length > 0) {
|
|
435
|
+
const parentRecord = parentRecords[0];
|
|
436
|
+
const array = this.getArrayFromParent(parentRecord);
|
|
437
|
+
if (array[index]) {
|
|
438
|
+
// Update the item at the specified index
|
|
439
|
+
const currentItem = typeof array[index] === 'object' && array[index] !== null
|
|
440
|
+
? array[index]
|
|
441
|
+
: {};
|
|
442
|
+
array[index] = { ...currentItem, ...patch };
|
|
443
|
+
// Update the parent record - sequential to prevent conflicts
|
|
444
|
+
// eslint-disable-next-line no-await-in-loop -- Sequential prevents data conflicts
|
|
445
|
+
await this.parentCollection.update(caller, new datasource_toolkit_1.Filter({ conditionTree: new datasource_toolkit_1.ConditionTreeLeaf('id', 'Equal', parentId) }), { [this.arrayFieldPath]: array });
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
}
|
|
450
|
+
/**
|
|
451
|
+
* Delete array items
|
|
452
|
+
*/
|
|
453
|
+
async delete(caller, filter) {
|
|
454
|
+
// List all records matching the filter
|
|
455
|
+
const records = await this.list(caller, new datasource_toolkit_1.PaginatedFilter(filter), new datasource_toolkit_1.Projection('id'));
|
|
456
|
+
// Group by parent ID to minimize updates
|
|
457
|
+
const recordsByParent = new Map();
|
|
458
|
+
for (const record of records) {
|
|
459
|
+
const { parentId, index } = this.parseCompositeId(record.id);
|
|
460
|
+
if (!recordsByParent.has(parentId)) {
|
|
461
|
+
recordsByParent.set(parentId, []);
|
|
462
|
+
}
|
|
463
|
+
recordsByParent.get(parentId)?.push(index);
|
|
464
|
+
}
|
|
465
|
+
// Sequential execution required: deleting array items must be done one parent at a time
|
|
466
|
+
// to prevent conflicts and ensure data consistency
|
|
467
|
+
for (const [parentId, indices] of recordsByParent) {
|
|
468
|
+
// Fetch the parent record
|
|
469
|
+
// eslint-disable-next-line no-await-in-loop -- Sequential prevents data conflicts
|
|
470
|
+
const parentRecords = await this.parentCollection.list(caller, new datasource_toolkit_1.PaginatedFilter({
|
|
471
|
+
conditionTree: new datasource_toolkit_1.ConditionTreeLeaf('id', 'Equal', parentId),
|
|
472
|
+
}), new datasource_toolkit_1.Projection('id', this.arrayFieldPath));
|
|
473
|
+
// Skip if parent not found
|
|
474
|
+
if (parentRecords.length > 0) {
|
|
475
|
+
const parentRecord = parentRecords[0];
|
|
476
|
+
const array = this.getArrayFromParent(parentRecord);
|
|
477
|
+
// Remove items at the specified indices (sort in reverse to avoid index shifting)
|
|
478
|
+
const sortedIndices = indices.sort((a, b) => b - a);
|
|
479
|
+
for (const index of sortedIndices) {
|
|
480
|
+
array.splice(index, 1);
|
|
481
|
+
}
|
|
482
|
+
// Update the parent record - sequential to prevent conflicts
|
|
483
|
+
// eslint-disable-next-line no-await-in-loop -- Sequential prevents data conflicts
|
|
484
|
+
await this.parentCollection.update(caller, new datasource_toolkit_1.Filter({ conditionTree: new datasource_toolkit_1.ConditionTreeLeaf('id', 'Equal', parentId) }), { [this.arrayFieldPath]: array });
|
|
485
|
+
}
|
|
486
|
+
}
|
|
487
|
+
}
|
|
488
|
+
/**
|
|
489
|
+
* Aggregate - Support Count operations for array collections
|
|
490
|
+
*/
|
|
491
|
+
async aggregate(caller, filter, aggregation, limit) {
|
|
492
|
+
void limit; // Unused parameter required by interface
|
|
493
|
+
// Only support Count operation
|
|
494
|
+
if (aggregation.operation !== 'Count') {
|
|
495
|
+
throw new Error(`Aggregation operation '${aggregation.operation}' is not supported for ` +
|
|
496
|
+
`array collections. Only Count is supported.`);
|
|
497
|
+
}
|
|
498
|
+
// Get all records that match the filter
|
|
499
|
+
const records = await this.list(caller, new datasource_toolkit_1.PaginatedFilter(filter), new datasource_toolkit_1.Projection('id'));
|
|
500
|
+
// Return count aggregation result
|
|
501
|
+
return [
|
|
502
|
+
{
|
|
503
|
+
value: records.length,
|
|
504
|
+
group: {},
|
|
505
|
+
},
|
|
506
|
+
];
|
|
507
|
+
}
|
|
508
|
+
}
|
|
509
|
+
exports.default = ArrayCollection;
|
|
510
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXJyYXktY29sbGVjdGlvbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9hcnJheS1jb2xsZWN0aW9uLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBQ0Esd0VBYXlDO0FBRXpDLDhEQUE0QztBQUM1QyxrRUFBZ0Q7QUFFaEQ7Ozs7OztHQU1HO0FBQ0gsTUFBcUIsZUFBZ0IsU0FBUSxvQkFBZ0I7SUFNM0QsWUFDRSxVQUFzQixFQUN0QixnQkFBa0MsRUFDbEMsY0FBc0IsRUFDdEIsY0FBc0IsRUFDdEIsZUFBaUMsRUFDakMsTUFBZSxFQUNmLFlBQTJCLEVBQzNCLHNCQUFpQztRQUVqQyxxREFBcUQ7UUFDckQsTUFBTSxXQUFXLEdBQUksZ0JBQThEO2FBQ2hGLGFBQWEsQ0FBQztRQUVqQixNQUFNLEVBQUUsQ0FDTixPQUFPLEVBQ1AsaURBQ0UsZ0JBQWdCLEVBQUUsSUFDcEIsc0JBQXNCLENBQUMsQ0FBQyxXQUFXLEVBQUUsQ0FDdEMsQ0FBQztRQUVGLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQztZQUNqQixNQUFNLElBQUksS0FBSyxDQUNiLCtEQUErRCxnQkFBZ0IsRUFBRSxJQUFJLEVBQUUsQ0FDeEYsQ0FBQztRQUNKLENBQUM7UUFFRCx3REFBd0Q7UUFDeEQsTUFBTSxXQUFXLEdBQUcsWUFBWSxJQUFJLFdBQVcsQ0FBQyxlQUFlLEVBQUUsQ0FBQztRQUVsRSxNQUFNLEVBQUUsQ0FBQyxPQUFPLEVBQUUsZ0NBQWdDLENBQUMsQ0FBQyxXQUFXLEVBQUUsQ0FBQyxDQUFDO1FBRW5FLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQztZQUNqQixNQUFNLElBQUksS0FBSyxDQUFDLG9EQUFvRCxDQUFDLENBQUM7UUFDeEUsQ0FBQztRQUVELE1BQU0sTUFBTSxHQUFHLFdBQVcsQ0FBQyxlQUFlLEVBQUUsQ0FBQztRQUM3QyxNQUFNLGFBQWEsR0FBRyxXQUFXLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQztRQUNyRCxNQUFNLGdCQUFnQixH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
|
package/dist/collection.d.ts
CHANGED
|
@@ -5,6 +5,11 @@ export default class CosmosCollection extends BaseCollection {
|
|
|
5
5
|
protected internalModel: ModelCosmos;
|
|
6
6
|
private queryConverter;
|
|
7
7
|
constructor(datasource: DataSource, model: ModelCosmos, logger: Logger, nativeDriver: CosmosClient);
|
|
8
|
+
/**
|
|
9
|
+
* Mark virtualized array fields as non-sortable
|
|
10
|
+
* This should be called after virtual collections are created from array fields
|
|
11
|
+
*/
|
|
12
|
+
markVirtualizedFieldsAsNonSortable(virtualizedFieldPaths: string[]): void;
|
|
8
13
|
create(caller: Caller, data: RecordData[]): Promise<RecordData[]>;
|
|
9
14
|
list(caller: Caller, filter: PaginatedFilter, projection: Projection): Promise<RecordData[]>;
|
|
10
15
|
update(caller: Caller, filter: Filter, patch: RecordData): Promise<void>;
|
package/dist/collection.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"collection.d.ts","sourceRoot":"","sources":["../src/collection.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"collection.d.ts","sourceRoot":"","sources":["../src/collection.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,EACL,eAAe,EACf,WAAW,EACX,cAAc,EACd,MAAM,EACN,UAAU,EACV,MAAM,EACN,MAAM,EACN,eAAe,EACf,UAAU,EACV,UAAU,EACX,MAAM,iCAAiC,CAAC;AAEzC,OAAO,WAAW,MAAM,uBAAuB,CAAC;AAKhD,MAAM,CAAC,OAAO,OAAO,gBAAiB,SAAQ,cAAc;IAC1D,SAAS,CAAC,aAAa,EAAE,WAAW,CAAC;IAErC,OAAO,CAAC,cAAc,CAAiB;gBAGrC,UAAU,EAAE,UAAU,EACtB,KAAK,EAAE,WAAW,EAClB,MAAM,EAAE,MAAM,EACd,YAAY,EAAE,YAAY;IAmB5B;;;OAGG;IACI,kCAAkC,CAAC,qBAAqB,EAAE,MAAM,EAAE,GAAG,IAAI;IAgB1E,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,EAAE,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC;IAUjE,IAAI,CACR,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,eAAe,EACvB,UAAU,EAAE,UAAU,GACrB,OAAO,CAAC,UAAU,EAAE,CAAC;IA8DlB,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IAgBxE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAgBrD,SAAS,CACb,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,WAAW,EACxB,KAAK,CAAC,EAAE,MAAM,GACb,OAAO,CAAC,eAAe,EAAE,CAAC;CAkB9B"}
|