manu-sapiens's picture
copy of omnitool_latest - should be working
b39afbe
raw
history blame
8.41 kB
/**
* Copyright (c) 2023 MERCENARIES.AI PTE. LTD.
* All rights reserved.
*/
import { type IOmniMessage, type OmniSDKClientMessages, type OmniSDKHostMessages } from './types';
import { OmniResource } from './Resources/OmniResource';
import { OmniBaseResource } from './Resources/OmniBaseResource';
import { HTTPClient } from './Utils/HttpClient';
import EventEmitter from 'emittery';
import type OmniSDKClient from './OmniSDKClient';
export default class OmniSDKShared {
protected messageHandlers: {
[key in OmniSDKClientMessages | OmniSDKHostMessages]?: (
message: IOmniMessage,
source: MessageEventSource | null
) => void;
} = {};
protected _isClient = false; // Default to false, meaning it's considered as host by default
public static Resource = OmniResource;
public Resource = OmniResource;
public events = new EventEmitter();
protected intentMap: Map<string, any> = new Map<string, any>();
protected _httpClient: HTTPClient;
constructor() {
this._initMessageListener();
this._httpClient = new HTTPClient();
}
public unload(): void {
window.removeEventListener('message', this._messageListenerHandler);
console.log('Message listener removed.');
}
protected _initMessageListener(): void {
window.addEventListener('message', this._messageListenerHandler, false);
console.log('Message listener initialized.');
}
protected addMessageHandler(
type: OmniSDKClientMessages | OmniSDKHostMessages,
handler: (message: IOmniMessage, source: MessageEventSource | null) => void
): void {
this.messageHandlers[type] = handler;
}
private _messageListenerHandler = (event: MessageEvent): void => {
if (event.origin !== window.location.origin) {
console.warn(`Dropping Message received from an unknown origin: ${event.origin}`);
return;
}
try {
const data = event.data as IOmniMessage;
const handler = this.messageHandlers[data.type];
if (handler) {
handler.call(this, data, event.source);
} else {
console.warn(`No handler found for message type: ${data.type}`);
}
} catch (error) {
console.error('Error processing the message:', error);
}
};
public getLocalValue(key: string, value: any): any
{
let finalKey = key
// In an extensions
if (this._isClient)
{
finalKey = "omni/"+(this as unknown as OmniSDKClient)._extensionId + "/" + key
}
else
{
finalKey = "omni/host/" + key
}
let stored = globalThis.localStorage.getItem(finalKey)
if (stored !== null)
{
let record = JSON.parse(stored)
let value = record.value
switch (record.type)
{
case 'boolean': value = value === 'true' ? true : false; break;
case 'object':
case 'number':
case 'string': break;
default:
console.warn("Unsupported value type", record.type, "on", key)
return null
}
return value;
}
return null
}
public setLocalValue(key: string, value: any)
{
if (key == null || key.length == 0)
{
throw new Error("Invalid null Key passed into setLocalValue")
}
let finalKey = key
// In an extensions
if (this._isClient)
{
finalKey = "omni/"+(this as unknown as OmniSDKClient)._extensionId + "/" + key
}
else
{
finalKey = "omni/host/" + key
}
if (value === null || value === undefined)
{
globalThis.localStorage.removeItem(finalKey)
return
}
const valueType = typeof(value)
let finalValue = value
switch(valueType)
{
case 'number':
case 'string':
case 'object': break;
case 'boolean': finalValue = value ? "true" : "false"; break;
default:
console.warn("Unsupported value type", valueType, "on", key)
return;
}
globalThis.localStorage.setItem(finalKey, JSON.stringify({
type: valueType,
value
}))
}
protected send(message: IOmniMessage, token?: string) {
if (this._isClient) {
console.log('Sending message from client:', message);
//@ts-ignore
message.token = this.token;
message = JSON.parse(JSON.stringify(message));
window.parent.postMessage(message, '*');
} else {
// Host logic to send message is implemented in OmniHost.
console.warn('Attempted to send a message from the host without specifying a target.');
}
}
public async runServerScript(scriptName: string, payload: any) {
const response = await this._httpClient.executeRequest('/api/v1/mercenaries/runscript/' + scriptName, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(payload)
});
const data = await response.json();
return data;
}
public canEditFile(file: OmniBaseResource) {
if (!file) {
return false;
}
return this.intentMap.has(`file:edit:${file.mimeType}`);
}
public canViewFile(file: OmniBaseResource) {
if (!file) {
return false;
}
return this.intentMap.has(`file:show:${file.mimeType}`);
}
public async getFileObject(fid: string): Promise<OmniBaseResource | null> {
try {
const response = await this._httpClient.executeRequest('/fid/' + fid + '?obj=true', {
method: 'GET',
headers: {
'Content-Type': 'application/json'
}
});
const data = await response.json();
if (data) {
console.log('getFileObject', data);
return new OmniBaseResource(data);
} else {
console.warn(`No valid file object found for fid ${fid}`);
return null;
}
} catch (ex) {
console.error(ex);
return null;
}
}
public async getFileBlob(fid: string): Promise<Blob | null> {
try {
const response = await this._httpClient.executeRequest('/fid/' + fid + '?download=true');
const blob = await response.blob();
return blob;
} catch (ex) {
console.error(ex);
return null;
}
}
public async uploadFiles(files: FileList, storageType: 'temporary' | 'permanent' = 'temporary') {
if (files?.length > 0) {
let result = await Promise.all(
Array.from(files).map(async (file) => {
const form = new FormData();
form.append('storageType', storageType);
form.append('file', file, file.name || Date.now().toString());
try {
const response = await fetch('/fid', {
method: 'POST',
body: form
});
if (response.ok) {
const data = await response.json();
if (data.length > 0 && data[0].ticket && data[0].fid) {
return data[0];
} else {
console.warn('Failed to upload file', { data, file });
return null;
}
} else {
console.warn('Failed to upload file', { response, file });
return null;
}
} catch (error) {
console.error('Failed to upload file', { error, file });
return null;
}
})
);
result = result.filter((r) => r);
return result;
} else {
return [];
}
}
public async startRecipe(id: string, args: any) {
const response = await fetch('/api/v1/workflow/exec', {
method: 'POST',
credentials: 'include',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ workflow: id, args })
});
const data = await response.json();
if (data.status === 'JOB_STARTED') {
return { ...data }; /* jobId: result.jobId,*/
}
}
public async downloadFile(fileObject: OmniBaseResource, fileName?: string): Promise<void> {
const fid = fileObject.fid;
const filename = fileName || fileObject.fileName;
fetch('/fid/' + fid + '?download=true')
.then((response) => response.blob())
.then((blob) => {
const url = URL.createObjectURL(blob);
const link = document.createElement('a');
link.href = url;
link.download = filename;
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
})
.catch((error) => console.error(error));
}
}