Basic functions create tag and create execution feature
This commit is contained in:
		
							parent
							
								
									b4e5fdcd20
								
							
						
					
					
						commit
						d57c1e9696
					
				
					 19 changed files with 564 additions and 4557 deletions
				
			
		
							
								
								
									
										4636
									
								
								package-lock.json
									
										
									
										generated
									
									
									
								
							
							
						
						
									
										4636
									
								
								package-lock.json
									
										
									
										generated
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							
							
								
								
									
										34
									
								
								package.json
									
										
									
									
									
								
							
							
						
						
									
										34
									
								
								package.json
									
										
									
									
									
								
							| 
						 | 
					@ -30,7 +30,9 @@
 | 
				
			||||||
        "onView:Users",
 | 
					        "onView:Users",
 | 
				
			||||||
        "onView:Database",
 | 
					        "onView:Database",
 | 
				
			||||||
        "onView:Health",
 | 
					        "onView:Health",
 | 
				
			||||||
        "onCommand:vscode-appwrite.AddProject"
 | 
					        "onView:Functions",
 | 
				
			||||||
 | 
					        "onCommand:vscode-appwrite.AddProject",
 | 
				
			||||||
 | 
					        "onCommand:vscode-appwrite.CreateTag"
 | 
				
			||||||
    ],
 | 
					    ],
 | 
				
			||||||
    "main": "./dist/extension.js",
 | 
					    "main": "./dist/extension.js",
 | 
				
			||||||
    "contributes": {
 | 
					    "contributes": {
 | 
				
			||||||
| 
						 | 
					@ -188,6 +190,16 @@
 | 
				
			||||||
                "command": "vscode-appwrite.removeProject",
 | 
					                "command": "vscode-appwrite.removeProject",
 | 
				
			||||||
                "title": "Remove project",
 | 
					                "title": "Remove project",
 | 
				
			||||||
                "icon": "$(trash)"
 | 
					                "icon": "$(trash)"
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                "command": "vscode-appwrite.CreateTag",
 | 
				
			||||||
 | 
					                "title": "Create function tag",
 | 
				
			||||||
 | 
					                "icon": "$(cloud-upload)"
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                "command": "vscode-appwrite.CreateExecution",
 | 
				
			||||||
 | 
					                "title": "Execute function",
 | 
				
			||||||
 | 
					                "icon": "$(play)"
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        ],
 | 
					        ],
 | 
				
			||||||
        "views": {
 | 
					        "views": {
 | 
				
			||||||
| 
						 | 
					@ -211,6 +223,10 @@
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    "id": "Projects",
 | 
					                    "id": "Projects",
 | 
				
			||||||
                    "name": "Projects"
 | 
					                    "name": "Projects"
 | 
				
			||||||
 | 
					                },
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    "id": "Functions",
 | 
				
			||||||
 | 
					                    "name": "Functions"
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            ]
 | 
					            ]
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
| 
						 | 
					@ -383,6 +399,18 @@
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    "command": "vscode-appwrite.removeProject",
 | 
					                    "command": "vscode-appwrite.removeProject",
 | 
				
			||||||
                    "when": "viewItem =~ /(appwriteProject)/"
 | 
					                    "when": "viewItem =~ /(appwriteProject)/"
 | 
				
			||||||
 | 
					                },
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    "command": "vscode-appwrite.CreateExecution",
 | 
				
			||||||
 | 
					                    "when": "viewItem =~ /(function)/",
 | 
				
			||||||
 | 
					                    "group": "inline"
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            ],
 | 
				
			||||||
 | 
					            "explorer/context": [
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    "command": "vscode-appwrite.CreateTag",
 | 
				
			||||||
 | 
					                    "when": "explorerResourceIsFolder == true",
 | 
				
			||||||
 | 
					                    "group": "appwrite@1"
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            ],
 | 
					            ],
 | 
				
			||||||
            "commandPalette": [
 | 
					            "commandPalette": [
 | 
				
			||||||
| 
						 | 
					@ -499,6 +527,7 @@
 | 
				
			||||||
        "@types/glob": "^7.1.3",
 | 
					        "@types/glob": "^7.1.3",
 | 
				
			||||||
        "@types/mocha": "^8.0.4",
 | 
					        "@types/mocha": "^8.0.4",
 | 
				
			||||||
        "@types/node": "^12.11.7",
 | 
					        "@types/node": "^12.11.7",
 | 
				
			||||||
 | 
					        "@types/tar": "^4.0.4",
 | 
				
			||||||
        "@types/vscode": "^1.55.0",
 | 
					        "@types/vscode": "^1.55.0",
 | 
				
			||||||
        "@typescript-eslint/eslint-plugin": "^4.14.1",
 | 
					        "@typescript-eslint/eslint-plugin": "^4.14.1",
 | 
				
			||||||
        "@typescript-eslint/parser": "^4.14.1",
 | 
					        "@typescript-eslint/parser": "^4.14.1",
 | 
				
			||||||
| 
						 | 
					@ -515,6 +544,7 @@
 | 
				
			||||||
    "dependencies": {
 | 
					    "dependencies": {
 | 
				
			||||||
        "dayjs": "^1.10.4",
 | 
					        "dayjs": "^1.10.4",
 | 
				
			||||||
        "fs-extra": "^9.1.0",
 | 
					        "fs-extra": "^9.1.0",
 | 
				
			||||||
        "node-appwrite": "^2.2.1"
 | 
					        "node-appwrite": "^2.2.1",
 | 
				
			||||||
 | 
					        "tar": "^6.1.0"
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										88
									
								
								src/appwrite.d.ts
									
										
									
									
										vendored
									
									
								
							
							
						
						
									
										88
									
								
								src/appwrite.d.ts
									
										
									
									
										vendored
									
									
								
							| 
						 | 
					@ -1,3 +1,6 @@
 | 
				
			||||||
 | 
					import { ReadStream } from 'fs';
 | 
				
			||||||
 | 
					import { Stream } from 'node:stream';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export type Token = {
 | 
					export type Token = {
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * Token ID.
 | 
					     * Token ID.
 | 
				
			||||||
| 
						 | 
					@ -287,7 +290,7 @@ export type Rule = {
 | 
				
			||||||
    list: string[];
 | 
					    list: string[];
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
interface Permissions {
 | 
					export type Permissions = {
 | 
				
			||||||
    read: string[];
 | 
					    read: string[];
 | 
				
			||||||
    write: string[];
 | 
					    write: string[];
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -361,6 +364,88 @@ export type StorageClient = {
 | 
				
			||||||
    getFile: (fileId: string) => Promise<any>;
 | 
					    getFile: (fileId: string) => Promise<any>;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type Vars = Record<string, any>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export type Function = {
 | 
				
			||||||
 | 
					  '$id': string;
 | 
				
			||||||
 | 
					  '$permissions': Permissions;
 | 
				
			||||||
 | 
					  name: string;
 | 
				
			||||||
 | 
					  dateCreated: number;
 | 
				
			||||||
 | 
					  dateUpdated: number;
 | 
				
			||||||
 | 
					  status: string;
 | 
				
			||||||
 | 
					  env: string;
 | 
				
			||||||
 | 
					  tag: string;
 | 
				
			||||||
 | 
					  vars: Vars;
 | 
				
			||||||
 | 
					  events: string[];
 | 
				
			||||||
 | 
					  schedule: string;
 | 
				
			||||||
 | 
					  scheduleNext: number;
 | 
				
			||||||
 | 
					  schedulePrevious: number;
 | 
				
			||||||
 | 
					  timeout: number;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export type FunctionsList = {
 | 
				
			||||||
 | 
					    sum: number;
 | 
				
			||||||
 | 
					    functions: Function[];
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export type Tag = {
 | 
				
			||||||
 | 
					  '$id': string;
 | 
				
			||||||
 | 
					  functionId: string;
 | 
				
			||||||
 | 
					  dateCreated: number;
 | 
				
			||||||
 | 
					  command: string;
 | 
				
			||||||
 | 
					  size: string;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export type TagList = {
 | 
				
			||||||
 | 
					    sum: number;
 | 
				
			||||||
 | 
					    tags: Tag[];
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export type ExecutionStatus = "waiting" | "processing" | "completed" | "failed";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export type Execution = {
 | 
				
			||||||
 | 
					  '$id': string;
 | 
				
			||||||
 | 
					  functionId: string;
 | 
				
			||||||
 | 
					  dateCreated: number;
 | 
				
			||||||
 | 
					  trigger: string;
 | 
				
			||||||
 | 
					  status: ExecutionStatus;
 | 
				
			||||||
 | 
					  exitCode: number;
 | 
				
			||||||
 | 
					  stdout: string;
 | 
				
			||||||
 | 
					  stderr: string;
 | 
				
			||||||
 | 
					  time: number;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export type ExecutionList = {
 | 
				
			||||||
 | 
					    sum: number;
 | 
				
			||||||
 | 
					    executions: Execution[];
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export type Search = {
 | 
				
			||||||
 | 
					    search?: string;
 | 
				
			||||||
 | 
					    limit?: number;
 | 
				
			||||||
 | 
					    offset?: number;
 | 
				
			||||||
 | 
					    orderType?: 'ASC' | 'DESC';
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export type FunctionsClient = {
 | 
				
			||||||
 | 
					    create: (name: string, execute: string[], env: string, vars?: Vars, events?: string[], schedule?: string, timeout?: number) => Promise<any>;
 | 
				
			||||||
 | 
					    list: (search?: string, offset?: number, limit?: number, orderType?: 'ASC' | 'DESC') => Promise<any>;
 | 
				
			||||||
 | 
					    get: (functionId: string) => Promise<any>;
 | 
				
			||||||
 | 
					    update: (functionId: string, name: string, execute: string, vars: Vars, events: string[], schedule?: string, timeout?: number) => Promise<any>;
 | 
				
			||||||
 | 
					    updateTag: (functionId: string, tagId: string) => Promise<any>;
 | 
				
			||||||
 | 
					    delete: (functionId: string) => Promise<any>;
 | 
				
			||||||
 | 
					    createTag: (id: string, command: string, code: ReadStream) => Promise<any>;
 | 
				
			||||||
 | 
					    listTags: (id: string, search?: string, limit?: number, offset?: number, orderType?: 'ASC' | 'DESC') => Promise<any>;
 | 
				
			||||||
 | 
					    getTag: (functionId: string, tagId: string) => Promise<any>;
 | 
				
			||||||
 | 
					    deleteTag: (functionId: string, tagId: string) => Promise<any>;
 | 
				
			||||||
 | 
					    createExecution: (functionId: string, data?: string) => Promise<any>;
 | 
				
			||||||
 | 
					    listExecutions: (functionId: string, search?: string, limit?: number, offset?: number, orderType?: 'ASC' | 'DESC') => Promise<any>;
 | 
				
			||||||
 | 
					    getExecution: (functionId: string, executionId: string) => Promise<any>;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export type SDK = {
 | 
					export type SDK = {
 | 
				
			||||||
    Client: new () => Client;
 | 
					    Client: new () => Client;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -368,4 +453,5 @@ export type SDK = {
 | 
				
			||||||
    Health: new (client: Client) => HealthClient;
 | 
					    Health: new (client: Client) => HealthClient;
 | 
				
			||||||
    Database: new (client: Client) => DatabaseClient;
 | 
					    Database: new (client: Client) => DatabaseClient;
 | 
				
			||||||
    Storage: new (client: Client) => StorageClient;
 | 
					    Storage: new (client: Client) => StorageClient;
 | 
				
			||||||
 | 
					    Functions: new (client: Client) => FunctionsClient;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										52
									
								
								src/appwrite/Functions.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										52
									
								
								src/appwrite/Functions.ts
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,52 @@
 | 
				
			||||||
 | 
					import { Client, Execution, ExecutionList, FunctionsClient, TagList, Vars } from "../appwrite";
 | 
				
			||||||
 | 
					import { AppwriteSDK } from '../constants';
 | 
				
			||||||
 | 
					import AppwriteCall from '../utils/AppwriteCall';
 | 
				
			||||||
 | 
					import { ReadStream } from 'node:fs';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export class Functions {
 | 
				
			||||||
 | 
					    private readonly functions: FunctionsClient;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    constructor(client: Client) {
 | 
				
			||||||
 | 
					        this.functions = new AppwriteSDK.Functions(client);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public async create(name: string, execute: string[], env: string, vars?: Vars, events?: string[], schedule?: string, timeout?: number): Promise<any> {
 | 
				
			||||||
 | 
					        return await AppwriteCall(this.functions.create(name, execute, env, vars, events, schedule, timeout));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    public async list(search?: string, offset?: number, limit?: number, orderType?: 'ASC' | 'DESC'): Promise<any> {
 | 
				
			||||||
 | 
					        return await AppwriteCall(this.functions.list(search, offset, limit, orderType));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    public async get(functionId: string): Promise<any> {
 | 
				
			||||||
 | 
					        return await AppwriteCall(this.functions.get(functionId));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    public async update(functionId: string, name: string, execute: string, vars: Vars, events: string[], schedule?: string, timeout?: number): Promise<any> {
 | 
				
			||||||
 | 
					        return await AppwriteCall(this.functions.update(functionId, name, execute, vars, events, schedule, timeout));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    public async updateTag(functionId: string, tagId: string): Promise<any> {
 | 
				
			||||||
 | 
					        return await AppwriteCall(this.functions.updateTag(functionId, tagId));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    public async delete(functionId: string): Promise<void> {
 | 
				
			||||||
 | 
					        return await AppwriteCall(this.functions.delete(functionId));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    public async createTag(functionId: string, command: string, code: ReadStream): Promise<any> {
 | 
				
			||||||
 | 
					        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> {
 | 
				
			||||||
 | 
					        return await AppwriteCall<TagList>(this.functions.listTags(id, search, offset, limit, orderType));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    public async getTag(functionId: string, tagId: string): Promise<any> {
 | 
				
			||||||
 | 
					        return await AppwriteCall(this.functions.getTag(functionId, tagId));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    public async deleteTag(functionId: string, tagId: string): Promise<void> {
 | 
				
			||||||
 | 
					        return await AppwriteCall(this.functions.deleteTag(functionId, tagId));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    public async createExecution(functionId: string, data?: string): Promise<any> {
 | 
				
			||||||
 | 
					        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> {
 | 
				
			||||||
 | 
					        return await AppwriteCall(this.functions.listExecutions(functionId, search, offset, limit, orderType));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    public async getExecution(functionId: string, executionId: string): Promise<Execution | undefined> {
 | 
				
			||||||
 | 
					        return await AppwriteCall(this.functions.getExecution(functionId, executionId));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -1,5 +1,6 @@
 | 
				
			||||||
import { Client } from "./appwrite";
 | 
					import { Client } from "./appwrite";
 | 
				
			||||||
import { Database } from "./appwrite/Database";
 | 
					import { Database } from "./appwrite/Database";
 | 
				
			||||||
 | 
					import { Functions } from './appwrite/Functions';
 | 
				
			||||||
import { Health } from "./appwrite/Health";
 | 
					import { Health } from "./appwrite/Health";
 | 
				
			||||||
import { Storage } from "./appwrite/Storage";
 | 
					import { Storage } from "./appwrite/Storage";
 | 
				
			||||||
import { Users } from "./appwrite/Users";
 | 
					import { Users } from "./appwrite/Users";
 | 
				
			||||||
| 
						 | 
					@ -12,6 +13,8 @@ export let usersClient: Users | undefined;
 | 
				
			||||||
export let healthClient: Health | undefined;
 | 
					export let healthClient: Health | undefined;
 | 
				
			||||||
export let databaseClient: Database | undefined;
 | 
					export let databaseClient: Database | undefined;
 | 
				
			||||||
export let storageClient: Storage | undefined;
 | 
					export let storageClient: Storage | undefined;
 | 
				
			||||||
 | 
					export let functionsClient: Functions | undefined;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function initAppwriteClient({ endpoint, projectId, secret, selfSigned }: AppwriteProjectConfiguration) {
 | 
					function initAppwriteClient({ endpoint, projectId, secret, selfSigned }: AppwriteProjectConfiguration) {
 | 
				
			||||||
    client = new AppwriteSDK.Client();
 | 
					    client = new AppwriteSDK.Client();
 | 
				
			||||||
| 
						 | 
					@ -22,6 +25,7 @@ function initAppwriteClient({ endpoint, projectId, secret, selfSigned }: Appwrit
 | 
				
			||||||
    healthClient = new Health(client);
 | 
					    healthClient = new Health(client);
 | 
				
			||||||
    databaseClient = new Database(client);
 | 
					    databaseClient = new Database(client);
 | 
				
			||||||
    storageClient = new Storage(client);
 | 
					    storageClient = new Storage(client);
 | 
				
			||||||
 | 
					    functionsClient = new Functions(client);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return client;
 | 
					    return client;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -36,4 +40,5 @@ export function createAppwriteClient(config?: AppwriteProjectConfiguration): voi
 | 
				
			||||||
    healthClient = undefined;
 | 
					    healthClient = undefined;
 | 
				
			||||||
    databaseClient = undefined;
 | 
					    databaseClient = undefined;
 | 
				
			||||||
    storageClient = undefined;
 | 
					    storageClient = undefined;
 | 
				
			||||||
 | 
					    functionsClient = undefined;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										10
									
								
								src/commands/functions/createExecution.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								src/commands/functions/createExecution.ts
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,10 @@
 | 
				
			||||||
 | 
					import { functionsClient } from '../../client';
 | 
				
			||||||
 | 
					import { ext } from '../../extensionVariables';
 | 
				
			||||||
 | 
					import { FunctionTreeItem } from '../../tree/functions/FunctionTreeItem';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export async function createExecution(functionTreeItem: FunctionTreeItem): Promise<void> {
 | 
				
			||||||
 | 
					    const func = functionTreeItem.func;
 | 
				
			||||||
 | 
					    ext.outputChannel.appendLog(`Creating execution for function ${func.name}`);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    await functionsClient?.createExecution(func.$id);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										14
									
								
								src/commands/functions/createTag.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								src/commands/functions/createTag.ts
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,14 @@
 | 
				
			||||||
 | 
					import { Uri } from 'vscode';
 | 
				
			||||||
 | 
					import { functionsClient } from '../../client';
 | 
				
			||||||
 | 
					import { getTarReadStream } from '../../utils/tar';
 | 
				
			||||||
 | 
					import { ext } from '../../extensionVariables';
 | 
				
			||||||
 | 
					export async function createTag(folder: Uri): Promise<void> {
 | 
				
			||||||
 | 
					    const buffer = await getTarReadStream(folder);
 | 
				
			||||||
 | 
					    if (buffer !== undefined) {
 | 
				
			||||||
 | 
					        try {
 | 
				
			||||||
 | 
					            await functionsClient?.createTag('60b1836a8e5d9', "python hello.py", buffer);
 | 
				
			||||||
 | 
					        } catch (e) {
 | 
				
			||||||
 | 
					            ext.outputChannel.appendLog("Creating tag error: " + e);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -25,6 +25,8 @@ import { viewUserPrefs } from "./users/viewUserPrefs";
 | 
				
			||||||
import { editPermission } from "./database/permissions/editPermission";
 | 
					import { editPermission } from "./database/permissions/editPermission";
 | 
				
			||||||
import { setActiveProject } from "./project/setActiveProject";
 | 
					import { setActiveProject } from "./project/setActiveProject";
 | 
				
			||||||
import { removeProject } from "./project/removeProject";
 | 
					import { removeProject } from "./project/removeProject";
 | 
				
			||||||
 | 
					import { createTag } from './functions/createTag';
 | 
				
			||||||
 | 
					import { createExecution } from './functions/createExecution';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class CommandRegistrar {
 | 
					class CommandRegistrar {
 | 
				
			||||||
    constructor(private readonly context: ExtensionContext) {}
 | 
					    constructor(private readonly context: ExtensionContext) {}
 | 
				
			||||||
| 
						 | 
					@ -98,4 +100,8 @@ export function registerCommands(context: ExtensionContext): void {
 | 
				
			||||||
    registerCommand("setActiveProject", setActiveProject, "all");
 | 
					    registerCommand("setActiveProject", setActiveProject, "all");
 | 
				
			||||||
    registerCommand("refreshProjects", undefined, "projects");
 | 
					    registerCommand("refreshProjects", undefined, "projects");
 | 
				
			||||||
    registerCommand("removeProject", removeProject, "all");
 | 
					    registerCommand("removeProject", removeProject, "all");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /** Functions **/
 | 
				
			||||||
 | 
					    registerCommand("CreateTag", createTag, "functions");
 | 
				
			||||||
 | 
					    registerCommand("CreateExecution", createExecution, "functions");
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -4,6 +4,7 @@ import { registerCommands } from "./commands/registerCommands";
 | 
				
			||||||
import { ext } from "./extensionVariables";
 | 
					import { ext } from "./extensionVariables";
 | 
				
			||||||
import { getActiveProjectConfiguration } from "./settings";
 | 
					import { getActiveProjectConfiguration } from "./settings";
 | 
				
			||||||
import { DatabaseTreeItemProvider } from "./tree/database/DatabaseTreeItemProvider";
 | 
					import { DatabaseTreeItemProvider } from "./tree/database/DatabaseTreeItemProvider";
 | 
				
			||||||
 | 
					import { FunctionsTreeItemProvider } from './tree/functions/FunctionsTreeItemProvider';
 | 
				
			||||||
import { HealthTreeItemProvider } from "./tree/health/HealthTreeItemProvider";
 | 
					import { HealthTreeItemProvider } from "./tree/health/HealthTreeItemProvider";
 | 
				
			||||||
import { ProjectsTreeItemProvider } from "./tree/projects/ProjectsTreeItemProvider";
 | 
					import { ProjectsTreeItemProvider } from "./tree/projects/ProjectsTreeItemProvider";
 | 
				
			||||||
import { StorageTreeItemProvider } from "./tree/storage/StorageTreeItemProvider";
 | 
					import { StorageTreeItemProvider } from "./tree/storage/StorageTreeItemProvider";
 | 
				
			||||||
| 
						 | 
					@ -16,12 +17,14 @@ export async function activate(context: vscode.ExtensionContext): Promise<void>
 | 
				
			||||||
    const databaseTreeItemProvider = new DatabaseTreeItemProvider();
 | 
					    const databaseTreeItemProvider = new DatabaseTreeItemProvider();
 | 
				
			||||||
    const storageTreeItemProvider = new StorageTreeItemProvider();
 | 
					    const storageTreeItemProvider = new StorageTreeItemProvider();
 | 
				
			||||||
    const projectsTreeItemProvider = new ProjectsTreeItemProvider();
 | 
					    const projectsTreeItemProvider = new ProjectsTreeItemProvider();
 | 
				
			||||||
 | 
					    const functionsTreeItemProvider = new FunctionsTreeItemProvider();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    vscode.window.registerTreeDataProvider("Users", userTreeItemProvider);
 | 
					    vscode.window.registerTreeDataProvider("Users", userTreeItemProvider);
 | 
				
			||||||
    vscode.window.registerTreeDataProvider("Health", healthTreeItemProvider);
 | 
					    vscode.window.registerTreeDataProvider("Health", healthTreeItemProvider);
 | 
				
			||||||
    vscode.window.registerTreeDataProvider("Database", databaseTreeItemProvider);
 | 
					    vscode.window.registerTreeDataProvider("Database", databaseTreeItemProvider);
 | 
				
			||||||
    vscode.window.registerTreeDataProvider("Storage", storageTreeItemProvider);
 | 
					    vscode.window.registerTreeDataProvider("Storage", storageTreeItemProvider);
 | 
				
			||||||
    vscode.window.registerTreeDataProvider("Projects", projectsTreeItemProvider);
 | 
					    vscode.window.registerTreeDataProvider("Projects", projectsTreeItemProvider);
 | 
				
			||||||
 | 
					    vscode.window.registerTreeDataProvider("Functions", functionsTreeItemProvider);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const activeProject = await getActiveProjectConfiguration();
 | 
					    const activeProject = await getActiveProjectConfiguration();
 | 
				
			||||||
    createAppwriteClient(activeProject);
 | 
					    createAppwriteClient(activeProject);
 | 
				
			||||||
| 
						 | 
					@ -35,6 +38,7 @@ export async function activate(context: vscode.ExtensionContext): Promise<void>
 | 
				
			||||||
        database: databaseTreeItemProvider,
 | 
					        database: databaseTreeItemProvider,
 | 
				
			||||||
        storage: storageTreeItemProvider,
 | 
					        storage: storageTreeItemProvider,
 | 
				
			||||||
        projects: projectsTreeItemProvider,
 | 
					        projects: projectsTreeItemProvider,
 | 
				
			||||||
 | 
					        functions: functionsTreeItemProvider
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    registerCommands(context);
 | 
					    registerCommands(context);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,5 +1,6 @@
 | 
				
			||||||
import { ExtensionContext } from "vscode";
 | 
					import { ExtensionContext } from "vscode";
 | 
				
			||||||
import { DatabaseTreeItemProvider } from './tree/database/DatabaseTreeItemProvider';
 | 
					import { DatabaseTreeItemProvider } from './tree/database/DatabaseTreeItemProvider';
 | 
				
			||||||
 | 
					import { FunctionsTreeItemProvider } from './tree/functions/FunctionsTreeItemProvider';
 | 
				
			||||||
import { HealthTreeItemProvider } from './tree/health/HealthTreeItemProvider';
 | 
					import { HealthTreeItemProvider } from './tree/health/HealthTreeItemProvider';
 | 
				
			||||||
import { ProjectsTreeItemProvider } from './tree/projects/ProjectsTreeItemProvider';
 | 
					import { ProjectsTreeItemProvider } from './tree/projects/ProjectsTreeItemProvider';
 | 
				
			||||||
import { StorageTreeItemProvider } from './tree/storage/StorageTreeItemProvider';
 | 
					import { StorageTreeItemProvider } from './tree/storage/StorageTreeItemProvider';
 | 
				
			||||||
| 
						 | 
					@ -12,12 +13,13 @@ export type AppwriteTree = {
 | 
				
			||||||
    database?: DatabaseTreeItemProvider;
 | 
					    database?: DatabaseTreeItemProvider;
 | 
				
			||||||
    storage?: StorageTreeItemProvider;
 | 
					    storage?: StorageTreeItemProvider;
 | 
				
			||||||
    projects?: ProjectsTreeItemProvider;
 | 
					    projects?: ProjectsTreeItemProvider;
 | 
				
			||||||
 | 
					    functions?: FunctionsTreeItemProvider;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export type Ext = {
 | 
					export type Ext = {
 | 
				
			||||||
    context?: ExtensionContext;
 | 
					    context?: ExtensionContext;
 | 
				
			||||||
    outputChannel?: AppwriteOutputChannel;
 | 
					    outputChannel: AppwriteOutputChannel;
 | 
				
			||||||
    tree?: AppwriteTree;
 | 
					    tree?: AppwriteTree;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const ext: Ext = {};
 | 
					export const ext: Ext = {} as Ext;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -41,11 +41,11 @@ export class DatabaseTreeItemProvider implements vscode.TreeDataProvider<vscode.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        const collectionsList = await AppwriteCall<CollectionsList, CollectionsList>(databaseSdk.listCollections());
 | 
					        const collectionsList = await AppwriteCall<CollectionsList, CollectionsList>(databaseSdk.listCollections());
 | 
				
			||||||
        if (collectionsList) {
 | 
					        if (collectionsList) {
 | 
				
			||||||
            const userTreeItems = collectionsList.collections.map((collection: Collection) => new CollectionTreeItem(collection, this)) ?? [];
 | 
					            const collectionTreeItems = collectionsList.collections.map((collection: Collection) => new CollectionTreeItem(collection, this)) ?? [];
 | 
				
			||||||
            const headerItem: vscode.TreeItem = {
 | 
					            const headerItem: vscode.TreeItem = {
 | 
				
			||||||
                label: `Total collections: ${collectionsList.sum}`,
 | 
					                label: `Total collections: ${collectionsList.sum}`,
 | 
				
			||||||
            };
 | 
					            };
 | 
				
			||||||
            return [headerItem, ...userTreeItems];
 | 
					            return [headerItem, ...collectionTreeItems];
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return [{ label: "No collections found" }];
 | 
					        return [{ label: "No collections found" }];
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										73
									
								
								src/tree/functions/ExecutionTreeItem.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										73
									
								
								src/tree/functions/ExecutionTreeItem.ts
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,73 @@
 | 
				
			||||||
 | 
					import dayjs = require('dayjs');
 | 
				
			||||||
 | 
					import { MarkdownString, ThemeColor, ThemeIcon, TreeItem } from "vscode";
 | 
				
			||||||
 | 
					import { Execution, ExecutionStatus } from "../../appwrite";
 | 
				
			||||||
 | 
					import { functionsClient } from "../../client";
 | 
				
			||||||
 | 
					import { ext } from "../../extensionVariables";
 | 
				
			||||||
 | 
					import { ExecutionsTreeItem } from "./ExecutionsTreeItem";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const executionStatusIcons: Record<ExecutionStatus, ThemeIcon> = {
 | 
				
			||||||
 | 
					    processing: new ThemeIcon("loading"),
 | 
				
			||||||
 | 
					    waiting: new ThemeIcon("circle-outline"),
 | 
				
			||||||
 | 
					    completed: new ThemeIcon("circle-filled", new ThemeColor("testing.iconPassed")),
 | 
				
			||||||
 | 
					    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 {
 | 
				
			||||||
 | 
					    public isAutoRefreshing: boolean = false;
 | 
				
			||||||
 | 
					    private refreshCount: number = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    constructor(public readonly parent: ExecutionsTreeItem, private readonly execution: Execution) {
 | 
				
			||||||
 | 
					        super(execution.$id);
 | 
				
			||||||
 | 
					        this.label = this.getLabel(execution);
 | 
				
			||||||
 | 
					        this.iconPath = executionStatusIcons[execution.status];
 | 
				
			||||||
 | 
					        const md = `Id: ${execution.$id}  \nCreated: ${this.getCreated(execution)}  \nTrigger: ${execution.trigger}`;
 | 
				
			||||||
 | 
					        this.tooltip = new MarkdownString(md);
 | 
				
			||||||
 | 
					        this.description = execution.trigger;
 | 
				
			||||||
 | 
					        this.isAutoRefreshing = execution.status === "processing" || execution.status === "waiting";
 | 
				
			||||||
 | 
					        this.autoRefresh();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    async autoRefresh(): Promise<void> {
 | 
				
			||||||
 | 
					        if (!this.isAutoRefreshing) {
 | 
				
			||||||
 | 
					            return;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        this.refreshCount++;
 | 
				
			||||||
 | 
					        ext.outputChannel.appendLog("Refreshing execution.");
 | 
				
			||||||
 | 
					        const execution = await functionsClient?.getExecution(this.parent.parent.func.$id, this.execution.$id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (!execution) {
 | 
				
			||||||
 | 
					            ext.outputChannel.appendLog("Execution is undefined");
 | 
				
			||||||
 | 
					            this.isAutoRefreshing = false;
 | 
				
			||||||
 | 
					            return;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        this.iconPath = executionStatusIcons[execution.status];
 | 
				
			||||||
 | 
					        this.label = this.getLabel(execution);
 | 
				
			||||||
 | 
					        this.isAutoRefreshing = execution.status === "processing" || execution.status === "waiting";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        ext.tree?.functions?.refreshChild(this);
 | 
				
			||||||
 | 
					        await sleep(1000);
 | 
				
			||||||
 | 
					        this.autoRefresh();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    getLabel(execution: Execution): string {
 | 
				
			||||||
 | 
					        if (execution.status === "completed") {
 | 
				
			||||||
 | 
					            return `${this.getCreated(execution)} (${execution.time.toPrecision(2)}s)`;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return `${this.getCreated(execution)} (${execution.status})`;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    getCreated(execution: Execution): string {
 | 
				
			||||||
 | 
					        return dayjs(execution.dateCreated).format("LTS");
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    contextValue = "tag";
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										27
									
								
								src/tree/functions/ExecutionsTreeItem.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								src/tree/functions/ExecutionsTreeItem.ts
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,27 @@
 | 
				
			||||||
 | 
					import { ThemeIcon, TreeItem, TreeItemCollapsibleState } from "vscode";
 | 
				
			||||||
 | 
					import { Execution, ExecutionList } from '../../appwrite';
 | 
				
			||||||
 | 
					import { functionsClient } from "../../client";
 | 
				
			||||||
 | 
					import { AppwriteTreeItemBase } from '../../ui/AppwriteTreeItemBase';
 | 
				
			||||||
 | 
					import { ExecutionTreeItem } from './ExecutionTreeItem';
 | 
				
			||||||
 | 
					import { FunctionTreeItem } from './FunctionTreeItem';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export class ExecutionsTreeItem extends AppwriteTreeItemBase<FunctionTreeItem> {
 | 
				
			||||||
 | 
					    constructor(public readonly parent: FunctionTreeItem) {
 | 
				
			||||||
 | 
					        super(parent, "Executions");
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public async getChildren(): Promise<TreeItem[]> {
 | 
				
			||||||
 | 
					        if (!functionsClient) {
 | 
				
			||||||
 | 
					            return [];
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        const executions: ExecutionList | undefined = await functionsClient.listExecutions(this.parent.func.$id, undefined, undefined, undefined, 'DESC');
 | 
				
			||||||
 | 
					        const children = executions?.executions.map((execution: Execution) => new ExecutionTreeItem(this, execution)) ?? [new TreeItem('No exeuctions.')];
 | 
				
			||||||
 | 
					        return children;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    collapsibleState = TreeItemCollapsibleState.Collapsed;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    contextValue = "executions";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    iconPath = new ThemeIcon("history");
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										26
									
								
								src/tree/functions/FunctionTreeItem.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								src/tree/functions/FunctionTreeItem.ts
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,26 @@
 | 
				
			||||||
 | 
					import { ThemeIcon, TreeItem, TreeItemCollapsibleState } from "vscode";
 | 
				
			||||||
 | 
					import { Function } from "../../appwrite";
 | 
				
			||||||
 | 
					import { AppwriteTreeItemBase } from "../../ui/AppwriteTreeItemBase";
 | 
				
			||||||
 | 
					import { ExecutionsTreeItem } from './ExecutionsTreeItem';
 | 
				
			||||||
 | 
					import { FunctionsTreeItemProvider } from './FunctionsTreeItemProvider';
 | 
				
			||||||
 | 
					import { TagsTreeItem } from './TagsTreeItem';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export class FunctionTreeItem extends AppwriteTreeItemBase {
 | 
				
			||||||
 | 
					    constructor(public func: Function, public readonly provider: FunctionsTreeItemProvider) {
 | 
				
			||||||
 | 
					        super(undefined, func.name);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public async getChildren(): Promise<TreeItem[]> {
 | 
				
			||||||
 | 
					        return [new TagsTreeItem(this), new ExecutionsTreeItem(this)];
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public async refresh(): Promise<void> {
 | 
				
			||||||
 | 
					        this.provider.refreshChild(this);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    collapsibleState = TreeItemCollapsibleState.Collapsed;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    contextValue = "function";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    iconPath = new ThemeIcon("symbol-event");
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										55
									
								
								src/tree/functions/FunctionsTreeItemProvider.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										55
									
								
								src/tree/functions/FunctionsTreeItemProvider.ts
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,55 @@
 | 
				
			||||||
 | 
					import * as vscode from "vscode";
 | 
				
			||||||
 | 
					import { client } from "../../client";
 | 
				
			||||||
 | 
					import { Function, FunctionsList } from "../../appwrite";
 | 
				
			||||||
 | 
					import { AppwriteSDK } from "../../constants";
 | 
				
			||||||
 | 
					import { AppwriteTreeItemBase } from "../../ui/AppwriteTreeItemBase";
 | 
				
			||||||
 | 
					import { ext } from "../../extensionVariables";
 | 
				
			||||||
 | 
					import { EventEmitter, TreeItem } from "vscode";
 | 
				
			||||||
 | 
					import { FunctionTreeItem } from "./FunctionTreeItem";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export class FunctionsTreeItemProvider implements vscode.TreeDataProvider<vscode.TreeItem> {
 | 
				
			||||||
 | 
					    private _onDidChangeTreeData: EventEmitter<TreeItem | undefined | void> = new EventEmitter<TreeItem | undefined | void>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    readonly onDidChangeTreeData: vscode.Event<vscode.TreeItem | undefined | void> = this._onDidChangeTreeData.event;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    refresh(): void {
 | 
				
			||||||
 | 
					        ext.outputChannel?.appendLine("Refreshing functions tree provider...");
 | 
				
			||||||
 | 
					        this._onDidChangeTreeData.fire();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    refreshChild(child: vscode.TreeItem): void {
 | 
				
			||||||
 | 
					        this._onDidChangeTreeData.fire(child);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    getTreeItem(element: vscode.TreeItem): vscode.TreeItem {
 | 
				
			||||||
 | 
					        return element;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    async getChildren(parent?: AppwriteTreeItemBase | TreeItem): Promise<vscode.TreeItem[]> {
 | 
				
			||||||
 | 
					        if (client === undefined) {
 | 
				
			||||||
 | 
					            return Promise.resolve([]);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (parent === undefined) {
 | 
				
			||||||
 | 
					            const functionsSdk = new AppwriteSDK.Functions(client);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            const list: FunctionsList = await functionsSdk.list();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (list) {
 | 
				
			||||||
 | 
					                const functionTreeItems = list.functions.map((func: Function) => new FunctionTreeItem(func, this)) ?? [];
 | 
				
			||||||
 | 
					                const headerItem: vscode.TreeItem = {
 | 
				
			||||||
 | 
					                    label: `Total functions: ${list.sum}`,
 | 
				
			||||||
 | 
					                };
 | 
				
			||||||
 | 
					                return [headerItem, ...functionTreeItems];
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return [{ label: "No functions found" }];
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (parent instanceof AppwriteTreeItemBase) {
 | 
				
			||||||
 | 
					            return parent.getChildren?.() ?? [];
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return [];
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										16
									
								
								src/tree/functions/TagTreeItem.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								src/tree/functions/TagTreeItem.ts
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,16 @@
 | 
				
			||||||
 | 
					import { ThemeIcon, TreeItem } from "vscode";
 | 
				
			||||||
 | 
					import { Tag } from '../../appwrite';
 | 
				
			||||||
 | 
					import { TagsTreeItem } from './TagsTreeItem';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export class TagTreeItem extends TreeItem {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    constructor(public readonly parent: TagsTreeItem, tag: Tag) {
 | 
				
			||||||
 | 
					        super(tag.$id);
 | 
				
			||||||
 | 
					        const func = parent.parent.func;
 | 
				
			||||||
 | 
					        const active = func.tag === tag.$id;
 | 
				
			||||||
 | 
					        this.label = `${tag.$id}${active ? ' (Active)' : ''}`;
 | 
				
			||||||
 | 
					        this.iconPath = new ThemeIcon(active ? 'circle-filled' : 'circle-outline');
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    contextValue = "tag";
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										25
									
								
								src/tree/functions/TagsTreeItem.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								src/tree/functions/TagsTreeItem.ts
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,25 @@
 | 
				
			||||||
 | 
					import { ThemeIcon, TreeItem, TreeItemCollapsibleState } from "vscode";
 | 
				
			||||||
 | 
					import { functionsClient } from "../../client";
 | 
				
			||||||
 | 
					import { AppwriteTreeItemBase } from '../../ui/AppwriteTreeItemBase';
 | 
				
			||||||
 | 
					import { FunctionTreeItem } from './FunctionTreeItem';
 | 
				
			||||||
 | 
					import { TagTreeItem } from './TagTreeItem';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export class TagsTreeItem extends AppwriteTreeItemBase<FunctionTreeItem> {
 | 
				
			||||||
 | 
					    constructor(public readonly parent: FunctionTreeItem) {
 | 
				
			||||||
 | 
					        super(parent, "Tags");
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public async getChildren(): Promise<TreeItem[]> {
 | 
				
			||||||
 | 
					        if (!functionsClient) {
 | 
				
			||||||
 | 
					            return [];
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        const tags = await functionsClient.listTags(this.parent.func.$id);
 | 
				
			||||||
 | 
					        return tags?.tags.sort((a, b) => b.dateCreated - a.dateCreated).map((tag) => new TagTreeItem(this, tag)) ?? [new TreeItem('No tags.')];
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    collapsibleState = TreeItemCollapsibleState.Collapsed;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    contextValue = "tags";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    iconPath = new ThemeIcon("tag");
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -10,7 +10,7 @@ export default function AppwriteCall<T, R = T>(
 | 
				
			||||||
): Promise<R | undefined> {
 | 
					): Promise<R | undefined> {
 | 
				
			||||||
    return promise.then(
 | 
					    return promise.then(
 | 
				
			||||||
        (successResp) => {
 | 
					        (successResp) => {
 | 
				
			||||||
            ext.outputChannel?.appendLog("Appwrite call success");
 | 
					            ext.outputChannel?.appendLog(`Appwrite call success:`);
 | 
				
			||||||
            if (onSuccess) {
 | 
					            if (onSuccess) {
 | 
				
			||||||
                return onSuccess((successResp as unknown) as T);
 | 
					                return onSuccess((successResp as unknown) as T);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										38
									
								
								src/utils/tar.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								src/utils/tar.ts
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,38 @@
 | 
				
			||||||
 | 
					import tar = require("tar");
 | 
				
			||||||
 | 
					import { Uri, window, workspace } from "vscode";
 | 
				
			||||||
 | 
					import { ext } from "../extensionVariables";
 | 
				
			||||||
 | 
					import * as path from "path";
 | 
				
			||||||
 | 
					import * as os from "os";
 | 
				
			||||||
 | 
					import * as fs from "fs";
 | 
				
			||||||
 | 
					import { ReadStream } from 'node:fs';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export async function getTarReadStream(folder: Uri): Promise<ReadStream | undefined> {
 | 
				
			||||||
 | 
					    try {
 | 
				
			||||||
 | 
					        const folderName = path.basename(folder.path);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        const tarName = `${folderName}.tar.gz`;
 | 
				
			||||||
 | 
					        const cwd = folder.fsPath;
 | 
				
			||||||
 | 
					        if (cwd === undefined) {
 | 
				
			||||||
 | 
					            window.showErrorMessage("No workspace open.");
 | 
				
			||||||
 | 
					            return;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        ext.outputChannel.appendLog(`Creating '${tarName}' in '${workspace.workspaceFolders?.[0].uri.fsPath}'...`);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        const tarFilePath = path.join(os.tmpdir(), tarName);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        tar.create({ gzip: true, cwd: cwd }, [path.relative(cwd, folder.fsPath)]).pipe(fs.createWriteStream(tarFilePath, { emitClose: true}));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        const stream = fs.createReadStream(tarFilePath);
 | 
				
			||||||
 | 
					        stream.on('close', () => {
 | 
				
			||||||
 | 
					            try {
 | 
				
			||||||
 | 
					                fs.unlinkSync(tarFilePath);
 | 
				
			||||||
 | 
					            } catch (e) {
 | 
				
			||||||
 | 
					                //
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					        return stream;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    } catch (e) {
 | 
				
			||||||
 | 
					        ext.outputChannel?.appendLog("Error creating tar.gz: " + e);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Loading…
	
	Add table
		
		Reference in a new issue