generated at
複数のページを削除するUserScript
複数のページを一度に削除したいときに使うUserScript

js
await (async () => { const { deletePages } = await import("https://scrapbox.io/api/code/takker/複数のページを削除するUserScript/mod.js"); await deletePages([ "a", "b" ].map((title) => ({ project: "takker", title}))); })();

$ deno check --remote -r=https://scrapbox.io https://scrapbox.io/api/code/takker/複数のページを削除するUserScript/mod.ts
$ deno run -A jsr:@takker/esbuild-deno-cli@0.1.0-rc.5 https://scrapbox.io/api/code/takker/複数のページを削除するUserScript/mod.ts --bundle --minify --format=esm --outfile=mod.js
mod.ts
/// <reference no-default-lib="true" /> /// <reference lib="esnext" /> /// <reference lib="dom" /> import { useStatusBar, makeSocket, deletePage, disconnect, Socket, } from "../scrapbox-userscript-std/mod.ts"; import { delay } from "../deno_std%2Fasync/mod.ts"; export interface Page { project: string; title: string; } export const deletePages = async (pages: Page[]): Promise<void> => { const { render, dispose } = useStatusBar(); let socket: Socket | undefined; try { socket = await makeSocket(); let counter = 0; for (const page of pages) { await deletePage(page.project, page.title, { socket }); counter++; render( { type: "spinner" }, { type: "text", text: `delete ${counter}/${pages.length} pages...`}, ); } render( { type: "check-circle" }, { type: "text", text: `deleted ${pages.length} pages.`}, ); } catch(e: unknown) { render( { type: "exclamation-triangle" }, { type: "text", text: e instanceof Error ? `${e.name} ${e.message}` : `Unknown error! (see developper console)`, }, ); console.error(e); } finally { if (socket) await disconnect(socket); await delay(1000); dispose(); } }

mod.js
var d=e=>{let{fetch:t=globalThis.fetch,hostName:r="scrapbox.io",...o}=e;return{fetch:t,hostName:r,...o}};var ue=e=>typeof e=="object"&&e!==null,me=e=>ue(e)?(e.name===void 0||typeof e.name=="string")&&typeof e.message=="string":!1,B=e=>{try{let t=typeof e=="string"?JSON.parse(e):e;return me(t)?t:!1}catch(t){if(t instanceof SyntaxError)return!1;throw t}};var w=class extends Error{constructor(t){super(`${t.status} ${t.statusText} when fetching ${t.url}`);this.response=t;this.name="UnexpectedResponseError";Error.captureStackTrace&&Error.captureStackTrace(this,w)}},g=async e=>{let t=e.clone(),r=await t.text(),o=B(r);if(!o)throw new w(t);return{ok:!1,value:o}};var j=async e=>{let{sid:t,hostName:r,fetch:o}=d(e??{}),n=new Request(`https://${r}/api/users/me`,t?{headers:{Cookie:f(t)}}:void 0),s=await o(n);if(!s.ok)throw new w(s);return await s.json()};var f=e=>`connect.sid=${e}`;var D=e=>[...e].map((t,r)=>t===" "?"_":!le.includes(t)||r===e.length-1&&fe.includes(t)?encodeURIComponent(t):t).join(""),le='@$&+=:;",',fe=':;",';var A=(e,t,r)=>{let{sid:o,hostName:n,followRename:s,projects:i}=d(r??{}),c=new URLSearchParams;c.append("followRename",`${s??!0}`);for(let p of i??[])c.append("projects",p);let a=`https://${n}/api/pages/${e}/${D(t)}?${c.toString()}`;return new Request(a,o?{headers:{Cookie:f(o)}}:void 0)},F=async e=>{if(!e.ok)return e.status===414?{ok:!1,value:{name:"TooLongURIError",message:"project ids may be too much."}}:g(e);let t=await e.json();return{ok:!0,value:t}},T=async(e,t,r)=>{let{fetch:o}=d(r??{}),n=A(e,t,r),s=await o(n);return await F(s)};T.toRequest=A;T.fromResponse=F;var q=(e,t)=>{let{sid:r,hostName:o,sort:n,limit:s,skip:i}=d(t??{}),c=new URLSearchParams;n!==void 0&&c.append("sort",n),s!==void 0&&c.append("limit",`${s}`),i!==void 0&&c.append("skip",`${i}`);let a=`https://${o}/api/pages/${e}?${c.toString()}`;return new Request(a,r?{headers:{Cookie:f(r)}}:void 0)},_=async e=>{if(!e.ok)return g(e);let t=await e.json();return{ok:!0,value:t}},K=async(e,t)=>{let{fetch:r}=d(t??{}),o=await r(q(e,t));return await _(o)};K.toRequest=q;K.fromResponse=_;var z=(e,t)=>{let{sid:r,hostName:o}=d(t??{});return new Request(`https://${o}/api/projects/${e}`,r?{headers:{Cookie:f(r)}}:void 0)},G=async e=>{if(!e.ok)return g(e);let t=await e.json();return{ok:!0,value:t}},I=async(e,t)=>{let{fetch:r}=d(t??{}),o=z(e,t),n=await r(o);return G(n)};I.toRequest=z;I.fromResponse=G;var W=(e,t)=>{let{sid:r,hostName:o}=d(t??{}),n=new URLSearchParams;for(let s of e)n.append("ids",s);return new Request(`https://${o}/api/projects?${n.toString()}`,r?{headers:{Cookie:f(r)}}:void 0)},Q=async e=>{if(!e.ok)return g(e);let t=await e.json();return{ok:!0,value:t}},Y=async(e,t)=>{let{fetch:r}=d(t??{}),o=await r(W(e,t));return Q(o)};Y.toRequest=W;Y.fromResponse=Q;var X=(e,t)=>{if(!(e instanceof HTMLDivElement))throw new TypeError(`"${t}" must be HTMLDivElememt but actual is "${e}"`)};var V=()=>ge(document.getElementsByClassName("status-bar")?.[0],"div.status-bar"),ge=(e,t)=>{if(!!e)return X(e,t),e};var P=e=>new Promise(t=>setTimeout(()=>t(),e));var Z=()=>{let e=V();if(!e)throw new Error("div.status-bar can't be found");let t=document.createElement("div");return e.append(t),{render:(...r)=>{t.textContent="";let o=ee(...r);o&&t.append(o)},dispose:()=>t.remove()}},ee=(...e)=>{let t=e.flatMap(o=>{switch(o.type){case"spinner":return[Ee()];case"check-circle":return[be()];case"exclamation-triangle":return[ke()];case"text":return[N(o.text)];case"group":{let n=ee(...o.items);return n?[n]:[]}}});if(t.length===0)return;if(t.length===1)return t[0];let r=document.createElement("span");return r.classList.add("item-group"),r.append(...t),r},N=e=>{let t=document.createElement("span");return t.classList.add("item"),t.append(e),t},Ee=()=>{let e=document.createElement("i");return e.classList.add("fa","fa-spinner"),N(e)},be=()=>{let e=document.createElement("i");return e.classList.add("kamon","kamon-check-circle"),N(e)},ke=()=>{let e=document.createElement("i");return e.classList.add("fas","fa-exclamation-triangle"),N(e)};var Le="4.2.0";async function h(){let t=(await Te())("https://scrapbox.io",{reconnectionDelay:5e3,transports:["websocket"]});return await new Promise((r,o)=>{let n=s=>o(s);t.once("connect",()=>{t.off("disconnect",n),r()}),t.once("disconnect",n)}),t}function Te(){let e=`https://cdnjs.cloudflare.com/ajax/libs/socket.io/${Le}/socket.io.min.js`;if(document.querySelector(`script[src="${e}"]`))return Promise.resolve(window.io);let t=document.createElement("script");return t.src=e,new Promise((r,o)=>{t.onload=()=>r(window.io),t.onerror=n=>o(n),document.head.append(t)})}function y(e,t=9e4){function r(n,s){let i;return new Promise((c,a)=>{let p=l=>{clearTimeout(i),a(new Error(l))};e.emit(n,s,l=>{clearTimeout(i),e.off("disconnect",p),l.error&&a(new Error(JSON.stringify(l.error))),"data"in l?c(l?.data):c(void 0)}),i=setTimeout(()=>{e.off("disconnect",p),a(new Error(`Timeout: exceeded ${t}ms`))},t),e.once("disconnect",p)})}async function*o(...n){let s,i=()=>new Promise(a=>s=a),c=a=>{s?.(a)};for(let a of n)e.on(a,c);try{for(;;)yield await i()}finally{for(let a of n)e.off(a,c)}}return{request:r,response:o}}var te=()=>h(),v=async e=>{if(e.connected)return;let t=new Promise(r=>e.once("connect",()=>r()));e.connect(),await t},x=async e=>{if(e.disconnected)return;let t=new Promise(r=>{let o=n=>{n==="io client disconnect"&&(r(),e.off("disconnect",o))};e.on("disconnect",o)});e.disconnect(),await t};var R,S=async()=>{if(R!==void 0)return R;let e=await j();if(e.isGuest)throw new Error("this script can only be executed by Logged in users");return R=e.id,R},re=new Map,L=async e=>{let t=re.get(e);if(t!==void 0)return t;let r=await I(e);if(!r.ok){let{name:n,message:s}=r.value;throw new Error(`${n} ${s}`)}let{id:o}=r.value;return re.set(e,o),o};var u=(e,{parseOnNested:t,parseOnQuoted:r,patterns:o})=>(n,s,i)=>{var c,a,p,l,C,O;if(!t&&s.nested)return(c=i?.())!==null&&c!==void 0?c:[];if(!r&&s.quoted)return(a=i?.())!==null&&a!==void 0?a:[];for(let ae of o){let k=ae.exec(n);if(k===null)continue;let ce=n.substring(0,k.index),pe=n.substring(k.index+((l=(p=k[0])===null||p===void 0?void 0:p.length)!==null&&l!==void 0?l:0)),de=e((C=k[0])!==null&&C!==void 0?C:"",s);return[...E(ce,s),...de,...E(pe,s)]}return(O=i?.())!==null&&O!==void 0?O:[]},m=e=>[{type:"plain",raw:e,text:e}],Ie=u(m,{parseOnNested:!0,parseOnQuoted:!0,patterns:[/^()(.*)()$/]}),Pe=/^>.*$/,Ne=(e,t)=>t.context==="table"?m(e,t):[{type:"quote",raw:e,nodes:E(e.substring(1),{...t,quoted:!0})}],Re=u(Ne,{parseOnNested:!1,parseOnQuoted:!1,patterns:[Pe]}),Se=/^\? .+$/,Me=(e,t)=>t.context==="table"?m(e,t):[{type:"helpfeel",raw:e,text:e.substring(2)}],Ce=u(Me,{parseOnNested:!1,parseOnQuoted:!1,patterns:[Se]}),Oe=/\[\[https?:\/\/[^\s\]]+\.(?:png|jpe?g|gif|svg)\]\]/i,je=/\[\[https?:\/\/(?:[0-9a-z-]+\.)?gyazo\.com\/[0-9a-f]{32}\]\]/,De=(e,t)=>{if(t.context==="table")return m(e,t);let r=e.substring(2,e.length-2),o=/^https?:\/\/([0-9a-z-]\.)?gyazo\.com\/[0-9a-f]{32}$/.test(r);return[{type:"strongImage",raw:e,src:o?`${r}/thumb/1000`:r}]},$e=u(De,{parseOnNested:!1,parseOnQuoted:!0,patterns:[Oe,je]}),He=/\[[^[\]]*\.icon(?:\*[1-9]\d*)?\]/;function oe(e){return(t,r)=>{if(e==="strongIcon"&&r.context==="table")return m(t,r);let o=e==="icon"?t.substring(1,t.length-1):t.substring(2,t.length-2),n=o.lastIndexOf(".icon"),s=o.substring(0,n),i=s.startsWith("/")?"root":"relative",c=o.substring(n+5,o.length),a=c.startsWith("*")?parseInt(c.substring(1),10):1;return new Array(a).fill({}).map(()=>({path:s,pathType:i,type:e,raw:t}))}}var Ue=oe("icon"),Be=u(Ue,{parseOnNested:!0,parseOnQuoted:!0,patterns:[He]}),Ae=/\[\[[^[\]]*\.icon(?:\*\d+)?\]\]/,Fe=oe("strongIcon"),qe=u(Fe,{parseOnNested:!1,parseOnQuoted:!0,patterns:[Ae]}),_e=/\[\[(?:[^[]|\[[^[]).*?\]*\]\]/,Ke=(e,t)=>t.context==="table"?m(e,t):[{type:"strong",raw:e,nodes:E(e.substring(2,e.length-2),{...t,nested:!0})}],ze=u(Ke,{parseOnNested:!1,parseOnQuoted:!0,patterns:[_e]}),Ge=/\[\$ .+? \]/,We=/\[\$ [^\]]+\]/,Qe=(e,t)=>t.context==="table"?m(e,t):[{type:"formula",raw:e,formula:e.substring(3,e.length-(e.endsWith(" ]")?2:1))}],Ye=u(Qe,{parseOnNested:!1,parseOnQuoted:!0,patterns:[Ge,We]}),Xe=/\[[!"#%&'()*+,\-./{|}<>_~]+ (?:\[[^[\]]+\]|[^\]])+\]/,Ve=(e,t)=>{if(t.context==="table")return m(e,t);let r=e.indexOf(" "),o=e.substring(1,r),n=e.substring(r+1,e.length-1),s=new Set(o);if(s.has("*")){let i=o.split("*").length-1;s.delete("*"),s.add(`*-${Math.min(i,10)}`)}return[{type:"decoration",raw:e,rawDecos:o,decos:Array.from(s),nodes:E(n,{...t,nested:!0})}]},Je=u(Ve,{parseOnNested:!1,parseOnQuoted:!0,patterns:[Xe]}),Ze=/`.*?`/,et=(e,t)=>t.context==="table"?m(e,t):[{type:"code",raw:e,text:e.substring(1,e.length-1)}],tt=u(et,{parseOnNested:!1,parseOnQuoted:!0,patterns:[Ze]}),rt=/^[$%] .+$/,ot=(e,t)=>{var r;if(t.context==="table")return m(e,t);let o=(r=e[0])!==null&&r!==void 0?r:"",n=e.substring(2);return[{type:"commandLine",raw:e,symbol:o,text:n}]},nt=u(ot,{parseOnNested:!1,parseOnQuoted:!1,patterns:[rt]}),st=/\[\s+\]/,it=(e,t)=>t.context==="table"?m(e,t):[{type:"blank",raw:e,text:e.substring(1,e.length-1)}],at=u(it,{parseOnNested:!1,parseOnQuoted:!0,patterns:[st]}),ct=/\[https?:\/\/[^\s\]]+\.(?:png|jpe?g|gif|svg)(?:\?[^\]\s]+)?(?:\s+https?:\/\/[^\s\]]+)?\]/i,pt=/\[https?:\/\/[^\s\]]+\s+https?:\/\/[^\s\]]+\.(?:png|jpe?g|gif|svg)(?:\?[^\]\s]+)?\]/i,dt=/\[https?:\/\/(?:[0-9a-z-]+\.)?gyazo\.com\/[0-9a-f]{32}(?:\/raw)?(?:\s+https?:\/\/[^\s\]]+)?\]/,ut=/\[https?:\/\/[^\s\]]+\s+https?:\/\/(?:[0-9a-z-]+\.)?gyazo\.com\/[0-9a-f]{32}(?:\/raw)?\]/,mt=e=>/^https?:\/\/[^\s\]]+\.(png|jpe?g|gif|svg)(\?[^\]\s]+)?$/i.test(e)||lt(e),lt=e=>/^https?:\/\/([0-9a-z-]\.)?gyazo\.com\/[0-9a-f]{32}(\/raw)?$/.test(e),ft=(e,t)=>{if(t.context==="table")return m(e,t);let r=e.search(/\s/),o=r!==-1?e.substring(1,r):e.substring(1,e.length-1),n=r!==-1?e.substring(r,e.length-1).trimLeft():"",[s,i]=mt(n)?[n,o]:[o,n];return[{type:"image",raw:e,src:/^https?:\/\/([0-9a-z-]\.)?gyazo\.com\/[0-9a-f]{32}$/.test(s)?`${s}/thumb/1000`:s,link:i}]},gt=u(ft,{parseOnNested:!0,parseOnQuoted:!0,patterns:[ct,pt,dt,ut]}),ht=/\[https?:\/\/[^\s\]]+\s+[^\]]*[^\s]\]/,xt=/\[[^[\]]*[^\s]\s+https?:\/\/[^\s\]]+\]/,wt=/\[https?:\/\/[^\s\]]+\]/,yt=/https?:\/\/[^\s]+/,Et=(e,t)=>{if(t.context==="table")return m(e,t);let r=e.startsWith("[")&&e.endsWith("]")?e.substring(1,e.length-1):e,o=/^https?:\/\/[^\s\]]/.test(r),n=(o?/^https?:\/\/[^\s\]]+/:/https?:\/\/[^\s\]]+$/).exec(r);if(n?.[0]===void 0)return[];let s=o?r.substring(n[0].length):r.substring(0,n.index-1);return[{type:"link",raw:e,pathType:"absolute",href:n[0],content:s.trim()}]},bt=u(Et,{parseOnNested:!0,parseOnQuoted:!0,patterns:[ht,xt,wt,yt]}),ne=/\[([^\]]*[^\s])\s+([NS]\d+(?:\.\d+)?,[EW]\d+(?:\.\d+)?(?:,Z\d+)?)\]/,se=/\[([NS]\d+(?:\.\d+)?,[EW]\d+(?:\.\d+)?(?:,Z\d+)?)(?:\s+([^\]]*[^\s]))?\]/,kt=e=>{let[t="",r="",o=""]=e.split(","),n=parseFloat(t.replace(/^N/,"").replace(/^S/,"-")),s=parseFloat(r.replace(/^E/,"").replace(/^W/,"-")),i=/^Z\d+$/.test(o)?parseInt(o.replace(/^Z/,""),10):14;return{latitude:n,longitude:s,zoom:i}},vt=(e,t)=>{var r;if(t.context==="table")return m(e,t);let o=(r=e.match(ne))!==null&&r!==void 0?r:e.match(se);if(o===null)return[];let n=e.startsWith("[N")||e.startsWith("[S"),[,s="",i=""]=n?o:[o[0],o[2],o[1]],{latitude:c,longitude:a,zoom:p}=kt(s),l=i!==""?`https://www.google.com/maps/place/${encodeURIComponent(i)}/@${c},${a},${p}z`:`https://www.google.com/maps/@${c},${a},${p}z`;return[{type:"googleMap",raw:e,latitude:c,longitude:a,zoom:p,place:i,url:l}]},Lt=u(vt,{parseOnNested:!1,parseOnQuoted:!0,patterns:[ne,se]}),Tt=/\[\/?[^[\]]+\]/,It=e=>{let t=e.substring(1,e.length-1);return[{type:"link",raw:e,pathType:t.startsWith("/")?"root":"relative",href:t,content:""}]},Pt=u(It,{parseOnNested:!0,parseOnQuoted:!0,patterns:[Tt]}),Nt=/(?:^|\s)#\S+/,Rt=(e,t)=>{if(t.context==="table")return m(e,t);if(e.startsWith("#"))return[{type:"hashTag",raw:e,href:e.substring(1)}];let r=e.substring(0,1),o=e.substring(1);return[...m(r,t),{type:"hashTag",raw:o,href:o.substring(1)}]},St=u(Rt,{parseOnNested:!0,parseOnQuoted:!0,patterns:[Nt]}),Mt=/^[0-9]+\. .*$/,Ct=(e,t)=>{if(t.context==="table")return m(e,t);let r=e.indexOf(" "),o=e.substring(0,r-1),n=parseInt(o,10),s=e.substring(r+1,e.length);return[{type:"numberList",raw:e,rawNumber:o,number:n,nodes:E(s,{...t,nested:!0})}]},Ot=u(Ct,{parseOnNested:!1,parseOnQuoted:!1,patterns:[Mt]}),jt=(e,t,r)=>{var o;return e===""?[]:(o=r?.())!==null&&o!==void 0?o:[]},Dt=(...e)=>(t,r)=>e.reduceRight((o,n)=>()=>n(t,r,o),()=>Ie(t,r))(),E=Dt(jt,Re,Ce,tt,nt,Ye,at,Je,$e,qe,ze,gt,bt,Be,Lt,Pt,St,Ot);var b=async(e,t)=>{let r=await T(e,t);if(!r.ok)throw new Error(`You have no privilege of editing "/${e}/${t}".`);let{commitId:o,persistent:n,image:s,links:i,lines:c,id:a,pin:p}=r.value;return{commitId:o,pageId:a,persistent:n,image:s,links:i,pin:p,lines:c}};var U=async(e,t,r)=>t.length===0?{commitId:r.parentId}:await e("socket.io-request",{method:"commit",data:{kind:"page",...r,changes:t,cursor:null,freeze:!0}}),M=async(e,t,{project:r,title:o,retry:n=3,parentId:s,...i})=>{try{s=(await U(e,t,{parentId:s,...i})).commitId}catch{console.log("Faild to push a commit. Retry after pulling new commits");for(let a=0;a<n;a++){let{commitId:p}=await b(r,o);s=p;try{s=(await U(e,t,{parentId:s,...i})).commitId,console.log("Success in retrying");break}catch{continue}}throw Error("Faild to retry pushing.")}return s};var ie=async(e,t,r)=>{let[{pageId:o,commitId:n,persistent:s},i,c]=await Promise.all([b(e,t),L(e),S()]);if(!s)return;let a=r?.socket,p=a??await h();await v(p);let{request:l}=y(p);try{await M(l,[{deleted:!0}],{projectId:i,pageId:o,parentId:n,userId:c,project:e,title:t})}finally{a||await x(p)}};var zi=async e=>{let{render:t,dispose:r}=Z(),o;try{o=await te();let n=0;for(let s of e)await ie(s.project,s.title,{socket:o}),n++,t({type:"spinner"},{type:"text",text:`delete ${n}/${e.length} pages...`});t({type:"check-circle"},{type:"text",text:`deleted ${e.length} pages.`})}catch(n){t({type:"exclamation-triangle"},{type:"text",text:n instanceof Error?`${n.name} ${n.message}`:"Unknown error! (see developper console)"}),console.error(n)}finally{o&&await x(o),await P(1e3),r()}};export{zi as deletePages};

#2022-12-29 04:32:57