Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 8 additions & 4 deletions .vitepress/sidebars/guides.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,6 @@ export const guidesSidebar: DefaultTheme.SidebarItem[] = [
text: "Customizing Context Menus",
link: "/guides/components/menu",
},
{
text: "Handling Backend Events",
link: "/guides/components/backend_events",
},
{
text: "Using the Component Library",
link: "/guides/components/styling",
Expand All @@ -50,6 +46,10 @@ export const guidesSidebar: DefaultTheme.SidebarItem[] = [
text: "Creating and Calling a Custom Function",
link: "/guides/components/rpc",
},
{
text: "Handling Backend Events",
link: "/guides/components/backend_events",
},
{
text: "Sending HTTP Requests",
link: "/guides/components/request",
Expand Down Expand Up @@ -83,6 +83,10 @@ export const guidesSidebar: DefaultTheme.SidebarItem[] = [
{
text: "Shared",
items: [
{
text: "Adding Files",
link: "/guides/components/files",
},
{
text: "Using Environment Variables",
link: "/guides/components/env",
Expand Down
Binary file added src/_images/backend_assets_key.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/_images/frontend_assets_key.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/_images/view_file_frontend.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 2 additions & 2 deletions src/guides/components/fetch.md
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ To view the entire script, expand the following:
<details>
<summary>Full Script</summary>

``` js
``` ts
import type { SDK, DefineAPI } from "caido:plugin";
import { Request as FetchRequest, fetch } from "caido:http";

Expand Down Expand Up @@ -188,7 +188,7 @@ To view how the endpoint can be called with a frontend plugin, expand the follow
<details>
<summary>Full Script</summary>

``` js
``` ts
import type { Caido } from "@caido/sdk-frontend";
import type { API } from "../../backend/src/index.ts";

Expand Down
181 changes: 181 additions & 0 deletions src/guides/components/files.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,181 @@
# Adding Files

To include additional files in your Caido plugins, you can add the `assets` property key to either the frontend or backend component objects in the `caido.config.ts` file. The key value is an array that stores the locations of any files accessible to the plugin.

In this guide we'll cover how to add a file to a plugin named `myfile.txt`.

## Shared Steps

In the root directory of your plugin package, create a new directory named `assets`. Within this directory, create the `myfile.txt` file, write content to it, and save it. The file can now be referenced with:

``` ts
assets : ["./assets/myfile.txt"]
```

::: tip TIPS

Glob syntax (`*`) is supported to reference multiple files:

- `/path/*.txt`: Will include all `.txt` files in the path directory.
- `/**/file.txt`: Will include any `file.txt` within any directory.

Files and directories are included differently:

- For a file, it will copy it at the root of the output assets directory.
- For a directory, it will copy it recursively in the output assets directory.
:::

::: info
The `assets` key can also be added to a plugin's `manifest.json` file. However, multiple locations can not be defined with this method.
:::

## Adding Files to the Frontend Component

Open the `caido.config.ts` file and add the property to the `frontend` component object:

<img alt="Event output." src="/_images/frontend_assets_key.png" center/>

### /packages/frontend/src/index.ts

To read the file, the `sdk.assets.get()` method can be called.

``` ts
const file = await sdk.assets.get("myfile.txt");
```

::: tip
To view the entire frontend script, expand the following:

<details>
<summary>Full Script</summary>

``` ts
import "./styles/index.css";

import type { FrontendSDK } from "./types";

// Note that the init function is async to account for fetching the files.
export const init = async (sdk: FrontendSDK) => {

const root = document.createElement("div");
Object.assign(root.style, {
height: "100%",
width: "100%",
});

root.id = `plugin--frontend-vanilla`;

const parent = document.createElement("div");
parent.classList.add("h-full", "flex", "justify-center", "items-center");

const container = document.createElement("div");
container.classList.add("flex", "flex-col", "gap-1", "p-4");

const file = await sdk.assets.get("myfile.txt");
// For large files or to process in chunks, use file.asReadableStream() instead.
const content = await file.asString();
container.textContent = content;

parent.appendChild(container);

root.appendChild(parent);

sdk.navigation.addPage("/view-file-plugin", {
body: root,
});

sdk.sidebar.registerItem("View File Plugin", "/view-file-plugin");
};
```

</details>
:::

## Adding Files to the Backend Component

Open the `caido.config.ts` file and add the property to the `backend` component object:

<img alt="Event output." src="/_images/backend_assets_key.png" center/>

### /packages/backend/src/index.ts

By [creating a custom backend function](./rpc.md) to read the file, we can later call it from the frontend:

``` ts
import type { DefineAPI, SDK } from "caido:plugin";
import { readFile } from 'fs/promises';
import path from "path";

const readMyFile = async (sdk: SDK) => {
try {
const filePath = path.join(sdk.meta.assetsPath(), "myfile.txt");
const contents = await readFile(filePath, { encoding: 'utf8' });
sdk.console.log(contents);
return contents;
} catch (err: any) {
sdk.console.error(err.message);
throw err;
}
};

export type API = DefineAPI<{
readMyFile: typeof readMyFile;
}>;

export function init(sdk: SDK<API>) {
sdk.api.register("readMyFile", readMyFile);
}
```

::: tip
To view the entire frontend script, expand the following:

<details>
<summary>Full Script</summary>

``` ts
import "./styles/index.css";

import type { FrontendSDK } from "./types";

export const init = async (sdk: FrontendSDK) => {
const root = document.createElement("div");
Object.assign(root.style, {
height: "100%",
width: "100%",
});

root.id = `plugin--frontend-vanilla`;

const parent = document.createElement("div");
parent.classList.add("h-full", "flex", "justify-center", "items-center");

const container = document.createElement("div");
container.classList.add("flex", "flex-col", "gap-1", "p-4");

try {
// Call the backend readMyFile() function to read myfile.txt.
const content = await sdk.backend.readMyFile();
container.textContent = content;
} catch (error: any) {
container.textContent = `Error reading file: ${error.message}`;
}

parent.appendChild(container);

root.appendChild(parent);

sdk.navigation.addPage("/view-file-plugin", {
body: root,
});

sdk.sidebar.registerItem("View File Plugin", "/view-file-plugin");
};
```

</details>
:::

## The Result

<img alt="Event output." src="/_images/view_file_frontend.png" center/>
Loading