@onchaindb/sdk 0.4.0 → 0.4.2
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/.DS_Store +0 -0
- package/.claude/settings.local.json +8 -0
- package/.gitignore +5 -0
- package/.idea/.gitignore +5 -0
- package/.idea/compiler.xml +6 -0
- package/.idea/inspectionProfiles/Project_Default.xml +6 -0
- package/.idea/jsLinters/eslint.xml +6 -0
- package/.idea/modules.xml +8 -0
- package/.idea/prettier.xml +7 -0
- package/.idea/sdk.iml +12 -0
- package/.idea/vcs.xml +6 -0
- package/.idea/workspace.xml +257 -0
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +11 -3
- package/dist/client.js.map +1 -1
- package/dist/database.d.ts +0 -20
- package/dist/database.d.ts.map +1 -1
- package/dist/database.js +0 -40
- package/dist/database.js.map +1 -1
- package/dist/query-sdk/tests/setup.d.ts +16 -0
- package/dist/query-sdk/tests/setup.d.ts.map +1 -0
- package/dist/query-sdk/tests/setup.js +49 -0
- package/dist/query-sdk/tests/setup.js.map +1 -0
- package/examples/basic-usage.ts +136 -0
- package/examples/blob-upload-example.ts +140 -0
- package/examples/collection-schema-example.ts +304 -0
- package/examples/server-side-joins.ts +201 -0
- package/examples/tweet-self-joins-example.ts +352 -0
- package/package-lock.json +3823 -0
- package/package.json +1 -1
- package/skills.md +1096 -0
- package/src/.env +1 -0
- package/src/batch.d.ts +121 -0
- package/src/batch.js +205 -0
- package/src/batch.ts +257 -0
- package/src/client.ts +1856 -0
- package/src/database.d.ts +268 -0
- package/src/database.js +294 -0
- package/src/database.ts +695 -0
- package/src/index.d.ts +160 -0
- package/src/index.js +186 -0
- package/src/index.ts +253 -0
- package/src/query-sdk/ConditionBuilder.ts +103 -0
- package/src/query-sdk/FieldConditionBuilder.ts +2 -0
- package/src/query-sdk/NestedBuilders.ts +186 -0
- package/src/query-sdk/OnChainDB.ts +294 -0
- package/src/query-sdk/QueryBuilder.ts +1191 -0
- package/src/query-sdk/QueryResult.ts +375 -0
- package/src/query-sdk/README.md +866 -0
- package/src/query-sdk/SelectionBuilder.ts +94 -0
- package/src/query-sdk/adapters/HttpClientAdapter.ts +249 -0
- package/src/query-sdk/dist/ConditionBuilder.d.ts +22 -0
- package/src/query-sdk/dist/ConditionBuilder.js +90 -0
- package/src/query-sdk/dist/FieldConditionBuilder.d.ts +1 -0
- package/src/query-sdk/dist/FieldConditionBuilder.js +6 -0
- package/src/query-sdk/dist/NestedBuilders.d.ts +43 -0
- package/src/query-sdk/dist/NestedBuilders.js +144 -0
- package/src/query-sdk/dist/OnChainDB.d.ts +19 -0
- package/src/query-sdk/dist/OnChainDB.js +123 -0
- package/src/query-sdk/dist/QueryBuilder.d.ts +70 -0
- package/src/query-sdk/dist/QueryBuilder.js +295 -0
- package/src/query-sdk/dist/QueryResult.d.ts +52 -0
- package/src/query-sdk/dist/QueryResult.js +293 -0
- package/src/query-sdk/dist/SelectionBuilder.d.ts +20 -0
- package/src/query-sdk/dist/SelectionBuilder.js +80 -0
- package/src/query-sdk/dist/adapters/HttpClientAdapter.d.ts +27 -0
- package/src/query-sdk/dist/adapters/HttpClientAdapter.js +170 -0
- package/src/query-sdk/dist/index.d.ts +36 -0
- package/src/query-sdk/dist/index.js +27 -0
- package/src/query-sdk/dist/operators.d.ts +56 -0
- package/src/query-sdk/dist/operators.js +289 -0
- package/src/query-sdk/dist/tests/setup.d.ts +15 -0
- package/src/query-sdk/dist/tests/setup.js +46 -0
- package/src/query-sdk/index.ts +59 -0
- package/src/query-sdk/jest.config.js +25 -0
- package/src/query-sdk/operators.ts +335 -0
- package/src/query-sdk/package.json +46 -0
- package/src/query-sdk/tests/FieldConditionBuilder.test.ts +84 -0
- package/src/query-sdk/tests/LogicalOperator.test.ts +85 -0
- package/src/query-sdk/tests/NestedBuilders.test.ts +321 -0
- package/src/query-sdk/tests/QueryBuilder.test.ts +348 -0
- package/src/query-sdk/tests/QueryResult.test.ts +464 -0
- package/src/query-sdk/tests/aggregations.test.ts +653 -0
- package/src/query-sdk/tests/comprehensive.test.ts +279 -0
- package/src/query-sdk/tests/integration.test.ts +608 -0
- package/src/query-sdk/tests/operators.test.ts +327 -0
- package/src/query-sdk/tests/setup.ts +59 -0
- package/src/query-sdk/tests/unit.test.ts +794 -0
- package/src/query-sdk/tsconfig.json +26 -0
- package/src/query-sdk/yarn.lock +3092 -0
- package/src/types.d.ts +131 -0
- package/src/types.js +46 -0
- package/src/types.ts +534 -0
- package/src/x402/index.ts +12 -0
- package/src/x402/types.ts +250 -0
- package/src/x402/utils.ts +332 -0
- package/tsconfig.json +20 -0
- package/yarn.lock +2309 -0
|
@@ -0,0 +1,268 @@
|
|
|
1
|
+
import { AxiosInstance } from 'axios';
|
|
2
|
+
import { IndexPaymentProof } from './types';
|
|
3
|
+
export interface Collection {
|
|
4
|
+
name: string;
|
|
5
|
+
schema?: CollectionSchema;
|
|
6
|
+
indexes?: Index[];
|
|
7
|
+
metadata?: CollectionMetadata;
|
|
8
|
+
}
|
|
9
|
+
export interface CollectionSchema {
|
|
10
|
+
fields: {
|
|
11
|
+
[fieldName: string]: FieldDefinition;
|
|
12
|
+
};
|
|
13
|
+
required?: string[];
|
|
14
|
+
relationships?: Relationship[];
|
|
15
|
+
}
|
|
16
|
+
export interface FieldDefinition {
|
|
17
|
+
type: 'string' | 'number' | 'boolean' | 'date' | 'object' | 'array';
|
|
18
|
+
index?: boolean;
|
|
19
|
+
unique?: boolean;
|
|
20
|
+
required?: boolean;
|
|
21
|
+
default?: any;
|
|
22
|
+
validation?: FieldValidation;
|
|
23
|
+
}
|
|
24
|
+
export interface FieldValidation {
|
|
25
|
+
min?: number;
|
|
26
|
+
max?: number;
|
|
27
|
+
pattern?: string;
|
|
28
|
+
enum?: any[];
|
|
29
|
+
custom?: (value: any) => boolean | string;
|
|
30
|
+
}
|
|
31
|
+
export interface Relationship {
|
|
32
|
+
type: 'one-to-one' | 'one-to-many' | 'many-to-many';
|
|
33
|
+
collection: string;
|
|
34
|
+
localField: string;
|
|
35
|
+
foreignField: string;
|
|
36
|
+
cascade?: boolean;
|
|
37
|
+
}
|
|
38
|
+
export interface Index {
|
|
39
|
+
name: string;
|
|
40
|
+
collection: string;
|
|
41
|
+
field_name: string;
|
|
42
|
+
index_type: 'btree' | 'hash' | 'fulltext' | 'composite';
|
|
43
|
+
fields?: string[];
|
|
44
|
+
options?: IndexOptions;
|
|
45
|
+
status?: IndexStatus;
|
|
46
|
+
statistics?: IndexStatistics;
|
|
47
|
+
payment_proof?: IndexPaymentProof;
|
|
48
|
+
}
|
|
49
|
+
export interface IndexOptions {
|
|
50
|
+
unique?: boolean;
|
|
51
|
+
sparse?: boolean;
|
|
52
|
+
background?: boolean;
|
|
53
|
+
partialFilter?: any;
|
|
54
|
+
textIndexVersion?: number;
|
|
55
|
+
weights?: {
|
|
56
|
+
[field: string]: number;
|
|
57
|
+
};
|
|
58
|
+
defaultLanguage?: string;
|
|
59
|
+
}
|
|
60
|
+
export interface IndexStatus {
|
|
61
|
+
building: boolean;
|
|
62
|
+
progress?: number;
|
|
63
|
+
error?: string;
|
|
64
|
+
created_at?: string;
|
|
65
|
+
completed_at?: string;
|
|
66
|
+
}
|
|
67
|
+
export interface IndexStatistics {
|
|
68
|
+
size: number;
|
|
69
|
+
usage_count: number;
|
|
70
|
+
last_used?: string;
|
|
71
|
+
efficiency_score?: number;
|
|
72
|
+
memory_usage?: number;
|
|
73
|
+
}
|
|
74
|
+
export interface CollectionMetadata {
|
|
75
|
+
created_at: string;
|
|
76
|
+
updated_at: string;
|
|
77
|
+
document_count: number;
|
|
78
|
+
storage_size: number;
|
|
79
|
+
avg_document_size: number;
|
|
80
|
+
}
|
|
81
|
+
export interface DatabaseStats {
|
|
82
|
+
total_collections: number;
|
|
83
|
+
total_indexes: number;
|
|
84
|
+
total_documents: number;
|
|
85
|
+
storage_size: number;
|
|
86
|
+
index_size: number;
|
|
87
|
+
active_connections: number;
|
|
88
|
+
}
|
|
89
|
+
export interface QueryPlan {
|
|
90
|
+
query: any;
|
|
91
|
+
indexes_used: string[];
|
|
92
|
+
estimated_cost: number;
|
|
93
|
+
execution_time_estimate: number;
|
|
94
|
+
optimization_hints: string[];
|
|
95
|
+
}
|
|
96
|
+
export interface BatchOperation {
|
|
97
|
+
operation: 'create' | 'update' | 'delete';
|
|
98
|
+
collection: string;
|
|
99
|
+
data: any;
|
|
100
|
+
conditions?: any;
|
|
101
|
+
}
|
|
102
|
+
export interface BatchResult {
|
|
103
|
+
success: boolean;
|
|
104
|
+
operation: string;
|
|
105
|
+
collection: string;
|
|
106
|
+
result?: any;
|
|
107
|
+
error?: string;
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Comprehensive database management client for OnChainDB
|
|
111
|
+
*
|
|
112
|
+
* Provides full CRUD operations for collections, indexes, and schemas
|
|
113
|
+
* with advanced features like query planning, batch operations, and statistics
|
|
114
|
+
*/
|
|
115
|
+
export declare class DatabaseManager {
|
|
116
|
+
private httpClient;
|
|
117
|
+
private serverUrl;
|
|
118
|
+
private appId;
|
|
119
|
+
private apiKey?;
|
|
120
|
+
constructor(httpClient: AxiosInstance, serverUrl: string, appId: string, apiKey?: string | undefined);
|
|
121
|
+
/**
|
|
122
|
+
* Create a new collection with optional schema definition
|
|
123
|
+
*/
|
|
124
|
+
createCollection(name: string, schema?: CollectionSchema, options?: {
|
|
125
|
+
validate?: boolean;
|
|
126
|
+
createIndexes?: boolean;
|
|
127
|
+
}): Promise<Collection>;
|
|
128
|
+
/**
|
|
129
|
+
* List all collections in the application
|
|
130
|
+
*/
|
|
131
|
+
listCollections(includeStats?: boolean): Promise<Collection[]>;
|
|
132
|
+
/**
|
|
133
|
+
* Get detailed information about a specific collection
|
|
134
|
+
*/
|
|
135
|
+
getCollection(name: string, includeStats?: boolean): Promise<Collection>;
|
|
136
|
+
/**
|
|
137
|
+
* Update collection schema or metadata
|
|
138
|
+
*/
|
|
139
|
+
updateCollection(name: string, updates: Partial<Collection>, options?: {
|
|
140
|
+
validate?: boolean;
|
|
141
|
+
migrate?: boolean;
|
|
142
|
+
}): Promise<Collection>;
|
|
143
|
+
/**
|
|
144
|
+
* Delete a collection and all its data
|
|
145
|
+
*/
|
|
146
|
+
deleteCollection(name: string, options?: {
|
|
147
|
+
force?: boolean;
|
|
148
|
+
cascade?: boolean;
|
|
149
|
+
}): Promise<{
|
|
150
|
+
success: boolean;
|
|
151
|
+
message: string;
|
|
152
|
+
}>;
|
|
153
|
+
/**
|
|
154
|
+
* Create a new index on a collection with payment support
|
|
155
|
+
*
|
|
156
|
+
* @param indexDefinition - Index definition without status/statistics
|
|
157
|
+
* @param paymentOptions - Optional payment configuration for paid indexes
|
|
158
|
+
* @returns Created index with payment proof if applicable
|
|
159
|
+
*/
|
|
160
|
+
createIndex(indexDefinition: Omit<Index, 'status' | 'statistics'>, paymentOptions?: {
|
|
161
|
+
userWallet?: any;
|
|
162
|
+
brokerAddress?: string;
|
|
163
|
+
}): Promise<Index>;
|
|
164
|
+
/**
|
|
165
|
+
* Create multiple indexes in a batch operation
|
|
166
|
+
*/
|
|
167
|
+
createIndexes(collection: string, indexes: Omit<Index, 'collection' | 'status' | 'statistics'>[]): Promise<Index[]>;
|
|
168
|
+
/**
|
|
169
|
+
* List all indexes for a collection or entire application
|
|
170
|
+
*/
|
|
171
|
+
listIndexes(collection?: string, includeStats?: boolean): Promise<Index[]>;
|
|
172
|
+
/**
|
|
173
|
+
* Get detailed information about a specific index
|
|
174
|
+
*/
|
|
175
|
+
getIndex(collection: string, indexName: string): Promise<Index>;
|
|
176
|
+
/**
|
|
177
|
+
* Check the status of index building operations
|
|
178
|
+
*/
|
|
179
|
+
getIndexStatus(collection: string, indexName: string): Promise<IndexStatus>;
|
|
180
|
+
/**
|
|
181
|
+
* Get index performance statistics
|
|
182
|
+
*/
|
|
183
|
+
getIndexStatistics(collection: string, indexName: string): Promise<IndexStatistics>;
|
|
184
|
+
/**
|
|
185
|
+
* Rebuild an existing index
|
|
186
|
+
*/
|
|
187
|
+
rebuildIndex(collection: string, indexName: string, options?: {
|
|
188
|
+
background?: boolean;
|
|
189
|
+
}): Promise<{
|
|
190
|
+
success: boolean;
|
|
191
|
+
message: string;
|
|
192
|
+
}>;
|
|
193
|
+
/**
|
|
194
|
+
* Drop/delete an index
|
|
195
|
+
*/
|
|
196
|
+
dropIndex(collection: string, indexName: string): Promise<{
|
|
197
|
+
success: boolean;
|
|
198
|
+
message: string;
|
|
199
|
+
}>;
|
|
200
|
+
/**
|
|
201
|
+
* Validate data against collection schema
|
|
202
|
+
*/
|
|
203
|
+
validateSchema(collection: string, data: any): Promise<{
|
|
204
|
+
valid: boolean;
|
|
205
|
+
errors?: string[];
|
|
206
|
+
}>;
|
|
207
|
+
/**
|
|
208
|
+
* Migrate collection data to new schema
|
|
209
|
+
*/
|
|
210
|
+
migrateSchema(collection: string, newSchema: CollectionSchema, options?: {
|
|
211
|
+
dryRun?: boolean;
|
|
212
|
+
batchSize?: number;
|
|
213
|
+
}): Promise<{
|
|
214
|
+
success: boolean;
|
|
215
|
+
migrated: number;
|
|
216
|
+
errors?: any[];
|
|
217
|
+
}>;
|
|
218
|
+
/**
|
|
219
|
+
* Explain query execution plan
|
|
220
|
+
*/
|
|
221
|
+
explainQuery(collection: string, query: any): Promise<QueryPlan>;
|
|
222
|
+
/**
|
|
223
|
+
* Get optimization suggestions for query performance
|
|
224
|
+
*/
|
|
225
|
+
getOptimizationSuggestions(collection: string): Promise<{
|
|
226
|
+
missing_indexes: string[];
|
|
227
|
+
unused_indexes: string[];
|
|
228
|
+
slow_queries: any[];
|
|
229
|
+
recommendations: string[];
|
|
230
|
+
}>;
|
|
231
|
+
/**
|
|
232
|
+
* Execute multiple database operations in a single transaction
|
|
233
|
+
*/
|
|
234
|
+
executeBatch(operations: BatchOperation[]): Promise<BatchResult[]>;
|
|
235
|
+
/**
|
|
236
|
+
* Get overall database statistics
|
|
237
|
+
*/
|
|
238
|
+
getDatabaseStats(): Promise<DatabaseStats>;
|
|
239
|
+
/**
|
|
240
|
+
* Get collection-specific statistics
|
|
241
|
+
*/
|
|
242
|
+
getCollectionStats(collection: string): Promise<CollectionMetadata>;
|
|
243
|
+
/**
|
|
244
|
+
* Test database connection and basic functionality
|
|
245
|
+
*/
|
|
246
|
+
healthCheck(): Promise<{
|
|
247
|
+
healthy: boolean;
|
|
248
|
+
response_time: number;
|
|
249
|
+
version: string;
|
|
250
|
+
features: string[];
|
|
251
|
+
}>;
|
|
252
|
+
/**
|
|
253
|
+
* Get API headers including authentication
|
|
254
|
+
*/
|
|
255
|
+
private getHeaders;
|
|
256
|
+
/**
|
|
257
|
+
* Set API key for authenticated operations
|
|
258
|
+
*/
|
|
259
|
+
setApiKey(apiKey: string): void;
|
|
260
|
+
/**
|
|
261
|
+
* Update server configuration
|
|
262
|
+
*/
|
|
263
|
+
updateConfig(httpClient: AxiosInstance, serverUrl: string, appId: string): void;
|
|
264
|
+
}
|
|
265
|
+
/**
|
|
266
|
+
* Factory function to create a DatabaseManager instance
|
|
267
|
+
*/
|
|
268
|
+
export declare function createDatabaseManager(httpClient: AxiosInstance, serverUrl: string, appId: string, apiKey?: string): DatabaseManager;
|
package/src/database.js
ADDED
|
@@ -0,0 +1,294 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// Database Management Client for OnChainDB SDK
|
|
3
|
+
// Provides comprehensive collection and index management capabilities
|
|
4
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
5
|
+
exports.DatabaseManager = void 0;
|
|
6
|
+
exports.createDatabaseManager = createDatabaseManager;
|
|
7
|
+
const types_1 = require("./types");
|
|
8
|
+
/**
|
|
9
|
+
* Comprehensive database management client for OnChainDB
|
|
10
|
+
*
|
|
11
|
+
* Provides full CRUD operations for collections, indexes, and schemas
|
|
12
|
+
* with advanced features like query planning, batch operations, and statistics
|
|
13
|
+
*/
|
|
14
|
+
class DatabaseManager {
|
|
15
|
+
constructor(httpClient, serverUrl, appId, apiKey) {
|
|
16
|
+
this.httpClient = httpClient;
|
|
17
|
+
this.serverUrl = serverUrl;
|
|
18
|
+
this.appId = appId;
|
|
19
|
+
this.apiKey = apiKey;
|
|
20
|
+
}
|
|
21
|
+
// ==================== Collection Management ====================
|
|
22
|
+
/**
|
|
23
|
+
* Create a new collection with optional schema definition
|
|
24
|
+
*/
|
|
25
|
+
async createCollection(name, schema, options) {
|
|
26
|
+
const payload = {
|
|
27
|
+
name,
|
|
28
|
+
schema,
|
|
29
|
+
options
|
|
30
|
+
};
|
|
31
|
+
const response = await this.httpClient.post(`/api/apps/${this.appId}/collections`, payload, { headers: this.getHeaders() });
|
|
32
|
+
return response.data;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* List all collections in the application
|
|
36
|
+
*/
|
|
37
|
+
async listCollections(includeStats) {
|
|
38
|
+
const params = includeStats ? { include_stats: true } : {};
|
|
39
|
+
const response = await this.httpClient.get(`/api/apps/${this.appId}/collections`, {
|
|
40
|
+
params,
|
|
41
|
+
headers: this.getHeaders()
|
|
42
|
+
});
|
|
43
|
+
return response.data;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Get detailed information about a specific collection
|
|
47
|
+
*/
|
|
48
|
+
async getCollection(name, includeStats) {
|
|
49
|
+
const params = includeStats ? { include_stats: true } : {};
|
|
50
|
+
const response = await this.httpClient.get(`/api/apps/${this.appId}/collections/${name}`, {
|
|
51
|
+
params,
|
|
52
|
+
headers: this.getHeaders()
|
|
53
|
+
});
|
|
54
|
+
return response.data;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Update collection schema or metadata
|
|
58
|
+
*/
|
|
59
|
+
async updateCollection(name, updates, options) {
|
|
60
|
+
const payload = { ...updates, options };
|
|
61
|
+
const response = await this.httpClient.put(`/api/apps/${this.appId}/collections/${name}`, payload, { headers: this.getHeaders() });
|
|
62
|
+
return response.data;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Delete a collection and all its data
|
|
66
|
+
*/
|
|
67
|
+
async deleteCollection(name, options) {
|
|
68
|
+
const response = await this.httpClient.delete(`/api/apps/${this.appId}/collections/${name}`, {
|
|
69
|
+
data: options,
|
|
70
|
+
headers: this.getHeaders()
|
|
71
|
+
});
|
|
72
|
+
return response.data;
|
|
73
|
+
}
|
|
74
|
+
// ==================== Index Management ====================
|
|
75
|
+
/**
|
|
76
|
+
* Create a new index on a collection with payment support
|
|
77
|
+
*
|
|
78
|
+
* @param indexDefinition - Index definition without status/statistics
|
|
79
|
+
* @param paymentOptions - Optional payment configuration for paid indexes
|
|
80
|
+
* @returns Created index with payment proof if applicable
|
|
81
|
+
*/
|
|
82
|
+
async createIndex(indexDefinition, paymentOptions) {
|
|
83
|
+
let finalRequest = indexDefinition;
|
|
84
|
+
// Handle payment if options provided
|
|
85
|
+
if (paymentOptions?.userWallet && paymentOptions?.brokerAddress) {
|
|
86
|
+
console.log('💰 Getting index cost estimate...');
|
|
87
|
+
// Get cost estimate
|
|
88
|
+
const costEstimate = await this.httpClient.post('/api/indexes/cost-estimate', {
|
|
89
|
+
app_id: this.appId,
|
|
90
|
+
collection: indexDefinition.collection,
|
|
91
|
+
field_name: indexDefinition.field_name,
|
|
92
|
+
index_type: indexDefinition.index_type
|
|
93
|
+
});
|
|
94
|
+
const cost = costEstimate.data;
|
|
95
|
+
const costInUtia = cost.total_estimated_cost_utia;
|
|
96
|
+
console.log(`📊 Index cost: ${costInUtia} utia`);
|
|
97
|
+
// Request payment
|
|
98
|
+
console.log('💳 Requesting user payment via Keplr...');
|
|
99
|
+
const paymentResult = await paymentOptions.userWallet.signAndBroadcast(paymentOptions.brokerAddress, `${costInUtia}utia`, `OnChainDB index creation - ${indexDefinition.field_name}`);
|
|
100
|
+
if (!paymentResult.success) {
|
|
101
|
+
throw new types_1.OnChainDBError(`Payment failed: ${paymentResult.error}`, 'PAYMENT_ERROR');
|
|
102
|
+
}
|
|
103
|
+
console.log(`✅ Payment successful: ${paymentResult.txHash}`);
|
|
104
|
+
// Add payment proof
|
|
105
|
+
finalRequest = {
|
|
106
|
+
...indexDefinition,
|
|
107
|
+
payment_proof: {
|
|
108
|
+
tx_hash: paymentResult.txHash,
|
|
109
|
+
user_address: paymentOptions.userWallet.getState().address,
|
|
110
|
+
broker_address: paymentOptions.brokerAddress,
|
|
111
|
+
amount_utia: costInUtia,
|
|
112
|
+
estimated_cost: cost
|
|
113
|
+
}
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
// Use alternative index creation endpoint (collection-specific endpoint temporarily disabled)
|
|
117
|
+
const response = await this.httpClient.post(`/api/apps/${this.appId}/indexes`, finalRequest, { headers: this.getHeaders() });
|
|
118
|
+
return response.data;
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Create multiple indexes in a batch operation
|
|
122
|
+
*/
|
|
123
|
+
async createIndexes(collection, indexes) {
|
|
124
|
+
// Since batch endpoint doesn't exist, create indexes individually
|
|
125
|
+
const results = [];
|
|
126
|
+
for (const indexDef of indexes) {
|
|
127
|
+
const result = await this.createIndex({ ...indexDef, collection });
|
|
128
|
+
results.push(result);
|
|
129
|
+
}
|
|
130
|
+
return results;
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* List all indexes for a collection or entire application
|
|
134
|
+
*/
|
|
135
|
+
async listIndexes(collection, includeStats) {
|
|
136
|
+
const endpoint = collection
|
|
137
|
+
? `/api/apps/${this.appId}/collections/${collection}/indexes`
|
|
138
|
+
: `/api/apps/${this.appId}/indexes`;
|
|
139
|
+
const params = includeStats ? { include_stats: true } : {};
|
|
140
|
+
const response = await this.httpClient.get(endpoint, {
|
|
141
|
+
params,
|
|
142
|
+
headers: this.getHeaders()
|
|
143
|
+
});
|
|
144
|
+
return response.data;
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Get detailed information about a specific index
|
|
148
|
+
*/
|
|
149
|
+
async getIndex(collection, indexName) {
|
|
150
|
+
const response = await this.httpClient.get(`/api/apps/${this.appId}/collections/${collection}/indexes/${indexName}`, { headers: this.getHeaders() });
|
|
151
|
+
return response.data;
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Check the status of index building operations
|
|
155
|
+
*/
|
|
156
|
+
async getIndexStatus(collection, indexName) {
|
|
157
|
+
const response = await this.httpClient.get(`/api/apps/${this.appId}/collections/${collection}/indexes/${indexName}/status`, { headers: this.getHeaders() });
|
|
158
|
+
return response.data;
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Get index performance statistics
|
|
162
|
+
*/
|
|
163
|
+
async getIndexStatistics(collection, indexName) {
|
|
164
|
+
const response = await this.httpClient.get(`/api/apps/${this.appId}/collections/${collection}/indexes/${indexName}/statistics`, { headers: this.getHeaders() });
|
|
165
|
+
return response.data;
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Rebuild an existing index
|
|
169
|
+
*/
|
|
170
|
+
async rebuildIndex(collection, indexName, options) {
|
|
171
|
+
const response = await this.httpClient.post(`/api/apps/${this.appId}/collections/${collection}/indexes/${indexName}/rebuild`, options || {}, { headers: this.getHeaders() });
|
|
172
|
+
return response.data;
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* Drop/delete an index
|
|
176
|
+
*/
|
|
177
|
+
async dropIndex(collection, indexName) {
|
|
178
|
+
const response = await this.httpClient.delete(`/api/apps/${this.appId}/collections/${collection}/indexes/${indexName}`, { headers: this.getHeaders() });
|
|
179
|
+
return response.data;
|
|
180
|
+
}
|
|
181
|
+
// ==================== Schema Management ====================
|
|
182
|
+
/**
|
|
183
|
+
* Validate data against collection schema
|
|
184
|
+
*/
|
|
185
|
+
async validateSchema(collection, data) {
|
|
186
|
+
const response = await this.httpClient.post(`/api/apps/${this.appId}/collections/${collection}/validate`, { data }, { headers: this.getHeaders() });
|
|
187
|
+
return response.data;
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* Migrate collection data to new schema
|
|
191
|
+
*/
|
|
192
|
+
async migrateSchema(collection, newSchema, options) {
|
|
193
|
+
const payload = { schema: newSchema, ...options };
|
|
194
|
+
const response = await this.httpClient.post(`/api/apps/${this.appId}/collections/${collection}/migrate`, payload, { headers: this.getHeaders() });
|
|
195
|
+
return response.data;
|
|
196
|
+
}
|
|
197
|
+
// ==================== Query Planning and Optimization ====================
|
|
198
|
+
/**
|
|
199
|
+
* Explain query execution plan
|
|
200
|
+
*/
|
|
201
|
+
async explainQuery(collection, query) {
|
|
202
|
+
const response = await this.httpClient.post(`/api/apps/${this.appId}/collections/${collection}/explain`, { query }, { headers: this.getHeaders() });
|
|
203
|
+
return response.data;
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* Get optimization suggestions for query performance
|
|
207
|
+
*/
|
|
208
|
+
async getOptimizationSuggestions(collection) {
|
|
209
|
+
const response = await this.httpClient.get(`/api/apps/${this.appId}/collections/${collection}/optimize`, { headers: this.getHeaders() });
|
|
210
|
+
return response.data;
|
|
211
|
+
}
|
|
212
|
+
// ==================== Batch Operations ====================
|
|
213
|
+
/**
|
|
214
|
+
* Execute multiple database operations in a single transaction
|
|
215
|
+
*/
|
|
216
|
+
async executeBatch(operations) {
|
|
217
|
+
const response = await this.httpClient.post(`/api/apps/${this.appId}/batch`, { operations }, { headers: this.getHeaders() });
|
|
218
|
+
return response.data;
|
|
219
|
+
}
|
|
220
|
+
// ==================== Statistics and Monitoring ====================
|
|
221
|
+
/**
|
|
222
|
+
* Get overall database statistics
|
|
223
|
+
*/
|
|
224
|
+
async getDatabaseStats() {
|
|
225
|
+
const response = await this.httpClient.get(`/api/apps/${this.appId}/stats`, { headers: this.getHeaders() });
|
|
226
|
+
return response.data;
|
|
227
|
+
}
|
|
228
|
+
/**
|
|
229
|
+
* Get collection-specific statistics
|
|
230
|
+
*/
|
|
231
|
+
async getCollectionStats(collection) {
|
|
232
|
+
const response = await this.httpClient.get(`/api/apps/${this.appId}/collections/${collection}/stats`, { headers: this.getHeaders() });
|
|
233
|
+
return response.data;
|
|
234
|
+
}
|
|
235
|
+
// ==================== Utility Methods ====================
|
|
236
|
+
/**
|
|
237
|
+
* Test database connection and basic functionality
|
|
238
|
+
*/
|
|
239
|
+
async healthCheck() {
|
|
240
|
+
const startTime = Date.now();
|
|
241
|
+
try {
|
|
242
|
+
const response = await this.httpClient.get(`/api/apps/${this.appId}/health`, { headers: this.getHeaders() });
|
|
243
|
+
const responseTime = Date.now() - startTime;
|
|
244
|
+
return {
|
|
245
|
+
healthy: true,
|
|
246
|
+
response_time: responseTime,
|
|
247
|
+
version: response.data.version || '1.0.0',
|
|
248
|
+
features: response.data.features || []
|
|
249
|
+
};
|
|
250
|
+
}
|
|
251
|
+
catch (error) {
|
|
252
|
+
return {
|
|
253
|
+
healthy: false,
|
|
254
|
+
response_time: Date.now() - startTime,
|
|
255
|
+
version: 'unknown',
|
|
256
|
+
features: []
|
|
257
|
+
};
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
/**
|
|
261
|
+
* Get API headers including authentication
|
|
262
|
+
*/
|
|
263
|
+
getHeaders() {
|
|
264
|
+
const headers = {
|
|
265
|
+
'Content-Type': 'application/json'
|
|
266
|
+
};
|
|
267
|
+
if (this.apiKey) {
|
|
268
|
+
headers['Authorization'] = `Bearer ${this.apiKey}`;
|
|
269
|
+
}
|
|
270
|
+
return headers;
|
|
271
|
+
}
|
|
272
|
+
/**
|
|
273
|
+
* Set API key for authenticated operations
|
|
274
|
+
*/
|
|
275
|
+
setApiKey(apiKey) {
|
|
276
|
+
this.apiKey = apiKey;
|
|
277
|
+
}
|
|
278
|
+
/**
|
|
279
|
+
* Update server configuration
|
|
280
|
+
*/
|
|
281
|
+
updateConfig(httpClient, serverUrl, appId) {
|
|
282
|
+
this.httpClient = httpClient;
|
|
283
|
+
this.serverUrl = serverUrl;
|
|
284
|
+
this.appId = appId;
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
exports.DatabaseManager = DatabaseManager;
|
|
288
|
+
/**
|
|
289
|
+
* Factory function to create a DatabaseManager instance
|
|
290
|
+
*/
|
|
291
|
+
function createDatabaseManager(httpClient, serverUrl, appId, apiKey) {
|
|
292
|
+
return new DatabaseManager(httpClient, serverUrl, appId, apiKey);
|
|
293
|
+
}
|
|
294
|
+
// Types are available as imports, no need to re-export
|