initial
This commit is contained in:
307
ts_web/services/api.service.ts
Normal file
307
ts_web/services/api.service.ts
Normal file
@@ -0,0 +1,307 @@
|
||||
import * as plugins from '../plugins.js';
|
||||
|
||||
// Import interfaces from shared types
|
||||
// Note: In bundled form these are inlined
|
||||
export interface IS3Object {
|
||||
key: string;
|
||||
size?: number;
|
||||
lastModified?: string;
|
||||
isPrefix?: boolean;
|
||||
}
|
||||
|
||||
export interface IMongoDatabase {
|
||||
name: string;
|
||||
sizeOnDisk?: number;
|
||||
empty?: boolean;
|
||||
}
|
||||
|
||||
export interface IMongoCollection {
|
||||
name: string;
|
||||
count?: number;
|
||||
}
|
||||
|
||||
export interface IMongoIndex {
|
||||
name: string;
|
||||
keys: Record<string, number>;
|
||||
unique?: boolean;
|
||||
sparse?: boolean;
|
||||
}
|
||||
|
||||
export interface ICollectionStats {
|
||||
count: number;
|
||||
size: number;
|
||||
avgObjSize: number;
|
||||
storageSize: number;
|
||||
indexCount: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* API service for communicating with the tsview backend
|
||||
*/
|
||||
export class ApiService {
|
||||
private baseUrl: string;
|
||||
|
||||
constructor() {
|
||||
// Use current origin for API calls
|
||||
this.baseUrl = window.location.origin;
|
||||
}
|
||||
|
||||
/**
|
||||
* Make a typed request to the backend
|
||||
*/
|
||||
private async request<TReq, TRes>(method: string, requestData: TReq): Promise<TRes> {
|
||||
const typedRequest = new plugins.typedrequest.TypedRequest<{
|
||||
method: string;
|
||||
request: TReq;
|
||||
response: TRes;
|
||||
}>(this.baseUrl, method);
|
||||
|
||||
const response = await typedRequest.fire(requestData);
|
||||
return response;
|
||||
}
|
||||
|
||||
// ===========================================
|
||||
// S3 API Methods
|
||||
// ===========================================
|
||||
|
||||
async listBuckets(): Promise<string[]> {
|
||||
const result = await this.request<{}, { buckets: string[] }>('listBuckets', {});
|
||||
return result.buckets;
|
||||
}
|
||||
|
||||
async createBucket(bucketName: string): Promise<boolean> {
|
||||
const result = await this.request<{ bucketName: string }, { success: boolean }>(
|
||||
'createBucket',
|
||||
{ bucketName }
|
||||
);
|
||||
return result.success;
|
||||
}
|
||||
|
||||
async deleteBucket(bucketName: string): Promise<boolean> {
|
||||
const result = await this.request<{ bucketName: string }, { success: boolean }>(
|
||||
'deleteBucket',
|
||||
{ bucketName }
|
||||
);
|
||||
return result.success;
|
||||
}
|
||||
|
||||
async listObjects(
|
||||
bucketName: string,
|
||||
prefix?: string,
|
||||
delimiter?: string
|
||||
): Promise<{ objects: IS3Object[]; prefixes: string[] }> {
|
||||
return this.request('listObjects', { bucketName, prefix, delimiter });
|
||||
}
|
||||
|
||||
async getObject(
|
||||
bucketName: string,
|
||||
key: string
|
||||
): Promise<{ content: string; contentType: string; size: number; lastModified: string }> {
|
||||
return this.request('getObject', { bucketName, key });
|
||||
}
|
||||
|
||||
async getObjectMetadata(
|
||||
bucketName: string,
|
||||
key: string
|
||||
): Promise<{ contentType: string; size: number; lastModified: string }> {
|
||||
return this.request('getObjectMetadata', { bucketName, key });
|
||||
}
|
||||
|
||||
async putObject(
|
||||
bucketName: string,
|
||||
key: string,
|
||||
content: string,
|
||||
contentType: string
|
||||
): Promise<boolean> {
|
||||
const result = await this.request<
|
||||
{ bucketName: string; key: string; content: string; contentType: string },
|
||||
{ success: boolean }
|
||||
>('putObject', { bucketName, key, content, contentType });
|
||||
return result.success;
|
||||
}
|
||||
|
||||
async deleteObject(bucketName: string, key: string): Promise<boolean> {
|
||||
const result = await this.request<
|
||||
{ bucketName: string; key: string },
|
||||
{ success: boolean }
|
||||
>('deleteObject', { bucketName, key });
|
||||
return result.success;
|
||||
}
|
||||
|
||||
async copyObject(
|
||||
sourceBucket: string,
|
||||
sourceKey: string,
|
||||
destBucket: string,
|
||||
destKey: string
|
||||
): Promise<boolean> {
|
||||
const result = await this.request<
|
||||
{ sourceBucket: string; sourceKey: string; destBucket: string; destKey: string },
|
||||
{ success: boolean }
|
||||
>('copyObject', { sourceBucket, sourceKey, destBucket, destKey });
|
||||
return result.success;
|
||||
}
|
||||
|
||||
// ===========================================
|
||||
// MongoDB API Methods
|
||||
// ===========================================
|
||||
|
||||
async listDatabases(): Promise<IMongoDatabase[]> {
|
||||
const result = await this.request<{}, { databases: IMongoDatabase[] }>(
|
||||
'listDatabases',
|
||||
{}
|
||||
);
|
||||
return result.databases;
|
||||
}
|
||||
|
||||
async listCollections(databaseName: string): Promise<IMongoCollection[]> {
|
||||
const result = await this.request<
|
||||
{ databaseName: string },
|
||||
{ collections: IMongoCollection[] }
|
||||
>('listCollections', { databaseName });
|
||||
return result.collections;
|
||||
}
|
||||
|
||||
async createCollection(databaseName: string, collectionName: string): Promise<boolean> {
|
||||
const result = await this.request<
|
||||
{ databaseName: string; collectionName: string },
|
||||
{ success: boolean }
|
||||
>('createCollection', { databaseName, collectionName });
|
||||
return result.success;
|
||||
}
|
||||
|
||||
async findDocuments(
|
||||
databaseName: string,
|
||||
collectionName: string,
|
||||
options?: {
|
||||
filter?: Record<string, unknown>;
|
||||
projection?: Record<string, unknown>;
|
||||
sort?: Record<string, number>;
|
||||
skip?: number;
|
||||
limit?: number;
|
||||
}
|
||||
): Promise<{ documents: Record<string, unknown>[]; total: number }> {
|
||||
return this.request('findDocuments', {
|
||||
databaseName,
|
||||
collectionName,
|
||||
...options,
|
||||
});
|
||||
}
|
||||
|
||||
async getDocument(
|
||||
databaseName: string,
|
||||
collectionName: string,
|
||||
documentId: string
|
||||
): Promise<Record<string, unknown> | null> {
|
||||
const result = await this.request<
|
||||
{ databaseName: string; collectionName: string; documentId: string },
|
||||
{ document: Record<string, unknown> | null }
|
||||
>('getDocument', { databaseName, collectionName, documentId });
|
||||
return result.document;
|
||||
}
|
||||
|
||||
async insertDocument(
|
||||
databaseName: string,
|
||||
collectionName: string,
|
||||
document: Record<string, unknown>
|
||||
): Promise<string> {
|
||||
const result = await this.request<
|
||||
{ databaseName: string; collectionName: string; document: Record<string, unknown> },
|
||||
{ insertedId: string }
|
||||
>('insertDocument', { databaseName, collectionName, document });
|
||||
return result.insertedId;
|
||||
}
|
||||
|
||||
async updateDocument(
|
||||
databaseName: string,
|
||||
collectionName: string,
|
||||
documentId: string,
|
||||
update: Record<string, unknown>
|
||||
): Promise<{ success: boolean; modifiedCount: number }> {
|
||||
return this.request('updateDocument', {
|
||||
databaseName,
|
||||
collectionName,
|
||||
documentId,
|
||||
update,
|
||||
});
|
||||
}
|
||||
|
||||
async deleteDocument(
|
||||
databaseName: string,
|
||||
collectionName: string,
|
||||
documentId: string
|
||||
): Promise<{ success: boolean; deletedCount: number }> {
|
||||
return this.request('deleteDocument', { databaseName, collectionName, documentId });
|
||||
}
|
||||
|
||||
async runAggregation(
|
||||
databaseName: string,
|
||||
collectionName: string,
|
||||
pipeline: Record<string, unknown>[]
|
||||
): Promise<Record<string, unknown>[]> {
|
||||
const result = await this.request<
|
||||
{ databaseName: string; collectionName: string; pipeline: Record<string, unknown>[] },
|
||||
{ results: Record<string, unknown>[] }
|
||||
>('runAggregation', { databaseName, collectionName, pipeline });
|
||||
return result.results;
|
||||
}
|
||||
|
||||
async listIndexes(
|
||||
databaseName: string,
|
||||
collectionName: string
|
||||
): Promise<IMongoIndex[]> {
|
||||
const result = await this.request<
|
||||
{ databaseName: string; collectionName: string },
|
||||
{ indexes: IMongoIndex[] }
|
||||
>('listIndexes', { databaseName, collectionName });
|
||||
return result.indexes;
|
||||
}
|
||||
|
||||
async createIndex(
|
||||
databaseName: string,
|
||||
collectionName: string,
|
||||
keys: Record<string, number>,
|
||||
options?: { unique?: boolean; sparse?: boolean; name?: string }
|
||||
): Promise<string> {
|
||||
const result = await this.request<
|
||||
{
|
||||
databaseName: string;
|
||||
collectionName: string;
|
||||
keys: Record<string, number>;
|
||||
options?: { unique?: boolean; sparse?: boolean; name?: string };
|
||||
},
|
||||
{ indexName: string }
|
||||
>('createIndex', { databaseName, collectionName, keys, options });
|
||||
return result.indexName;
|
||||
}
|
||||
|
||||
async dropIndex(
|
||||
databaseName: string,
|
||||
collectionName: string,
|
||||
indexName: string
|
||||
): Promise<boolean> {
|
||||
const result = await this.request<
|
||||
{ databaseName: string; collectionName: string; indexName: string },
|
||||
{ success: boolean }
|
||||
>('dropIndex', { databaseName, collectionName, indexName });
|
||||
return result.success;
|
||||
}
|
||||
|
||||
async getCollectionStats(
|
||||
databaseName: string,
|
||||
collectionName: string
|
||||
): Promise<ICollectionStats> {
|
||||
const result = await this.request<
|
||||
{ databaseName: string; collectionName: string },
|
||||
{ stats: ICollectionStats }
|
||||
>('getCollectionStats', { databaseName, collectionName });
|
||||
return result.stats;
|
||||
}
|
||||
|
||||
async getServerStatus(): Promise<{
|
||||
version: string;
|
||||
uptime: number;
|
||||
connections: { current: number; available: number };
|
||||
}> {
|
||||
return this.request('getServerStatus', {});
|
||||
}
|
||||
}
|
||||
4
ts_web/services/index.ts
Normal file
4
ts_web/services/index.ts
Normal file
@@ -0,0 +1,4 @@
|
||||
export * from './api.service.js';
|
||||
import { ApiService } from './api.service.js';
|
||||
|
||||
export const apiService = new ApiService();
|
||||
Reference in New Issue
Block a user