health
This commit is contained in:
parent
045342f813
commit
799da899ae
9 changed files with 6944 additions and 6847 deletions
20
README.md
20
README.md
|
@ -1,4 +1,6 @@
|
||||||
# vscode-appwrite
|
# Appwrite for Visual Studio Code
|
||||||
|
|
||||||
|
Use the Appwrite extension to quickly monitor, manage, and interact with your Appwrite instance directly from VS Code.
|
||||||
|
|
||||||
## What is Appwrite?
|
## What is Appwrite?
|
||||||
|
|
||||||
|
@ -10,17 +12,20 @@ From [appwrite.io](https://appwrite.io)
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Describe specific features of your extension including screenshots of your extension in action. Image paths are relative to this README file.
|
Describe specific features of your extension including screenshots of your extension in action. Image paths are relative to this README file.
|
||||||
|
|
||||||
For example if there is an image subfolder under your extension project workspace:
|
For example if there is an image subfolder under your extension project workspace:
|
||||||
|
|
||||||
\!\[feature X\]\(images/feature-x.png\)
|
### Check the health of all the Appwrite services.
|
||||||
|
![Health feature](./media/features/health/scr1.png)
|
||||||
|
|
||||||
> Tip: Many popular extensions utilize animations. This is an excellent way to show off your extension! We recommend short, focused animations that are easy to follow.
|
> Tip: Many popular extensions utilize animations. This is an excellent way to show off your extension! We recommend short, focused animations that are easy to follow.
|
||||||
|
|
||||||
## Requirements
|
## Requirements
|
||||||
|
|
||||||
If you have any requirements or dependencies, add a section describing those and how to install and configure them.
|
This extension does not provide features for setting up or installing Appwrite. Only managing and interacting with Appwrite once it's running.
|
||||||
|
|
||||||
## Extension Settings
|
## Extension Settings
|
||||||
|
|
||||||
|
@ -43,15 +48,8 @@ Users appreciate release notes as you update your extension.
|
||||||
|
|
||||||
### 1.0.0
|
### 1.0.0
|
||||||
|
|
||||||
Initial release of ...
|
Initial release of the Appwrite extension for VS Code
|
||||||
|
|
||||||
### 1.0.1
|
|
||||||
|
|
||||||
Fixed issue #.
|
|
||||||
|
|
||||||
### 1.1.0
|
|
||||||
|
|
||||||
Added features X, Y, and Z.
|
|
||||||
|
|
||||||
-----------------------------------------------------------------------------------------------------------
|
-----------------------------------------------------------------------------------------------------------
|
||||||
## Following extension guidelines
|
## Following extension guidelines
|
||||||
|
|
BIN
media/features/health/scr1.png
Normal file
BIN
media/features/health/scr1.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 62 KiB |
13
package-lock.json
generated
13
package-lock.json
generated
|
@ -7,6 +7,7 @@
|
||||||
"": {
|
"": {
|
||||||
"version": "0.0.1",
|
"version": "0.0.1",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"dayjs": "^1.10.4",
|
||||||
"fs-extra": "^9.1.0",
|
"fs-extra": "^9.1.0",
|
||||||
"node-appwrite": "^2.1.0"
|
"node-appwrite": "^2.1.0"
|
||||||
},
|
},
|
||||||
|
@ -1012,6 +1013,7 @@
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"anymatch": "~3.1.1",
|
"anymatch": "~3.1.1",
|
||||||
"braces": "~3.0.2",
|
"braces": "~3.0.2",
|
||||||
|
"fsevents": "~2.3.1",
|
||||||
"glob-parent": "~5.1.0",
|
"glob-parent": "~5.1.0",
|
||||||
"is-binary-path": "~2.1.0",
|
"is-binary-path": "~2.1.0",
|
||||||
"is-glob": "~4.0.1",
|
"is-glob": "~4.0.1",
|
||||||
|
@ -1126,6 +1128,11 @@
|
||||||
"node": ">= 8"
|
"node": ">= 8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/dayjs": {
|
||||||
|
"version": "1.10.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.10.4.tgz",
|
||||||
|
"integrity": "sha512-RI/Hh4kqRc1UKLOAf/T5zdMMX5DQIlDxwUe3wSyMMnEbGunnpENCdbUgM+dW7kXidZqCttBrmw7BhN4TMddkCw=="
|
||||||
|
},
|
||||||
"node_modules/debug": {
|
"node_modules/debug": {
|
||||||
"version": "4.3.1",
|
"version": "4.3.1",
|
||||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz",
|
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz",
|
||||||
|
@ -2268,6 +2275,7 @@
|
||||||
"resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz",
|
||||||
"integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==",
|
"integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"graceful-fs": "^4.1.6",
|
||||||
"universalify": "^2.0.0"
|
"universalify": "^2.0.0"
|
||||||
},
|
},
|
||||||
"optionalDependencies": {
|
"optionalDependencies": {
|
||||||
|
@ -4798,6 +4806,11 @@
|
||||||
"which": "^2.0.1"
|
"which": "^2.0.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"dayjs": {
|
||||||
|
"version": "1.10.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.10.4.tgz",
|
||||||
|
"integrity": "sha512-RI/Hh4kqRc1UKLOAf/T5zdMMX5DQIlDxwUe3wSyMMnEbGunnpENCdbUgM+dW7kXidZqCttBrmw7BhN4TMddkCw=="
|
||||||
|
},
|
||||||
"debug": {
|
"debug": {
|
||||||
"version": "4.3.1",
|
"version": "4.3.1",
|
||||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz",
|
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz",
|
||||||
|
|
42
package.json
42
package.json
|
@ -6,6 +6,9 @@
|
||||||
"engines": {
|
"engines": {
|
||||||
"vscode": "^1.55.0"
|
"vscode": "^1.55.0"
|
||||||
},
|
},
|
||||||
|
"repository": {
|
||||||
|
"url": "https://github.com/streamlux/vscode-appwrite"
|
||||||
|
},
|
||||||
"categories": [
|
"categories": [
|
||||||
"Other"
|
"Other"
|
||||||
],
|
],
|
||||||
|
@ -78,7 +81,12 @@
|
||||||
"icon": "$(refresh)"
|
"icon": "$(refresh)"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"command": "vscode-appwrite.OpenDocumentation",
|
"command": "vscode-appwrite.OpenUsersDocumentation",
|
||||||
|
"title": "Open documentation",
|
||||||
|
"icon": "$(book)"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"command": "vscode-appwrite.OpenDatabaseDocumentation",
|
||||||
"title": "Open documentation",
|
"title": "Open documentation",
|
||||||
"icon": "$(book)"
|
"icon": "$(book)"
|
||||||
},
|
},
|
||||||
|
@ -136,6 +144,16 @@
|
||||||
"command": "vscode-appwrite.editPermission",
|
"command": "vscode-appwrite.editPermission",
|
||||||
"title": "Edit permission",
|
"title": "Edit permission",
|
||||||
"icon": "$(edit)"
|
"icon": "$(edit)"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"command": "vscode-appwrite.refreshHealth",
|
||||||
|
"title": "Refresh health",
|
||||||
|
"icon": "$(refresh)"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"command": "vscode-appwrite.openHealthDocumentation",
|
||||||
|
"title": "Open health documentation",
|
||||||
|
"icon": "$(book)"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"views": {
|
"views": {
|
||||||
|
@ -171,10 +189,15 @@
|
||||||
"menus": {
|
"menus": {
|
||||||
"view/title": [
|
"view/title": [
|
||||||
{
|
{
|
||||||
"command": "vscode-appwrite.OpenDocumentation",
|
"command": "vscode-appwrite.OpenUsersDocumentation",
|
||||||
"when": "view == Users",
|
"when": "view == Users",
|
||||||
"group": "navigation"
|
"group": "navigation"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"command": "vscode-appwrite.OpenDatabaseDocumentation",
|
||||||
|
"when": "view == Database",
|
||||||
|
"group": "navigation"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"command": "vscode-appwrite.refreshUsersList",
|
"command": "vscode-appwrite.refreshUsersList",
|
||||||
"when": "view == Users",
|
"when": "view == Users",
|
||||||
|
@ -194,6 +217,16 @@
|
||||||
"command": "vscode-appwrite.createCollection",
|
"command": "vscode-appwrite.createCollection",
|
||||||
"when": "view == Database",
|
"when": "view == Database",
|
||||||
"group": "navigation"
|
"group": "navigation"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"command": "vscode-appwrite.refreshHealth",
|
||||||
|
"when": "view == Health",
|
||||||
|
"group": "navigation"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"command": "vscode-appwrite.openHealthDocumentation",
|
||||||
|
"when": "view == Health",
|
||||||
|
"group": "navigation"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"view/item/context": [
|
"view/item/context": [
|
||||||
|
@ -292,7 +325,7 @@
|
||||||
{
|
{
|
||||||
"id": "Appwrite",
|
"id": "Appwrite",
|
||||||
"title": "Appwrite",
|
"title": "Appwrite",
|
||||||
"icon": "resources/vscode-appwrite.svg"
|
"icon": "./resources/vscode-appwrite.svg"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
@ -302,7 +335,7 @@
|
||||||
"appwrite.projects": {
|
"appwrite.projects": {
|
||||||
"type": "array",
|
"type": "array",
|
||||||
"default": [],
|
"default": [],
|
||||||
"description": "List of Appwrite projects"
|
"markdownDescription": "List of Appwrite project configurations. You can use the Connect command to set this up, or see [docs](https://github.com/streamlux/vscode-appwrite/) for more information."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -336,6 +369,7 @@
|
||||||
"webpack-cli": "^4.4.0"
|
"webpack-cli": "^4.4.0"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"dayjs": "^1.10.4",
|
||||||
"fs-extra": "^9.1.0",
|
"fs-extra": "^9.1.0",
|
||||||
"node-appwrite": "^2.1.0"
|
"node-appwrite": "^2.1.0"
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import { MarkdownString } from 'vscode';
|
||||||
import { AppwriteHealth, Client, HealthClient, SDK } from "../appwrite";
|
import { AppwriteHealth, Client, HealthClient, SDK } from "../appwrite";
|
||||||
const sdk: SDK = require("node-appwrite");
|
const sdk: SDK = require("node-appwrite");
|
||||||
|
|
||||||
|
@ -28,3 +29,20 @@ export class Health {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const healthTooltips: Record<keyof AppwriteHealth, string | MarkdownString | undefined> = {
|
||||||
|
HTTP: "Check the Appwrite HTTP server is up and responsive.",
|
||||||
|
DB: "Check the Appwrite in-memory cache server is up and connection is successful.",
|
||||||
|
Cache: "Check the Appwrite in-memory cache server is up and connection is successful.",
|
||||||
|
Time:
|
||||||
|
new MarkdownString("Check the Appwrite server time is synced with Google remote NTP server. We use this technology to smoothly handle leap seconds with no disruptive events. The [Network Time Protocol (NTP)](https://en.wikipedia.org/wiki/Network_Time_Protocol) is used by hundreds of millions of computers and devices to synchronize their clocks over the Internet. If your computer sets its own clock, it likely uses NTP."),
|
||||||
|
QueueWebhooks: "The number of webhooks that are waiting to be processed in the Appwrite internal queue server.",
|
||||||
|
QueueTasks: "The number of tasks that are waiting to be processed in the Appwrite internal queue server.",
|
||||||
|
QueueLogs: "The number of logs that are waiting to be processed in the Appwrite internal queue server.",
|
||||||
|
QueueUsage: "The number of usage stats that are waiting to be processed in the Appwrite internal queue server.",
|
||||||
|
QueueCertificates:
|
||||||
|
new MarkdownString("The number of certificates that are waiting to be issued against [Letsencrypt](https://letsencrypt.org/) in the Appwrite internal queue server."),
|
||||||
|
QueueFunctions: "The number of functions waiting to be executed.",
|
||||||
|
StorageLocal: "Check the Appwrite local storage device is up and connection is successful.",
|
||||||
|
AntiVirus: "Check the Appwrite Anti Virus server is up and connection is successful.",
|
||||||
|
};
|
||||||
|
|
|
@ -1,7 +1,14 @@
|
||||||
import { openUrl } from '../utils/openUrl';
|
import { openUrl } from '../utils/openUrl';
|
||||||
|
|
||||||
const appwriteDocsUrl = 'https://appwrite.io/docs';
|
const documentationLinks = {
|
||||||
|
home: 'https://appwrite.io/docs',
|
||||||
|
users: 'https://appwrite.io/docs/server/users',
|
||||||
|
database: 'https://appwrite.io/docs/client/database',
|
||||||
|
health: 'https://appwrite.io/docs/server/health'
|
||||||
|
};
|
||||||
|
|
||||||
export async function openDocumentation(): Promise<void> {
|
type DocsPage = keyof typeof documentationLinks;
|
||||||
await openUrl(appwriteDocsUrl);
|
|
||||||
|
export async function openDocumentation(page?: DocsPage): Promise<void> {
|
||||||
|
await openUrl(documentationLinks[page || 'home']);
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,7 +52,8 @@ export function registerCommands(context: ExtensionContext): void {
|
||||||
registerCommand("CreateUser", createUser);
|
registerCommand("CreateUser", createUser);
|
||||||
registerCommand("refreshUsersList", refreshUsersList);
|
registerCommand("refreshUsersList", refreshUsersList);
|
||||||
registerCommand("DeleteUser", deleteUser);
|
registerCommand("DeleteUser", deleteUser);
|
||||||
registerCommand("OpenDocumentation", openDocumentation);
|
registerCommand("OpenUsersDocumentation", () => openDocumentation('users'));
|
||||||
|
registerCommand("OpenDatabaseDocumentation", () => openDocumentation('database'));
|
||||||
registerCommand("GetUserLogs", getUserLogs);
|
registerCommand("GetUserLogs", getUserLogs);
|
||||||
registerCommand("viewDocumentAsJson", viewDocumentAsJson);
|
registerCommand("viewDocumentAsJson", viewDocumentAsJson);
|
||||||
registerCommand("AddProject", addProject);
|
registerCommand("AddProject", addProject);
|
||||||
|
@ -66,4 +67,6 @@ export function registerCommands(context: ExtensionContext): void {
|
||||||
registerCommand("createCollection", createCollection, 'database');
|
registerCommand("createCollection", createCollection, 'database');
|
||||||
registerCommand("createPermission", createPermission, 'database');
|
registerCommand("createPermission", createPermission, 'database');
|
||||||
registerCommand("deletePermission", deletePermission, 'database');
|
registerCommand("deletePermission", deletePermission, 'database');
|
||||||
|
registerCommand("refreshHealth", () => {}, 'health');
|
||||||
|
registerCommand("openHealthDocumentation", () => openDocumentation('health'));
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,15 @@
|
||||||
import * as vscode from "vscode";
|
import * as vscode from "vscode";
|
||||||
|
import { MarkdownString } from 'vscode';
|
||||||
|
|
||||||
export class HealthTreeItem extends vscode.TreeItem {
|
export class HealthTreeItem extends vscode.TreeItem {
|
||||||
constructor(public readonly label: string, status: boolean) {
|
constructor(public readonly label: string, status: any, tooltip?: string | MarkdownString | undefined) {
|
||||||
super(label);
|
super(label);
|
||||||
|
console.log(status);
|
||||||
this.label = label;
|
this.label = label;
|
||||||
this.iconPath = new vscode.ThemeIcon(status ? "check" : "error", new vscode.ThemeColor(status ? "#00ff00" : "list.errorForeground"));
|
this.iconPath = new vscode.ThemeIcon(status ? "check" : "error", new vscode.ThemeColor(status ? "#00ff00" : "list.errorForeground"));
|
||||||
this.contextValue = `health.${label}`;
|
this.contextValue = `health.${label}`;
|
||||||
|
this.description = "" + Object.values(status)[0];
|
||||||
|
this.tooltip = tooltip;
|
||||||
}
|
}
|
||||||
|
|
||||||
contextValue = "health";
|
contextValue = "health";
|
||||||
|
|
|
@ -1,12 +1,24 @@
|
||||||
import * as vscode from "vscode";
|
import * as vscode from "vscode";
|
||||||
import { healthClient } from "../../client";
|
import { healthClient } from "../../client";
|
||||||
|
import { ext } from "../../extensionVariables";
|
||||||
import { HealthTreeItem } from "./HealthTreeItem";
|
import { HealthTreeItem } from "./HealthTreeItem";
|
||||||
|
import * as dayjs from "dayjs";
|
||||||
|
import * as relativeTime from "dayjs/plugin/relativeTime";
|
||||||
|
import * as localizedFormat from "dayjs/plugin/localizedFormat";
|
||||||
|
import { healthTooltips } from "../../appwrite/Health";
|
||||||
|
import { AppwriteHealth } from "../../appwrite";
|
||||||
|
// dayjs.extend(relativeTime);
|
||||||
|
dayjs.extend(localizedFormat);
|
||||||
|
|
||||||
|
type PartialRecord<K extends string | number | symbol, T> = { [P in K]?: T };
|
||||||
|
|
||||||
export class HealthTreeItemProvider implements vscode.TreeDataProvider<vscode.TreeItem> {
|
export class HealthTreeItemProvider implements vscode.TreeDataProvider<vscode.TreeItem> {
|
||||||
private _onDidChangeTreeData: vscode.EventEmitter<HealthTreeItem | undefined | void> = new vscode.EventEmitter<
|
private _onDidChangeTreeData: vscode.EventEmitter<HealthTreeItem | undefined | void> = new vscode.EventEmitter<
|
||||||
HealthTreeItem | undefined | void
|
HealthTreeItem | undefined | void
|
||||||
>();
|
>();
|
||||||
|
|
||||||
|
private lastChecked: Date = new Date();
|
||||||
|
|
||||||
readonly onDidChangeTreeData: vscode.Event<HealthTreeItem | undefined | void> = this._onDidChangeTreeData.event;
|
readonly onDidChangeTreeData: vscode.Event<HealthTreeItem | undefined | void> = this._onDidChangeTreeData.event;
|
||||||
|
|
||||||
constructor() {}
|
constructor() {}
|
||||||
|
@ -23,9 +35,17 @@ export class HealthTreeItemProvider implements vscode.TreeDataProvider<vscode.Tr
|
||||||
// get children for root
|
// get children for root
|
||||||
if (element === undefined) {
|
if (element === undefined) {
|
||||||
const health = await healthClient.checkup();
|
const health = await healthClient.checkup();
|
||||||
return Object.entries(health).map(([service, status]) => {
|
ext.outputChannel?.append(JSON.stringify(health, null, 4));
|
||||||
return new HealthTreeItem(service, status);
|
const healthItems = Object.entries(health).map(([service, status]) => {
|
||||||
|
return new HealthTreeItem(service, status, healthTooltips[service as keyof AppwriteHealth]);
|
||||||
});
|
});
|
||||||
|
this.lastChecked = new Date();
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
label: `Updated at ${dayjs(this.lastChecked).format("LTS")}`,
|
||||||
|
},
|
||||||
|
...healthItems,
|
||||||
|
];
|
||||||
}
|
}
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue