@kitschpatrol/tldraw-cli 3.0.0 → 3.1.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 +65 -23
- package/dist/lib/index.js +50 -21
- package/dist/lib/tldraw-controller.d.ts +4 -4
- package/dist/lib/tldraw-to-image.d.ts +1 -0
- package/package.json +1 -1
- package/readme.md +58 -43
package/bin/cli.js
CHANGED
|
@@ -610,7 +610,7 @@ var require_boolbase = __commonJS({
|
|
|
610
610
|
});
|
|
611
611
|
|
|
612
612
|
// package.json
|
|
613
|
-
var version = "
|
|
613
|
+
var version = "3.0.0";
|
|
614
614
|
|
|
615
615
|
// src/lib/local-tldraw-server.ts
|
|
616
616
|
import express from "express";
|
|
@@ -16482,13 +16482,13 @@ var TldrawController = class {
|
|
|
16482
16482
|
console.log("Stopped controller");
|
|
16483
16483
|
}
|
|
16484
16484
|
// Public method doesn't expose pageFrame
|
|
16485
|
-
async download(output, filename, format3, stripStyle) {
|
|
16486
|
-
return this._download(output, filename, format3, stripStyle);
|
|
16485
|
+
async download(output, filename, format3, stripStyle, print) {
|
|
16486
|
+
return this._download(output, filename, format3, stripStyle, void 0, print);
|
|
16487
16487
|
}
|
|
16488
|
-
async downloadFrame(output, filename, format3, stripStyle, frameNameOrId) {
|
|
16489
|
-
return this.downloadFrames(output, filename, format3, stripStyle, [frameNameOrId]);
|
|
16488
|
+
async downloadFrame(output, filename, format3, stripStyle, frameNameOrId, print) {
|
|
16489
|
+
return this.downloadFrames(output, filename, format3, stripStyle, [frameNameOrId], print);
|
|
16490
16490
|
}
|
|
16491
|
-
async downloadFrames(output, filename, format3, stripStyle, frameNamesOrIds) {
|
|
16491
|
+
async downloadFrames(output, filename, format3, stripStyle, frameNamesOrIds, print) {
|
|
16492
16492
|
const validPageFrames = [];
|
|
16493
16493
|
for (const frame of frameNamesOrIds) {
|
|
16494
16494
|
const pageFrame = await this.getPageFrameWithNameOrId(frame);
|
|
@@ -16512,15 +16512,22 @@ var TldrawController = class {
|
|
|
16512
16512
|
for (const frame of validPageFrames) {
|
|
16513
16513
|
const frameSuffix = isFrameNameCollision ? `-${frame.id.replace("shape:", "")}` : "";
|
|
16514
16514
|
outputAccumulator.push(
|
|
16515
|
-
...await this._download(
|
|
16515
|
+
...await this._download(
|
|
16516
|
+
output,
|
|
16517
|
+
`${filename}${frameSuffix}`,
|
|
16518
|
+
format3,
|
|
16519
|
+
stripStyle,
|
|
16520
|
+
frame,
|
|
16521
|
+
print
|
|
16522
|
+
)
|
|
16516
16523
|
);
|
|
16517
16524
|
}
|
|
16518
16525
|
return outputAccumulator;
|
|
16519
16526
|
}
|
|
16520
|
-
async downloadAllFrames(output, filename, format3, stripStyle) {
|
|
16527
|
+
async downloadAllFrames(output, filename, format3, stripStyle, print) {
|
|
16521
16528
|
const pageFrames = await this.getPageFrames();
|
|
16522
16529
|
const frameNamesOrIds = pageFrames.map((f) => f.id);
|
|
16523
|
-
return this.downloadFrames(output, filename, format3, stripStyle, frameNamesOrIds);
|
|
16530
|
+
return this.downloadFrames(output, filename, format3, stripStyle, frameNamesOrIds, print);
|
|
16524
16531
|
}
|
|
16525
16532
|
// Ephemeral means we don't have to restore the user's value
|
|
16526
16533
|
async setTransparency(transparent) {
|
|
@@ -16545,19 +16552,17 @@ var TldrawController = class {
|
|
|
16545
16552
|
await this.page.evaluate(`editor.user.updateUserPreferences({ isDarkMode: ${darkMode}})`);
|
|
16546
16553
|
}
|
|
16547
16554
|
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
16548
|
-
async _download(output, filename, format3, stripStyle, pageFrame) {
|
|
16555
|
+
async _download(output, filename, format3, stripStyle, pageFrame, print) {
|
|
16549
16556
|
if (!this.page)
|
|
16550
16557
|
throw new Error("Controller not started");
|
|
16551
16558
|
if (this.isEmpty) {
|
|
16552
16559
|
throw new Error("Cannot export an empty document");
|
|
16553
16560
|
}
|
|
16554
16561
|
if (stripStyle && format3 !== "svg") {
|
|
16555
|
-
console.warn("
|
|
16562
|
+
console.warn("--strip-style is only supported for SVG output");
|
|
16556
16563
|
}
|
|
16557
16564
|
if (pageFrame !== void 0 && format3 === "tldr") {
|
|
16558
|
-
console.warn(
|
|
16559
|
-
"Warning: --frames is not supported for tldr output, downloading entire document"
|
|
16560
|
-
);
|
|
16565
|
+
console.warn("--frames is not supported for tldr output, downloading entire document");
|
|
16561
16566
|
}
|
|
16562
16567
|
const completionPromise = this.waitForDownloadCompletion();
|
|
16563
16568
|
await this.closeMenus();
|
|
@@ -16586,15 +16591,24 @@ var TldrawController = class {
|
|
|
16586
16591
|
const downloadGuid = await completionPromise;
|
|
16587
16592
|
await this.page.waitForNetworkIdle();
|
|
16588
16593
|
const downloadPath = path2.join(os3.tmpdir(), downloadGuid);
|
|
16589
|
-
const outputPath = path2.resolve(
|
|
16590
|
-
|
|
16591
|
-
|
|
16592
|
-
await fs.rename(downloadPath, outputPath);
|
|
16594
|
+
const outputPath = print ? downloadPath : path2.resolve(untildify(path2.join(output, `${filename}${frameSuffix}.${format3}`)));
|
|
16595
|
+
if (!print)
|
|
16596
|
+
await fs.rename(downloadPath, outputPath);
|
|
16593
16597
|
if (stripStyle && format3 === "svg") {
|
|
16594
16598
|
const svg = await fs.readFile(outputPath, "utf8");
|
|
16595
16599
|
const strippedSvg = this.stripStyleElement(svg);
|
|
16596
16600
|
await fs.writeFile(outputPath, strippedSvg);
|
|
16597
16601
|
}
|
|
16602
|
+
if (print) {
|
|
16603
|
+
if (format3 === "png") {
|
|
16604
|
+
const buffer = await fs.readFile(outputPath);
|
|
16605
|
+
const outputBase64 = buffer.toString("base64");
|
|
16606
|
+
return [outputBase64];
|
|
16607
|
+
}
|
|
16608
|
+
const outputString = await fs.readFile(outputPath, "utf8");
|
|
16609
|
+
const outputStringNoNewlines = outputString.replaceAll("\n", "");
|
|
16610
|
+
return [outputStringNoNewlines];
|
|
16611
|
+
}
|
|
16598
16612
|
return [outputPath];
|
|
16599
16613
|
}
|
|
16600
16614
|
async closeMenus() {
|
|
@@ -16738,16 +16752,23 @@ var defaultOptions2 = {
|
|
|
16738
16752
|
frames: false,
|
|
16739
16753
|
name: void 0,
|
|
16740
16754
|
output: "./",
|
|
16755
|
+
print: false,
|
|
16741
16756
|
stripStyle: false,
|
|
16742
16757
|
transparent: false,
|
|
16743
16758
|
verbose: false
|
|
16744
16759
|
};
|
|
16745
16760
|
async function tldrawToImage(tldrPathOrUrl, options) {
|
|
16761
|
+
if (options?.print && options.output !== void 0) {
|
|
16762
|
+
throw new Error("Cannot use --output with --print");
|
|
16763
|
+
}
|
|
16764
|
+
if (options?.print && options.name !== void 0) {
|
|
16765
|
+
console.warn("Ignoring --name when using --print");
|
|
16766
|
+
}
|
|
16746
16767
|
const resolvedOptions = {
|
|
16747
16768
|
...defaultOptions2,
|
|
16748
16769
|
...stripUndefined(options ?? {})
|
|
16749
16770
|
};
|
|
16750
|
-
const { darkMode, format: format3, frames, name, output, stripStyle, transparent, verbose } = resolvedOptions;
|
|
16771
|
+
const { darkMode, format: format3, frames, name, output, print, stripStyle, transparent, verbose } = resolvedOptions;
|
|
16751
16772
|
if (verbose)
|
|
16752
16773
|
console.time("Export time");
|
|
16753
16774
|
const validatedPathOrUrl = validatePathOrUrl(tldrPathOrUrl, {
|
|
@@ -16776,7 +16797,8 @@ async function tldrawToImage(tldrPathOrUrl, options) {
|
|
|
16776
16797
|
output,
|
|
16777
16798
|
outputFilename,
|
|
16778
16799
|
format3,
|
|
16779
|
-
stripStyle
|
|
16800
|
+
stripStyle,
|
|
16801
|
+
print
|
|
16780
16802
|
);
|
|
16781
16803
|
} else if (Array.isArray(frames) && frames.length > 0) {
|
|
16782
16804
|
exportReport = await tldrawController.downloadFrames(
|
|
@@ -16784,10 +16806,17 @@ async function tldrawToImage(tldrPathOrUrl, options) {
|
|
|
16784
16806
|
outputFilename,
|
|
16785
16807
|
format3,
|
|
16786
16808
|
stripStyle,
|
|
16787
|
-
frames
|
|
16809
|
+
frames,
|
|
16810
|
+
print
|
|
16788
16811
|
);
|
|
16789
16812
|
} else {
|
|
16790
|
-
exportReport = await tldrawController.download(
|
|
16813
|
+
exportReport = await tldrawController.download(
|
|
16814
|
+
output,
|
|
16815
|
+
outputFilename,
|
|
16816
|
+
format3,
|
|
16817
|
+
stripStyle,
|
|
16818
|
+
print
|
|
16819
|
+
);
|
|
16791
16820
|
}
|
|
16792
16821
|
await tldrawController.close();
|
|
16793
16822
|
if (isLocal)
|
|
@@ -22191,7 +22220,8 @@ await yargs_default(hideBin(process.argv)).scriptName("tldraw-cli").command("$0
|
|
|
22191
22220
|
type: "string"
|
|
22192
22221
|
}).option("output", {
|
|
22193
22222
|
alias: "o",
|
|
22194
|
-
default:
|
|
22223
|
+
default: void 0,
|
|
22224
|
+
defaultDescription: '"./"',
|
|
22195
22225
|
describe: "Output image directory.",
|
|
22196
22226
|
type: "string"
|
|
22197
22227
|
}).option("name", {
|
|
@@ -22223,10 +22253,20 @@ await yargs_default(hideBin(process.argv)).scriptName("tldraw-cli").command("$0
|
|
|
22223
22253
|
default: false,
|
|
22224
22254
|
describe: "Remove all style tags from the SVG output. Applies to SVG output only.",
|
|
22225
22255
|
type: "boolean"
|
|
22256
|
+
}).option("print", {
|
|
22257
|
+
alias: "p",
|
|
22258
|
+
default: false,
|
|
22259
|
+
describe: "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.",
|
|
22260
|
+
type: "boolean"
|
|
22226
22261
|
}).option("verbose", {
|
|
22227
22262
|
default: false,
|
|
22228
22263
|
describe: "Enable verbose output",
|
|
22229
22264
|
type: "boolean"
|
|
22265
|
+
}).check((argv) => {
|
|
22266
|
+
if (argv.print && argv.output !== void 0) {
|
|
22267
|
+
throw new Error("Cannot use --output with --print");
|
|
22268
|
+
}
|
|
22269
|
+
return true;
|
|
22230
22270
|
}),
|
|
22231
22271
|
async (argv) => {
|
|
22232
22272
|
const {
|
|
@@ -22236,6 +22276,7 @@ await yargs_default(hideBin(process.argv)).scriptName("tldraw-cli").command("$0
|
|
|
22236
22276
|
frames,
|
|
22237
22277
|
name,
|
|
22238
22278
|
output,
|
|
22279
|
+
print,
|
|
22239
22280
|
stripStyle,
|
|
22240
22281
|
transparent,
|
|
22241
22282
|
verbose
|
|
@@ -22248,6 +22289,7 @@ await yargs_default(hideBin(process.argv)).scriptName("tldraw-cli").command("$0
|
|
|
22248
22289
|
frames,
|
|
22249
22290
|
name,
|
|
22250
22291
|
output,
|
|
22292
|
+
print,
|
|
22251
22293
|
stripStyle,
|
|
22252
22294
|
transparent,
|
|
22253
22295
|
verbose
|
package/dist/lib/index.js
CHANGED
|
@@ -16471,13 +16471,13 @@ var TldrawController = class {
|
|
|
16471
16471
|
console.log("Stopped controller");
|
|
16472
16472
|
}
|
|
16473
16473
|
// Public method doesn't expose pageFrame
|
|
16474
|
-
async download(output, filename, format, stripStyle) {
|
|
16475
|
-
return this._download(output, filename, format, stripStyle);
|
|
16474
|
+
async download(output, filename, format, stripStyle, print) {
|
|
16475
|
+
return this._download(output, filename, format, stripStyle, void 0, print);
|
|
16476
16476
|
}
|
|
16477
|
-
async downloadFrame(output, filename, format, stripStyle, frameNameOrId) {
|
|
16478
|
-
return this.downloadFrames(output, filename, format, stripStyle, [frameNameOrId]);
|
|
16477
|
+
async downloadFrame(output, filename, format, stripStyle, frameNameOrId, print) {
|
|
16478
|
+
return this.downloadFrames(output, filename, format, stripStyle, [frameNameOrId], print);
|
|
16479
16479
|
}
|
|
16480
|
-
async downloadFrames(output, filename, format, stripStyle, frameNamesOrIds) {
|
|
16480
|
+
async downloadFrames(output, filename, format, stripStyle, frameNamesOrIds, print) {
|
|
16481
16481
|
const validPageFrames = [];
|
|
16482
16482
|
for (const frame of frameNamesOrIds) {
|
|
16483
16483
|
const pageFrame = await this.getPageFrameWithNameOrId(frame);
|
|
@@ -16501,15 +16501,22 @@ var TldrawController = class {
|
|
|
16501
16501
|
for (const frame of validPageFrames) {
|
|
16502
16502
|
const frameSuffix = isFrameNameCollision ? `-${frame.id.replace("shape:", "")}` : "";
|
|
16503
16503
|
outputAccumulator.push(
|
|
16504
|
-
...await this._download(
|
|
16504
|
+
...await this._download(
|
|
16505
|
+
output,
|
|
16506
|
+
`${filename}${frameSuffix}`,
|
|
16507
|
+
format,
|
|
16508
|
+
stripStyle,
|
|
16509
|
+
frame,
|
|
16510
|
+
print
|
|
16511
|
+
)
|
|
16505
16512
|
);
|
|
16506
16513
|
}
|
|
16507
16514
|
return outputAccumulator;
|
|
16508
16515
|
}
|
|
16509
|
-
async downloadAllFrames(output, filename, format, stripStyle) {
|
|
16516
|
+
async downloadAllFrames(output, filename, format, stripStyle, print) {
|
|
16510
16517
|
const pageFrames = await this.getPageFrames();
|
|
16511
16518
|
const frameNamesOrIds = pageFrames.map((f) => f.id);
|
|
16512
|
-
return this.downloadFrames(output, filename, format, stripStyle, frameNamesOrIds);
|
|
16519
|
+
return this.downloadFrames(output, filename, format, stripStyle, frameNamesOrIds, print);
|
|
16513
16520
|
}
|
|
16514
16521
|
// Ephemeral means we don't have to restore the user's value
|
|
16515
16522
|
async setTransparency(transparent) {
|
|
@@ -16534,19 +16541,17 @@ var TldrawController = class {
|
|
|
16534
16541
|
await this.page.evaluate(`editor.user.updateUserPreferences({ isDarkMode: ${darkMode}})`);
|
|
16535
16542
|
}
|
|
16536
16543
|
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
16537
|
-
async _download(output, filename, format, stripStyle, pageFrame) {
|
|
16544
|
+
async _download(output, filename, format, stripStyle, pageFrame, print) {
|
|
16538
16545
|
if (!this.page)
|
|
16539
16546
|
throw new Error("Controller not started");
|
|
16540
16547
|
if (this.isEmpty) {
|
|
16541
16548
|
throw new Error("Cannot export an empty document");
|
|
16542
16549
|
}
|
|
16543
16550
|
if (stripStyle && format !== "svg") {
|
|
16544
|
-
console.warn("
|
|
16551
|
+
console.warn("--strip-style is only supported for SVG output");
|
|
16545
16552
|
}
|
|
16546
16553
|
if (pageFrame !== void 0 && format === "tldr") {
|
|
16547
|
-
console.warn(
|
|
16548
|
-
"Warning: --frames is not supported for tldr output, downloading entire document"
|
|
16549
|
-
);
|
|
16554
|
+
console.warn("--frames is not supported for tldr output, downloading entire document");
|
|
16550
16555
|
}
|
|
16551
16556
|
const completionPromise = this.waitForDownloadCompletion();
|
|
16552
16557
|
await this.closeMenus();
|
|
@@ -16575,15 +16580,24 @@ var TldrawController = class {
|
|
|
16575
16580
|
const downloadGuid = await completionPromise;
|
|
16576
16581
|
await this.page.waitForNetworkIdle();
|
|
16577
16582
|
const downloadPath = path2.join(os3.tmpdir(), downloadGuid);
|
|
16578
|
-
const outputPath = path2.resolve(
|
|
16579
|
-
|
|
16580
|
-
|
|
16581
|
-
await fs.rename(downloadPath, outputPath);
|
|
16583
|
+
const outputPath = print ? downloadPath : path2.resolve(untildify(path2.join(output, `${filename}${frameSuffix}.${format}`)));
|
|
16584
|
+
if (!print)
|
|
16585
|
+
await fs.rename(downloadPath, outputPath);
|
|
16582
16586
|
if (stripStyle && format === "svg") {
|
|
16583
16587
|
const svg = await fs.readFile(outputPath, "utf8");
|
|
16584
16588
|
const strippedSvg = this.stripStyleElement(svg);
|
|
16585
16589
|
await fs.writeFile(outputPath, strippedSvg);
|
|
16586
16590
|
}
|
|
16591
|
+
if (print) {
|
|
16592
|
+
if (format === "png") {
|
|
16593
|
+
const buffer = await fs.readFile(outputPath);
|
|
16594
|
+
const outputBase64 = buffer.toString("base64");
|
|
16595
|
+
return [outputBase64];
|
|
16596
|
+
}
|
|
16597
|
+
const outputString = await fs.readFile(outputPath, "utf8");
|
|
16598
|
+
const outputStringNoNewlines = outputString.replaceAll("\n", "");
|
|
16599
|
+
return [outputStringNoNewlines];
|
|
16600
|
+
}
|
|
16587
16601
|
return [outputPath];
|
|
16588
16602
|
}
|
|
16589
16603
|
async closeMenus() {
|
|
@@ -16727,16 +16741,23 @@ var defaultOptions2 = {
|
|
|
16727
16741
|
frames: false,
|
|
16728
16742
|
name: void 0,
|
|
16729
16743
|
output: "./",
|
|
16744
|
+
print: false,
|
|
16730
16745
|
stripStyle: false,
|
|
16731
16746
|
transparent: false,
|
|
16732
16747
|
verbose: false
|
|
16733
16748
|
};
|
|
16734
16749
|
async function tldrawToImage(tldrPathOrUrl, options) {
|
|
16750
|
+
if (options?.print && options.output !== void 0) {
|
|
16751
|
+
throw new Error("Cannot use --output with --print");
|
|
16752
|
+
}
|
|
16753
|
+
if (options?.print && options.name !== void 0) {
|
|
16754
|
+
console.warn("Ignoring --name when using --print");
|
|
16755
|
+
}
|
|
16735
16756
|
const resolvedOptions = {
|
|
16736
16757
|
...defaultOptions2,
|
|
16737
16758
|
...stripUndefined(options ?? {})
|
|
16738
16759
|
};
|
|
16739
|
-
const { darkMode, format, frames, name, output, stripStyle, transparent, verbose } = resolvedOptions;
|
|
16760
|
+
const { darkMode, format, frames, name, output, print, stripStyle, transparent, verbose } = resolvedOptions;
|
|
16740
16761
|
if (verbose)
|
|
16741
16762
|
console.time("Export time");
|
|
16742
16763
|
const validatedPathOrUrl = validatePathOrUrl(tldrPathOrUrl, {
|
|
@@ -16765,7 +16786,8 @@ async function tldrawToImage(tldrPathOrUrl, options) {
|
|
|
16765
16786
|
output,
|
|
16766
16787
|
outputFilename,
|
|
16767
16788
|
format,
|
|
16768
|
-
stripStyle
|
|
16789
|
+
stripStyle,
|
|
16790
|
+
print
|
|
16769
16791
|
);
|
|
16770
16792
|
} else if (Array.isArray(frames) && frames.length > 0) {
|
|
16771
16793
|
exportReport = await tldrawController.downloadFrames(
|
|
@@ -16773,10 +16795,17 @@ async function tldrawToImage(tldrPathOrUrl, options) {
|
|
|
16773
16795
|
outputFilename,
|
|
16774
16796
|
format,
|
|
16775
16797
|
stripStyle,
|
|
16776
|
-
frames
|
|
16798
|
+
frames,
|
|
16799
|
+
print
|
|
16777
16800
|
);
|
|
16778
16801
|
} else {
|
|
16779
|
-
exportReport = await tldrawController.download(
|
|
16802
|
+
exportReport = await tldrawController.download(
|
|
16803
|
+
output,
|
|
16804
|
+
outputFilename,
|
|
16805
|
+
format,
|
|
16806
|
+
stripStyle,
|
|
16807
|
+
print
|
|
16808
|
+
);
|
|
16780
16809
|
}
|
|
16781
16810
|
await tldrawController.close();
|
|
16782
16811
|
if (isLocal)
|
|
@@ -11,10 +11,10 @@ export default class TldrawController {
|
|
|
11
11
|
private get isLocal();
|
|
12
12
|
start(): Promise<void>;
|
|
13
13
|
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[]>;
|
|
14
|
+
download(output: string, filename: string, format: TldrawFormat, stripStyle: boolean, print: boolean): Promise<string[]>;
|
|
15
|
+
downloadFrame(output: string, filename: string, format: TldrawFormat, stripStyle: boolean, frameNameOrId: string, print: boolean): Promise<string[]>;
|
|
16
|
+
downloadFrames(output: string, filename: string, format: TldrawFormat, stripStyle: boolean, frameNamesOrIds: string[], print: boolean): Promise<string[]>;
|
|
17
|
+
downloadAllFrames(output: string, filename: string, format: TldrawFormat, stripStyle: boolean, print: boolean): Promise<string[]>;
|
|
18
18
|
setTransparency(transparent: boolean): Promise<void>;
|
|
19
19
|
setDarkMode(darkMode: boolean): Promise<void>;
|
|
20
20
|
private _download;
|
package/package.json
CHANGED
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
|
|
|
@@ -59,22 +59,23 @@ The top-level collection of CLI tools for tldraw.
|
|
|
59
59
|
tldraw-cli export <file-or-url>
|
|
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 | Description
|
|
65
|
-
| --------------- |
|
|
66
|
-
| `<file-or-url>` | The sketch to
|
|
64
|
+
| Argument | Description |
|
|
65
|
+
| --------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
66
|
+
| `<file-or-url>` | The sketch to export — either a path to a local `.tldr` file, or a tldraw\.com sketch URL. Prints the absolute path(s) to the exported image(s) to `stdout`. |
|
|
67
67
|
|
|
68
|
-
| Option | Alias | Description Value
|
|
69
|
-
| ------------------- | ----- |
|
|
70
|
-
| `--format <string>` | `-f` | Output image format, one of `svg`, `png`, `json`, or `tldr`.
|
|
71
|
-
| `--dark-mode ` | `-d` | Output a dark theme version of the image.
|
|
72
|
-
| `--transparent ` | `-t` | Output an image with a transparent background.
|
|
73
|
-
| `--output <string>` | `-o` | Output directory.
|
|
74
|
-
| `--name <string>` | `-n` | Output file name without extension; by default the original file name or URL id is used.
|
|
75
|
-
| `--frames <array?>` | | Export each sketch "frame" as a separate image
|
|
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
|
+
| `--dark-mode ` | `-d` | Output a dark theme version of the image. | `false` |
|
|
72
|
+
| `--transparent ` | `-t` | Output an image with a transparent background. | `false` |
|
|
73
|
+
| `--output <string>` | `-o` | Output directory. | `./` |
|
|
74
|
+
| `--name <string>` | `-n` | Output file name without extension; by default the original file name or URL id is used. | |
|
|
75
|
+
| `--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` |
|
|
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. | `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 output. | `false` |
|
|
78
79
|
|
|
79
80
|
#### Command: Open
|
|
80
81
|
|
|
@@ -82,26 +83,26 @@ Export a tldraw ".tldr" file or tldraw\.com URL to an svg, png image, and other
|
|
|
82
83
|
tldraw-cli open [file-or-url]
|
|
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.
|
|
86
87
|
|
|
87
88
|
Sketches opened via URL are copied to the local system, and will not be kept in sync with tldraw.com.
|
|
88
89
|
|
|
89
|
-
"Save as" support is not yet implemented in the local tldraw instance, so
|
|
90
|
+
_"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._
|
|
90
91
|
|
|
91
|
-
| Argument | Description
|
|
92
|
-
| --------------- |
|
|
93
|
-
| `[file-or-url]` | The
|
|
92
|
+
| Argument | Description |
|
|
93
|
+
| --------------- | --------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
94
|
+
| `[file-or-url]` | The `.tldr` file or tldraw\.com sketch url to open. Omit the argument to open a blank sketch. Prints the url of the local server to `stdout`. |
|
|
94
95
|
|
|
95
96
|
No options.
|
|
96
97
|
|
|
97
98
|
## Examples
|
|
98
99
|
|
|
99
|
-
### Basic
|
|
100
|
+
### Basic `.tldr` file image export
|
|
100
101
|
|
|
101
|
-
To export the file `your-drawing.tldr` to an
|
|
102
|
+
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
103
|
|
|
103
104
|
```sh
|
|
104
|
-
|
|
105
|
+
tldraw-cli export your-drawing.tldr
|
|
105
106
|
```
|
|
106
107
|
|
|
107
108
|
The file will retain its original name, e.g. `your-drawing.svg`
|
|
@@ -109,27 +110,27 @@ The file will retain its original name, e.g. `your-drawing.svg`
|
|
|
109
110
|
### Basic tldraw\.com image download
|
|
110
111
|
|
|
111
112
|
```sh
|
|
112
|
-
|
|
113
|
+
tldraw-cli export https://www.tldraw.com/s/v2_c_JsxJk8dag6QsrqExukis4
|
|
113
114
|
```
|
|
114
115
|
|
|
115
|
-
The tldraw URL's id (e.g. `v2_c_JsxJk8dag6QsrqExukis4`) will be used for the file name.
|
|
116
|
+
The tldraw.com URL's id (e.g. `v2_c_JsxJk8dag6QsrqExukis4`) will be used for the file name.
|
|
116
117
|
|
|
117
118
|
This is approximately equivalent to clicking the tldraw\.com "☰ → Edit → Export As → SVG" menu item.
|
|
118
119
|
|
|
119
120
|
### Export a remote tldraw\.com image to a local .tldr file
|
|
120
121
|
|
|
121
122
|
```sh
|
|
122
|
-
|
|
123
|
+
tldraw-cli export https://www.tldraw.com/s/v2_c_JsxJk8dag6QsrqExukis4 --format tldr
|
|
123
124
|
```
|
|
124
125
|
|
|
125
126
|
This is approximately equivalent to clicking the tldraw\.com "☰ → File → Save a copy" menu item.
|
|
126
127
|
|
|
127
128
|
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
129
|
|
|
129
|
-
### Export to a specific format
|
|
130
|
+
### Export to a specific image / file format
|
|
130
131
|
|
|
131
132
|
```sh
|
|
132
|
-
|
|
133
|
+
tldraw-cli export your-drawing.tldr --format png
|
|
133
134
|
```
|
|
134
135
|
|
|
135
136
|
This is approximately equivalent to clicking the tldraw\.com "☰ → Edit → Export As → PNG" menu item.
|
|
@@ -137,7 +138,7 @@ This is approximately equivalent to clicking the tldraw\.com "☰ → Edit → E
|
|
|
137
138
|
### Export with a transparent background
|
|
138
139
|
|
|
139
140
|
```sh
|
|
140
|
-
|
|
141
|
+
tldraw-cli export your-drawing.tldr --transparent --format png
|
|
141
142
|
```
|
|
142
143
|
|
|
143
144
|
This is approximately equivalent to checking the tldraw\.com "☰ → Edit → Export As → ☐ Transparent" menu item.
|
|
@@ -145,7 +146,7 @@ This is approximately equivalent to checking the tldraw\.com "☰ → Edit → E
|
|
|
145
146
|
### Export to a specific destination
|
|
146
147
|
|
|
147
148
|
```sh
|
|
148
|
-
|
|
149
|
+
tldraw-cli export your-drawing.tldr --output ~/Desktop
|
|
149
150
|
```
|
|
150
151
|
|
|
151
152
|
Exports to `~/Desktop/your-drawing.svg`
|
|
@@ -153,15 +154,15 @@ Exports to `~/Desktop/your-drawing.svg`
|
|
|
153
154
|
### Export to a specific destination and filename
|
|
154
155
|
|
|
155
156
|
```sh
|
|
156
|
-
|
|
157
|
+
tldraw-cli export your-drawing.tldr --output ~/Desktop --name not-your-drawing
|
|
157
158
|
```
|
|
158
159
|
|
|
159
160
|
Exports to `~/Desktop/not-your-drawing.svg`
|
|
160
161
|
|
|
161
|
-
### Export all frames from a tldraw URL
|
|
162
|
+
### Export all frames from a tldraw.com URL
|
|
162
163
|
|
|
163
164
|
```sh
|
|
164
|
-
|
|
165
|
+
tldraw-cli export https://www.tldraw.com/s/v2_c_FI5RYWbdpAtjsy4OIKrKw --frames
|
|
165
166
|
```
|
|
166
167
|
|
|
167
168
|
The exported files will be suffixed with their frame name, e.g.:
|
|
@@ -174,33 +175,45 @@ The frame name will be slugified.
|
|
|
174
175
|
|
|
175
176
|
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
177
|
|
|
177
|
-
### Export a specific frame from a tldraw URL
|
|
178
|
+
### Export a specific frame from a tldraw.com URL
|
|
178
179
|
|
|
179
180
|
```sh
|
|
180
|
-
|
|
181
|
+
tldraw-cli export https://www.tldraw.com/s/v2_c_FI5RYWbdpAtjsy4OIKrKw --frames "Frame 3"
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
### Export multiple frames from a tldraw.com URL
|
|
185
|
+
|
|
186
|
+
```sh
|
|
187
|
+
tldraw-cli export https://www.tldraw.com/s/v2_c_FI5RYWbdpAtjsy4OIKrKw --frames "Frame 1" "Frame 3"
|
|
181
188
|
```
|
|
182
189
|
|
|
183
190
|
### Export to JSON
|
|
184
191
|
|
|
185
192
|
```sh
|
|
186
|
-
|
|
193
|
+
tldraw-cli export https://www.tldraw.com/s/v2_c_FI5RYWbdpAtjsy4OIKrKw --format "json"
|
|
187
194
|
```
|
|
188
195
|
|
|
189
|
-
The
|
|
196
|
+
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
197
|
|
|
191
198
|
I'm not completely clear on the use-case for this format, but since tldr.com supports it, so too shall `tldraw-cli`.
|
|
192
199
|
|
|
193
|
-
###
|
|
200
|
+
### Write an SVG to stdout
|
|
201
|
+
|
|
202
|
+
```sh
|
|
203
|
+
tldraw-cli export https://www.tldraw.com/s/v2_c_FI5RYWbdpAtjsy4OIKrKw --print
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
### Open a tldraw.com URL
|
|
194
207
|
|
|
195
208
|
```sh
|
|
196
|
-
|
|
209
|
+
tldraw-cli open https://www.tldraw.com/s/v2_c_FI5RYWbdpAtjsy4OIKrKw
|
|
197
210
|
```
|
|
198
211
|
|
|
199
212
|
The remote sketch is copied to a locally-hosted instance of tldraw, which is then opened in your default browser.
|
|
200
213
|
|
|
201
214
|
## API usage
|
|
202
215
|
|
|
203
|
-
The `export` command's functionality is also provided
|
|
216
|
+
The `export` command's functionality is also provided in module form for use in TypeScript or JavaScript Node projects.
|
|
204
217
|
|
|
205
218
|
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
219
|
|
|
@@ -234,10 +247,10 @@ import { tldrawToImage } from '@kitschpatrol/tldraw-cli'
|
|
|
234
247
|
const [imagePath] = await tldrawToImage('./some-file.tldr', { format: 'png', output: './' })
|
|
235
248
|
console.log(`Wrote image to: "${imagePath}"`)
|
|
236
249
|
|
|
237
|
-
// Convert a remote tldraw URL to SVG
|
|
250
|
+
// Convert a remote tldraw.com URL to SVG
|
|
238
251
|
await tldrawToImage('https://www.tldraw.com/s/v2_c_JsxJk8dag6QsrqExukis4')
|
|
239
252
|
|
|
240
|
-
// Convert all frames from a single tldraw URL to separate SVGs
|
|
253
|
+
// Convert all frames from a single tldraw.com URL to separate SVGs
|
|
241
254
|
// When the `frames` option is set, the function returns an array
|
|
242
255
|
// of resulting file paths, instead of a solitary string
|
|
243
256
|
const framePathsArray = await tldrawToImage('https://www.tldraw.com/s/v2_c_FI5RYWbdpAtjsy4OIKrKw', {
|
|
@@ -245,7 +258,7 @@ const framePathsArray = await tldrawToImage('https://www.tldraw.com/s/v2_c_FI5RY
|
|
|
245
258
|
})
|
|
246
259
|
console.log(`Wrote frames to: "${framePathsArray}"`)
|
|
247
260
|
|
|
248
|
-
// Convert a specific frame from a tldraw URL to a PNG
|
|
261
|
+
// Convert a specific frame from a tldraw.com URL to a PNG
|
|
249
262
|
await tldrawToImage('https://www.tldraw.com/s/v2_c_FI5RYWbdpAtjsy4OIKrKw', {
|
|
250
263
|
frames: ['Frame 3'],
|
|
251
264
|
format: 'png',
|
|
@@ -297,6 +310,8 @@ This is a very minimal implementation. Current plans for future improvements inc
|
|
|
297
310
|
- Implement the ability to export specific pages as separate image files
|
|
298
311
|
- Add an option flag to set dpi when exporting to a bitmap format
|
|
299
312
|
- Additional commands beyond sketch conversion / export?
|
|
313
|
+
- There's room for optimization in how tldraw functions are passed to Puppeteer
|
|
314
|
+
- There's room for optimization in the `--print` option implementation
|
|
300
315
|
|
|
301
316
|
Any other suggestions are welcome.
|
|
302
317
|
|