@futdevpro/fsm-dynamo 1.11.31 → 1.11.33
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/.github/workflows/main.yml +20 -21
- package/build/_collections/utils/json-error-helper.util.d.ts +8 -0
- package/build/_collections/utils/json-error-helper.util.d.ts.map +1 -1
- package/build/_collections/utils/json-error-helper.util.js +118 -39
- package/build/_collections/utils/json-error-helper.util.js.map +1 -1
- package/build/_collections/utils/object.util.d.ts +6 -0
- package/build/_collections/utils/object.util.d.ts.map +1 -1
- package/build/_collections/utils/object.util.js +37 -1
- package/build/_collections/utils/object.util.js.map +1 -1
- package/build/_collections/utils/object.util.spec.js +393 -0
- package/build/_collections/utils/object.util.spec.js.map +1 -1
- package/build/_collections/utils/string.util.d.ts +130 -0
- package/build/_collections/utils/string.util.d.ts.map +1 -1
- package/build/_collections/utils/string.util.js +354 -0
- package/build/_collections/utils/string.util.js.map +1 -1
- package/build/_collections/utils/string.util.spec.js +694 -0
- package/build/_collections/utils/string.util.spec.js.map +1 -1
- package/build/_modules/crypto/_collections/crypto-2-non-stable.util.d.ts.map +1 -1
- package/build/_modules/crypto/_collections/crypto-2-non-stable.util.js +3 -2
- package/build/_modules/crypto/_collections/crypto-2-non-stable.util.js.map +1 -1
- package/build/_modules/crypto/_collections/crypto.util.d.ts.map +1 -1
- package/build/_modules/crypto/_collections/crypto.util.js +22 -9
- package/build/_modules/crypto/_collections/crypto.util.js.map +1 -1
- package/build/_modules/crypto/_collections/crypto.util.spec.js +3 -3
- package/build/_modules/crypto/_collections/crypto.util.spec.js.map +1 -1
- package/build/_modules/crypto/index.js +7 -6
- package/build/_modules/crypto/index.js.map +1 -1
- package/build/_modules/open-ai/index.js +7 -6
- package/build/_modules/open-ai/index.js.map +1 -1
- package/futdevpro-fsm-dynamo-01.11.33.tgz +0 -0
- package/package.json +1 -1
- package/src/_collections/utils/json-error-helper.util.ts +135 -45
- package/src/_collections/utils/object.util.spec.ts +503 -0
- package/src/_collections/utils/object.util.ts +40 -10
- package/src/_collections/utils/string.util.spec.ts +773 -1
- package/src/_collections/utils/string.util.ts +426 -0
- package/src/_modules/crypto/_collections/crypto-2-non-stable.util.ts +3 -2
- package/src/_modules/crypto/_collections/crypto.util.spec.ts +3 -3
- package/src/_modules/crypto/_collections/crypto.util.ts +20 -8
- package/src/_modules/crypto/index.ts +2 -2
- package/src/_modules/open-ai/index.ts +2 -2
- package/futdevpro-fsm-dynamo-01.11.31.tgz +0 -0
|
@@ -39,13 +39,30 @@ export class DyFM_JsonErrorHelper {
|
|
|
39
39
|
contextLines: number = 5
|
|
40
40
|
): JsonErrorLineInfo | null {
|
|
41
41
|
try {
|
|
42
|
-
// Extract position from error message
|
|
42
|
+
// Extract position from various error message formats
|
|
43
43
|
let positionMatch = errorMessage.match(/at position (\d+)/);
|
|
44
44
|
if (!positionMatch) {
|
|
45
45
|
// Handle "Unexpected end of JSON input at position 17" format
|
|
46
46
|
positionMatch = errorMessage.match(/Unexpected end of JSON input at position (\d+)/);
|
|
47
47
|
}
|
|
48
48
|
if (!positionMatch) {
|
|
49
|
+
// Handle "Unexpected token" format which might include position
|
|
50
|
+
positionMatch = errorMessage.match(/position (\d+)/);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
if (!positionMatch) {
|
|
54
|
+
// For "Unexpected token" errors without explicit position, try to find it from the token
|
|
55
|
+
const tokenMatch = errorMessage.match(/Unexpected token '(.)'|Unexpected token (.)/);
|
|
56
|
+
if (tokenMatch && jsonInput.includes('\n')) {
|
|
57
|
+
const token = tokenMatch[1] || tokenMatch[2];
|
|
58
|
+
if (token) {
|
|
59
|
+
// Find the first occurrence of this token (this is a simple heuristic)
|
|
60
|
+
const tokenPosition = jsonInput.indexOf(token);
|
|
61
|
+
if (tokenPosition !== -1) {
|
|
62
|
+
return this.createLineInfoFromPosition(jsonInput, tokenPosition, contextLines);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
49
66
|
return null;
|
|
50
67
|
}
|
|
51
68
|
|
|
@@ -60,54 +77,74 @@ export class DyFM_JsonErrorHelper {
|
|
|
60
77
|
return null;
|
|
61
78
|
}
|
|
62
79
|
|
|
63
|
-
|
|
64
|
-
const lines = jsonInput.split('\n');
|
|
65
|
-
let currentPosition = 0;
|
|
66
|
-
let lineNumber = 1;
|
|
67
|
-
let characterPosition = 0;
|
|
68
|
-
|
|
69
|
-
for (let i = 0; i < lines.length; i++) {
|
|
70
|
-
const lineLength = lines[i].length;
|
|
71
|
-
if (currentPosition + lineLength >= position) {
|
|
72
|
-
lineNumber = i + 1;
|
|
73
|
-
characterPosition = position - currentPosition;
|
|
74
|
-
break;
|
|
75
|
-
}
|
|
76
|
-
currentPosition += lineLength + 1; // +1 for newline character
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
// If we didn't find the line in the loop, it's at the end
|
|
80
|
-
if (characterPosition === 0) {
|
|
81
|
-
lineNumber = lines.length;
|
|
82
|
-
characterPosition = position - currentPosition;
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
// Ensure character position is not negative
|
|
86
|
-
if (characterPosition < 0) {
|
|
87
|
-
characterPosition = 0;
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
// Ensure line number is within bounds
|
|
91
|
-
if (lineNumber > lines.length) {
|
|
92
|
-
lineNumber = lines.length;
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
// Get surrounding context (±contextLines)
|
|
96
|
-
const contextStart = Math.max(0, lineNumber - contextLines - 1);
|
|
97
|
-
const contextEnd = Math.min(lines.length, lineNumber + contextLines);
|
|
98
|
-
const contextLinesArray = lines.slice(contextStart, contextEnd);
|
|
99
|
-
|
|
100
|
-
return {
|
|
101
|
-
lineNumber,
|
|
102
|
-
contextLines: contextLinesArray,
|
|
103
|
-
characterPosition
|
|
104
|
-
};
|
|
80
|
+
return this.createLineInfoFromPosition(jsonInput, position, contextLines);
|
|
105
81
|
} catch (error) {
|
|
106
82
|
// If we can't parse the error, return null to fall back to simple preview
|
|
107
83
|
return null;
|
|
108
84
|
}
|
|
109
85
|
}
|
|
110
86
|
|
|
87
|
+
/**
|
|
88
|
+
* Helper method to create line info from a character position
|
|
89
|
+
*/
|
|
90
|
+
private static createLineInfoFromPosition(
|
|
91
|
+
jsonInput: string,
|
|
92
|
+
position: number,
|
|
93
|
+
contextLines: number
|
|
94
|
+
): JsonErrorLineInfo {
|
|
95
|
+
// Handle undefined or invalid input
|
|
96
|
+
if (!jsonInput || typeof jsonInput !== 'string') {
|
|
97
|
+
return {
|
|
98
|
+
lineNumber: 1,
|
|
99
|
+
contextLines: ['(invalid or empty input)'],
|
|
100
|
+
characterPosition: 0
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// Split input into lines to find the line number
|
|
105
|
+
const lines = jsonInput.split('\n');
|
|
106
|
+
let currentPosition = 0;
|
|
107
|
+
let lineNumber = 1;
|
|
108
|
+
let characterPosition = 0;
|
|
109
|
+
|
|
110
|
+
for (let i = 0; i < lines.length; i++) {
|
|
111
|
+
const lineLength = lines[i].length;
|
|
112
|
+
if (currentPosition + lineLength >= position) {
|
|
113
|
+
lineNumber = i + 1;
|
|
114
|
+
characterPosition = position - currentPosition;
|
|
115
|
+
break;
|
|
116
|
+
}
|
|
117
|
+
currentPosition += lineLength + 1; // +1 for newline character
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// If we didn't find the line in the loop, it's at the end
|
|
121
|
+
if (characterPosition === 0 && lineNumber === 1) {
|
|
122
|
+
lineNumber = lines.length;
|
|
123
|
+
characterPosition = position - currentPosition;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
// Ensure character position is not negative
|
|
127
|
+
if (characterPosition < 0) {
|
|
128
|
+
characterPosition = 0;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
// Ensure line number is within bounds
|
|
132
|
+
if (lineNumber > lines.length) {
|
|
133
|
+
lineNumber = lines.length;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
// Get surrounding context (±contextLines)
|
|
137
|
+
const contextStart = Math.max(0, lineNumber - contextLines - 1);
|
|
138
|
+
const contextEnd = Math.min(lines.length, lineNumber + contextLines);
|
|
139
|
+
const contextLinesArray = lines.slice(contextStart, contextEnd);
|
|
140
|
+
|
|
141
|
+
return {
|
|
142
|
+
lineNumber,
|
|
143
|
+
contextLines: contextLinesArray,
|
|
144
|
+
characterPosition
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
|
|
111
148
|
/**
|
|
112
149
|
* Formats JSON error information for logging
|
|
113
150
|
* Creates a formatted string showing the error location and context
|
|
@@ -152,13 +189,39 @@ export class DyFM_JsonErrorHelper {
|
|
|
152
189
|
static parseJsonWithEnhancedError(
|
|
153
190
|
jsonString: string,
|
|
154
191
|
reviver?: (key: string, value: any) => any,
|
|
155
|
-
contextLines: number =
|
|
192
|
+
contextLines: number = 2
|
|
156
193
|
): any {
|
|
194
|
+
// Prevent infinite recursion and handle invalid input
|
|
195
|
+
if (!jsonString || typeof jsonString !== 'string') {
|
|
196
|
+
throw new Error(`Invalid JSON input: expected string, got ${typeof jsonString}`);
|
|
197
|
+
}
|
|
198
|
+
|
|
157
199
|
try {
|
|
158
200
|
return JSON.parse(jsonString, reviver);
|
|
159
201
|
} catch (error) {
|
|
160
202
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
161
|
-
const
|
|
203
|
+
const originalJsonString = jsonString;
|
|
204
|
+
|
|
205
|
+
// First try to extract line info from the original JSON
|
|
206
|
+
let lineInfo = this.extractLineInfoFromJsonError(errorMessage, originalJsonString, contextLines);
|
|
207
|
+
|
|
208
|
+
// If no line info was found and the JSON is on a single line, try formatting it
|
|
209
|
+
if (!lineInfo && !originalJsonString.includes('\n')) {
|
|
210
|
+
try {
|
|
211
|
+
const formattedJson = this.formatJsonForBetterErrors(originalJsonString);
|
|
212
|
+
|
|
213
|
+
// Try parsing the formatted JSON to get a new error with position info
|
|
214
|
+
try {
|
|
215
|
+
JSON.parse(formattedJson, reviver);
|
|
216
|
+
} catch (formattedError) {
|
|
217
|
+
const formattedErrorMessage = formattedError instanceof Error ? formattedError.message : String(formattedError);
|
|
218
|
+
lineInfo = this.extractLineInfoFromJsonError(formattedErrorMessage, formattedJson, contextLines);
|
|
219
|
+
}
|
|
220
|
+
} catch (formatError) {
|
|
221
|
+
// If formatting fails, skip enhanced error reporting
|
|
222
|
+
lineInfo = null;
|
|
223
|
+
}
|
|
224
|
+
}
|
|
162
225
|
|
|
163
226
|
if (lineInfo) {
|
|
164
227
|
const formattedError = this.formatJsonErrorForLogging(lineInfo, errorMessage);
|
|
@@ -169,4 +232,31 @@ export class DyFM_JsonErrorHelper {
|
|
|
169
232
|
}
|
|
170
233
|
}
|
|
171
234
|
}
|
|
235
|
+
|
|
236
|
+
/**
|
|
237
|
+
* Formats single-line JSON with line breaks for better error reporting
|
|
238
|
+
*/
|
|
239
|
+
private static formatJsonForBetterErrors(jsonString: string): string {
|
|
240
|
+
if (!jsonString || typeof jsonString !== 'string') {
|
|
241
|
+
return jsonString || '';
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
return jsonString
|
|
245
|
+
.replace(/,/g, ',\n ')
|
|
246
|
+
.replace(/{/g, '{\n ')
|
|
247
|
+
.replace(/}/g, '\n}')
|
|
248
|
+
.replace(/\[/g, '[\n ')
|
|
249
|
+
.replace(/\]/g, '\n]')
|
|
250
|
+
.replace(/\n\s*\n/g, '\n') // Remove double newlines
|
|
251
|
+
.replace(/^\s+|\s+$/gm, function(match, offset, string) {
|
|
252
|
+
// Trim but preserve indentation structure
|
|
253
|
+
if (!string || typeof string !== 'string') {
|
|
254
|
+
return match;
|
|
255
|
+
}
|
|
256
|
+
const lines = string.slice(0, offset).split('\n');
|
|
257
|
+
const depth = (string.slice(0, offset).match(/{|\[/g) || []).length -
|
|
258
|
+
(string.slice(0, offset).match(/}|\]/g) || []).length;
|
|
259
|
+
return ' '.repeat(Math.max(0, depth));
|
|
260
|
+
});
|
|
261
|
+
}
|
|
172
262
|
}
|