E2E workflow for creating docs
This commit is contained in:
parent
f9dafdfc88
commit
0db1380d27
3 changed files with 106 additions and 47 deletions
|
|
@ -1,21 +1,27 @@
|
||||||
import { TAbstractFile } from "obsidian";
|
import { TAbstractFile, TFile } from "obsidian";
|
||||||
import { FileEventHandler } from "./file-event-handler";
|
import { FileEventHandler } from "./file-event-handler";
|
||||||
import { Logger } from "src/logger";
|
import { Logger } from "src/logger";
|
||||||
|
import { Syncer } from "src/syncer/syncer";
|
||||||
|
|
||||||
export class SyncEventHandler implements FileEventHandler {
|
export class SyncEventHandler implements FileEventHandler {
|
||||||
onCreate(path: TAbstractFile) {
|
constructor(private syncer: Syncer) {}
|
||||||
Logger.getInstance().info(`File created: ${path}`);
|
|
||||||
|
async onCreate(file: TAbstractFile) {
|
||||||
|
if (file instanceof TFile) {
|
||||||
|
Logger.getInstance().info(`File created: ${file}`);
|
||||||
|
this.syncer.onCreate(file.path, await file.vault.read(file));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onDelete(path: TAbstractFile) {
|
onDelete(file: TAbstractFile) {
|
||||||
Logger.getInstance().info(`File deleted: ${path}`);
|
Logger.getInstance().info(`File deleted: ${file}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
onRename(path: TAbstractFile, oldPath: string) {
|
onRename(file: TAbstractFile, oldPath: string) {
|
||||||
Logger.getInstance().info(`File renamed: ${oldPath} -> ${path}`);
|
Logger.getInstance().info(`File renamed: ${oldPath} -> ${file}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
onModify(path: TAbstractFile) {
|
onModify(file: TAbstractFile) {
|
||||||
Logger.getInstance().info(`File modified: ${path}`);
|
Logger.getInstance().info(`File modified: ${file}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,8 +10,8 @@ import {
|
||||||
WorkspaceLeaf,
|
WorkspaceLeaf,
|
||||||
} from "obsidian";
|
} from "obsidian";
|
||||||
|
|
||||||
import * as plugin from "../../backend/sync_wasm/pkg/sync_wasm.js";
|
import * as plugin from "../../backend/sync_lib/pkg/sync_lib.js";
|
||||||
import * as wasmBin from "../../backend/sync_wasm/pkg/sync_wasm_bg.wasm";
|
import * as wasmBin from "../../backend/sync_lib/pkg/sync_lib_bg.wasm";
|
||||||
import { getSystemErrorName } from "util";
|
import { getSystemErrorName } from "util";
|
||||||
import { SyncSettingsTab } from "./settings/settings-tab.js";
|
import { SyncSettingsTab } from "./settings/settings-tab.js";
|
||||||
import { SyncView } from "./views/sync-view.js";
|
import { SyncView } from "./views/sync-view.js";
|
||||||
|
|
@ -22,6 +22,7 @@ import {
|
||||||
} from "./settings/settings.js";
|
} from "./settings/settings.js";
|
||||||
import { Logger } from "./logger.js";
|
import { Logger } from "./logger.js";
|
||||||
import { SyncEventHandler } from "./events/sync-event-handler.js";
|
import { SyncEventHandler } from "./events/sync-event-handler.js";
|
||||||
|
import { Syncer } from "./syncer/syncer.js";
|
||||||
|
|
||||||
export default class SyncPlugin extends Plugin {
|
export default class SyncPlugin extends Plugin {
|
||||||
async onload() {
|
async onload() {
|
||||||
|
|
@ -29,7 +30,26 @@ export default class SyncPlugin extends Plugin {
|
||||||
|
|
||||||
await plugin.default(Promise.resolve((wasmBin as any).default));
|
await plugin.default(Promise.resolve((wasmBin as any).default));
|
||||||
|
|
||||||
const eventHandler = new SyncEventHandler();
|
// This adds an editor command that can perform some operation on the current editor instance
|
||||||
|
this.addCommand({
|
||||||
|
id: "sample-editor-command",
|
||||||
|
name: "Sample editor command",
|
||||||
|
editorCallback: (editor: Editor, view: MarkdownView) => {
|
||||||
|
console.log(editor.getSelection());
|
||||||
|
editor.replaceSelection("Sample Editor Command");
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const settingsContainer = new SettingsContainer(
|
||||||
|
this,
|
||||||
|
await this.loadData()
|
||||||
|
);
|
||||||
|
this.addSettingTab(
|
||||||
|
new SyncSettingsTab(this.app, this, settingsContainer)
|
||||||
|
);
|
||||||
|
|
||||||
|
const syncer = new Syncer(settingsContainer);
|
||||||
|
const eventHandler = new SyncEventHandler(syncer);
|
||||||
|
|
||||||
[
|
[
|
||||||
this.app.vault.on(
|
this.app.vault.on(
|
||||||
|
|
@ -50,49 +70,22 @@ export default class SyncPlugin extends Plugin {
|
||||||
),
|
),
|
||||||
].forEach((event) => this.registerEvent(event));
|
].forEach((event) => this.registerEvent(event));
|
||||||
|
|
||||||
// This creates an icon in the left ribbon.
|
|
||||||
const ribbonIconEl = this.addRibbonIcon(
|
|
||||||
"dice",
|
|
||||||
"Sample Plugin",
|
|
||||||
(evt: MouseEvent) => {
|
|
||||||
// Called when the user clicks the icon.
|
|
||||||
new Notice("This is a notice!");
|
|
||||||
}
|
|
||||||
);
|
|
||||||
// Perform additional things with the ribbon
|
|
||||||
ribbonIconEl.addClass("my-plugin-ribbon-class");
|
|
||||||
|
|
||||||
// This adds a status bar item to the bottom of the app. Does not work on mobile apps.
|
|
||||||
const statusBarItemEl = this.addStatusBarItem();
|
|
||||||
statusBarItemEl.setText("Status Bar Text");
|
|
||||||
|
|
||||||
// This adds an editor command that can perform some operation on the current editor instance
|
|
||||||
this.addCommand({
|
|
||||||
id: "sample-editor-command",
|
|
||||||
name: "Sample editor command",
|
|
||||||
editorCallback: (editor: Editor, view: MarkdownView) => {
|
|
||||||
console.log(editor.getSelection());
|
|
||||||
editor.replaceSelection("Sample Editor Command");
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const settingsContainer = new SettingsContainer(
|
|
||||||
this,
|
|
||||||
await this.loadData()
|
|
||||||
);
|
|
||||||
this.addSettingTab(
|
|
||||||
new SyncSettingsTab(this.app, this, settingsContainer)
|
|
||||||
);
|
|
||||||
|
|
||||||
// When registering intervals, this function will automatically clear the interval when the plugin is disabled.
|
// When registering intervals, this function will automatically clear the interval when the plugin is disabled.
|
||||||
this.registerInterval(
|
this.registerInterval(
|
||||||
window.setInterval(() => console.log("setInterval"), 5 * 60 * 1000)
|
window.setInterval(() => console.log("setInterval"), 5 * 60 * 1000)
|
||||||
);
|
);
|
||||||
this.registerView(SyncView.TYPE, (leaf) => new SyncView(leaf));
|
this.registerView(SyncView.TYPE, (leaf) => new SyncView(leaf));
|
||||||
|
|
||||||
this.addRibbonIcon("dice", "Activate view", () => {
|
const ribbonIconEl = this.addRibbonIcon(
|
||||||
|
"dice",
|
||||||
|
"Sample Plugin",
|
||||||
|
(evt: MouseEvent) => {
|
||||||
this.activateView();
|
this.activateView();
|
||||||
});
|
|
||||||
|
new Notice("This is a notice!");
|
||||||
|
}
|
||||||
|
);
|
||||||
|
ribbonIconEl.addClass("my-plugin-ribbon-class");
|
||||||
}
|
}
|
||||||
|
|
||||||
onunload() {}
|
onunload() {}
|
||||||
|
|
|
||||||
60
plugin/src/syncer/syncer.ts
Normal file
60
plugin/src/syncer/syncer.ts
Normal file
|
|
@ -0,0 +1,60 @@
|
||||||
|
import { SettingsContainer, SyncSettings } from "src/settings/settings";
|
||||||
|
|
||||||
|
import * as plugin from "../../../backend/sync_lib/pkg/sync_lib.js";
|
||||||
|
|
||||||
|
import createClient, { Client } from "openapi-fetch";
|
||||||
|
import type { components, paths } from "./types"; // generated by openapi-typescript
|
||||||
|
import { Logger } from "src/logger.js";
|
||||||
|
|
||||||
|
export class Syncer {
|
||||||
|
private static vault_id = "default";
|
||||||
|
private client: Client<paths>;
|
||||||
|
|
||||||
|
public constructor(private settings: SettingsContainer) {
|
||||||
|
this.createClient(settings.getSettings());
|
||||||
|
settings.onChange((s) => this.createClient(s));
|
||||||
|
}
|
||||||
|
|
||||||
|
private createClient(settings: SyncSettings) {
|
||||||
|
this.client = createClient<paths>({
|
||||||
|
baseUrl: settings.remoteUri,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public async onCreate(
|
||||||
|
relativePath: string,
|
||||||
|
content: string
|
||||||
|
): Promise<
|
||||||
|
components["schemas"]["DocumentVersionWithoutContent"] | undefined
|
||||||
|
> {
|
||||||
|
let response = await this.client.POST("/vaults/{vault_id}/documents", {
|
||||||
|
params: {
|
||||||
|
path: { vault_id: Syncer.vault_id },
|
||||||
|
header: {
|
||||||
|
authorization:
|
||||||
|
"Bearer " + this.settings.getSettings().token,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
body: {
|
||||||
|
contentBase64: plugin.string_to_base64(content),
|
||||||
|
createdDate: new Date().toISOString(),
|
||||||
|
isBinary: true,
|
||||||
|
relativePath,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
Logger.getInstance().info(
|
||||||
|
"Created document " + JSON.stringify(response.data)
|
||||||
|
);
|
||||||
|
|
||||||
|
return response.data;
|
||||||
|
}
|
||||||
|
|
||||||
|
private uri(path: string) {
|
||||||
|
let uri = this.settings.getSettings().remoteUri;
|
||||||
|
if (!uri.endsWith("/")) {
|
||||||
|
uri += "/";
|
||||||
|
}
|
||||||
|
return uri + path;
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue