@jsenv/terminal-recorder 1.2.1 → 1.3.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jsenv/terminal-recorder",
3
- "version": "1.2.1",
3
+ "version": "1.3.0",
4
4
  "description": "Record terminal output as .svg, .gif, .webm, .mp4",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -10,8 +10,7 @@
10
10
  },
11
11
  "author": {
12
12
  "name": "dmail",
13
- "email": "dmaillard06@gmail.com",
14
- "url": "https://twitter.com/damienmaillard"
13
+ "email": "dmaillard06@gmail.com"
15
14
  },
16
15
  "publishConfig": {
17
16
  "access": "public"
@@ -32,9 +31,9 @@
32
31
  "prepublishOnly": "npm run build"
33
32
  },
34
33
  "dependencies": {
35
- "@jsenv/humanize": "1.2.3",
36
- "@jsenv/server": "15.2.12",
37
- "@playwright/browser-webkit": "1.45.1",
34
+ "@jsenv/humanize": "1.2.4",
35
+ "@jsenv/server": "15.2.13",
36
+ "@playwright/browser-chromium": "1.45.1",
38
37
  "ansi-regex": "6.0.1",
39
38
  "he": "1.2.0",
40
39
  "playwright": "1.45.1",
package/src/main.js CHANGED
@@ -1,5 +1,6 @@
1
- // not yet available
2
- // export { renderTerminalHtml } from "./render_terminal_html.js";
3
-
4
1
  export { startTerminalRecording } from "./terminal_recording.js";
5
2
  export { recordCommandToSvg } from "./command_recording.js";
3
+
4
+ export { renderTerminalSvg } from "./svg/render_terminal_svg.js";
5
+ // not yet available
6
+ // export { renderTerminalHtml } from "./render_terminal_html.js";
@@ -1,4 +1,3 @@
1
- import prettier from "prettier";
2
1
  import { parseAnsi } from "./parse_ansi.js";
3
2
  import { createSvgRootNode } from "./xml_generator.js";
4
3
 
@@ -36,8 +35,11 @@ const colorsDefault = {
36
35
  bgCyanBright: "#00FFFF",
37
36
  bgWhiteBright: "#FFFFFF",
38
37
  };
38
+ const headDefault = {
39
+ height: 40,
40
+ };
39
41
 
40
- export const renderTerminalSvg = async (
42
+ export const renderTerminalSvg = (
41
43
  ansi,
42
44
  {
43
45
  title = "ansi to terminal",
@@ -61,9 +63,10 @@ export const renderTerminalSvg = async (
61
63
  height,
62
64
  maxWidth,
63
65
  maxHeight,
66
+
67
+ head = true,
64
68
  } = {},
65
69
  ) => {
66
- const { rows, columns, chunks } = parseAnsi(ansi);
67
70
  const font = {
68
71
  size: fontSize,
69
72
  width: 8.4013671875,
@@ -75,13 +78,20 @@ export const renderTerminalSvg = async (
75
78
  emHeightDescent: 3.4453125,
76
79
  };
77
80
 
78
- const headerHeight = 40;
79
- const textWidth = columns * font.width;
80
- const textHeight = rows * (font.lineHeight + 1) + font.emHeightDescent;
81
- const bodyContentWidth = paddingLeft + textWidth + paddingRight;
82
- const bodyContentHeight = paddingTop + textHeight + paddingBottom;
83
- const contentWidth = bodyContentWidth;
84
- const contentHeight = headerHeight + bodyContentHeight;
81
+ let headerHeight = 0;
82
+ if (head) {
83
+ if (head === true) head = {};
84
+ const headOptions = { ...headDefault, ...head };
85
+ headerHeight = headOptions.height;
86
+ }
87
+
88
+ const { rows, columns, chunks } = parseAnsi(ansi);
89
+ const bodyTextWidth = columns * font.width;
90
+ const bodyTextHeight = rows * (font.lineHeight + 1) + font.emHeightDescent;
91
+ const bodyContentWidth = paddingLeft + bodyTextWidth + paddingRight;
92
+ const bodyContentHeight = paddingTop + bodyTextHeight + paddingBottom;
93
+ let contentWidth = bodyContentWidth;
94
+ let contentHeight = headerHeight + bodyContentHeight;
85
95
 
86
96
  let computedWidth;
87
97
  if (typeof width === "number") {
@@ -111,7 +121,7 @@ export const renderTerminalSvg = async (
111
121
  backgroundColor,
112
122
  });
113
123
 
114
- background: {
124
+ render_background: {
115
125
  const backgroundGroup = svg.createNode("g", {
116
126
  id: "background",
117
127
  });
@@ -129,48 +139,50 @@ export const renderTerminalSvg = async (
129
139
  svg.appendChild(backgroundGroup);
130
140
  }
131
141
 
132
- header: {
133
- const headerGroup = svg.createNode("g", {
134
- id: "header",
135
- });
136
- const iconsGroup = svg.createNode("g", {
137
- transform: `translate(20,${headerHeight / 2})`,
138
- });
139
- const circleA = svg.createNode("circle", {
140
- cx: 0,
141
- cy: 0,
142
- r: 6,
143
- fill: "#ff5f57",
144
- });
145
- iconsGroup.appendChild(circleA);
146
- const circleB = svg.createNode("circle", {
147
- cx: 20,
148
- cy: 0,
149
- r: 6,
150
- fill: "#febc2e",
151
- });
152
- iconsGroup.appendChild(circleB);
153
- const circleC = svg.createNode("circle", {
154
- cx: 40,
155
- cy: 0,
156
- r: 6,
157
- fill: "#28c840",
158
- });
159
- iconsGroup.appendChild(circleC);
160
- headerGroup.appendChild(iconsGroup);
142
+ if (head) {
143
+ render_head: {
144
+ const headerGroup = svg.createNode("g", {
145
+ id: "header",
146
+ });
147
+ const iconsGroup = svg.createNode("g", {
148
+ transform: `translate(20,${headerHeight / 2})`,
149
+ });
150
+ const circleA = svg.createNode("circle", {
151
+ cx: 0,
152
+ cy: 0,
153
+ r: 6,
154
+ fill: "#ff5f57",
155
+ });
156
+ iconsGroup.appendChild(circleA);
157
+ const circleB = svg.createNode("circle", {
158
+ cx: 20,
159
+ cy: 0,
160
+ r: 6,
161
+ fill: "#febc2e",
162
+ });
163
+ iconsGroup.appendChild(circleB);
164
+ const circleC = svg.createNode("circle", {
165
+ cx: 40,
166
+ cy: 0,
167
+ r: 6,
168
+ fill: "#28c840",
169
+ });
170
+ iconsGroup.appendChild(circleC);
171
+ headerGroup.appendChild(iconsGroup);
161
172
 
162
- const text = svg.createNode("text", {
163
- "fill": "#abb2bf",
164
- "text-anchor": "middle",
165
- "x": computedWidth / 2,
166
- "y": headerHeight / 2,
167
- });
168
- text.setContent(title);
169
- headerGroup.appendChild(text);
170
- svg.appendChild(headerGroup);
173
+ const text = svg.createNode("text", {
174
+ "fill": "#abb2bf",
175
+ "text-anchor": "middle",
176
+ "x": computedWidth / 2,
177
+ "y": headerHeight / 2,
178
+ });
179
+ text.setContent(title);
180
+ headerGroup.appendChild(text);
181
+ svg.appendChild(headerGroup);
182
+ }
171
183
  }
172
184
 
173
- body: {
185
+ render_body: {
174
186
  const bodyComputedHeight = computedHeight - headerHeight + paddingBottom;
175
187
  const foreignObject = svg.createNode("foreignObject", {
176
188
  id: "body",
@@ -281,10 +293,7 @@ export const renderTerminalSvg = async (
281
293
  }
282
294
 
283
295
  const svgString = svg.renderAsString();
284
- const formatted = await prettier.format(svgString, {
285
- parser: "html",
286
- });
287
- return formatted;
296
+ return svgString;
288
297
  };
289
298
 
290
299
  // Some SVG Implementations drop whitespaces
@@ -9,6 +9,8 @@
9
9
  - we should have a webm video
10
10
  */
11
11
 
12
+ import prettier from "prettier";
13
+
12
14
  import { renderTerminalSvg } from "./svg/render_terminal_svg.js";
13
15
 
14
16
  const isDev = process.execArgv.includes("--conditions=development");
@@ -78,9 +80,9 @@ export const startTerminalRecording = async ({
78
80
  if (!svg && !gif && !video) {
79
81
  throw new Error("svg, video or gif must be enabled ");
80
82
  }
81
- const { webkit } = await import("playwright");
83
+ const { chromium } = await import("playwright");
82
84
  const server = await startLocalServer();
83
- const browser = await webkit.launch({
85
+ const browser = await chromium.launch({
84
86
  // channel: "chrome", // https://github.com/microsoft/playwright/issues/7716#issuecomment-882634893
85
87
  headless: !debug,
86
88
  // needed because https-localhost fails to trust cert on chrome + linux (ubuntu 20.04)
@@ -155,8 +157,11 @@ export const startTerminalRecording = async ({
155
157
  }
156
158
  terminalRecords.svg = async () => {
157
159
  const ansi = recordedFormats.textInViewport;
158
- const terminalSvg = await renderTerminalSvg(ansi, svg);
159
- return terminalSvg;
160
+ const terminalSvg = renderTerminalSvg(ansi, svg);
161
+ const terminalSvgFormatted = await prettier.format(terminalSvg, {
162
+ parser: "html",
163
+ });
164
+ return terminalSvgFormatted;
160
165
  };
161
166
  terminalRecords.gif = () => {
162
167
  const terminalGifBuffer = Buffer.from(recordedFormats.gif, "binary");