From 3c6a13ad02a5ee0975223290ca1a4f505fd279f8 Mon Sep 17 00:00:00 2001 From: corb3nik Date: Thu, 18 Dec 2025 09:44:00 -0500 Subject: [PATCH] add docs --- src/guides/filters.md | 151 +++++++++++++++++++++++++++++++++++ src/guides/match_replace.md | 154 ++++++++++++++++++++++++++++++++++++ src/guides/scopes.md | 154 ++++++++++++++++++++++++++++++++++++ 3 files changed, 459 insertions(+) diff --git a/src/guides/filters.md b/src/guides/filters.md index a93477c..b832ccc 100644 --- a/src/guides/filters.md +++ b/src/guides/filters.md @@ -51,6 +51,96 @@ To delete a filter: await sdk.filters.delete(filterId); ``` +### Getting the Current Filter + +To get the currently selected filter: + +```ts +const currentFilter = sdk.filters.getCurrentFilter(); +``` + +Returns the currently selected filter, or `undefined` if no filter is selected. + +### Subscribing to Filter Changes + +To subscribe to changes in the currently selected filter: + +```ts +const handler = sdk.filters.onCurrentFilterChange((event) => { + console.log(`Filter ${event.filterId} got selected!`); +}); + +// Later, stop listening +handler.stop(); +``` + +The callback receives an event object with a `filterId` property that contains the ID of the newly selected filter, or `undefined` if no filter is selected. + +::: info +The subscription handler returns an object with a `stop()` method that can be called to unsubscribe from filter changes. +::: + +## Adding Components to Filter Slots + +You can add custom components to filter slots to extend the Filters page UI. Available slots are: + +- `FilterSlot.CreateHeader` - The header area of the preset form create component +- `FilterSlot.UpdateHeader` - The header area of the preset form update component + +### Adding a Button to a Slot + +Add a button with a label, icon, and click handler: + +```ts +import { FilterSlot } from "@caido/sdk-frontend"; + +sdk.filters.addToSlot(FilterSlot.UpdateHeader, { + type: "Button", + label: "My Button", + icon: "my-icon", + onClick: () => { + console.log("Button clicked"); + }, +}); +``` + +### Adding a Command to a Slot + +Add a button that triggers a registered command: + +```ts +import { FilterSlot } from "@caido/sdk-frontend"; + +// First register the command +sdk.commands.register("my-command", { + name: "My Command", + run: () => { + sdk.window.showToast("Command executed", { variant: "info" }); + }, +}); + +// Then add to slot +sdk.filters.addToSlot(FilterSlot.UpdateHeader, { + type: "Command", + commandId: "my-command", + icon: "my-icon", +}); +``` + +### Adding a Custom Component to a Slot + +Add a custom Vue component: + +```ts +import { FilterSlot } from "@caido/sdk-frontend"; +import MyComponent from "./MyComponent.vue"; + +sdk.filters.addToSlot(FilterSlot.CreateHeader, { + type: "Custom", + definition: MyComponent, +}); +``` + ## Setting HTTPQL Queries on Pages ### HTTP History @@ -206,3 +296,64 @@ const filter = await sdk.filters.create({ // Use the filter in a query sdk.httpHistory.setQuery("preset:success-get"); ``` + +### Tracking Current Filter Changes + +This example subscribes to filter selection changes and logs information about the currently selected filter whenever it changes. + +```ts +import type { Caido } from "@caido/sdk-frontend"; + +export type CaidoSDK = Caido; + +export const init = (sdk: CaidoSDK) => { + const handler = sdk.filters.onCurrentFilterChange((event) => { + if (event.filterId) { + const filter = sdk.filters.getCurrentFilter(); + if (filter) { + sdk.log.info(`Filter selected: ${filter.name} (${filter.alias})`); + sdk.log.info(`Query: ${filter.query}`); + } + } else { + sdk.log.info("No filter selected"); + } + }); + + // Store handler for cleanup if needed + // handler.stop(); +}; +``` + +### Adding Custom Actions to Filter Slots + +This example adds a custom button to the filter update header that duplicates the current filter when clicked. + +```ts +import type { Caido } from "@caido/sdk-frontend"; +import { FilterSlot } from "@caido/sdk-frontend"; + +export type CaidoSDK = Caido; + +export const init = (sdk: CaidoSDK) => { + sdk.filters.addToSlot(FilterSlot.UpdateHeader, { + type: "Button", + label: "Duplicate Filter", + icon: "fas fa-copy", + onClick: async () => { + const currentFilter = sdk.filters.getCurrentFilter(); + if (currentFilter) { + const duplicated = await sdk.filters.create({ + name: `${currentFilter.name} (Copy)`, + alias: `${currentFilter.alias}-copy`, + query: currentFilter.query, + }); + sdk.window.showToast(`Filter "${duplicated.name}" created`, { + variant: "success", + }); + } else { + sdk.window.showToast("No filter selected", { variant: "warning" }); + } + }, + }); +}; +``` diff --git a/src/guides/match_replace.md b/src/guides/match_replace.md index 167672a..d98db35 100644 --- a/src/guides/match_replace.md +++ b/src/guides/match_replace.md @@ -122,6 +122,96 @@ To clear the selection: sdk.matchReplace.selectRule(undefined); ``` +### Getting the Current Rule + +To get the currently selected rule: + +```ts +const currentRule = sdk.matchReplace.getCurrentRule(); +``` + +Returns the currently selected rule, or `undefined` if no rule is selected. + +### Subscribing to Rule Changes + +To subscribe to changes in the currently selected rule: + +```ts +const handler = sdk.matchReplace.onCurrentRuleChange((event) => { + console.log(`Rule ${event.ruleId} got selected!`); +}); + +// Later, stop listening +handler.stop(); +``` + +The callback receives an event object with a `ruleId` property that contains the ID of the newly selected rule, or `undefined` if no rule is selected. + +::: info +The subscription handler returns an object with a `stop()` method that can be called to unsubscribe from rule changes. +::: + +## Adding Components to Match and Replace Slots + +You can add custom components to match and replace slots to extend the Match and Replace page UI. Available slots are: + +- `MatchReplaceSlot.CreateHeader` - The header area of the rule form create component +- `MatchReplaceSlot.UpdateHeader` - The header area of the rule form update component + +### Adding a Button to a Slot + +Add a button with a label, icon, and click handler: + +```ts +import { MatchReplaceSlot } from "@caido/sdk-frontend"; + +sdk.matchReplace.addToSlot(MatchReplaceSlot.UpdateHeader, { + type: "Button", + label: "My Button", + icon: "my-icon", + onClick: () => { + console.log("Button clicked"); + }, +}); +``` + +### Adding a Command to a Slot + +Add a button that triggers a registered command: + +```ts +import { MatchReplaceSlot } from "@caido/sdk-frontend"; + +// First register the command +sdk.commands.register("my-command", { + name: "My Command", + run: () => { + sdk.window.showToast("Command executed", { variant: "info" }); + }, +}); + +// Then add to slot +sdk.matchReplace.addToSlot(MatchReplaceSlot.UpdateHeader, { + type: "Command", + commandId: "my-command", + icon: "my-icon", +}); +``` + +### Adding a Custom Component to a Slot + +Add a custom Vue component: + +```ts +import { MatchReplaceSlot } from "@caido/sdk-frontend"; +import MyComponent from "./MyComponent.vue"; + +sdk.matchReplace.addToSlot(MatchReplaceSlot.CreateHeader, { + type: "Custom", + definition: MyComponent, +}); +``` + ## Examples ### Auto-Enable Rules @@ -176,3 +266,67 @@ export const init = (sdk: CaidoSDK) => { }); }; ``` + +### Tracking Current Rule Changes + +This example subscribes to rule selection changes and logs information about the currently selected rule whenever it changes. + +```ts +import type { Caido } from "@caido/sdk-frontend"; + +export type CaidoSDK = Caido; + +export const init = (sdk: CaidoSDK) => { + const handler = sdk.matchReplace.onCurrentRuleChange((event) => { + if (event.ruleId) { + const rule = sdk.matchReplace.getCurrentRule(); + if (rule) { + sdk.log.info(`Rule selected: ${rule.name}`); + sdk.log.info(`Query: ${rule.query}`); + sdk.log.info(`Enabled: ${rule.isEnabled}`); + } + } else { + sdk.log.info("No rule selected"); + } + }); + + // Store handler for cleanup if needed + // handler.stop(); +}; +``` + +### Adding Custom Actions to Match and Replace Slots + +This example adds a custom button to the rule update header that duplicates the current rule when clicked. + +```ts +import type { Caido } from "@caido/sdk-frontend"; +import { MatchReplaceSlot } from "@caido/sdk-frontend"; + +export type CaidoSDK = Caido; + +export const init = (sdk: CaidoSDK) => { + sdk.matchReplace.addToSlot(MatchReplaceSlot.UpdateHeader, { + type: "Button", + label: "Duplicate Rule", + icon: "fas fa-copy", + onClick: async () => { + const currentRule = sdk.matchReplace.getCurrentRule(); + if (currentRule) { + const duplicated = await sdk.matchReplace.createRule({ + collectionId: currentRule.collectionId, + name: `${currentRule.name} (Copy)`, + query: currentRule.query, + section: currentRule.section, + sources: [], + }); + sdk.window.showToast(`Rule "${duplicated.name}" created`, { + variant: "success", + }); + } else { + sdk.window.showToast("No rule selected", { variant: "warning" }); + } + }, + }); +}; +``` diff --git a/src/guides/scopes.md b/src/guides/scopes.md index 23f14d2..f05fb1e 100644 --- a/src/guides/scopes.md +++ b/src/guides/scopes.md @@ -48,6 +48,96 @@ Delete a scope by its ID. The method returns `true` if the scope was successfull const deleted = await sdk.scopes.deleteScope(scopeId); ``` +### Getting the Current Scope + +To get the currently selected scope: + +```ts +const currentScope = sdk.scopes.getCurrentScope(); +``` + +Returns the currently selected scope, or `undefined` if no scope is selected. + +### Subscribing to Scope Changes + +To subscribe to changes in the currently selected scope: + +```ts +const handler = sdk.scopes.onCurrentScopeChange((event) => { + console.log(`Scope ${event.scopeId} got selected!`); +}); + +// Later, stop listening +handler.stop(); +``` + +The callback receives an event object with a `scopeId` property that contains the ID of the newly selected scope, or `undefined` if no scope is selected. + +::: info +The subscription handler returns an object with a `stop()` method that can be called to unsubscribe from scope changes. +::: + +## Adding Components to Scope Slots + +You can add custom components to scope slots to extend the Scopes page UI. Available slots are: + +- `ScopeSlot.CreateHeader` - The header area of the preset form create component, to the left of the ScopeTooltip +- `ScopeSlot.UpdateHeader` - The header area of the preset form update component, to the left of the ScopeTooltip + +### Adding a Button to a Slot + +Add a button with a label, icon, and click handler: + +```ts +import { ScopeSlot } from "@caido/sdk-frontend"; + +sdk.scopes.addToSlot(ScopeSlot.UpdateHeader, { + type: "Button", + label: "My Button", + icon: "my-icon", + onClick: () => { + console.log("Button clicked"); + }, +}); +``` + +### Adding a Command to a Slot + +Add a button that triggers a registered command: + +```ts +import { ScopeSlot } from "@caido/sdk-frontend"; + +// First register the command +sdk.commands.register("my-command", { + name: "My Command", + run: () => { + sdk.window.showToast("Command executed", { variant: "info" }); + }, +}); + +// Then add to slot +sdk.scopes.addToSlot(ScopeSlot.UpdateHeader, { + type: "Command", + commandId: "my-command", + icon: "my-icon", +}); +``` + +### Adding a Custom Component to a Slot + +Add a custom Vue component: + +```ts +import { ScopeSlot } from "@caido/sdk-frontend"; +import MyComponent from "./MyComponent.vue"; + +sdk.scopes.addToSlot(ScopeSlot.CreateHeader, { + type: "Custom", + definition: MyComponent, +}); +``` + ## Setting Scopes on Different Pages Different pages in Caido provide scope operations specific to their context. You can get the current scope ID and set a new scope for each page. @@ -270,3 +360,67 @@ export const init = (sdk: CaidoSDK) => { initializeScope(); }; ``` + +### Tracking Current Scope Changes + +This example subscribes to scope selection changes and logs information about the currently selected scope whenever it changes. + +```ts +import type { Caido } from "@caido/sdk-frontend"; + +export type CaidoSDK = Caido; + +export const init = (sdk: CaidoSDK) => { + const handler = sdk.scopes.onCurrentScopeChange((event) => { + if (event.scopeId) { + const scope = sdk.scopes.getCurrentScope(); + if (scope) { + sdk.log.info(`Scope selected: ${scope.name}`); + sdk.log.info(`Allowlist: ${scope.allowlist.join(", ")}`); + sdk.log.info(`Denylist: ${scope.denylist.join(", ")}`); + } + } else { + sdk.log.info("No scope selected"); + } + }); + + // Store handler for cleanup if needed + // handler.stop(); +}; +``` + +### Adding Custom Actions to Scope Slots + +This example adds a custom button to the scope update header that duplicates the current scope when clicked. + +```ts +import type { Caido } from "@caido/sdk-frontend"; +import { ScopeSlot } from "@caido/sdk-frontend"; + +export type CaidoSDK = Caido; + +export const init = (sdk: CaidoSDK) => { + sdk.scopes.addToSlot(ScopeSlot.UpdateHeader, { + type: "Button", + label: "Duplicate Scope", + icon: "fas fa-copy", + onClick: async () => { + const currentScope = sdk.scopes.getCurrentScope(); + if (currentScope) { + const duplicated = await sdk.scopes.createScope({ + name: `${currentScope.name} (Copy)`, + allowlist: [...currentScope.allowlist], + denylist: [...currentScope.denylist], + }); + if (duplicated) { + sdk.window.showToast(`Scope "${duplicated.name}" created`, { + variant: "success", + }); + } + } else { + sdk.window.showToast("No scope selected", { variant: "warning" }); + } + }, + }); +}; +```