echos-ocr/src/lib/monday.ts

190 lines
5 KiB
TypeScript
Raw Normal View History

const MONDAY_API = "https://api.monday.com/v2";
const MONDAY_FILE_API = "https://api.monday.com/v2/file";
type MondayColumn = { id: string; title: string; type: string };
async function gql(token: string, query: string, variables?: Record<string, unknown>) {
const res = await fetch(MONDAY_API, {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: token,
},
body: JSON.stringify({ query, variables }),
});
if (!res.ok) {
const text = await res.text().catch(() => "");
throw new Error(`Monday.com API ${res.status}: ${text}`);
}
const json = await res.json();
if (json.errors?.length) {
throw new Error(`Monday.com GraphQL: ${json.errors[0].message}`);
}
return json.data;
}
export async function fetchBoardColumns(token: string, boardId: string): Promise<MondayColumn[]> {
const data = await gql(token, `
query ($boardId: [ID!]!) {
boards(ids: $boardId) {
columns { id title type }
}
}
`, { boardId: [boardId] });
return data?.boards?.[0]?.columns ?? [];
}
export async function createItem(
token: string,
boardId: string,
itemName: string,
columnValues: Record<string, unknown>
): Promise<string> {
const data = await gql(token, `
mutation ($boardId: ID!, $itemName: String!, $columnValues: JSON!) {
create_item(
board_id: $boardId,
item_name: $itemName,
column_values: $columnValues,
create_labels_if_missing: true
) { id }
}
`, {
boardId,
itemName,
columnValues: JSON.stringify(columnValues),
});
return String(data.create_item.id);
}
export async function updateItem(
token: string,
boardId: string,
itemId: string,
columnValues: Record<string, unknown>
): Promise<void> {
await gql(token, `
mutation ($boardId: ID!, $itemId: ID!, $columnValues: JSON!) {
change_multiple_column_values(
board_id: $boardId,
item_id: $itemId,
column_values: $columnValues,
create_labels_if_missing: true
) { id }
}
`, {
boardId,
itemId,
columnValues: JSON.stringify(columnValues),
});
}
export async function uploadFileToItem(
token: string,
itemId: string,
columnId: string,
fileBuffer: Buffer,
fileName: string
): Promise<void> {
const query = `mutation ($file: File!) { add_file_to_column(file: $file, item_id: ${itemId}, column_id: "${columnId}") { id } }`;
const form = new FormData();
form.append("query", query);
form.append("variables[file]", new Blob([new Uint8Array(fileBuffer)]), fileName);
const res = await fetch(MONDAY_FILE_API, {
method: "POST",
headers: { Authorization: token },
body: form,
});
if (!res.ok) {
const text = await res.text().catch(() => "");
throw new Error(`Monday.com file upload ${res.status}: ${text}`);
}
}
type ItemColumnValue = { id: string; text: string; value: string | null };
export async function readItem(
token: string,
itemId: string
): Promise<{ name: string; columnValues: ItemColumnValue[] } | null> {
const data = await gql(token, `
query ($itemId: [ID!]!) {
items(ids: $itemId) {
name
column_values { id text value }
}
}
`, { itemId: [itemId] });
const item = data?.items?.[0];
if (!item) return null;
return {
name: item.name,
columnValues: item.column_values.map((cv: { id: string; text: string; value: string | null }) => ({
id: cv.id,
text: cv.text,
value: cv.value,
})),
};
}
export function mapCardToColumnValues(
card: Record<string, unknown>,
columnMap: Record<string, string>
): Record<string, unknown> {
const values: Record<string, unknown> = {};
for (const [cardField, colId] of Object.entries(columnMap)) {
if (!colId || !cardField) continue;
const val = card[cardField];
if (val === null || val === undefined) continue;
values[colId] = String(val);
}
return values;
}
export function mapItemToCardFields(
columnValues: ItemColumnValue[],
columnMap: Record<string, string>
): Record<string, string> {
const reverseMap: Record<string, string> = {};
for (const [cardField, colId] of Object.entries(columnMap)) {
reverseMap[colId] = cardField;
}
const cardData: Record<string, string> = {};
for (const cv of columnValues) {
const cardField = reverseMap[cv.id];
if (cardField && cv.text) {
cardData[cardField] = cv.text;
}
}
return cardData;
}
export async function createWebhookSubscription(
token: string,
boardId: string,
callbackUrl: string
): Promise<string> {
const data = await gql(token, `
mutation ($boardId: ID!, $url: String!) {
create_webhook(board_id: $boardId, url: $url, event: change_column_value) { id }
}
`, { boardId, url: callbackUrl });
return String(data.create_webhook.id);
}
export async function deleteWebhookSubscription(
token: string,
webhookId: string
): Promise<void> {
await gql(token, `
mutation ($webhookId: ID!) {
delete_webhook(id: $webhookId) { id }
}
`, { webhookId });
}