Skip to content
Open
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
7 changes: 4 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,16 @@
},
"devDependencies": {
"@caido-community/dev": "0.1.5",
"@caido/eslint-config": "0.5.0",
"@caido/tailwindcss": "0.0.1",
"@vitejs/plugin-vue": "5.2.3",
"eslint": "9.29.0",
"postcss-prefixwrap": "1.55.0",
"tailwindcss": "3.4.13",
"tailwindcss-primeui": "0.6.1",
"typescript": "5.8.3",
"@caido/eslint-config": "0.5.0",
"eslint": "9.29.0"
"typescript": "5.8.3"
},
"dependencies": {
"pnpm": "^10.16.1"
}
}
29 changes: 28 additions & 1 deletion packages/backend/src/db/db.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import type { SDK } from "caido:plugin";
import type { RoleDTO, UserAttributeDTO } from "shared";
import type { RoleDTO, SubstitutionDTO, UserAttributeDTO } from "shared";

import { RoleStore } from "../stores/roles";
import { SubstitutionStore } from "../stores/substitutions";
import { TemplateStore } from "../stores/templates";
import { UserStore } from "../stores/users";

Expand Down Expand Up @@ -83,6 +84,16 @@ export const initDatabase = async (sdk: SDK) => {
);
`);

await db.exec(`
CREATE TABLE IF NOT EXISTS substitutions (
id TEXT NOT NULL,
project_id TEXT NOT NULL,
pattern TEXT NOT NULL,
replacement TEXT NOT NULL,
PRIMARY KEY (id, project_id)
);
`);

return db;
};

Expand All @@ -91,12 +102,19 @@ export const hydrateStoresFromDb = async (sdk: SDK) => {
const roleStore = RoleStore.get();
const templateStore = TemplateStore.get();
const userStore = UserStore.get();
const substitutionStore = SubstitutionStore.get();

const current = await sdk.projects.getCurrent();
if (!current) return;

const projectID = current.getId();

// Clear all stores first to ensure clean state
roleStore.clear();
templateStore.clearTemplates();
userStore.clear();
substitutionStore.clear();

const rolesStmt = await db.prepare(
"SELECT id, name, description FROM roles WHERE project_id = ?",
);
Expand Down Expand Up @@ -182,4 +200,13 @@ export const hydrateStoresFromDb = async (sdk: SDK) => {
dto.rules = rules;
templateStore.addTemplate(dto);
}

const substitutionsStmt = await db.prepare(
"SELECT id, pattern, replacement FROM substitutions WHERE project_id = ?",
);
const substitutionRows: SubstitutionDTO[] =
await substitutionsStmt.all(projectID);
for (const substitution of substitutionRows) {
substitutionStore.addSubstitution(substitution);
}
};
48 changes: 48 additions & 0 deletions packages/backend/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,36 @@ import {
} from "./services/analysis";
import { addRole, deleteRole, getRoles, updateRole } from "./services/roles";
import { getSettings, updateSettings } from "./services/settings";
import {
addSubstitution,
clearSubstitutions,
deleteSubstitution,
getSubstitutions,
updateSubstitutionFields,
} from "./services/substitutions";
import {
addTemplate,
addTemplateFromContext,
checkAllTemplatesForRole,
checkAllTemplatesForUser,
clearTemplates,
deleteTemplate,
exportConfiguration,
getTemplates,
importConfiguration,
importTemplatesFromOpenApi,
registerTemplateEvents,
sendTemplateToReplay,
toggleTemplateRole,
toggleTemplateUser,
updateTemplate,
updateTemplateRequest,
updateTemplateRequestRaw,
} from "./services/templates";
import { addUser, deleteUser, getUsers, updateUser } from "./services/users";
import { deleteProjectData, getActiveProject } from "./services/utils";
import { RoleStore } from "./stores/roles";
import { SubstitutionStore } from "./stores/substitutions";
import { TemplateStore } from "./stores/templates";
import { UserStore } from "./stores/users";
import { type BackendEvents } from "./types";
Expand All @@ -45,11 +61,19 @@ export type API = DefineAPI<{
getTemplates: typeof getTemplates;
addTemplate: typeof addTemplate;
updateTemplate: typeof updateTemplate;
updateTemplateRequest: typeof updateTemplateRequest;
updateTemplateRequestRaw: typeof updateTemplateRequestRaw;
deleteTemplate: typeof deleteTemplate;
clearTemplates: typeof clearTemplates;
toggleTemplateRole: typeof toggleTemplateRole;
toggleTemplateUser: typeof toggleTemplateUser;
checkAllTemplatesForRole: typeof checkAllTemplatesForRole;
checkAllTemplatesForUser: typeof checkAllTemplatesForUser;
addTemplateFromContext: typeof addTemplateFromContext;
importTemplatesFromOpenApi: typeof importTemplatesFromOpenApi;
sendTemplateToReplay: typeof sendTemplateToReplay;
exportConfiguration: typeof exportConfiguration;
importConfiguration: typeof importConfiguration;

// Settings endpoints
getSettings: typeof getSettings;
Expand All @@ -60,6 +84,13 @@ export type API = DefineAPI<{
getResults: typeof getResults;
getRequestResponse: typeof getRequestResponse;

// Substitution endpoints
getSubstitutions: typeof getSubstitutions;
addSubstitution: typeof addSubstitution;
updateSubstitutionFields: typeof updateSubstitutionFields;
deleteSubstitution: typeof deleteSubstitution;
clearSubstitutions: typeof clearSubstitutions;

// Utils endpoints
getActiveProject: typeof getActiveProject;
deleteProjectData: typeof deleteProjectData;
Expand All @@ -86,11 +117,19 @@ export async function init(sdk: SDK<API, BackendEvents>) {
sdk.api.register("getTemplates", getTemplates);
sdk.api.register("addTemplate", addTemplate);
sdk.api.register("updateTemplate", updateTemplate);
sdk.api.register("updateTemplateRequest", updateTemplateRequest);
sdk.api.register("updateTemplateRequestRaw", updateTemplateRequestRaw);
sdk.api.register("deleteTemplate", deleteTemplate);
sdk.api.register("toggleTemplateRole", toggleTemplateRole);
sdk.api.register("toggleTemplateUser", toggleTemplateUser);
sdk.api.register("checkAllTemplatesForRole", checkAllTemplatesForRole);
sdk.api.register("checkAllTemplatesForUser", checkAllTemplatesForUser);
sdk.api.register("clearTemplates", clearTemplates);
sdk.api.register("addTemplateFromContext", addTemplateFromContext);
sdk.api.register("importTemplatesFromOpenApi", importTemplatesFromOpenApi);
sdk.api.register("sendTemplateToReplay", sendTemplateToReplay);
sdk.api.register("exportConfiguration", exportConfiguration);
sdk.api.register("importConfiguration", importConfiguration);

// Settings endpoints
sdk.api.register("getSettings", getSettings);
Expand All @@ -101,6 +140,13 @@ export async function init(sdk: SDK<API, BackendEvents>) {
sdk.api.register("getResults", getResults);
sdk.api.register("getRequestResponse", getRequestResponse);

// Substitution endpoints
sdk.api.register("getSubstitutions", getSubstitutions);
sdk.api.register("addSubstitution", addSubstitution);
sdk.api.register("updateSubstitutionFields", updateSubstitutionFields);
sdk.api.register("deleteSubstitution", deleteSubstitution);
sdk.api.register("clearSubstitutions", clearSubstitutions);

// Utils endpoints
sdk.api.register("getActiveProject", getActiveProject);
sdk.api.register("deleteProjectData", deleteProjectData);
Expand All @@ -113,10 +159,12 @@ export async function init(sdk: SDK<API, BackendEvents>) {
const roleStore = RoleStore.get();
const templateStore = TemplateStore.get();
const userStore = UserStore.get();
const substitutionStore = SubstitutionStore.get();

roleStore.clear();
templateStore.clearTemplates();
userStore.clear();
substitutionStore.clear();

await hydrateStoresFromDb(sdk);

Expand Down
63 changes: 63 additions & 0 deletions packages/backend/src/repositories/substitutions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import type { SDK } from "caido:plugin";
import type { SubstitutionDTO } from "shared";

import { getDb } from "../db/client";

export const createSubstitution = async (
sdk: SDK,
projectId: string,
substitution: SubstitutionDTO,
): Promise<void> => {
const db = await getDb(sdk);
const stmt = await db.prepare(`
INSERT INTO substitutions (id, project_id, pattern, replacement)
VALUES (?, ?, ?, ?)
`);

await stmt.run(
substitution.id,
projectId,
substitution.pattern,
substitution.replacement,
);
};

export const updateSubstitution = async (
sdk: SDK,
projectId: string,
id: string,
fields: Omit<SubstitutionDTO, "id">,
): Promise<void> => {
const db = await getDb(sdk);
const stmt = await db.prepare(`
UPDATE substitutions SET pattern = ?, replacement = ?
WHERE id = ? AND project_id = ?
`);

await stmt.run(fields.pattern, fields.replacement, id, projectId);
};

export const removeSubstitution = async (
sdk: SDK,
projectId: string,
id: string,
): Promise<void> => {
const db = await getDb(sdk);
const stmt = await db.prepare(`
DELETE FROM substitutions WHERE id = ? AND project_id = ?
`);

await stmt.run(id, projectId);
};

export const clearAllSubstitutions = async (
sdk: SDK,
projectId: string,
): Promise<void> => {
const db = await getDb(sdk);
const stmt = await db.prepare(`
DELETE FROM substitutions WHERE project_id = ?
`);

await stmt.run(projectId);
};
Loading