///
///
///
import { deletePage, getPage, patch } from "../scrapbox-userscript-std/mod.ts";
import { isErr, unwrapErr, unwrapOk } from "npm:option-t@49/plain_result";
export interface TransportInit {
/** 転送元project */
from: string;
/** 転送先project */
to: string;
/** 転送先に同じタイトルのページがあったときの挙動
*
* - `true`: 末尾に追記する
* - `false`: 何もしない
* @default false
*/
merge?: boolean;
}
export type TransportResult = {
success: true;
/** 同名のページが転送先にあったらtrue */
dup: boolean;
} | {
success: false;
at: "from" | "to";
name: string;
message: string;
};
export async function transport(title: string, {
from,
to,
merge,
}: TransportInit): Promise {
if (from === to) return { success: true, dup: false };
// 転送するページを取得
const res = await getPage(from, title);
if (isErr(res)) {
return {
success: false,
at: "from",
name: unwrapErr(res).name,
message: unwrapErr(res).message,
};
}
const page = unwrapOk(res);
if (!page.persistent) {
return {
success: false,
at: "from",
name: "EmptyPageError",
message: "The request page is empty.",
};
}
// 転送先ページがあるかどうかを調べる
const res2 = await getPage(to, title);
if (isErr(res2)) {
return {
success: false,
at: "to",
name: unwrapErr(res2).name,
message: unwrapErr(res2).message,
};
}
const page2 = unwrapOk(res);
if (page2.persistent && !merge) {
return {
success: false,
at: "to",
name: "NoEmptyPageError",
message: `The same page already exists in "/${to}"`,
};
}
// 転送する
await patch(
to,
title,
(lines) => [...lines, ...page.lines.slice(1)].map((line) => line.text),
);
await deletePage(from, title);
return { success: true, dup: page2.persistent };
}