UNPKG

magically-sdk

Version:

Official SDK for Magically - Build mobile apps with AI

194 lines (193 loc) 6.7 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.MagicallyData = void 0; const APIClient_1 = require("./APIClient"); class MagicallyData { constructor(config, auth) { this.config = config; this.auth = auth; this.apiClient = new APIClient_1.APIClient(config, 'MagicallyData'); } /** * Check if a query is public (doesn't require authentication) */ isPublicQuery(filter) { return filter?.isPublic === true; } /** * Check if an aggregate pipeline is public (doesn't require authentication) */ isPublicAggregate(pipeline) { return pipeline?.[0]?.$match?.isPublic === true; } /** * Check if a raw operation is public (read-only with isPublic filter) */ isPublicRawOperation(operation, query) { const readOperations = ['find', 'findOne', 'count', 'countDocuments', 'distinct']; return readOperations.includes(operation) && query?.isPublic === true; } /** * Query data from a collection with type safety * @param collection - Collection name * @param filter - MongoDB filter object (optional) * @param options - Query options (sort, limit, skip) */ async query(collection, filter, options) { try { // In edge environment, API key is used automatically // Otherwise, get user token const token = this.apiClient.isEdgeEnvironment() ? null : await this.auth.getValidToken(); const result = await this.apiClient.request(`/api/project/${this.config.projectId}/data/query`, { method: 'POST', body: { collection, filter: filter || {}, sort: options?.sort || {}, limit: options?.limit || 100, skip: options?.skip || 0, }, operation: `query:${collection}` }, token); return { data: result.data || [], total: result.total || 0 }; } catch (error) { throw error; } } /** * Insert data into a collection with type safety */ async insert(collection, data, options = {}) { try { const token = this.apiClient.isEdgeEnvironment() ? null : await this.auth.getValidToken(); const result = await this.apiClient.request(`/api/project/${this.config.projectId}/data/insert`, { method: 'POST', body: { collection, data, upsert: options.upsert || false, }, operation: `insert:${collection}` }, token); return result.data; } catch (error) { throw error; } } /** * Update existing data in a collection (fails if not found) */ async update(collection, filter, data) { try { const token = this.apiClient.isEdgeEnvironment() ? null : await this.auth.getValidToken(); const result = await this.apiClient.request(`/api/project/${this.config.projectId}/data/raw`, { method: 'POST', body: { collection, operation: 'findOneAndUpdate', query: filter, update: { $set: data }, options: { returnDocument: 'after' } }, operation: `update:${collection}` }, token); if (!result.result) { throw new Error('Document not found for update'); } return result.result; } catch (error) { throw error; } } /** * Delete data from a collection */ async delete(collection, filter) { try { const token = this.apiClient.isEdgeEnvironment() ? null : await this.auth.getValidToken(); const result = await this.apiClient.request(`/api/project/${this.config.projectId}/data/raw`, { method: 'POST', body: { collection, operation: 'deleteMany', query: filter, }, operation: `delete:${collection}` }, token); return { deletedCount: result.result.deletedCount || 0 }; } catch (error) { throw error; } } /** * Run aggregation query with type safety */ async aggregate(collection, pipeline) { try { const token = this.apiClient.isEdgeEnvironment() ? null : await this.auth.getValidToken(); const result = await this.apiClient.request(`/api/project/${this.config.projectId}/data/aggregate`, { method: 'POST', body: { collection, pipeline, allowDiskUse: false }, operation: `aggregate:${collection}` }, token); return result.data; } catch (error) { throw error; } } /** * Run raw MongoDB operations with type safety and validation */ async raw(collection, operation, options = {}) { // Validate allowed operations for security const allowedOperations = [ 'find', 'findOne', 'count', 'countDocuments', 'distinct', 'aggregate', 'findOneAndUpdate', 'updateOne', 'updateMany', 'deleteOne', 'deleteMany', 'insertOne', 'insertMany' ]; if (!allowedOperations.includes(operation)) { throw new Error(`Operation '${operation}' is not allowed. Allowed operations: ${allowedOperations.join(', ')}`); } try { const token = this.apiClient.isEdgeEnvironment() ? null : await this.auth.getValidToken(); const result = await this.apiClient.request(`/api/project/${this.config.projectId}/data/raw`, { method: 'POST', body: { collection, operation, ...options }, operation: `raw:${operation}:${collection}` }, token); return result.result; } catch (error) { throw error; } } } exports.MagicallyData = MagicallyData;