funda-ui 4.7.604 → 4.7.608
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/Chatbox/index.js +123 -69
- package/LiveSearch/index.js +117 -67
- package/MultipleCheckboxes/index.js +117 -67
- package/MultipleSelect/index.js +117 -67
- package/NativeSelect/index.js +117 -67
- package/Radio/index.js +117 -67
- package/Select/index.js +117 -67
- package/Utils/anim.js +116 -62
- package/Utils/initDefaultOptions.js +116 -62
- package/Utils/validate.d.ts +1 -7
- package/Utils/validate.js +115 -62
- package/lib/cjs/Chatbox/index.js +123 -69
- package/lib/cjs/LiveSearch/index.js +117 -67
- package/lib/cjs/MultipleCheckboxes/index.js +117 -67
- package/lib/cjs/MultipleSelect/index.js +117 -67
- package/lib/cjs/NativeSelect/index.js +117 -67
- package/lib/cjs/Radio/index.js +117 -67
- package/lib/cjs/Select/index.js +117 -67
- package/lib/cjs/Utils/anim.js +116 -62
- package/lib/cjs/Utils/initDefaultOptions.js +116 -62
- package/lib/cjs/Utils/validate.d.ts +1 -7
- package/lib/cjs/Utils/validate.js +115 -62
- package/lib/esm/Chatbox/index.tsx +8 -2
- package/lib/esm/Utils/libs/validate.ts +167 -194
- package/package.json +1 -1
package/lib/cjs/Utils/anim.js
CHANGED
|
@@ -217,67 +217,86 @@ function setDefaultOptions(props, options) {
|
|
|
217
217
|
/* harmony export */ "isJSON": () => (/* binding */ isJSON),
|
|
218
218
|
/* harmony export */ "isValidNumeric": () => (/* binding */ isValidNumeric)
|
|
219
219
|
/* harmony export */ });
|
|
220
|
-
/* unused harmony exports
|
|
220
|
+
/* unused harmony exports isEmpty, isNumber, isInt, isEmail, isTel, isMobile */
|
|
221
221
|
function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); }
|
|
222
222
|
/**
|
|
223
223
|
* Fix And Parse JSON (Support for handling complex escape JSON strings)
|
|
224
|
+
* @desc recursively fix top-level key/value (recursively handles when encountering top-level values that are objects/arrays)
|
|
224
225
|
* @private
|
|
225
226
|
*/
|
|
226
227
|
/*
|
|
227
|
-
-
|
|
228
|
-
-
|
|
229
|
-
- Then process the outermost object or array key
|
|
230
|
-
- If a top-level value is an unquoted object or array (e.g
|
|
231
|
-
|
|
232
|
-
- For values wrapped in quotes ('...' or "..."), extract the inner text and
|
|
233
|
-
re-encode it using JSON.stringify (ensures internal single/double quotes
|
|
234
|
-
are not corrupted);
|
|
228
|
+
- Still prioritize JSON.parse first;
|
|
229
|
+
- After parse fails, do unescaping (\\" → ");
|
|
230
|
+
- Then process the outermost layer (object or array) key by key, value by value;
|
|
231
|
+
- If a top-level value is an unquoted object or array (e.g., messages: [ {...} ]), recursively treat that value as a new outermost layer for fixing;
|
|
232
|
+
- For strings wrapped in quotes ('...' or "..."), only extract the outer layer and re-encode with JSON.stringify (ensuring internal single/double quotes won't be mistakenly changed);
|
|
235
233
|
- Set MAX_DEPTH to prevent infinite recursion.
|
|
236
234
|
*/
|
|
237
|
-
// fixAndParseJSON - recursively repairs top-level key/value
|
|
238
|
-
// (when encountering outermost values that are objects/arrays, it recurses)
|
|
239
|
-
|
|
240
235
|
/*
|
|
241
|
-
|
|
236
|
+
@Examples:
|
|
242
237
|
|
|
243
|
-
// ✅ Valid JSON (contains svg and single
|
|
238
|
+
// ✅ Valid JSON (contains svg and single quote content)
|
|
244
239
|
const okJson = `{
|
|
245
|
-
"label":"<svg width='16' height='16'><path fill='currentColor' d='M19 13h-6'/></svg>
|
|
240
|
+
"label":"<svg width='16' height='16'><path fill='currentColor' d='M19 13h-6'/></svg> 新建会话",
|
|
246
241
|
"value":"new",
|
|
247
242
|
"onClick":"method.setVal(''); method.clearData();"
|
|
248
243
|
}`;
|
|
249
244
|
|
|
250
|
-
|
|
245
|
+
const okJson2 = `{
|
|
246
|
+
label:"<svg width='16' height='16'><path fill='currentColor' d='M19 13h-6'/></svg> 新建会话",
|
|
247
|
+
value:"new",
|
|
248
|
+
onClick:"method.setVal(''); method.clearData();"
|
|
249
|
+
}`;
|
|
250
|
+
|
|
251
|
+
// ⚠️ Single quote JSON
|
|
251
252
|
const badJson = "{'model':'{model}','messages':[{'role':'user','content':'{message}'}],'stream': true}";
|
|
252
253
|
|
|
253
|
-
//
|
|
254
|
-
const badJson2 = "{\\\"label\\\":\\\"<svg width='16' height='16' viewBox='0 0 24 24'><path fill='currentColor' d='M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z'/></svg>
|
|
254
|
+
// ⚠️ Escaped JSON
|
|
255
|
+
const badJson2 = "{\\\"label\\\":\\\"<svg width='16' height='16' viewBox='0 0 24 24'><path fill='currentColor' d='M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z'/></svg> 新建会话\\\",\\\"value\\\":\\\"new\\\",\\\"onClick\\\":\\\"method.setVal(''); method.clearData();\\\"}";
|
|
256
|
+
|
|
257
|
+
const badJson3 = "{\"label\":\"<svg width='16' height='16' viewBox='0 0 24 24'><path fill='currentColor' d='M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z'/></svg> 新建会话\",\"value\":\"new\",\"onClick\":\"method.setVal(''); method.clearData();\"}";
|
|
258
|
+
|
|
259
|
+
const badJson4 = "[{\"label\":\"<svg fill='currentColor' width='12' height='12' viewBox='0 0 24 24'><path d='M20.5 9a3.49 3.49 0 0 0-3.45 3h-1.1a2.49 2.49 0 0 0-4.396-1.052L8.878 9.731l3.143-4.225a2.458 2.458 0 0 0 2.98-.019L17.339 8H16v1h3V6h-1v1.243l-2.336-2.512A2.473 2.473 0 0 0 16 3.5a2.5 2.5 0 0 0-5 0 2.474 2.474 0 0 0 .343 1.243L7.947 9.308 4.955 7.947a2.404 2.404 0 0 0-.161-1.438l3.704-1.385-.44 1.371.942.333L10 4 7.172 3l-.334.943 1.01.357-3.659 1.368a2.498 2.498 0 1 0-.682 4.117l2.085 2.688-2.053 2.76a2.5 2.5 0 1 0 .87 3.864l3.484 1.587-1.055.373.334.943L10 21l-1-2.828-.943.333.435 1.354-3.608-1.645A2.471 2.471 0 0 0 5 17.5a2.5 2.5 0 0 0-.058-.527l3.053-1.405 3.476 4.48a2.498 2.498 0 1 0 4.113.075L18 17.707V19h1v-3h-3v1h1.293l-2.416 2.416a2.466 2.466 0 0 0-2.667-.047l-3.283-4.23 2.554-1.176A2.494 2.494 0 0 0 15.95 13h1.1a3.493 3.493 0 1 0 3.45-4zm-7-7A1.5 1.5 0 1 1 12 3.5 1.502 1.502 0 0 1 13.5 2zm0 18a1.5 1.5 0 1 1-1.5 1.5 1.502 1.502 0 0 1 1.5-1.5zM1 7.5a1.5 1.5 0 1 1 2.457 1.145l-.144.112A1.496 1.496 0 0 1 1 7.5zm3.32 1.703a2.507 2.507 0 0 0 .264-.326l2.752 1.251-1.124 1.512zM2.5 19A1.5 1.5 0 1 1 4 17.5 1.502 1.502 0 0 1 2.5 19zm2.037-2.941a2.518 2.518 0 0 0-.193-.234l1.885-2.532 1.136 1.464zm3.76-1.731L6.849 12.46l1.42-1.908L11.1 11.84a2.29 2.29 0 0 0-.033 1.213zM13.5 14a1.5 1.5 0 1 1 1.5-1.5 1.502 1.502 0 0 1-1.5 1.5zm7 1a2.5 2.5 0 1 1 2.5-2.5 2.502 2.502 0 0 1-2.5 2.5zm1.5-2.5a1.5 1.5 0 1 1-1.5-1.5 1.502 1.502 0 0 1 1.5 1.5z'/><path fill='none' d='M0 0h24v24H0z'/></svg> 深度思考\",\"value\":\"brief\",\"onClick\":\"if(isActive){method.executeCustomMethod('changeModel', true)}else{method.executeCustomMethod('changeModel', false)}\"},{\"label\":\"<svg fill='currentColor' width='12' height='12' viewBox='0 0 24 24'><path d='M19 2H5c-1.103 0-2 .897-2 2v12c0 1.103.897 2 2 2h3.586L12 21.414 15.414 18H19c1.103 0 2-.897 2-2V4c0-1.103-.897-2-2-2zm0 14h-4.414L12 18.586 9.414 16H5V4h14v12z'/></svg> 精简回答\",\"value\":\"brief\",\"onClick\":\"if(isActive){method.setContextData({systemPrompt:'请精简回答,字数控制在150个字左右, 思考过程请简洁简短',mergedText:method.getContextData().mergedText,analyzeMetrics:method.getContextData().analyzeMetrics});}else{method.setContextData({mergedText:method.getContextData().mergedText,analyzeMetrics:method.getContextData().analyzeMetrics});}\"},{\"label\":\"<svg fill='none' width='12' height='12' viewBox='0 0 16 16'><path d='M7 0.0618896V9H15.9381C15.446 12.9463 12.0796 16 8 16C3.58172 16 0 12.4183 0 8C0 3.92038 3.05369 0.553988 7 0.0618896Z' fill='currentColor'/><path d='M9 0.0618897V7H15.9381C15.4869 3.38128 12.6187 0.513137 9 0.0618897Z' fill='currentColor'/></svg> 指标分析\",\"value\":\"lab\",\"onClick\":\"return method.executeCustomMethod('getLibList')\",\"isSelect\":true,\"dynamicOptions\":true}]";
|
|
260
|
+
|
|
261
|
+
|
|
262
|
+
// ❌ Invalid JSON with missing } or ]
|
|
263
|
+
const errorJson001 = "{'model':'qwen-plus','base_url':'https://dashscope.aliyuncs.com/compatible-mode/v1/','api_key':'sk-0989fb9baab8450682af4d000f5b7cba','message':'{message}','stream':'true','chatId': '{chatId}', 'token': '{token}'";
|
|
264
|
+
|
|
265
|
+
const errorJson002 = "[{'model':'qwen-plus','base_url':'https://dashscope.aliyuncs.com/compatible-mode/v1/','api_key':'sk-0989fb9baab8450682af4d000f5b7cba','message':'{message}','stream':'true','chatId': '{chatId}', 'token': '{token}'}";
|
|
255
266
|
|
|
256
|
-
|
|
267
|
+
// ❌ Invalid JSON with missing quotes
|
|
268
|
+
const errorJson003 = "{'model':'qwen-plus','base_url':'https://dashscope.aliyuncs.com/compatible-mode/v1/','api_key':'sk-0989fb9baab8450682af4d000f5b7cba','message':'{message}','stream':'true','chatId': {chatId}', 'token': '{token}'}";
|
|
257
269
|
|
|
258
|
-
const badJson4 = "[{\"label\":\"<svg fill='currentColor' width='12' height='12' viewBox='0 0 24 24'><path d='M20.5 9a3.49 3.49 0 0 0-3.45 3h-1.1a2.49 2.49 0 0 0-4.396-1.052L8.878 9.731l3.143-4.225a2.458 2.458 0 0 0 2.98-.019L17.339 8H16v1h3V6h-1v1.243l-2.336-2.512A2.473 2.473 0 0 0 16 3.5a2.5 2.5 0 0 0-5 0 2.474 2.474 0 0 0 .343 1.243L7.947 9.308 4.955 7.947a2.404 2.404 0 0 0-.161-1.438l3.704-1.385-.44 1.371.942.333L10 4 7.172 3l-.334.943 1.01.357-3.659 1.368a2.498 2.498 0 1 0-.682 4.117l2.085 2.688-2.053 2.76a2.5 2.5 0 1 0 .87 3.864l3.484 1.587-1.055.373.334.943L10 21l-1-2.828-.943.333.435 1.354-3.608-1.645A2.471 2.471 0 0 0 5 17.5a2.5 2.5 0 0 0-.058-.527l3.053-1.405 3.476 4.48a2.498 2.498 0 1 0 4.113.075L18 17.707V19h1v-3h-3v1h1.293l-2.416 2.416a2.466 2.466 0 0 0-2.667-.047l-3.283-4.23 2.554-1.176A2.494 2.494 0 0 0 15.95 13h1.1a3.493 3.493 0 1 0 3.45-4zm-7-7A1.5 1.5 0 1 1 12 3.5 1.502 1.502 0 0 1 13.5 2zm0 18a1.5 1.5 0 1 1-1.5 1.5 1.502 1.502 0 0 1 1.5-1.5zM1 7.5a1.5 1.5 0 1 1 2.457 1.145l-.144.112A1.496 1.496 0 0 1 1 7.5zm3.32 1.703a2.507 2.507 0 0 0 .264-.326l2.752 1.251-1.124 1.512zM2.5 19A1.5 1.5 0 1 1 4 17.5 1.502 1.502 0 0 1 2.5 19zm2.037-2.941a2.518 2.518 0 0 0-.193-.234l1.885-2.532 1.136 1.464zm3.76-1.731L6.849 12.46l1.42-1.908L11.1 11.84a2.29 2.29 0 0 0-.033 1.213zM13.5 14a1.5 1.5 0 1 1 1.5-1.5 1.502 1.502 0 0 1-1.5 1.5zm7 1a2.5 2.5 0 1 1 2.5-2.5 2.502 2.502 0 0 1-2.5 2.5zm1.5-2.5a1.5 1.5 0 1 1-1.5-1.5 1.502 1.502 0 0 1 1.5 1.5z'/><path fill='none' d='M0 0h24v24H0z'/></svg> Deep Thought","value":"brief","onClick":"if(isActive){method.executeCustomMethod('changeModel', true)}else{method.executeCustomMethod('changeModel', false)}"},{"label":"<svg fill='currentColor' width='12' height='12' viewBox='0 0 24 24'><path d='M19 2H5c-1.103 0-2 .897-2 2v12c0 1.103.897 2 2 2h3.586L12 21.414 15.414 18H19c1.103 0 2-.897 2-2V4c0-1.103-.897-2-2-2zm0 14h-4.414L12 18.586 9.414 16H5V4h14v12z'/></svg> Concise Answer","value":"brief","onClick":"if(isActive){method.setContextData({systemPrompt:'Please answer concisely, around 150 words, keep reasoning brief',mergedText:method.getContextData().mergedText,analyzeMetrics:method.getContextData().analyzeMetrics});}else{method.setContextData({mergedText:method.getContextData().mergedText,analyzeMetrics:method.getContextData().analyzeMetrics});}"},{"label":"<svg fill='none' width='12' height='12' viewBox='0 0 16 16'><path d='M7 0.0618896V9H15.9381C15.446 12.9463 12.0796 16 8 16C3.58172 16 0 12.4183 0 8C0 3.92038 3.05369 0.553988 7 0.0618896Z' fill='currentColor'/><path d='M9 0.0618897V7H15.9381C15.4869 3.38128 12.6187 0.513137 9 0.0618897Z' fill='currentColor'/></svg> Metrics Analysis","value":"lab","onClick":"return method.executeCustomMethod('getLibList')","isSelect":true,"dynamicOptions":true}]";
|
|
259
270
|
|
|
260
271
|
|
|
261
|
-
console.log('okJson =>', fixAndParseJSON(okJson));
|
|
262
|
-
console.log('
|
|
263
|
-
console.log('
|
|
264
|
-
console.log('
|
|
265
|
-
console.log('
|
|
272
|
+
console.log('okJson =>', fixAndParseJSON(okJson)); // Can parse normally success = true
|
|
273
|
+
console.log('okJson =>', fixAndParseJSON(okJson2)); // Can parse normally success = true
|
|
274
|
+
console.log('badJson =>', fixAndParseJSON(badJson)); // Can parse after fixing success = true
|
|
275
|
+
console.log('badJson =>', fixAndParseJSON(badJson2)); // Can parse after fixing success = true
|
|
276
|
+
console.log('badJson =>', fixAndParseJSON(badJson3)); // Can parse after fixing success = true
|
|
277
|
+
console.log('badJson =>', fixAndParseJSON(badJson4)); // Can parse after fixing success = true
|
|
278
|
+
console.log('errorJson =>', fixAndParseJSON(errorJson001)); // {success: false, error: 'Invalid JSON format', details: 'Invalid object: mismatched braces'}
|
|
279
|
+
console.log('errorJson =>', fixAndParseJSON(errorJson002)); // {success: false, error: 'Invalid JSON format', details: "Expected property name or '}' in JSON at position 2 (line 1 column 3)"}
|
|
280
|
+
console.log('errorJson =>', fixAndParseJSON(errorJson003)); // {success: false, error: 'Invalid JSON format', details: 'Invalid object: mismatched braces'}
|
|
281
|
+
|
|
266
282
|
*/
|
|
283
|
+
|
|
284
|
+
// Type definitions
|
|
285
|
+
|
|
267
286
|
function fixAndParseJSON(input) {
|
|
268
287
|
var MAX_DEPTH = 6;
|
|
269
288
|
|
|
270
|
-
// 1.
|
|
289
|
+
// 1. Quick attempt
|
|
271
290
|
try {
|
|
272
291
|
return {
|
|
273
292
|
success: true,
|
|
274
293
|
data: JSON.parse(input)
|
|
275
294
|
};
|
|
276
295
|
} catch (e) {
|
|
277
|
-
//
|
|
296
|
+
// Continue with fixing
|
|
278
297
|
}
|
|
279
298
|
|
|
280
|
-
// 2. Simple
|
|
299
|
+
// 2. Simple unescaping of escaped \" (common case from pasted JS literals)
|
|
281
300
|
var s = input;
|
|
282
301
|
if (s.includes('\\"')) s = s.replace(/\\"/g, '"');
|
|
283
302
|
s = s.trim();
|
|
@@ -294,24 +313,54 @@ function fixAndParseJSON(input) {
|
|
|
294
313
|
data: JSON.parse(s)
|
|
295
314
|
};
|
|
296
315
|
} catch (err) {
|
|
316
|
+
var error = err instanceof Error ? err : new Error('Unknown error');
|
|
297
317
|
return {
|
|
298
318
|
success: false,
|
|
299
319
|
error: 'Invalid JSON format',
|
|
300
|
-
details:
|
|
320
|
+
details: error.message
|
|
301
321
|
};
|
|
302
322
|
}
|
|
303
323
|
}
|
|
304
324
|
|
|
305
|
-
/* ---------- Helper (
|
|
325
|
+
/* ---------- Helper (Recursive) Functions ---------- */
|
|
306
326
|
|
|
307
327
|
function processTopObject(str, depth, MAX_DEPTH) {
|
|
308
328
|
if (depth > MAX_DEPTH) return str;
|
|
309
329
|
str = str.trim();
|
|
310
|
-
|
|
330
|
+
|
|
331
|
+
// First check if braces match
|
|
332
|
+
var braceCount = 0;
|
|
333
|
+
var inString = false;
|
|
334
|
+
var escapeNext = false;
|
|
335
|
+
for (var i = 0; i < str.length; i++) {
|
|
336
|
+
var ch = str[i];
|
|
337
|
+
if (escapeNext) {
|
|
338
|
+
escapeNext = false;
|
|
339
|
+
continue;
|
|
340
|
+
}
|
|
341
|
+
if (ch === '\\') {
|
|
342
|
+
escapeNext = true;
|
|
343
|
+
continue;
|
|
344
|
+
}
|
|
345
|
+
if ((ch === '"' || ch === "'") && !escapeNext) {
|
|
346
|
+
inString = !inString;
|
|
347
|
+
continue;
|
|
348
|
+
}
|
|
349
|
+
if (!inString) {
|
|
350
|
+
if (ch === '{') braceCount++;else if (ch === '}') braceCount--;
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
if (braceCount !== 0) {
|
|
354
|
+
throw new Error('Invalid object: mismatched braces');
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
// Ensure both ends are { ... }
|
|
311
358
|
if (!(str.startsWith('{') && str.endsWith('}'))) {
|
|
312
|
-
var f = str.indexOf('{')
|
|
313
|
-
|
|
314
|
-
if (f === -1 || l === -1 || l <= f)
|
|
359
|
+
var f = str.indexOf('{'),
|
|
360
|
+
l = str.lastIndexOf('}');
|
|
361
|
+
if (f === -1 || l === -1 || l <= f) {
|
|
362
|
+
throw new Error('Invalid object format: missing or mismatched braces');
|
|
363
|
+
}
|
|
315
364
|
str = str.slice(f, l + 1);
|
|
316
365
|
}
|
|
317
366
|
var inner = str.slice(1, -1);
|
|
@@ -336,8 +385,8 @@ function processTopArray(str, depth, MAX_DEPTH) {
|
|
|
336
385
|
if (depth > MAX_DEPTH) return str;
|
|
337
386
|
str = str.trim();
|
|
338
387
|
if (!(str.startsWith('[') && str.endsWith(']'))) {
|
|
339
|
-
var f = str.indexOf('[')
|
|
340
|
-
|
|
388
|
+
var f = str.indexOf('['),
|
|
389
|
+
l = str.lastIndexOf(']');
|
|
341
390
|
if (f === -1 || l === -1 || l <= f) return str;
|
|
342
391
|
str = str.slice(f, l + 1);
|
|
343
392
|
}
|
|
@@ -353,21 +402,21 @@ function processTopArray(str, depth, MAX_DEPTH) {
|
|
|
353
402
|
return '[' + processed.join(',') + ']';
|
|
354
403
|
}
|
|
355
404
|
|
|
356
|
-
// If
|
|
357
|
-
// If
|
|
358
|
-
// Otherwise return
|
|
405
|
+
// If it's a string wrapped in quotes, extract the inner content and JSON.stringify (safe escaping)
|
|
406
|
+
// If it's an object/array literal (not wrapped in quotes), recursively process (treat as new outermost layer)
|
|
407
|
+
// Otherwise return the original fragment directly (numbers/true/false/null or JS expressions)
|
|
359
408
|
function repairPossiblyQuotedValue(rawVal, depth, MAX_DEPTH) {
|
|
360
409
|
var v = rawVal.trim();
|
|
361
410
|
if (v === '') return v;
|
|
362
411
|
if (v[0] === '"' || v[0] === "'") {
|
|
363
412
|
var quote = v[0];
|
|
364
|
-
// Find the last unescaped
|
|
413
|
+
// Find the last unescaped same quote
|
|
365
414
|
var lastPos = -1;
|
|
366
415
|
for (var i = v.length - 1; i >= 0; i--) {
|
|
367
416
|
if (v[i] === quote) {
|
|
368
|
-
// check
|
|
369
|
-
var bs = 0
|
|
370
|
-
|
|
417
|
+
// check escaped
|
|
418
|
+
var bs = 0,
|
|
419
|
+
k = i - 1;
|
|
371
420
|
while (k >= 0 && v[k] === '\\') {
|
|
372
421
|
bs++;
|
|
373
422
|
k--;
|
|
@@ -379,10 +428,10 @@ function repairPossiblyQuotedValue(rawVal, depth, MAX_DEPTH) {
|
|
|
379
428
|
}
|
|
380
429
|
}
|
|
381
430
|
var inner = lastPos > 0 ? v.slice(1, lastPos) : v.slice(1);
|
|
382
|
-
return JSON.stringify(inner); //
|
|
431
|
+
return JSON.stringify(inner); // Use JSON.stringify to generate valid JSON string (automatically escape internal quotes, etc.)
|
|
383
432
|
}
|
|
384
433
|
|
|
385
|
-
// If
|
|
434
|
+
// If it's an object or array literal (not wrapped in quotes) -> recursively treat as new outermost layer
|
|
386
435
|
if (v.startsWith('{')) {
|
|
387
436
|
return processTopObject(v, depth, MAX_DEPTH);
|
|
388
437
|
}
|
|
@@ -390,22 +439,22 @@ function repairPossiblyQuotedValue(rawVal, depth, MAX_DEPTH) {
|
|
|
390
439
|
return processTopArray(v, depth, MAX_DEPTH);
|
|
391
440
|
}
|
|
392
441
|
|
|
393
|
-
//
|
|
442
|
+
// Others (numbers, boolean, null, or JS expressions): return as-is
|
|
394
443
|
return v;
|
|
395
444
|
}
|
|
396
445
|
|
|
397
|
-
/* ---------
|
|
446
|
+
/* --------- Utilities: Split by top-level commas, find top-level colon, extract key --------- */
|
|
398
447
|
|
|
399
|
-
// Split
|
|
448
|
+
// Split by top-level commas (ignore strings, sub-objects, sub-arrays, commas inside parentheses)
|
|
400
449
|
function splitTopLevel(str) {
|
|
401
450
|
var parts = [];
|
|
402
451
|
var buf = '';
|
|
403
|
-
var depthCurly = 0
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
var inSingle = false
|
|
407
|
-
|
|
408
|
-
|
|
452
|
+
var depthCurly = 0,
|
|
453
|
+
depthSquare = 0,
|
|
454
|
+
depthParen = 0;
|
|
455
|
+
var inSingle = false,
|
|
456
|
+
inDouble = false,
|
|
457
|
+
esc = false;
|
|
409
458
|
for (var i = 0; i < str.length; i++) {
|
|
410
459
|
var ch = str[i];
|
|
411
460
|
if (esc) {
|
|
@@ -467,18 +516,23 @@ function splitTopLevel(str) {
|
|
|
467
516
|
}
|
|
468
517
|
buf += ch;
|
|
469
518
|
}
|
|
519
|
+
|
|
520
|
+
// Check for unclosed brackets or quotes
|
|
521
|
+
if (depthCurly !== 0 || depthSquare !== 0 || depthParen !== 0 || inSingle || inDouble) {
|
|
522
|
+
throw new Error('Invalid JSON: unclosed brackets or quotes');
|
|
523
|
+
}
|
|
470
524
|
if (buf.trim() !== '') parts.push(buf);
|
|
471
525
|
return parts;
|
|
472
526
|
}
|
|
473
527
|
|
|
474
|
-
// Find the first top-level colon (
|
|
528
|
+
// Find the first "top-level" colon index (ignore inside strings & sub-levels)
|
|
475
529
|
function findTopLevelColon(str) {
|
|
476
|
-
var inSingle = false
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
var depthCurly = 0
|
|
480
|
-
|
|
481
|
-
|
|
530
|
+
var inSingle = false,
|
|
531
|
+
inDouble = false,
|
|
532
|
+
esc = false;
|
|
533
|
+
var depthCurly = 0,
|
|
534
|
+
depthSquare = 0,
|
|
535
|
+
depthParen = 0;
|
|
482
536
|
for (var i = 0; i < str.length; i++) {
|
|
483
537
|
var ch = str[i];
|
|
484
538
|
if (esc) {
|
|
@@ -530,7 +584,7 @@ function findTopLevelColon(str) {
|
|
|
530
584
|
return -1;
|
|
531
585
|
}
|
|
532
586
|
|
|
533
|
-
// Extract key content (supports "key", 'key', key)
|
|
587
|
+
// Extract key content (supports "key", 'key', key), returns pure key string
|
|
534
588
|
function extractKeyContent(rawKey) {
|
|
535
589
|
var r = rawKey.trim();
|
|
536
590
|
if (r.startsWith('"') && r.endsWith('"') || r.startsWith("'") && r.endsWith("'")) {
|
|
@@ -19,67 +19,86 @@ return /******/ (() => { // webpackBootstrap
|
|
|
19
19
|
/* harmony export */ "isJSON": () => (/* binding */ isJSON),
|
|
20
20
|
/* harmony export */ "isValidNumeric": () => (/* binding */ isValidNumeric)
|
|
21
21
|
/* harmony export */ });
|
|
22
|
-
/* unused harmony exports
|
|
22
|
+
/* unused harmony exports isEmpty, isNumber, isInt, isEmail, isTel, isMobile */
|
|
23
23
|
function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); }
|
|
24
24
|
/**
|
|
25
25
|
* Fix And Parse JSON (Support for handling complex escape JSON strings)
|
|
26
|
+
* @desc recursively fix top-level key/value (recursively handles when encountering top-level values that are objects/arrays)
|
|
26
27
|
* @private
|
|
27
28
|
*/
|
|
28
29
|
/*
|
|
29
|
-
-
|
|
30
|
-
-
|
|
31
|
-
- Then process the outermost object or array key
|
|
32
|
-
- If a top-level value is an unquoted object or array (e.g
|
|
33
|
-
|
|
34
|
-
- For values wrapped in quotes ('...' or "..."), extract the inner text and
|
|
35
|
-
re-encode it using JSON.stringify (ensures internal single/double quotes
|
|
36
|
-
are not corrupted);
|
|
30
|
+
- Still prioritize JSON.parse first;
|
|
31
|
+
- After parse fails, do unescaping (\\" → ");
|
|
32
|
+
- Then process the outermost layer (object or array) key by key, value by value;
|
|
33
|
+
- If a top-level value is an unquoted object or array (e.g., messages: [ {...} ]), recursively treat that value as a new outermost layer for fixing;
|
|
34
|
+
- For strings wrapped in quotes ('...' or "..."), only extract the outer layer and re-encode with JSON.stringify (ensuring internal single/double quotes won't be mistakenly changed);
|
|
37
35
|
- Set MAX_DEPTH to prevent infinite recursion.
|
|
38
36
|
*/
|
|
39
|
-
// fixAndParseJSON - recursively repairs top-level key/value
|
|
40
|
-
// (when encountering outermost values that are objects/arrays, it recurses)
|
|
41
|
-
|
|
42
37
|
/*
|
|
43
|
-
|
|
38
|
+
@Examples:
|
|
44
39
|
|
|
45
|
-
// ✅ Valid JSON (contains svg and single
|
|
40
|
+
// ✅ Valid JSON (contains svg and single quote content)
|
|
46
41
|
const okJson = `{
|
|
47
|
-
"label":"<svg width='16' height='16'><path fill='currentColor' d='M19 13h-6'/></svg>
|
|
42
|
+
"label":"<svg width='16' height='16'><path fill='currentColor' d='M19 13h-6'/></svg> 新建会话",
|
|
48
43
|
"value":"new",
|
|
49
44
|
"onClick":"method.setVal(''); method.clearData();"
|
|
50
45
|
}`;
|
|
51
46
|
|
|
52
|
-
|
|
47
|
+
const okJson2 = `{
|
|
48
|
+
label:"<svg width='16' height='16'><path fill='currentColor' d='M19 13h-6'/></svg> 新建会话",
|
|
49
|
+
value:"new",
|
|
50
|
+
onClick:"method.setVal(''); method.clearData();"
|
|
51
|
+
}`;
|
|
52
|
+
|
|
53
|
+
// ⚠️ Single quote JSON
|
|
53
54
|
const badJson = "{'model':'{model}','messages':[{'role':'user','content':'{message}'}],'stream': true}";
|
|
54
55
|
|
|
55
|
-
//
|
|
56
|
-
const badJson2 = "{\\\"label\\\":\\\"<svg width='16' height='16' viewBox='0 0 24 24'><path fill='currentColor' d='M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z'/></svg>
|
|
56
|
+
// ⚠️ Escaped JSON
|
|
57
|
+
const badJson2 = "{\\\"label\\\":\\\"<svg width='16' height='16' viewBox='0 0 24 24'><path fill='currentColor' d='M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z'/></svg> 新建会话\\\",\\\"value\\\":\\\"new\\\",\\\"onClick\\\":\\\"method.setVal(''); method.clearData();\\\"}";
|
|
58
|
+
|
|
59
|
+
const badJson3 = "{\"label\":\"<svg width='16' height='16' viewBox='0 0 24 24'><path fill='currentColor' d='M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z'/></svg> 新建会话\",\"value\":\"new\",\"onClick\":\"method.setVal(''); method.clearData();\"}";
|
|
60
|
+
|
|
61
|
+
const badJson4 = "[{\"label\":\"<svg fill='currentColor' width='12' height='12' viewBox='0 0 24 24'><path d='M20.5 9a3.49 3.49 0 0 0-3.45 3h-1.1a2.49 2.49 0 0 0-4.396-1.052L8.878 9.731l3.143-4.225a2.458 2.458 0 0 0 2.98-.019L17.339 8H16v1h3V6h-1v1.243l-2.336-2.512A2.473 2.473 0 0 0 16 3.5a2.5 2.5 0 0 0-5 0 2.474 2.474 0 0 0 .343 1.243L7.947 9.308 4.955 7.947a2.404 2.404 0 0 0-.161-1.438l3.704-1.385-.44 1.371.942.333L10 4 7.172 3l-.334.943 1.01.357-3.659 1.368a2.498 2.498 0 1 0-.682 4.117l2.085 2.688-2.053 2.76a2.5 2.5 0 1 0 .87 3.864l3.484 1.587-1.055.373.334.943L10 21l-1-2.828-.943.333.435 1.354-3.608-1.645A2.471 2.471 0 0 0 5 17.5a2.5 2.5 0 0 0-.058-.527l3.053-1.405 3.476 4.48a2.498 2.498 0 1 0 4.113.075L18 17.707V19h1v-3h-3v1h1.293l-2.416 2.416a2.466 2.466 0 0 0-2.667-.047l-3.283-4.23 2.554-1.176A2.494 2.494 0 0 0 15.95 13h1.1a3.493 3.493 0 1 0 3.45-4zm-7-7A1.5 1.5 0 1 1 12 3.5 1.502 1.502 0 0 1 13.5 2zm0 18a1.5 1.5 0 1 1-1.5 1.5 1.502 1.502 0 0 1 1.5-1.5zM1 7.5a1.5 1.5 0 1 1 2.457 1.145l-.144.112A1.496 1.496 0 0 1 1 7.5zm3.32 1.703a2.507 2.507 0 0 0 .264-.326l2.752 1.251-1.124 1.512zM2.5 19A1.5 1.5 0 1 1 4 17.5 1.502 1.502 0 0 1 2.5 19zm2.037-2.941a2.518 2.518 0 0 0-.193-.234l1.885-2.532 1.136 1.464zm3.76-1.731L6.849 12.46l1.42-1.908L11.1 11.84a2.29 2.29 0 0 0-.033 1.213zM13.5 14a1.5 1.5 0 1 1 1.5-1.5 1.502 1.502 0 0 1-1.5 1.5zm7 1a2.5 2.5 0 1 1 2.5-2.5 2.502 2.502 0 0 1-2.5 2.5zm1.5-2.5a1.5 1.5 0 1 1-1.5-1.5 1.502 1.502 0 0 1 1.5 1.5z'/><path fill='none' d='M0 0h24v24H0z'/></svg> 深度思考\",\"value\":\"brief\",\"onClick\":\"if(isActive){method.executeCustomMethod('changeModel', true)}else{method.executeCustomMethod('changeModel', false)}\"},{\"label\":\"<svg fill='currentColor' width='12' height='12' viewBox='0 0 24 24'><path d='M19 2H5c-1.103 0-2 .897-2 2v12c0 1.103.897 2 2 2h3.586L12 21.414 15.414 18H19c1.103 0 2-.897 2-2V4c0-1.103-.897-2-2-2zm0 14h-4.414L12 18.586 9.414 16H5V4h14v12z'/></svg> 精简回答\",\"value\":\"brief\",\"onClick\":\"if(isActive){method.setContextData({systemPrompt:'请精简回答,字数控制在150个字左右, 思考过程请简洁简短',mergedText:method.getContextData().mergedText,analyzeMetrics:method.getContextData().analyzeMetrics});}else{method.setContextData({mergedText:method.getContextData().mergedText,analyzeMetrics:method.getContextData().analyzeMetrics});}\"},{\"label\":\"<svg fill='none' width='12' height='12' viewBox='0 0 16 16'><path d='M7 0.0618896V9H15.9381C15.446 12.9463 12.0796 16 8 16C3.58172 16 0 12.4183 0 8C0 3.92038 3.05369 0.553988 7 0.0618896Z' fill='currentColor'/><path d='M9 0.0618897V7H15.9381C15.4869 3.38128 12.6187 0.513137 9 0.0618897Z' fill='currentColor'/></svg> 指标分析\",\"value\":\"lab\",\"onClick\":\"return method.executeCustomMethod('getLibList')\",\"isSelect\":true,\"dynamicOptions\":true}]";
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
// ❌ Invalid JSON with missing } or ]
|
|
65
|
+
const errorJson001 = "{'model':'qwen-plus','base_url':'https://dashscope.aliyuncs.com/compatible-mode/v1/','api_key':'sk-0989fb9baab8450682af4d000f5b7cba','message':'{message}','stream':'true','chatId': '{chatId}', 'token': '{token}'";
|
|
66
|
+
|
|
67
|
+
const errorJson002 = "[{'model':'qwen-plus','base_url':'https://dashscope.aliyuncs.com/compatible-mode/v1/','api_key':'sk-0989fb9baab8450682af4d000f5b7cba','message':'{message}','stream':'true','chatId': '{chatId}', 'token': '{token}'}";
|
|
57
68
|
|
|
58
|
-
|
|
69
|
+
// ❌ Invalid JSON with missing quotes
|
|
70
|
+
const errorJson003 = "{'model':'qwen-plus','base_url':'https://dashscope.aliyuncs.com/compatible-mode/v1/','api_key':'sk-0989fb9baab8450682af4d000f5b7cba','message':'{message}','stream':'true','chatId': {chatId}', 'token': '{token}'}";
|
|
59
71
|
|
|
60
|
-
const badJson4 = "[{\"label\":\"<svg fill='currentColor' width='12' height='12' viewBox='0 0 24 24'><path d='M20.5 9a3.49 3.49 0 0 0-3.45 3h-1.1a2.49 2.49 0 0 0-4.396-1.052L8.878 9.731l3.143-4.225a2.458 2.458 0 0 0 2.98-.019L17.339 8H16v1h3V6h-1v1.243l-2.336-2.512A2.473 2.473 0 0 0 16 3.5a2.5 2.5 0 0 0-5 0 2.474 2.474 0 0 0 .343 1.243L7.947 9.308 4.955 7.947a2.404 2.404 0 0 0-.161-1.438l3.704-1.385-.44 1.371.942.333L10 4 7.172 3l-.334.943 1.01.357-3.659 1.368a2.498 2.498 0 1 0-.682 4.117l2.085 2.688-2.053 2.76a2.5 2.5 0 1 0 .87 3.864l3.484 1.587-1.055.373.334.943L10 21l-1-2.828-.943.333.435 1.354-3.608-1.645A2.471 2.471 0 0 0 5 17.5a2.5 2.5 0 0 0-.058-.527l3.053-1.405 3.476 4.48a2.498 2.498 0 1 0 4.113.075L18 17.707V19h1v-3h-3v1h1.293l-2.416 2.416a2.466 2.466 0 0 0-2.667-.047l-3.283-4.23 2.554-1.176A2.494 2.494 0 0 0 15.95 13h1.1a3.493 3.493 0 1 0 3.45-4zm-7-7A1.5 1.5 0 1 1 12 3.5 1.502 1.502 0 0 1 13.5 2zm0 18a1.5 1.5 0 1 1-1.5 1.5 1.502 1.502 0 0 1 1.5-1.5zM1 7.5a1.5 1.5 0 1 1 2.457 1.145l-.144.112A1.496 1.496 0 0 1 1 7.5zm3.32 1.703a2.507 2.507 0 0 0 .264-.326l2.752 1.251-1.124 1.512zM2.5 19A1.5 1.5 0 1 1 4 17.5 1.502 1.502 0 0 1 2.5 19zm2.037-2.941a2.518 2.518 0 0 0-.193-.234l1.885-2.532 1.136 1.464zm3.76-1.731L6.849 12.46l1.42-1.908L11.1 11.84a2.29 2.29 0 0 0-.033 1.213zM13.5 14a1.5 1.5 0 1 1 1.5-1.5 1.502 1.502 0 0 1-1.5 1.5zm7 1a2.5 2.5 0 1 1 2.5-2.5 2.502 2.502 0 0 1-2.5 2.5zm1.5-2.5a1.5 1.5 0 1 1-1.5-1.5 1.502 1.502 0 0 1 1.5 1.5z'/><path fill='none' d='M0 0h24v24H0z'/></svg> Deep Thought","value":"brief","onClick":"if(isActive){method.executeCustomMethod('changeModel', true)}else{method.executeCustomMethod('changeModel', false)}"},{"label":"<svg fill='currentColor' width='12' height='12' viewBox='0 0 24 24'><path d='M19 2H5c-1.103 0-2 .897-2 2v12c0 1.103.897 2 2 2h3.586L12 21.414 15.414 18H19c1.103 0 2-.897 2-2V4c0-1.103-.897-2-2-2zm0 14h-4.414L12 18.586 9.414 16H5V4h14v12z'/></svg> Concise Answer","value":"brief","onClick":"if(isActive){method.setContextData({systemPrompt:'Please answer concisely, around 150 words, keep reasoning brief',mergedText:method.getContextData().mergedText,analyzeMetrics:method.getContextData().analyzeMetrics});}else{method.setContextData({mergedText:method.getContextData().mergedText,analyzeMetrics:method.getContextData().analyzeMetrics});}"},{"label":"<svg fill='none' width='12' height='12' viewBox='0 0 16 16'><path d='M7 0.0618896V9H15.9381C15.446 12.9463 12.0796 16 8 16C3.58172 16 0 12.4183 0 8C0 3.92038 3.05369 0.553988 7 0.0618896Z' fill='currentColor'/><path d='M9 0.0618897V7H15.9381C15.4869 3.38128 12.6187 0.513137 9 0.0618897Z' fill='currentColor'/></svg> Metrics Analysis","value":"lab","onClick":"return method.executeCustomMethod('getLibList')","isSelect":true,"dynamicOptions":true}]";
|
|
61
72
|
|
|
62
73
|
|
|
63
|
-
console.log('okJson =>', fixAndParseJSON(okJson));
|
|
64
|
-
console.log('
|
|
65
|
-
console.log('
|
|
66
|
-
console.log('
|
|
67
|
-
console.log('
|
|
74
|
+
console.log('okJson =>', fixAndParseJSON(okJson)); // Can parse normally success = true
|
|
75
|
+
console.log('okJson =>', fixAndParseJSON(okJson2)); // Can parse normally success = true
|
|
76
|
+
console.log('badJson =>', fixAndParseJSON(badJson)); // Can parse after fixing success = true
|
|
77
|
+
console.log('badJson =>', fixAndParseJSON(badJson2)); // Can parse after fixing success = true
|
|
78
|
+
console.log('badJson =>', fixAndParseJSON(badJson3)); // Can parse after fixing success = true
|
|
79
|
+
console.log('badJson =>', fixAndParseJSON(badJson4)); // Can parse after fixing success = true
|
|
80
|
+
console.log('errorJson =>', fixAndParseJSON(errorJson001)); // {success: false, error: 'Invalid JSON format', details: 'Invalid object: mismatched braces'}
|
|
81
|
+
console.log('errorJson =>', fixAndParseJSON(errorJson002)); // {success: false, error: 'Invalid JSON format', details: "Expected property name or '}' in JSON at position 2 (line 1 column 3)"}
|
|
82
|
+
console.log('errorJson =>', fixAndParseJSON(errorJson003)); // {success: false, error: 'Invalid JSON format', details: 'Invalid object: mismatched braces'}
|
|
83
|
+
|
|
68
84
|
*/
|
|
85
|
+
|
|
86
|
+
// Type definitions
|
|
87
|
+
|
|
69
88
|
function fixAndParseJSON(input) {
|
|
70
89
|
var MAX_DEPTH = 6;
|
|
71
90
|
|
|
72
|
-
// 1.
|
|
91
|
+
// 1. Quick attempt
|
|
73
92
|
try {
|
|
74
93
|
return {
|
|
75
94
|
success: true,
|
|
76
95
|
data: JSON.parse(input)
|
|
77
96
|
};
|
|
78
97
|
} catch (e) {
|
|
79
|
-
//
|
|
98
|
+
// Continue with fixing
|
|
80
99
|
}
|
|
81
100
|
|
|
82
|
-
// 2. Simple
|
|
101
|
+
// 2. Simple unescaping of escaped \" (common case from pasted JS literals)
|
|
83
102
|
var s = input;
|
|
84
103
|
if (s.includes('\\"')) s = s.replace(/\\"/g, '"');
|
|
85
104
|
s = s.trim();
|
|
@@ -96,24 +115,54 @@ function fixAndParseJSON(input) {
|
|
|
96
115
|
data: JSON.parse(s)
|
|
97
116
|
};
|
|
98
117
|
} catch (err) {
|
|
118
|
+
var error = err instanceof Error ? err : new Error('Unknown error');
|
|
99
119
|
return {
|
|
100
120
|
success: false,
|
|
101
121
|
error: 'Invalid JSON format',
|
|
102
|
-
details:
|
|
122
|
+
details: error.message
|
|
103
123
|
};
|
|
104
124
|
}
|
|
105
125
|
}
|
|
106
126
|
|
|
107
|
-
/* ---------- Helper (
|
|
127
|
+
/* ---------- Helper (Recursive) Functions ---------- */
|
|
108
128
|
|
|
109
129
|
function processTopObject(str, depth, MAX_DEPTH) {
|
|
110
130
|
if (depth > MAX_DEPTH) return str;
|
|
111
131
|
str = str.trim();
|
|
112
|
-
|
|
132
|
+
|
|
133
|
+
// First check if braces match
|
|
134
|
+
var braceCount = 0;
|
|
135
|
+
var inString = false;
|
|
136
|
+
var escapeNext = false;
|
|
137
|
+
for (var i = 0; i < str.length; i++) {
|
|
138
|
+
var ch = str[i];
|
|
139
|
+
if (escapeNext) {
|
|
140
|
+
escapeNext = false;
|
|
141
|
+
continue;
|
|
142
|
+
}
|
|
143
|
+
if (ch === '\\') {
|
|
144
|
+
escapeNext = true;
|
|
145
|
+
continue;
|
|
146
|
+
}
|
|
147
|
+
if ((ch === '"' || ch === "'") && !escapeNext) {
|
|
148
|
+
inString = !inString;
|
|
149
|
+
continue;
|
|
150
|
+
}
|
|
151
|
+
if (!inString) {
|
|
152
|
+
if (ch === '{') braceCount++;else if (ch === '}') braceCount--;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
if (braceCount !== 0) {
|
|
156
|
+
throw new Error('Invalid object: mismatched braces');
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
// Ensure both ends are { ... }
|
|
113
160
|
if (!(str.startsWith('{') && str.endsWith('}'))) {
|
|
114
|
-
var f = str.indexOf('{')
|
|
115
|
-
|
|
116
|
-
if (f === -1 || l === -1 || l <= f)
|
|
161
|
+
var f = str.indexOf('{'),
|
|
162
|
+
l = str.lastIndexOf('}');
|
|
163
|
+
if (f === -1 || l === -1 || l <= f) {
|
|
164
|
+
throw new Error('Invalid object format: missing or mismatched braces');
|
|
165
|
+
}
|
|
117
166
|
str = str.slice(f, l + 1);
|
|
118
167
|
}
|
|
119
168
|
var inner = str.slice(1, -1);
|
|
@@ -138,8 +187,8 @@ function processTopArray(str, depth, MAX_DEPTH) {
|
|
|
138
187
|
if (depth > MAX_DEPTH) return str;
|
|
139
188
|
str = str.trim();
|
|
140
189
|
if (!(str.startsWith('[') && str.endsWith(']'))) {
|
|
141
|
-
var f = str.indexOf('[')
|
|
142
|
-
|
|
190
|
+
var f = str.indexOf('['),
|
|
191
|
+
l = str.lastIndexOf(']');
|
|
143
192
|
if (f === -1 || l === -1 || l <= f) return str;
|
|
144
193
|
str = str.slice(f, l + 1);
|
|
145
194
|
}
|
|
@@ -155,21 +204,21 @@ function processTopArray(str, depth, MAX_DEPTH) {
|
|
|
155
204
|
return '[' + processed.join(',') + ']';
|
|
156
205
|
}
|
|
157
206
|
|
|
158
|
-
// If
|
|
159
|
-
// If
|
|
160
|
-
// Otherwise return
|
|
207
|
+
// If it's a string wrapped in quotes, extract the inner content and JSON.stringify (safe escaping)
|
|
208
|
+
// If it's an object/array literal (not wrapped in quotes), recursively process (treat as new outermost layer)
|
|
209
|
+
// Otherwise return the original fragment directly (numbers/true/false/null or JS expressions)
|
|
161
210
|
function repairPossiblyQuotedValue(rawVal, depth, MAX_DEPTH) {
|
|
162
211
|
var v = rawVal.trim();
|
|
163
212
|
if (v === '') return v;
|
|
164
213
|
if (v[0] === '"' || v[0] === "'") {
|
|
165
214
|
var quote = v[0];
|
|
166
|
-
// Find the last unescaped
|
|
215
|
+
// Find the last unescaped same quote
|
|
167
216
|
var lastPos = -1;
|
|
168
217
|
for (var i = v.length - 1; i >= 0; i--) {
|
|
169
218
|
if (v[i] === quote) {
|
|
170
|
-
// check
|
|
171
|
-
var bs = 0
|
|
172
|
-
|
|
219
|
+
// check escaped
|
|
220
|
+
var bs = 0,
|
|
221
|
+
k = i - 1;
|
|
173
222
|
while (k >= 0 && v[k] === '\\') {
|
|
174
223
|
bs++;
|
|
175
224
|
k--;
|
|
@@ -181,10 +230,10 @@ function repairPossiblyQuotedValue(rawVal, depth, MAX_DEPTH) {
|
|
|
181
230
|
}
|
|
182
231
|
}
|
|
183
232
|
var inner = lastPos > 0 ? v.slice(1, lastPos) : v.slice(1);
|
|
184
|
-
return JSON.stringify(inner); //
|
|
233
|
+
return JSON.stringify(inner); // Use JSON.stringify to generate valid JSON string (automatically escape internal quotes, etc.)
|
|
185
234
|
}
|
|
186
235
|
|
|
187
|
-
// If
|
|
236
|
+
// If it's an object or array literal (not wrapped in quotes) -> recursively treat as new outermost layer
|
|
188
237
|
if (v.startsWith('{')) {
|
|
189
238
|
return processTopObject(v, depth, MAX_DEPTH);
|
|
190
239
|
}
|
|
@@ -192,22 +241,22 @@ function repairPossiblyQuotedValue(rawVal, depth, MAX_DEPTH) {
|
|
|
192
241
|
return processTopArray(v, depth, MAX_DEPTH);
|
|
193
242
|
}
|
|
194
243
|
|
|
195
|
-
//
|
|
244
|
+
// Others (numbers, boolean, null, or JS expressions): return as-is
|
|
196
245
|
return v;
|
|
197
246
|
}
|
|
198
247
|
|
|
199
|
-
/* ---------
|
|
248
|
+
/* --------- Utilities: Split by top-level commas, find top-level colon, extract key --------- */
|
|
200
249
|
|
|
201
|
-
// Split
|
|
250
|
+
// Split by top-level commas (ignore strings, sub-objects, sub-arrays, commas inside parentheses)
|
|
202
251
|
function splitTopLevel(str) {
|
|
203
252
|
var parts = [];
|
|
204
253
|
var buf = '';
|
|
205
|
-
var depthCurly = 0
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
var inSingle = false
|
|
209
|
-
|
|
210
|
-
|
|
254
|
+
var depthCurly = 0,
|
|
255
|
+
depthSquare = 0,
|
|
256
|
+
depthParen = 0;
|
|
257
|
+
var inSingle = false,
|
|
258
|
+
inDouble = false,
|
|
259
|
+
esc = false;
|
|
211
260
|
for (var i = 0; i < str.length; i++) {
|
|
212
261
|
var ch = str[i];
|
|
213
262
|
if (esc) {
|
|
@@ -269,18 +318,23 @@ function splitTopLevel(str) {
|
|
|
269
318
|
}
|
|
270
319
|
buf += ch;
|
|
271
320
|
}
|
|
321
|
+
|
|
322
|
+
// Check for unclosed brackets or quotes
|
|
323
|
+
if (depthCurly !== 0 || depthSquare !== 0 || depthParen !== 0 || inSingle || inDouble) {
|
|
324
|
+
throw new Error('Invalid JSON: unclosed brackets or quotes');
|
|
325
|
+
}
|
|
272
326
|
if (buf.trim() !== '') parts.push(buf);
|
|
273
327
|
return parts;
|
|
274
328
|
}
|
|
275
329
|
|
|
276
|
-
// Find the first top-level colon (
|
|
330
|
+
// Find the first "top-level" colon index (ignore inside strings & sub-levels)
|
|
277
331
|
function findTopLevelColon(str) {
|
|
278
|
-
var inSingle = false
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
var depthCurly = 0
|
|
282
|
-
|
|
283
|
-
|
|
332
|
+
var inSingle = false,
|
|
333
|
+
inDouble = false,
|
|
334
|
+
esc = false;
|
|
335
|
+
var depthCurly = 0,
|
|
336
|
+
depthSquare = 0,
|
|
337
|
+
depthParen = 0;
|
|
284
338
|
for (var i = 0; i < str.length; i++) {
|
|
285
339
|
var ch = str[i];
|
|
286
340
|
if (esc) {
|
|
@@ -332,7 +386,7 @@ function findTopLevelColon(str) {
|
|
|
332
386
|
return -1;
|
|
333
387
|
}
|
|
334
388
|
|
|
335
|
-
// Extract key content (supports "key", 'key', key)
|
|
389
|
+
// Extract key content (supports "key", 'key', key), returns pure key string
|
|
336
390
|
function extractKeyContent(rawKey) {
|
|
337
391
|
var r = rawKey.trim();
|
|
338
392
|
if (r.startsWith('"') && r.endsWith('"') || r.startsWith("'") && r.endsWith("'")) {
|
|
@@ -1,14 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Fix And Parse JSON (Support for handling complex escape JSON strings)
|
|
3
|
+
* @desc recursively fix top-level key/value (recursively handles when encountering top-level values that are objects/arrays)
|
|
3
4
|
* @private
|
|
4
5
|
*/
|
|
5
|
-
interface ParseResult {
|
|
6
|
-
success: boolean;
|
|
7
|
-
data?: any;
|
|
8
|
-
error?: string;
|
|
9
|
-
details?: string;
|
|
10
|
-
}
|
|
11
|
-
export declare function fixAndParseJSON(input: string): ParseResult;
|
|
12
6
|
/**
|
|
13
7
|
* Determine whether it is in JSON format
|
|
14
8
|
* @private
|