@midscene/core 0.0.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.
@@ -0,0 +1,307 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+
30
+ // src/image/index.ts
31
+ var image_exports = {};
32
+ __export(image_exports, {
33
+ alignCoordByTrim: () => alignCoordByTrim,
34
+ base64Encoded: () => base64Encoded,
35
+ calculateNewDimensions: () => calculateNewDimensions,
36
+ composeSectionDiagram: () => composeSectionDiagram,
37
+ imageInfo: () => imageInfo,
38
+ imageInfoOfBase64: () => imageInfoOfBase64,
39
+ resizeImg: () => resizeImg,
40
+ saveBase64Image: () => saveBase64Image,
41
+ transformImgPathToBase64: () => transformImgPathToBase64,
42
+ trimImage: () => trimImage
43
+ });
44
+ module.exports = __toCommonJS(image_exports);
45
+
46
+ // src/image/info.ts
47
+ var import_node_assert = __toESM(require("assert"));
48
+ var import_buffer = require("buffer");
49
+ var import_node_fs = require("fs");
50
+ var import_sharp = __toESM(require("sharp"));
51
+ async function imageInfo(image) {
52
+ const { width, height } = await (0, import_sharp.default)(image).metadata();
53
+ (0, import_node_assert.default)(width && height, `invalid image: ${image}`);
54
+ return { width, height };
55
+ }
56
+ async function imageInfoOfBase64(imageBase64) {
57
+ const base64Data = imageBase64.replace(/^data:image\/\w+;base64,/, "");
58
+ return imageInfo(import_buffer.Buffer.from(base64Data, "base64"));
59
+ }
60
+ function base64Encoded(image, withHeader = true) {
61
+ const imageBuffer = (0, import_node_fs.readFileSync)(image);
62
+ if (!withHeader) {
63
+ return imageBuffer.toString("base64");
64
+ }
65
+ if (image.endsWith("png")) {
66
+ return `data:image/png;base64,${imageBuffer.toString("base64")}`;
67
+ } else if (image.endsWith("jpg") || image.endsWith("jpeg")) {
68
+ return `data:image/jpeg;base64,${imageBuffer.toString("base64")}`;
69
+ }
70
+ throw new Error("unsupported image type");
71
+ }
72
+
73
+ // src/image/transform.ts
74
+ var import_node_buffer = require("buffer");
75
+ var import_sharp2 = __toESM(require("sharp"));
76
+ async function saveBase64Image(options) {
77
+ const { base64Data, outputPath } = options;
78
+ const base64Image = base64Data.split(";base64,").pop() || base64Data;
79
+ const imageBuffer = import_node_buffer.Buffer.from(base64Image, "base64");
80
+ await (0, import_sharp2.default)(imageBuffer).toFile(outputPath);
81
+ console.log("Image successfully written to file.");
82
+ }
83
+ async function transformImgPathToBase64(inputPath) {
84
+ return await (0, import_sharp2.default)(inputPath).toBuffer().then((data) => {
85
+ const base64Data = data.toString("base64");
86
+ return base64Data;
87
+ });
88
+ }
89
+ async function resizeImg(base64Data) {
90
+ const base64Image = base64Data.split(";base64,").pop() || base64Data;
91
+ const imageBuffer = import_node_buffer.Buffer.from(base64Image, "base64");
92
+ const metadata = await (0, import_sharp2.default)(imageBuffer).metadata();
93
+ const { width, height } = metadata;
94
+ if (!width || !height) {
95
+ throw Error("undefined width or height with url");
96
+ }
97
+ const newSize = calculateNewDimensions(width, height);
98
+ return await (0, import_sharp2.default)(imageBuffer).resize(newSize.width, newSize.height).toBuffer().then((data) => {
99
+ const base64Data2 = data.toString("base64");
100
+ return base64Data2;
101
+ });
102
+ }
103
+ function calculateNewDimensions(originalWidth, originalHeight) {
104
+ const maxWidth = 768;
105
+ const maxHeight = 2048;
106
+ let newWidth = originalWidth;
107
+ let newHeight = originalHeight;
108
+ const aspectRatio = originalWidth / originalHeight;
109
+ if (originalWidth > maxWidth) {
110
+ newWidth = maxWidth;
111
+ newHeight = newWidth / aspectRatio;
112
+ }
113
+ if (newHeight > maxHeight) {
114
+ newHeight = maxHeight;
115
+ newWidth = newHeight * aspectRatio;
116
+ }
117
+ return {
118
+ width: Math.round(newWidth),
119
+ height: Math.round(newHeight)
120
+ };
121
+ }
122
+ async function trimImage(image) {
123
+ const { info } = await (0, import_sharp2.default)(image).trim().toBuffer({
124
+ resolveWithObject: true
125
+ });
126
+ if (typeof info.trimOffsetLeft === "undefined" || typeof info.trimOffsetTop === "undefined") {
127
+ return null;
128
+ }
129
+ return {
130
+ trimOffsetLeft: info.trimOffsetLeft,
131
+ trimOffsetTop: info.trimOffsetTop,
132
+ width: info.width,
133
+ height: info.height
134
+ };
135
+ }
136
+ async function alignCoordByTrim(image, center) {
137
+ const img = await (0, import_sharp2.default)(image).extract(center).toBuffer();
138
+ const trimInfo = await trimImage(img);
139
+ if (!trimInfo) {
140
+ return center;
141
+ }
142
+ return {
143
+ left: center.left - trimInfo.trimOffsetLeft,
144
+ top: center.top - trimInfo.trimOffsetTop,
145
+ width: trimInfo.width,
146
+ height: trimInfo.height
147
+ };
148
+ }
149
+
150
+ // src/image/visualization.ts
151
+ var import_buffer2 = require("buffer");
152
+ var import_sharp3 = __toESM(require("sharp"));
153
+
154
+ // src/utils.ts
155
+ var import_os = require("os");
156
+ var import_path = require("path");
157
+ var import_fs = require("fs");
158
+ var import_crypto = require("crypto");
159
+ var import_assert = __toESM(require("assert"));
160
+ var pkg;
161
+ function getPkgInfo() {
162
+ if (pkg) {
163
+ return pkg;
164
+ }
165
+ let pkgJsonFile = "";
166
+ if ((0, import_fs.existsSync)((0, import_path.join)(__dirname, "../package.json"))) {
167
+ pkgJsonFile = (0, import_path.join)(__dirname, "../package.json");
168
+ } else if ((0, import_fs.existsSync)((0, import_path.join)(__dirname, "../../../package.json"))) {
169
+ pkgJsonFile = (0, import_path.join)(__dirname, "../../../package.json");
170
+ }
171
+ if (pkgJsonFile) {
172
+ const { name, version } = JSON.parse((0, import_fs.readFileSync)(pkgJsonFile, "utf-8"));
173
+ pkg = { name, version };
174
+ return pkg;
175
+ } else {
176
+ return {
177
+ name: "midscene-unknown-page-name",
178
+ version: "0.0.0"
179
+ };
180
+ }
181
+ }
182
+ var logDir = (0, import_path.join)(process.cwd(), "./midscene_run/");
183
+ function getTmpDir() {
184
+ const path = (0, import_path.join)((0, import_os.tmpdir)(), getPkgInfo().name);
185
+ (0, import_fs.mkdirSync)(path, { recursive: true });
186
+ return path;
187
+ }
188
+ function getTmpFile(fileExt) {
189
+ const filename = `${(0, import_crypto.randomUUID)()}.${fileExt}`;
190
+ return (0, import_path.join)(getTmpDir(), filename);
191
+ }
192
+
193
+ // src/image/visualization.ts
194
+ var colors = [
195
+ {
196
+ name: "Red",
197
+ hex: "#FF0000"
198
+ },
199
+ {
200
+ name: "Green",
201
+ hex: "#00FF00"
202
+ },
203
+ {
204
+ name: "Blue",
205
+ hex: "#0000FF"
206
+ },
207
+ {
208
+ name: "Yellow",
209
+ hex: "#FFFF00"
210
+ },
211
+ {
212
+ name: "Cyan",
213
+ hex: "#00FFFF"
214
+ },
215
+ {
216
+ name: "Magenta",
217
+ hex: "#FF00FF"
218
+ },
219
+ {
220
+ name: "Orange",
221
+ hex: "#FFA500"
222
+ },
223
+ {
224
+ name: "Purple",
225
+ hex: "#800080"
226
+ },
227
+ {
228
+ name: "Brown",
229
+ hex: "#A52A2A"
230
+ },
231
+ {
232
+ name: "Pink",
233
+ hex: "#FFC0CB"
234
+ },
235
+ {
236
+ name: "Light Blue",
237
+ hex: "#ADD8E6"
238
+ },
239
+ {
240
+ name: "Lime",
241
+ hex: "#00FF00"
242
+ },
243
+ {
244
+ name: "Violet",
245
+ hex: "#EE82EE"
246
+ },
247
+ {
248
+ name: "Gold",
249
+ hex: "#FFD700"
250
+ },
251
+ {
252
+ name: "Teal",
253
+ hex: "#008080"
254
+ }
255
+ ];
256
+ var sizeLimit = 512;
257
+ var textFontSize = 12;
258
+ async function composeSectionDiagram(sections, context) {
259
+ const { width, height } = await imageInfo(context.screenshotBase64);
260
+ const ratio = Math.min(sizeLimit / width, sizeLimit / height, 1);
261
+ const canvasWidth = width * ratio;
262
+ const canvasHeight = height * ratio;
263
+ const sectionNameColorMap = {};
264
+ const rects = sections.map((section, index) => {
265
+ const { left, top, width: width2, height: height2 } = section.rect;
266
+ const color = colors[index % colors.length];
267
+ sectionNameColorMap[section.name] = color;
268
+ return `
269
+ <rect x="${left * ratio}" y="${top * ratio}" width="${width2 * ratio}" height="${height2 * ratio}" fill="${color.hex}" />
270
+ <text x="${left * ratio}" y="${top * ratio + textFontSize}" font-family="Arial" font-size="${textFontSize}" fill="black">
271
+ ${section.name}
272
+ </text>
273
+ `;
274
+ });
275
+ const rectangles = `
276
+ <svg width="${canvasWidth}" height="${canvasHeight}">
277
+ ${rects.join("\n")}
278
+ </svg>
279
+ `;
280
+ const svgBuffer = import_buffer2.Buffer.from(rectangles);
281
+ const file = getTmpFile("png");
282
+ await (0, import_sharp3.default)({
283
+ create: {
284
+ width: canvasWidth,
285
+ height: canvasHeight,
286
+ channels: 4,
287
+ background: { r: 255, g: 255, b: 255, alpha: 1 }
288
+ }
289
+ }).composite([{ input: svgBuffer }]).png().toFile(file);
290
+ return {
291
+ file,
292
+ sectionNameColorMap
293
+ };
294
+ }
295
+ // Annotate the CommonJS export names for ESM import in node:
296
+ 0 && (module.exports = {
297
+ alignCoordByTrim,
298
+ base64Encoded,
299
+ calculateNewDimensions,
300
+ composeSectionDiagram,
301
+ imageInfo,
302
+ imageInfoOfBase64,
303
+ resizeImg,
304
+ saveBase64Image,
305
+ transformImgPathToBase64,
306
+ trimImage
307
+ });