@kitschpatrol/tldraw-cli 4.5.5 → 4.6.1
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 +101 -116
- package/dist/lib/index.d.ts +2 -0
- package/dist/lib/index.js +565 -6
- package/dist/lib/tldraw-open.d.ts +10 -0
- package/dist/lib/tldraw-to-share-url.d.ts +1 -0
- package/package.json +3 -3
- package/readme.md +70 -8
package/bin/cli.js
CHANGED
|
@@ -786,7 +786,7 @@ var require_irregular_plurals2 = __commonJS({
|
|
|
786
786
|
});
|
|
787
787
|
|
|
788
788
|
// package.json
|
|
789
|
-
var version = "4.
|
|
789
|
+
var version = "4.6.1";
|
|
790
790
|
|
|
791
791
|
// node_modules/.pnpm/chalk@5.3.0/node_modules/chalk/source/vendor/ansi-styles/index.js
|
|
792
792
|
var ANSI_BACKGROUND_OFFSET = 10;
|
|
@@ -17221,13 +17221,16 @@ var TldrawController = class {
|
|
|
17221
17221
|
log_default.errorPrefixed("Browser", messageText);
|
|
17222
17222
|
}
|
|
17223
17223
|
} else if (messageType === "warn") {
|
|
17224
|
-
|
|
17224
|
+
if (messageText !== "[tldraw] `Store.loadSnapshot` is deprecated and will be removed in a future release. Use `loadSnapshot` from the 'tldraw' package instead.") {
|
|
17225
|
+
log_default.warnPrefixed("Browser", messageText);
|
|
17226
|
+
}
|
|
17225
17227
|
} else {
|
|
17226
17228
|
log_default.infoPrefixed("Browser", messageText);
|
|
17227
17229
|
}
|
|
17228
17230
|
});
|
|
17229
17231
|
log_default.info(`Navigating to: ${this.href}`);
|
|
17230
17232
|
await this.page.goto(this.href, { waitUntil: "networkidle0" });
|
|
17233
|
+
await this.page.waitForFunction("editor !== undefined");
|
|
17231
17234
|
const shapeCount = await this.page.evaluate("editor.getCurrentPageShapes().length");
|
|
17232
17235
|
this.isEmpty = shapeCount === 0;
|
|
17233
17236
|
}
|
|
@@ -17308,6 +17311,7 @@ var TldrawController = class {
|
|
|
17308
17311
|
await this.setCurrentPage(download.pageId);
|
|
17309
17312
|
pageChanged = true;
|
|
17310
17313
|
}
|
|
17314
|
+
await this.page.waitForFunction("editor !== undefined");
|
|
17311
17315
|
if (download.frameId === void 0) {
|
|
17312
17316
|
await this.page.evaluate("editor.selectAll()");
|
|
17313
17317
|
} else {
|
|
@@ -17832,6 +17836,7 @@ function nanoid(size = 21) {
|
|
|
17832
17836
|
// src/lib/tldraw-open.ts
|
|
17833
17837
|
import fs8 from "node:fs/promises";
|
|
17834
17838
|
import os5 from "node:os";
|
|
17839
|
+
import { URL as URL2 } from "node:url";
|
|
17835
17840
|
|
|
17836
17841
|
// node_modules/.pnpm/open@10.1.0/node_modules/open/index.js
|
|
17837
17842
|
import process7 from "node:process";
|
|
@@ -18273,79 +18278,64 @@ defineLazyProperty(apps, "browserPrivate", () => "browserPrivate");
|
|
|
18273
18278
|
var open_default = open;
|
|
18274
18279
|
|
|
18275
18280
|
// src/lib/tldraw-open.ts
|
|
18276
|
-
|
|
18281
|
+
var tldrawOpenDefaultOptions = {
|
|
18282
|
+
location: "remote"
|
|
18283
|
+
};
|
|
18284
|
+
async function tldrawOpen(tldrPathOrUrl, options) {
|
|
18277
18285
|
const tldrawRemoteUrl = "https://www.tldraw.com";
|
|
18278
|
-
|
|
18286
|
+
const { location } = { ...tldrawOpenDefaultOptions, ...options };
|
|
18287
|
+
let urlToOpen;
|
|
18288
|
+
const validatedPathOrUrl = tldrPathOrUrl === void 0 ? void 0 : validatePathOrUrl(tldrPathOrUrl, {
|
|
18289
|
+
requireFileExistence: true,
|
|
18290
|
+
validFileExtensions: [".tldr"],
|
|
18291
|
+
validHostnames: ["www.tldraw.com"]
|
|
18292
|
+
});
|
|
18293
|
+
if (location === "local" && validatedPathOrUrl === void 0) {
|
|
18279
18294
|
const tldrawServer = new LocalTldrawServer();
|
|
18280
18295
|
await tldrawServer.start();
|
|
18281
|
-
|
|
18282
|
-
|
|
18283
|
-
|
|
18284
|
-
await
|
|
18285
|
-
|
|
18286
|
-
|
|
18287
|
-
|
|
18288
|
-
|
|
18289
|
-
|
|
18290
|
-
|
|
18291
|
-
|
|
18292
|
-
|
|
18293
|
-
|
|
18294
|
-
if (tldrPathOrUrl !== void 0) {
|
|
18295
|
-
const validatedPathOrUrl = validatePathOrUrl(tldrPathOrUrl, {
|
|
18296
|
-
requireFileExistence: true,
|
|
18297
|
-
validFileExtensions: [".tldr"],
|
|
18298
|
-
validHostnames: ["www.tldraw.com"]
|
|
18296
|
+
urlToOpen = tldrawServer.href;
|
|
18297
|
+
log_default.info(`Opened blank tldraw sketch locally at "${urlToOpen}"`);
|
|
18298
|
+
} else if (location === "local" && typeof validatedPathOrUrl === "string") {
|
|
18299
|
+
const tldrData = await fs8.readFile(validatedPathOrUrl, "utf8");
|
|
18300
|
+
const tldrawServer = new LocalTldrawServer(tldrData);
|
|
18301
|
+
await tldrawServer.start();
|
|
18302
|
+
urlToOpen = tldrawServer.href;
|
|
18303
|
+
log_default.info(`Opened copy of tldraw sketch "${validatedPathOrUrl}" locally at "${urlToOpen}"`);
|
|
18304
|
+
} else if (location === "local" && validatedPathOrUrl instanceof URL2) {
|
|
18305
|
+
const [savedFile] = await tldrawToImage(validatedPathOrUrl.href, {
|
|
18306
|
+
format: "tldr",
|
|
18307
|
+
name: nanoid(),
|
|
18308
|
+
output: os5.tmpdir()
|
|
18299
18309
|
});
|
|
18300
|
-
|
|
18301
|
-
|
|
18302
|
-
|
|
18303
|
-
|
|
18304
|
-
|
|
18305
|
-
|
|
18306
|
-
|
|
18307
|
-
|
|
18308
|
-
|
|
18309
|
-
|
|
18310
|
-
|
|
18311
|
-
|
|
18312
|
-
|
|
18313
|
-
|
|
18314
|
-
|
|
18315
|
-
|
|
18316
|
-
|
|
18317
|
-
|
|
18318
|
-
|
|
18319
|
-
|
|
18320
|
-
|
|
18321
|
-
}
|
|
18322
|
-
if (typeof validatedPathOrUrl !== "string" && local) {
|
|
18323
|
-
const [savedFile] = await tldrawToImage(validatedPathOrUrl.href, {
|
|
18324
|
-
format: "tldr",
|
|
18325
|
-
name: nanoid(),
|
|
18326
|
-
output: os5.tmpdir()
|
|
18327
|
-
});
|
|
18328
|
-
const tldrData = await fs8.readFile(savedFile, "utf8");
|
|
18329
|
-
await fs8.rm(savedFile, { force: true });
|
|
18330
|
-
const tldrawServer = new LocalTldrawServer(tldrData);
|
|
18331
|
-
await tldrawServer.start();
|
|
18332
|
-
log_default.info(
|
|
18333
|
-
`Opened a local copy of tldraw sketch url "${validatedPathOrUrl.href}" locally at ${tldrawServer.href}`
|
|
18334
|
-
);
|
|
18335
|
-
process.stdout.write(`${tldrawServer.href}
|
|
18336
|
-
`);
|
|
18337
|
-
await open_default(tldrawServer.href, { wait: true });
|
|
18338
|
-
return tldrawServer.href;
|
|
18339
|
-
}
|
|
18340
|
-
if (typeof validatedPathOrUrl !== "string" && !local) {
|
|
18341
|
-
await open_default(validatedPathOrUrl.href);
|
|
18342
|
-
log_default.info(`Opened tldraw sketch url at ${validatedPathOrUrl.href}`);
|
|
18343
|
-
process.stdout.write(`${validatedPathOrUrl.href}
|
|
18344
|
-
`);
|
|
18345
|
-
return validatedPathOrUrl.href;
|
|
18346
|
-
}
|
|
18310
|
+
const tldrData = await fs8.readFile(savedFile, "utf8");
|
|
18311
|
+
await fs8.rm(savedFile, { force: true });
|
|
18312
|
+
const tldrawServer = new LocalTldrawServer(tldrData);
|
|
18313
|
+
await tldrawServer.start();
|
|
18314
|
+
urlToOpen = tldrawServer.href;
|
|
18315
|
+
log_default.info(
|
|
18316
|
+
`Opened a local copy of tldraw sketch url "${validatedPathOrUrl.href}" locally at ${urlToOpen}`
|
|
18317
|
+
);
|
|
18318
|
+
} else if (location === "remote" && validatedPathOrUrl === void 0) {
|
|
18319
|
+
urlToOpen = tldrawRemoteUrl;
|
|
18320
|
+
log_default.info(`Opened tldraw.com`);
|
|
18321
|
+
} else if (location === "remote" && typeof validatedPathOrUrl === "string") {
|
|
18322
|
+
urlToOpen = await tldrawToShareUrl(validatedPathOrUrl);
|
|
18323
|
+
log_default.info(
|
|
18324
|
+
`Opened copy of local tldraw sketch "${validatedPathOrUrl}" remotely at "${urlToOpen}"`
|
|
18325
|
+
);
|
|
18326
|
+
} else if (location === "remote" && validatedPathOrUrl instanceof URL2) {
|
|
18327
|
+
urlToOpen = validatedPathOrUrl.href;
|
|
18328
|
+
log_default.info(`Opened tldraw sketch url at ${urlToOpen}`);
|
|
18329
|
+
} else {
|
|
18330
|
+
throw new Error("Invalid tldrawOpen options");
|
|
18347
18331
|
}
|
|
18348
|
-
|
|
18332
|
+
const exitPromise = open_default(urlToOpen, {
|
|
18333
|
+
wait: true
|
|
18334
|
+
});
|
|
18335
|
+
return {
|
|
18336
|
+
browserExitPromise: exitPromise,
|
|
18337
|
+
openedSketchUrl: urlToOpen
|
|
18338
|
+
};
|
|
18349
18339
|
}
|
|
18350
18340
|
|
|
18351
18341
|
// node_modules/.pnpm/plur@5.1.0/node_modules/plur/index.js
|
|
@@ -18463,29 +18453,29 @@ await yargsInstance.scriptName("tldraw").command("$0 <command>", "CLI tools for
|
|
|
18463
18453
|
}
|
|
18464
18454
|
return true;
|
|
18465
18455
|
}),
|
|
18466
|
-
async (
|
|
18467
|
-
|
|
18468
|
-
|
|
18469
|
-
|
|
18470
|
-
|
|
18471
|
-
|
|
18472
|
-
|
|
18473
|
-
|
|
18474
|
-
|
|
18475
|
-
|
|
18476
|
-
|
|
18477
|
-
|
|
18478
|
-
|
|
18479
|
-
|
|
18480
|
-
|
|
18481
|
-
|
|
18456
|
+
async ({
|
|
18457
|
+
dark,
|
|
18458
|
+
filesOrUrls,
|
|
18459
|
+
format,
|
|
18460
|
+
frames,
|
|
18461
|
+
name,
|
|
18462
|
+
output,
|
|
18463
|
+
padding,
|
|
18464
|
+
pages,
|
|
18465
|
+
print,
|
|
18466
|
+
scale,
|
|
18467
|
+
stripStyle,
|
|
18468
|
+
transparent,
|
|
18469
|
+
verbose
|
|
18470
|
+
}) => {
|
|
18471
|
+
const cleanFilesOrUrls = filesOrUrls.filter((fileOrUrl) => fileOrUrl !== void 0);
|
|
18482
18472
|
log_default.verbose = verbose;
|
|
18483
|
-
log_default.info(`Exporting ${
|
|
18473
|
+
log_default.info(`Exporting ${cleanFilesOrUrls.length} ${plur("sketch", cleanFilesOrUrls.length)}...`);
|
|
18484
18474
|
let nameIndex = 0;
|
|
18485
18475
|
const errorReport = [];
|
|
18486
|
-
for (const fileOrUrl of
|
|
18476
|
+
for (const fileOrUrl of cleanFilesOrUrls) {
|
|
18487
18477
|
try {
|
|
18488
|
-
const resolvedName =
|
|
18478
|
+
const resolvedName = cleanFilesOrUrls.length > 1 && name !== void 0 ? `${name}-${nameIndex++}` : name;
|
|
18489
18479
|
const exportList = await tldrawToImage(fileOrUrl, {
|
|
18490
18480
|
dark,
|
|
18491
18481
|
format,
|
|
@@ -18508,26 +18498,28 @@ await yargsInstance.scriptName("tldraw").command("$0 <command>", "CLI tools for
|
|
|
18508
18498
|
);
|
|
18509
18499
|
}
|
|
18510
18500
|
}
|
|
18511
|
-
const successCount =
|
|
18501
|
+
const successCount = cleanFilesOrUrls.length - errorReport.length;
|
|
18512
18502
|
if (errorReport.length > 0) {
|
|
18513
18503
|
log_default.error(
|
|
18514
|
-
`${successCount} of ${
|
|
18504
|
+
`${successCount} of ${cleanFilesOrUrls.length} ${plur("sketch", cleanFilesOrUrls.length)} exported successfully`
|
|
18515
18505
|
);
|
|
18516
18506
|
log_default.error(errorReport.join("\n"));
|
|
18517
18507
|
process.exit(1);
|
|
18518
18508
|
}
|
|
18519
18509
|
if (successCount === 0) {
|
|
18520
18510
|
log_default.error(
|
|
18521
|
-
`${successCount} of ${
|
|
18511
|
+
`${successCount} of ${cleanFilesOrUrls.length} ${plur("sketch", cleanFilesOrUrls.length)} exported successfully`
|
|
18522
18512
|
);
|
|
18523
18513
|
} else {
|
|
18524
|
-
log_default.info(
|
|
18514
|
+
log_default.info(
|
|
18515
|
+
`All ${successCount} ${plur("sketch", cleanFilesOrUrls.length)} exported successfully`
|
|
18516
|
+
);
|
|
18525
18517
|
}
|
|
18526
18518
|
process.exit(0);
|
|
18527
18519
|
}
|
|
18528
18520
|
).command(
|
|
18529
18521
|
"open [files-or-urls..]",
|
|
18530
|
-
"Open a tldraw `.tldr` file or tldraw.com URL in your default browser with either the official tldraw.com site or a locally-hosted instance of the editor. Call `open` without an argument to open a blank sketch. Sketches opened via URL with the `--local` flag will be temporarily copied to the local system, and will not be kept in sync with tldraw.com. This process does not exit until the browser is closed.",
|
|
18522
|
+
"Open a tldraw `.tldr` file or tldraw.com URL in your default browser with either the official tldraw.com site or a locally-hosted instance of the editor. Call `open` without an argument to open a blank sketch. Sketches opened via URL with the `--local` flag will be temporarily copied to the local system, and will not be kept in sync with tldraw.com. This process does not exit until the browser is closed. Warning: Passing a local .tldr file without the `--local` option will upload and share the sketch on tldraw.com.",
|
|
18531
18523
|
(yargs2) => yargs2.positional("files-or-urls", {
|
|
18532
18524
|
array: true,
|
|
18533
18525
|
default: void 0,
|
|
@@ -18543,37 +18535,30 @@ await yargsInstance.scriptName("tldraw").command("$0 <command>", "CLI tools for
|
|
|
18543
18535
|
describe: "Enable verbose logging. All verbose logs and prefixed with their log level and are printed to `stderr` for ease of redirection.",
|
|
18544
18536
|
type: "boolean"
|
|
18545
18537
|
}),
|
|
18546
|
-
async (
|
|
18547
|
-
const
|
|
18548
|
-
const { local
|
|
18538
|
+
async ({ filesOrUrls, local, verbose }) => {
|
|
18539
|
+
const cleanFilesOrUrls = filesOrUrls === void 0 ? [void 0] : filesOrUrls.length > 1 ? filesOrUrls.filter((fileOrUrl) => fileOrUrl !== void 0) : filesOrUrls;
|
|
18540
|
+
const tlDrawOpenOptions = { location: local ? "local" : "remote" };
|
|
18549
18541
|
log_default.verbose = verbose;
|
|
18550
|
-
const resultPromises = [];
|
|
18551
18542
|
let errorCount = 0;
|
|
18552
|
-
|
|
18543
|
+
const browserExitPromises = [];
|
|
18544
|
+
for (const fileOrUrl of cleanFilesOrUrls) {
|
|
18545
|
+
console.log("opening----------------------------------");
|
|
18546
|
+
console.log(fileOrUrl);
|
|
18553
18547
|
try {
|
|
18554
|
-
|
|
18548
|
+
const openResult = await tldrawOpen(fileOrUrl, tlDrawOpenOptions);
|
|
18549
|
+
process.stdout.write(`${openResult.openedSketchUrl}
|
|
18550
|
+
`);
|
|
18551
|
+
browserExitPromises.push(openResult.browserExitPromise);
|
|
18555
18552
|
} catch (error) {
|
|
18556
18553
|
errorCount++;
|
|
18557
|
-
log_default.error(
|
|
18558
|
-
|
|
18559
|
-
|
|
18560
|
-
for (const fileOrUrl of filesOrUrls) {
|
|
18561
|
-
if (fileOrUrl === void 0 || fileOrUrl === null) continue;
|
|
18562
|
-
try {
|
|
18563
|
-
resultPromises.push(tldrawOpen(fileOrUrl, local));
|
|
18564
|
-
} catch (error) {
|
|
18565
|
-
errorCount++;
|
|
18566
|
-
log_default.error(
|
|
18567
|
-
`Failed to open "${fileOrUrl}": ${error instanceof Error ? error.message : "Unknown Error"}`
|
|
18568
|
-
);
|
|
18569
|
-
}
|
|
18554
|
+
log_default.error(
|
|
18555
|
+
`Failed to open "${fileOrUrl}": ${error instanceof Error ? error.message : "Unknown Error"}`
|
|
18556
|
+
);
|
|
18570
18557
|
}
|
|
18571
18558
|
}
|
|
18572
18559
|
if (local) {
|
|
18573
18560
|
log_default.info(source_default.yellow(`Note: This process will exit once the browser is closed.`));
|
|
18574
|
-
|
|
18575
|
-
await Promise.all(resultPromises);
|
|
18576
|
-
if (local) {
|
|
18561
|
+
await Promise.allSettled(browserExitPromises);
|
|
18577
18562
|
log_default.info(`Closing local tldraw ${plur("server", filesOrUrls ? filesOrUrls.length : 1)}`);
|
|
18578
18563
|
}
|
|
18579
18564
|
if (errorCount === 0) {
|
package/dist/lib/index.d.ts
CHANGED
|
@@ -1,2 +1,4 @@
|
|
|
1
|
+
export { type TldrawOpenOptions, type TldrawOpenResult, tldrawOpen } from './tldraw-open';
|
|
1
2
|
export { type TldrawFormat, type TldrawToImageOptions, tldrawToImage } from './tldraw-to-image';
|
|
3
|
+
export { tldrawToShareUrl } from './tldraw-to-share-url';
|
|
2
4
|
export { default as log } from './utilities/log';
|
package/dist/lib/index.js
CHANGED
|
@@ -1031,18 +1031,18 @@ var proto = Object.defineProperties(() => {
|
|
|
1031
1031
|
}
|
|
1032
1032
|
}
|
|
1033
1033
|
});
|
|
1034
|
-
var createStyler = (
|
|
1034
|
+
var createStyler = (open2, close, parent2) => {
|
|
1035
1035
|
let openAll;
|
|
1036
1036
|
let closeAll;
|
|
1037
1037
|
if (parent2 === void 0) {
|
|
1038
|
-
openAll =
|
|
1038
|
+
openAll = open2;
|
|
1039
1039
|
closeAll = close;
|
|
1040
1040
|
} else {
|
|
1041
|
-
openAll = parent2.openAll +
|
|
1041
|
+
openAll = parent2.openAll + open2;
|
|
1042
1042
|
closeAll = close + parent2.closeAll;
|
|
1043
1043
|
}
|
|
1044
1044
|
return {
|
|
1045
|
-
open,
|
|
1045
|
+
open: open2,
|
|
1046
1046
|
close,
|
|
1047
1047
|
openAll,
|
|
1048
1048
|
closeAll,
|
|
@@ -17027,13 +17027,16 @@ var TldrawController = class {
|
|
|
17027
17027
|
log_default.errorPrefixed("Browser", messageText);
|
|
17028
17028
|
}
|
|
17029
17029
|
} else if (messageType === "warn") {
|
|
17030
|
-
|
|
17030
|
+
if (messageText !== "[tldraw] `Store.loadSnapshot` is deprecated and will be removed in a future release. Use `loadSnapshot` from the 'tldraw' package instead.") {
|
|
17031
|
+
log_default.warnPrefixed("Browser", messageText);
|
|
17032
|
+
}
|
|
17031
17033
|
} else {
|
|
17032
17034
|
log_default.infoPrefixed("Browser", messageText);
|
|
17033
17035
|
}
|
|
17034
17036
|
});
|
|
17035
17037
|
log_default.info(`Navigating to: ${this.href}`);
|
|
17036
17038
|
await this.page.goto(this.href, { waitUntil: "networkidle0" });
|
|
17039
|
+
await this.page.waitForFunction("editor !== undefined");
|
|
17037
17040
|
const shapeCount = await this.page.evaluate("editor.getCurrentPageShapes().length");
|
|
17038
17041
|
this.isEmpty = shapeCount === 0;
|
|
17039
17042
|
}
|
|
@@ -17114,6 +17117,7 @@ var TldrawController = class {
|
|
|
17114
17117
|
await this.setCurrentPage(download.pageId);
|
|
17115
17118
|
pageChanged = true;
|
|
17116
17119
|
}
|
|
17120
|
+
await this.page.waitForFunction("editor !== undefined");
|
|
17117
17121
|
if (download.frameId === void 0) {
|
|
17118
17122
|
await this.page.evaluate("editor.selectAll()");
|
|
17119
17123
|
} else {
|
|
@@ -17586,7 +17590,562 @@ function sanitizeName(name, format) {
|
|
|
17586
17590
|
}
|
|
17587
17591
|
return path4.basename(name);
|
|
17588
17592
|
}
|
|
17593
|
+
|
|
17594
|
+
// src/lib/tldraw-to-share-url.ts
|
|
17595
|
+
async function tldrawToShareUrl(tldrPathOrUrl) {
|
|
17596
|
+
const validatedPathOrUrl = validatePathOrUrl(tldrPathOrUrl, {
|
|
17597
|
+
requireFileExistence: true,
|
|
17598
|
+
validFileExtensions: [".tldr"],
|
|
17599
|
+
validHostnames: ["www.tldraw.com"]
|
|
17600
|
+
});
|
|
17601
|
+
if (typeof validatedPathOrUrl === "string") {
|
|
17602
|
+
const tldrawController = new TldrawController("https://www.tldraw.com");
|
|
17603
|
+
await tldrawController.start();
|
|
17604
|
+
await tldrawController.loadFile(validatedPathOrUrl);
|
|
17605
|
+
const shareUrl = await tldrawController.getShareUrl();
|
|
17606
|
+
await tldrawController.close();
|
|
17607
|
+
return shareUrl;
|
|
17608
|
+
}
|
|
17609
|
+
return validatedPathOrUrl.href;
|
|
17610
|
+
}
|
|
17611
|
+
|
|
17612
|
+
// node_modules/.pnpm/nanoid@5.0.7/node_modules/nanoid/index.js
|
|
17613
|
+
import { webcrypto as crypto } from "node:crypto";
|
|
17614
|
+
|
|
17615
|
+
// node_modules/.pnpm/nanoid@5.0.7/node_modules/nanoid/url-alphabet/index.js
|
|
17616
|
+
var urlAlphabet = "useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict";
|
|
17617
|
+
|
|
17618
|
+
// node_modules/.pnpm/nanoid@5.0.7/node_modules/nanoid/index.js
|
|
17619
|
+
var POOL_SIZE_MULTIPLIER = 128;
|
|
17620
|
+
var pool;
|
|
17621
|
+
var poolOffset;
|
|
17622
|
+
function fillPool(bytes) {
|
|
17623
|
+
if (!pool || pool.length < bytes) {
|
|
17624
|
+
pool = Buffer.allocUnsafe(bytes * POOL_SIZE_MULTIPLIER);
|
|
17625
|
+
crypto.getRandomValues(pool);
|
|
17626
|
+
poolOffset = 0;
|
|
17627
|
+
} else if (poolOffset + bytes > pool.length) {
|
|
17628
|
+
crypto.getRandomValues(pool);
|
|
17629
|
+
poolOffset = 0;
|
|
17630
|
+
}
|
|
17631
|
+
poolOffset += bytes;
|
|
17632
|
+
}
|
|
17633
|
+
function nanoid(size = 21) {
|
|
17634
|
+
fillPool(size -= 0);
|
|
17635
|
+
let id = "";
|
|
17636
|
+
for (let i = poolOffset - size; i < poolOffset; i++) {
|
|
17637
|
+
id += urlAlphabet[pool[i] & 63];
|
|
17638
|
+
}
|
|
17639
|
+
return id;
|
|
17640
|
+
}
|
|
17641
|
+
|
|
17642
|
+
// src/lib/tldraw-open.ts
|
|
17643
|
+
import fs8 from "node:fs/promises";
|
|
17644
|
+
import os5 from "node:os";
|
|
17645
|
+
import { URL as URL2 } from "node:url";
|
|
17646
|
+
|
|
17647
|
+
// node_modules/.pnpm/open@10.1.0/node_modules/open/index.js
|
|
17648
|
+
import process7 from "node:process";
|
|
17649
|
+
import { Buffer as Buffer2 } from "node:buffer";
|
|
17650
|
+
import path5 from "node:path";
|
|
17651
|
+
import { fileURLToPath as fileURLToPath3 } from "node:url";
|
|
17652
|
+
import childProcess from "node:child_process";
|
|
17653
|
+
import fs7, { constants as fsConstants } from "node:fs/promises";
|
|
17654
|
+
|
|
17655
|
+
// node_modules/.pnpm/is-wsl@3.1.0/node_modules/is-wsl/index.js
|
|
17656
|
+
import process3 from "node:process";
|
|
17657
|
+
import os4 from "node:os";
|
|
17658
|
+
import fs6 from "node:fs";
|
|
17659
|
+
|
|
17660
|
+
// node_modules/.pnpm/is-inside-container@1.0.0/node_modules/is-inside-container/index.js
|
|
17661
|
+
import fs5 from "node:fs";
|
|
17662
|
+
|
|
17663
|
+
// node_modules/.pnpm/is-docker@3.0.0/node_modules/is-docker/index.js
|
|
17664
|
+
import fs4 from "node:fs";
|
|
17665
|
+
var isDockerCached;
|
|
17666
|
+
function hasDockerEnv() {
|
|
17667
|
+
try {
|
|
17668
|
+
fs4.statSync("/.dockerenv");
|
|
17669
|
+
return true;
|
|
17670
|
+
} catch {
|
|
17671
|
+
return false;
|
|
17672
|
+
}
|
|
17673
|
+
}
|
|
17674
|
+
function hasDockerCGroup() {
|
|
17675
|
+
try {
|
|
17676
|
+
return fs4.readFileSync("/proc/self/cgroup", "utf8").includes("docker");
|
|
17677
|
+
} catch {
|
|
17678
|
+
return false;
|
|
17679
|
+
}
|
|
17680
|
+
}
|
|
17681
|
+
function isDocker() {
|
|
17682
|
+
if (isDockerCached === void 0) {
|
|
17683
|
+
isDockerCached = hasDockerEnv() || hasDockerCGroup();
|
|
17684
|
+
}
|
|
17685
|
+
return isDockerCached;
|
|
17686
|
+
}
|
|
17687
|
+
|
|
17688
|
+
// node_modules/.pnpm/is-inside-container@1.0.0/node_modules/is-inside-container/index.js
|
|
17689
|
+
var cachedResult;
|
|
17690
|
+
var hasContainerEnv = () => {
|
|
17691
|
+
try {
|
|
17692
|
+
fs5.statSync("/run/.containerenv");
|
|
17693
|
+
return true;
|
|
17694
|
+
} catch {
|
|
17695
|
+
return false;
|
|
17696
|
+
}
|
|
17697
|
+
};
|
|
17698
|
+
function isInsideContainer() {
|
|
17699
|
+
if (cachedResult === void 0) {
|
|
17700
|
+
cachedResult = hasContainerEnv() || isDocker();
|
|
17701
|
+
}
|
|
17702
|
+
return cachedResult;
|
|
17703
|
+
}
|
|
17704
|
+
|
|
17705
|
+
// node_modules/.pnpm/is-wsl@3.1.0/node_modules/is-wsl/index.js
|
|
17706
|
+
var isWsl = () => {
|
|
17707
|
+
if (process3.platform !== "linux") {
|
|
17708
|
+
return false;
|
|
17709
|
+
}
|
|
17710
|
+
if (os4.release().toLowerCase().includes("microsoft")) {
|
|
17711
|
+
if (isInsideContainer()) {
|
|
17712
|
+
return false;
|
|
17713
|
+
}
|
|
17714
|
+
return true;
|
|
17715
|
+
}
|
|
17716
|
+
try {
|
|
17717
|
+
return fs6.readFileSync("/proc/version", "utf8").toLowerCase().includes("microsoft") ? !isInsideContainer() : false;
|
|
17718
|
+
} catch {
|
|
17719
|
+
return false;
|
|
17720
|
+
}
|
|
17721
|
+
};
|
|
17722
|
+
var is_wsl_default = process3.env.__IS_WSL_TEST__ ? isWsl : isWsl();
|
|
17723
|
+
|
|
17724
|
+
// node_modules/.pnpm/define-lazy-prop@3.0.0/node_modules/define-lazy-prop/index.js
|
|
17725
|
+
function defineLazyProperty(object, propertyName, valueGetter) {
|
|
17726
|
+
const define = (value) => Object.defineProperty(object, propertyName, { value, enumerable: true, writable: true });
|
|
17727
|
+
Object.defineProperty(object, propertyName, {
|
|
17728
|
+
configurable: true,
|
|
17729
|
+
enumerable: true,
|
|
17730
|
+
get() {
|
|
17731
|
+
const result = valueGetter();
|
|
17732
|
+
define(result);
|
|
17733
|
+
return result;
|
|
17734
|
+
},
|
|
17735
|
+
set(value) {
|
|
17736
|
+
define(value);
|
|
17737
|
+
}
|
|
17738
|
+
});
|
|
17739
|
+
return object;
|
|
17740
|
+
}
|
|
17741
|
+
|
|
17742
|
+
// node_modules/.pnpm/default-browser@5.2.1/node_modules/default-browser/index.js
|
|
17743
|
+
import { promisify as promisify4 } from "node:util";
|
|
17744
|
+
import process6 from "node:process";
|
|
17745
|
+
import { execFile as execFile4 } from "node:child_process";
|
|
17746
|
+
|
|
17747
|
+
// node_modules/.pnpm/default-browser-id@5.0.0/node_modules/default-browser-id/index.js
|
|
17748
|
+
import { promisify } from "node:util";
|
|
17749
|
+
import process4 from "node:process";
|
|
17750
|
+
import { execFile } from "node:child_process";
|
|
17751
|
+
var execFileAsync = promisify(execFile);
|
|
17752
|
+
async function defaultBrowserId() {
|
|
17753
|
+
if (process4.platform !== "darwin") {
|
|
17754
|
+
throw new Error("macOS only");
|
|
17755
|
+
}
|
|
17756
|
+
const { stdout } = await execFileAsync("defaults", ["read", "com.apple.LaunchServices/com.apple.launchservices.secure", "LSHandlers"]);
|
|
17757
|
+
const match = /LSHandlerRoleAll = "(?!-)(?<id>[^"]+?)";\s+?LSHandlerURLScheme = (?:http|https);/.exec(stdout);
|
|
17758
|
+
return match?.groups.id ?? "com.apple.Safari";
|
|
17759
|
+
}
|
|
17760
|
+
|
|
17761
|
+
// node_modules/.pnpm/run-applescript@7.0.0/node_modules/run-applescript/index.js
|
|
17762
|
+
import process5 from "node:process";
|
|
17763
|
+
import { promisify as promisify2 } from "node:util";
|
|
17764
|
+
import { execFile as execFile2, execFileSync } from "node:child_process";
|
|
17765
|
+
var execFileAsync2 = promisify2(execFile2);
|
|
17766
|
+
async function runAppleScript(script, { humanReadableOutput = true } = {}) {
|
|
17767
|
+
if (process5.platform !== "darwin") {
|
|
17768
|
+
throw new Error("macOS only");
|
|
17769
|
+
}
|
|
17770
|
+
const outputArguments = humanReadableOutput ? [] : ["-ss"];
|
|
17771
|
+
const { stdout } = await execFileAsync2("osascript", ["-e", script, outputArguments]);
|
|
17772
|
+
return stdout.trim();
|
|
17773
|
+
}
|
|
17774
|
+
|
|
17775
|
+
// node_modules/.pnpm/bundle-name@4.1.0/node_modules/bundle-name/index.js
|
|
17776
|
+
async function bundleName(bundleId) {
|
|
17777
|
+
return runAppleScript(`tell application "Finder" to set app_path to application file id "${bundleId}" as string
|
|
17778
|
+
tell application "System Events" to get value of property list item "CFBundleName" of property list file (app_path & ":Contents:Info.plist")`);
|
|
17779
|
+
}
|
|
17780
|
+
|
|
17781
|
+
// node_modules/.pnpm/default-browser@5.2.1/node_modules/default-browser/windows.js
|
|
17782
|
+
import { promisify as promisify3 } from "node:util";
|
|
17783
|
+
import { execFile as execFile3 } from "node:child_process";
|
|
17784
|
+
var execFileAsync3 = promisify3(execFile3);
|
|
17785
|
+
var windowsBrowserProgIds = {
|
|
17786
|
+
AppXq0fevzme2pys62n3e0fbqa7peapykr8v: { name: "Edge", id: "com.microsoft.edge.old" },
|
|
17787
|
+
MSEdgeDHTML: { name: "Edge", id: "com.microsoft.edge" },
|
|
17788
|
+
// On macOS, it's "com.microsoft.edgemac"
|
|
17789
|
+
MSEdgeHTM: { name: "Edge", id: "com.microsoft.edge" },
|
|
17790
|
+
// Newer Edge/Win10 releases
|
|
17791
|
+
"IE.HTTP": { name: "Internet Explorer", id: "com.microsoft.ie" },
|
|
17792
|
+
FirefoxURL: { name: "Firefox", id: "org.mozilla.firefox" },
|
|
17793
|
+
ChromeHTML: { name: "Chrome", id: "com.google.chrome" },
|
|
17794
|
+
BraveHTML: { name: "Brave", id: "com.brave.Browser" },
|
|
17795
|
+
BraveBHTML: { name: "Brave Beta", id: "com.brave.Browser.beta" },
|
|
17796
|
+
BraveSSHTM: { name: "Brave Nightly", id: "com.brave.Browser.nightly" }
|
|
17797
|
+
};
|
|
17798
|
+
var UnknownBrowserError = class extends Error {
|
|
17799
|
+
};
|
|
17800
|
+
async function defaultBrowser(_execFileAsync = execFileAsync3) {
|
|
17801
|
+
const { stdout } = await _execFileAsync("reg", [
|
|
17802
|
+
"QUERY",
|
|
17803
|
+
" HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\Shell\\Associations\\UrlAssociations\\http\\UserChoice",
|
|
17804
|
+
"/v",
|
|
17805
|
+
"ProgId"
|
|
17806
|
+
]);
|
|
17807
|
+
const match = /ProgId\s*REG_SZ\s*(?<id>\S+)/.exec(stdout);
|
|
17808
|
+
if (!match) {
|
|
17809
|
+
throw new UnknownBrowserError(`Cannot find Windows browser in stdout: ${JSON.stringify(stdout)}`);
|
|
17810
|
+
}
|
|
17811
|
+
const { id } = match.groups;
|
|
17812
|
+
const browser = windowsBrowserProgIds[id];
|
|
17813
|
+
if (!browser) {
|
|
17814
|
+
throw new UnknownBrowserError(`Unknown browser ID: ${id}`);
|
|
17815
|
+
}
|
|
17816
|
+
return browser;
|
|
17817
|
+
}
|
|
17818
|
+
|
|
17819
|
+
// node_modules/.pnpm/default-browser@5.2.1/node_modules/default-browser/index.js
|
|
17820
|
+
var execFileAsync4 = promisify4(execFile4);
|
|
17821
|
+
var titleize = (string) => string.toLowerCase().replaceAll(/(?:^|\s|-)\S/g, (x) => x.toUpperCase());
|
|
17822
|
+
async function defaultBrowser2() {
|
|
17823
|
+
if (process6.platform === "darwin") {
|
|
17824
|
+
const id = await defaultBrowserId();
|
|
17825
|
+
const name = await bundleName(id);
|
|
17826
|
+
return { name, id };
|
|
17827
|
+
}
|
|
17828
|
+
if (process6.platform === "linux") {
|
|
17829
|
+
const { stdout } = await execFileAsync4("xdg-mime", ["query", "default", "x-scheme-handler/http"]);
|
|
17830
|
+
const id = stdout.trim();
|
|
17831
|
+
const name = titleize(id.replace(/.desktop$/, "").replace("-", " "));
|
|
17832
|
+
return { name, id };
|
|
17833
|
+
}
|
|
17834
|
+
if (process6.platform === "win32") {
|
|
17835
|
+
return defaultBrowser();
|
|
17836
|
+
}
|
|
17837
|
+
throw new Error("Only macOS, Linux, and Windows are supported");
|
|
17838
|
+
}
|
|
17839
|
+
|
|
17840
|
+
// node_modules/.pnpm/open@10.1.0/node_modules/open/index.js
|
|
17841
|
+
var __dirname = path5.dirname(fileURLToPath3(import.meta.url));
|
|
17842
|
+
var localXdgOpenPath = path5.join(__dirname, "xdg-open");
|
|
17843
|
+
var { platform, arch } = process7;
|
|
17844
|
+
var getWslDrivesMountPoint = /* @__PURE__ */ (() => {
|
|
17845
|
+
const defaultMountPoint = "/mnt/";
|
|
17846
|
+
let mountPoint;
|
|
17847
|
+
return async function() {
|
|
17848
|
+
if (mountPoint) {
|
|
17849
|
+
return mountPoint;
|
|
17850
|
+
}
|
|
17851
|
+
const configFilePath = "/etc/wsl.conf";
|
|
17852
|
+
let isConfigFileExists = false;
|
|
17853
|
+
try {
|
|
17854
|
+
await fs7.access(configFilePath, fsConstants.F_OK);
|
|
17855
|
+
isConfigFileExists = true;
|
|
17856
|
+
} catch {
|
|
17857
|
+
}
|
|
17858
|
+
if (!isConfigFileExists) {
|
|
17859
|
+
return defaultMountPoint;
|
|
17860
|
+
}
|
|
17861
|
+
const configContent = await fs7.readFile(configFilePath, { encoding: "utf8" });
|
|
17862
|
+
const configMountPoint = /(?<!#.*)root\s*=\s*(?<mountPoint>.*)/g.exec(configContent);
|
|
17863
|
+
if (!configMountPoint) {
|
|
17864
|
+
return defaultMountPoint;
|
|
17865
|
+
}
|
|
17866
|
+
mountPoint = configMountPoint.groups.mountPoint.trim();
|
|
17867
|
+
mountPoint = mountPoint.endsWith("/") ? mountPoint : `${mountPoint}/`;
|
|
17868
|
+
return mountPoint;
|
|
17869
|
+
};
|
|
17870
|
+
})();
|
|
17871
|
+
var pTryEach = async (array, mapper) => {
|
|
17872
|
+
let latestError;
|
|
17873
|
+
for (const item of array) {
|
|
17874
|
+
try {
|
|
17875
|
+
return await mapper(item);
|
|
17876
|
+
} catch (error) {
|
|
17877
|
+
latestError = error;
|
|
17878
|
+
}
|
|
17879
|
+
}
|
|
17880
|
+
throw latestError;
|
|
17881
|
+
};
|
|
17882
|
+
var baseOpen = async (options) => {
|
|
17883
|
+
options = {
|
|
17884
|
+
wait: false,
|
|
17885
|
+
background: false,
|
|
17886
|
+
newInstance: false,
|
|
17887
|
+
allowNonzeroExitCode: false,
|
|
17888
|
+
...options
|
|
17889
|
+
};
|
|
17890
|
+
if (Array.isArray(options.app)) {
|
|
17891
|
+
return pTryEach(options.app, (singleApp) => baseOpen({
|
|
17892
|
+
...options,
|
|
17893
|
+
app: singleApp
|
|
17894
|
+
}));
|
|
17895
|
+
}
|
|
17896
|
+
let { name: app, arguments: appArguments = [] } = options.app ?? {};
|
|
17897
|
+
appArguments = [...appArguments];
|
|
17898
|
+
if (Array.isArray(app)) {
|
|
17899
|
+
return pTryEach(app, (appName) => baseOpen({
|
|
17900
|
+
...options,
|
|
17901
|
+
app: {
|
|
17902
|
+
name: appName,
|
|
17903
|
+
arguments: appArguments
|
|
17904
|
+
}
|
|
17905
|
+
}));
|
|
17906
|
+
}
|
|
17907
|
+
if (app === "browser" || app === "browserPrivate") {
|
|
17908
|
+
const ids = {
|
|
17909
|
+
"com.google.chrome": "chrome",
|
|
17910
|
+
"google-chrome.desktop": "chrome",
|
|
17911
|
+
"org.mozilla.firefox": "firefox",
|
|
17912
|
+
"firefox.desktop": "firefox",
|
|
17913
|
+
"com.microsoft.msedge": "edge",
|
|
17914
|
+
"com.microsoft.edge": "edge",
|
|
17915
|
+
"microsoft-edge.desktop": "edge"
|
|
17916
|
+
};
|
|
17917
|
+
const flags = {
|
|
17918
|
+
chrome: "--incognito",
|
|
17919
|
+
firefox: "--private-window",
|
|
17920
|
+
edge: "--inPrivate"
|
|
17921
|
+
};
|
|
17922
|
+
const browser = await defaultBrowser2();
|
|
17923
|
+
if (browser.id in ids) {
|
|
17924
|
+
const browserName = ids[browser.id];
|
|
17925
|
+
if (app === "browserPrivate") {
|
|
17926
|
+
appArguments.push(flags[browserName]);
|
|
17927
|
+
}
|
|
17928
|
+
return baseOpen({
|
|
17929
|
+
...options,
|
|
17930
|
+
app: {
|
|
17931
|
+
name: apps[browserName],
|
|
17932
|
+
arguments: appArguments
|
|
17933
|
+
}
|
|
17934
|
+
});
|
|
17935
|
+
}
|
|
17936
|
+
throw new Error(`${browser.name} is not supported as a default browser`);
|
|
17937
|
+
}
|
|
17938
|
+
let command;
|
|
17939
|
+
const cliArguments = [];
|
|
17940
|
+
const childProcessOptions = {};
|
|
17941
|
+
if (platform === "darwin") {
|
|
17942
|
+
command = "open";
|
|
17943
|
+
if (options.wait) {
|
|
17944
|
+
cliArguments.push("--wait-apps");
|
|
17945
|
+
}
|
|
17946
|
+
if (options.background) {
|
|
17947
|
+
cliArguments.push("--background");
|
|
17948
|
+
}
|
|
17949
|
+
if (options.newInstance) {
|
|
17950
|
+
cliArguments.push("--new");
|
|
17951
|
+
}
|
|
17952
|
+
if (app) {
|
|
17953
|
+
cliArguments.push("-a", app);
|
|
17954
|
+
}
|
|
17955
|
+
} else if (platform === "win32" || is_wsl_default && !isInsideContainer() && !app) {
|
|
17956
|
+
const mountPoint = await getWslDrivesMountPoint();
|
|
17957
|
+
command = is_wsl_default ? `${mountPoint}c/Windows/System32/WindowsPowerShell/v1.0/powershell.exe` : `${process7.env.SYSTEMROOT || process7.env.windir || "C:\\Windows"}\\System32\\WindowsPowerShell\\v1.0\\powershell`;
|
|
17958
|
+
cliArguments.push(
|
|
17959
|
+
"-NoProfile",
|
|
17960
|
+
"-NonInteractive",
|
|
17961
|
+
"-ExecutionPolicy",
|
|
17962
|
+
"Bypass",
|
|
17963
|
+
"-EncodedCommand"
|
|
17964
|
+
);
|
|
17965
|
+
if (!is_wsl_default) {
|
|
17966
|
+
childProcessOptions.windowsVerbatimArguments = true;
|
|
17967
|
+
}
|
|
17968
|
+
const encodedArguments = ["Start"];
|
|
17969
|
+
if (options.wait) {
|
|
17970
|
+
encodedArguments.push("-Wait");
|
|
17971
|
+
}
|
|
17972
|
+
if (app) {
|
|
17973
|
+
encodedArguments.push(`"\`"${app}\`""`);
|
|
17974
|
+
if (options.target) {
|
|
17975
|
+
appArguments.push(options.target);
|
|
17976
|
+
}
|
|
17977
|
+
} else if (options.target) {
|
|
17978
|
+
encodedArguments.push(`"${options.target}"`);
|
|
17979
|
+
}
|
|
17980
|
+
if (appArguments.length > 0) {
|
|
17981
|
+
appArguments = appArguments.map((argument) => `"\`"${argument}\`""`);
|
|
17982
|
+
encodedArguments.push("-ArgumentList", appArguments.join(","));
|
|
17983
|
+
}
|
|
17984
|
+
options.target = Buffer2.from(encodedArguments.join(" "), "utf16le").toString("base64");
|
|
17985
|
+
} else {
|
|
17986
|
+
if (app) {
|
|
17987
|
+
command = app;
|
|
17988
|
+
} else {
|
|
17989
|
+
const isBundled = !__dirname || __dirname === "/";
|
|
17990
|
+
let exeLocalXdgOpen = false;
|
|
17991
|
+
try {
|
|
17992
|
+
await fs7.access(localXdgOpenPath, fsConstants.X_OK);
|
|
17993
|
+
exeLocalXdgOpen = true;
|
|
17994
|
+
} catch {
|
|
17995
|
+
}
|
|
17996
|
+
const useSystemXdgOpen = process7.versions.electron ?? (platform === "android" || isBundled || !exeLocalXdgOpen);
|
|
17997
|
+
command = useSystemXdgOpen ? "xdg-open" : localXdgOpenPath;
|
|
17998
|
+
}
|
|
17999
|
+
if (appArguments.length > 0) {
|
|
18000
|
+
cliArguments.push(...appArguments);
|
|
18001
|
+
}
|
|
18002
|
+
if (!options.wait) {
|
|
18003
|
+
childProcessOptions.stdio = "ignore";
|
|
18004
|
+
childProcessOptions.detached = true;
|
|
18005
|
+
}
|
|
18006
|
+
}
|
|
18007
|
+
if (platform === "darwin" && appArguments.length > 0) {
|
|
18008
|
+
cliArguments.push("--args", ...appArguments);
|
|
18009
|
+
}
|
|
18010
|
+
if (options.target) {
|
|
18011
|
+
cliArguments.push(options.target);
|
|
18012
|
+
}
|
|
18013
|
+
const subprocess = childProcess.spawn(command, cliArguments, childProcessOptions);
|
|
18014
|
+
if (options.wait) {
|
|
18015
|
+
return new Promise((resolve, reject) => {
|
|
18016
|
+
subprocess.once("error", reject);
|
|
18017
|
+
subprocess.once("close", (exitCode) => {
|
|
18018
|
+
if (!options.allowNonzeroExitCode && exitCode > 0) {
|
|
18019
|
+
reject(new Error(`Exited with code ${exitCode}`));
|
|
18020
|
+
return;
|
|
18021
|
+
}
|
|
18022
|
+
resolve(subprocess);
|
|
18023
|
+
});
|
|
18024
|
+
});
|
|
18025
|
+
}
|
|
18026
|
+
subprocess.unref();
|
|
18027
|
+
return subprocess;
|
|
18028
|
+
};
|
|
18029
|
+
var open = (target, options) => {
|
|
18030
|
+
if (typeof target !== "string") {
|
|
18031
|
+
throw new TypeError("Expected a `target`");
|
|
18032
|
+
}
|
|
18033
|
+
return baseOpen({
|
|
18034
|
+
...options,
|
|
18035
|
+
target
|
|
18036
|
+
});
|
|
18037
|
+
};
|
|
18038
|
+
function detectArchBinary(binary) {
|
|
18039
|
+
if (typeof binary === "string" || Array.isArray(binary)) {
|
|
18040
|
+
return binary;
|
|
18041
|
+
}
|
|
18042
|
+
const { [arch]: archBinary } = binary;
|
|
18043
|
+
if (!archBinary) {
|
|
18044
|
+
throw new Error(`${arch} is not supported`);
|
|
18045
|
+
}
|
|
18046
|
+
return archBinary;
|
|
18047
|
+
}
|
|
18048
|
+
function detectPlatformBinary({ [platform]: platformBinary }, { wsl }) {
|
|
18049
|
+
if (wsl && is_wsl_default) {
|
|
18050
|
+
return detectArchBinary(wsl);
|
|
18051
|
+
}
|
|
18052
|
+
if (!platformBinary) {
|
|
18053
|
+
throw new Error(`${platform} is not supported`);
|
|
18054
|
+
}
|
|
18055
|
+
return detectArchBinary(platformBinary);
|
|
18056
|
+
}
|
|
18057
|
+
var apps = {};
|
|
18058
|
+
defineLazyProperty(apps, "chrome", () => detectPlatformBinary({
|
|
18059
|
+
darwin: "google chrome",
|
|
18060
|
+
win32: "chrome",
|
|
18061
|
+
linux: ["google-chrome", "google-chrome-stable", "chromium"]
|
|
18062
|
+
}, {
|
|
18063
|
+
wsl: {
|
|
18064
|
+
ia32: "/mnt/c/Program Files (x86)/Google/Chrome/Application/chrome.exe",
|
|
18065
|
+
x64: ["/mnt/c/Program Files/Google/Chrome/Application/chrome.exe", "/mnt/c/Program Files (x86)/Google/Chrome/Application/chrome.exe"]
|
|
18066
|
+
}
|
|
18067
|
+
}));
|
|
18068
|
+
defineLazyProperty(apps, "firefox", () => detectPlatformBinary({
|
|
18069
|
+
darwin: "firefox",
|
|
18070
|
+
win32: "C:\\Program Files\\Mozilla Firefox\\firefox.exe",
|
|
18071
|
+
linux: "firefox"
|
|
18072
|
+
}, {
|
|
18073
|
+
wsl: "/mnt/c/Program Files/Mozilla Firefox/firefox.exe"
|
|
18074
|
+
}));
|
|
18075
|
+
defineLazyProperty(apps, "edge", () => detectPlatformBinary({
|
|
18076
|
+
darwin: "microsoft edge",
|
|
18077
|
+
win32: "msedge",
|
|
18078
|
+
linux: ["microsoft-edge", "microsoft-edge-dev"]
|
|
18079
|
+
}, {
|
|
18080
|
+
wsl: "/mnt/c/Program Files (x86)/Microsoft/Edge/Application/msedge.exe"
|
|
18081
|
+
}));
|
|
18082
|
+
defineLazyProperty(apps, "browser", () => "browser");
|
|
18083
|
+
defineLazyProperty(apps, "browserPrivate", () => "browserPrivate");
|
|
18084
|
+
var open_default = open;
|
|
18085
|
+
|
|
18086
|
+
// src/lib/tldraw-open.ts
|
|
18087
|
+
var tldrawOpenDefaultOptions = {
|
|
18088
|
+
location: "remote"
|
|
18089
|
+
};
|
|
18090
|
+
async function tldrawOpen(tldrPathOrUrl, options) {
|
|
18091
|
+
const tldrawRemoteUrl = "https://www.tldraw.com";
|
|
18092
|
+
const { location } = { ...tldrawOpenDefaultOptions, ...options };
|
|
18093
|
+
let urlToOpen;
|
|
18094
|
+
const validatedPathOrUrl = tldrPathOrUrl === void 0 ? void 0 : validatePathOrUrl(tldrPathOrUrl, {
|
|
18095
|
+
requireFileExistence: true,
|
|
18096
|
+
validFileExtensions: [".tldr"],
|
|
18097
|
+
validHostnames: ["www.tldraw.com"]
|
|
18098
|
+
});
|
|
18099
|
+
if (location === "local" && validatedPathOrUrl === void 0) {
|
|
18100
|
+
const tldrawServer = new LocalTldrawServer();
|
|
18101
|
+
await tldrawServer.start();
|
|
18102
|
+
urlToOpen = tldrawServer.href;
|
|
18103
|
+
log_default.info(`Opened blank tldraw sketch locally at "${urlToOpen}"`);
|
|
18104
|
+
} else if (location === "local" && typeof validatedPathOrUrl === "string") {
|
|
18105
|
+
const tldrData = await fs8.readFile(validatedPathOrUrl, "utf8");
|
|
18106
|
+
const tldrawServer = new LocalTldrawServer(tldrData);
|
|
18107
|
+
await tldrawServer.start();
|
|
18108
|
+
urlToOpen = tldrawServer.href;
|
|
18109
|
+
log_default.info(`Opened copy of tldraw sketch "${validatedPathOrUrl}" locally at "${urlToOpen}"`);
|
|
18110
|
+
} else if (location === "local" && validatedPathOrUrl instanceof URL2) {
|
|
18111
|
+
const [savedFile] = await tldrawToImage(validatedPathOrUrl.href, {
|
|
18112
|
+
format: "tldr",
|
|
18113
|
+
name: nanoid(),
|
|
18114
|
+
output: os5.tmpdir()
|
|
18115
|
+
});
|
|
18116
|
+
const tldrData = await fs8.readFile(savedFile, "utf8");
|
|
18117
|
+
await fs8.rm(savedFile, { force: true });
|
|
18118
|
+
const tldrawServer = new LocalTldrawServer(tldrData);
|
|
18119
|
+
await tldrawServer.start();
|
|
18120
|
+
urlToOpen = tldrawServer.href;
|
|
18121
|
+
log_default.info(
|
|
18122
|
+
`Opened a local copy of tldraw sketch url "${validatedPathOrUrl.href}" locally at ${urlToOpen}`
|
|
18123
|
+
);
|
|
18124
|
+
} else if (location === "remote" && validatedPathOrUrl === void 0) {
|
|
18125
|
+
urlToOpen = tldrawRemoteUrl;
|
|
18126
|
+
log_default.info(`Opened tldraw.com`);
|
|
18127
|
+
} else if (location === "remote" && typeof validatedPathOrUrl === "string") {
|
|
18128
|
+
urlToOpen = await tldrawToShareUrl(validatedPathOrUrl);
|
|
18129
|
+
log_default.info(
|
|
18130
|
+
`Opened copy of local tldraw sketch "${validatedPathOrUrl}" remotely at "${urlToOpen}"`
|
|
18131
|
+
);
|
|
18132
|
+
} else if (location === "remote" && validatedPathOrUrl instanceof URL2) {
|
|
18133
|
+
urlToOpen = validatedPathOrUrl.href;
|
|
18134
|
+
log_default.info(`Opened tldraw sketch url at ${urlToOpen}`);
|
|
18135
|
+
} else {
|
|
18136
|
+
throw new Error("Invalid tldrawOpen options");
|
|
18137
|
+
}
|
|
18138
|
+
const exitPromise = open_default(urlToOpen, {
|
|
18139
|
+
wait: true
|
|
18140
|
+
});
|
|
18141
|
+
return {
|
|
18142
|
+
browserExitPromise: exitPromise,
|
|
18143
|
+
openedSketchUrl: urlToOpen
|
|
18144
|
+
};
|
|
18145
|
+
}
|
|
17589
18146
|
export {
|
|
17590
18147
|
log_default as log,
|
|
17591
|
-
|
|
18148
|
+
tldrawOpen,
|
|
18149
|
+
tldrawToImage,
|
|
18150
|
+
tldrawToShareUrl
|
|
17592
18151
|
};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
import { type ChildProcess } from 'node:child_process';
|
|
3
|
+
export type TldrawOpenOptions = {
|
|
4
|
+
location: 'local' | 'remote';
|
|
5
|
+
};
|
|
6
|
+
export type TldrawOpenResult = {
|
|
7
|
+
browserExitPromise: Promise<ChildProcess>;
|
|
8
|
+
openedSketchUrl: string;
|
|
9
|
+
};
|
|
10
|
+
export declare function tldrawOpen(tldrPathOrUrl?: string, options?: Partial<TldrawOpenOptions>): Promise<TldrawOpenResult>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function tldrawToShareUrl(tldrPathOrUrl: string): Promise<string>;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kitschpatrol/tldraw-cli",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.6.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "A CLI tool for exporting tldraw sketch URLs and local .tldr files to SVG or PNG images.",
|
|
6
6
|
"repository": {
|
|
@@ -100,8 +100,8 @@
|
|
|
100
100
|
"preview": "pnpm run preview:tldraw",
|
|
101
101
|
"preview:tldraw": "vite preview",
|
|
102
102
|
"release": "pnpm bumpp --commit 'Release: %s' && pnpm build && pnpm publish --otp $(op read 'op://Personal/Npmjs/one-time password?attribute=otp')",
|
|
103
|
-
"test": "
|
|
104
|
-
"test:
|
|
103
|
+
"test": "vitest --run",
|
|
104
|
+
"test:watch": "pnpm run build && vitest",
|
|
105
105
|
"tldraw:copy-assets": "rsync -av --include='/*/' --exclude='/*' --exclude='favicon.ico' ./node_modules/@tldraw/assets/ ./src/tldraw/public/"
|
|
106
106
|
}
|
|
107
107
|
}
|
package/readme.md
CHANGED
|
@@ -88,10 +88,10 @@ Usage:
|
|
|
88
88
|
tldraw <command>
|
|
89
89
|
```
|
|
90
90
|
|
|
91
|
-
| Command | Argument | Description
|
|
92
|
-
| -------- | ------------------- |
|
|
93
|
-
| `export` | `<files-or-urls..>` | Export a local tldraw ".tldr" file or a tldraw\.com URL to an svg, png, json, or tldr file. Prints the absolute path(s) to the exported image(s) to stdout.
|
|
94
|
-
| `open` | `[files-or-urls..]` | Open a tldraw `.tldr` file or tldraw\.com URL in your default browser with either the official tldraw\.com site or a locally-hosted instance of the editor. Call `open` without an argument to open a blank sketch. Sketches opened via URL with the `--local` flag will be temporarily copied to the local system, and will not be kept in sync with tldraw\.com. This process does not exit until the browser is closed. |
|
|
91
|
+
| Command | Argument | Description |
|
|
92
|
+
| -------- | ------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
93
|
+
| `export` | `<files-or-urls..>` | Export a local tldraw ".tldr" file or a tldraw\.com URL to an svg, png, json, or tldr file. Prints the absolute path(s) to the exported image(s) to stdout. |
|
|
94
|
+
| `open` | `[files-or-urls..]` | Open a tldraw `.tldr` file or tldraw\.com URL in your default browser with either the official tldraw\.com site or a locally-hosted instance of the editor. Call `open` without an argument to open a blank sketch. Sketches opened via URL with the `--local` flag will be temporarily copied to the local system, and will not be kept in sync with tldraw\.com. This process does not exit until the browser is closed. Warning: Passing a local .tldr file without the `--local` option will upload and share the sketch on tldraw\.com. |
|
|
95
95
|
|
|
96
96
|
| Option | Alias | Description | Type |
|
|
97
97
|
| ----------- | ----- | ------------------- | --------- |
|
|
@@ -133,7 +133,7 @@ tldraw export <files-or-urls..>
|
|
|
133
133
|
|
|
134
134
|
#### Subcommand: `tldraw open`
|
|
135
135
|
|
|
136
|
-
Open a tldraw `.tldr` file or tldraw\.com URL in your default browser with either the official tldraw\.com site or a locally-hosted instance of the editor. Call `open` without an argument to open a blank sketch. Sketches opened via URL with the `--local` flag will be temporarily copied to the local system, and will not be kept in sync with tldraw\.com. This process does not exit until the browser is closed.
|
|
136
|
+
Open a tldraw `.tldr` file or tldraw\.com URL in your default browser with either the official tldraw\.com site or a locally-hosted instance of the editor. Call `open` without an argument to open a blank sketch. Sketches opened via URL with the `--local` flag will be temporarily copied to the local system, and will not be kept in sync with tldraw\.com. This process does not exit until the browser is closed. Warning: Passing a local .tldr file without the `--local` option will upload and share the sketch on tldraw\.com.
|
|
137
137
|
|
|
138
138
|
Usage:
|
|
139
139
|
|
|
@@ -290,9 +290,15 @@ The remote sketch is copied to a locally-hosted instance of tldraw, which is the
|
|
|
290
290
|
|
|
291
291
|
### API
|
|
292
292
|
|
|
293
|
-
The `
|
|
293
|
+
The `tldraw-cli` command line functionality is also provided in module form for programmatic use in TypeScript or JavaScript Node projects.
|
|
294
294
|
|
|
295
|
-
The library exports
|
|
295
|
+
The library exports two async function, `tldrawToImage`, and `tldrawOpen`.
|
|
296
|
+
|
|
297
|
+
#### `tldrawToImage`
|
|
298
|
+
|
|
299
|
+
This mirrors the `tldraw export` CLI command.
|
|
300
|
+
|
|
301
|
+
It takes an options argument mirroring the arguments available via the command line. The same default values apply:
|
|
296
302
|
|
|
297
303
|
```ts
|
|
298
304
|
async function tldrawToImage(
|
|
@@ -367,7 +373,63 @@ log.verbose = false
|
|
|
367
373
|
await tldrawToImage('https://www.tldraw.com/s/v2_c_JsxJk8dag6QsrqExukis4')
|
|
368
374
|
```
|
|
369
375
|
|
|
370
|
-
|
|
376
|
+
#### `tldrawOpen`
|
|
377
|
+
|
|
378
|
+
Mirrors the `tldraw open` CLI command.
|
|
379
|
+
|
|
380
|
+
> \[!CAUTION]
|
|
381
|
+
> Passing a local .tldr file with the `location: 'remote'` option will upload and share your sketch on tldraw\.com.
|
|
382
|
+
|
|
383
|
+
```tsx
|
|
384
|
+
async function tldrawOpen(
|
|
385
|
+
tldrPathOrUrl?: string,
|
|
386
|
+
options?: Partial<{
|
|
387
|
+
location: 'local' | 'remote'
|
|
388
|
+
}>,
|
|
389
|
+
): Promise<{
|
|
390
|
+
browserExitPromise: Promise<ChildProcess>
|
|
391
|
+
openedSketchUrl: string
|
|
392
|
+
}>
|
|
393
|
+
```
|
|
394
|
+
|
|
395
|
+
It's important to note that the returned result includes `browserExitPromise`, which resolves when the user has completely exited the web browser used to open the tldr file or url.
|
|
396
|
+
|
|
397
|
+
You _must_ await the `browserExitPromise` (or somehow keep script's process alive) if you're opening a tldr file with the \`location: 'local'\`. This prevents the local server from closing prematurely, which would interfere with any server-dependent actions in tldraw.
|
|
398
|
+
|
|
399
|
+
Example of opening a local file:
|
|
400
|
+
|
|
401
|
+
```ts
|
|
402
|
+
import { tldrawOpen } from 'tldraw-cli'
|
|
403
|
+
|
|
404
|
+
const { browserExitPromise } = await tldrawOpen('./sketch.tldr', {
|
|
405
|
+
location: 'local',
|
|
406
|
+
})
|
|
407
|
+
|
|
408
|
+
// Wait for the browser to close to keep
|
|
409
|
+
// the local tldraw instance running!
|
|
410
|
+
await browserExitPromise
|
|
411
|
+
```
|
|
412
|
+
|
|
413
|
+
While opening the file remotely on tldraw\.com is more casual:
|
|
414
|
+
|
|
415
|
+
```ts
|
|
416
|
+
import { tldrawOpen } from 'tldraw-cli'
|
|
417
|
+
|
|
418
|
+
await tldrawOpen('./sketch.tldr', {
|
|
419
|
+
location: 'remote',
|
|
420
|
+
})
|
|
421
|
+
```
|
|
422
|
+
|
|
423
|
+
#### `tldrawToShareUrl`
|
|
424
|
+
|
|
425
|
+
```ts
|
|
426
|
+
async function tldrawToShareUrl(tldrPathOrUrl: string): Promise<string>
|
|
427
|
+
```
|
|
428
|
+
|
|
429
|
+
Returns a live "share" url for a given local or remote tldraw sketch URL.
|
|
430
|
+
|
|
431
|
+
> \[!CAUTION]
|
|
432
|
+
> Passing a local .tldr file to this function will upload and share your local file to tldraw\.com.
|
|
371
433
|
|
|
372
434
|
## Background
|
|
373
435
|
|