Compare commits
1 commit
main
...
alex/fixDe
Author | SHA1 | Date | |
---|---|---|---|
|
36a976765c |
44 changed files with 184 additions and 782 deletions
48
.github/ISSUE_TEMPLATE/bug.yaml
vendored
48
.github/ISSUE_TEMPLATE/bug.yaml
vendored
|
@ -1,48 +0,0 @@
|
|||
name: Bug Report
|
||||
description: File a bug report
|
||||
title: "[Bug] "
|
||||
labels: [bug]
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Thanks for taking the time to fill out this bug report!
|
||||
- type: textarea
|
||||
id: repro
|
||||
attributes:
|
||||
label: Reproduction steps
|
||||
description: "How do you trigger this bug? Please walk us through it step by step."
|
||||
value: |
|
||||
1.
|
||||
2.
|
||||
3.
|
||||
...
|
||||
render: bash
|
||||
validations:
|
||||
required: true
|
||||
- type: dropdown
|
||||
id: version
|
||||
attributes:
|
||||
label: Version
|
||||
description: What version of VS Code are you using?
|
||||
options:
|
||||
- Stable (Default)
|
||||
- Insiders
|
||||
validations:
|
||||
required: true
|
||||
- type: dropdown
|
||||
id: os
|
||||
attributes:
|
||||
label: What operating system are you seeing the problem on?
|
||||
multiple: true
|
||||
options:
|
||||
- All
|
||||
- Windows
|
||||
- macOS
|
||||
- Linux
|
||||
- type: textarea
|
||||
id: logs
|
||||
attributes:
|
||||
label: Relevant log output
|
||||
description: Please copy and paste any relevant log output. This will be automatically formatted into code, so no need for backticks.
|
||||
render: shell
|
1
.github/workflows/ciBuild.yml
vendored
1
.github/workflows/ciBuild.yml
vendored
|
@ -26,6 +26,7 @@ jobs:
|
|||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
- run: npm ci
|
||||
- run: npm run package
|
||||
- run: npx vsce package
|
||||
|
||||
- uses: actions/upload-artifact@v2
|
||||
|
|
15
CHANGELOG.md
15
CHANGELOG.md
|
@ -6,21 +6,6 @@ Check [Keep a Changelog](http://keepachangelog.com/) for recommendations on how
|
|||
|
||||
## [Unreleased]
|
||||
|
||||
## [0.1.3] - 2021-6-17
|
||||
## Added
|
||||
- New feature! JSON strings inside documents will now be automatically formatted as JSON when viewing documents. You can turn this feature off via the `appwrite.formatJsonStrings` setting.
|
||||
|
||||
## [0.1.2] - 2021-6-03
|
||||
## Added
|
||||
- Ability to set the `list`, `default` and `array` properties when creating a new collection. | [Issue #20](https://github.com/streamlux/vscode-appwrite/issues/20) | [PR #21](https://github.com/streamlux/vscode-appwrite/pull/21) | Thanks [@Maatteogekko](https://github.com/Maatteogekko)!
|
||||
|
||||
## [0.1.1] - 2021-5-31
|
||||
## Added
|
||||
- You can now easily create function tags from multiple places in the extension. [PR #19](https://github.com/streamlux/vscode-appwrite/pull/19)
|
||||
|
||||
## Fixed
|
||||
- Fixed an error when deleting a user. [Issue #17](https://github.com/streamlux/vscode-appwrite/issues/17) [PR #18](https://github.com/streamlux/vscode-appwrite/pull/18) Thanks [@aadarshadhakalg](https://github.com/aadarshadhakalg)!
|
||||
|
||||
## [0.1.0] - 2021-5-29
|
||||
|
||||
## Functions!
|
||||
|
|
10
README.md
10
README.md
|
@ -18,15 +18,7 @@ From [appwrite.io](https://appwrite.io)
|
|||
|
||||
### Connect to multiple Appwrite projects
|
||||
|
||||
<img src="media/features/projects/projectsView1.gif" height="600">
|
||||
|
||||
### Creating function tags with ease!
|
||||
|
||||
![Functions feature](media/features/functions/CreateTag.gif)
|
||||
|
||||
### Create and manage Appwrite cloud functions, upload tags, and view function output
|
||||
|
||||
<img src="media/features/functions/functionsOverview.png" height="500">
|
||||
![Mutliple projects](media/features/projects/projectsView1.gif)
|
||||
|
||||
### View database documents right inside VS Code.
|
||||
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 1.9 MiB |
Binary file not shown.
Before Width: | Height: | Size: 470 KiB |
2
package-lock.json
generated
2
package-lock.json
generated
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "vscode-appwrite",
|
||||
"version": "0.0.9",
|
||||
"version": "0.1.0",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
|
|
168
package.json
168
package.json
|
@ -2,7 +2,7 @@
|
|||
"name": "vscode-appwrite",
|
||||
"displayName": "Appwrite",
|
||||
"description": "Manage your Appwrite resources right from VS Code!",
|
||||
"version": "0.1.3",
|
||||
"version": "0.1.0",
|
||||
"engines": {
|
||||
"vscode": "^1.55.0"
|
||||
},
|
||||
|
@ -40,187 +40,151 @@
|
|||
{
|
||||
"command": "vscode-appwrite.Connect",
|
||||
"title": "Connect to Appwrite",
|
||||
"category": "Appwrite"
|
||||
"category": ""
|
||||
},
|
||||
{
|
||||
"command": "vscode-appwrite.CreateUser",
|
||||
"title": "Create user",
|
||||
"icon": "$(add)",
|
||||
"category": "Appwrite"
|
||||
"icon": "$(add)"
|
||||
},
|
||||
{
|
||||
"command": "vscode-appwrite.DeleteUser",
|
||||
"title": "Delete user",
|
||||
"icon": "$(trash)",
|
||||
"category": "Appwrite"
|
||||
"icon": "$(trash)"
|
||||
},
|
||||
{
|
||||
"command": "vscode-appwrite.GetUserLogs",
|
||||
"title": "Get user logs",
|
||||
"icon": "$(output)",
|
||||
"category": "Appwrite"
|
||||
"icon": "$(output)"
|
||||
},
|
||||
{
|
||||
"command": "vscode-appwrite.openUserInConsole",
|
||||
"title": "View user in Appwrite console",
|
||||
"icon": "$(link-external)",
|
||||
"category": "Appwrite"
|
||||
"icon": "$(link-external)"
|
||||
},
|
||||
{
|
||||
"command": "vscode-appwrite.viewUserPrefs",
|
||||
"title": "View user preferences",
|
||||
"icon": "$(json)",
|
||||
"category": "Appwrite"
|
||||
"icon": "$(json)"
|
||||
},
|
||||
{
|
||||
"command": "vscode-appwrite.refreshEntry",
|
||||
"title": "Refresh",
|
||||
"icon": "$(refresh)",
|
||||
"category": "Appwrite"
|
||||
"icon": "$(refresh)"
|
||||
},
|
||||
{
|
||||
"command": "vscode-appwrite.copyUserId",
|
||||
"title": "Copy user ID",
|
||||
"icon": "$(clippy)",
|
||||
"category": "Appwrite"
|
||||
"icon": "$(clippy)"
|
||||
},
|
||||
{
|
||||
"command": "vscode-appwrite.copyUserEmail",
|
||||
"title": "Copy user email",
|
||||
"icon": "$(clippy)",
|
||||
"category": "Appwrite"
|
||||
"icon": "$(clippy)"
|
||||
},
|
||||
{
|
||||
"command": "vscode-appwrite.refreshUsersList",
|
||||
"title": "Refresh users list",
|
||||
"icon": "$(refresh)",
|
||||
"category": "Appwrite"
|
||||
"icon": "$(refresh)"
|
||||
},
|
||||
{
|
||||
"command": "vscode-appwrite.OpenUsersDocumentation",
|
||||
"title": "Open documentation",
|
||||
"icon": "$(book)",
|
||||
"category": "Appwrite"
|
||||
"icon": "$(book)"
|
||||
},
|
||||
{
|
||||
"command": "vscode-appwrite.OpenDatabaseDocumentation",
|
||||
"title": "Open documentation",
|
||||
"icon": "$(book)",
|
||||
"category": "Appwrite"
|
||||
"icon": "$(book)"
|
||||
},
|
||||
{
|
||||
"command": "vscode-appwrite.viewDocumentAsJson",
|
||||
"title": "View as JSON",
|
||||
"category": "Appwrite"
|
||||
"title": "View as JSON"
|
||||
},
|
||||
{
|
||||
"command": "vscode-appwrite.viewCollectionAsJson",
|
||||
"title": "View collection as JSON",
|
||||
"category": "Appwrite"
|
||||
"title": "View collection as JSON"
|
||||
},
|
||||
{
|
||||
"command": "vscode-appwrite.refreshCollection",
|
||||
"title": "Refresh",
|
||||
"icon": "$(refresh)",
|
||||
"category": "Appwrite"
|
||||
"icon": "$(refresh)"
|
||||
},
|
||||
{
|
||||
"command": "vscode-appwrite.createRule",
|
||||
"title": "Create collection rule",
|
||||
"icon": "$(add)",
|
||||
"category": "Appwrite"
|
||||
"icon": "$(add)"
|
||||
},
|
||||
{
|
||||
"command": "vscode-appwrite.removeRule",
|
||||
"title": "Remove collection rule",
|
||||
"category": "Appwrite"
|
||||
"title": "Remove collection rule"
|
||||
},
|
||||
{
|
||||
"command": "vscode-appwrite.deleteDocument",
|
||||
"title": "Delete document",
|
||||
"category": "Appwrite"
|
||||
"title": "Delete document"
|
||||
},
|
||||
{
|
||||
"command": "vscode-appwrite.deleteCollection",
|
||||
"title": "Delete collection",
|
||||
"category": "Appwrite"
|
||||
"title": "Delete collection"
|
||||
},
|
||||
{
|
||||
"command": "vscode-appwrite.refreshCollectionsList",
|
||||
"title": "Refresh",
|
||||
"icon": "$(refresh)",
|
||||
"category": "Appwrite"
|
||||
"icon": "$(refresh)"
|
||||
},
|
||||
{
|
||||
"command": "vscode-appwrite.createCollection",
|
||||
"title": "Create collection",
|
||||
"icon": "$(add)",
|
||||
"category": "Appwrite"
|
||||
"icon": "$(add)"
|
||||
},
|
||||
{
|
||||
"command": "vscode-appwrite.createPermission",
|
||||
"title": "Create permission",
|
||||
"icon": "$(add)",
|
||||
"category": "Appwrite"
|
||||
"icon": "$(add)"
|
||||
},
|
||||
{
|
||||
"command": "vscode-appwrite.deletePermission",
|
||||
"title": "Delete permission",
|
||||
"icon": "$(trash)",
|
||||
"category": "Appwrite"
|
||||
"icon": "$(trash)"
|
||||
},
|
||||
{
|
||||
"command": "vscode-appwrite.editPermission",
|
||||
"title": "Edit permission",
|
||||
"icon": "$(edit)",
|
||||
"category": "Appwrite"
|
||||
"icon": "$(edit)"
|
||||
},
|
||||
{
|
||||
"command": "vscode-appwrite.refreshHealth",
|
||||
"title": "Refresh health",
|
||||
"icon": "$(refresh)",
|
||||
"category": "Appwrite"
|
||||
"icon": "$(refresh)"
|
||||
},
|
||||
{
|
||||
"command": "vscode-appwrite.openHealthDocumentation",
|
||||
"title": "Open health documentation",
|
||||
"icon": "$(book)",
|
||||
"category": "Appwrite"
|
||||
"icon": "$(book)"
|
||||
},
|
||||
{
|
||||
"command": "vscode-appwrite.refreshStorage",
|
||||
"title": "Refresh storage",
|
||||
"icon": "$(refresh)",
|
||||
"category": "Appwrite"
|
||||
"icon": "$(refresh)"
|
||||
},
|
||||
{
|
||||
"command": "vscode-appwrite.openStorageDocumentation",
|
||||
"title": "Open storage documentation",
|
||||
"icon": "$(book)",
|
||||
"category": "Appwrite"
|
||||
"icon": "$(book)"
|
||||
},
|
||||
{
|
||||
"command": "vscode-appwrite.addProject",
|
||||
"title": "Add Appwrite project",
|
||||
"icon": "$(plus)",
|
||||
"category": "Appwrite"
|
||||
"icon": "$(plus)"
|
||||
},
|
||||
{
|
||||
"command": "vscode-appwrite.setActiveProject",
|
||||
"title": "Set as active",
|
||||
"category": "Appwrite"
|
||||
"title": "Set as active"
|
||||
},
|
||||
{
|
||||
"command": "vscode-appwrite.refreshProjects",
|
||||
"title": "Refresh projects",
|
||||
"icon": "$(refresh)",
|
||||
"category": "Appwrite"
|
||||
},
|
||||
{
|
||||
"command": "vscode-appwrite.refreshFunctions",
|
||||
"title": "Refresh functions",
|
||||
"icon": "$(refresh)",
|
||||
"category": "Appwrite"
|
||||
"icon": "$(refresh)"
|
||||
},
|
||||
{
|
||||
"command": "vscode-appwrite.refreshFunctions",
|
||||
|
@ -230,115 +194,91 @@
|
|||
{
|
||||
"command": "vscode-appwrite.removeProject",
|
||||
"title": "Remove project",
|
||||
"icon": "$(trash)",
|
||||
"category": "Appwrite"
|
||||
"icon": "$(trash)"
|
||||
},
|
||||
{
|
||||
"command": "vscode-appwrite.CreateTag",
|
||||
"title": "Create function tag",
|
||||
"icon": "$(cloud-upload)",
|
||||
"shortTitle": "Create function tag",
|
||||
"category": "Appwrite"
|
||||
"icon": "$(cloud-upload)"
|
||||
},
|
||||
{
|
||||
"command": "vscode-appwrite.deleteTag",
|
||||
"title": "Delete tag",
|
||||
"icon": "$(trash)",
|
||||
"category": "Appwrite"
|
||||
"icon": "$(trash)"
|
||||
},
|
||||
{
|
||||
"command": "vscode-appwrite.CreateExecution",
|
||||
"title": "Execute",
|
||||
"category": "Appwrite"
|
||||
"title": "Execute"
|
||||
},
|
||||
{
|
||||
"command": "vscode-appwrite.activateTag",
|
||||
"title": "Activate",
|
||||
"category": "Appwrite"
|
||||
"title": "Activate"
|
||||
},
|
||||
{
|
||||
"command": "vscode-appwrite.editValue",
|
||||
"title": "Edit",
|
||||
"icon": "$(edit)",
|
||||
"category": "Appwrite"
|
||||
"icon": "$(edit)"
|
||||
},
|
||||
{
|
||||
"command": "vscode-appwrite.deleteFunction",
|
||||
"title": "Delete",
|
||||
"icon": "$(trash)",
|
||||
"category": "Appwrite"
|
||||
"icon": "$(trash)"
|
||||
},
|
||||
{
|
||||
"command": "vscode-appwrite.openFunctionsDocumentation",
|
||||
"title": "Open functions documentation",
|
||||
"icon": "$(book)",
|
||||
"category": "Appwrite"
|
||||
"icon": "$(book)"
|
||||
},
|
||||
{
|
||||
"command": "vscode-appwrite.createFunction",
|
||||
"title": "Create function",
|
||||
"icon": "$(add)",
|
||||
"category": "Appwrite"
|
||||
"icon": "$(add)"
|
||||
},
|
||||
{
|
||||
"command": "vscode-appwrite.createFunctionVar",
|
||||
"title": "Create variable",
|
||||
"icon": "$(add)",
|
||||
"category": "Appwrite"
|
||||
"icon": "$(add)"
|
||||
},
|
||||
{
|
||||
"command": "vscode-appwrite.deleteFunctionVar",
|
||||
"title": "Delete variable",
|
||||
"icon": "$(trash)",
|
||||
"category": "Appwrite"
|
||||
"icon": "$(trash)"
|
||||
},
|
||||
{
|
||||
"command": "vscode-appwrite.viewExecutionOutput",
|
||||
"title": "View execution stdout",
|
||||
"enablement": "viewItem =~ /^((execution|execution_outputOnly))$/",
|
||||
"category": "Appwrite"
|
||||
"enablement": "viewItem =~ /^((execution|execution_outputOnly))$/"
|
||||
},
|
||||
{
|
||||
"command": "vscode-appwrite.viewExecutionErrors",
|
||||
"title": "View execution stderr",
|
||||
"enablement": "viewItem =~ /^((execution|execution_errorOnly))$/",
|
||||
"category": "Appwrite"
|
||||
"enablement": "viewItem =~ /^((execution|execution_errorOnly))$/"
|
||||
},
|
||||
{
|
||||
"command": "vscode-appwrite.copyExecutionOutput",
|
||||
"title": "Copy execution stdout",
|
||||
"enablement": "viewItem =~ /^((execution|execution_outputOnly))$/",
|
||||
"category": "Appwrite"
|
||||
"enablement": "viewItem =~ /^((execution|execution_outputOnly))$/"
|
||||
},
|
||||
{
|
||||
"command": "vscode-appwrite.copyExecutionErrors",
|
||||
"title": "Copy execution stderr",
|
||||
"enablement": "viewItem =~ /^((execution|execution_errorOnly))$/",
|
||||
"category": "Appwrite"
|
||||
"enablement": "viewItem =~ /^((execution|execution_errorOnly))$/"
|
||||
},
|
||||
{
|
||||
"command": "vscode-appwrite.openExecutionsInBrowser",
|
||||
"title": "View executions in browser",
|
||||
"enablement": "viewItem =~ /^(executions)$/",
|
||||
"icon": "$(link-external)",
|
||||
"category": "Appwrite"
|
||||
"icon": "$(link-external)"
|
||||
},
|
||||
{
|
||||
"command": "vscode-appwrite.openFunctionTagsInBrowser",
|
||||
"title": "Open function tags in browser",
|
||||
"icon": "$(link-external)",
|
||||
"category": "Appwrite"
|
||||
"icon": "$(link-external)"
|
||||
},
|
||||
{
|
||||
"command": "vscode-appwrite.openFunctionSettingsInBrowser",
|
||||
"title": "Open function settings in browser",
|
||||
"icon": "$(link-external)",
|
||||
"category": "Appwrite"
|
||||
},
|
||||
{
|
||||
"command": "vscode-appwrite.viewMore",
|
||||
"title": "View more",
|
||||
"category": "Appwrite"
|
||||
"icon": "$(link-external)"
|
||||
}
|
||||
],
|
||||
"views": {
|
||||
|
@ -630,9 +570,6 @@
|
|||
}
|
||||
],
|
||||
"commandPalette": [
|
||||
{
|
||||
"command": "vscode-appwrite.CreateTag"
|
||||
},
|
||||
{
|
||||
"command": "vscode-appwrite.Connect"
|
||||
},
|
||||
|
@ -726,11 +663,6 @@
|
|||
"type": "string",
|
||||
"default": "",
|
||||
"markdownDescription": "Project id of the active project, see [docs](https://github.com/streamlux/vscode-appwrite/) for more information."
|
||||
},
|
||||
"appwrite.formatJsonStrings": {
|
||||
"type": "boolean",
|
||||
"default": true,
|
||||
"markdownDescription": "Format JSON strings when viewing documents"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
8
src/appwrite.d.ts
vendored
8
src/appwrite.d.ts
vendored
|
@ -276,7 +276,7 @@ export type CollectionsList = {
|
|||
collections: Collection[];
|
||||
};
|
||||
|
||||
export type CreatedRule = Omit<Rule, "$id" | "$collection">;
|
||||
export type CreatedRule = Omit<Rule, "$id" | "$collection" | "default" | "list">;
|
||||
|
||||
export type Rule = {
|
||||
$id: string;
|
||||
|
@ -284,10 +284,10 @@ export type Rule = {
|
|||
type: string;
|
||||
key: string;
|
||||
label: string;
|
||||
default?: any;
|
||||
required: boolean;
|
||||
default: string;
|
||||
array: boolean;
|
||||
list?: string[];
|
||||
required: boolean;
|
||||
list: string[];
|
||||
};
|
||||
|
||||
export type Permissions = {
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
import { Client, Execution, ExecutionList, FunctionsClient, FunctionsList, Tag, TagList, Vars } from "../appwrite";
|
||||
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 {
|
||||
public readonly functions: FunctionsClient;
|
||||
private readonly functions: FunctionsClient;
|
||||
|
||||
constructor(client: Client) {
|
||||
this.functions = new AppwriteSDK.Functions(client);
|
||||
|
@ -13,7 +13,7 @@ export class Functions {
|
|||
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<FunctionsList | undefined> {
|
||||
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> {
|
||||
|
@ -28,7 +28,7 @@ export class Functions {
|
|||
public async delete(functionId: string): Promise<void> {
|
||||
return await AppwriteCall(this.functions.delete(functionId));
|
||||
}
|
||||
public async createTag(functionId: string, command: string, code: ReadStream): Promise<Tag | undefined> {
|
||||
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> {
|
||||
|
@ -40,11 +40,11 @@ export class Functions {
|
|||
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<Execution | undefined> {
|
||||
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, limit, offset, orderType));
|
||||
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,4 +1,4 @@
|
|||
import { EditableTreeItem } from '../../tree/common/editable/SimpleEditableTreeItem';
|
||||
import { EditableTreeItem } from '../../tree/common/SimpleEditableTreeItem';
|
||||
|
||||
export async function editValue(treeItem: EditableTreeItem): Promise<void> {
|
||||
if (treeItem === undefined) {
|
||||
|
|
|
@ -1,5 +0,0 @@
|
|||
import { AppwriteTreeItemBase } from '../../ui/AppwriteTreeItemBase';
|
||||
|
||||
export async function viewMore(treeItem: AppwriteTreeItemBase<any>): Promise<void> {
|
||||
await treeItem.viewMore();
|
||||
}
|
|
@ -10,13 +10,15 @@ export async function createRule(rulesTreeItem: RulesTreeItem): Promise<void> {
|
|||
return;
|
||||
}
|
||||
|
||||
const ruleContext = await createRuleWizard();
|
||||
const collection = rulesTreeItem.parent.collection;
|
||||
const ruleContext = await createRuleWizard(collection);
|
||||
|
||||
if (ruleContext) {
|
||||
const newRule: CreatedRule = {
|
||||
...ruleContext,
|
||||
type: ruleContext.type,
|
||||
required: true,
|
||||
array: false,
|
||||
};
|
||||
|
||||
databaseClient.createRule(collection, newRule);
|
||||
|
|
|
@ -1,30 +1,8 @@
|
|||
import { workspace } from "vscode";
|
||||
import { DocumentTreeItem } from "../../tree/database/DocumentTreeItem";
|
||||
import { openReadOnlyJson } from "../../ui/openReadonlyContent";
|
||||
|
||||
function parseJSONString(str: string): { valid: boolean; value: any } {
|
||||
try {
|
||||
return { value: JSON.parse(str), valid: true };
|
||||
} catch (e) {
|
||||
return { value: str, valid: false };
|
||||
}
|
||||
}
|
||||
|
||||
export async function viewDocumentAsJson(documentTreeItem: DocumentTreeItem): Promise<void> {
|
||||
const document = documentTreeItem.document;
|
||||
const documentId = document["$id"];
|
||||
|
||||
const formatJsonStrings = workspace.getConfiguration("appwrite").get<Boolean>("formatJsonStrings");
|
||||
|
||||
if (formatJsonStrings) {
|
||||
Object.entries(document).forEach(([key, value]) => {
|
||||
if (typeof value === "string") {
|
||||
const result = parseJSONString(value);
|
||||
document[key] = result.value;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
const documentId = documentTreeItem.document["$id"];
|
||||
await openReadOnlyJson(
|
||||
{
|
||||
label: documentId,
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
import { Tag } from '../../appwrite';
|
||||
import { functionsClient } from '../../client';
|
||||
import { TagTreeItem } from '../../tree/functions/tags/TagTreeItem';
|
||||
|
||||
export async function activateTag(tagItem: TagTreeItem | Tag): Promise<void> {
|
||||
const tag = tagItem instanceof TagTreeItem ? tagItem.tag : tagItem;
|
||||
export async function activateTag(tagItem: TagTreeItem): Promise<void> {
|
||||
const tag = tagItem.tag;
|
||||
await functionsClient?.updateTag(tag.functionId, tag.$id);
|
||||
}
|
||||
|
|
|
@ -1,57 +1,10 @@
|
|||
import { window } from 'vscode';
|
||||
import { Execution } from '../../appwrite';
|
||||
import { functionsClient } from '../../client';
|
||||
import { ext } from '../../extensionVariables';
|
||||
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> {
|
||||
const func = functionTreeItem.func;
|
||||
await executeFunction(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);
|
||||
ext.outputChannel.appendLog(JSON.stringify(execution, null, 2));
|
||||
await ext.tree?.functions?.refresh();
|
||||
|
||||
if (execution === undefined) {
|
||||
return;
|
||||
}
|
||||
|
||||
execution = await waitForExecution(execution);
|
||||
ext.tree?.functions?.refresh();
|
||||
|
||||
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> {
|
||||
if (execution === undefined) {
|
||||
return;
|
||||
}
|
||||
if (execution.status === "processing" || execution.status === "waiting") {
|
||||
await sleep(5000);
|
||||
|
||||
ext.outputChannel.appendLog("Execution still ...");
|
||||
return await waitForExecution(await functionsClient?.getExecution(execution.functionId, execution.$id));
|
||||
}
|
||||
|
||||
return execution;
|
||||
ext.outputChannel.appendLog(`Creating execution for function ${func.name}`);
|
||||
|
||||
await functionsClient?.createExecution(func.$id);
|
||||
}
|
||||
|
|
|
@ -1,164 +1,41 @@
|
|||
import { ProgressLocation, QuickPickItem, Uri, window, workspace } from "vscode";
|
||||
import { functionsClient } from "../../client";
|
||||
import { ProgressLocation, Uri, window } from "vscode";
|
||||
import { functionsClient, storageClient } from "../../client";
|
||||
import { getTarReadStream } from "../../utils/tar";
|
||||
import { ext } from "../../extensionVariables";
|
||||
import * as fs from "fs";
|
||||
import { TagsTreeItem } from "../../tree/functions/tags/TagsTreeItem";
|
||||
import { selectWorkspaceFolder } from "../../utils/workspace";
|
||||
import { ProgressMessage } from "../../utils/types";
|
||||
import { Tag } from "../../appwrite";
|
||||
import { activateTag } from "./activateTag";
|
||||
|
||||
export async function createTag(item?: TagsTreeItem | Uri): Promise<void> {
|
||||
export async function createTag(item: TagsTreeItem | Uri): Promise<void> {
|
||||
if (item instanceof Uri) {
|
||||
const functions = await functionsClient?.list();
|
||||
if (functions === undefined) {
|
||||
return;
|
||||
}
|
||||
const pick = await window.showQuickPick(
|
||||
functions.functions.map<QuickPickItem>(
|
||||
(func): QuickPickItem => ({ label: func.name, description: func.env, detail: func.$id })
|
||||
),
|
||||
{ placeHolder: "Select a function to create tag" }
|
||||
);
|
||||
if (pick === undefined || pick.detail === undefined) {
|
||||
return;
|
||||
}
|
||||
const tags = await functionsClient?.listTags(pick.detail);
|
||||
let value;
|
||||
if (tags && tags.tags.length > 0) {
|
||||
value = tags.tags[tags.tags.length - 1].command;
|
||||
}
|
||||
const command = await window.showInputBox({ value, prompt: "Command to run your code" });
|
||||
if (command === undefined) {
|
||||
return;
|
||||
}
|
||||
const tag = await window.withProgress(
|
||||
{ location: ProgressLocation.Notification, title: "Creating tag..." },
|
||||
async (progress, _token) => {
|
||||
if (pick.detail === undefined) {
|
||||
return;
|
||||
}
|
||||
return await createTagFromUri(pick.detail, command, item, progress);
|
||||
}
|
||||
);
|
||||
if (tag) {
|
||||
await tagNotification(tag);
|
||||
}
|
||||
|
||||
window.withProgress({ location: ProgressLocation.Notification, title: "Creating tag..." }, async (_progress, _token) => {
|
||||
await createTagFromUri(item);
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
if (item instanceof TagsTreeItem) {
|
||||
const func = item.parent.func;
|
||||
const folder = await selectWorkspaceFolder("Select folder of your function code.");
|
||||
if (folder === undefined || folder === "") {
|
||||
return;
|
||||
}
|
||||
const tags = await functionsClient?.listTags(func.$id);
|
||||
let value;
|
||||
if (tags && tags.tags.length > 0) {
|
||||
value = tags.tags[tags.tags.length - 1].command;
|
||||
}
|
||||
const command = await window.showInputBox({ value, prompt: "Command to run your code" });
|
||||
if (command === undefined) {
|
||||
return;
|
||||
}
|
||||
const tag = await window.withProgress(
|
||||
{ location: ProgressLocation.Notification, title: "Creating tag..." },
|
||||
async (progress, _token) => {
|
||||
return await createTagFromUri(func.$id, command, Uri.parse(folder), progress);
|
||||
}
|
||||
);
|
||||
|
||||
if (tag) {
|
||||
await tagNotification(tag);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (item === undefined) {
|
||||
const functions = await functionsClient?.list();
|
||||
if (functions === undefined) {
|
||||
return;
|
||||
}
|
||||
const pick = await window.showQuickPick(
|
||||
functions.functions.map<QuickPickItem>(
|
||||
(func): QuickPickItem => ({ label: func.name, description: func.env, detail: func.$id })
|
||||
),
|
||||
{ placeHolder: "Select a function to create tag" }
|
||||
);
|
||||
if (pick === undefined || pick.detail === undefined) {
|
||||
return;
|
||||
}
|
||||
const funcId = pick.detail;
|
||||
const folder = await selectWorkspaceFolder("Select folder of your function code.");
|
||||
const tags = await functionsClient?.listTags(funcId);
|
||||
let value;
|
||||
if (tags && tags.tags.length > 0) {
|
||||
value = tags.tags[tags.tags.length - 1].command;
|
||||
}
|
||||
const command = await window.showInputBox({ value, prompt: "Command to run your code" });
|
||||
if (command === undefined) {
|
||||
return;
|
||||
}
|
||||
const tag = await window.withProgress(
|
||||
{ location: ProgressLocation.Notification, title: "Creating tag..." },
|
||||
async (progress, _token) => {
|
||||
return await createTagFromUri(funcId, command, Uri.parse(folder), progress);
|
||||
}
|
||||
);
|
||||
|
||||
if (tag) {
|
||||
await tagNotification(tag);
|
||||
return;
|
||||
}
|
||||
console.log(folder);
|
||||
window.withProgress({ location: ProgressLocation.Notification, title: "Creating tag..." }, async (_progress, _token) => {
|
||||
await createTagFromUri(Uri.parse(folder));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
async function createTagFromUri(functionId: string, command: string, uri: Uri, progress: ProgressMessage): Promise<Tag | undefined> {
|
||||
progress.report({ message: "Creating tarball", increment: 10 });
|
||||
|
||||
async function createTagFromUri(uri: Uri): Promise<void> {
|
||||
const tarFilePath = await getTarReadStream(uri);
|
||||
if (functionsClient === undefined) {
|
||||
return;
|
||||
}
|
||||
|
||||
let tarFilePath;
|
||||
try {
|
||||
tarFilePath = await getTarReadStream(uri);
|
||||
} catch (e) {
|
||||
window.showErrorMessage("Error creating tar file.\n" + e);
|
||||
return;
|
||||
}
|
||||
if (tarFilePath === undefined) {
|
||||
window.showErrorMessage("Failed to create tar file.");
|
||||
ext.outputChannel.appendLog("Failed to create tar file.");
|
||||
ext.outputChannel.appendLog("Error creating tar file.");
|
||||
return;
|
||||
}
|
||||
// somehow makes the upload work
|
||||
await workspace.fs.readFile(Uri.file(tarFilePath));
|
||||
progress.report({ message: "Uploading tag", increment: 60 });
|
||||
try {
|
||||
return await functionsClient.createTag(functionId, command, fs.createReadStream(tarFilePath));
|
||||
await functionsClient.createTag("60b1836a8e5d9", "python ./hello.py", fs.createReadStream(tarFilePath));
|
||||
await storageClient?.createFile(fs.createReadStream(tarFilePath));
|
||||
} catch (e) {
|
||||
ext.outputChannel.appendLog("Creating tag error: " + e);
|
||||
}
|
||||
}
|
||||
|
||||
async function tagNotification(tag: Tag): Promise<void> {
|
||||
ext.tree?.functions?.refresh();
|
||||
if (tag) {
|
||||
const action = await window.showInformationMessage(
|
||||
`Successfully created tag with size ${tag.size}B.`,
|
||||
"Activate tag",
|
||||
"View in console"
|
||||
);
|
||||
if (action === "Activate tag") {
|
||||
await activateTag(tag);
|
||||
}
|
||||
if (action === "View in console") {
|
||||
//
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,16 +1,11 @@
|
|||
import { Execution } from '../../appwrite';
|
||||
import { ExecutionTreeItem } from "../../tree/functions/executions/ExecutionTreeItem";
|
||||
import { openReadOnlyContent } from "../../ui/openReadonlyContent";
|
||||
|
||||
export async function viewExecutionErrors(executionItem: ExecutionTreeItem | Execution): Promise<void> {
|
||||
export async function viewExecutionErrors(executionItem: ExecutionTreeItem): Promise<void> {
|
||||
if (executionItem === undefined) {
|
||||
return;
|
||||
}
|
||||
|
||||
let execution = executionItem as Execution;
|
||||
|
||||
if (executionItem instanceof ExecutionTreeItem) {
|
||||
execution = executionItem.execution;
|
||||
}
|
||||
await openReadOnlyContent({ label: `Execution stderr`, fullId: `${execution.$id}-errors.txt` }, execution.stderr, '.txt');
|
||||
const execution = executionItem.execution;
|
||||
await openReadOnlyContent({ label: `${executionItem.parent.parent.func.name} execution stderr`, fullId: `${execution.$id}-errors.txt` }, execution.stderr, '.txt');
|
||||
}
|
||||
|
|
|
@ -1,19 +1,11 @@
|
|||
import { Execution } from '../../appwrite';
|
||||
import { ExecutionTreeItem } from "../../tree/functions/executions/ExecutionTreeItem";
|
||||
import { openReadOnlyContent } from "../../ui/openReadonlyContent";
|
||||
|
||||
export async function viewExecutionOutput(executionItem: ExecutionTreeItem | Execution): Promise<void> {
|
||||
export async function viewExecutionOutput(executionItem: ExecutionTreeItem): Promise<void> {
|
||||
if (executionItem === undefined) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
let execution = executionItem as Execution;
|
||||
|
||||
if (executionItem instanceof ExecutionTreeItem) {
|
||||
execution = executionItem.execution;
|
||||
}
|
||||
console.log(execution.dateCreated);
|
||||
|
||||
await openReadOnlyContent({ label: `Execution stdout`, fullId: `${execution.$id}-output.txt` }, execution.stdout, '.txt');
|
||||
const execution = executionItem.execution;
|
||||
await openReadOnlyContent({ label: `${executionItem.parent.parent.func.name} execution stdout`, fullId: `${execution.$id}-output.txt` }, execution.stdout, '.txt');
|
||||
}
|
||||
|
|
|
@ -42,8 +42,6 @@ import { openExecutionsInBrowser } from './functions/openExecutionsInBrowser';
|
|||
import { openFunctionSettingsInBrowser } from './functions/openFunctionSettingsInBrowser';
|
||||
import { openFunctionTagsInBrowser } from './functions/openFunctionTagsInBrowser';
|
||||
|
||||
import { viewMore } from './common/viewMore';
|
||||
|
||||
class CommandRegistrar {
|
||||
constructor(private readonly context: ExtensionContext) {}
|
||||
|
||||
|
@ -76,7 +74,6 @@ export function registerCommands(context: ExtensionContext): void {
|
|||
|
||||
/** Common **/
|
||||
registerCommand("editValue", editValue);
|
||||
registerCommand("viewMore", viewMore);
|
||||
|
||||
/** General **/
|
||||
registerCommand("Connect", connectAppwrite, "all");
|
||||
|
|
|
@ -17,7 +17,7 @@ export type AppwriteTree = {
|
|||
};
|
||||
|
||||
export type Ext = {
|
||||
context: ExtensionContext;
|
||||
context?: ExtensionContext;
|
||||
outputChannel: AppwriteOutputChannel;
|
||||
tree?: AppwriteTree;
|
||||
};
|
||||
|
|
|
@ -1,13 +0,0 @@
|
|||
import { TreeItem } from "vscode";
|
||||
|
||||
export abstract class EditableTreeItemBase<T> extends TreeItem {
|
||||
public abstract setValue(value: T): Promise<void>;
|
||||
|
||||
constructor(contextValuePrefix: string, public readonly value: T, description?: string) {
|
||||
super(typeof value === "string" ? value : "No label");
|
||||
this.contextValue = `editable_${contextValuePrefix}`;
|
||||
this.description = description ?? contextValuePrefix;
|
||||
}
|
||||
|
||||
public abstract prompt(): Promise<void>;
|
||||
}
|
|
@ -1,38 +0,0 @@
|
|||
import { QuickPickItem, QuickPickOptions, window } from "vscode";
|
||||
import { EditableTreeItemBase } from "./EditableTreeItemBase";
|
||||
|
||||
export abstract class EnumEditableTreeItemBase extends EditableTreeItemBase<string[]> {
|
||||
public abstract options: string[] | QuickPickItem[];
|
||||
|
||||
public quickPickOptions: QuickPickOptions;
|
||||
|
||||
constructor(contextValuePrefix: string, public readonly value: string[], description?: string) {
|
||||
super(contextValuePrefix, value, description);
|
||||
this.quickPickOptions = {};
|
||||
}
|
||||
|
||||
public async prompt(): Promise<void> {
|
||||
|
||||
const value = await window.showQuickPick(
|
||||
this.options.map<QuickPickItem>((option: QuickPickItem | string): QuickPickItem => {
|
||||
if (typeof option === "string") {
|
||||
return { label: option, picked: this.value.includes(option) };
|
||||
}
|
||||
const picked = this.value.includes(option.label);
|
||||
return { ...option, picked, alwaysShow: picked };
|
||||
}).sort((a, b) => {
|
||||
if (a.picked) {
|
||||
return -1;
|
||||
}
|
||||
if (b.picked) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}),
|
||||
{ ...this.quickPickOptions, canPickMany: true }
|
||||
);
|
||||
if (value !== undefined) {
|
||||
this.setValue(value.map((item) => item.label));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,18 +0,0 @@
|
|||
import { TreeItem, window } from "vscode";
|
||||
|
||||
export class EditableTreeItem extends TreeItem {
|
||||
public readonly setValue: (value: string) => Promise<void>;
|
||||
|
||||
constructor(label: string, contextValuePrefix: string, public readonly value: string, setValue: (value: string) => Promise<void>) {
|
||||
super(label);
|
||||
this.setValue = setValue;
|
||||
this.contextValue = `editable_${contextValuePrefix}`;
|
||||
}
|
||||
|
||||
public async prompt(): Promise<void> {
|
||||
const value = await window.showInputBox({ value: this.value });
|
||||
if (value !== undefined) {
|
||||
this.setValue(value);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,22 +0,0 @@
|
|||
import { InputBoxOptions, window } from "vscode";
|
||||
import { EditableTreeItemBase } from "./EditableTreeItemBase";
|
||||
|
||||
export abstract class StringEditableTreeItemBase extends EditableTreeItemBase<string> {
|
||||
public abstract setValue(value: string): Promise<void>;
|
||||
public inputBoxOptions: InputBoxOptions;
|
||||
|
||||
constructor(contextValuePrefix: string, public readonly value: string, description?: string) {
|
||||
super(contextValuePrefix, value, description);
|
||||
|
||||
this.inputBoxOptions = {
|
||||
prompt: description,
|
||||
};
|
||||
}
|
||||
|
||||
public async prompt(): Promise<void> {
|
||||
const value = await window.showInputBox({ value: this.value, ...this.inputBoxOptions });
|
||||
if (value !== undefined) {
|
||||
this.setValue(value);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -4,8 +4,8 @@ import AppwriteCall from "../../utils/AppwriteCall";
|
|||
import { Collection, CollectionsList } from "../../appwrite";
|
||||
import { CollectionTreeItem } from "./CollectionTreeItem";
|
||||
import { AppwriteSDK } from "../../constants";
|
||||
import { AppwriteTreeItemBase } from "../../ui/AppwriteTreeItemBase";
|
||||
import { ext } from '../../extensionVariables';
|
||||
import { AppwriteTreeItemBase } from '../../ui/AppwriteTreeItemBase';
|
||||
|
||||
export class DatabaseTreeItemProvider implements vscode.TreeDataProvider<vscode.TreeItem> {
|
||||
private _onDidChangeTreeData: vscode.EventEmitter<vscode.TreeItem | undefined | void> = new vscode.EventEmitter<
|
||||
|
@ -34,7 +34,7 @@ export class DatabaseTreeItemProvider implements vscode.TreeDataProvider<vscode.
|
|||
}
|
||||
|
||||
if (parent instanceof AppwriteTreeItemBase) {
|
||||
return await parent.getChildren?.() ?? [];
|
||||
return parent.getChildren?.() ?? [];
|
||||
}
|
||||
|
||||
const databaseSdk = new AppwriteSDK.Database(client);
|
||||
|
|
|
@ -44,7 +44,7 @@ export class FunctionsTreeItemProvider implements vscode.TreeDataProvider<vscode
|
|||
}
|
||||
|
||||
if (parent instanceof AppwriteTreeItemBase) {
|
||||
return await parent.getChildren?.() ?? [];
|
||||
return parent.getChildren?.() ?? [];
|
||||
}
|
||||
|
||||
return [];
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
import { MarkdownString, ThemeColor, ThemeIcon, TreeItem } from "vscode";
|
||||
import { Execution, ExecutionStatus } from "../../../appwrite";
|
||||
import { functionsClient } from "../../../client";
|
||||
import { ext } from "../../../extensionVariables";
|
||||
import { msToDate } from "../../../utils/date";
|
||||
import { ExecutionsTreeItem } from "./ExecutionsTreeItem";
|
||||
|
||||
|
@ -10,11 +12,17 @@ const executionStatusIcons: Record<ExecutionStatus, ThemeIcon> = {
|
|||
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, public execution: Execution) {
|
||||
constructor(public readonly parent: ExecutionsTreeItem, public readonly execution: Execution) {
|
||||
super(execution.$id);
|
||||
this.label = this.getLabel(execution);
|
||||
this.iconPath = executionStatusIcons[execution.status];
|
||||
|
@ -23,45 +31,40 @@ export class ExecutionTreeItem extends TreeItem {
|
|||
this.description = execution.trigger;
|
||||
this.contextValue = this.getContextValue(execution);
|
||||
this.isAutoRefreshing = execution.status === "processing" || execution.status === "waiting";
|
||||
// if (this.isAutoRefreshing) {
|
||||
// this.autoRefresh();
|
||||
// }
|
||||
this.autoRefresh();
|
||||
}
|
||||
|
||||
// async autoRefresh(): Promise<void> {
|
||||
// if (!this.isAutoRefreshing && this.refreshCount < 5) {
|
||||
// return;
|
||||
// }
|
||||
// this.refreshCount++;
|
||||
// ext.outputChannel.appendLog("Refreshing execution.");
|
||||
// const execution = await functionsClient?.getExecution(this.parent.parent.func.$id, this.execution.$id);
|
||||
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.execution = execution;
|
||||
// this.contextValue = this.getContextValue(execution);
|
||||
// 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();
|
||||
// }
|
||||
if (!execution) {
|
||||
ext.outputChannel.appendLog("Execution is undefined");
|
||||
this.isAutoRefreshing = false;
|
||||
return;
|
||||
}
|
||||
|
||||
this.contextValue = this.getContextValue(execution);
|
||||
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" || execution.status === "failed") {
|
||||
return `${this.getCreated(execution)} (${this.getExecutionTime(execution)}s)`;
|
||||
return `${this.getCreated(execution)} (${execution.time.toPrecision(2)}s)`;
|
||||
}
|
||||
return `${this.getCreated(execution)} (${execution.status})`;
|
||||
}
|
||||
|
||||
getExecutionTime(execution: Execution): string {
|
||||
return execution.time.toPrecision(2);
|
||||
}
|
||||
|
||||
getContextValue(execution: Execution): string {
|
||||
if (execution.status === "completed" || execution.status === "failed") {
|
||||
if (execution.stderr === "" && execution.stdout === "") {
|
||||
|
|
|
@ -1,47 +1,21 @@
|
|||
import { ThemeIcon, TreeItem, TreeItemCollapsibleState } from "vscode";
|
||||
import { Execution, ExecutionList } from "../../../appwrite";
|
||||
import { Execution, ExecutionList } from '../../../appwrite';
|
||||
import { functionsClient } from "../../../client";
|
||||
import { ExecutionTreeItem } from "./ExecutionTreeItem";
|
||||
import { FunctionTreeItem } from "../FunctionTreeItem";
|
||||
import { ext } from "../../../extensionVariables";
|
||||
import { AppwriteTreeItemBase } from "../../../ui/AppwriteTreeItemBase";
|
||||
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");
|
||||
}
|
||||
|
||||
private executionsToShow = 10;
|
||||
|
||||
public async getChildren(): Promise<TreeItem[]> {
|
||||
if (!functionsClient) {
|
||||
return [];
|
||||
}
|
||||
const executions: ExecutionList | undefined = await functionsClient.listExecutions(
|
||||
this.parent.func.$id,
|
||||
undefined,
|
||||
this.executionsToShow,
|
||||
undefined,
|
||||
"DESC"
|
||||
);
|
||||
const children = executions?.executions.map((execution: Execution) => new ExecutionTreeItem(this, execution)) ?? [
|
||||
new TreeItem("No executions."),
|
||||
];
|
||||
if (children.length === 0) {
|
||||
children.push(new TreeItem("No executions."));
|
||||
}
|
||||
ext.outputChannel.appendLog(`Found ${executions?.sum} executions`);
|
||||
if (executions?.sum ?? (0 > this.executionsToShow && this.executionsToShow !== 100)) {
|
||||
const viewMoreItem: TreeItem = {
|
||||
command: {
|
||||
command: "vscode-appwrite.viewMore",
|
||||
arguments: [this],
|
||||
title: "View more",
|
||||
},
|
||||
label: "View more...",
|
||||
};
|
||||
children.push(viewMoreItem);
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -50,12 +24,4 @@ export class ExecutionsTreeItem extends AppwriteTreeItemBase<FunctionTreeItem> {
|
|||
contextValue = "executions";
|
||||
|
||||
iconPath = new ThemeIcon("history");
|
||||
|
||||
async viewMore(): Promise<void> {
|
||||
this.executionsToShow += 10;
|
||||
if (this.executionsToShow > 100) {
|
||||
this.executionsToShow = 100;
|
||||
}
|
||||
ext.tree?.functions?.refreshChild(this);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@ import { Function } from "../../../appwrite";
|
|||
import { functionsClient } from "../../../client";
|
||||
import { appwriteSystemEvents } from "../../../constants";
|
||||
import { ext } from "../../../extensionVariables";
|
||||
import { EnumEditableTreeItemBase } from "../../common/editable/EnumEditableTreeItem";
|
||||
import { EnumEditableTreeItemBase } from "../../common/EnumEditableTreeItem";
|
||||
import { FunctionSettingsTreeItem } from "./FunctionSettingsTreeItem";
|
||||
|
||||
export class EventsTreeItem extends EnumEditableTreeItemBase {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { ThemeIcon, TreeItem, TreeItemCollapsibleState } from "vscode";
|
||||
import { Function } from "../../../appwrite";
|
||||
import { functionsClient } from "../../../client";
|
||||
import { AppwriteTreeItemBase } from '../../../ui/AppwriteTreeItemBase';
|
||||
import { AppwriteTreeItemBase } from "../../../ui/AppwriteTreeItemBase";
|
||||
import { ChildTreeItem } from "../../ChildTreeItem";
|
||||
import { FunctionTreeItem } from "../FunctionTreeItem";
|
||||
import { EventsTreeItem } from "./EventsTreeItem";
|
||||
|
|
|
@ -2,7 +2,7 @@ import { InputBoxOptions, MarkdownString } from "vscode";
|
|||
import { Function } from "../../../appwrite";
|
||||
import { functionsClient } from "../../../client";
|
||||
import { ext } from "../../../extensionVariables";
|
||||
import { StringEditableTreeItemBase } from '../../common/editable/StringEditableTreeItem';
|
||||
import { StringEditableTreeItemBase } from '../../common/StringEditableTreeItem';
|
||||
import { FunctionSettingsTreeItem } from "./FunctionSettingsTreeItem";
|
||||
|
||||
const tooltip = "Function name";
|
||||
|
|
|
@ -5,7 +5,7 @@ import { ext } from "../../../extensionVariables";
|
|||
import cron from "cron-validate";
|
||||
import { FunctionSettingsTreeItem } from "./FunctionSettingsTreeItem";
|
||||
import cronstrue from "cronstrue";
|
||||
import { StringEditableTreeItemBase } from '../../common/editable/StringEditableTreeItem';
|
||||
import { StringEditableTreeItemBase } from '../../common/StringEditableTreeItem';
|
||||
|
||||
export class ScheduleTreeItem extends StringEditableTreeItemBase {
|
||||
private readonly func: Function;
|
||||
|
|
|
@ -2,7 +2,7 @@ import { InputBoxOptions, MarkdownString } from "vscode";
|
|||
import { Function } from "../../../appwrite";
|
||||
import { functionsClient } from "../../../client";
|
||||
import { ext } from "../../../extensionVariables";
|
||||
import { StringEditableTreeItemBase } from "../../common/editable/StringEditableTreeItem";
|
||||
import { StringEditableTreeItemBase } from "../../common/StringEditableTreeItem";
|
||||
|
||||
function isNumeric(str: string) {
|
||||
console.log("here");
|
||||
|
|
|
@ -2,7 +2,7 @@ import { InputBoxOptions, MarkdownString, window } from "vscode";
|
|||
import { Function } from "../../../appwrite";
|
||||
import { functionsClient } from "../../../client";
|
||||
import { ext } from "../../../extensionVariables";
|
||||
import { StringEditableTreeItemBase } from "../../common/editable/StringEditableTreeItem";
|
||||
import { StringEditableTreeItemBase } from "../../common/StringEditableTreeItem";
|
||||
import { VarsTreeItem } from "./VarsTreeItem";
|
||||
|
||||
const tooltip = "Environment var";
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { TreeItem, TreeItemCollapsibleState } from "vscode";
|
||||
import { Vars } from "../../../appwrite";
|
||||
import { AppwriteTreeItemBase } from '../../../ui/AppwriteTreeItemBase';
|
||||
import { AppwriteTreeItemBase } from "../../../ui/AppwriteTreeItemBase";
|
||||
import { FunctionSettingsTreeItem } from "./FunctionSettingsTreeItem";
|
||||
import { VarTreeItem } from "./VarTreeItem";
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@ export class TagTreeItem extends TreeItem {
|
|||
const active = func.tag === tag.$id;
|
||||
this.label = `${msToDate(tag.dateCreated)}${active ? ' (Active)' : ''}`;
|
||||
this.description = tag.$id;
|
||||
this.iconPath = new ThemeIcon(active ? 'circle-large-filled' : 'circle-large-outline');
|
||||
this.iconPath = new ThemeIcon(active ? 'circle-filled' : 'circle-outline');
|
||||
this.contextValue = `tag${active ? '_active' : ''}`;
|
||||
this.tooltip = new MarkdownString(`ID: ${tag.$id} \nCreated: ${msToDate(tag.dateCreated)} \nCommand: ${tag.command} \nSize: ${tag.size}B`);
|
||||
}
|
||||
|
|
|
@ -14,22 +14,7 @@ export class TagsTreeItem extends AppwriteTreeItemBase<FunctionTreeItem> {
|
|||
return [];
|
||||
}
|
||||
const tags = await functionsClient.listTags(this.parent.func.$id);
|
||||
const children = tags?.tags.sort((a, b) => b.dateCreated - a.dateCreated).map((tag) => new TagTreeItem(this, tag)) ?? [new TreeItem('No tags.')];
|
||||
|
||||
if (children.length === 0) {
|
||||
const noTagsItem: TreeItem = {
|
||||
command: {
|
||||
command: "vscode-appwrite.CreateTag",
|
||||
title: "Create tag",
|
||||
arguments: [this],
|
||||
tooltip: "Create a tag"
|
||||
},
|
||||
label: "Create a tag",
|
||||
iconPath: new ThemeIcon("cloud-upload"),
|
||||
};
|
||||
children.push(noTagsItem);
|
||||
}
|
||||
return children;
|
||||
return tags?.tags.sort((a, b) => b.dateCreated - a.dateCreated).map((tag) => new TagTreeItem(this, tag)) ?? [new TreeItem('No tags.')];
|
||||
}
|
||||
|
||||
collapsibleState = TreeItemCollapsibleState.Collapsed;
|
||||
|
|
|
@ -7,7 +7,4 @@ export abstract class AppwriteTreeItemBase<Parent = void> extends TreeItem {
|
|||
|
||||
abstract getChildren?(): Promise<TreeItem[]>;
|
||||
|
||||
viewMore(): Promise<void> {
|
||||
return Promise.resolve();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,19 +1,42 @@
|
|||
import { QuickPickItem, window } from "vscode";
|
||||
import { Collection, CollectionsList } from "../appwrite";
|
||||
import { client } from "../client";
|
||||
import { AppwriteSDK } from "../constants";
|
||||
import AppwriteCall from "../utils/AppwriteCall";
|
||||
|
||||
export type CreateRuleWizardContext = {
|
||||
label: string;
|
||||
key: string;
|
||||
type: keyof typeof ruleTypes;
|
||||
default: any;
|
||||
required: boolean;
|
||||
array: boolean;
|
||||
list?: string[];
|
||||
};
|
||||
|
||||
export async function createRuleWizard(): Promise<CreateRuleWizardContext | undefined> {
|
||||
const label = await window.showInputBox({
|
||||
placeHolder: "Label",
|
||||
prompt: "Attribute internal display name",
|
||||
});
|
||||
if (label === undefined) {
|
||||
return;
|
||||
}
|
||||
const key = await window.showInputBox({
|
||||
placeHolder: "Key",
|
||||
prompt: "Attribute key name. Used as the document JSON key in the Database API.",
|
||||
});
|
||||
if (key === undefined) {
|
||||
return;
|
||||
}
|
||||
const ruleTypeItems: QuickPickItem[] = Object.entries(ruleTypes).map(([label, description]) => ({
|
||||
label,
|
||||
description,
|
||||
}));
|
||||
|
||||
const type = await window.showQuickPick(ruleTypeItems);
|
||||
|
||||
if (type === undefined) {
|
||||
return;
|
||||
}
|
||||
if (label && key && type) {
|
||||
return { label, key, type: (type.label as unknown) as keyof typeof ruleTypes };
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const ruleTypes = {
|
||||
text: "Any string value.",
|
||||
numeric: "Any integer or float value.",
|
||||
|
@ -22,119 +45,6 @@ const ruleTypes = {
|
|||
url: "Any valid URL.",
|
||||
email: "Any valid email address.",
|
||||
ip: "Any valid IP v4 or v6 address.",
|
||||
document: "Accept a valid child document from specified collection(s).",
|
||||
document:
|
||||
"Accept a valid child document. When using this type you are also required to pass the 'list' parameter with an array of the collections UID values of the document types you want to accept.",
|
||||
};
|
||||
|
||||
type RuleType = keyof typeof ruleTypes;
|
||||
|
||||
export async function createRuleWizard(collection: Collection): Promise<CreateRuleWizardContext | undefined> {
|
||||
const label = await window.showInputBox({
|
||||
placeHolder: "Attribute label",
|
||||
prompt: "Attribute internal display name",
|
||||
validateInput: (value) => {
|
||||
if (value === "") {
|
||||
return "Label cannot be empty.";
|
||||
}
|
||||
},
|
||||
});
|
||||
if (label === undefined) {
|
||||
return;
|
||||
}
|
||||
const key = await window.showInputBox({
|
||||
placeHolder: "Attribute key name",
|
||||
prompt: "Attribute key name. Used as the document JSON key in the Database API.",
|
||||
ignoreFocusOut: true,
|
||||
validateInput: (value) => {
|
||||
if (value === "") {
|
||||
return "Key name cannot be empty.";
|
||||
}
|
||||
},
|
||||
});
|
||||
if (key === undefined) {
|
||||
return;
|
||||
}
|
||||
const ruleTypeItems: QuickPickItem[] = Object.entries(ruleTypes).map(([label, description]) => ({
|
||||
label,
|
||||
detail: description,
|
||||
}));
|
||||
|
||||
const typeItem = await window.showQuickPick(ruleTypeItems, { placeHolder: "Rule value type." });
|
||||
const type: RuleType | undefined = (typeItem?.label as RuleType) ?? undefined;
|
||||
|
||||
if (typeItem === undefined || type === undefined) {
|
||||
return;
|
||||
}
|
||||
|
||||
let list: string[] | undefined = undefined;
|
||||
|
||||
if (type === "document") {
|
||||
const databaseSdk = new AppwriteSDK.Database(client);
|
||||
const collectionsList = await AppwriteCall<CollectionsList, CollectionsList>(databaseSdk.listCollections());
|
||||
|
||||
if (collectionsList === undefined) {
|
||||
window.showErrorMessage("Could not get collections list.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (collectionsList) {
|
||||
const collections = collectionsList.collections.filter((c) => c.$id !== collection.$id);
|
||||
const qpItems: QuickPickItem[] = collections.map((collection) => ({
|
||||
label: collection.name,
|
||||
description: collection.$id,
|
||||
}));
|
||||
|
||||
const listInput = await window.showQuickPick(qpItems, {
|
||||
canPickMany: true,
|
||||
placeHolder: "Collections which contain valid child documents for this document attribute.",
|
||||
ignoreFocusOut: true,
|
||||
});
|
||||
list = listInput?.map((item) => item.description as string) ?? [];
|
||||
}
|
||||
}
|
||||
|
||||
if (label === "document" && list === undefined) {
|
||||
return;
|
||||
}
|
||||
|
||||
const array = await window.showQuickPick(["Primitive", "Array"], {
|
||||
placeHolder: "Decide if this rule is a primitive or an array of values.",
|
||||
ignoreFocusOut: true,
|
||||
});
|
||||
|
||||
if (array === undefined) {
|
||||
return;
|
||||
}
|
||||
|
||||
const required = await window.showQuickPick(["Required", "Optional"], {
|
||||
placeHolder: "Decide if this rule value is required in order to pass document validation.",
|
||||
ignoreFocusOut: true,
|
||||
});
|
||||
|
||||
if (required === undefined) {
|
||||
return;
|
||||
}
|
||||
|
||||
const defaultValue = await window.showInputBox({
|
||||
placeHolder: "Default value (press Enter to skip)",
|
||||
prompt: "Default value for this rule type. Make sure that the default value is able to pass validation in order to avoid errors when skipping optional values.",
|
||||
ignoreFocusOut: true,
|
||||
});
|
||||
|
||||
if (defaultValue === undefined) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (label && key && type) {
|
||||
return {
|
||||
label,
|
||||
key,
|
||||
type,
|
||||
default: defaultValue,
|
||||
array: array === "Array",
|
||||
required: required === "Required",
|
||||
list,
|
||||
};
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
|
|
@ -1,9 +1,5 @@
|
|||
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);
|
||||
import dayjs = require('dayjs');
|
||||
|
||||
export function msToDate(ms: number): string {
|
||||
return dayjs(ms * 1000).tz(dayjs.tz.guess()).format("LTS");
|
||||
return dayjs(ms).format("LTS");
|
||||
}
|
||||
|
|
|
@ -1,5 +0,0 @@
|
|||
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 { ext } from "../extensionVariables";
|
||||
import * as path from "path";
|
||||
import * as os from "os";
|
||||
import * as fs from "fs";
|
||||
import { sleep } from './sleep';
|
||||
|
||||
export async function getTarReadStream(folder: Uri): Promise<string | undefined> {
|
||||
try {
|
||||
|
@ -15,14 +15,11 @@ export async function getTarReadStream(folder: Uri): Promise<string | undefined>
|
|||
window.showErrorMessage("No workspace open.");
|
||||
return;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
tar.create({ gzip: true, cwd: cwd, mode: 1777 }, [path.relative(cwd, folder.fsPath)]).pipe(fs.createWriteStream(tarFilePath));
|
||||
const tarFilePath = path.join(os.tmpdir(), tarName);
|
||||
|
||||
await sleep(500);
|
||||
tar.create({ gzip: true, cwd: cwd }, [path.relative(cwd, folder.fsPath)]).pipe(fs.createWriteStream(tarFilePath));
|
||||
|
||||
ext.outputChannel.appendLog(`Created ${tarFilePath}`);
|
||||
|
||||
|
|
6
src/utils/types.d.ts
vendored
6
src/utils/types.d.ts
vendored
|
@ -1,6 +0,0 @@
|
|||
import { Progress } from 'vscode';
|
||||
|
||||
export type ProgressMessage = Progress<{
|
||||
message?: string | undefined;
|
||||
increment?: number | undefined;
|
||||
}>;
|
Loading…
Reference in a new issue