Initialize fork and rebrand app to event_manager
This commit is contained in:
@@ -0,0 +1,223 @@
|
||||
import { APIRequestContext } from "@playwright/test";
|
||||
import * as fs from "fs";
|
||||
|
||||
/**
|
||||
* Frappe API response wrapper.
|
||||
*/
|
||||
export interface FrappeResponse<T = unknown> {
|
||||
message?: T;
|
||||
exc?: string;
|
||||
exc_type?: string;
|
||||
_server_messages?: string;
|
||||
}
|
||||
|
||||
// Path to CSRF token file saved by auth.setup.ts
|
||||
const CSRF_FILE = "e2e/.auth/csrf.json";
|
||||
|
||||
// Cache for CSRF token (read from file once)
|
||||
let csrfTokenCache: string | null = null;
|
||||
|
||||
/**
|
||||
* Get CSRF token from the file saved during auth setup.
|
||||
* The token is extracted from window.frappe.csrf_token after login.
|
||||
*/
|
||||
function getCsrfToken(): string {
|
||||
// Return cached token if available
|
||||
if (csrfTokenCache !== null) {
|
||||
return csrfTokenCache;
|
||||
}
|
||||
|
||||
// Read token from file
|
||||
try {
|
||||
if (fs.existsSync(CSRF_FILE)) {
|
||||
const data = JSON.parse(fs.readFileSync(CSRF_FILE, "utf-8"));
|
||||
csrfTokenCache = data.csrf_token || "";
|
||||
return csrfTokenCache;
|
||||
}
|
||||
} catch (error) {
|
||||
console.warn("Failed to read CSRF token file:", error);
|
||||
}
|
||||
|
||||
csrfTokenCache = "";
|
||||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new document via Frappe REST API.
|
||||
*/
|
||||
export async function createDoc<T = Record<string, unknown>>(
|
||||
request: APIRequestContext,
|
||||
doctype: string,
|
||||
doc: Record<string, unknown>,
|
||||
): Promise<T> {
|
||||
const csrfToken = getCsrfToken();
|
||||
|
||||
const response = await request.post(`/api/resource/${doctype}`, {
|
||||
data: doc,
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
...(csrfToken ? { "X-Frappe-CSRF-Token": csrfToken } : {}),
|
||||
},
|
||||
});
|
||||
|
||||
if (!response.ok()) {
|
||||
const error = await response.text();
|
||||
throw new Error(`Failed to create ${doctype}: ${error}`);
|
||||
}
|
||||
|
||||
const result = await response.json();
|
||||
return result.data as T;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a document by name via Frappe REST API.
|
||||
*/
|
||||
export async function getDoc<T = Record<string, unknown>>(
|
||||
request: APIRequestContext,
|
||||
doctype: string,
|
||||
name: string,
|
||||
): Promise<T> {
|
||||
const response = await request.get(
|
||||
`/api/resource/${doctype}/${encodeURIComponent(name)}`,
|
||||
);
|
||||
|
||||
if (!response.ok()) {
|
||||
const error = await response.text();
|
||||
throw new Error(`Failed to get ${doctype}/${name}: ${error}`);
|
||||
}
|
||||
|
||||
const result = await response.json();
|
||||
return result.data as T;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update a document via Frappe REST API.
|
||||
*/
|
||||
export async function updateDoc<T = Record<string, unknown>>(
|
||||
request: APIRequestContext,
|
||||
doctype: string,
|
||||
name: string,
|
||||
updates: Record<string, unknown>,
|
||||
): Promise<T> {
|
||||
const csrfToken = getCsrfToken();
|
||||
|
||||
const response = await request.put(`/api/resource/${doctype}/${encodeURIComponent(name)}`, {
|
||||
data: updates,
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
...(csrfToken ? { "X-Frappe-CSRF-Token": csrfToken } : {}),
|
||||
},
|
||||
});
|
||||
|
||||
if (!response.ok()) {
|
||||
const error = await response.text();
|
||||
throw new Error(`Failed to update ${doctype}/${name}: ${error}`);
|
||||
}
|
||||
|
||||
const result = await response.json();
|
||||
return result.data as T;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a document via Frappe REST API.
|
||||
*/
|
||||
export async function deleteDoc(
|
||||
request: APIRequestContext,
|
||||
doctype: string,
|
||||
name: string,
|
||||
): Promise<void> {
|
||||
const csrfToken = getCsrfToken();
|
||||
|
||||
const response = await request.delete(`/api/resource/${doctype}/${encodeURIComponent(name)}`, {
|
||||
headers: {
|
||||
...(csrfToken ? { "X-Frappe-CSRF-Token": csrfToken } : {}),
|
||||
},
|
||||
});
|
||||
|
||||
if (!response.ok()) {
|
||||
const error = await response.text();
|
||||
throw new Error(`Failed to delete ${doctype}/${name}: ${error}`);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Call a Frappe whitelisted method.
|
||||
*/
|
||||
export async function callMethod<T = unknown>(
|
||||
request: APIRequestContext,
|
||||
method: string,
|
||||
args: Record<string, unknown> = {},
|
||||
): Promise<T> {
|
||||
const csrfToken = getCsrfToken();
|
||||
|
||||
const response = await request.post(`/api/method/${method}`, {
|
||||
data: args,
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
...(csrfToken ? { "X-Frappe-CSRF-Token": csrfToken } : {}),
|
||||
},
|
||||
});
|
||||
|
||||
if (!response.ok()) {
|
||||
const error = await response.text();
|
||||
throw new Error(`Failed to call ${method}: ${error}`);
|
||||
}
|
||||
|
||||
const result: FrappeResponse<T> = await response.json();
|
||||
return result.message as T;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a list of documents via Frappe REST API.
|
||||
*/
|
||||
export async function getList<T = Record<string, unknown>>(
|
||||
request: APIRequestContext,
|
||||
doctype: string,
|
||||
options: {
|
||||
fields?: string[];
|
||||
filters?: Record<string, unknown>;
|
||||
limit?: number;
|
||||
orderBy?: string;
|
||||
} = {},
|
||||
): Promise<T[]> {
|
||||
const params = new URLSearchParams();
|
||||
|
||||
if (options.fields) {
|
||||
params.set("fields", JSON.stringify(options.fields));
|
||||
}
|
||||
if (options.filters) {
|
||||
params.set("filters", JSON.stringify(options.filters));
|
||||
}
|
||||
if (options.limit) {
|
||||
params.set("limit_page_length", options.limit.toString());
|
||||
}
|
||||
if (options.orderBy) {
|
||||
params.set("order_by", options.orderBy);
|
||||
}
|
||||
|
||||
const response = await request.get(`/api/resource/${doctype}?${params.toString()}`);
|
||||
|
||||
if (!response.ok()) {
|
||||
const error = await response.text();
|
||||
throw new Error(`Failed to get list of ${doctype}: ${error}`);
|
||||
}
|
||||
|
||||
const result = await response.json();
|
||||
return result.data as T[];
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a document exists.
|
||||
*/
|
||||
export async function docExists(
|
||||
request: APIRequestContext,
|
||||
doctype: string,
|
||||
name: string,
|
||||
): Promise<boolean> {
|
||||
try {
|
||||
await getDoc(request, doctype, name);
|
||||
return true;
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user