@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/dist/lib/index.js CHANGED
@@ -601,12 +601,523 @@ var require_boolbase = __commonJS({
601
601
  }
602
602
  });
603
603
 
604
+ // node_modules/.pnpm/chalk@5.3.0/node_modules/chalk/source/vendor/ansi-styles/index.js
605
+ var ANSI_BACKGROUND_OFFSET = 10;
606
+ var wrapAnsi16 = (offset = 0) => (code) => `\x1B[${code + offset}m`;
607
+ var wrapAnsi256 = (offset = 0) => (code) => `\x1B[${38 + offset};5;${code}m`;
608
+ var wrapAnsi16m = (offset = 0) => (red, green, blue) => `\x1B[${38 + offset};2;${red};${green};${blue}m`;
609
+ var styles = {
610
+ modifier: {
611
+ reset: [0, 0],
612
+ // 21 isn't widely supported and 22 does the same thing
613
+ bold: [1, 22],
614
+ dim: [2, 22],
615
+ italic: [3, 23],
616
+ underline: [4, 24],
617
+ overline: [53, 55],
618
+ inverse: [7, 27],
619
+ hidden: [8, 28],
620
+ strikethrough: [9, 29]
621
+ },
622
+ color: {
623
+ black: [30, 39],
624
+ red: [31, 39],
625
+ green: [32, 39],
626
+ yellow: [33, 39],
627
+ blue: [34, 39],
628
+ magenta: [35, 39],
629
+ cyan: [36, 39],
630
+ white: [37, 39],
631
+ // Bright color
632
+ blackBright: [90, 39],
633
+ gray: [90, 39],
634
+ // Alias of `blackBright`
635
+ grey: [90, 39],
636
+ // Alias of `blackBright`
637
+ redBright: [91, 39],
638
+ greenBright: [92, 39],
639
+ yellowBright: [93, 39],
640
+ blueBright: [94, 39],
641
+ magentaBright: [95, 39],
642
+ cyanBright: [96, 39],
643
+ whiteBright: [97, 39]
644
+ },
645
+ bgColor: {
646
+ bgBlack: [40, 49],
647
+ bgRed: [41, 49],
648
+ bgGreen: [42, 49],
649
+ bgYellow: [43, 49],
650
+ bgBlue: [44, 49],
651
+ bgMagenta: [45, 49],
652
+ bgCyan: [46, 49],
653
+ bgWhite: [47, 49],
654
+ // Bright color
655
+ bgBlackBright: [100, 49],
656
+ bgGray: [100, 49],
657
+ // Alias of `bgBlackBright`
658
+ bgGrey: [100, 49],
659
+ // Alias of `bgBlackBright`
660
+ bgRedBright: [101, 49],
661
+ bgGreenBright: [102, 49],
662
+ bgYellowBright: [103, 49],
663
+ bgBlueBright: [104, 49],
664
+ bgMagentaBright: [105, 49],
665
+ bgCyanBright: [106, 49],
666
+ bgWhiteBright: [107, 49]
667
+ }
668
+ };
669
+ var modifierNames = Object.keys(styles.modifier);
670
+ var foregroundColorNames = Object.keys(styles.color);
671
+ var backgroundColorNames = Object.keys(styles.bgColor);
672
+ var colorNames = [...foregroundColorNames, ...backgroundColorNames];
673
+ function assembleStyles() {
674
+ const codes = /* @__PURE__ */ new Map();
675
+ for (const [groupName, group] of Object.entries(styles)) {
676
+ for (const [styleName, style] of Object.entries(group)) {
677
+ styles[styleName] = {
678
+ open: `\x1B[${style[0]}m`,
679
+ close: `\x1B[${style[1]}m`
680
+ };
681
+ group[styleName] = styles[styleName];
682
+ codes.set(style[0], style[1]);
683
+ }
684
+ Object.defineProperty(styles, groupName, {
685
+ value: group,
686
+ enumerable: false
687
+ });
688
+ }
689
+ Object.defineProperty(styles, "codes", {
690
+ value: codes,
691
+ enumerable: false
692
+ });
693
+ styles.color.close = "\x1B[39m";
694
+ styles.bgColor.close = "\x1B[49m";
695
+ styles.color.ansi = wrapAnsi16();
696
+ styles.color.ansi256 = wrapAnsi256();
697
+ styles.color.ansi16m = wrapAnsi16m();
698
+ styles.bgColor.ansi = wrapAnsi16(ANSI_BACKGROUND_OFFSET);
699
+ styles.bgColor.ansi256 = wrapAnsi256(ANSI_BACKGROUND_OFFSET);
700
+ styles.bgColor.ansi16m = wrapAnsi16m(ANSI_BACKGROUND_OFFSET);
701
+ Object.defineProperties(styles, {
702
+ rgbToAnsi256: {
703
+ value(red, green, blue) {
704
+ if (red === green && green === blue) {
705
+ if (red < 8) {
706
+ return 16;
707
+ }
708
+ if (red > 248) {
709
+ return 231;
710
+ }
711
+ return Math.round((red - 8) / 247 * 24) + 232;
712
+ }
713
+ return 16 + 36 * Math.round(red / 255 * 5) + 6 * Math.round(green / 255 * 5) + Math.round(blue / 255 * 5);
714
+ },
715
+ enumerable: false
716
+ },
717
+ hexToRgb: {
718
+ value(hex) {
719
+ const matches = /[a-f\d]{6}|[a-f\d]{3}/i.exec(hex.toString(16));
720
+ if (!matches) {
721
+ return [0, 0, 0];
722
+ }
723
+ let [colorString] = matches;
724
+ if (colorString.length === 3) {
725
+ colorString = [...colorString].map((character) => character + character).join("");
726
+ }
727
+ const integer = Number.parseInt(colorString, 16);
728
+ return [
729
+ /* eslint-disable no-bitwise */
730
+ integer >> 16 & 255,
731
+ integer >> 8 & 255,
732
+ integer & 255
733
+ /* eslint-enable no-bitwise */
734
+ ];
735
+ },
736
+ enumerable: false
737
+ },
738
+ hexToAnsi256: {
739
+ value: (hex) => styles.rgbToAnsi256(...styles.hexToRgb(hex)),
740
+ enumerable: false
741
+ },
742
+ ansi256ToAnsi: {
743
+ value(code) {
744
+ if (code < 8) {
745
+ return 30 + code;
746
+ }
747
+ if (code < 16) {
748
+ return 90 + (code - 8);
749
+ }
750
+ let red;
751
+ let green;
752
+ let blue;
753
+ if (code >= 232) {
754
+ red = ((code - 232) * 10 + 8) / 255;
755
+ green = red;
756
+ blue = red;
757
+ } else {
758
+ code -= 16;
759
+ const remainder = code % 36;
760
+ red = Math.floor(code / 36) / 5;
761
+ green = Math.floor(remainder / 6) / 5;
762
+ blue = remainder % 6 / 5;
763
+ }
764
+ const value = Math.max(red, green, blue) * 2;
765
+ if (value === 0) {
766
+ return 30;
767
+ }
768
+ let result = 30 + (Math.round(blue) << 2 | Math.round(green) << 1 | Math.round(red));
769
+ if (value === 2) {
770
+ result += 60;
771
+ }
772
+ return result;
773
+ },
774
+ enumerable: false
775
+ },
776
+ rgbToAnsi: {
777
+ value: (red, green, blue) => styles.ansi256ToAnsi(styles.rgbToAnsi256(red, green, blue)),
778
+ enumerable: false
779
+ },
780
+ hexToAnsi: {
781
+ value: (hex) => styles.ansi256ToAnsi(styles.hexToAnsi256(hex)),
782
+ enumerable: false
783
+ }
784
+ });
785
+ return styles;
786
+ }
787
+ var ansiStyles = assembleStyles();
788
+ var ansi_styles_default = ansiStyles;
789
+
790
+ // node_modules/.pnpm/chalk@5.3.0/node_modules/chalk/source/vendor/supports-color/index.js
791
+ import process from "node:process";
792
+ import os from "node:os";
793
+ import tty from "node:tty";
794
+ function hasFlag(flag, argv = globalThis.Deno ? globalThis.Deno.args : process.argv) {
795
+ const prefix = flag.startsWith("-") ? "" : flag.length === 1 ? "-" : "--";
796
+ const position = argv.indexOf(prefix + flag);
797
+ const terminatorPosition = argv.indexOf("--");
798
+ return position !== -1 && (terminatorPosition === -1 || position < terminatorPosition);
799
+ }
800
+ var { env } = process;
801
+ var flagForceColor;
802
+ if (hasFlag("no-color") || hasFlag("no-colors") || hasFlag("color=false") || hasFlag("color=never")) {
803
+ flagForceColor = 0;
804
+ } else if (hasFlag("color") || hasFlag("colors") || hasFlag("color=true") || hasFlag("color=always")) {
805
+ flagForceColor = 1;
806
+ }
807
+ function envForceColor() {
808
+ if ("FORCE_COLOR" in env) {
809
+ if (env.FORCE_COLOR === "true") {
810
+ return 1;
811
+ }
812
+ if (env.FORCE_COLOR === "false") {
813
+ return 0;
814
+ }
815
+ return env.FORCE_COLOR.length === 0 ? 1 : Math.min(Number.parseInt(env.FORCE_COLOR, 10), 3);
816
+ }
817
+ }
818
+ function translateLevel(level) {
819
+ if (level === 0) {
820
+ return false;
821
+ }
822
+ return {
823
+ level,
824
+ hasBasic: true,
825
+ has256: level >= 2,
826
+ has16m: level >= 3
827
+ };
828
+ }
829
+ function _supportsColor(haveStream, { streamIsTTY, sniffFlags = true } = {}) {
830
+ const noFlagForceColor = envForceColor();
831
+ if (noFlagForceColor !== void 0) {
832
+ flagForceColor = noFlagForceColor;
833
+ }
834
+ const forceColor = sniffFlags ? flagForceColor : noFlagForceColor;
835
+ if (forceColor === 0) {
836
+ return 0;
837
+ }
838
+ if (sniffFlags) {
839
+ if (hasFlag("color=16m") || hasFlag("color=full") || hasFlag("color=truecolor")) {
840
+ return 3;
841
+ }
842
+ if (hasFlag("color=256")) {
843
+ return 2;
844
+ }
845
+ }
846
+ if ("TF_BUILD" in env && "AGENT_NAME" in env) {
847
+ return 1;
848
+ }
849
+ if (haveStream && !streamIsTTY && forceColor === void 0) {
850
+ return 0;
851
+ }
852
+ const min = forceColor || 0;
853
+ if (env.TERM === "dumb") {
854
+ return min;
855
+ }
856
+ if (process.platform === "win32") {
857
+ const osRelease = os.release().split(".");
858
+ if (Number(osRelease[0]) >= 10 && Number(osRelease[2]) >= 10586) {
859
+ return Number(osRelease[2]) >= 14931 ? 3 : 2;
860
+ }
861
+ return 1;
862
+ }
863
+ if ("CI" in env) {
864
+ if ("GITHUB_ACTIONS" in env || "GITEA_ACTIONS" in env) {
865
+ return 3;
866
+ }
867
+ if (["TRAVIS", "CIRCLECI", "APPVEYOR", "GITLAB_CI", "BUILDKITE", "DRONE"].some((sign) => sign in env) || env.CI_NAME === "codeship") {
868
+ return 1;
869
+ }
870
+ return min;
871
+ }
872
+ if ("TEAMCITY_VERSION" in env) {
873
+ return /^(9\.(0*[1-9]\d*)\.|\d{2,}\.)/.test(env.TEAMCITY_VERSION) ? 1 : 0;
874
+ }
875
+ if (env.COLORTERM === "truecolor") {
876
+ return 3;
877
+ }
878
+ if (env.TERM === "xterm-kitty") {
879
+ return 3;
880
+ }
881
+ if ("TERM_PROGRAM" in env) {
882
+ const version = Number.parseInt((env.TERM_PROGRAM_VERSION || "").split(".")[0], 10);
883
+ switch (env.TERM_PROGRAM) {
884
+ case "iTerm.app": {
885
+ return version >= 3 ? 3 : 2;
886
+ }
887
+ case "Apple_Terminal": {
888
+ return 2;
889
+ }
890
+ }
891
+ }
892
+ if (/-256(color)?$/i.test(env.TERM)) {
893
+ return 2;
894
+ }
895
+ if (/^screen|^xterm|^vt100|^vt220|^rxvt|color|ansi|cygwin|linux/i.test(env.TERM)) {
896
+ return 1;
897
+ }
898
+ if ("COLORTERM" in env) {
899
+ return 1;
900
+ }
901
+ return min;
902
+ }
903
+ function createSupportsColor(stream, options = {}) {
904
+ const level = _supportsColor(stream, {
905
+ streamIsTTY: stream && stream.isTTY,
906
+ ...options
907
+ });
908
+ return translateLevel(level);
909
+ }
910
+ var supportsColor = {
911
+ stdout: createSupportsColor({ isTTY: tty.isatty(1) }),
912
+ stderr: createSupportsColor({ isTTY: tty.isatty(2) })
913
+ };
914
+ var supports_color_default = supportsColor;
915
+
916
+ // node_modules/.pnpm/chalk@5.3.0/node_modules/chalk/source/utilities.js
917
+ function stringReplaceAll(string, substring, replacer) {
918
+ let index2 = string.indexOf(substring);
919
+ if (index2 === -1) {
920
+ return string;
921
+ }
922
+ const substringLength = substring.length;
923
+ let endIndex = 0;
924
+ let returnValue = "";
925
+ do {
926
+ returnValue += string.slice(endIndex, index2) + substring + replacer;
927
+ endIndex = index2 + substringLength;
928
+ index2 = string.indexOf(substring, endIndex);
929
+ } while (index2 !== -1);
930
+ returnValue += string.slice(endIndex);
931
+ return returnValue;
932
+ }
933
+ function stringEncaseCRLFWithFirstIndex(string, prefix, postfix, index2) {
934
+ let endIndex = 0;
935
+ let returnValue = "";
936
+ do {
937
+ const gotCR = string[index2 - 1] === "\r";
938
+ returnValue += string.slice(endIndex, gotCR ? index2 - 1 : index2) + prefix + (gotCR ? "\r\n" : "\n") + postfix;
939
+ endIndex = index2 + 1;
940
+ index2 = string.indexOf("\n", endIndex);
941
+ } while (index2 !== -1);
942
+ returnValue += string.slice(endIndex);
943
+ return returnValue;
944
+ }
945
+
946
+ // node_modules/.pnpm/chalk@5.3.0/node_modules/chalk/source/index.js
947
+ var { stdout: stdoutColor, stderr: stderrColor } = supports_color_default;
948
+ var GENERATOR = Symbol("GENERATOR");
949
+ var STYLER = Symbol("STYLER");
950
+ var IS_EMPTY = Symbol("IS_EMPTY");
951
+ var levelMapping = [
952
+ "ansi",
953
+ "ansi",
954
+ "ansi256",
955
+ "ansi16m"
956
+ ];
957
+ var styles2 = /* @__PURE__ */ Object.create(null);
958
+ var applyOptions = (object, options = {}) => {
959
+ if (options.level && !(Number.isInteger(options.level) && options.level >= 0 && options.level <= 3)) {
960
+ throw new Error("The `level` option should be an integer from 0 to 3");
961
+ }
962
+ const colorLevel = stdoutColor ? stdoutColor.level : 0;
963
+ object.level = options.level === void 0 ? colorLevel : options.level;
964
+ };
965
+ var chalkFactory = (options) => {
966
+ const chalk2 = (...strings) => strings.join(" ");
967
+ applyOptions(chalk2, options);
968
+ Object.setPrototypeOf(chalk2, createChalk.prototype);
969
+ return chalk2;
970
+ };
971
+ function createChalk(options) {
972
+ return chalkFactory(options);
973
+ }
974
+ Object.setPrototypeOf(createChalk.prototype, Function.prototype);
975
+ for (const [styleName, style] of Object.entries(ansi_styles_default)) {
976
+ styles2[styleName] = {
977
+ get() {
978
+ const builder = createBuilder(this, createStyler(style.open, style.close, this[STYLER]), this[IS_EMPTY]);
979
+ Object.defineProperty(this, styleName, { value: builder });
980
+ return builder;
981
+ }
982
+ };
983
+ }
984
+ styles2.visible = {
985
+ get() {
986
+ const builder = createBuilder(this, this[STYLER], true);
987
+ Object.defineProperty(this, "visible", { value: builder });
988
+ return builder;
989
+ }
990
+ };
991
+ var getModelAnsi = (model, level, type, ...arguments_) => {
992
+ if (model === "rgb") {
993
+ if (level === "ansi16m") {
994
+ return ansi_styles_default[type].ansi16m(...arguments_);
995
+ }
996
+ if (level === "ansi256") {
997
+ return ansi_styles_default[type].ansi256(ansi_styles_default.rgbToAnsi256(...arguments_));
998
+ }
999
+ return ansi_styles_default[type].ansi(ansi_styles_default.rgbToAnsi(...arguments_));
1000
+ }
1001
+ if (model === "hex") {
1002
+ return getModelAnsi("rgb", level, type, ...ansi_styles_default.hexToRgb(...arguments_));
1003
+ }
1004
+ return ansi_styles_default[type][model](...arguments_);
1005
+ };
1006
+ var usedModels = ["rgb", "hex", "ansi256"];
1007
+ for (const model of usedModels) {
1008
+ styles2[model] = {
1009
+ get() {
1010
+ const { level } = this;
1011
+ return function(...arguments_) {
1012
+ const styler = createStyler(getModelAnsi(model, levelMapping[level], "color", ...arguments_), ansi_styles_default.color.close, this[STYLER]);
1013
+ return createBuilder(this, styler, this[IS_EMPTY]);
1014
+ };
1015
+ }
1016
+ };
1017
+ const bgModel = "bg" + model[0].toUpperCase() + model.slice(1);
1018
+ styles2[bgModel] = {
1019
+ get() {
1020
+ const { level } = this;
1021
+ return function(...arguments_) {
1022
+ const styler = createStyler(getModelAnsi(model, levelMapping[level], "bgColor", ...arguments_), ansi_styles_default.bgColor.close, this[STYLER]);
1023
+ return createBuilder(this, styler, this[IS_EMPTY]);
1024
+ };
1025
+ }
1026
+ };
1027
+ }
1028
+ var proto = Object.defineProperties(() => {
1029
+ }, {
1030
+ ...styles2,
1031
+ level: {
1032
+ enumerable: true,
1033
+ get() {
1034
+ return this[GENERATOR].level;
1035
+ },
1036
+ set(level) {
1037
+ this[GENERATOR].level = level;
1038
+ }
1039
+ }
1040
+ });
1041
+ var createStyler = (open, close, parent2) => {
1042
+ let openAll;
1043
+ let closeAll;
1044
+ if (parent2 === void 0) {
1045
+ openAll = open;
1046
+ closeAll = close;
1047
+ } else {
1048
+ openAll = parent2.openAll + open;
1049
+ closeAll = close + parent2.closeAll;
1050
+ }
1051
+ return {
1052
+ open,
1053
+ close,
1054
+ openAll,
1055
+ closeAll,
1056
+ parent: parent2
1057
+ };
1058
+ };
1059
+ var createBuilder = (self, _styler, _isEmpty) => {
1060
+ const builder = (...arguments_) => applyStyle(builder, arguments_.length === 1 ? "" + arguments_[0] : arguments_.join(" "));
1061
+ Object.setPrototypeOf(builder, proto);
1062
+ builder[GENERATOR] = self;
1063
+ builder[STYLER] = _styler;
1064
+ builder[IS_EMPTY] = _isEmpty;
1065
+ return builder;
1066
+ };
1067
+ var applyStyle = (self, string) => {
1068
+ if (self.level <= 0 || !string) {
1069
+ return self[IS_EMPTY] ? "" : string;
1070
+ }
1071
+ let styler = self[STYLER];
1072
+ if (styler === void 0) {
1073
+ return string;
1074
+ }
1075
+ const { openAll, closeAll } = styler;
1076
+ if (string.includes("\x1B")) {
1077
+ while (styler !== void 0) {
1078
+ string = stringReplaceAll(string, styler.close, styler.open);
1079
+ styler = styler.parent;
1080
+ }
1081
+ }
1082
+ const lfIndex = string.indexOf("\n");
1083
+ if (lfIndex !== -1) {
1084
+ string = stringEncaseCRLFWithFirstIndex(string, closeAll, openAll, lfIndex);
1085
+ }
1086
+ return openAll + string + closeAll;
1087
+ };
1088
+ Object.defineProperties(createChalk.prototype, styles2);
1089
+ var chalk = createChalk();
1090
+ var chalkStderr = createChalk({ level: stderrColor ? stderrColor.level : 0 });
1091
+ var source_default = chalk;
1092
+
1093
+ // src/lib/utilities/logger.ts
1094
+ var cli = false;
1095
+ var verbose = false;
1096
+ function setVerbose(value) {
1097
+ verbose = value;
1098
+ }
1099
+ function warn(...data2) {
1100
+ console.warn(source_default.yellow("[Warning]"), ...data2);
1101
+ }
1102
+ function error(...data2) {
1103
+ console.error(source_default.red("[Error]"), ...data2);
1104
+ }
1105
+ function info(...data2) {
1106
+ if (!verbose)
1107
+ return;
1108
+ if (cli) {
1109
+ console.warn(source_default.green("[Info]"), ...data2);
1110
+ } else {
1111
+ console.log(...data2);
1112
+ }
1113
+ }
1114
+
604
1115
  // src/lib/local-tldraw-server.ts
605
1116
  import express from "express";
606
1117
 
607
1118
  // node_modules/.pnpm/get-port@7.0.0/node_modules/get-port/index.js
608
1119
  import net from "node:net";
609
- import os from "node:os";
1120
+ import os2 from "node:os";
610
1121
  var Locked = class extends Error {
611
1122
  constructor(port) {
612
1123
  super(`${port} is locked`);
@@ -619,7 +1130,7 @@ var lockedPorts = {
619
1130
  var releaseOldLockedPortsIntervalMs = 1e3 * 15;
620
1131
  var timeout;
621
1132
  var getLocalHosts = () => {
622
- const interfaces = os.networkInterfaces();
1133
+ const interfaces = os2.networkInterfaces();
623
1134
  const results = /* @__PURE__ */ new Set([void 0, "0.0.0.0"]);
624
1135
  for (const _interface of Object.values(interfaces)) {
625
1136
  for (const config of _interface) {
@@ -646,9 +1157,9 @@ var getAvailablePort = async (options, hosts) => {
646
1157
  for (const host of hosts) {
647
1158
  try {
648
1159
  await checkAvailablePort({ port: options.port, host });
649
- } catch (error) {
650
- if (!["EADDRNOTAVAIL", "EINVAL"].includes(error.code)) {
651
- throw error;
1160
+ } catch (error2) {
1161
+ if (!["EADDRNOTAVAIL", "EINVAL"].includes(error2.code)) {
1162
+ throw error2;
652
1163
  }
653
1164
  }
654
1165
  }
@@ -708,9 +1219,9 @@ async function getPorts(options) {
708
1219
  }
709
1220
  lockedPorts.young.add(availablePort);
710
1221
  return availablePort;
711
- } catch (error) {
712
- if (!["EADDRINUSE", "EACCES"].includes(error.code) && !(error instanceof Locked)) {
713
- throw error;
1222
+ } catch (error2) {
1223
+ if (!["EADDRINUSE", "EACCES"].includes(error2.code) && !(error2 instanceof Locked)) {
1224
+ throw error2;
714
1225
  }
715
1226
  }
716
1227
  }
@@ -721,31 +1232,25 @@ async function getPorts(options) {
721
1232
  import path, { dirname } from "node:path";
722
1233
  import { fileURLToPath } from "node:url";
723
1234
  var LocalTldrawServer = class {
724
- constructor(tldrData, verbose = false) {
1235
+ constructor(tldrData) {
725
1236
  this.tldrData = tldrData;
726
- this.verbose = verbose;
727
1237
  this.tldrData = tldrData;
728
1238
  }
729
- verbose;
730
- // eslint-disable-next-line perfectionist/sort-classes
731
1239
  server;
732
1240
  close() {
733
1241
  if (!this.server)
734
1242
  throw new Error("Server not started");
735
1243
  this.server.close();
736
- if (this.verbose)
737
- console.log("Stopped tldraw server");
1244
+ info("Stopped tldraw server");
738
1245
  }
739
1246
  async start() {
740
- if (this.verbose)
741
- console.log("Starting tldraw server...");
1247
+ info("Starting tldraw server...");
742
1248
  const scriptDirectory = dirname(fileURLToPath(import.meta.url));
743
1249
  const tldrawPath = path.join(
744
1250
  scriptDirectory,
745
1251
  scriptDirectory.endsWith("/src/lib") ? "../../dist/tldraw" : scriptDirectory.endsWith("/dist/lib") ? "../tldraw" : "../dist/tldraw"
746
1252
  );
747
- if (this.verbose)
748
- console.log(`tldraw served from "${tldrawPath}"`);
1253
+ info(`tldraw served from "${tldrawPath}"`);
749
1254
  const app = express();
750
1255
  const port = await getPorts();
751
1256
  app.get("/tldr-data", (_, response) => {
@@ -759,11 +1264,10 @@ var LocalTldrawServer = class {
759
1264
  app.use(express.static(tldrawPath));
760
1265
  try {
761
1266
  this.server = app.listen(port);
762
- } catch (error) {
763
- console.error(error);
1267
+ } catch (error2) {
1268
+ error(error2);
764
1269
  }
765
- if (this.verbose)
766
- console.log(`tldraw hosted at "${this.href}"`);
1270
+ info(`tldraw hosted at "${this.href}"`);
767
1271
  }
768
1272
  get href() {
769
1273
  if (!this.server)
@@ -3316,8 +3820,8 @@ var DomHandler = class {
3316
3820
  this.parser = null;
3317
3821
  this.handleCallback(null);
3318
3822
  }
3319
- onerror(error) {
3320
- this.handleCallback(error);
3823
+ onerror(error2) {
3824
+ this.handleCallback(error2);
3321
3825
  }
3322
3826
  onclosetag() {
3323
3827
  this.lastNode = null;
@@ -3373,11 +3877,11 @@ var DomHandler = class {
3373
3877
  const node = new ProcessingInstruction(name, data2);
3374
3878
  this.addNode(node);
3375
3879
  }
3376
- handleCallback(error) {
3880
+ handleCallback(error2) {
3377
3881
  if (typeof this.callback === "function") {
3378
- this.callback(error, this.dom);
3379
- } else if (error) {
3380
- throw error;
3882
+ this.callback(error2, this.dom);
3883
+ } else if (error2) {
3884
+ throw error2;
3381
3885
  }
3382
3886
  }
3383
3887
  addNode(node) {
@@ -7035,14 +7539,14 @@ function css(prop2, val2) {
7035
7539
  }
7036
7540
  function setCss(el, prop2, value, idx) {
7037
7541
  if (typeof prop2 === "string") {
7038
- const styles = getCss(el);
7039
- const val2 = typeof value === "function" ? value.call(el, idx, styles[prop2]) : value;
7542
+ const styles3 = getCss(el);
7543
+ const val2 = typeof value === "function" ? value.call(el, idx, styles3[prop2]) : value;
7040
7544
  if (val2 === "") {
7041
- delete styles[prop2];
7545
+ delete styles3[prop2];
7042
7546
  } else if (val2 != null) {
7043
- styles[prop2] = val2;
7547
+ styles3[prop2] = val2;
7044
7548
  }
7045
- el.attribs["style"] = stringify(styles);
7549
+ el.attribs["style"] = stringify(styles3);
7046
7550
  } else if (typeof prop2 === "object") {
7047
7551
  Object.keys(prop2).forEach((k, i) => {
7048
7552
  setCss(el, k, prop2[k], i);
@@ -7052,31 +7556,31 @@ function setCss(el, prop2, value, idx) {
7052
7556
  function getCss(el, prop2) {
7053
7557
  if (!el || !isTag2(el))
7054
7558
  return;
7055
- const styles = parse5(el.attribs["style"]);
7559
+ const styles3 = parse5(el.attribs["style"]);
7056
7560
  if (typeof prop2 === "string") {
7057
- return styles[prop2];
7561
+ return styles3[prop2];
7058
7562
  }
7059
7563
  if (Array.isArray(prop2)) {
7060
7564
  const newStyles = {};
7061
7565
  prop2.forEach((item) => {
7062
- if (styles[item] != null) {
7063
- newStyles[item] = styles[item];
7566
+ if (styles3[item] != null) {
7567
+ newStyles[item] = styles3[item];
7064
7568
  }
7065
7569
  });
7066
7570
  return newStyles;
7067
7571
  }
7068
- return styles;
7572
+ return styles3;
7069
7573
  }
7070
7574
  function stringify(obj) {
7071
7575
  return Object.keys(obj).reduce((str, prop2) => `${str}${str ? " " : ""}${prop2}: ${obj[prop2]};`, "");
7072
7576
  }
7073
- function parse5(styles) {
7074
- styles = (styles || "").trim();
7075
- if (!styles)
7577
+ function parse5(styles3) {
7578
+ styles3 = (styles3 || "").trim();
7579
+ if (!styles3)
7076
7580
  return {};
7077
7581
  const obj = {};
7078
7582
  let key;
7079
- for (const str of styles.split(";")) {
7583
+ for (const str of styles3.split(";")) {
7080
7584
  const n = str.indexOf(":");
7081
7585
  if (n < 1 || n === str.length - 1) {
7082
7586
  const trimmed = str.trimEnd();
@@ -16397,13 +16901,13 @@ var { root: root2 } = static_exports;
16397
16901
 
16398
16902
  // src/lib/tldraw-controller.ts
16399
16903
  import fs from "node:fs/promises";
16400
- import os3 from "node:os";
16904
+ import os4 from "node:os";
16401
16905
  import path2 from "node:path";
16402
16906
  import puppeteer from "puppeteer";
16403
16907
 
16404
16908
  // node_modules/.pnpm/untildify@5.0.0/node_modules/untildify/index.js
16405
- import os2 from "node:os";
16406
- var homeDirectory = os2.homedir();
16909
+ import os3 from "node:os";
16910
+ var homeDirectory = os3.homedir();
16407
16911
  function untildify(pathWithTilde) {
16408
16912
  if (typeof pathWithTilde !== "string") {
16409
16913
  throw new TypeError(`Expected a string, got ${typeof pathWithTilde}`);
@@ -16413,12 +16917,10 @@ function untildify(pathWithTilde) {
16413
16917
 
16414
16918
  // src/lib/tldraw-controller.ts
16415
16919
  var TldrawController = class {
16416
- constructor(href, verbose = false) {
16920
+ constructor(href) {
16417
16921
  this.href = href;
16418
- this.verbose = verbose;
16419
16922
  this.href = href;
16420
16923
  }
16421
- verbose;
16422
16924
  page;
16423
16925
  isEmpty;
16424
16926
  browser;
@@ -16428,8 +16930,7 @@ var TldrawController = class {
16428
16930
  return this.href.startsWith("http://localhost");
16429
16931
  }
16430
16932
  async start() {
16431
- if (this.verbose)
16432
- console.log("Starting Puppeteer...");
16933
+ info("Starting Puppeteer...");
16433
16934
  this.browser = await puppeteer.launch({
16434
16935
  args: this.isLocal ? ["--no-sandbox", "--disable-web-security"] : [],
16435
16936
  headless: "new"
@@ -16439,21 +16940,20 @@ var TldrawController = class {
16439
16940
  const messageType = message.type();
16440
16941
  const messageText = message.text();
16441
16942
  if (messageType === "error") {
16442
- console.error(`[Browser] ${messageText}`);
16943
+ error(source_default.blue("[Browser]"), messageText);
16443
16944
  } else if (messageType === "warning") {
16444
- console.warn(`[Browser] ${messageText}`);
16445
- } else if (this.verbose) {
16446
- console.log(`[Browser] ${messageText}`);
16945
+ warn(source_default.blue("[Browser]"), messageText);
16946
+ } else {
16947
+ info(source_default.blue("[Browser]"), messageText);
16447
16948
  }
16448
16949
  });
16449
16950
  this.client = await this.page.target().createCDPSession();
16450
16951
  await this.client.send("Browser.setDownloadBehavior", {
16451
16952
  behavior: "allowAndName",
16452
- downloadPath: os3.tmpdir(),
16953
+ downloadPath: os4.tmpdir(),
16453
16954
  eventsEnabled: true
16454
16955
  });
16455
- if (this.verbose)
16456
- console.log(`Navigating to: ${this.href}`);
16956
+ info(`Navigating to: ${this.href}`);
16457
16957
  await this.page.goto(this.href, { waitUntil: "networkidle0" });
16458
16958
  const shapeCount = await this.page.evaluate("editor.getCurrentPageShapes().length");
16459
16959
  this.isEmpty = shapeCount === 0;
@@ -16462,27 +16962,25 @@ var TldrawController = class {
16462
16962
  if (!this.browser)
16463
16963
  throw new Error("Controller not started");
16464
16964
  if (this.originalDarkMode !== void 0) {
16465
- if (this.verbose)
16466
- console.log(`Restoring dark mode: ${this.originalDarkMode}`);
16965
+ info(`Restoring dark mode: ${this.originalDarkMode}`);
16467
16966
  await this.setDarkMode(this.originalDarkMode);
16468
16967
  }
16469
16968
  await this.browser.close();
16470
- if (this.verbose)
16471
- console.log("Stopped controller");
16969
+ info("Stopped controller");
16472
16970
  }
16473
16971
  // Public method doesn't expose pageFrame
16474
- async download(output, filename, format, stripStyle) {
16475
- return this._download(output, filename, format, stripStyle);
16972
+ async download(output, filename, format, stripStyle, print) {
16973
+ return this._download(output, filename, format, stripStyle, void 0, print);
16476
16974
  }
16477
- async downloadFrame(output, filename, format, stripStyle, frameNameOrId) {
16478
- return this.downloadFrames(output, filename, format, stripStyle, [frameNameOrId]);
16975
+ async downloadFrame(output, filename, format, stripStyle, frameNameOrId, print) {
16976
+ return this.downloadFrames(output, filename, format, stripStyle, [frameNameOrId], print);
16479
16977
  }
16480
- async downloadFrames(output, filename, format, stripStyle, frameNamesOrIds) {
16978
+ async downloadFrames(output, filename, format, stripStyle, frameNamesOrIds, print) {
16481
16979
  const validPageFrames = [];
16482
16980
  for (const frame of frameNamesOrIds) {
16483
16981
  const pageFrame = await this.getPageFrameWithNameOrId(frame);
16484
16982
  if (pageFrame === void 0) {
16485
- console.warn(`Frame "${frame}" not found, skipping`);
16983
+ warn(`Frame "${frame}" not found, skipping`);
16486
16984
  } else {
16487
16985
  validPageFrames.push(pageFrame);
16488
16986
  }
@@ -16492,8 +16990,8 @@ var TldrawController = class {
16492
16990
  }
16493
16991
  const validFrameNames = validPageFrames.map((frame) => slugify(frame.name));
16494
16992
  const isFrameNameCollision = validFrameNames.length !== new Set(validFrameNames).size;
16495
- if (this.verbose && isFrameNameCollision) {
16496
- console.warn(
16993
+ if (isFrameNameCollision) {
16994
+ warn(
16497
16995
  "Frame names are not unique, including frame IDs in the output filenames to avoid collisions"
16498
16996
  );
16499
16997
  }
@@ -16501,22 +16999,28 @@ var TldrawController = class {
16501
16999
  for (const frame of validPageFrames) {
16502
17000
  const frameSuffix = isFrameNameCollision ? `-${frame.id.replace("shape:", "")}` : "";
16503
17001
  outputAccumulator.push(
16504
- ...await this._download(output, `${filename}${frameSuffix}`, format, stripStyle, frame)
17002
+ ...await this._download(
17003
+ output,
17004
+ `${filename}${frameSuffix}`,
17005
+ format,
17006
+ stripStyle,
17007
+ frame,
17008
+ print
17009
+ )
16505
17010
  );
16506
17011
  }
16507
17012
  return outputAccumulator;
16508
17013
  }
16509
- async downloadAllFrames(output, filename, format, stripStyle) {
17014
+ async downloadAllFrames(output, filename, format, stripStyle, print) {
16510
17015
  const pageFrames = await this.getPageFrames();
16511
17016
  const frameNamesOrIds = pageFrames.map((f) => f.id);
16512
- return this.downloadFrames(output, filename, format, stripStyle, frameNamesOrIds);
17017
+ return this.downloadFrames(output, filename, format, stripStyle, frameNamesOrIds, print);
16513
17018
  }
16514
17019
  // Ephemeral means we don't have to restore the user's value
16515
17020
  async setTransparency(transparent) {
16516
17021
  if (!this.page)
16517
17022
  throw new Error("Controller not started");
16518
- if (this.verbose)
16519
- console.log(`Setting background transparency: ${transparent}`);
17023
+ info(`Setting background transparency: ${transparent}`);
16520
17024
  await this.page.evaluate(
16521
17025
  `editor.updateInstanceState(
16522
17026
  { exportBackground: ${!transparent} },
@@ -16527,34 +17031,29 @@ var TldrawController = class {
16527
17031
  async setDarkMode(darkMode) {
16528
17032
  if (!this.page)
16529
17033
  throw new Error("Controller not started");
16530
- if (this.verbose)
16531
- console.log(`Setting dark mode: ${darkMode}`);
17034
+ info(`Setting dark mode: ${darkMode}`);
16532
17035
  if (!this.originalDarkMode)
16533
17036
  this.originalDarkMode = await this.getDarkMode();
16534
17037
  await this.page.evaluate(`editor.user.updateUserPreferences({ isDarkMode: ${darkMode}})`);
16535
17038
  }
16536
17039
  // eslint-disable-next-line @typescript-eslint/naming-convention
16537
- async _download(output, filename, format, stripStyle, pageFrame) {
17040
+ async _download(output, filename, format, stripStyle, pageFrame, print) {
16538
17041
  if (!this.page)
16539
17042
  throw new Error("Controller not started");
16540
17043
  if (this.isEmpty) {
16541
17044
  throw new Error("Cannot export an empty document");
16542
17045
  }
16543
17046
  if (stripStyle && format !== "svg") {
16544
- console.warn("Warning: --strip-style is only supported for SVG output");
17047
+ warn("--strip-style is only supported for SVG output");
16545
17048
  }
16546
17049
  if (pageFrame !== void 0 && format === "tldr") {
16547
- console.warn(
16548
- "Warning: --frames is not supported for tldr output, downloading entire document"
16549
- );
17050
+ warn("--frames is not supported for tldr output, downloading entire document");
16550
17051
  }
16551
17052
  const completionPromise = this.waitForDownloadCompletion();
16552
17053
  await this.closeMenus();
16553
17054
  let frameSuffix = "";
16554
17055
  if (pageFrame !== void 0 && format !== "tldr") {
16555
- if (this.verbose) {
16556
- console.log(`Selecting sketch frame "${pageFrame.name}" with ID "${pageFrame.id}"`);
16557
- }
17056
+ info(`Selecting sketch frame "${pageFrame.name}" with ID "${pageFrame.id}"`);
16558
17057
  frameSuffix = `-${slugify(pageFrame.name)}`;
16559
17058
  await this.page.evaluate("editor.selectNone()");
16560
17059
  await this.page.evaluate(`editor.select('${pageFrame.id}')`);
@@ -16574,16 +17073,25 @@ var TldrawController = class {
16574
17073
  }
16575
17074
  const downloadGuid = await completionPromise;
16576
17075
  await this.page.waitForNetworkIdle();
16577
- const downloadPath = path2.join(os3.tmpdir(), downloadGuid);
16578
- const outputPath = path2.resolve(
16579
- untildify(path2.join(output, `${filename}${frameSuffix}.${format}`))
16580
- );
16581
- await fs.rename(downloadPath, outputPath);
17076
+ const downloadPath = path2.join(os4.tmpdir(), downloadGuid);
17077
+ const outputPath = print ? downloadPath : path2.resolve(untildify(path2.join(output, `${filename}${frameSuffix}.${format}`)));
17078
+ if (!print)
17079
+ await fs.rename(downloadPath, outputPath);
16582
17080
  if (stripStyle && format === "svg") {
16583
17081
  const svg = await fs.readFile(outputPath, "utf8");
16584
17082
  const strippedSvg = this.stripStyleElement(svg);
16585
17083
  await fs.writeFile(outputPath, strippedSvg);
16586
17084
  }
17085
+ if (print) {
17086
+ if (format === "png") {
17087
+ const buffer = await fs.readFile(outputPath);
17088
+ const outputBase64 = buffer.toString("base64");
17089
+ return [outputBase64];
17090
+ }
17091
+ const outputString = await fs.readFile(outputPath, "utf8");
17092
+ const outputStringNoNewlines = outputString.replaceAll("\n", "");
17093
+ return [outputStringNoNewlines];
17094
+ }
16587
17095
  return [outputPath];
16588
17096
  }
16589
17097
  async closeMenus() {
@@ -16664,11 +17172,11 @@ async function isType(fsStatType, statsMethodName, filePath) {
16664
17172
  try {
16665
17173
  const stats = await fsPromises[fsStatType](filePath);
16666
17174
  return stats[statsMethodName]();
16667
- } catch (error) {
16668
- if (error.code === "ENOENT") {
17175
+ } catch (error2) {
17176
+ if (error2.code === "ENOENT") {
16669
17177
  return false;
16670
17178
  }
16671
- throw error;
17179
+ throw error2;
16672
17180
  }
16673
17181
  }
16674
17182
  function isTypeSync(fsStatType, statsMethodName, filePath) {
@@ -16677,11 +17185,11 @@ function isTypeSync(fsStatType, statsMethodName, filePath) {
16677
17185
  }
16678
17186
  try {
16679
17187
  return fs2[fsStatType](filePath)[statsMethodName]();
16680
- } catch (error) {
16681
- if (error.code === "ENOENT") {
17188
+ } catch (error2) {
17189
+ if (error2.code === "ENOENT") {
16682
17190
  return false;
16683
17191
  }
16684
- throw error;
17192
+ throw error2;
16685
17193
  }
16686
17194
  }
16687
17195
  var isFile = isType.bind(null, "stat", "isFile");
@@ -16721,12 +17229,141 @@ function validatePathOrUrl(pathOrUrl, options = {}) {
16721
17229
  // src/lib/tldraw-to-image.ts
16722
17230
  import fs3 from "node:fs/promises";
16723
17231
  import path4 from "node:path";
17232
+
17233
+ // node_modules/.pnpm/parse-ms@4.0.0/node_modules/parse-ms/index.js
17234
+ var toZeroIfInfinity = (value) => Number.isFinite(value) ? value : 0;
17235
+ function parseNumber(milliseconds) {
17236
+ return {
17237
+ days: Math.trunc(milliseconds / 864e5),
17238
+ hours: Math.trunc(milliseconds / 36e5 % 24),
17239
+ minutes: Math.trunc(milliseconds / 6e4 % 60),
17240
+ seconds: Math.trunc(milliseconds / 1e3 % 60),
17241
+ milliseconds: Math.trunc(milliseconds % 1e3),
17242
+ microseconds: Math.trunc(toZeroIfInfinity(milliseconds * 1e3) % 1e3),
17243
+ nanoseconds: Math.trunc(toZeroIfInfinity(milliseconds * 1e6) % 1e3)
17244
+ };
17245
+ }
17246
+ function parseBigint(milliseconds) {
17247
+ return {
17248
+ days: milliseconds / 86400000n,
17249
+ hours: milliseconds / 3600000n % 24n,
17250
+ minutes: milliseconds / 60000n % 60n,
17251
+ seconds: milliseconds / 1000n % 60n,
17252
+ milliseconds: milliseconds % 1000n,
17253
+ microseconds: 0n,
17254
+ nanoseconds: 0n
17255
+ };
17256
+ }
17257
+ function parseMilliseconds(milliseconds) {
17258
+ switch (typeof milliseconds) {
17259
+ case "number": {
17260
+ if (Number.isFinite(milliseconds)) {
17261
+ return parseNumber(milliseconds);
17262
+ }
17263
+ break;
17264
+ }
17265
+ case "bigint": {
17266
+ return parseBigint(milliseconds);
17267
+ }
17268
+ }
17269
+ throw new TypeError("Expected a finite number or bigint");
17270
+ }
17271
+
17272
+ // node_modules/.pnpm/pretty-ms@9.0.0/node_modules/pretty-ms/index.js
17273
+ var isZero = (value) => value === 0 || value === 0n;
17274
+ var pluralize = (word, count) => count === 1 || count === 1n ? word : `${word}s`;
17275
+ var SECOND_ROUNDING_EPSILON = 1e-7;
17276
+ var ONE_DAY_IN_MILLISECONDS = 24n * 60n * 60n * 1000n;
17277
+ function prettyMilliseconds(milliseconds, options) {
17278
+ const isBigInt = typeof milliseconds === "bigint";
17279
+ if (!isBigInt && !Number.isFinite(milliseconds)) {
17280
+ throw new TypeError("Expected a finite number or bigint");
17281
+ }
17282
+ options = { ...options };
17283
+ if (options.colonNotation) {
17284
+ options.compact = false;
17285
+ options.formatSubMilliseconds = false;
17286
+ options.separateMilliseconds = false;
17287
+ options.verbose = false;
17288
+ }
17289
+ if (options.compact) {
17290
+ options.unitCount = 1;
17291
+ options.secondsDecimalDigits = 0;
17292
+ options.millisecondsDecimalDigits = 0;
17293
+ }
17294
+ let result = [];
17295
+ const floorDecimals = (value, decimalDigits) => {
17296
+ const flooredInterimValue = Math.floor(value * 10 ** decimalDigits + SECOND_ROUNDING_EPSILON);
17297
+ const flooredValue = Math.round(flooredInterimValue) / 10 ** decimalDigits;
17298
+ return flooredValue.toFixed(decimalDigits);
17299
+ };
17300
+ const add2 = (value, long, short, valueString) => {
17301
+ if ((result.length === 0 || !options.colonNotation) && isZero(value) && !(options.colonNotation && short === "m")) {
17302
+ return;
17303
+ }
17304
+ valueString = valueString ?? String(value);
17305
+ if (options.colonNotation) {
17306
+ const wholeDigits = valueString.includes(".") ? valueString.split(".")[0].length : valueString.length;
17307
+ const minLength = result.length > 0 ? 2 : 1;
17308
+ valueString = "0".repeat(Math.max(0, minLength - wholeDigits)) + valueString;
17309
+ } else {
17310
+ valueString += options.verbose ? " " + pluralize(long, value) : short;
17311
+ }
17312
+ result.push(valueString);
17313
+ };
17314
+ const parsed = parseMilliseconds(milliseconds);
17315
+ const days = BigInt(parsed.days);
17316
+ add2(days / 365n, "year", "y");
17317
+ add2(days % 365n, "day", "d");
17318
+ add2(Number(parsed.hours), "hour", "h");
17319
+ add2(Number(parsed.minutes), "minute", "m");
17320
+ if (options.separateMilliseconds || options.formatSubMilliseconds || !options.colonNotation && milliseconds < 1e3) {
17321
+ const seconds = Number(parsed.seconds);
17322
+ const milliseconds2 = Number(parsed.milliseconds);
17323
+ const microseconds = Number(parsed.microseconds);
17324
+ const nanoseconds = Number(parsed.nanoseconds);
17325
+ add2(seconds, "second", "s");
17326
+ if (options.formatSubMilliseconds) {
17327
+ add2(milliseconds2, "millisecond", "ms");
17328
+ add2(microseconds, "microsecond", "\xB5s");
17329
+ add2(nanoseconds, "nanosecond", "ns");
17330
+ } else {
17331
+ const millisecondsAndBelow = milliseconds2 + microseconds / 1e3 + nanoseconds / 1e6;
17332
+ const millisecondsDecimalDigits = typeof options.millisecondsDecimalDigits === "number" ? options.millisecondsDecimalDigits : 0;
17333
+ const roundedMilliseconds = millisecondsAndBelow >= 1 ? Math.round(millisecondsAndBelow) : Math.ceil(millisecondsAndBelow);
17334
+ const millisecondsString = millisecondsDecimalDigits ? millisecondsAndBelow.toFixed(millisecondsDecimalDigits) : roundedMilliseconds;
17335
+ add2(
17336
+ Number.parseFloat(millisecondsString),
17337
+ "millisecond",
17338
+ "ms",
17339
+ millisecondsString
17340
+ );
17341
+ }
17342
+ } else {
17343
+ const seconds = (isBigInt ? Number(milliseconds % ONE_DAY_IN_MILLISECONDS) : milliseconds) / 1e3 % 60;
17344
+ const secondsDecimalDigits = typeof options.secondsDecimalDigits === "number" ? options.secondsDecimalDigits : 1;
17345
+ const secondsFixed = floorDecimals(seconds, secondsDecimalDigits);
17346
+ const secondsString = options.keepDecimalsOnWholeSeconds ? secondsFixed : secondsFixed.replace(/\.0+$/, "");
17347
+ add2(Number.parseFloat(secondsString), "second", "s", secondsString);
17348
+ }
17349
+ if (result.length === 0) {
17350
+ return "0" + (options.verbose ? " milliseconds" : "ms");
17351
+ }
17352
+ const separator = options.colonNotation ? ":" : " ";
17353
+ if (typeof options.unitCount === "number") {
17354
+ result = result.slice(0, Math.max(options.unitCount, 1));
17355
+ }
17356
+ return result.join(separator);
17357
+ }
17358
+
17359
+ // src/lib/tldraw-to-image.ts
16724
17360
  var defaultOptions2 = {
16725
17361
  darkMode: false,
16726
17362
  format: "svg",
16727
17363
  frames: false,
16728
17364
  name: void 0,
16729
17365
  output: "./",
17366
+ print: false,
16730
17367
  stripStyle: false,
16731
17368
  transparent: false,
16732
17369
  verbose: false
@@ -16736,26 +17373,32 @@ async function tldrawToImage(tldrPathOrUrl, options) {
16736
17373
  ...defaultOptions2,
16737
17374
  ...stripUndefined(options ?? {})
16738
17375
  };
16739
- const { darkMode, format, frames, name, output, stripStyle, transparent, verbose } = resolvedOptions;
16740
- if (verbose)
16741
- console.time("Export time");
17376
+ const { darkMode, format, frames, name, output, print, stripStyle, transparent, verbose: verbose2 } = resolvedOptions;
17377
+ const initialVerbosity = verbose;
17378
+ setVerbose(verbose2);
17379
+ if (options?.print && options.output !== void 0) {
17380
+ throw new Error("Cannot use --output with --print");
17381
+ }
17382
+ if (options?.print && options.name !== void 0) {
17383
+ warn("Ignoring --name when using --print");
17384
+ }
17385
+ const startTime = performance.now();
16742
17386
  const validatedPathOrUrl = validatePathOrUrl(tldrPathOrUrl, {
16743
17387
  requireFileExistence: true,
16744
17388
  validFileExtensions: [".tldr"],
16745
17389
  validHostnames: ["www.tldraw.com"]
16746
17390
  });
16747
17391
  const isLocal = typeof validatedPathOrUrl === "string";
16748
- if (verbose)
16749
- console.log(isLocal ? "Local file detected" : "tldraw URL detected");
17392
+ info(isLocal ? "Local file detected" : "tldraw URL detected");
16750
17393
  const outputFilename = name === void 0 ? isLocal ? path4.basename(validatedPathOrUrl, path4.extname(validatedPathOrUrl)) : validatedPathOrUrl.pathname.split("/").pop() ?? validatedPathOrUrl.pathname : sanitizeName(name, format);
16751
- if (isLocal && verbose)
16752
- console.log(`Loading tldr data "${validatedPathOrUrl}"`);
17394
+ if (isLocal)
17395
+ info(`Loading tldr data "${validatedPathOrUrl}"`);
16753
17396
  const tldrData = isLocal ? await fs3.readFile(validatedPathOrUrl, "utf8") : void 0;
16754
- const tldrawServer = new LocalTldrawServer(tldrData, verbose);
17397
+ const tldrawServer = new LocalTldrawServer(tldrData);
16755
17398
  if (isLocal)
16756
17399
  await tldrawServer.start();
16757
17400
  const tldrawUrl = isLocal ? tldrawServer.href : validatedPathOrUrl.href;
16758
- const tldrawController = new TldrawController(tldrawUrl, verbose);
17401
+ const tldrawController = new TldrawController(tldrawUrl);
16759
17402
  await tldrawController.start();
16760
17403
  await tldrawController.setTransparency(transparent);
16761
17404
  await tldrawController.setDarkMode(darkMode);
@@ -16765,7 +17408,8 @@ async function tldrawToImage(tldrPathOrUrl, options) {
16765
17408
  output,
16766
17409
  outputFilename,
16767
17410
  format,
16768
- stripStyle
17411
+ stripStyle,
17412
+ print
16769
17413
  );
16770
17414
  } else if (Array.isArray(frames) && frames.length > 0) {
16771
17415
  exportReport = await tldrawController.downloadFrames(
@@ -16773,16 +17417,23 @@ async function tldrawToImage(tldrPathOrUrl, options) {
16773
17417
  outputFilename,
16774
17418
  format,
16775
17419
  stripStyle,
16776
- frames
17420
+ frames,
17421
+ print
16777
17422
  );
16778
17423
  } else {
16779
- exportReport = await tldrawController.download(output, outputFilename, format, stripStyle);
17424
+ exportReport = await tldrawController.download(
17425
+ output,
17426
+ outputFilename,
17427
+ format,
17428
+ stripStyle,
17429
+ print
17430
+ );
16780
17431
  }
16781
17432
  await tldrawController.close();
16782
17433
  if (isLocal)
16783
17434
  tldrawServer.close();
16784
- if (verbose)
16785
- console.timeEnd("Export time");
17435
+ info(`Export time: ${prettyMilliseconds(performance.now() - startTime)}`);
17436
+ setVerbose(initialVerbosity);
16786
17437
  return exportReport;
16787
17438
  }
16788
17439
  function stripUndefined(options) {