@kitschpatrol/tldraw-cli 1.3.0 → 2.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/lib/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import v from"express";import C from"node:net";import L from"node:os";var h=class extends Error{constructor(o){super(`${o} is locked`)}},d={old:new Set,young:new Set},q=1e3*15;var u,M=()=>{let e=L.networkInterfaces(),o=new Set([void 0,"0.0.0.0"]);for(let r of Object.values(e))for(let t of r)o.add(t.address);return o},b=e=>new Promise((o,r)=>{let t=C.createServer();t.unref(),t.on("error",r),t.listen(e,()=>{let{port:n}=t.address();t.close(()=>{o(n)})})}),I=async(e,o)=>{if(e.host||e.port===0)return b(e);for(let r of o)try{await b({port:e.port,host:r})}catch(t){if(!["EADDRNOTAVAIL","EINVAL"].includes(t.code))throw t}return e.port},U=function*(e){e&&(yield*e),yield 0};async function S(e){let o,r=new Set;if(e&&(e.port&&(o=typeof e.port=="number"?[e.port]:e.port),e.exclude)){let n=e.exclude;if(typeof n[Symbol.iterator]!="function")throw new TypeError("The `exclude` option must be an iterable.");for(let a of n){if(typeof a!="number")throw new TypeError("Each item in the `exclude` option must be a number corresponding to the port you want excluded.");if(!Number.isSafeInteger(a))throw new TypeError(`Number ${a} in the exclude option is not a safe integer and can't be used`)}r=new Set(n)}u===void 0&&(u=setTimeout(()=>{u=void 0,d.old=d.young,d.young=new Set},q),u.unref&&u.unref());let t=M();for(let n of U(o))try{if(r.has(n))continue;let a=await I({...e,port:n},t);for(;d.old.has(a)||d.young.has(a);){if(n!==0)throw new h(n);a=await I({...e,port:n},t)}return d.young.add(a),a}catch(a){if(!["EADDRINUSE","EACCES"].includes(a.code)&&!(a instanceof h))throw a}throw new Error("No available ports found")}import E from"node:fs/promises";import y from"node:os";import s from"node:path";import{dirname as O}from"node:path";import{fileURLToPath as V}from"node:url";import D from"puppeteer";import G from"node:os";var T=G.homedir();function p(e){if(typeof e!="string")throw new TypeError(`Expected a string, got ${typeof e}`);return T?e.replace(/^~(?=$|\/|\\)/,T):e}async function _(e,o="svg",r="./",t=!1,n=void 0){return e.startsWith("https://www.tldraw.com/")?(t&&console.log("tldraw URL detected"),J(e,o,r,t,n)):(t&&console.log("Local file detected"),K(e,o,r,t,n))}async function H(e){await e.evaluate("app.clearOpenMenus()")}async function W(e){return!await e.evaluate("editor.getInstanceState().exportBackground")}async function z(e,o){await e.evaluate(`editor.updateInstanceState(
2
- { exportBackground: ${!o} },
1
+ import R from"express";import L from"node:net";import O from"node:os";var b=class extends Error{constructor(t){super(`${t} is locked`)}},u={old:new Set,young:new Set},j=1e3*15;var w,F=()=>{let e=O.networkInterfaces(),t=new Set([void 0,"0.0.0.0"]);for(let r of Object.values(e))for(let o of r)t.add(o.address);return t},I=e=>new Promise((t,r)=>{let o=L.createServer();o.unref(),o.on("error",r),o.listen(e,()=>{let{port:n}=o.address();o.close(()=>{t(n)})})}),D=async(e,t)=>{if(e.host||e.port===0)return I(e);for(let r of t)try{await I({port:e.port,host:r})}catch(o){if(!["EADDRNOTAVAIL","EINVAL"].includes(o.code))throw o}return e.port},q=function*(e){e&&(yield*e),yield 0};async function P(e){let t,r=new Set;if(e&&(e.port&&(t=typeof e.port=="number"?[e.port]:e.port),e.exclude)){let n=e.exclude;if(typeof n[Symbol.iterator]!="function")throw new TypeError("The `exclude` option must be an iterable.");for(let a of n){if(typeof a!="number")throw new TypeError("Each item in the `exclude` option must be a number corresponding to the port you want excluded.");if(!Number.isSafeInteger(a))throw new TypeError(`Number ${a} in the exclude option is not a safe integer and can't be used`)}r=new Set(n)}w===void 0&&(w=setTimeout(()=>{w=void 0,u.old=u.young,u.young=new Set},j),w.unref&&w.unref());let o=F();for(let n of q(t))try{if(r.has(n))continue;let a=await D({...e,port:n},o);for(;u.old.has(a)||u.young.has(a);){if(n!==0)throw new b(n);a=await D({...e,port:n},o)}return u.young.add(a),a}catch(a){if(!["EADDRINUSE","EACCES"].includes(a.code)&&!(a instanceof b))throw a}throw new Error("No available ports found")}import M from"node:fs/promises";import N from"node:os";import l from"node:path";import{dirname as V}from"node:path";import{fileURLToPath as _}from"node:url";import G from"puppeteer";import U from"node:os";var T=U.homedir();function y(e){if(typeof e!="string")throw new TypeError(`Expected a string, got ${typeof e}`);return T?e.replace(/^~(?=$|\/|\\)/,T):e}var H={darkMode:!1,format:"svg",output:"./",transparent:!1,verbose:!0};async function W(e,t={}){let r={...H,...X(t)},{darkMode:o,format:n,output:a,transparent:p,verbose:s}=r,c=!e.startsWith("https://www.tldraw.com/");s&&console.log(c?"Local file detected":"tldraw URL detected");let h=0,m;if(c){s&&console.log("Starting tldraw server...");let d=V(_(import.meta.url)),g=l.join(d,d.endsWith("/src/lib")?"../../dist/tldraw":d.endsWith("/dist/lib")?"../tldraw":"../dist/tldraw");s&&console.log(`tldraw served from "${g}"`),m=await J(g),h=m.address().port,s&&console.log(`tldraw hosted at "http://localhost:${h}"`)}s&&console.log("Starting Puppeteer...");let S=await G.launch({args:c?["--no-sandbox","--disable-web-security"]:[],headless:"new"}),i=await S.newPage();z(i,s);let $=await i.target().createCDPSession();if(await $.send("Browser.setDownloadBehavior",{behavior:"allowAndName",downloadPath:N.tmpdir(),eventsEnabled:!0}),c){await i.setRequestInterception(!0),i.on("request",f=>{f.url().endsWith("favicon.ico")?f.respond({status:200}):f.continue()});let d=l.resolve(y(e));s&&console.log(`Loading tldr file "${d}"`);let g=await M.readFile(d,"utf8");await i.evaluateOnNewDocument(f=>{localStorage.clear(),localStorage.setItem("tldrData",f)},g)}let x=c?`http://localhost:${h}`:e;s&&console.log(`Navigating to: ${x}`),await i.goto(x,{waitUntil:"networkidle0"}),s&&console.log(`Setting background transparency: ${p}`),await ee(i,p),s&&console.log(`Setting dark mode: ${o}`);let k=await Z(i);await A(i,o),s&&console.log("Requesting download"),await Y(i),await Q(i,["main.menu","menu-item.edit","menu-item.export-as",`menu-item.export-as-${n}`]);let E=await K($);s&&console.log("Download complete"),s&&console.log(`Restoring dark mode: ${k}`),await A(i,k),await S.close(),s&&console.log("Stopped Puppeteer"),c&&m&&(m.close(),s&&console.log("Stopped tldraw server"));let B=c?l.basename(e,l.extname(e)):E,C=l.join(N.tmpdir(),E),v=y(l.join(a,`${B}.${n}`));return await M.rename(C,v),s&&console.log(`Saved to "${v}"`),l.resolve(v)}function z(e,t){e.on("console",r=>{let o=r.type(),n=r.text();o==="error"?console.error(`[Browser] ${n}`):o==="warning"?console.warn(`[Browser] ${n}`):t&&console.log(`[Browser] ${n}`)})}async function J(e){let t=R(),r=await P();return t.use(R.static(e)),new Promise((o,n)=>{let a=t.listen(r,()=>{o(a)});a.on("error",p=>{n(p)})})}async function K(e){return new Promise((t,r)=>{e.on("Browser.downloadProgress",o=>{o.state==="completed"?t(o.guid):o.state==="canceled"&&r(new Error("Download was canceled"))})})}async function Q(e,t){for(let r of t)await e.waitForSelector(`[data-testid="${r}"]`),await e.click(`[data-testid="${r}"]`)}function X(e){return Object.fromEntries(Object.entries(e).filter(([,t])=>t!==void 0))}async function Y(e){await e.evaluate("app.clearOpenMenus()")}async function Z(e){return!!await e.evaluate("editor.user.getUserPreferences().isDarkMode")}async function A(e,t){await e.evaluate(`editor.user.updateUserPreferences({ isDarkMode: ${t}})`)}async function ee(e,t){await e.evaluate(`editor.updateInstanceState(
2
+ { exportBackground: ${!t} },
3
3
  { ephemeral: true },
4
- )`)}async function J(e,o,r,t,n){t&&console.log("Starting Puppeteer...");let a=await D.launch({headless:"new"}),i=await a.newPage(),m=await i.target().createCDPSession();await m.send("Browser.setDownloadBehavior",{behavior:"allowAndName",downloadPath:y.tmpdir(),eventsEnabled:!0}),t&&console.log(`Navigating to: ${e}`),await i.goto(e,{waitUntil:"networkidle0"}),n===void 0?t&&console.log("Using project transparency"):await W(i)!==n&&(t&&console.log(`Setting background to transparent: ${n}`),await z(i,n)),t&&console.log("Requesting download"),await H(i),await Y(i,["main.menu","menu-item.edit","menu-item.export-as",`menu-item.export-as-${o}`]);let f=await F(m);t&&console.log("Download complete"),await a.close(),t&&console.log("Stopped Puppeteer");let g=s.join(y.tmpdir(),f),c=p(s.join(r,`${f}.${o}`));return await E.rename(g,c),t&&console.log(`Saved to "${c}"`),c}async function K(e,o,r,t,n){let a=O(V(import.meta.url)),i=s.resolve(p(e));t&&console.log(`Loading tldr file "${i}"`);let m=await E.readFile(i,"utf8");t&&console.log("Starting tldraw server...");let f=s.join(a,a.endsWith("/src/lib")?"../../dist/tldraw":a.endsWith("/dist/lib")?"../tldraw":"../dist/tldraw");t&&console.log(`tldraw served from "${f}"`);let g=await X(f),{port:c}=g.address();t&&console.log(`tldraw hosted at "http://localhost:${c}"`),t&&console.log("Starting Puppeteer...");let P=await D.launch({headless:"new"}),l=await P.newPage();await l.setRequestInterception(!0),l.on("request",w=>{w.url().endsWith("favicon.ico")?w.respond({status:200}):w.continue()}),Q(l,t);let $=await l.target().createCDPSession();await $.send("Browser.setDownloadBehavior",{behavior:"allowAndName",downloadPath:y.tmpdir(),eventsEnabled:!0}),await l.goto(`http://localhost:${c}`),await l.waitForFunction(()=>window.tldrawExportFile!==void 0),t&&console.log("Requesting download");let N=n===void 0?null:n;await l.evaluate((w,R,j)=>{window.tldrawExportFile(w,R,j)},m,o,N);let A=await F($);t&&console.log("Download complete"),await P.close(),t&&console.log("Stopped Puppeteer");let k=s.basename(e,s.extname(e)),B=s.join(y.tmpdir(),A),x=p(s.join(r,`${k}.${o}`));return await E.rename(B,x),t&&console.log(`Saved to "${x}"`),g.close(),t&&console.log("Stopped tldraw server"),s.resolve(x)}function Q(e,o){e.on("console",r=>{let t=r.type(),n=r.text();t==="error"?console.error(`[Browser] ${n}`):t==="warning"?console.warn(`[Browser] ${n}`):o&&console.log(`[Browser] ${n}`)})}async function X(e){let o=v(),r=await S();return o.use(v.static(e)),new Promise((t,n)=>{let a=o.listen(r,()=>{t(a)});a.on("error",i=>{n(i)})})}async function F(e){return new Promise((o,r)=>{e.on("Browser.downloadProgress",t=>{t.state==="completed"?o(t.guid):t.state==="canceled"&&r(new Error("Download was canceled"))})})}async function Y(e,o){for(let r of o)await e.waitForSelector(`[data-testid="${r}"]`),await e.click(`[data-testid="${r}"]`)}export{_ as tldrawToImage};
4
+ )`)}export{W as tldrawToImage};
@@ -1,2 +1,8 @@
1
- import type { ExportFormat } from '../types';
2
- export declare function tldrawToImage(tldrPathOrUrl: string, format?: ExportFormat, destination?: string, verbose?: boolean, transparent?: boolean | undefined): Promise<string>;
1
+ export type TldrawImageOptions = {
2
+ darkMode?: boolean;
3
+ format?: 'png' | 'svg';
4
+ output?: string;
5
+ transparent?: boolean;
6
+ verbose?: boolean;
7
+ };
8
+ export declare function tldrawToImage(tldrPathOrUrl: string, options?: TldrawImageOptions): Promise<string>;