@kitschpatrol/tldraw-cli 3.0.0 → 3.2.0
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/bin/cli.js +1145 -199
- package/dist/.DS_Store +0 -0
- package/dist/lib/index.js +760 -109
- package/dist/lib/local-tldraw-server.d.ts +1 -2
- package/dist/lib/tldraw-controller.d.ts +5 -6
- package/dist/lib/tldraw-to-image.d.ts +1 -0
- package/dist/lib/utilities/logger.d.ts +8 -0
- package/dist/tldraw/assets/{index-ehug49np.js → index-l3509weP.js} +1 -1
- package/dist/tldraw/index.html +1 -1
- package/package.json +4 -1
- package/readme.md +64 -50
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
export default class LocalTldrawServer {
|
|
2
2
|
private readonly tldrData?;
|
|
3
|
-
verbose: boolean;
|
|
4
3
|
private server?;
|
|
5
|
-
constructor(tldrData?: string | undefined
|
|
4
|
+
constructor(tldrData?: string | undefined);
|
|
6
5
|
close(): void;
|
|
7
6
|
start(): Promise<void>;
|
|
8
7
|
get href(): string;
|
|
@@ -1,20 +1,19 @@
|
|
|
1
1
|
import type { TldrawFormat } from './tldraw-to-image';
|
|
2
2
|
export default class TldrawController {
|
|
3
3
|
private readonly href;
|
|
4
|
-
verbose: boolean;
|
|
5
4
|
private page?;
|
|
6
5
|
private isEmpty?;
|
|
7
6
|
private browser?;
|
|
8
7
|
private client?;
|
|
9
8
|
private originalDarkMode?;
|
|
10
|
-
constructor(href: string
|
|
9
|
+
constructor(href: string);
|
|
11
10
|
private get isLocal();
|
|
12
11
|
start(): Promise<void>;
|
|
13
12
|
close(): Promise<void>;
|
|
14
|
-
download(output: string, filename: string, format: TldrawFormat, stripStyle: boolean): Promise<string[]>;
|
|
15
|
-
downloadFrame(output: string, filename: string, format: TldrawFormat, stripStyle: boolean, frameNameOrId: string): Promise<string[]>;
|
|
16
|
-
downloadFrames(output: string, filename: string, format: TldrawFormat, stripStyle: boolean, frameNamesOrIds: string[]): Promise<string[]>;
|
|
17
|
-
downloadAllFrames(output: string, filename: string, format: TldrawFormat, stripStyle: boolean): Promise<string[]>;
|
|
13
|
+
download(output: string, filename: string, format: TldrawFormat, stripStyle: boolean, print: boolean): Promise<string[]>;
|
|
14
|
+
downloadFrame(output: string, filename: string, format: TldrawFormat, stripStyle: boolean, frameNameOrId: string, print: boolean): Promise<string[]>;
|
|
15
|
+
downloadFrames(output: string, filename: string, format: TldrawFormat, stripStyle: boolean, frameNamesOrIds: string[], print: boolean): Promise<string[]>;
|
|
16
|
+
downloadAllFrames(output: string, filename: string, format: TldrawFormat, stripStyle: boolean, print: boolean): Promise<string[]>;
|
|
18
17
|
setTransparency(transparent: boolean): Promise<void>;
|
|
19
18
|
setDarkMode(darkMode: boolean): Promise<void>;
|
|
20
19
|
private _download;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export declare let cli: boolean;
|
|
2
|
+
export declare let verbose: boolean;
|
|
3
|
+
export declare function setCli(value: boolean): void;
|
|
4
|
+
export declare function setVerbose(value: boolean): void;
|
|
5
|
+
export declare function log(...data: unknown[]): void;
|
|
6
|
+
export declare function warn(...data: unknown[]): void;
|
|
7
|
+
export declare function error(...data: unknown[]): void;
|
|
8
|
+
export declare function info(...data: unknown[]): void;
|
|
@@ -312,4 +312,4 @@ Error generating stack: `+s.message+`
|
|
|
312
312
|
font-weight: ${m.weight};
|
|
313
313
|
font-style: ${m.style};
|
|
314
314
|
src: url("${o}") format("woff2")
|
|
315
|
-
}`,()=>{document.fonts.delete(m),h=!0}},[e,n]),t};function Eee(e){return{draw:{url:e.fonts.draw},serif:{url:e.fonts.serif},sansSerif:{url:e.fonts.sansSerif},monospace:{url:e.fonts.monospace}}}function _ee(e){const n=x.useMemo(()=>Eee(e),[e]),t=[Fd("tldraw_draw",n.draw),Fd("tldraw_serif",n.serif),Fd("tldraw_sans",n.sansSerif),Fd("tldraw_mono",n.monospace)];return{error:t.some(r=>r===1),done:!t.some(r=>r===2)}}function Iee(e){const{children:n,maxImageDimension:t,maxAssetSize:r,acceptedImageMimeTypes:o,acceptedVideoMimeTypes:s,onMount:i,...a}=e,l=i7(a.components??{}),c=Cx(a.shapeUtils??[]),u=Cx(a.tools??[]),d={initialState:"select",...a,components:x.useMemo(()=>({Scribble:vb,CollaboratorScribble:vb,SelectionForeground:gU,SelectionBackground:pU,Handles:aU,HoveredShapeIndicator:lU,...l}),[l]),shapeUtils:x.useMemo(()=>[..._V,...c],[c]),tools:x.useMemo(()=>[...BV,...iH,...u],[u])},h=DG(a.assetUrls),{done:p,error:m}=_ee(h);return m?g.jsx(n7,{children:"Could not load assets. Please refresh the page."}):p?g.jsx(Qj,{...d,children:g.jsxs(nee,{...d,children:[g.jsx(Pee,{children:g.jsx(Rv,{})}),g.jsx(Tee,{maxImageDimension:t,maxAssetSize:r,acceptedImageMimeTypes:o,acceptedVideoMimeTypes:s,onMount:i}),n]})}):g.jsx(bk,{children:"Loading assets..."})}function Tee({maxImageDimension:e=1e3,maxAssetSize:n=10*1024*1024,acceptedImageMimeTypes:t=["image/jpeg","image/png","image/gif","image/svg+xml"],acceptedVideoMimeTypes:r=["video/mp4","video/quicktime"],onMount:o}){const s=V(),i=$ee(a=>{const l=[];return l.push(...IV(a)),GU(a,{maxImageDimension:e,maxAssetSize:n,acceptedImageMimeTypes:t,acceptedVideoMimeTypes:r}),l.push(o==null?void 0:o(a)),()=>{l.forEach(c=>c==null?void 0:c())}});return x.useLayoutEffect(()=>{if(s)return i==null?void 0:i(s)},[s,i]),null}function $ee(e){const n=x.useRef();return x.useLayoutEffect(()=>{n.current=e}),x.useDebugValue(e),x.useCallback((...t)=>{const r=n.current;return _o(r,"fn does not exist"),r(...t)},[])}const Mee=1,Aee=be({tldrawFileFormatVersion:P5,schema:be({schemaVersion:Uu,storeVersion:Uu,recordVersions:xy(ge,be({version:Uu,subTypeVersions:xy(ge,Uu).optional(),subTypeKey:ge.optional()}))}),records:Xt(be({id:ge,typeName:ge}).allowUnknownProperties())});function Oee(e){var n;try{return!!((n=e.document)!=null&&n.version)}catch{return!1}}function Ree({json:e,schema:n}){let t;try{t=Aee.validate(JSON.parse(e))}catch(o){try{if(t=JSON.parse(e),Oee(t))return Gs.err({type:"v1File",data:t})}catch{}return Gs.err({type:"notATldrawFile",cause:o})}if(t.tldrawFileFormatVersion>Mee)return Gs.err({type:"fileFormatVersionTooNew",version:t.tldrawFileFormatVersion});let r;try{const o=Object.fromEntries(t.records.map(s=>[s.id,s]));r=n.migrateStoreSnapshot({store:o,schema:t.schema})}catch(o){return Gs.err({type:"invalidRecords",cause:o})}if(r.type==="error")return Gs.err({type:"migrationFailed",reason:r.reason});try{return Gs.ok(vk({initialData:r.value,schema:n}))}catch(o){return Gs.err({type:"invalidRecords",cause:o})}}function Dee(){const[e,n]=x.useState();function t(r){e===void 0?fetch("/tldr-data").then(async o=>{if(!o.ok){console.log(`No tldr data to load from local endpoint (${o.status})`);return}return o.text()}).then(o=>{if(o===void 0)return;const s=Ree({json:o,schema:r.store.schema});s.ok?(console.log("Loaded tldr file from local endpoint"),n(s.value)):console.error(`
|
|
315
|
+
}`,()=>{document.fonts.delete(m),h=!0}},[e,n]),t};function Eee(e){return{draw:{url:e.fonts.draw},serif:{url:e.fonts.serif},sansSerif:{url:e.fonts.sansSerif},monospace:{url:e.fonts.monospace}}}function _ee(e){const n=x.useMemo(()=>Eee(e),[e]),t=[Fd("tldraw_draw",n.draw),Fd("tldraw_serif",n.serif),Fd("tldraw_sans",n.sansSerif),Fd("tldraw_mono",n.monospace)];return{error:t.some(r=>r===1),done:!t.some(r=>r===2)}}function Iee(e){const{children:n,maxImageDimension:t,maxAssetSize:r,acceptedImageMimeTypes:o,acceptedVideoMimeTypes:s,onMount:i,...a}=e,l=i7(a.components??{}),c=Cx(a.shapeUtils??[]),u=Cx(a.tools??[]),d={initialState:"select",...a,components:x.useMemo(()=>({Scribble:vb,CollaboratorScribble:vb,SelectionForeground:gU,SelectionBackground:pU,Handles:aU,HoveredShapeIndicator:lU,...l}),[l]),shapeUtils:x.useMemo(()=>[..._V,...c],[c]),tools:x.useMemo(()=>[...BV,...iH,...u],[u])},h=DG(a.assetUrls),{done:p,error:m}=_ee(h);return m?g.jsx(n7,{children:"Could not load assets. Please refresh the page."}):p?g.jsx(Qj,{...d,children:g.jsxs(nee,{...d,children:[g.jsx(Pee,{children:g.jsx(Rv,{})}),g.jsx(Tee,{maxImageDimension:t,maxAssetSize:r,acceptedImageMimeTypes:o,acceptedVideoMimeTypes:s,onMount:i}),n]})}):g.jsx(bk,{children:"Loading assets..."})}function Tee({maxImageDimension:e=1e3,maxAssetSize:n=10*1024*1024,acceptedImageMimeTypes:t=["image/jpeg","image/png","image/gif","image/svg+xml"],acceptedVideoMimeTypes:r=["video/mp4","video/quicktime"],onMount:o}){const s=V(),i=$ee(a=>{const l=[];return l.push(...IV(a)),GU(a,{maxImageDimension:e,maxAssetSize:n,acceptedImageMimeTypes:t,acceptedVideoMimeTypes:r}),l.push(o==null?void 0:o(a)),()=>{l.forEach(c=>c==null?void 0:c())}});return x.useLayoutEffect(()=>{if(s)return i==null?void 0:i(s)},[s,i]),null}function $ee(e){const n=x.useRef();return x.useLayoutEffect(()=>{n.current=e}),x.useDebugValue(e),x.useCallback((...t)=>{const r=n.current;return _o(r,"fn does not exist"),r(...t)},[])}const Mee=1,Aee=be({tldrawFileFormatVersion:P5,schema:be({schemaVersion:Uu,storeVersion:Uu,recordVersions:xy(ge,be({version:Uu,subTypeVersions:xy(ge,Uu).optional(),subTypeKey:ge.optional()}))}),records:Xt(be({id:ge,typeName:ge}).allowUnknownProperties())});function Oee(e){var n;try{return!!((n=e.document)!=null&&n.version)}catch{return!1}}function Ree({json:e,schema:n}){let t;try{t=Aee.validate(JSON.parse(e))}catch(o){try{if(t=JSON.parse(e),Oee(t))return Gs.err({type:"v1File",data:t})}catch{}return Gs.err({type:"notATldrawFile",cause:o})}if(t.tldrawFileFormatVersion>Mee)return Gs.err({type:"fileFormatVersionTooNew",version:t.tldrawFileFormatVersion});let r;try{const o=Object.fromEntries(t.records.map(s=>[s.id,s]));r=n.migrateStoreSnapshot({store:o,schema:t.schema})}catch(o){return Gs.err({type:"invalidRecords",cause:o})}if(r.type==="error")return Gs.err({type:"migrationFailed",reason:r.reason});try{return Gs.ok(vk({initialData:r.value,schema:n}))}catch(o){return Gs.err({type:"invalidRecords",cause:o})}}function Dee(){const[e,n]=x.useState();function t(r){e===void 0?fetch("/tldr-data").then(async o=>{if(!o.ok){console.log(`No tldr data to load from local endpoint (${o.status})`);return}return o.text()}).then(o=>{if(o===void 0)return;const s=Ree({json:o,schema:r.store.schema});s.ok?(console.log("Loaded tldr file from local endpoint"),n(s.value)):console.error(`Couldn't parse tldr file: ${String(s.error.type)}`)}).catch(o=>{console.error("Couldn't fetch data:",o)}):(r.updateViewportScreenBounds(),r.zoomToFit(),window.app.clearOpenMenus())}return g.jsx("div",{style:{inset:0,position:"fixed"},children:g.jsx(Iee,{assetUrls:LA(),onMount:t,store:e})})}var cv={},zC=il;cv.createRoot=zC.createRoot,cv.hydrateRoot=zC.hydrateRoot;cv.createRoot(document.querySelector("#root")).render(g.jsx(ne.StrictMode,{children:g.jsx(Dee,{})}));
|
package/dist/tldraw/index.html
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
<meta charset="UTF-8" />
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
6
|
<title>tldraw via tldraw-cli</title>
|
|
7
|
-
<script type="module" crossorigin src="/assets/index-
|
|
7
|
+
<script type="module" crossorigin src="/assets/index-l3509weP.js"></script>
|
|
8
8
|
<link rel="stylesheet" crossorigin href="/assets/index-S3CdIkLU.css">
|
|
9
9
|
</head>
|
|
10
10
|
<body>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kitschpatrol/tldraw-cli",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.2.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "A tiny little CLI tool for exporting tldraw sketches to svg or png images.",
|
|
6
6
|
"repository": {
|
|
@@ -56,6 +56,7 @@
|
|
|
56
56
|
"@types/yargs": "^17.0.32",
|
|
57
57
|
"@vitejs/plugin-react-swc": "^3.5.0",
|
|
58
58
|
"bumpp": "^9.3.0",
|
|
59
|
+
"chalk": "^5.3.0",
|
|
59
60
|
"cheerio": "1.0.0-rc.12",
|
|
60
61
|
"esbuild": "^0.19.11",
|
|
61
62
|
"eslint-plugin-react-hooks": "^4.6.0",
|
|
@@ -64,6 +65,8 @@
|
|
|
64
65
|
"nanoid": "^5.0.4",
|
|
65
66
|
"open": "^10.0.3",
|
|
66
67
|
"path-type": "^5.0.0",
|
|
68
|
+
"plur": "^5.1.0",
|
|
69
|
+
"pretty-ms": "^9.0.0",
|
|
67
70
|
"react": "^18.2.0",
|
|
68
71
|
"react-dom": "^18.2.0",
|
|
69
72
|
"tsx": "^4.7.0",
|
package/readme.md
CHANGED
|
@@ -34,7 +34,7 @@ npm install --global @kitschpatrol/tldraw-cli
|
|
|
34
34
|
|
|
35
35
|
### Invocation
|
|
36
36
|
|
|
37
|
-
|
|
37
|
+
`tldraw-cli`'s functionality is organized into several sub-commands.
|
|
38
38
|
|
|
39
39
|
#### Top-level
|
|
40
40
|
|
|
@@ -44,9 +44,9 @@ tldraw-cli <command>
|
|
|
44
44
|
|
|
45
45
|
The top-level collection of CLI tools for tldraw.
|
|
46
46
|
|
|
47
|
-
| Argument | Description
|
|
48
|
-
| --------- |
|
|
49
|
-
| `command` | `export`
|
|
47
|
+
| Argument | Description |
|
|
48
|
+
| --------- | ----------------------------------------------------------------- |
|
|
49
|
+
| `command` | CLI tools for tldraw. Available commands are `export` and `open`. |
|
|
50
50
|
|
|
51
51
|
| Option | Alias | Description Value |
|
|
52
52
|
| ----------- | ----- | -------------------- |
|
|
@@ -56,52 +56,51 @@ The top-level collection of CLI tools for tldraw.
|
|
|
56
56
|
#### Command: Export
|
|
57
57
|
|
|
58
58
|
```sh
|
|
59
|
-
tldraw-cli export <
|
|
59
|
+
tldraw-cli export <files-or-urls..>
|
|
60
60
|
```
|
|
61
61
|
|
|
62
|
-
Export a tldraw
|
|
62
|
+
Export a tldraw `.tldr` file or tldraw\.com URL to SVG, PNG, and other formats.
|
|
63
63
|
|
|
64
|
-
| Argument
|
|
65
|
-
|
|
|
66
|
-
| `<
|
|
64
|
+
| Argument | Description |
|
|
65
|
+
| ------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
66
|
+
| `<files-or-urls..>` | The tldraw sketch to export. May be one or more paths to local `.tldr` files, or tldraw.com sketch URLs. Accepts a mix of both file paths and URLs, and supports glob matching via your shell. Prints the absolute path(s) to the exported image(s) to `stdout`. |
|
|
67
67
|
|
|
68
|
-
| Option | Alias | Description Value
|
|
69
|
-
| ------------------- | ----- |
|
|
70
|
-
| `--format
|
|
71
|
-
| `--
|
|
72
|
-
| `--
|
|
73
|
-
| `--
|
|
74
|
-
| `--
|
|
75
|
-
| `--
|
|
76
|
-
| `--strip-style` | | Remove `<style>` elements from SVG output, useful to lighten the load of embedded fonts
|
|
77
|
-
| `--
|
|
68
|
+
| Option | Alias | Description Value | Default Value |
|
|
69
|
+
| ------------------- | ----- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------- |
|
|
70
|
+
| `--format [string]` | `-f` | Output image format, one of `svg`, `png`, `json`, or `tldr`. | `svg` |
|
|
71
|
+
| `--output <string>` | `-o` | Output image directory. | `./` |
|
|
72
|
+
| `--name <string>` | `-n` | Output image name (without extension). By default the original file name or URL id is used. | |
|
|
73
|
+
| `--frames [array]` | | Export each sketch "frame" as a separate image. Pass one or more frame names or IDs to export specific frames, or skip the arguments to export all frames. | `false` |
|
|
74
|
+
| `--transparent ` | `-t` | Export an image with a transparent background. | `false` |
|
|
75
|
+
| `--dark-mode ` | `-d` | Export a dark theme version of the image. | `false` |
|
|
76
|
+
| `--strip-style` | | Remove `<style>` elements from SVG output, useful to lighten the load of embedded fonts if you intend to provide your own stylesheets. Applies to SVG output only. | `false` |
|
|
77
|
+
| `--print` | `-p` | Print the exported image(s) to stdout instead of saving to a file. Incompatible with `--output`, and overrides `--name`. PNGs are printed as base64-encoded strings. | `false` |
|
|
78
|
+
| `--verbose` | | Enable verbose logging. All verbose logs and prefixed with their log level and are printed to `stderr` for ease of redirection. | `false` |
|
|
78
79
|
|
|
79
80
|
#### Command: Open
|
|
80
81
|
|
|
81
82
|
```sh
|
|
82
|
-
tldraw-cli open [
|
|
83
|
+
tldraw-cli open [files-or-urls..]
|
|
83
84
|
```
|
|
84
85
|
|
|
85
|
-
Open a tldraw
|
|
86
|
+
Open a tldraw `.tldr` file or tldraw\.com URL your default browser. Uses a locally-hosted instance of tldraw. Call `open` without an argument to open a blank sketch. Sketches opened via URL are temporarily copied to the local system, and will not be kept in sync with tldraw.com.
|
|
86
87
|
|
|
87
|
-
|
|
88
|
+
_"Save as" support is not yet implemented in the local tldraw instance, so the `open` command is only recommended for viewing purposes at the moment._
|
|
88
89
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
|
92
|
-
| --------------- | ------------------------------------------------------------------------------------------------------------------------------ |
|
|
93
|
-
| `[file-or-url]` | The .tldr file or tldraw\.com sketch url to open. Omit to open a blank sketch. Prints the url of the local server to `stdout`. |
|
|
90
|
+
| Argument | Description |
|
|
91
|
+
| ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
92
|
+
| `[files-or-urls..]` | The `.tldr` file(s) or tldraw\.com sketch URL(s) to open. Omit the argument to open a blank sketch. Supports glob matching via your shell. Prints the URL of the local server to `stdout`. |
|
|
94
93
|
|
|
95
94
|
No options.
|
|
96
95
|
|
|
97
96
|
## Examples
|
|
98
97
|
|
|
99
|
-
### Basic
|
|
98
|
+
### Basic `.tldr` file image export
|
|
100
99
|
|
|
101
|
-
To export the file `your-drawing.tldr` to an
|
|
100
|
+
To export the file `your-drawing.tldr` to an SVG named `your-drawing.svg` in the current working directory, run the following command. Note that the default output format is SVG, and the default export location is the current working directory.
|
|
102
101
|
|
|
103
102
|
```sh
|
|
104
|
-
|
|
103
|
+
tldraw-cli export your-drawing.tldr
|
|
105
104
|
```
|
|
106
105
|
|
|
107
106
|
The file will retain its original name, e.g. `your-drawing.svg`
|
|
@@ -109,27 +108,27 @@ The file will retain its original name, e.g. `your-drawing.svg`
|
|
|
109
108
|
### Basic tldraw\.com image download
|
|
110
109
|
|
|
111
110
|
```sh
|
|
112
|
-
|
|
111
|
+
tldraw-cli export https://www.tldraw.com/s/v2_c_JsxJk8dag6QsrqExukis4
|
|
113
112
|
```
|
|
114
113
|
|
|
115
|
-
The tldraw URL's id (e.g. `v2_c_JsxJk8dag6QsrqExukis4`) will be used for the file name.
|
|
114
|
+
The tldraw.com URL's id (e.g. `v2_c_JsxJk8dag6QsrqExukis4`) will be used for the file name.
|
|
116
115
|
|
|
117
116
|
This is approximately equivalent to clicking the tldraw\.com "☰ → Edit → Export As → SVG" menu item.
|
|
118
117
|
|
|
119
118
|
### Export a remote tldraw\.com image to a local .tldr file
|
|
120
119
|
|
|
121
120
|
```sh
|
|
122
|
-
|
|
121
|
+
tldraw-cli export https://www.tldraw.com/s/v2_c_JsxJk8dag6QsrqExukis4 --format tldr
|
|
123
122
|
```
|
|
124
123
|
|
|
125
124
|
This is approximately equivalent to clicking the tldraw\.com "☰ → File → Save a copy" menu item.
|
|
126
125
|
|
|
127
126
|
Note that using `--format tldr` with a _file path_ instead of a _URL_ will still send the file through the pipeline, but it's effectively a no-op. (Except perhaps rare edge cases where tldraw performs a file format version migration).
|
|
128
127
|
|
|
129
|
-
### Export to a specific format
|
|
128
|
+
### Export to a specific image / file format
|
|
130
129
|
|
|
131
130
|
```sh
|
|
132
|
-
|
|
131
|
+
tldraw-cli export your-drawing.tldr --format png
|
|
133
132
|
```
|
|
134
133
|
|
|
135
134
|
This is approximately equivalent to clicking the tldraw\.com "☰ → Edit → Export As → PNG" menu item.
|
|
@@ -137,7 +136,7 @@ This is approximately equivalent to clicking the tldraw\.com "☰ → Edit → E
|
|
|
137
136
|
### Export with a transparent background
|
|
138
137
|
|
|
139
138
|
```sh
|
|
140
|
-
|
|
139
|
+
tldraw-cli export your-drawing.tldr --transparent --format png
|
|
141
140
|
```
|
|
142
141
|
|
|
143
142
|
This is approximately equivalent to checking the tldraw\.com "☰ → Edit → Export As → ☐ Transparent" menu item.
|
|
@@ -145,7 +144,7 @@ This is approximately equivalent to checking the tldraw\.com "☰ → Edit → E
|
|
|
145
144
|
### Export to a specific destination
|
|
146
145
|
|
|
147
146
|
```sh
|
|
148
|
-
|
|
147
|
+
tldraw-cli export your-drawing.tldr --output ~/Desktop
|
|
149
148
|
```
|
|
150
149
|
|
|
151
150
|
Exports to `~/Desktop/your-drawing.svg`
|
|
@@ -153,15 +152,15 @@ Exports to `~/Desktop/your-drawing.svg`
|
|
|
153
152
|
### Export to a specific destination and filename
|
|
154
153
|
|
|
155
154
|
```sh
|
|
156
|
-
|
|
155
|
+
tldraw-cli export your-drawing.tldr --output ~/Desktop --name not-your-drawing
|
|
157
156
|
```
|
|
158
157
|
|
|
159
158
|
Exports to `~/Desktop/not-your-drawing.svg`
|
|
160
159
|
|
|
161
|
-
### Export all frames from a tldraw URL
|
|
160
|
+
### Export all frames from a tldraw.com URL
|
|
162
161
|
|
|
163
162
|
```sh
|
|
164
|
-
|
|
163
|
+
tldraw-cli export https://www.tldraw.com/s/v2_c_FI5RYWbdpAtjsy4OIKrKw --frames
|
|
165
164
|
```
|
|
166
165
|
|
|
167
166
|
The exported files will be suffixed with their frame name, e.g.:
|
|
@@ -174,33 +173,45 @@ The frame name will be slugified.
|
|
|
174
173
|
|
|
175
174
|
It's possible in tldraw to give multiple frames in a single sketch the same name. In these cases, the frame ID is used in addition to the name to ensure unique output file names.
|
|
176
175
|
|
|
177
|
-
### Export a specific frame from a tldraw URL
|
|
176
|
+
### Export a specific frame from a tldraw.com URL
|
|
177
|
+
|
|
178
|
+
```sh
|
|
179
|
+
tldraw-cli export https://www.tldraw.com/s/v2_c_FI5RYWbdpAtjsy4OIKrKw --frames "Frame 3"
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
### Export multiple frames from a tldraw.com URL
|
|
178
183
|
|
|
179
184
|
```sh
|
|
180
|
-
|
|
185
|
+
tldraw-cli export https://www.tldraw.com/s/v2_c_FI5RYWbdpAtjsy4OIKrKw --frames "Frame 1" "Frame 3"
|
|
181
186
|
```
|
|
182
187
|
|
|
183
188
|
### Export to JSON
|
|
184
189
|
|
|
185
190
|
```sh
|
|
186
|
-
|
|
191
|
+
tldraw-cli export https://www.tldraw.com/s/v2_c_FI5RYWbdpAtjsy4OIKrKw --format "json"
|
|
187
192
|
```
|
|
188
193
|
|
|
189
|
-
The
|
|
194
|
+
The `.tldr` file format is also JSON under the covers, but the `--format json` flag will yield a slightly different format than `--format tldr`. `--format json` is equivalent to what's produced via the tldraw\.com "☰ → Edit → Export As → JSON" menu item.
|
|
190
195
|
|
|
191
196
|
I'm not completely clear on the use-case for this format, but since tldr.com supports it, so too shall `tldraw-cli`.
|
|
192
197
|
|
|
193
|
-
###
|
|
198
|
+
### Write an SVG to stdout
|
|
199
|
+
|
|
200
|
+
```sh
|
|
201
|
+
tldraw-cli export https://www.tldraw.com/s/v2_c_FI5RYWbdpAtjsy4OIKrKw --print
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
### Open a tldraw.com URL
|
|
194
205
|
|
|
195
206
|
```sh
|
|
196
|
-
|
|
207
|
+
tldraw-cli open https://www.tldraw.com/s/v2_c_FI5RYWbdpAtjsy4OIKrKw
|
|
197
208
|
```
|
|
198
209
|
|
|
199
210
|
The remote sketch is copied to a locally-hosted instance of tldraw, which is then opened in your default browser.
|
|
200
211
|
|
|
201
212
|
## API usage
|
|
202
213
|
|
|
203
|
-
The `export` command's functionality is also provided
|
|
214
|
+
The `export` command's functionality is also provided in module form for use in TypeScript or JavaScript Node projects.
|
|
204
215
|
|
|
205
216
|
The library exports a single async function, `tldrawToImage`, which takes an options argument mirroring the arguments available via the command line. The same default values apply:
|
|
206
217
|
|
|
@@ -234,10 +245,10 @@ import { tldrawToImage } from '@kitschpatrol/tldraw-cli'
|
|
|
234
245
|
const [imagePath] = await tldrawToImage('./some-file.tldr', { format: 'png', output: './' })
|
|
235
246
|
console.log(`Wrote image to: "${imagePath}"`)
|
|
236
247
|
|
|
237
|
-
// Convert a remote tldraw URL to SVG
|
|
248
|
+
// Convert a remote tldraw.com URL to SVG
|
|
238
249
|
await tldrawToImage('https://www.tldraw.com/s/v2_c_JsxJk8dag6QsrqExukis4')
|
|
239
250
|
|
|
240
|
-
// Convert all frames from a single tldraw URL to separate SVGs
|
|
251
|
+
// Convert all frames from a single tldraw.com URL to separate SVGs
|
|
241
252
|
// When the `frames` option is set, the function returns an array
|
|
242
253
|
// of resulting file paths, instead of a solitary string
|
|
243
254
|
const framePathsArray = await tldrawToImage('https://www.tldraw.com/s/v2_c_FI5RYWbdpAtjsy4OIKrKw', {
|
|
@@ -245,7 +256,7 @@ const framePathsArray = await tldrawToImage('https://www.tldraw.com/s/v2_c_FI5RY
|
|
|
245
256
|
})
|
|
246
257
|
console.log(`Wrote frames to: "${framePathsArray}"`)
|
|
247
258
|
|
|
248
|
-
// Convert a specific frame from a tldraw URL to a PNG
|
|
259
|
+
// Convert a specific frame from a tldraw.com URL to a PNG
|
|
249
260
|
await tldrawToImage('https://www.tldraw.com/s/v2_c_FI5RYWbdpAtjsy4OIKrKw', {
|
|
250
261
|
frames: ['Frame 3'],
|
|
251
262
|
format: 'png',
|
|
@@ -293,10 +304,13 @@ The local instance of tldraw includes its assets dependencies, so the tool shoul
|
|
|
293
304
|
This is a very minimal implementation. Current plans for future improvements include the following:
|
|
294
305
|
|
|
295
306
|
- Add save button to local tldraw
|
|
307
|
+
- Accept globs and optimize batch processing with a single puppeteer instance
|
|
296
308
|
- Add CLI tests
|
|
297
309
|
- Implement the ability to export specific pages as separate image files
|
|
298
310
|
- Add an option flag to set dpi when exporting to a bitmap format
|
|
299
311
|
- Additional commands beyond sketch conversion / export?
|
|
312
|
+
- There's room for optimization in how tldraw functions are passed to Puppeteer
|
|
313
|
+
- There's room for optimization in the `--print` option implementation
|
|
300
314
|
|
|
301
315
|
Any other suggestions are welcome.
|
|
302
316
|
|