json-rescue 0.0.1 → 0.2.2
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/CHANGELOG.md +3 -0
- package/LICENSE +21 -0
- package/README.md +1 -1
- package/dist/extraction.d.ts +18 -0
- package/dist/extraction.d.ts.map +1 -0
- package/dist/extraction.js +117 -0
- package/dist/extraction.js.map +1 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +21 -0
- package/dist/index.js.map +1 -0
- package/dist/repair.d.ts +32 -0
- package/dist/repair.d.ts.map +1 -0
- package/dist/repair.js +111 -0
- package/dist/repair.js.map +1 -0
- package/dist/rescue.d.ts +24 -0
- package/dist/rescue.d.ts.map +1 -0
- package/dist/rescue.js +118 -0
- package/dist/rescue.js.map +1 -0
- package/dist/types.d.ts +52 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +6 -0
- package/dist/types.js.map +1 -0
- package/package.json +30 -5
- package/PROPOSAL.md +0 -0
- package/src/index.ts +0 -1
- package/tsconfig.json +0 -19
package/CHANGELOG.md
ADDED
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 json-rescue contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -84,7 +84,7 @@ Typical environments where this breaks:
|
|
|
84
84
|
### 3.1 Version Roadmap (Planned)
|
|
85
85
|
|
|
86
86
|
```text
|
|
87
|
-
v0.1.0 (Core) → v0.2.
|
|
87
|
+
v0.1.0 (Core) → v0.2.1 → v0.3.0 → v0.4.0 → v1.0.0
|
|
88
88
|
│ │ │ │ │
|
|
89
89
|
▼ ▼ ▼ ▼ ▼
|
|
90
90
|
Extract + Repair Multi + Streaming Stable
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Extraction strategies for finding JSON in messy text
|
|
3
|
+
*/
|
|
4
|
+
import { ExtractionCandidate } from './types';
|
|
5
|
+
/**
|
|
6
|
+
* Extract JSON from Markdown code blocks (```json ... ```)
|
|
7
|
+
*/
|
|
8
|
+
export declare function extractFromMarkdown(text: string): ExtractionCandidate[];
|
|
9
|
+
/**
|
|
10
|
+
* Extract JSON using balanced braces/brackets (string-aware)
|
|
11
|
+
* Handles nested structures and respects string boundaries
|
|
12
|
+
*/
|
|
13
|
+
export declare function extractBalancedBraces(text: string): ExtractionCandidate[];
|
|
14
|
+
/**
|
|
15
|
+
* Extract all JSON candidates from text
|
|
16
|
+
*/
|
|
17
|
+
export declare function extractAllCandidates(text: string): ExtractionCandidate[];
|
|
18
|
+
//# sourceMappingURL=extraction.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"extraction.d.ts","sourceRoot":"","sources":["../src/extraction.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,mBAAmB,EAAE,MAAM,SAAS,CAAC;AAE9C;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,mBAAmB,EAAE,CAoBvE;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,mBAAmB,EAAE,CAuBzE;AA0DD;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,mBAAmB,EAAE,CAgBxE"}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Extraction strategies for finding JSON in messy text
|
|
4
|
+
*/
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.extractFromMarkdown = extractFromMarkdown;
|
|
7
|
+
exports.extractBalancedBraces = extractBalancedBraces;
|
|
8
|
+
exports.extractAllCandidates = extractAllCandidates;
|
|
9
|
+
/**
|
|
10
|
+
* Extract JSON from Markdown code blocks (```json ... ```)
|
|
11
|
+
*/
|
|
12
|
+
function extractFromMarkdown(text) {
|
|
13
|
+
const candidates = [];
|
|
14
|
+
// Match ```json ... ``` blocks
|
|
15
|
+
const markdownRegex = /```json\s*\n([\s\S]*?)```/g;
|
|
16
|
+
let match;
|
|
17
|
+
while ((match = markdownRegex.exec(text)) !== null) {
|
|
18
|
+
const jsonText = match[1].trim();
|
|
19
|
+
if (jsonText) {
|
|
20
|
+
candidates.push({
|
|
21
|
+
text: jsonText,
|
|
22
|
+
source: 'markdown',
|
|
23
|
+
startIndex: match.index,
|
|
24
|
+
endIndex: match.index + match[0].length,
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
return candidates;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Extract JSON using balanced braces/brackets (string-aware)
|
|
32
|
+
* Handles nested structures and respects string boundaries
|
|
33
|
+
*/
|
|
34
|
+
function extractBalancedBraces(text) {
|
|
35
|
+
const candidates = [];
|
|
36
|
+
for (let i = 0; i < text.length; i++) {
|
|
37
|
+
const char = text[i];
|
|
38
|
+
// Look for object or array start
|
|
39
|
+
if (char === '{' || char === '[') {
|
|
40
|
+
const result = extractBalancedRegion(text, i);
|
|
41
|
+
if (result) {
|
|
42
|
+
const { endIndex, extracted } = result;
|
|
43
|
+
candidates.push({
|
|
44
|
+
text: extracted,
|
|
45
|
+
source: 'balanced-braces',
|
|
46
|
+
startIndex: i,
|
|
47
|
+
endIndex,
|
|
48
|
+
});
|
|
49
|
+
i = endIndex - 1; // Move past this candidate
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
return candidates;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Extract a balanced region from startIndex, respecting string boundaries
|
|
57
|
+
*/
|
|
58
|
+
function extractBalancedRegion(text, startIndex) {
|
|
59
|
+
const opening = text[startIndex];
|
|
60
|
+
const closing = opening === '{' ? '}' : ']';
|
|
61
|
+
let depth = 0;
|
|
62
|
+
let inString = false;
|
|
63
|
+
let escaped = false;
|
|
64
|
+
for (let i = startIndex; i < text.length; i++) {
|
|
65
|
+
const char = text[i];
|
|
66
|
+
if (escaped) {
|
|
67
|
+
escaped = false;
|
|
68
|
+
continue;
|
|
69
|
+
}
|
|
70
|
+
if (char === '\\' && inString) {
|
|
71
|
+
escaped = true;
|
|
72
|
+
continue;
|
|
73
|
+
}
|
|
74
|
+
if (char === '"') {
|
|
75
|
+
inString = !inString;
|
|
76
|
+
continue;
|
|
77
|
+
}
|
|
78
|
+
if (!inString) {
|
|
79
|
+
if (char === opening) {
|
|
80
|
+
depth++;
|
|
81
|
+
}
|
|
82
|
+
else if (char === closing) {
|
|
83
|
+
depth--;
|
|
84
|
+
if (depth === 0) {
|
|
85
|
+
const extracted = text.substring(startIndex, i + 1);
|
|
86
|
+
// Validate it looks like valid JSON structure
|
|
87
|
+
if (extracted.trim().length > 2) {
|
|
88
|
+
return {
|
|
89
|
+
endIndex: i + 1,
|
|
90
|
+
extracted,
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
return null;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
return null;
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Extract all JSON candidates from text
|
|
102
|
+
*/
|
|
103
|
+
function extractAllCandidates(text) {
|
|
104
|
+
const markdown = extractFromMarkdown(text);
|
|
105
|
+
const balanced = extractBalancedBraces(text);
|
|
106
|
+
// Combine and deduplicate by content
|
|
107
|
+
const seen = new Set();
|
|
108
|
+
const all = [];
|
|
109
|
+
for (const candidate of [...markdown, ...balanced]) {
|
|
110
|
+
if (!seen.has(candidate.text)) {
|
|
111
|
+
seen.add(candidate.text);
|
|
112
|
+
all.push(candidate);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
return all;
|
|
116
|
+
}
|
|
117
|
+
//# sourceMappingURL=extraction.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"extraction.js","sourceRoot":"","sources":["../src/extraction.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* json-rescue - Extract, repair, and parse JSON from messy real-world text
|
|
3
|
+
* @packageDocumentation
|
|
4
|
+
*/
|
|
5
|
+
export { rescueJson } from './rescue';
|
|
6
|
+
export type { RescueResult, RescueOptions, RepairIssue, ExtractionCandidate } from './types';
|
|
7
|
+
export { extractAllCandidates, extractFromMarkdown, extractBalancedBraces } from './extraction';
|
|
8
|
+
export { autoRepair, repairTrailingCommas, repairJsoncComments, repairSmartQuotes } from './repair';
|
|
9
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AACtC,YAAY,EAAE,YAAY,EAAE,aAAa,EAAE,WAAW,EAAE,mBAAmB,EAAE,MAAM,SAAS,CAAC;AAG7F,OAAO,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC;AAGhG,OAAO,EAAE,UAAU,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* json-rescue - Extract, repair, and parse JSON from messy real-world text
|
|
4
|
+
* @packageDocumentation
|
|
5
|
+
*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.repairSmartQuotes = exports.repairJsoncComments = exports.repairTrailingCommas = exports.autoRepair = exports.extractBalancedBraces = exports.extractFromMarkdown = exports.extractAllCandidates = exports.rescueJson = void 0;
|
|
8
|
+
var rescue_1 = require("./rescue");
|
|
9
|
+
Object.defineProperty(exports, "rescueJson", { enumerable: true, get: function () { return rescue_1.rescueJson; } });
|
|
10
|
+
// Re-export extraction utilities
|
|
11
|
+
var extraction_1 = require("./extraction");
|
|
12
|
+
Object.defineProperty(exports, "extractAllCandidates", { enumerable: true, get: function () { return extraction_1.extractAllCandidates; } });
|
|
13
|
+
Object.defineProperty(exports, "extractFromMarkdown", { enumerable: true, get: function () { return extraction_1.extractFromMarkdown; } });
|
|
14
|
+
Object.defineProperty(exports, "extractBalancedBraces", { enumerable: true, get: function () { return extraction_1.extractBalancedBraces; } });
|
|
15
|
+
// Re-export repair utilities
|
|
16
|
+
var repair_1 = require("./repair");
|
|
17
|
+
Object.defineProperty(exports, "autoRepair", { enumerable: true, get: function () { return repair_1.autoRepair; } });
|
|
18
|
+
Object.defineProperty(exports, "repairTrailingCommas", { enumerable: true, get: function () { return repair_1.repairTrailingCommas; } });
|
|
19
|
+
Object.defineProperty(exports, "repairJsoncComments", { enumerable: true, get: function () { return repair_1.repairJsoncComments; } });
|
|
20
|
+
Object.defineProperty(exports, "repairSmartQuotes", { enumerable: true, get: function () { return repair_1.repairSmartQuotes; } });
|
|
21
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAEH,mCAAsC;AAA7B,oGAAA,UAAU,OAAA;AAGnB,iCAAiC;AACjC,2CAAgG;AAAvF,kHAAA,oBAAoB,OAAA;AAAE,iHAAA,mBAAmB,OAAA;AAAE,mHAAA,qBAAqB,OAAA;AAEzE,6BAA6B;AAC7B,mCAAoG;AAA3F,oGAAA,UAAU,OAAA;AAAE,8GAAA,oBAAoB,OAAA;AAAE,6GAAA,mBAAmB,OAAA;AAAE,2GAAA,iBAAiB,OAAA"}
|
package/dist/repair.d.ts
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Auto-repair strategies for common JSON defects
|
|
3
|
+
*/
|
|
4
|
+
import { RepairIssue } from './types';
|
|
5
|
+
export interface RepairResult {
|
|
6
|
+
text: string;
|
|
7
|
+
issues: RepairIssue[];
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Apply all default repairs to the text
|
|
11
|
+
*/
|
|
12
|
+
export declare function autoRepair(text: string): RepairResult;
|
|
13
|
+
/**
|
|
14
|
+
* Remove trailing commas before closing braces/brackets
|
|
15
|
+
* e.g., {a: 1,} → {a: 1}
|
|
16
|
+
*/
|
|
17
|
+
export declare function repairTrailingCommas(text: string): RepairResult;
|
|
18
|
+
/**
|
|
19
|
+
* Remove JSONC-style comments
|
|
20
|
+
* Handles both line and block style comments
|
|
21
|
+
*/
|
|
22
|
+
export declare function repairJsoncComments(text: string): RepairResult;
|
|
23
|
+
/**
|
|
24
|
+
* Replace smart quotes (curly quotes) with standard quotes
|
|
25
|
+
* e.g., "hello" → "hello"
|
|
26
|
+
*/
|
|
27
|
+
export declare function repairSmartQuotes(text: string): RepairResult;
|
|
28
|
+
/**
|
|
29
|
+
* Check if text is valid JSON without throwing
|
|
30
|
+
*/
|
|
31
|
+
export declare function isValidJson(text: string): boolean;
|
|
32
|
+
//# sourceMappingURL=repair.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"repair.d.ts","sourceRoot":"","sources":["../src/repair.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAEtC,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,WAAW,EAAE,CAAC;CACvB;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,YAAY,CAiBrD;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,YAAY,CAkB/D;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,YAAY,CA2B9D;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,YAAY,CAmB5D;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAOjD"}
|
package/dist/repair.js
ADDED
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Auto-repair strategies for common JSON defects
|
|
4
|
+
*/
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.autoRepair = autoRepair;
|
|
7
|
+
exports.repairTrailingCommas = repairTrailingCommas;
|
|
8
|
+
exports.repairJsoncComments = repairJsoncComments;
|
|
9
|
+
exports.repairSmartQuotes = repairSmartQuotes;
|
|
10
|
+
exports.isValidJson = isValidJson;
|
|
11
|
+
/**
|
|
12
|
+
* Apply all default repairs to the text
|
|
13
|
+
*/
|
|
14
|
+
function autoRepair(text) {
|
|
15
|
+
let current = text;
|
|
16
|
+
const allIssues = [];
|
|
17
|
+
// Apply repairs in order
|
|
18
|
+
const repairs = [repairTrailingCommas, repairJsoncComments, repairSmartQuotes];
|
|
19
|
+
for (const repair of repairs) {
|
|
20
|
+
const result = repair(current);
|
|
21
|
+
current = result.text;
|
|
22
|
+
allIssues.push(...result.issues);
|
|
23
|
+
}
|
|
24
|
+
return {
|
|
25
|
+
text: current,
|
|
26
|
+
issues: allIssues,
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Remove trailing commas before closing braces/brackets
|
|
31
|
+
* e.g., {a: 1,} → {a: 1}
|
|
32
|
+
*/
|
|
33
|
+
function repairTrailingCommas(text) {
|
|
34
|
+
const issues = [];
|
|
35
|
+
let modified = false;
|
|
36
|
+
// Match comma followed by whitespace and closing bracket/brace
|
|
37
|
+
const repaired = text.replace(/,(\s*[}\]])/g, (match, closing) => {
|
|
38
|
+
if (!modified) {
|
|
39
|
+
modified = true;
|
|
40
|
+
issues.push({
|
|
41
|
+
code: 'TRAILING_COMMA',
|
|
42
|
+
message: 'Removed trailing comma before closing bracket',
|
|
43
|
+
severity: 'warning',
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
return closing;
|
|
47
|
+
});
|
|
48
|
+
return { text: repaired, issues };
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Remove JSONC-style comments
|
|
52
|
+
* Handles both line and block style comments
|
|
53
|
+
*/
|
|
54
|
+
function repairJsoncComments(text) {
|
|
55
|
+
const issues = [];
|
|
56
|
+
let result = text;
|
|
57
|
+
// Remove // comments (to end of line)
|
|
58
|
+
const singleLineRegex = /\/\/.*$/gm;
|
|
59
|
+
if (singleLineRegex.test(result)) {
|
|
60
|
+
issues.push({
|
|
61
|
+
code: 'JSONC_COMMENT_SINGLE',
|
|
62
|
+
message: 'Removed single-line comments',
|
|
63
|
+
severity: 'warning',
|
|
64
|
+
});
|
|
65
|
+
result = result.replace(singleLineRegex, '');
|
|
66
|
+
}
|
|
67
|
+
// Remove /* */ comments
|
|
68
|
+
const multiLineRegex = /\/\*[\s\S]*?\*\//g;
|
|
69
|
+
if (multiLineRegex.test(result)) {
|
|
70
|
+
issues.push({
|
|
71
|
+
code: 'JSONC_COMMENT_MULTI',
|
|
72
|
+
message: 'Removed multi-line comments',
|
|
73
|
+
severity: 'warning',
|
|
74
|
+
});
|
|
75
|
+
result = result.replace(multiLineRegex, '');
|
|
76
|
+
}
|
|
77
|
+
return { text: result, issues };
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Replace smart quotes (curly quotes) with standard quotes
|
|
81
|
+
* e.g., "hello" → "hello"
|
|
82
|
+
*/
|
|
83
|
+
function repairSmartQuotes(text) {
|
|
84
|
+
const issues = [];
|
|
85
|
+
// Unicode smart quotes: " " ' '
|
|
86
|
+
const smartQuoteRegex = /[\u201C\u201D\u2018\u2019]/g;
|
|
87
|
+
if (smartQuoteRegex.test(text)) {
|
|
88
|
+
issues.push({
|
|
89
|
+
code: 'SMART_QUOTES',
|
|
90
|
+
message: 'Converted smart quotes to standard ASCII quotes',
|
|
91
|
+
severity: 'warning',
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
const repaired = text
|
|
95
|
+
.replace(/[\u201C\u201D]/g, '"') // Convert curly double quotes
|
|
96
|
+
.replace(/[\u2018\u2019]/g, "'"); // Convert curly single quotes
|
|
97
|
+
return { text: repaired, issues };
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Check if text is valid JSON without throwing
|
|
101
|
+
*/
|
|
102
|
+
function isValidJson(text) {
|
|
103
|
+
try {
|
|
104
|
+
JSON.parse(text);
|
|
105
|
+
return true;
|
|
106
|
+
}
|
|
107
|
+
catch {
|
|
108
|
+
return false;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
//# sourceMappingURL=repair.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"repair.js","sourceRoot":"","sources":["../src/repair.ts"],"names":[],"mappings":"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"}
|
package/dist/rescue.d.ts
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Main rescue function with support for generics and multiple modes
|
|
3
|
+
*/
|
|
4
|
+
import { RescueResult, RescueOptions } from './types';
|
|
5
|
+
/**
|
|
6
|
+
* Rescue JSON from messy text with transparent repair reporting
|
|
7
|
+
*
|
|
8
|
+
* @template T - The expected type of the parsed JSON
|
|
9
|
+
* @param text - The text containing JSON
|
|
10
|
+
* @param options - Configuration options
|
|
11
|
+
* @returns A RescueResult with parsed data, repair issues, and metadata
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```typescript
|
|
15
|
+
* const result = rescueJson<{ name: string }>(mixedText);
|
|
16
|
+
* if (result.success) {
|
|
17
|
+
* console.log(result.data.name);
|
|
18
|
+
* console.log(result.issues); // See what was repaired
|
|
19
|
+
* }
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
22
|
+
export declare function rescueJson<T = unknown>(text: string, options?: RescueOptions): RescueResult<T> | RescueResult<T>[];
|
|
23
|
+
export { RescueResult, RescueOptions, RepairIssue } from './types';
|
|
24
|
+
//# sourceMappingURL=rescue.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rescue.d.ts","sourceRoot":"","sources":["../src/rescue.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,YAAY,EAAE,aAAa,EAAe,MAAM,SAAS,CAAC;AAInE;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,UAAU,CAAC,CAAC,GAAG,OAAO,EACpC,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE,aAAkB,GAC1B,YAAY,CAAC,CAAC,CAAC,GAAG,YAAY,CAAC,CAAC,CAAC,EAAE,CA2CrC;AA8DD,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC"}
|
package/dist/rescue.js
ADDED
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Main rescue function with support for generics and multiple modes
|
|
4
|
+
*/
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.rescueJson = rescueJson;
|
|
7
|
+
const extraction_1 = require("./extraction");
|
|
8
|
+
const repair_1 = require("./repair");
|
|
9
|
+
/**
|
|
10
|
+
* Rescue JSON from messy text with transparent repair reporting
|
|
11
|
+
*
|
|
12
|
+
* @template T - The expected type of the parsed JSON
|
|
13
|
+
* @param text - The text containing JSON
|
|
14
|
+
* @param options - Configuration options
|
|
15
|
+
* @returns A RescueResult with parsed data, repair issues, and metadata
|
|
16
|
+
*
|
|
17
|
+
* @example
|
|
18
|
+
* ```typescript
|
|
19
|
+
* const result = rescueJson<{ name: string }>(mixedText);
|
|
20
|
+
* if (result.success) {
|
|
21
|
+
* console.log(result.data.name);
|
|
22
|
+
* console.log(result.issues); // See what was repaired
|
|
23
|
+
* }
|
|
24
|
+
* ```
|
|
25
|
+
*/
|
|
26
|
+
function rescueJson(text, options = {}) {
|
|
27
|
+
const { mode = 'first', autoRepair: shouldRepair = true } = options;
|
|
28
|
+
// Extract candidates
|
|
29
|
+
const candidates = (0, extraction_1.extractAllCandidates)(text);
|
|
30
|
+
if (candidates.length === 0) {
|
|
31
|
+
const emptyResult = {
|
|
32
|
+
data: null,
|
|
33
|
+
success: false,
|
|
34
|
+
issues: [
|
|
35
|
+
{
|
|
36
|
+
code: 'NO_JSON_FOUND',
|
|
37
|
+
message: 'No JSON candidates found in the text',
|
|
38
|
+
severity: 'error',
|
|
39
|
+
},
|
|
40
|
+
],
|
|
41
|
+
raw: '',
|
|
42
|
+
repaired: '',
|
|
43
|
+
};
|
|
44
|
+
return mode === 'all' ? [emptyResult] : emptyResult;
|
|
45
|
+
}
|
|
46
|
+
// Process candidates
|
|
47
|
+
const results = [];
|
|
48
|
+
for (const candidate of candidates) {
|
|
49
|
+
const result = processCandidate(candidate.text, shouldRepair);
|
|
50
|
+
results.push(result);
|
|
51
|
+
// Stop if we found a valid one and only want the first
|
|
52
|
+
if (mode === 'first' && result.success) {
|
|
53
|
+
break;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
// Return based on mode
|
|
57
|
+
if (mode === 'all') {
|
|
58
|
+
return results;
|
|
59
|
+
}
|
|
60
|
+
// Return first successful or first result
|
|
61
|
+
return results.find((r) => r.success) || results[0];
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Process a single candidate: attempt repair and parse
|
|
65
|
+
*/
|
|
66
|
+
function processCandidate(raw, shouldRepair) {
|
|
67
|
+
const allIssues = [];
|
|
68
|
+
let repaired = raw;
|
|
69
|
+
// Try to parse as-is first
|
|
70
|
+
if ((0, repair_1.isValidJson)(raw)) {
|
|
71
|
+
return {
|
|
72
|
+
data: JSON.parse(raw),
|
|
73
|
+
success: true,
|
|
74
|
+
issues: [],
|
|
75
|
+
raw,
|
|
76
|
+
repaired: raw,
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
// If we should repair, apply repairs
|
|
80
|
+
if (shouldRepair) {
|
|
81
|
+
const repairResult = (0, repair_1.autoRepair)(raw);
|
|
82
|
+
repaired = repairResult.text;
|
|
83
|
+
allIssues.push(...repairResult.issues);
|
|
84
|
+
// Try parsing after repair
|
|
85
|
+
if ((0, repair_1.isValidJson)(repaired)) {
|
|
86
|
+
return {
|
|
87
|
+
data: JSON.parse(repaired),
|
|
88
|
+
success: true,
|
|
89
|
+
issues: allIssues,
|
|
90
|
+
raw,
|
|
91
|
+
repaired,
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
// Failed to parse
|
|
96
|
+
let parseError = 'Unknown parse error';
|
|
97
|
+
try {
|
|
98
|
+
JSON.parse(repaired);
|
|
99
|
+
}
|
|
100
|
+
catch (e) {
|
|
101
|
+
parseError = e instanceof Error ? e.message : String(e);
|
|
102
|
+
}
|
|
103
|
+
return {
|
|
104
|
+
data: null,
|
|
105
|
+
success: false,
|
|
106
|
+
issues: [
|
|
107
|
+
...allIssues,
|
|
108
|
+
{
|
|
109
|
+
code: 'PARSE_ERROR',
|
|
110
|
+
message: `Failed to parse JSON: ${parseError}`,
|
|
111
|
+
severity: 'error',
|
|
112
|
+
},
|
|
113
|
+
],
|
|
114
|
+
raw,
|
|
115
|
+
repaired,
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
//# sourceMappingURL=rescue.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rescue.js","sourceRoot":"","sources":["../src/rescue.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Core type definitions for json-rescue
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Represents a single repair issue found during extraction/repair
|
|
6
|
+
*/
|
|
7
|
+
export interface RepairIssue {
|
|
8
|
+
code: string;
|
|
9
|
+
message: string;
|
|
10
|
+
line?: number;
|
|
11
|
+
column?: number;
|
|
12
|
+
severity: 'warning' | 'error';
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Result of a rescue operation with transparent repair reporting
|
|
16
|
+
*/
|
|
17
|
+
export interface RescueResult<T = unknown> {
|
|
18
|
+
/** The parsed JSON object */
|
|
19
|
+
data: T | null;
|
|
20
|
+
/** Whether parsing was successful */
|
|
21
|
+
success: boolean;
|
|
22
|
+
/** List of repairs applied */
|
|
23
|
+
issues: RepairIssue[];
|
|
24
|
+
/** The original extracted text before repairs */
|
|
25
|
+
raw: string;
|
|
26
|
+
/** The repaired text before parsing */
|
|
27
|
+
repaired: string;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Extraction candidate found in the text
|
|
31
|
+
*/
|
|
32
|
+
export interface ExtractionCandidate {
|
|
33
|
+
text: string;
|
|
34
|
+
source: 'markdown' | 'balanced-braces';
|
|
35
|
+
startIndex: number;
|
|
36
|
+
endIndex: number;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Options for rescueJson function
|
|
40
|
+
*/
|
|
41
|
+
export interface RescueOptions {
|
|
42
|
+
/** Mode of extraction: 'first' (default) or 'all' */
|
|
43
|
+
mode?: 'first' | 'all';
|
|
44
|
+
/** Whether to attempt auto-repair */
|
|
45
|
+
autoRepair?: boolean;
|
|
46
|
+
/** Custom repair rules */
|
|
47
|
+
customRepairs?: ((text: string) => {
|
|
48
|
+
text: string;
|
|
49
|
+
issues: RepairIssue[];
|
|
50
|
+
})[];
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,SAAS,GAAG,OAAO,CAAC;CAC/B;AAED;;GAEG;AACH,MAAM,WAAW,YAAY,CAAC,CAAC,GAAG,OAAO;IACvC,6BAA6B;IAC7B,IAAI,EAAE,CAAC,GAAG,IAAI,CAAC;IACf,qCAAqC;IACrC,OAAO,EAAE,OAAO,CAAC;IACjB,8BAA8B;IAC9B,MAAM,EAAE,WAAW,EAAE,CAAC;IACtB,iDAAiD;IACjD,GAAG,EAAE,MAAM,CAAC;IACZ,uCAAuC;IACvC,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,UAAU,GAAG,iBAAiB,CAAC;IACvC,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,qDAAqD;IACrD,IAAI,CAAC,EAAE,OAAO,GAAG,KAAK,CAAC;IACvB,qCAAqC;IACrC,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,0BAA0B;IAC1B,aAAa,CAAC,EAAE,CAAC,CAAC,IAAI,EAAE,MAAM,KAAK;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,WAAW,EAAE,CAAA;KAAE,CAAC,EAAE,CAAC;CAC/E"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":";AAAA;;GAEG"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "json-rescue",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.2",
|
|
4
4
|
"description": "Rescue valid JSON from messy text by extracting candidates, applying safe repairs, and returning a parsed result with a transparent repair report.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"json",
|
|
@@ -22,18 +22,43 @@
|
|
|
22
22
|
"url": "https://azeemmirza.co"
|
|
23
23
|
},
|
|
24
24
|
"type": "commonjs",
|
|
25
|
-
"main": "index.
|
|
25
|
+
"main": "dist/index.js",
|
|
26
|
+
"types": "dist/index.d.ts",
|
|
27
|
+
"files": [
|
|
28
|
+
"dist",
|
|
29
|
+
"README.md",
|
|
30
|
+
"LICENSE",
|
|
31
|
+
"CHANGELOG.md"
|
|
32
|
+
],
|
|
26
33
|
"scripts": {
|
|
27
34
|
"build": "tsc",
|
|
28
35
|
"test": "jest",
|
|
29
36
|
"test:watch": "jest --watch",
|
|
30
|
-
"
|
|
31
|
-
"
|
|
37
|
+
"lint": "eslint src --ext .ts",
|
|
38
|
+
"lint:fix": "eslint src --ext .ts --fix",
|
|
39
|
+
"format": "prettier --write \"src/**/*.ts\"",
|
|
40
|
+
"format:check": "prettier --check \"src/**/*.ts\"",
|
|
41
|
+
"release": "release-it",
|
|
42
|
+
"release:dry": "release-it --dry-run",
|
|
43
|
+
"prepublishOnly": "npm run build && npm run lint && npm run test",
|
|
44
|
+
"publish": "npm publish --access public"
|
|
32
45
|
},
|
|
33
46
|
"devDependencies": {
|
|
47
|
+
"@commitlint/cli": "^20.4.2",
|
|
48
|
+
"@commitlint/config-conventional": "^20.4.2",
|
|
49
|
+
"@eslint/js": "^10.0.1",
|
|
50
|
+
"@release-it/conventional-changelog": "^10.0.5",
|
|
34
51
|
"@types/jest": "^30.0.0",
|
|
52
|
+
"@typescript-eslint/eslint-plugin": "^8.56.0",
|
|
53
|
+
"@typescript-eslint/parser": "^8.56.0",
|
|
54
|
+
"conventional-changelog-conventionalcommits": "^9.1.0",
|
|
55
|
+
"eslint": "^10.0.0",
|
|
56
|
+
"eslint-config-prettier": "^10.1.8",
|
|
57
|
+
"eslint-plugin-prettier": "^5.5.5",
|
|
35
58
|
"jest": "^30.2.0",
|
|
59
|
+
"release-it": "^19.2.4",
|
|
36
60
|
"ts-jest": "^29.4.6",
|
|
37
|
-
"typescript": "^5.9.3"
|
|
61
|
+
"typescript": "^5.9.3",
|
|
62
|
+
"typescript-eslint": "^8.56.0"
|
|
38
63
|
}
|
|
39
64
|
}
|
package/PROPOSAL.md
DELETED
|
File without changes
|
package/src/index.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
console.log('json-rescue...');
|
package/tsconfig.json
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"compilerOptions": {
|
|
3
|
-
"target": "ES2020",
|
|
4
|
-
"module": "commonjs",
|
|
5
|
-
"lib": ["dom", "esnext"],
|
|
6
|
-
"outDir": "./dist",
|
|
7
|
-
"rootDir": "./src",
|
|
8
|
-
"strict": true,
|
|
9
|
-
"esModuleInterop": true,
|
|
10
|
-
"skipLibCheck": true,
|
|
11
|
-
"forceConsistentCasingInFileNames": true,
|
|
12
|
-
"resolveJsonModule": true,
|
|
13
|
-
"declaration": true,
|
|
14
|
-
"declarationMap": true,
|
|
15
|
-
"sourceMap": true
|
|
16
|
-
},
|
|
17
|
-
"include": ["src/**/*"],
|
|
18
|
-
"exclude": ["node_modules", "dist", "**/*.test.ts"]
|
|
19
|
-
}
|