function tag creation
This commit is contained in:
parent
5eca23247a
commit
7624a7fc77
32 changed files with 180 additions and 74 deletions
|
@ -1,10 +1,10 @@
|
||||||
import { Client, Execution, ExecutionList, FunctionsClient, TagList, Vars } from "../appwrite";
|
import { Client, Execution, ExecutionList, FunctionsClient, Tag, TagList, Vars } from "../appwrite";
|
||||||
import { AppwriteSDK } from '../constants';
|
import { AppwriteSDK } from '../constants';
|
||||||
import AppwriteCall from '../utils/AppwriteCall';
|
import AppwriteCall from '../utils/AppwriteCall';
|
||||||
import { ReadStream } from 'node:fs';
|
import { ReadStream } from 'node:fs';
|
||||||
|
|
||||||
export class Functions {
|
export class Functions {
|
||||||
private readonly functions: FunctionsClient;
|
public readonly functions: FunctionsClient;
|
||||||
|
|
||||||
constructor(client: Client) {
|
constructor(client: Client) {
|
||||||
this.functions = new AppwriteSDK.Functions(client);
|
this.functions = new AppwriteSDK.Functions(client);
|
||||||
|
@ -28,7 +28,7 @@ export class Functions {
|
||||||
public async delete(functionId: string): Promise<void> {
|
public async delete(functionId: string): Promise<void> {
|
||||||
return await AppwriteCall(this.functions.delete(functionId));
|
return await AppwriteCall(this.functions.delete(functionId));
|
||||||
}
|
}
|
||||||
public async createTag(functionId: string, command: string, code: ReadStream): Promise<any> {
|
public async createTag(functionId: string, command: string, code: ReadStream): Promise<Tag | undefined> {
|
||||||
return await AppwriteCall(this.functions.createTag(functionId, command, code));
|
return await AppwriteCall(this.functions.createTag(functionId, command, code));
|
||||||
}
|
}
|
||||||
public async listTags(id: string, search?: string, limit?: number, offset?: number, orderType?: 'ASC' | 'DESC'): Promise<TagList | undefined> {
|
public async listTags(id: string, search?: string, limit?: number, offset?: number, orderType?: 'ASC' | 'DESC'): Promise<TagList | undefined> {
|
||||||
|
@ -40,7 +40,7 @@ export class Functions {
|
||||||
public async deleteTag(functionId: string, tagId: string): Promise<void> {
|
public async deleteTag(functionId: string, tagId: string): Promise<void> {
|
||||||
return await AppwriteCall(this.functions.deleteTag(functionId, tagId));
|
return await AppwriteCall(this.functions.deleteTag(functionId, tagId));
|
||||||
}
|
}
|
||||||
public async createExecution(functionId: string, data?: string): Promise<any> {
|
public async createExecution(functionId: string, data?: string): Promise<Execution | undefined> {
|
||||||
return await AppwriteCall(this.functions.createExecution(functionId, data));
|
return await AppwriteCall(this.functions.createExecution(functionId, data));
|
||||||
}
|
}
|
||||||
public async listExecutions(functionId: string, search?: string, limit?: number, offset?: number, orderType?: 'ASC' | 'DESC'): Promise<ExecutionList | undefined> {
|
public async listExecutions(functionId: string, search?: string, limit?: number, offset?: number, orderType?: 'ASC' | 'DESC'): Promise<ExecutionList | undefined> {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { EditableTreeItem } from '../../tree/common/SimpleEditableTreeItem';
|
import { EditableTreeItem } from '../../tree/common/editable/SimpleEditableTreeItem';
|
||||||
|
|
||||||
export async function editValue(treeItem: EditableTreeItem): Promise<void> {
|
export async function editValue(treeItem: EditableTreeItem): Promise<void> {
|
||||||
if (treeItem === undefined) {
|
if (treeItem === undefined) {
|
||||||
|
|
|
@ -1,10 +1,56 @@
|
||||||
|
import { window } from 'vscode';
|
||||||
|
import { Execution } from '../../appwrite';
|
||||||
import { functionsClient } from '../../client';
|
import { functionsClient } from '../../client';
|
||||||
import { ext } from '../../extensionVariables';
|
import { ext } from '../../extensionVariables';
|
||||||
import { FunctionTreeItem } from '../../tree/functions/FunctionTreeItem';
|
import { FunctionTreeItem } from '../../tree/functions/FunctionTreeItem';
|
||||||
|
import { sleep } from '../../utils/sleep';
|
||||||
|
import { viewExecutionErrors } from './viewExecutionErrors';
|
||||||
|
import { viewExecutionOutput } from './viewExecutionOutput';
|
||||||
|
|
||||||
export async function createExecution(functionTreeItem: FunctionTreeItem): Promise<void> {
|
export async function createExecution(functionTreeItem: FunctionTreeItem): Promise<void> {
|
||||||
const func = functionTreeItem.func;
|
const func = functionTreeItem.func;
|
||||||
ext.outputChannel.appendLog(`Creating execution for function ${func.name}`);
|
await executeFunction(func.$id);
|
||||||
|
}
|
||||||
await functionsClient?.createExecution(func.$id);
|
|
||||||
|
export async function executeFunction(functionId: string): Promise<void> {
|
||||||
|
ext.outputChannel.appendLog(`Creating execution for function with ID: ${functionId}`);
|
||||||
|
let execution = await functionsClient?.createExecution(functionId);
|
||||||
|
await ext.tree?.functions?.refresh();
|
||||||
|
|
||||||
|
if (execution === undefined) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
execution = await waitForExecution(execution);
|
||||||
|
|
||||||
|
if (execution === undefined) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const failed = execution.status === "failed";
|
||||||
|
const item = !failed ? "View output" : "View errors";
|
||||||
|
const action = await window.showInformationMessage(`Execution ${failed ? "failed" : "completed"} in ${execution.time.toFixed(2)}s.`, item);
|
||||||
|
if (action === item) {
|
||||||
|
if (item === "View output") {
|
||||||
|
await viewExecutionOutput(execution);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
await viewExecutionErrors(execution);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function waitForExecution(execution: Execution | undefined): Promise<Execution | undefined> {
|
||||||
|
ext.outputChannel.appendLog("Waiting for execution...");
|
||||||
|
if (execution === undefined) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (execution.status === "processing" || execution.status === "waiting") {
|
||||||
|
await sleep(2000);
|
||||||
|
|
||||||
|
ext.outputChannel.appendLog("Execution still ...");
|
||||||
|
return await waitForExecution(await functionsClient?.getExecution(execution.functionId, execution.$id));
|
||||||
|
}
|
||||||
|
|
||||||
|
return execution;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,40 +1,64 @@
|
||||||
import { ProgressLocation, Uri, window } from "vscode";
|
import { ProgressLocation, Uri, window, workspace } from "vscode";
|
||||||
import { functionsClient, storageClient } from "../../client";
|
import { functionsClient } from "../../client";
|
||||||
import { getTarReadStream } from "../../utils/tar";
|
import { getTarReadStream } from "../../utils/tar";
|
||||||
import { ext } from "../../extensionVariables";
|
import { ext } from "../../extensionVariables";
|
||||||
import * as fs from "fs";
|
import * as fs from "fs";
|
||||||
import { TagsTreeItem } from "../../tree/functions/tags/TagsTreeItem";
|
import { TagsTreeItem } from "../../tree/functions/tags/TagsTreeItem";
|
||||||
import { selectWorkspaceFolder } from "../../utils/workspace";
|
import { selectWorkspaceFolder } from "../../utils/workspace";
|
||||||
|
import { ProgressMessage } from '../../utils/types';
|
||||||
|
import { Tag } from '../../appwrite';
|
||||||
|
|
||||||
export async function createTag(item: TagsTreeItem | Uri): Promise<void> {
|
export async function createTag(item: TagsTreeItem | Uri): Promise<void> {
|
||||||
if (item instanceof Uri) {
|
if (item instanceof Uri) {
|
||||||
window.withProgress({ location: ProgressLocation.Notification, title: "Creating tag..." }, async (_progress, _token) => {
|
const tag = await window.withProgress({ location: ProgressLocation.Notification, title: "Creating tag..." }, async (progress, _token) => {
|
||||||
await createTagFromUri(item);
|
return await createTagFromUri(item, progress);
|
||||||
});
|
});
|
||||||
|
if (tag) {
|
||||||
|
await window.showInformationMessage(`Successfully created tag with size ${tag.size}B.`, "Execution function", "View in console");
|
||||||
|
return;
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (item instanceof TagsTreeItem) {
|
if (item instanceof TagsTreeItem) {
|
||||||
const folder = await selectWorkspaceFolder("Select folder of your function code.");
|
const folder = await selectWorkspaceFolder("Select folder of your function code.");
|
||||||
console.log(folder);
|
console.log(folder);
|
||||||
window.withProgress({ location: ProgressLocation.Notification, title: "Creating tag..." }, async (_progress, _token) => {
|
const tag = await window.withProgress({ location: ProgressLocation.Notification, title: "Creating tag..." }, async (progress, _token) => {
|
||||||
await createTagFromUri(Uri.parse(folder));
|
return await createTagFromUri(Uri.parse(folder), progress);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (tag) {
|
||||||
|
await window.showInformationMessage(`Successfully created tag with size ${tag.size}B.`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function createTagFromUri(uri: Uri): Promise<void> {
|
async function createTagFromUri(uri: Uri, progress: ProgressMessage): Promise<Tag | undefined> {
|
||||||
const tarFilePath = await getTarReadStream(uri);
|
|
||||||
|
progress.report({message: "Creating tarball", increment: 10});
|
||||||
|
|
||||||
if (functionsClient === undefined) {
|
if (functionsClient === undefined) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tarFilePath === undefined) {
|
let tarFilePath;
|
||||||
ext.outputChannel.appendLog("Error creating tar file.");
|
try {
|
||||||
|
tarFilePath = await getTarReadStream(uri);
|
||||||
|
} catch (e) {
|
||||||
|
window.showErrorMessage("Error creating tar file.\n" + e);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (tarFilePath === undefined) {
|
||||||
|
window.showErrorMessage("Failed to create tar file.");
|
||||||
|
ext.outputChannel.appendLog("Failed to create tar file.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// somehow makes the upload work
|
||||||
|
await workspace.fs.readFile(Uri.file(tarFilePath));
|
||||||
|
progress.report({message: "Uploading tag", increment: 60});
|
||||||
try {
|
try {
|
||||||
await functionsClient.createTag("60b1836a8e5d9", "python ./hello.py", fs.createReadStream(tarFilePath));
|
return await functionsClient.createTag("60b1836a8e5d9", "python ./hello.py", fs.createReadStream(tarFilePath));
|
||||||
await storageClient?.createFile(fs.createReadStream(tarFilePath));
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
ext.outputChannel.appendLog("Creating tag error: " + e);
|
ext.outputChannel.appendLog("Creating tag error: " + e);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,16 @@
|
||||||
|
import { Execution } from '../../appwrite';
|
||||||
import { ExecutionTreeItem } from "../../tree/functions/executions/ExecutionTreeItem";
|
import { ExecutionTreeItem } from "../../tree/functions/executions/ExecutionTreeItem";
|
||||||
import { openReadOnlyContent } from "../../ui/openReadonlyContent";
|
import { openReadOnlyContent } from "../../ui/openReadonlyContent";
|
||||||
|
|
||||||
export async function viewExecutionErrors(executionItem: ExecutionTreeItem): Promise<void> {
|
export async function viewExecutionErrors(executionItem: ExecutionTreeItem | Execution): Promise<void> {
|
||||||
if (executionItem === undefined) {
|
if (executionItem === undefined) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const execution = executionItem.execution;
|
let execution = executionItem as Execution;
|
||||||
await openReadOnlyContent({ label: `${executionItem.parent.parent.func.name} execution stderr`, fullId: `${execution.$id}-errors.txt` }, execution.stderr, '.txt');
|
|
||||||
|
if (executionItem instanceof ExecutionTreeItem) {
|
||||||
|
execution = executionItem.execution;
|
||||||
|
}
|
||||||
|
await openReadOnlyContent({ label: `Execution stderr`, fullId: `${execution.$id}-errors.txt` }, execution.stderr, '.txt');
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,17 @@
|
||||||
|
import { Execution } from '../../appwrite';
|
||||||
import { ExecutionTreeItem } from "../../tree/functions/executions/ExecutionTreeItem";
|
import { ExecutionTreeItem } from "../../tree/functions/executions/ExecutionTreeItem";
|
||||||
import { openReadOnlyContent } from "../../ui/openReadonlyContent";
|
import { openReadOnlyContent } from "../../ui/openReadonlyContent";
|
||||||
|
|
||||||
export async function viewExecutionOutput(executionItem: ExecutionTreeItem): Promise<void> {
|
export async function viewExecutionOutput(executionItem: ExecutionTreeItem | Execution): Promise<void> {
|
||||||
if (executionItem === undefined) {
|
if (executionItem === undefined) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const execution = executionItem.execution;
|
let execution = executionItem as Execution;
|
||||||
await openReadOnlyContent({ label: `${executionItem.parent.parent.func.name} execution stdout`, fullId: `${execution.$id}-output.txt` }, execution.stdout, '.txt');
|
|
||||||
|
if (executionItem instanceof ExecutionTreeItem) {
|
||||||
|
execution = executionItem.execution;
|
||||||
|
}
|
||||||
|
|
||||||
|
await openReadOnlyContent({ label: `Execution stdout`, fullId: `${execution.$id}-output.txt` }, execution.stdout, '.txt');
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,7 +17,7 @@ export type AppwriteTree = {
|
||||||
};
|
};
|
||||||
|
|
||||||
export type Ext = {
|
export type Ext = {
|
||||||
context?: ExtensionContext;
|
context: ExtensionContext;
|
||||||
outputChannel: AppwriteOutputChannel;
|
outputChannel: AppwriteOutputChannel;
|
||||||
tree?: AppwriteTree;
|
tree?: AppwriteTree;
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
import { ThemeIcon, TreeItem, TreeItemCollapsibleState } from "vscode";
|
import { ThemeIcon, TreeItem, TreeItemCollapsibleState } from "vscode";
|
||||||
import { Collection } from "../../appwrite";
|
import { Collection } from "../../appwrite";
|
||||||
import { databaseClient } from "../../client";
|
import { databaseClient } from "../../client";
|
||||||
import { AppwriteTreeItemBase } from "../../ui/AppwriteTreeItemBase";
|
import { AwTreeItem } from "../common/AwTreeItem";
|
||||||
import { DatabaseTreeItemProvider } from "./DatabaseTreeItemProvider";
|
import { DatabaseTreeItemProvider } from "./DatabaseTreeItemProvider";
|
||||||
import { DocumentsTreeItem } from "./DocumentsTreeItem";
|
import { DocumentsTreeItem } from "./DocumentsTreeItem";
|
||||||
import { PermissionsTreeItem } from "./settings/PermissionsTreeItem";
|
import { PermissionsTreeItem } from "./settings/PermissionsTreeItem";
|
||||||
import { RulesTreeItem } from "./settings/RulesTreeItem";
|
import { RulesTreeItem } from "./settings/RulesTreeItem";
|
||||||
|
|
||||||
export class CollectionTreeItem extends AppwriteTreeItemBase {
|
export class CollectionTreeItem extends AwTreeItem {
|
||||||
constructor(public collection: Collection, public readonly provider: DatabaseTreeItemProvider) {
|
constructor(public collection: Collection, public readonly provider: DatabaseTreeItemProvider) {
|
||||||
super(undefined, collection.name);
|
super(undefined, collection.name);
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,8 +4,8 @@ import AppwriteCall from "../../utils/AppwriteCall";
|
||||||
import { Collection, CollectionsList } from "../../appwrite";
|
import { Collection, CollectionsList } from "../../appwrite";
|
||||||
import { CollectionTreeItem } from "./CollectionTreeItem";
|
import { CollectionTreeItem } from "./CollectionTreeItem";
|
||||||
import { AppwriteSDK } from "../../constants";
|
import { AppwriteSDK } from "../../constants";
|
||||||
import { AppwriteTreeItemBase } from "../../ui/AppwriteTreeItemBase";
|
|
||||||
import { ext } from '../../extensionVariables';
|
import { ext } from '../../extensionVariables';
|
||||||
|
import { AwParentTreeItem } from '../common/AwParentTreeItem';
|
||||||
|
|
||||||
export class DatabaseTreeItemProvider implements vscode.TreeDataProvider<vscode.TreeItem> {
|
export class DatabaseTreeItemProvider implements vscode.TreeDataProvider<vscode.TreeItem> {
|
||||||
private _onDidChangeTreeData: vscode.EventEmitter<vscode.TreeItem | undefined | void> = new vscode.EventEmitter<
|
private _onDidChangeTreeData: vscode.EventEmitter<vscode.TreeItem | undefined | void> = new vscode.EventEmitter<
|
||||||
|
@ -33,8 +33,8 @@ export class DatabaseTreeItemProvider implements vscode.TreeDataProvider<vscode.
|
||||||
return Promise.resolve([]);
|
return Promise.resolve([]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (parent instanceof AppwriteTreeItemBase) {
|
if (parent instanceof AwParentTreeItem) {
|
||||||
return parent.getChildren?.() ?? [];
|
return parent.getChildrenInternal() ?? [];
|
||||||
}
|
}
|
||||||
|
|
||||||
const databaseSdk = new AppwriteSDK.Database(client);
|
const databaseSdk = new AppwriteSDK.Database(client);
|
||||||
|
|
|
@ -3,12 +3,12 @@ import { DocumentsList } from "../../appwrite";
|
||||||
import { client } from "../../client";
|
import { client } from "../../client";
|
||||||
import { AppwriteSDK } from "../../constants";
|
import { AppwriteSDK } from "../../constants";
|
||||||
import { ext } from "../../extensionVariables";
|
import { ext } from "../../extensionVariables";
|
||||||
import { AppwriteTreeItemBase } from "../../ui/AppwriteTreeItemBase";
|
import { AwTreeItem } from "../common/AwTreeItem";
|
||||||
import AppwriteCall from "../../utils/AppwriteCall";
|
import AppwriteCall from "../../utils/AppwriteCall";
|
||||||
import { CollectionTreeItem } from "./CollectionTreeItem";
|
import { CollectionTreeItem } from "./CollectionTreeItem";
|
||||||
import { DocumentTreeItem } from "./DocumentTreeItem";
|
import { DocumentTreeItem } from "./DocumentTreeItem";
|
||||||
|
|
||||||
export class DocumentsTreeItem extends AppwriteTreeItemBase<CollectionTreeItem> {
|
export class DocumentsTreeItem extends AwTreeItem<CollectionTreeItem> {
|
||||||
constructor(parent: CollectionTreeItem) {
|
constructor(parent: CollectionTreeItem) {
|
||||||
super(parent, "Documents");
|
super(parent, "Documents");
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
import { ThemeIcon, TreeItem, TreeItemCollapsibleState } from "vscode";
|
import { ThemeIcon, TreeItem, TreeItemCollapsibleState } from "vscode";
|
||||||
import { Permissions } from "../../../appwrite";
|
import { Permissions } from "../../../appwrite";
|
||||||
import { AppwriteTreeItemBase } from "../../../ui/AppwriteTreeItemBase";
|
import { AwTreeItem } from "../../common/AwTreeItem";
|
||||||
import { CollapsableTreeItem } from "../../CollapsableTreeItem";
|
import { CollapsableTreeItem } from "../../CollapsableTreeItem";
|
||||||
import { CollectionTreeItem } from "../CollectionTreeItem";
|
import { CollectionTreeItem } from "../CollectionTreeItem";
|
||||||
import { PermissionTreeItem } from "./PermissionTreeItem";
|
import { PermissionTreeItem } from "./PermissionTreeItem";
|
||||||
|
|
||||||
export class PermissionsTreeItem extends AppwriteTreeItemBase<CollectionTreeItem> {
|
export class PermissionsTreeItem extends AwTreeItem<CollectionTreeItem> {
|
||||||
public readonly permissions: Permissions;
|
public readonly permissions: Permissions;
|
||||||
|
|
||||||
constructor(parent: CollectionTreeItem) {
|
constructor(parent: CollectionTreeItem) {
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
import { ThemeIcon, TreeItem, TreeItemCollapsibleState } from "vscode";
|
import { ThemeIcon, TreeItem, TreeItemCollapsibleState } from "vscode";
|
||||||
import { Rule } from "../../../appwrite";
|
import { Rule } from "../../../appwrite";
|
||||||
import { AppwriteTreeItemBase } from "../../../ui/AppwriteTreeItemBase";
|
import { AwTreeItem } from "../../common/AwTreeItem";
|
||||||
import { CommandTreeItem } from "../../CommandTreeItem";
|
import { CommandTreeItem } from "../../CommandTreeItem";
|
||||||
import { CollectionTreeItem } from "../CollectionTreeItem";
|
import { CollectionTreeItem } from "../CollectionTreeItem";
|
||||||
import { RuleTreeItem } from "./RuleTreeItem";
|
import { RuleTreeItem } from "./RuleTreeItem";
|
||||||
|
|
||||||
export class RulesTreeItem extends AppwriteTreeItemBase<CollectionTreeItem> {
|
export class RulesTreeItem extends AwTreeItem<CollectionTreeItem> {
|
||||||
public readonly rules: Rule[];
|
public readonly rules: Rule[];
|
||||||
|
|
||||||
constructor(parent: CollectionTreeItem) {
|
constructor(parent: CollectionTreeItem) {
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
import { MarkdownString, ThemeIcon, TreeItem, TreeItemCollapsibleState } from "vscode";
|
import { MarkdownString, ThemeIcon, TreeItem, TreeItemCollapsibleState } from "vscode";
|
||||||
import { Function } from "../../appwrite";
|
import { Function } from "../../appwrite";
|
||||||
import { AppwriteTreeItemBase } from "../../ui/AppwriteTreeItemBase";
|
import { AwTreeItem } from "../common/AwTreeItem";
|
||||||
import { msToDate } from '../../utils/date';
|
import { msToDate } from '../../utils/date';
|
||||||
import { ExecutionsTreeItem } from './executions/ExecutionsTreeItem';
|
import { ExecutionsTreeItem } from './executions/ExecutionsTreeItem';
|
||||||
import { FunctionsTreeItemProvider } from './FunctionsTreeItemProvider';
|
import { FunctionsTreeItemProvider } from './FunctionsTreeItemProvider';
|
||||||
import { FunctionSettingsTreeItem } from './settings/FunctionSettingsTreeItem';
|
import { FunctionSettingsTreeItem } from './settings/FunctionSettingsTreeItem';
|
||||||
import { TagsTreeItem } from './tags/TagsTreeItem';
|
import { TagsTreeItem } from './tags/TagsTreeItem';
|
||||||
|
|
||||||
export class FunctionTreeItem extends AppwriteTreeItemBase {
|
export class FunctionTreeItem extends AwTreeItem {
|
||||||
constructor(public func: Function, public readonly provider: FunctionsTreeItemProvider) {
|
constructor(public func: Function, public readonly provider: FunctionsTreeItemProvider) {
|
||||||
super(undefined, func.name);
|
super(undefined, func.name);
|
||||||
this.tooltip = new MarkdownString(`ID: ${func.$id} \nLast updated: ${msToDate(func.dateUpdated)} \nCreated: ${msToDate(func.dateCreated)}`);
|
this.tooltip = new MarkdownString(`ID: ${func.$id} \nLast updated: ${msToDate(func.dateUpdated)} \nCreated: ${msToDate(func.dateCreated)}`);
|
||||||
|
|
|
@ -2,10 +2,11 @@ import * as vscode from "vscode";
|
||||||
import { client } from "../../client";
|
import { client } from "../../client";
|
||||||
import { Function, FunctionsList } from "../../appwrite";
|
import { Function, FunctionsList } from "../../appwrite";
|
||||||
import { AppwriteSDK } from "../../constants";
|
import { AppwriteSDK } from "../../constants";
|
||||||
import { AppwriteTreeItemBase } from "../../ui/AppwriteTreeItemBase";
|
import { AwTreeItem } from "../common/AwTreeItem";
|
||||||
import { ext } from "../../extensionVariables";
|
import { ext } from "../../extensionVariables";
|
||||||
import { EventEmitter, TreeItem } from "vscode";
|
import { EventEmitter, TreeItem } from "vscode";
|
||||||
import { FunctionTreeItem } from "./FunctionTreeItem";
|
import { FunctionTreeItem } from "./FunctionTreeItem";
|
||||||
|
import { AwParentTreeItem } from '../common/AwParentTreeItem';
|
||||||
|
|
||||||
export class FunctionsTreeItemProvider implements vscode.TreeDataProvider<vscode.TreeItem> {
|
export class FunctionsTreeItemProvider implements vscode.TreeDataProvider<vscode.TreeItem> {
|
||||||
private _onDidChangeTreeData: EventEmitter<TreeItem | undefined | void> = new EventEmitter<TreeItem | undefined | void>();
|
private _onDidChangeTreeData: EventEmitter<TreeItem | undefined | void> = new EventEmitter<TreeItem | undefined | void>();
|
||||||
|
@ -25,7 +26,7 @@ export class FunctionsTreeItemProvider implements vscode.TreeDataProvider<vscode
|
||||||
return element;
|
return element;
|
||||||
}
|
}
|
||||||
|
|
||||||
async getChildren(parent?: AppwriteTreeItemBase | TreeItem): Promise<vscode.TreeItem[]> {
|
async getChildren(parent?: AwTreeItem | TreeItem): Promise<vscode.TreeItem[]> {
|
||||||
if (client === undefined) {
|
if (client === undefined) {
|
||||||
return Promise.resolve([]);
|
return Promise.resolve([]);
|
||||||
}
|
}
|
||||||
|
@ -43,8 +44,8 @@ export class FunctionsTreeItemProvider implements vscode.TreeDataProvider<vscode
|
||||||
return [{ label: "No functions found" }];
|
return [{ label: "No functions found" }];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (parent instanceof AppwriteTreeItemBase) {
|
if (parent instanceof AwParentTreeItem) {
|
||||||
return parent.getChildren?.() ?? [];
|
return parent.getChildren();
|
||||||
}
|
}
|
||||||
|
|
||||||
return [];
|
return [];
|
||||||
|
|
|
@ -3,6 +3,7 @@ import { Execution, ExecutionStatus } from "../../../appwrite";
|
||||||
import { functionsClient } from "../../../client";
|
import { functionsClient } from "../../../client";
|
||||||
import { ext } from "../../../extensionVariables";
|
import { ext } from "../../../extensionVariables";
|
||||||
import { msToDate } from "../../../utils/date";
|
import { msToDate } from "../../../utils/date";
|
||||||
|
import { sleep } from '../../../utils/sleep';
|
||||||
import { ExecutionsTreeItem } from "./ExecutionsTreeItem";
|
import { ExecutionsTreeItem } from "./ExecutionsTreeItem";
|
||||||
|
|
||||||
const executionStatusIcons: Record<ExecutionStatus, ThemeIcon> = {
|
const executionStatusIcons: Record<ExecutionStatus, ThemeIcon> = {
|
||||||
|
@ -12,17 +13,11 @@ const executionStatusIcons: Record<ExecutionStatus, ThemeIcon> = {
|
||||||
failed: new ThemeIcon("circle-filled", new ThemeColor("testing.iconFailed")),
|
failed: new ThemeIcon("circle-filled", new ThemeColor("testing.iconFailed")),
|
||||||
};
|
};
|
||||||
|
|
||||||
function sleep(ms: number) {
|
|
||||||
return new Promise((resolve) => {
|
|
||||||
setTimeout(resolve, ms);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
export class ExecutionTreeItem extends TreeItem {
|
export class ExecutionTreeItem extends TreeItem {
|
||||||
public isAutoRefreshing: boolean = false;
|
public isAutoRefreshing: boolean = false;
|
||||||
private refreshCount: number = 0;
|
private refreshCount: number = 0;
|
||||||
|
|
||||||
constructor(public readonly parent: ExecutionsTreeItem, public readonly execution: Execution) {
|
constructor(public readonly parent: ExecutionsTreeItem, public execution: Execution) {
|
||||||
super(execution.$id);
|
super(execution.$id);
|
||||||
this.label = this.getLabel(execution);
|
this.label = this.getLabel(execution);
|
||||||
this.iconPath = executionStatusIcons[execution.status];
|
this.iconPath = executionStatusIcons[execution.status];
|
||||||
|
@ -31,7 +26,9 @@ export class ExecutionTreeItem extends TreeItem {
|
||||||
this.description = execution.trigger;
|
this.description = execution.trigger;
|
||||||
this.contextValue = this.getContextValue(execution);
|
this.contextValue = this.getContextValue(execution);
|
||||||
this.isAutoRefreshing = execution.status === "processing" || execution.status === "waiting";
|
this.isAutoRefreshing = execution.status === "processing" || execution.status === "waiting";
|
||||||
this.autoRefresh();
|
if (this.isAutoRefreshing) {
|
||||||
|
this.autoRefresh();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async autoRefresh(): Promise<void> {
|
async autoRefresh(): Promise<void> {
|
||||||
|
@ -47,12 +44,11 @@ export class ExecutionTreeItem extends TreeItem {
|
||||||
this.isAutoRefreshing = false;
|
this.isAutoRefreshing = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
this.execution = execution;
|
||||||
this.contextValue = this.getContextValue(execution);
|
this.contextValue = this.getContextValue(execution);
|
||||||
this.iconPath = executionStatusIcons[execution.status];
|
this.iconPath = executionStatusIcons[execution.status];
|
||||||
this.label = this.getLabel(execution);
|
this.label = this.getLabel(execution);
|
||||||
this.isAutoRefreshing = execution.status === "processing" || execution.status === "waiting";
|
this.isAutoRefreshing = execution.status === "processing" || execution.status === "waiting";
|
||||||
|
|
||||||
ext.tree?.functions?.refreshChild(this);
|
ext.tree?.functions?.refreshChild(this);
|
||||||
await sleep(1000);
|
await sleep(1000);
|
||||||
this.autoRefresh();
|
this.autoRefresh();
|
||||||
|
@ -60,11 +56,15 @@ export class ExecutionTreeItem extends TreeItem {
|
||||||
|
|
||||||
getLabel(execution: Execution): string {
|
getLabel(execution: Execution): string {
|
||||||
if (execution.status === "completed" || execution.status === "failed") {
|
if (execution.status === "completed" || execution.status === "failed") {
|
||||||
return `${this.getCreated(execution)} (${execution.time.toPrecision(2)}s)`;
|
return `${this.getCreated(execution)} (${this.getExecutionTime(execution)}s)`;
|
||||||
}
|
}
|
||||||
return `${this.getCreated(execution)} (${execution.status})`;
|
return `${this.getCreated(execution)} (${execution.status})`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getExecutionTime(execution: Execution): string {
|
||||||
|
return execution.time.toPrecision(2);
|
||||||
|
}
|
||||||
|
|
||||||
getContextValue(execution: Execution): string {
|
getContextValue(execution: Execution): string {
|
||||||
if (execution.status === "completed" || execution.status === "failed") {
|
if (execution.status === "completed" || execution.status === "failed") {
|
||||||
if (execution.stderr === "" && execution.stdout === "") {
|
if (execution.stderr === "" && execution.stdout === "") {
|
||||||
|
|
|
@ -1,11 +1,14 @@
|
||||||
import { ThemeIcon, TreeItem, TreeItemCollapsibleState } from "vscode";
|
import { ThemeIcon, TreeItem, TreeItemCollapsibleState } from "vscode";
|
||||||
import { Execution, ExecutionList } from '../../../appwrite';
|
import { Execution, ExecutionList } from '../../../appwrite';
|
||||||
import { functionsClient } from "../../../client";
|
import { functionsClient } from "../../../client";
|
||||||
import { AppwriteTreeItemBase } from '../../../ui/AppwriteTreeItemBase';
|
import { AwTreeItem } from '../../common/AwTreeItem';
|
||||||
import { ExecutionTreeItem } from './ExecutionTreeItem';
|
import { ExecutionTreeItem } from './ExecutionTreeItem';
|
||||||
import { FunctionTreeItem } from '../FunctionTreeItem';
|
import { FunctionTreeItem } from '../FunctionTreeItem';
|
||||||
|
import { ext } from '../../../extensionVariables';
|
||||||
|
|
||||||
export class ExecutionsTreeItem extends AppwriteTreeItemBase<FunctionTreeItem> {
|
const executionsToShow = 10;
|
||||||
|
|
||||||
|
export class ExecutionsTreeItem extends AwTreeItem<FunctionTreeItem> {
|
||||||
constructor(public readonly parent: FunctionTreeItem) {
|
constructor(public readonly parent: FunctionTreeItem) {
|
||||||
super(parent, "Executions");
|
super(parent, "Executions");
|
||||||
}
|
}
|
||||||
|
@ -14,8 +17,10 @@ export class ExecutionsTreeItem extends AppwriteTreeItemBase<FunctionTreeItem> {
|
||||||
if (!functionsClient) {
|
if (!functionsClient) {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
const executions: ExecutionList | undefined = await functionsClient.listExecutions(this.parent.func.$id, undefined, undefined, undefined, 'DESC');
|
const executions: ExecutionList | undefined = await functionsClient.listExecutions(this.parent.func.$id, undefined, executionsToShow, undefined, 'DESC');
|
||||||
const children = executions?.executions.map((execution: Execution) => new ExecutionTreeItem(this, execution)) ?? [new TreeItem('No exeuctions.')];
|
const children = executions?.executions.map((execution: Execution) => new ExecutionTreeItem(this, execution)) ?? [new TreeItem('No exeuctions.')];
|
||||||
|
ext.outputChannel.appendLog(`Found ${executions?.sum} executions`);
|
||||||
|
children.push(new TreeItem('View more'));
|
||||||
return children;
|
return children;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@ import { Function } from "../../../appwrite";
|
||||||
import { functionsClient } from "../../../client";
|
import { functionsClient } from "../../../client";
|
||||||
import { appwriteSystemEvents } from "../../../constants";
|
import { appwriteSystemEvents } from "../../../constants";
|
||||||
import { ext } from "../../../extensionVariables";
|
import { ext } from "../../../extensionVariables";
|
||||||
import { EnumEditableTreeItemBase } from "../../common/EnumEditableTreeItem";
|
import { EnumEditableTreeItemBase } from "../../common/editable/EnumEditableTreeItem";
|
||||||
import { FunctionSettingsTreeItem } from "./FunctionSettingsTreeItem";
|
import { FunctionSettingsTreeItem } from "./FunctionSettingsTreeItem";
|
||||||
|
|
||||||
export class EventsTreeItem extends EnumEditableTreeItemBase {
|
export class EventsTreeItem extends EnumEditableTreeItemBase {
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import { ThemeIcon, TreeItem, TreeItemCollapsibleState } from "vscode";
|
import { ThemeIcon, TreeItem, TreeItemCollapsibleState } from "vscode";
|
||||||
import { Function } from "../../../appwrite";
|
import { Function } from "../../../appwrite";
|
||||||
import { functionsClient } from "../../../client";
|
import { functionsClient } from "../../../client";
|
||||||
import { AppwriteTreeItemBase } from "../../../ui/AppwriteTreeItemBase";
|
import { AwTreeItem } from "../../common/AwTreeItem";
|
||||||
import { ChildTreeItem } from "../../ChildTreeItem";
|
import { ChildTreeItem } from "../../ChildTreeItem";
|
||||||
import { FunctionTreeItem } from "../FunctionTreeItem";
|
import { FunctionTreeItem } from "../FunctionTreeItem";
|
||||||
import { EventsTreeItem } from "./EventsTreeItem";
|
import { EventsTreeItem } from "./EventsTreeItem";
|
||||||
|
@ -10,7 +10,7 @@ import { ScheduleTreeItem } from "./ScheduleTreeItem";
|
||||||
import { TimeoutTreeItem } from "./TimeoutTreeItem";
|
import { TimeoutTreeItem } from "./TimeoutTreeItem";
|
||||||
import { VarsTreeItem } from "./VarsTreeItem";
|
import { VarsTreeItem } from "./VarsTreeItem";
|
||||||
|
|
||||||
export class FunctionSettingsTreeItem extends AppwriteTreeItemBase<FunctionTreeItem> {
|
export class FunctionSettingsTreeItem extends AwTreeItem<FunctionTreeItem> {
|
||||||
public readonly func: Function;
|
public readonly func: Function;
|
||||||
|
|
||||||
constructor(public readonly parent: FunctionTreeItem) {
|
constructor(public readonly parent: FunctionTreeItem) {
|
||||||
|
|
|
@ -2,7 +2,7 @@ import { InputBoxOptions, MarkdownString } from "vscode";
|
||||||
import { Function } from "../../../appwrite";
|
import { Function } from "../../../appwrite";
|
||||||
import { functionsClient } from "../../../client";
|
import { functionsClient } from "../../../client";
|
||||||
import { ext } from "../../../extensionVariables";
|
import { ext } from "../../../extensionVariables";
|
||||||
import { StringEditableTreeItemBase } from '../../common/StringEditableTreeItem';
|
import { StringEditableTreeItemBase } from '../../common/editable/StringEditableTreeItem';
|
||||||
import { FunctionSettingsTreeItem } from "./FunctionSettingsTreeItem";
|
import { FunctionSettingsTreeItem } from "./FunctionSettingsTreeItem";
|
||||||
|
|
||||||
const tooltip = "Function name";
|
const tooltip = "Function name";
|
||||||
|
|
|
@ -5,7 +5,7 @@ import { ext } from "../../../extensionVariables";
|
||||||
import cron from "cron-validate";
|
import cron from "cron-validate";
|
||||||
import { FunctionSettingsTreeItem } from "./FunctionSettingsTreeItem";
|
import { FunctionSettingsTreeItem } from "./FunctionSettingsTreeItem";
|
||||||
import cronstrue from "cronstrue";
|
import cronstrue from "cronstrue";
|
||||||
import { StringEditableTreeItemBase } from '../../common/StringEditableTreeItem';
|
import { StringEditableTreeItemBase } from '../../common/editable/StringEditableTreeItem';
|
||||||
|
|
||||||
export class ScheduleTreeItem extends StringEditableTreeItemBase {
|
export class ScheduleTreeItem extends StringEditableTreeItemBase {
|
||||||
private readonly func: Function;
|
private readonly func: Function;
|
||||||
|
|
|
@ -2,7 +2,7 @@ import { InputBoxOptions, MarkdownString } from "vscode";
|
||||||
import { Function } from "../../../appwrite";
|
import { Function } from "../../../appwrite";
|
||||||
import { functionsClient } from "../../../client";
|
import { functionsClient } from "../../../client";
|
||||||
import { ext } from "../../../extensionVariables";
|
import { ext } from "../../../extensionVariables";
|
||||||
import { StringEditableTreeItemBase } from "../../common/StringEditableTreeItem";
|
import { StringEditableTreeItemBase } from "../../common/editable/StringEditableTreeItem";
|
||||||
|
|
||||||
function isNumeric(str: string) {
|
function isNumeric(str: string) {
|
||||||
console.log("here");
|
console.log("here");
|
||||||
|
|
|
@ -2,7 +2,7 @@ import { InputBoxOptions, MarkdownString, window } from "vscode";
|
||||||
import { Function } from "../../../appwrite";
|
import { Function } from "../../../appwrite";
|
||||||
import { functionsClient } from "../../../client";
|
import { functionsClient } from "../../../client";
|
||||||
import { ext } from "../../../extensionVariables";
|
import { ext } from "../../../extensionVariables";
|
||||||
import { StringEditableTreeItemBase } from "../../common/StringEditableTreeItem";
|
import { StringEditableTreeItemBase } from "../../common/editable/StringEditableTreeItem";
|
||||||
import { VarsTreeItem } from "./VarsTreeItem";
|
import { VarsTreeItem } from "./VarsTreeItem";
|
||||||
|
|
||||||
const tooltip = "Environment var";
|
const tooltip = "Environment var";
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
import { TreeItem, TreeItemCollapsibleState } from "vscode";
|
import { TreeItem, TreeItemCollapsibleState } from "vscode";
|
||||||
import { Vars } from "../../../appwrite";
|
import { Vars } from "../../../appwrite";
|
||||||
import { AppwriteTreeItemBase } from "../../../ui/AppwriteTreeItemBase";
|
import { AwTreeItem } from "../../common/AwTreeItem";
|
||||||
import { FunctionSettingsTreeItem } from "./FunctionSettingsTreeItem";
|
import { FunctionSettingsTreeItem } from "./FunctionSettingsTreeItem";
|
||||||
import { VarTreeItem } from "./VarTreeItem";
|
import { VarTreeItem } from "./VarTreeItem";
|
||||||
|
|
||||||
export class VarsTreeItem extends AppwriteTreeItemBase<FunctionSettingsTreeItem> {
|
export class VarsTreeItem extends AwTreeItem<FunctionSettingsTreeItem> {
|
||||||
public readonly vars: Vars;
|
public readonly vars: Vars;
|
||||||
|
|
||||||
constructor(parent: FunctionSettingsTreeItem) {
|
constructor(parent: FunctionSettingsTreeItem) {
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
import { ThemeIcon, TreeItem, TreeItemCollapsibleState } from "vscode";
|
import { ThemeIcon, TreeItem, TreeItemCollapsibleState } from "vscode";
|
||||||
import { functionsClient } from "../../../client";
|
import { functionsClient } from "../../../client";
|
||||||
import { AppwriteTreeItemBase } from '../../../ui/AppwriteTreeItemBase';
|
import { AwParentTreeItem } from '../../common/AwParentTreeItem';
|
||||||
|
import { AwTreeItem } from '../../common/AwTreeItem';
|
||||||
import { FunctionTreeItem } from '../FunctionTreeItem';
|
import { FunctionTreeItem } from '../FunctionTreeItem';
|
||||||
import { TagTreeItem } from './TagTreeItem';
|
import { TagTreeItem } from './TagTreeItem';
|
||||||
|
|
||||||
export class TagsTreeItem extends AppwriteTreeItemBase<FunctionTreeItem> {
|
export class TagsTreeItem extends AwParentTreeItem {
|
||||||
constructor(public readonly parent: FunctionTreeItem) {
|
constructor(public readonly parent: FunctionTreeItem) {
|
||||||
super(parent, "Tags");
|
super(parent, "Tags");
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,9 @@
|
||||||
import dayjs = require('dayjs');
|
import dayjs = require("dayjs");
|
||||||
|
import utc = require("dayjs/plugin/utc");
|
||||||
|
import timezone = require("dayjs/plugin/timezone"); // dependent on utc plugin
|
||||||
|
dayjs.extend(utc);
|
||||||
|
dayjs.extend(timezone);
|
||||||
|
|
||||||
export function msToDate(ms: number): string {
|
export function msToDate(ms: number): string {
|
||||||
return dayjs(ms).format("LTS");
|
return dayjs(ms * 1000).tz("America/Chicago").format("LTS");
|
||||||
}
|
}
|
||||||
|
|
5
src/utils/sleep.ts
Normal file
5
src/utils/sleep.ts
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
export function sleep(ms: number): Promise<void> {
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
setTimeout(resolve, ms);
|
||||||
|
});
|
||||||
|
}
|
|
@ -2,8 +2,8 @@ import tar = require("tar");
|
||||||
import { Uri, window, workspace } from "vscode";
|
import { Uri, window, workspace } from "vscode";
|
||||||
import { ext } from "../extensionVariables";
|
import { ext } from "../extensionVariables";
|
||||||
import * as path from "path";
|
import * as path from "path";
|
||||||
import * as os from "os";
|
|
||||||
import * as fs from "fs";
|
import * as fs from "fs";
|
||||||
|
import { sleep } from './sleep';
|
||||||
|
|
||||||
export async function getTarReadStream(folder: Uri): Promise<string | undefined> {
|
export async function getTarReadStream(folder: Uri): Promise<string | undefined> {
|
||||||
try {
|
try {
|
||||||
|
@ -15,11 +15,14 @@ export async function getTarReadStream(folder: Uri): Promise<string | undefined>
|
||||||
window.showErrorMessage("No workspace open.");
|
window.showErrorMessage("No workspace open.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ext.outputChannel.appendLog(`Creating '${tarName}' in '${workspace.workspaceFolders?.[0].uri.fsPath}'...`);
|
ext.outputChannel.appendLog(`Creating '${tarName}' in '${workspace.workspaceFolders?.[0].uri.fsPath}'...`);
|
||||||
|
const tarFilePath = path.join(ext.context?.globalStorageUri.fsPath ?? '', tarName);
|
||||||
|
await workspace.fs.createDirectory(ext.context.globalStorageUri);
|
||||||
|
|
||||||
const tarFilePath = path.join(os.tmpdir(), tarName);
|
tar.create({ gzip: true, cwd: cwd, mode: 1777 }, [path.relative(cwd, folder.fsPath)]).pipe(fs.createWriteStream(tarFilePath));
|
||||||
|
|
||||||
tar.create({ gzip: true, cwd: cwd }, [path.relative(cwd, folder.fsPath)]).pipe(fs.createWriteStream(tarFilePath));
|
await sleep(500);
|
||||||
|
|
||||||
ext.outputChannel.appendLog(`Created ${tarFilePath}`);
|
ext.outputChannel.appendLog(`Created ${tarFilePath}`);
|
||||||
|
|
||||||
|
|
6
src/utils/types.d.ts
vendored
Normal file
6
src/utils/types.d.ts
vendored
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
import { Progress } from 'vscode';
|
||||||
|
|
||||||
|
export type ProgressMessage = Progress<{
|
||||||
|
message?: string | undefined;
|
||||||
|
increment?: number | undefined;
|
||||||
|
}>;
|
Loading…
Reference in a new issue