@antscorp/antsomi-ui 1.3.5-beta.810 → 1.3.5-beta.811

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.
@@ -6,6 +6,17 @@ import { iconsViber } from './iconsViber';
6
6
  import { globalToken } from '@antscorp/antsomi-ui/es/constants';
7
7
  // Utils
8
8
  import { acceptablePatternChecking, getCachedRegex, patternHandlers, tagRegexStringPattern, } from './patternHandlers';
9
+ /*
10
+ * Custom error type for JSON parse errors
11
+ */
12
+ class JsonParseError extends Error {
13
+ constructor(message, originalError, partialResult) {
14
+ super(message);
15
+ this.originalError = originalError;
16
+ this.partialResult = partialResult;
17
+ this.name = 'JsonParseError';
18
+ }
19
+ }
9
20
  /**
10
21
  * Parses the input string and replaces matching patterns with processed tags.
11
22
  * This function iterates over predefined regex patterns and replaces each match
@@ -82,31 +93,65 @@ function isValidTag(tag) {
82
93
  return tag && typeof tag === 'object' && 'label' in tag && 'value' in tag;
83
94
  }
84
95
  /**
85
- * Sanitizes the JSON string by replacing single quotes with double quotes.
86
- * @param jsonString The JSON string to sanitize.
87
- * @returns The sanitized JSON string.
88
- */
89
- function sanitizeJsonString(jsonString) {
90
- return jsonString.replace(/'/g, '"');
91
- }
92
- /**
93
- * Parses the sanitized JSON string into an object.
94
- * @param jsonString The sanitized JSON string.
95
- * @returns The parsed object or null if invalid.
96
+ * Attempts to parse a JSON string with robust error handling
97
+ * @param jsonString The JSON string to parse
98
+ * @param options Configuration options
99
+ * @returns Parsed JSON object or null if parsing fails and throwOnError is false
100
+ * @throws JsonParseError if parsing fails and throwOnError is true
96
101
  */
97
- function parseTag(jsonString) {
98
- try {
99
- const parsed = JSON.parse(jsonString);
100
- if (isValidTag(parsed)) {
101
- return parsed;
102
+ function robustJsonParse(jsonString, options = {}) {
103
+ const { sanitize = true, throwOnError = false, allowPartialParse = false } = options;
104
+ let sanitizedString = jsonString;
105
+ // Helper function to sanitize the JSON string
106
+ const sanitizeJson = (str) => str
107
+ .replace(/'/g, '"') // Replace single quotes with double quotes
108
+ .replace(/([{,]\s*)(\w+)(\s*:)/g, '$1"$2"$3') // Add quotes to unquoted keys
109
+ .replace(/,\s*([\]}])/g, '$1') // Remove trailing commas
110
+ .replace(/\\'/g, "'") // Unescape single quotes within strings
111
+ .trim(); // Trim whitespace
112
+ const tryParse = (str) => {
113
+ try {
114
+ return { result: JSON.parse(str), error: null };
115
+ }
116
+ catch (e) {
117
+ return { result: null, error: e };
102
118
  }
119
+ };
120
+ // First, try parsing the string as-is
121
+ let parseResult = tryParse(jsonString);
122
+ if (!parseResult.error) {
123
+ return parseResult.result;
103
124
  }
104
- catch (error) {
125
+ // If sanitize option is true, try sanitizing and parsing again
126
+ if (sanitize) {
127
+ sanitizedString = sanitizeJson(jsonString);
128
+ parseResult = tryParse(sanitizedString);
129
+ if (!parseResult.error) {
130
+ return parseResult.result;
131
+ }
132
+ }
133
+ // If allowPartialParse is true, attempt to salvage partial data
134
+ if (allowPartialParse) {
135
+ const partialJson = sanitizedString.replace(/[^}]*$/, '}');
136
+ parseResult = tryParse(partialJson);
137
+ if (!parseResult.error) {
138
+ // eslint-disable-next-line no-console
139
+ console.warn('Parsed partial JSON data. Some information may be missing.', {
140
+ result: parseResult.result,
141
+ });
142
+ return parseResult.result;
143
+ }
144
+ }
145
+ // If we've reached this point, all parsing attempts have failed
146
+ const errorMessage = `Failed to parse JSON${sanitize ? ' even after sanitization' : ''}${allowPartialParse ? ' and partial parsing' : ''}: ${parseResult.error.message}`;
147
+ if (throwOnError) {
148
+ throw new JsonParseError(errorMessage, parseResult.error, null);
149
+ }
150
+ else {
105
151
  // eslint-disable-next-line no-console
106
- console.error('Error parsing tag:', error);
152
+ console.error(errorMessage);
107
153
  return null;
108
154
  }
109
- return null;
110
155
  }
111
156
  /**
112
157
  * Formats the parsed tag object into a string.
@@ -125,15 +170,40 @@ export function convertInputStringToOriginal(input) {
125
170
  // Regex to match JSON-like tags
126
171
  const tagRegex = getCachedRegex(tagRegexStringPattern, 'g', 'convertInputStringToOriginal');
127
172
  const textFormated = input.replace(tagRegex, (_, jsonString) => {
128
- const cleanedJsonString = sanitizeJsonString(jsonString);
129
- const parsedTag = parseTag(cleanedJsonString);
130
- if (!parsedTag) {
173
+ let parsedJsonString;
174
+ try {
175
+ parsedJsonString = robustJsonParse(jsonString, {
176
+ sanitize: true,
177
+ throwOnError: true,
178
+ });
179
+ // If the parsed string is not a valid tag, fallback to original string
180
+ if (!isValidTag(parsedJsonString)) {
181
+ parsedJsonString = null;
182
+ }
183
+ }
184
+ catch (error) {
185
+ if (error instanceof JsonParseError) {
186
+ // eslint-disable-next-line no-console
187
+ console.error('Parsing failed:', error.message);
188
+ if (error.partialResult) {
189
+ // eslint-disable-next-line no-console
190
+ console.log('Partial result:', error.partialResult);
191
+ }
192
+ }
193
+ else {
194
+ // eslint-disable-next-line no-console
195
+ console.error('Unexpected error:', error);
196
+ }
197
+ // Fall back to original string if parsing fails
198
+ parsedJsonString = null;
199
+ }
200
+ // Return the original string if parsing fails or is not a valid tag
201
+ if (!parsedJsonString) {
131
202
  // eslint-disable-next-line no-console
132
203
  console.error('Error parsing tag:', jsonString);
133
- // Return the original string if parsing fails
134
204
  return _;
135
205
  }
136
- return formatTag(parsedTag);
206
+ return formatTag(parsedJsonString);
137
207
  });
138
208
  // Remove Zero Width Space characters (Unicode U+200B)
139
209
  const cleanedString = textFormated.replace(/\u200B/g, '');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@antscorp/antsomi-ui",
3
- "version": "1.3.5-beta.810",
3
+ "version": "1.3.5-beta.811",
4
4
  "description": "An enterprise-class UI design language and React UI library.",
5
5
  "sideEffects": [
6
6
  "dist/*",