Plug format now changed to YAML
This commit is contained in:
parent
a382ab3baa
commit
621e55dbcf
@ -4,8 +4,7 @@ import { CronHook } from "../plugbox/feature/node_cron";
|
||||
import { EventHook } from "../plugbox/feature/event";
|
||||
|
||||
export type CommandDef = {
|
||||
// Function name to invoke
|
||||
invoke: string;
|
||||
name: string;
|
||||
|
||||
// Bind to keyboard shortcut
|
||||
key?: string;
|
||||
@ -17,9 +16,7 @@ export type CommandDef = {
|
||||
};
|
||||
|
||||
export type SilverBulletHooks = {
|
||||
commands?: {
|
||||
[key: string]: CommandDef;
|
||||
};
|
||||
command?: CommandDef | CommandDef[];
|
||||
} & EndpointHook &
|
||||
CronHook &
|
||||
EventHook;
|
||||
|
@ -14,7 +14,7 @@
|
||||
"watch": "rm -rf .parcel-cache && parcel watch",
|
||||
"build": "parcel build",
|
||||
"clean": "rm -rf dist",
|
||||
"plugs": "plugbox-bundle -w --dist plugs/dist plugs/core/core.plug.json plugs/git/git.plug.json",
|
||||
"plugs": "plugbox-bundle -w --dist plugs/dist plugs/*/*.plug.yaml",
|
||||
"server": "nodemon -w dist/server dist/server/server.js pages",
|
||||
"test": "jest"
|
||||
},
|
||||
|
@ -8,6 +8,7 @@ import yargs from "yargs";
|
||||
import { hideBin } from "yargs/helpers";
|
||||
import { Manifest } from "../types";
|
||||
import { watchFile } from "fs";
|
||||
import YAML from "yaml";
|
||||
|
||||
async function compile(filePath: string, functionName: string, debug: boolean) {
|
||||
let outFile = "out.js";
|
||||
@ -48,7 +49,7 @@ export default ${functionName};`
|
||||
|
||||
async function bundle(manifestPath: string, sourceMaps: boolean) {
|
||||
const rootPath = path.dirname(manifestPath);
|
||||
const manifest = JSON.parse(
|
||||
const manifest = YAML.parse(
|
||||
(await readFile(manifestPath)).toString()
|
||||
) as Manifest<any>;
|
||||
|
||||
@ -71,7 +72,12 @@ async function buildManifest(
|
||||
debug: boolean
|
||||
) {
|
||||
let generatedManifest = await bundle(manifestPath, debug);
|
||||
const outPath = path.join(distPath, path.basename(manifestPath));
|
||||
const outFile =
|
||||
manifestPath.substring(
|
||||
0,
|
||||
manifestPath.length - path.extname(manifestPath).length
|
||||
) + ".json";
|
||||
const outPath = path.join(distPath, path.basename(outFile));
|
||||
console.log("Emitting bundle to", outPath);
|
||||
await writeFile(outPath, JSON.stringify(generatedManifest, null, 2));
|
||||
return { generatedManifest, outPath };
|
||||
@ -93,7 +99,7 @@ async function run() {
|
||||
.parse();
|
||||
if (args._.length === 0) {
|
||||
console.log(
|
||||
"Usage: plugbox-bundle [--debug] [--dist <path>] <manifest.plug.json> <manifest2.plug.json> ..."
|
||||
"Usage: plugbox-bundle [--debug] [--dist <path>] <manifest.plug.yaml> <manifest2.plug.yaml> ..."
|
||||
);
|
||||
process.exit(1);
|
||||
}
|
||||
|
@ -16,6 +16,8 @@ import {
|
||||
storeWriteSyscalls,
|
||||
} from "../syscall/store.knex_node";
|
||||
import { fetchSyscalls } from "../syscall/fetch.node";
|
||||
import { EventFeature, EventHook } from "../feature/event";
|
||||
import { eventSyscalls } from "../syscall/event";
|
||||
|
||||
let args = yargs(hideBin(process.argv))
|
||||
.option("port", {
|
||||
@ -33,7 +35,7 @@ const plugPath = args._[0] as string;
|
||||
|
||||
const app = express();
|
||||
|
||||
type ServerHook = EndpointHook & CronHook;
|
||||
type ServerHook = EndpointHook & CronHook & EventHook;
|
||||
const system = new System<ServerHook>("server");
|
||||
|
||||
safeRun(async () => {
|
||||
@ -51,6 +53,9 @@ safeRun(async () => {
|
||||
await plugLoader.loadPlugs();
|
||||
plugLoader.watcher();
|
||||
system.addFeature(new NodeCronFeature());
|
||||
let eventFeature = new EventFeature();
|
||||
system.addFeature(eventFeature);
|
||||
system.registerSyscalls("event", [], eventSyscalls(eventFeature));
|
||||
system.addFeature(new EndpointFeature(app, ""));
|
||||
system.registerSyscalls("shell", [], shellSyscalls("."));
|
||||
system.registerSyscalls("fetch", [], fetchSyscalls());
|
||||
|
@ -13,6 +13,9 @@ test("Run a plugbox endpoint server", async () => {
|
||||
{
|
||||
functions: {
|
||||
testhandler: {
|
||||
http: {
|
||||
path: "/",
|
||||
},
|
||||
code: `(() => {
|
||||
return {
|
||||
default: (req) => {
|
||||
@ -23,9 +26,6 @@ test("Run a plugbox endpoint server", async () => {
|
||||
})()`,
|
||||
},
|
||||
},
|
||||
hooks: {
|
||||
endpoints: [{ method: "GET", path: "/", handler: "testhandler" }],
|
||||
},
|
||||
} as Manifest<EndpointHook>,
|
||||
createSandbox
|
||||
);
|
||||
|
@ -17,13 +17,12 @@ export type EndpointResponse = {
|
||||
};
|
||||
|
||||
export type EndpointHook = {
|
||||
endpoints?: EndPointDef[];
|
||||
http?: EndPointDef | EndPointDef[];
|
||||
};
|
||||
|
||||
export type EndPointDef = {
|
||||
method: "GET" | "POST" | "PUT" | "DELETE" | "HEAD" | "OPTIONS";
|
||||
method?: "GET" | "POST" | "PUT" | "DELETE" | "HEAD" | "OPTIONS" | "ANY";
|
||||
path: string;
|
||||
handler: string; // function name
|
||||
};
|
||||
|
||||
export class EndpointFeature implements Feature<EndpointHook> {
|
||||
@ -43,35 +42,42 @@ export class EndpointFeature implements Feature<EndpointHook> {
|
||||
console.log("Endpoint request", req.path);
|
||||
Promise.resolve()
|
||||
.then(async () => {
|
||||
// Iterate over all loaded plugins
|
||||
for (const [plugName, plug] of system.loadedPlugs.entries()) {
|
||||
const manifest = plug.manifest;
|
||||
if (!manifest) {
|
||||
continue;
|
||||
}
|
||||
const endpoints = manifest.hooks?.endpoints;
|
||||
console.log("Checking plug", plugName, endpoints);
|
||||
if (endpoints) {
|
||||
let prefix = `${this.prefix}/${plugName}`;
|
||||
console.log("Need prefix", prefix, "got", req.path);
|
||||
if (!req.path.startsWith(prefix)) {
|
||||
const functions = manifest.functions;
|
||||
console.log("Checking plug", plugName);
|
||||
let prefix = `${this.prefix}/${plugName}`;
|
||||
if (!req.path.startsWith(prefix)) {
|
||||
continue;
|
||||
}
|
||||
for (const [name, functionDef] of Object.entries(functions)) {
|
||||
if (!functionDef.http) {
|
||||
continue;
|
||||
}
|
||||
for (const { path, method, handler } of endpoints) {
|
||||
let endpoints = Array.isArray(functionDef.http)
|
||||
? functionDef.http
|
||||
: [functionDef.http];
|
||||
console.log(endpoints);
|
||||
for (const { path, method } of endpoints) {
|
||||
let prefixedPath = `${prefix}${path}`;
|
||||
if (prefixedPath === req.path && method === req.method) {
|
||||
if (
|
||||
prefixedPath === req.path &&
|
||||
((method || "GET") === req.method || method === "ANY")
|
||||
) {
|
||||
try {
|
||||
const response: EndpointResponse = await plug.invoke(
|
||||
handler,
|
||||
[
|
||||
{
|
||||
path: req.path,
|
||||
method: req.method,
|
||||
body: req.body,
|
||||
query: req.query,
|
||||
headers: req.headers,
|
||||
} as EndpointRequest,
|
||||
]
|
||||
);
|
||||
const response: EndpointResponse = await plug.invoke(name, [
|
||||
{
|
||||
path: req.path,
|
||||
method: req.method,
|
||||
body: req.body,
|
||||
query: req.query,
|
||||
headers: req.headers,
|
||||
} as EndpointRequest,
|
||||
]);
|
||||
let resp = res.status(response.status);
|
||||
if (response.headers) {
|
||||
for (const [key, value] of Object.entries(
|
||||
@ -101,21 +107,26 @@ export class EndpointFeature implements Feature<EndpointHook> {
|
||||
}
|
||||
|
||||
validateManifest(manifest: Manifest<EndpointHook>): string[] {
|
||||
const endpoints = manifest.hooks.endpoints;
|
||||
let errors = [];
|
||||
if (endpoints) {
|
||||
for (let { method, path, handler } of endpoints) {
|
||||
for (const [name, functionDef] of Object.entries(manifest.functions)) {
|
||||
if (!functionDef.http) {
|
||||
continue;
|
||||
}
|
||||
let endpoints = Array.isArray(functionDef.http)
|
||||
? functionDef.http
|
||||
: [functionDef.http];
|
||||
for (let { path, method } of endpoints) {
|
||||
if (!path) {
|
||||
errors.push("Path not defined for endpoint");
|
||||
}
|
||||
if (["GET", "POST", "PUT", "DELETE"].indexOf(method) === -1) {
|
||||
if (
|
||||
method &&
|
||||
["GET", "POST", "PUT", "DELETE", "ANY"].indexOf(method) === -1
|
||||
) {
|
||||
errors.push(
|
||||
`Invalid method ${method} for end point with with ${path}`
|
||||
);
|
||||
}
|
||||
if (!manifest.functions[handler]) {
|
||||
errors.push(`Endpoint handler function ${handler} not found`);
|
||||
}
|
||||
}
|
||||
}
|
||||
return errors;
|
||||
|
@ -2,29 +2,24 @@ import { Feature, Manifest } from "../types";
|
||||
import { System } from "../system";
|
||||
|
||||
export type EventHook = {
|
||||
events?: { [key: string]: string[] };
|
||||
events?: string[];
|
||||
};
|
||||
|
||||
export class EventFeature implements Feature<EventHook> {
|
||||
private system?: System<EventHook>;
|
||||
|
||||
async dispatchEvent(name: string, data?: any): Promise<any[]> {
|
||||
async dispatchEvent(eventName: string, data?: any): Promise<any[]> {
|
||||
if (!this.system) {
|
||||
throw new Error("EventFeature is not initialized");
|
||||
}
|
||||
let promises: Promise<any>[] = [];
|
||||
for (const plug of this.system.loadedPlugs.values()) {
|
||||
if (!plug.manifest!.hooks?.events) {
|
||||
continue;
|
||||
}
|
||||
let functionsToSpawn = plug.manifest!.hooks.events[name];
|
||||
if (functionsToSpawn) {
|
||||
functionsToSpawn.forEach((functionToSpawn) => {
|
||||
// Only dispatch functions on events when they're allowed to be invoked in this environment
|
||||
if (plug.canInvoke(functionToSpawn)) {
|
||||
promises.push(plug.invoke(functionToSpawn, [data]));
|
||||
}
|
||||
});
|
||||
for (const [name, functionDef] of Object.entries(
|
||||
plug.manifest!.functions
|
||||
)) {
|
||||
if (functionDef.events && functionDef.events.includes(eventName)) {
|
||||
promises.push(plug.invoke(name, [data]));
|
||||
}
|
||||
}
|
||||
}
|
||||
return Promise.all(promises);
|
||||
@ -32,12 +27,15 @@ export class EventFeature implements Feature<EventHook> {
|
||||
|
||||
apply(system: System<EventHook>): void {
|
||||
this.system = system;
|
||||
system.on({
|
||||
plugLoaded: (name, plug) => {},
|
||||
});
|
||||
}
|
||||
|
||||
validateManifest(manifest: Manifest<EventHook>): string[] {
|
||||
return [];
|
||||
let errors = [];
|
||||
for (const [name, functionDef] of Object.entries(manifest.functions)) {
|
||||
if (functionDef.events && !Array.isArray(functionDef.events)) {
|
||||
errors.push("'events' key must be an array of strings");
|
||||
}
|
||||
}
|
||||
return errors;
|
||||
}
|
||||
}
|
||||
|
@ -4,12 +4,7 @@ import { safeRun } from "../util";
|
||||
import { System } from "../system";
|
||||
|
||||
export type CronHook = {
|
||||
crons?: CronDef[];
|
||||
};
|
||||
|
||||
export type CronDef = {
|
||||
cron: string;
|
||||
handler: string; // function name
|
||||
cron?: string | string[];
|
||||
};
|
||||
|
||||
export class NodeCronFeature implements Feature<CronHook> {
|
||||
@ -27,19 +22,28 @@ export class NodeCronFeature implements Feature<CronHook> {
|
||||
reloadCrons();
|
||||
|
||||
function reloadCrons() {
|
||||
// ts-ignore
|
||||
tasks.forEach((task) => task.stop());
|
||||
tasks = [];
|
||||
for (let plug of system.loadedPlugs.values()) {
|
||||
const crons = plug.manifest?.hooks?.crons;
|
||||
if (crons) {
|
||||
if (!plug.manifest) {
|
||||
continue;
|
||||
}
|
||||
for (const [name, functionDef] of Object.entries(
|
||||
plug.manifest.functions
|
||||
)) {
|
||||
if (!functionDef.cron) {
|
||||
continue;
|
||||
}
|
||||
const crons = Array.isArray(functionDef.cron)
|
||||
? functionDef.cron
|
||||
: [functionDef.cron];
|
||||
for (let cronDef of crons) {
|
||||
tasks.push(
|
||||
cron.schedule(cronDef.cron, () => {
|
||||
console.log("Now acting on cron", cronDef.cron);
|
||||
cron.schedule(cronDef, () => {
|
||||
console.log("Now acting on cron", cronDef);
|
||||
safeRun(async () => {
|
||||
try {
|
||||
await plug.invoke(cronDef.handler, []);
|
||||
await plug.invoke(name, [cronDef]);
|
||||
} catch (e: any) {
|
||||
console.error("Execution of cron function failed", e);
|
||||
}
|
||||
@ -53,15 +57,17 @@ export class NodeCronFeature implements Feature<CronHook> {
|
||||
}
|
||||
|
||||
validateManifest(manifest: Manifest<CronHook>): string[] {
|
||||
const crons = manifest.hooks.crons;
|
||||
let errors = [];
|
||||
if (crons) {
|
||||
for (const [name, functionDef] of Object.entries(manifest.functions)) {
|
||||
if (!functionDef.cron) {
|
||||
continue;
|
||||
}
|
||||
const crons = Array.isArray(functionDef.cron)
|
||||
? functionDef.cron
|
||||
: [functionDef.cron];
|
||||
for (let cronDef of crons) {
|
||||
if (!cron.validate(cronDef.cron)) {
|
||||
errors.push(`Invalid cron expression ${cronDef.cron}`);
|
||||
}
|
||||
if (!manifest.functions[cronDef.handler]) {
|
||||
errors.push(`Cron handler function ${cronDef.handler} not found`);
|
||||
if (!cron.validate(cronDef)) {
|
||||
errors.push(`Invalid cron expression ${cronDef}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -82,9 +82,6 @@ test("Run a Node sandbox", async () => {
|
||||
})()`,
|
||||
},
|
||||
},
|
||||
hooks: {
|
||||
events: {},
|
||||
},
|
||||
},
|
||||
createSandbox
|
||||
);
|
||||
|
10
plugbox/syscall/event.ts
Normal file
10
plugbox/syscall/event.ts
Normal file
@ -0,0 +1,10 @@
|
||||
import { SysCallMapping } from "../system";
|
||||
import { EventFeature } from "../feature/event";
|
||||
|
||||
export function eventSyscalls(eventFeature: EventFeature): SysCallMapping {
|
||||
return {
|
||||
async dispatch(ctx, eventName: string, data: any) {
|
||||
return eventFeature.dispatchEvent(eventName, data);
|
||||
},
|
||||
};
|
||||
}
|
@ -3,11 +3,11 @@ import { SysCallMapping } from "../system";
|
||||
|
||||
export function fetchSyscalls(): SysCallMapping {
|
||||
return {
|
||||
async fetchJson(ctx, url: RequestInfo, init: RequestInit) {
|
||||
async json(ctx, url: RequestInfo, init: RequestInit) {
|
||||
let resp = await fetch(url, init);
|
||||
return resp.json();
|
||||
},
|
||||
async fetchText(ctx, url: RequestInfo, init: RequestInit) {
|
||||
async text(ctx, url: RequestInfo, init: RequestInit) {
|
||||
let resp = await fetch(url, init);
|
||||
return resp.text();
|
||||
},
|
||||
|
@ -12,7 +12,6 @@ test("Test store", async () => {
|
||||
let plug = await system.load(
|
||||
"test",
|
||||
{
|
||||
hooks: {},
|
||||
functions: {
|
||||
test1: {
|
||||
code: `(() => {
|
||||
|
@ -28,7 +28,6 @@ test("Test store", async () => {
|
||||
let plug = await system.load(
|
||||
"test",
|
||||
{
|
||||
hooks: {},
|
||||
functions: {
|
||||
test1: {
|
||||
code: `(() => {
|
||||
|
@ -2,17 +2,16 @@ import { System } from "./system";
|
||||
|
||||
export interface Manifest<HookT> {
|
||||
requiredPermissions?: string[];
|
||||
hooks: HookT;
|
||||
functions: {
|
||||
[key: string]: FunctionDef;
|
||||
[key: string]: FunctionDef<HookT>;
|
||||
};
|
||||
}
|
||||
|
||||
export interface FunctionDef {
|
||||
export type FunctionDef<HookT> = {
|
||||
path?: string;
|
||||
code?: string;
|
||||
env?: RuntimeEnvironment;
|
||||
}
|
||||
} & HookT;
|
||||
|
||||
export type RuntimeEnvironment = "client" | "server";
|
||||
|
||||
|
@ -1,95 +0,0 @@
|
||||
{
|
||||
"hooks": {
|
||||
"commands": {
|
||||
"Navigate To page": {
|
||||
"invoke": "linkNavigate",
|
||||
"key": "Ctrl-Enter",
|
||||
"mac": "Cmd-Enter"
|
||||
},
|
||||
"Insert Current Date": {
|
||||
"invoke": "insertToday",
|
||||
"slashCommand": "today"
|
||||
},
|
||||
"Toggle : Heading 1": {
|
||||
"invoke": "toggle_h1",
|
||||
"mac": "Cmd-1",
|
||||
"key": "Ctrl-1"
|
||||
},
|
||||
"Toggle : Heading 2": {
|
||||
"invoke": "toggle_h2",
|
||||
"mac": "Cmd-2",
|
||||
"key": "Ctrl-2"
|
||||
},
|
||||
"Page: Delete": {
|
||||
"invoke": "deletePage"
|
||||
},
|
||||
"Page: Rename": {
|
||||
"invoke": "renamePage"
|
||||
},
|
||||
"Pages: Reindex": {
|
||||
"invoke": "reindexPages"
|
||||
},
|
||||
"Pages: Back Links": {
|
||||
"invoke": "showBackLinks"
|
||||
}
|
||||
},
|
||||
"events": {
|
||||
"page:click": ["taskToggle", "clickNavigate"],
|
||||
"editor:complete": ["pageComplete"],
|
||||
"page:index": ["indexLinks"],
|
||||
"load": ["welcome"]
|
||||
},
|
||||
"endpoints": [
|
||||
{
|
||||
"method": "GET",
|
||||
"path": "/",
|
||||
"handler": "endpointTest"
|
||||
}
|
||||
]
|
||||
},
|
||||
"functions": {
|
||||
"indexLinks": {
|
||||
"path": "./page.ts:indexLinks"
|
||||
},
|
||||
"deletePage": {
|
||||
"path": "./page.ts:deletePage"
|
||||
},
|
||||
"showBackLinks": {
|
||||
"path": "./page.ts:showBackLinks"
|
||||
},
|
||||
"renamePage": {
|
||||
"path": "./page.ts:renamePage"
|
||||
},
|
||||
"reindexPages": {
|
||||
"path": "./page.ts:reindex"
|
||||
},
|
||||
"pageComplete": {
|
||||
"path": "./navigate.ts:pageComplete"
|
||||
},
|
||||
"linkNavigate": {
|
||||
"path": "./navigate.ts:linkNavigate"
|
||||
},
|
||||
"clickNavigate": {
|
||||
"path": "./navigate.ts:clickNavigate"
|
||||
},
|
||||
"taskToggle": {
|
||||
"path": "./task.ts:taskToggle"
|
||||
},
|
||||
"insertToday": {
|
||||
"path": "./dates.ts:insertToday"
|
||||
},
|
||||
"toggle_h1": {
|
||||
"path": "./markup.ts:toggleH1"
|
||||
},
|
||||
"toggle_h2": {
|
||||
"path": "./markup.ts:toggleH2"
|
||||
},
|
||||
"endpointTest": {
|
||||
"path": "./server.ts:endpointTest"
|
||||
},
|
||||
"welcome": {
|
||||
"path": "./server.ts:welcome",
|
||||
"env": "server"
|
||||
}
|
||||
}
|
||||
}
|
46
plugs/core/core.plug.yaml
Normal file
46
plugs/core/core.plug.yaml
Normal file
@ -0,0 +1,46 @@
|
||||
functions:
|
||||
indexLinks:
|
||||
path: "./page.ts:indexLinks"
|
||||
events:
|
||||
- page:index
|
||||
deletePage:
|
||||
path: "./page.ts:deletePage"
|
||||
command:
|
||||
name: "Page: Delete"
|
||||
showBackLinks:
|
||||
path: "./page.ts:showBackLinks"
|
||||
command:
|
||||
name: "Page: Back Links"
|
||||
renamePage:
|
||||
path: "./page.ts:renamePage"
|
||||
command:
|
||||
name: "Page: Rename"
|
||||
pageComplete:
|
||||
path: "./navigate.ts:pageComplete"
|
||||
events:
|
||||
- editor:complete
|
||||
linkNavigate:
|
||||
path: "./navigate.ts:linkNavigate"
|
||||
command:
|
||||
name: Navigate To page
|
||||
key: Ctrl-Enter
|
||||
mac: Cmd-Enter
|
||||
clickNavigate:
|
||||
path: "./navigate.ts:clickNavigate"
|
||||
events:
|
||||
- page:click
|
||||
taskToggle:
|
||||
path: "./task.ts:taskToggle"
|
||||
events:
|
||||
- page:click
|
||||
insertToday:
|
||||
path: "./dates.ts:insertToday"
|
||||
command:
|
||||
name: Insert Current Date
|
||||
slashCommand: today
|
||||
welcome:
|
||||
path: "./server.ts:welcome"
|
||||
events:
|
||||
- load
|
||||
env: server
|
||||
|
@ -1,37 +0,0 @@
|
||||
{
|
||||
"requiredPermissions": ["shell"],
|
||||
"hooks": {
|
||||
"commands": {
|
||||
"Git: Snapshot": {
|
||||
"invoke": "snapshotCommand"
|
||||
},
|
||||
"Git: Sync": {
|
||||
"invoke": "syncCommand"
|
||||
}
|
||||
},
|
||||
"crons": [
|
||||
{
|
||||
"cron": "*/15 * * * *",
|
||||
"handler": "commit"
|
||||
}
|
||||
]
|
||||
},
|
||||
"functions": {
|
||||
"snapshotCommand": {
|
||||
"path": "./git.ts:snapshotCommand",
|
||||
"env": "client"
|
||||
},
|
||||
"syncCommand": {
|
||||
"path": "./git.ts:syncCommand",
|
||||
"env": "client"
|
||||
},
|
||||
"commit": {
|
||||
"path": "./git.ts:commit",
|
||||
"env": "server"
|
||||
},
|
||||
"sync": {
|
||||
"path": "./git.ts:sync",
|
||||
"env": "server"
|
||||
}
|
||||
}
|
||||
}
|
22
plugs/git/git.plug.yaml
Normal file
22
plugs/git/git.plug.yaml
Normal file
@ -0,0 +1,22 @@
|
||||
requiredPermissions:
|
||||
- shell
|
||||
functions:
|
||||
snapshotCommand:
|
||||
path: "./git.ts:snapshotCommand"
|
||||
env: client
|
||||
command:
|
||||
name: "Git: Snapshot"
|
||||
syncCommand:
|
||||
path: "./git.ts:syncCommand"
|
||||
env: client
|
||||
command:
|
||||
name: "Git: Sync"
|
||||
commit:
|
||||
path: "./git.ts:commit"
|
||||
env: server
|
||||
cron:
|
||||
- "*/15 * * * *"
|
||||
sync:
|
||||
path: "./git.ts:sync"
|
||||
env: server
|
||||
|
@ -9,16 +9,16 @@ import {hideBin} from "yargs/helpers";
|
||||
import {SilverBulletHooks} from "../common/manifest";
|
||||
import {ExpressServer} from "./express_server";
|
||||
import {DiskPlugLoader} from "../plugbox/plug_loader";
|
||||
import { NodeCronFeature } from "../plugbox/feature/node_cron";
|
||||
import {NodeCronFeature} from "../plugbox/feature/node_cron";
|
||||
import shellSyscalls from "../plugbox/syscall/shell.node";
|
||||
import { System } from "../plugbox/system";
|
||||
import {System} from "../plugbox/system";
|
||||
|
||||
let args = yargs(hideBin(process.argv))
|
||||
.option("port", {
|
||||
type: "number",
|
||||
default: 3000,
|
||||
})
|
||||
.parse();
|
||||
.option("port", {
|
||||
type: "number",
|
||||
default: 3000,
|
||||
})
|
||||
.parse();
|
||||
|
||||
if (!args._.length) {
|
||||
console.error("Usage: silverbullet <path-to-pages>");
|
||||
@ -50,20 +50,20 @@ socketServer.init().catch((e) => {
|
||||
|
||||
const expressServer = new ExpressServer(app, pagesPath, distDir, system);
|
||||
expressServer
|
||||
.init()
|
||||
.then(async () => {
|
||||
let plugLoader = new DiskPlugLoader(
|
||||
system,
|
||||
`${__dirname}/../../plugs/dist`
|
||||
);
|
||||
await plugLoader.loadPlugs();
|
||||
plugLoader.watcher();
|
||||
system.registerSyscalls("shell", ["shell"], shellSyscalls(pagesPath));
|
||||
system.addFeature(new NodeCronFeature());
|
||||
server.listen(port, () => {
|
||||
console.log(`Server listening on port ${port}`);
|
||||
});
|
||||
})
|
||||
.catch((e) => {
|
||||
console.error(e);
|
||||
.init()
|
||||
.then(async () => {
|
||||
let plugLoader = new DiskPlugLoader(
|
||||
system,
|
||||
`${__dirname}/../../plugs/dist`
|
||||
);
|
||||
await plugLoader.loadPlugs();
|
||||
plugLoader.watcher();
|
||||
system.registerSyscalls("shell", ["shell"], shellSyscalls(pagesPath));
|
||||
system.addFeature(new NodeCronFeature());
|
||||
server.listen(port, () => {
|
||||
console.log(`Server listening on port ${port}`);
|
||||
});
|
||||
})
|
||||
.catch((e) => {
|
||||
console.error(e);
|
||||
});
|
||||
|
@ -163,15 +163,23 @@ export class Editor implements AppEventDispatcher {
|
||||
console.log("Loaded plugs, now updating editor commands");
|
||||
this.editorCommands.clear();
|
||||
for (let plug of this.system.loadedPlugs.values()) {
|
||||
const cmds = plug.manifest!.hooks.commands;
|
||||
for (let name in cmds) {
|
||||
let cmd = cmds[name];
|
||||
this.editorCommands.set(name, {
|
||||
command: cmd,
|
||||
run: async (arg): Promise<any> => {
|
||||
return await plug.invoke(cmd.invoke, [arg]);
|
||||
},
|
||||
});
|
||||
for (const [name, functionDef] of Object.entries(
|
||||
plug.manifest!.functions
|
||||
)) {
|
||||
if (!functionDef.command) {
|
||||
continue;
|
||||
}
|
||||
const cmds = Array.isArray(functionDef.command)
|
||||
? functionDef.command
|
||||
: [functionDef.command];
|
||||
for (let cmd of cmds) {
|
||||
this.editorCommands.set(cmd.name, {
|
||||
command: cmd,
|
||||
run: async (arg): Promise<any> => {
|
||||
return await plug.invoke(name, [arg]);
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
this.viewDispatch({
|
||||
|
Loading…
Reference in New Issue
Block a user