@midscene/shared 1.8.4-beta-20260521070317.0 → 1.8.4

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.
@@ -5,7 +5,7 @@ import { assert } from "../utils.mjs";
5
5
  import { maskConfig, parseJson } from "./helper.mjs";
6
6
  import { initDebugConfig } from "./init-debug.mjs";
7
7
  const MODEL_CONFIG_DOC_URL = 'https://midscenejs.com/model-common-config.html';
8
- const getCurrentVersion = ()=>"1.8.4-beta-20260521070317.0";
8
+ const getCurrentVersion = ()=>"1.8.4";
9
9
  const getInvalidModelFamilyMessage = (modelFamily)=>`Invalid MIDSCENE_MODEL_FAMILY value: ${modelFamily}. Current version v${getCurrentVersion()} accepts the following model families: ${MODEL_FAMILY_VALUES.join(', ')}. You can also visit ${MODEL_CONFIG_DOC_URL} for the latest configuration information.`;
10
10
  const KEYS_MAP = {
11
11
  insight: INSIGHT_MODEL_CONFIG_KEYS,
@@ -1,9 +1,21 @@
1
1
  import node_assert from "node:assert";
2
+ import { Buffer } from "node:buffer";
2
3
  import get_photon from "./get-photon.mjs";
3
4
  async function imageInfoOfBase64(imageBase64) {
4
5
  const { PhotonImage } = await get_photon();
5
- const base64Data = imageBase64.replace(/^data:image\/\w+;base64,/, '');
6
- const result = PhotonImage.new_from_base64(base64Data);
6
+ const base64Data = imageBase64.replace(/^data:image\/\w+;base64,/, '').replace(/\s/g, '');
7
+ node_assert(base64Data, 'Invalid image: empty base64 data');
8
+ node_assert(/^[A-Za-z0-9+/]+={0,2}$/.test(base64Data) && base64Data.length % 4 !== 1, 'Invalid image: malformed base64 data');
9
+ const imageBuffer = Buffer.from(base64Data, 'base64');
10
+ node_assert(isValidImageBuffer(imageBuffer), 'Invalid image: unsupported format');
11
+ let result;
12
+ try {
13
+ result = PhotonImage.new_from_base64(base64Data);
14
+ } catch (error) {
15
+ throw new Error(`Invalid image: failed to decode base64 data (${error instanceof Error ? error.message : String(error)})`, {
16
+ cause: error
17
+ });
18
+ }
7
19
  const image = result instanceof Promise ? await result : result;
8
20
  const width = image.get_width();
9
21
  const height = image.get_height();
@@ -69,7 +69,8 @@ async function resizeAndConvertImgBuffer(inputFormat, inputData, newSize) {
69
69
  format: 'jpeg'
70
70
  };
71
71
  }
72
- const createImgBase64ByFormat = (format, body)=>`data:image/${format};base64,${body}`;
72
+ const normalizeBase64Body = (body)=>body.replace(/\s/g, '');
73
+ const createImgBase64ByFormat = (format, body)=>`data:image/${format};base64,${normalizeBase64Body(body)}`;
73
74
  async function resizeImgBase64(inputBase64, newSize) {
74
75
  const { body, mimeType } = parseBase64(inputBase64);
75
76
  const imageBuffer = Buffer.from(body, 'base64');
@@ -195,7 +196,10 @@ const localImg2Base64 = (imgPath, withoutHeader = false)=>{
195
196
  };
196
197
  const preProcessImageUrl = async (url, convertHttpImage2Base64)=>{
197
198
  if ('string' != typeof url) throw new Error(`url must be a string, but got ${url} with type ${typeof url}`);
198
- if (url.startsWith('data:')) return url;
199
+ if (url.startsWith('data:')) {
200
+ const { mimeType, body } = parseBase64(url);
201
+ return `data:${mimeType};base64,${body}`;
202
+ }
199
203
  if (!(url.startsWith('http://') || url.startsWith('https://'))) return await localImg2Base64(url);
200
204
  if (!convertHttpImage2Base64) return url;
201
205
  return await httpImg2Base64(url);
@@ -207,7 +211,7 @@ const parseBase64 = (fullBase64String)=>{
207
211
  if (-1 === index) throw new Error('Invalid base64 string');
208
212
  return {
209
213
  mimeType: fullBase64String.slice(5, index),
210
- body: fullBase64String.slice(index + separator.length)
214
+ body: normalizeBase64Body(fullBase64String.slice(index + separator.length))
211
215
  };
212
216
  } catch (e) {
213
217
  throw new Error(`parseBase64 fail because intput is not a valid base64 string: ${fullBase64String}`, {
@@ -272,4 +276,4 @@ async function scaleImage(imageBase64, scale) {
272
276
  imageBase64: base64
273
277
  };
274
278
  }
275
- export { createImgBase64ByFormat, cropByRect, httpImg2Base64, localImg2Base64, paddingToMatchBlock, paddingToMatchBlockByBase64, parseBase64, photonFromBase64, photonToBase64, preProcessImageUrl, resizeAndConvertImgBuffer, resizeImgBase64, saveBase64Image, scaleImage, zoomForGPT4o };
279
+ export { createImgBase64ByFormat, cropByRect, httpImg2Base64, localImg2Base64, normalizeBase64Body, paddingToMatchBlock, paddingToMatchBlockByBase64, parseBase64, photonFromBase64, photonToBase64, preProcessImageUrl, resizeAndConvertImgBuffer, resizeImgBase64, saveBase64Image, scaleImage, zoomForGPT4o };
@@ -37,7 +37,7 @@ const external_utils_js_namespaceObject = require("../utils.js");
37
37
  const external_helper_js_namespaceObject = require("./helper.js");
38
38
  const external_init_debug_js_namespaceObject = require("./init-debug.js");
39
39
  const MODEL_CONFIG_DOC_URL = 'https://midscenejs.com/model-common-config.html';
40
- const getCurrentVersion = ()=>"1.8.4-beta-20260521070317.0";
40
+ const getCurrentVersion = ()=>"1.8.4";
41
41
  const getInvalidModelFamilyMessage = (modelFamily)=>`Invalid MIDSCENE_MODEL_FAMILY value: ${modelFamily}. Current version v${getCurrentVersion()} accepts the following model families: ${external_types_js_namespaceObject.MODEL_FAMILY_VALUES.join(', ')}. You can also visit ${MODEL_CONFIG_DOC_URL} for the latest configuration information.`;
42
42
  const KEYS_MAP = {
43
43
  insight: external_constants_js_namespaceObject.INSIGHT_MODEL_CONFIG_KEYS,
@@ -41,12 +41,24 @@ __webpack_require__.d(__webpack_exports__, {
41
41
  });
42
42
  const external_node_assert_namespaceObject = require("node:assert");
43
43
  var external_node_assert_default = /*#__PURE__*/ __webpack_require__.n(external_node_assert_namespaceObject);
44
+ const external_node_buffer_namespaceObject = require("node:buffer");
44
45
  const external_get_photon_js_namespaceObject = require("./get-photon.js");
45
46
  var external_get_photon_js_default = /*#__PURE__*/ __webpack_require__.n(external_get_photon_js_namespaceObject);
46
47
  async function imageInfoOfBase64(imageBase64) {
47
48
  const { PhotonImage } = await external_get_photon_js_default()();
48
- const base64Data = imageBase64.replace(/^data:image\/\w+;base64,/, '');
49
- const result = PhotonImage.new_from_base64(base64Data);
49
+ const base64Data = imageBase64.replace(/^data:image\/\w+;base64,/, '').replace(/\s/g, '');
50
+ external_node_assert_default()(base64Data, 'Invalid image: empty base64 data');
51
+ external_node_assert_default()(/^[A-Za-z0-9+/]+={0,2}$/.test(base64Data) && base64Data.length % 4 !== 1, 'Invalid image: malformed base64 data');
52
+ const imageBuffer = external_node_buffer_namespaceObject.Buffer.from(base64Data, 'base64');
53
+ external_node_assert_default()(isValidImageBuffer(imageBuffer), 'Invalid image: unsupported format');
54
+ let result;
55
+ try {
56
+ result = PhotonImage.new_from_base64(base64Data);
57
+ } catch (error) {
58
+ throw new Error(`Invalid image: failed to decode base64 data (${error instanceof Error ? error.message : String(error)})`, {
59
+ cause: error
60
+ });
61
+ }
50
62
  const image = result instanceof Promise ? await result : result;
51
63
  const width = image.get_width();
52
64
  const height = image.get_height();
@@ -44,6 +44,7 @@ __webpack_require__.d(__webpack_exports__, {
44
44
  preProcessImageUrl: ()=>preProcessImageUrl,
45
45
  cropByRect: ()=>cropByRect,
46
46
  scaleImage: ()=>scaleImage,
47
+ normalizeBase64Body: ()=>normalizeBase64Body,
47
48
  zoomForGPT4o: ()=>zoomForGPT4o,
48
49
  createImgBase64ByFormat: ()=>createImgBase64ByFormat,
49
50
  paddingToMatchBlock: ()=>paddingToMatchBlock,
@@ -124,7 +125,8 @@ async function resizeAndConvertImgBuffer(inputFormat, inputData, newSize) {
124
125
  format: 'jpeg'
125
126
  };
126
127
  }
127
- const createImgBase64ByFormat = (format, body)=>`data:image/${format};base64,${body}`;
128
+ const normalizeBase64Body = (body)=>body.replace(/\s/g, '');
129
+ const createImgBase64ByFormat = (format, body)=>`data:image/${format};base64,${normalizeBase64Body(body)}`;
128
130
  async function resizeImgBase64(inputBase64, newSize) {
129
131
  const { body, mimeType } = parseBase64(inputBase64);
130
132
  const imageBuffer = external_node_buffer_namespaceObject.Buffer.from(body, 'base64');
@@ -250,7 +252,10 @@ const localImg2Base64 = (imgPath, withoutHeader = false)=>{
250
252
  };
251
253
  const preProcessImageUrl = async (url, convertHttpImage2Base64)=>{
252
254
  if ('string' != typeof url) throw new Error(`url must be a string, but got ${url} with type ${typeof url}`);
253
- if (url.startsWith('data:')) return url;
255
+ if (url.startsWith('data:')) {
256
+ const { mimeType, body } = parseBase64(url);
257
+ return `data:${mimeType};base64,${body}`;
258
+ }
254
259
  if (!(url.startsWith('http://') || url.startsWith('https://'))) return await localImg2Base64(url);
255
260
  if (!convertHttpImage2Base64) return url;
256
261
  return await httpImg2Base64(url);
@@ -262,7 +267,7 @@ const parseBase64 = (fullBase64String)=>{
262
267
  if (-1 === index) throw new Error('Invalid base64 string');
263
268
  return {
264
269
  mimeType: fullBase64String.slice(5, index),
265
- body: fullBase64String.slice(index + separator.length)
270
+ body: normalizeBase64Body(fullBase64String.slice(index + separator.length))
266
271
  };
267
272
  } catch (e) {
268
273
  throw new Error(`parseBase64 fail because intput is not a valid base64 string: ${fullBase64String}`, {
@@ -331,6 +336,7 @@ exports.createImgBase64ByFormat = __webpack_exports__.createImgBase64ByFormat;
331
336
  exports.cropByRect = __webpack_exports__.cropByRect;
332
337
  exports.httpImg2Base64 = __webpack_exports__.httpImg2Base64;
333
338
  exports.localImg2Base64 = __webpack_exports__.localImg2Base64;
339
+ exports.normalizeBase64Body = __webpack_exports__.normalizeBase64Body;
334
340
  exports.paddingToMatchBlock = __webpack_exports__.paddingToMatchBlock;
335
341
  exports.paddingToMatchBlockByBase64 = __webpack_exports__.paddingToMatchBlockByBase64;
336
342
  exports.parseBase64 = __webpack_exports__.parseBase64;
@@ -347,6 +353,7 @@ for(var __rspack_i in __webpack_exports__)if (-1 === [
347
353
  "cropByRect",
348
354
  "httpImg2Base64",
349
355
  "localImg2Base64",
356
+ "normalizeBase64Body",
350
357
  "paddingToMatchBlock",
351
358
  "paddingToMatchBlockByBase64",
352
359
  "parseBase64",
@@ -1,3 +1,4 @@
1
+ import { Buffer } from 'node:buffer';
1
2
  import type { Size } from '../types';
2
3
  export interface ImageInfo extends Size {
3
4
  }
@@ -26,6 +26,7 @@ export declare function resizeAndConvertImgBuffer(inputFormat: string, inputData
26
26
  buffer: Buffer;
27
27
  format: string;
28
28
  }>;
29
+ export declare const normalizeBase64Body: (body: string) => string;
29
30
  export declare const createImgBase64ByFormat: (format: string, body: string) => string;
30
31
  export declare function resizeImgBase64(inputBase64: string, newSize: {
31
32
  width: number;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@midscene/shared",
3
- "version": "1.8.4-beta-20260521070317.0",
3
+ "version": "1.8.4",
4
4
  "repository": "https://github.com/web-infra-dev/midscene",
5
5
  "homepage": "https://midscenejs.com/",
6
6
  "types": "./dist/types/index.d.ts",
package/src/img/info.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import assert from 'node:assert';
2
+ import { Buffer } from 'node:buffer';
2
3
  import type { Size } from '../types';
3
4
  import getPhoton from './get-photon';
4
5
 
@@ -15,9 +16,26 @@ export async function imageInfoOfBase64(
15
16
  imageBase64: string,
16
17
  ): Promise<ImageInfo> {
17
18
  const { PhotonImage } = await getPhoton();
18
- const base64Data = imageBase64.replace(/^data:image\/\w+;base64,/, '');
19
+ const base64Data = imageBase64
20
+ .replace(/^data:image\/\w+;base64,/, '')
21
+ .replace(/\s/g, '');
22
+ assert(base64Data, 'Invalid image: empty base64 data');
23
+ assert(
24
+ /^[A-Za-z0-9+/]+={0,2}$/.test(base64Data) && base64Data.length % 4 !== 1,
25
+ 'Invalid image: malformed base64 data',
26
+ );
27
+ const imageBuffer = Buffer.from(base64Data, 'base64');
28
+ assert(isValidImageBuffer(imageBuffer), 'Invalid image: unsupported format');
19
29
  // Support both sync (Photon) and async (Canvas fallback) versions
20
- const result = PhotonImage.new_from_base64(base64Data);
30
+ let result: ReturnType<typeof PhotonImage.new_from_base64>;
31
+ try {
32
+ result = PhotonImage.new_from_base64(base64Data);
33
+ } catch (error) {
34
+ throw new Error(
35
+ `Invalid image: failed to decode base64 data (${error instanceof Error ? error.message : String(error)})`,
36
+ { cause: error },
37
+ );
38
+ }
21
39
  const image = result instanceof Promise ? await result : result;
22
40
  const width = image.get_width();
23
41
  const height = image.get_height();
@@ -154,8 +154,10 @@ export async function resizeAndConvertImgBuffer(
154
154
  };
155
155
  }
156
156
 
157
+ export const normalizeBase64Body = (body: string) => body.replace(/\s/g, '');
158
+
157
159
  export const createImgBase64ByFormat = (format: string, body: string) => {
158
- return `data:image/${format};base64,${body}`;
160
+ return `data:image/${format};base64,${normalizeBase64Body(body)}`;
159
161
  };
160
162
 
161
163
  export async function resizeImgBase64(
@@ -397,7 +399,8 @@ export const preProcessImageUrl = async (
397
399
  );
398
400
  }
399
401
  if (url.startsWith('data:')) {
400
- return url;
402
+ const { mimeType, body } = parseBase64(url);
403
+ return `data:${mimeType};base64,${body}`;
401
404
  } else if (url.startsWith('http://') || url.startsWith('https://')) {
402
405
  if (!convertHttpImage2Base64) {
403
406
  return url;
@@ -426,7 +429,9 @@ export const parseBase64 = (
426
429
  return {
427
430
  // 5 means 'data:'
428
431
  mimeType: fullBase64String.slice(5, index),
429
- body: fullBase64String.slice(index + separator.length),
432
+ body: normalizeBase64Body(
433
+ fullBase64String.slice(index + separator.length),
434
+ ),
430
435
  };
431
436
  } catch (e) {
432
437
  throw new Error(