flex-md 1.1.0 → 3.0.0
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/README.md +75 -29
- package/SPEC.md +559 -0
- package/dist/__tests__/validate.test.d.ts +1 -0
- package/dist/__tests__/validate.test.js +108 -0
- package/dist/detect/json/detectIntent.d.ts +2 -0
- package/dist/detect/json/detectIntent.js +79 -0
- package/dist/detect/json/detectPresence.d.ts +6 -0
- package/dist/detect/json/detectPresence.js +191 -0
- package/dist/detect/json/index.d.ts +7 -0
- package/dist/detect/json/index.js +12 -0
- package/dist/detect/json/types.d.ts +43 -0
- package/dist/detect/json/types.js +1 -0
- package/dist/detection/detector.d.ts +6 -0
- package/dist/detection/detector.js +104 -0
- package/dist/detection/extractor.d.ts +10 -0
- package/dist/detection/extractor.js +54 -0
- package/dist/extract/extract.d.ts +5 -0
- package/dist/extract/extract.js +50 -0
- package/dist/extract/types.d.ts +11 -0
- package/dist/extract/types.js +1 -0
- package/dist/index.d.ts +13 -3
- package/dist/index.js +20 -3
- package/dist/issues/build.d.ts +26 -0
- package/dist/issues/build.js +62 -0
- package/dist/md/lists.d.ts +14 -0
- package/dist/md/lists.js +33 -0
- package/dist/md/match.d.ts +12 -0
- package/dist/md/match.js +44 -0
- package/dist/md/outline.d.ts +6 -0
- package/dist/md/outline.js +67 -0
- package/dist/md/parse.d.ts +29 -0
- package/dist/md/parse.js +105 -0
- package/dist/md/tables.d.ts +25 -0
- package/dist/md/tables.js +72 -0
- package/dist/ofs/enricher.d.ts +16 -0
- package/dist/ofs/enricher.js +77 -0
- package/dist/ofs/extractor.d.ts +9 -0
- package/dist/ofs/extractor.js +75 -0
- package/dist/ofs/issues.d.ts +14 -0
- package/dist/ofs/issues.js +92 -0
- package/dist/ofs/issuesEnvelope.d.ts +15 -0
- package/dist/ofs/issuesEnvelope.js +71 -0
- package/dist/ofs/parser.d.ts +9 -0
- package/dist/ofs/parser.js +133 -0
- package/dist/ofs/stringify.d.ts +5 -0
- package/dist/ofs/stringify.js +32 -0
- package/dist/ofs/validator.d.ts +10 -0
- package/dist/ofs/validator.js +91 -0
- package/dist/outline/builder.d.ts +10 -0
- package/dist/outline/builder.js +85 -0
- package/dist/outline/renderer.d.ts +6 -0
- package/dist/outline/renderer.js +23 -0
- package/dist/parser.js +58 -10
- package/dist/parsers/lists.d.ts +6 -0
- package/dist/parsers/lists.js +36 -0
- package/dist/parsers/tables.d.ts +10 -0
- package/dist/parsers/tables.js +58 -0
- package/dist/pipeline/enforce.d.ts +10 -0
- package/dist/pipeline/enforce.js +46 -0
- package/dist/pipeline/kind.d.ts +16 -0
- package/dist/pipeline/kind.js +24 -0
- package/dist/pipeline/repair.d.ts +14 -0
- package/dist/pipeline/repair.js +112 -0
- package/dist/strictness/container.d.ts +14 -0
- package/dist/strictness/container.js +46 -0
- package/dist/strictness/processor.d.ts +5 -0
- package/dist/strictness/processor.js +29 -0
- package/dist/strictness/types.d.ts +77 -0
- package/dist/strictness/types.js +106 -0
- package/dist/test-pipeline.d.ts +1 -0
- package/dist/test-pipeline.js +53 -0
- package/dist/test-runner.d.ts +1 -0
- package/dist/test-runner.js +331 -0
- package/dist/test-strictness.d.ts +1 -0
- package/dist/test-strictness.js +213 -0
- package/dist/types.d.ts +140 -22
- package/dist/validate/policy.d.ts +10 -0
- package/dist/validate/policy.js +17 -0
- package/dist/validate/types.d.ts +11 -0
- package/dist/validate/types.js +1 -0
- package/dist/validate/validate.d.ts +2 -0
- package/dist/validate/validate.js +308 -0
- package/docs/mdflex-compliance.md +216 -0
- package/package.json +15 -6
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
import { parseOutputFormatSpec, processResponseMarkdown, strictnessDefaults } from "../src/index.js";
|
|
2
|
+
const specText = `
|
|
3
|
+
## Output format (Markdown)
|
|
4
|
+
Include these sections somewhere (order does not matter):
|
|
5
|
+
|
|
6
|
+
- Short answer — prose
|
|
7
|
+
- Long answer — prose
|
|
8
|
+
- Reasoning — ordered list
|
|
9
|
+
- Assumptions — list
|
|
10
|
+
- Unknowns — list
|
|
11
|
+
|
|
12
|
+
tables:
|
|
13
|
+
- (property, value — table)
|
|
14
|
+
|
|
15
|
+
empty sections:
|
|
16
|
+
- If a section is empty, write \`None\`.
|
|
17
|
+
`;
|
|
18
|
+
const spec = parseOutputFormatSpec(specText);
|
|
19
|
+
// --- L0 Test ---
|
|
20
|
+
console.log("--- Level 0 Test ---");
|
|
21
|
+
const l0Response = `
|
|
22
|
+
I thought about it.
|
|
23
|
+
## Short answer
|
|
24
|
+
Yes, it works.
|
|
25
|
+
|
|
26
|
+
## Unknowns
|
|
27
|
+
- None so far.
|
|
28
|
+
`;
|
|
29
|
+
const l0Result = processResponseMarkdown(l0Response, spec, strictnessDefaults(0));
|
|
30
|
+
console.log("L0 OK:", l0Result.ok);
|
|
31
|
+
console.log("L0 Issues:", l0Result.issues);
|
|
32
|
+
// --- L1 Test ---
|
|
33
|
+
console.log("\n--- Level 1 Test ---");
|
|
34
|
+
const l1Response = `
|
|
35
|
+
## Short answer
|
|
36
|
+
Yes.
|
|
37
|
+
|
|
38
|
+
## Long answer
|
|
39
|
+
Full details.
|
|
40
|
+
|
|
41
|
+
## Reasoning
|
|
42
|
+
1. Step one.
|
|
43
|
+
2. Step two.
|
|
44
|
+
|
|
45
|
+
## Assumptions
|
|
46
|
+
- Assumption A.
|
|
47
|
+
|
|
48
|
+
## Unknowns
|
|
49
|
+
None
|
|
50
|
+
`;
|
|
51
|
+
const l1Result = processResponseMarkdown(l1Response, spec, strictnessDefaults(1));
|
|
52
|
+
console.log("L1 OK:", l1Result.ok);
|
|
53
|
+
console.log("L1 Issues:", l1Result.issues);
|
|
54
|
+
// --- L2 Test ---
|
|
55
|
+
console.log("\n--- Level 2 Test ---");
|
|
56
|
+
const l2Response = `
|
|
57
|
+
Some chatter before.
|
|
58
|
+
\`\`\`markdown
|
|
59
|
+
## Short answer
|
|
60
|
+
Yes.
|
|
61
|
+
## Long answer
|
|
62
|
+
None
|
|
63
|
+
## Reasoning
|
|
64
|
+
1. A
|
|
65
|
+
## Assumptions
|
|
66
|
+
None
|
|
67
|
+
## Unknowns
|
|
68
|
+
None
|
|
69
|
+
\`\`\`
|
|
70
|
+
Some chatter after.
|
|
71
|
+
`;
|
|
72
|
+
const l2Result = processResponseMarkdown(l2Response, spec, strictnessDefaults(2));
|
|
73
|
+
console.log("L2 OK (should be false if chatter exists):", l2Result.ok);
|
|
74
|
+
console.log("L2 Issues (should include 'content_outside_container'):", l2Result.issues);
|
|
75
|
+
const l2ResponseClean = `\`\`\`markdown
|
|
76
|
+
## Short answer
|
|
77
|
+
Yes.
|
|
78
|
+
## Long answer
|
|
79
|
+
None
|
|
80
|
+
## Reasoning
|
|
81
|
+
1. A
|
|
82
|
+
## Assumptions
|
|
83
|
+
None
|
|
84
|
+
## Unknowns
|
|
85
|
+
None
|
|
86
|
+
\`\`\``;
|
|
87
|
+
const l2ResultClean = processResponseMarkdown(l2ResponseClean, spec, strictnessDefaults(2));
|
|
88
|
+
console.log("L2 Clean OK:", l2ResultClean.ok);
|
|
89
|
+
// --- L3 Test ---
|
|
90
|
+
console.log("\n--- Level 3 Test ---");
|
|
91
|
+
const l3Response = `\`\`\`markdown
|
|
92
|
+
## Short answer
|
|
93
|
+
Data processed.
|
|
94
|
+
## Long answer
|
|
95
|
+
None
|
|
96
|
+
## Reasoning
|
|
97
|
+
1. Step
|
|
98
|
+
## Assumptions
|
|
99
|
+
None
|
|
100
|
+
## Unknowns
|
|
101
|
+
None
|
|
102
|
+
|
|
103
|
+
\`\`\`json
|
|
104
|
+
{ "status": "success", "val": 42 }
|
|
105
|
+
\`\`\`
|
|
106
|
+
\`\`\``;
|
|
107
|
+
// The regex in processor.ts is: /```json\s*\n([\s\S]*?)\n```/i
|
|
108
|
+
// Let's see why it failed. Ah, the innerMarkdown was extracted but maybe the nested blocks were messed up.
|
|
109
|
+
// Actually, l3Result returned issues: [ 'content_outside_container', 'json_payload_missing' ]
|
|
110
|
+
// content_outside_container is due to the trailing \`\`\` outside if the first one was matched greedily?
|
|
111
|
+
// No, regex is non-greedy in container.ts: /\`\`\`" + fenceLang + "\\s*\\n([\\s\\S]*?)\\n\`\`\`/i
|
|
112
|
+
// Wait, the container extractor in container.ts uses: /\`\`\`" + fenceLang + "\\s*\\n([\\s\\S]*?)\\n\`\`\`/i
|
|
113
|
+
// In my L3 test:
|
|
114
|
+
// \`\`\`markdown
|
|
115
|
+
// ...
|
|
116
|
+
// \`\`\`json
|
|
117
|
+
// ...
|
|
118
|
+
// \`\`\`
|
|
119
|
+
// \`\`\`
|
|
120
|
+
// The second to last \`\`\` matches the end of the markdown block. The last \`\`\` is "outside".
|
|
121
|
+
const l3ResponseFixed = `\`\`\`markdown
|
|
122
|
+
## Short answer
|
|
123
|
+
Data processed.
|
|
124
|
+
## Long answer
|
|
125
|
+
None
|
|
126
|
+
## Reasoning
|
|
127
|
+
1. Step
|
|
128
|
+
## Assumptions
|
|
129
|
+
None
|
|
130
|
+
## Unknowns
|
|
131
|
+
None
|
|
132
|
+
|
|
133
|
+
\`\`\`json
|
|
134
|
+
{ "status": "success", "val": 42 }
|
|
135
|
+
\`\`\`
|
|
136
|
+
\`\`\``;
|
|
137
|
+
// In this one there are two closing fences.
|
|
138
|
+
const l3ResponseSimple = `\`\`\`markdown
|
|
139
|
+
## Short answer
|
|
140
|
+
Data processed.
|
|
141
|
+
## Long answer
|
|
142
|
+
None
|
|
143
|
+
## Reasoning
|
|
144
|
+
1. Step
|
|
145
|
+
## Assumptions
|
|
146
|
+
None
|
|
147
|
+
## Unknowns
|
|
148
|
+
None
|
|
149
|
+
|
|
150
|
+
\`\`\`json
|
|
151
|
+
{ "status": "success", "val": 42 }
|
|
152
|
+
\`\`\`
|
|
153
|
+
\`\`\``;
|
|
154
|
+
// Let's try again with a simpler L3 mock
|
|
155
|
+
const l3ResponseSuccess = `\`\`\`markdown
|
|
156
|
+
## Short answer
|
|
157
|
+
Done.
|
|
158
|
+
## Long answer
|
|
159
|
+
None
|
|
160
|
+
## Reasoning
|
|
161
|
+
1. A
|
|
162
|
+
## Assumptions
|
|
163
|
+
None
|
|
164
|
+
## Unknowns
|
|
165
|
+
None
|
|
166
|
+
|
|
167
|
+
\`\`\`json
|
|
168
|
+
{"ok": true}
|
|
169
|
+
\`\`\`
|
|
170
|
+
\`\`\``;
|
|
171
|
+
const lResult3 = processResponseMarkdown(l3ResponseSuccess, spec, strictnessDefaults(3));
|
|
172
|
+
console.log("L3 Success OK:", lResult3.ok);
|
|
173
|
+
console.log("L3 Issues:", lResult3.issues);
|
|
174
|
+
// --- Semi-Strict Test ---
|
|
175
|
+
console.log("\n--- Semi-Strict Test ---");
|
|
176
|
+
const semiStrictSpecText = `
|
|
177
|
+
## Output format
|
|
178
|
+
- Answer — prose (required)
|
|
179
|
+
- Extra — list (optional)
|
|
180
|
+
`;
|
|
181
|
+
const semiStrictSpec = parseOutputFormatSpec(semiStrictSpecText);
|
|
182
|
+
const semiStrictResponse = `
|
|
183
|
+
## Answer
|
|
184
|
+
This is the answer.
|
|
185
|
+
`;
|
|
186
|
+
// Level 1 defaults to requireAllSections: true.
|
|
187
|
+
// But "Extra" is marked (optional).
|
|
188
|
+
const semiStrictResult = processResponseMarkdown(semiStrictResponse, semiStrictSpec, { level: 1 });
|
|
189
|
+
console.log("Semi-Strict Missing Optional OK:", semiStrictResult.ok); // Should be true
|
|
190
|
+
console.log("Semi-Strict Issues:", semiStrictResult.issues);
|
|
191
|
+
const semiStrictResponseError = `
|
|
192
|
+
## Extra
|
|
193
|
+
- Something
|
|
194
|
+
`;
|
|
195
|
+
const semiStrictResultError = processResponseMarkdown(semiStrictResponseError, semiStrictSpec, { level: 1 });
|
|
196
|
+
console.log("Semi-Strict Missing Required OK:", semiStrictResultError.ok); // Should be false
|
|
197
|
+
console.log("Semi-Strict Issues (should have missing_section:Answer):", semiStrictResultError.issues.map((i) => i.code));
|
|
198
|
+
// --- Mode B (Issues Envelope) Test ---
|
|
199
|
+
console.log("\n--- Mode B Test ---");
|
|
200
|
+
const modeBResponse = `
|
|
201
|
+
## Status
|
|
202
|
+
- status: error
|
|
203
|
+
- code: missing_input
|
|
204
|
+
- message: The user forgot the org_id.
|
|
205
|
+
|
|
206
|
+
## Issues
|
|
207
|
+
- issue: missing_org_id
|
|
208
|
+
hint: please provide org_id
|
|
209
|
+
`;
|
|
210
|
+
const modeBResult = processResponseMarkdown(modeBResponse, semiStrictSpec, { level: 1 });
|
|
211
|
+
console.log("Mode B Detected:", !!modeBResult.issuesEnvelope);
|
|
212
|
+
console.log("Mode B Status Code:", modeBResult.issuesEnvelope?.status.code);
|
|
213
|
+
console.log("Mode B OK (should be false for error status):", modeBResult.ok);
|
package/dist/types.d.ts
CHANGED
|
@@ -1,12 +1,8 @@
|
|
|
1
1
|
export type FlexMetaValue = string | string[] | number | boolean | null;
|
|
2
2
|
export interface FlexPayload {
|
|
3
|
-
/** Language from the fenced block, e.g. "json", "yaml", "text" */
|
|
4
3
|
lang?: string;
|
|
5
|
-
/** Parsed value for json fences; otherwise a string raw value */
|
|
6
4
|
value: unknown;
|
|
7
|
-
/** Raw text inside the fence (no surrounding ``` lines) */
|
|
8
5
|
raw: string;
|
|
9
|
-
/** If lang=json but parsing failed */
|
|
10
6
|
parseError?: string;
|
|
11
7
|
}
|
|
12
8
|
export interface FlexFrame {
|
|
@@ -14,37 +10,23 @@ export interface FlexFrame {
|
|
|
14
10
|
role?: string;
|
|
15
11
|
id?: string;
|
|
16
12
|
ts?: string;
|
|
17
|
-
/** Metadata from @key: lines */
|
|
18
13
|
meta?: Record<string, FlexMetaValue>;
|
|
19
|
-
/** Body markdown between header/meta and next frame header */
|
|
20
14
|
body_md?: string;
|
|
21
|
-
/** Payloads keyed by @payload:name: X */
|
|
22
15
|
payloads?: Record<string, FlexPayload>;
|
|
23
16
|
}
|
|
24
17
|
export interface FlexDocument {
|
|
18
|
+
title?: string;
|
|
19
|
+
meta?: Record<string, FlexMetaValue>;
|
|
25
20
|
frames: FlexFrame[];
|
|
26
21
|
}
|
|
27
22
|
export interface ParseOptions {
|
|
28
|
-
/**
|
|
29
|
-
* Which metadata keys should be split by commas into string[]
|
|
30
|
-
* Default: ["tags", "refs"]
|
|
31
|
-
*/
|
|
32
23
|
arrayMetaKeys?: string[];
|
|
24
|
+
metaTypeMode?: "strings" | "infer" | "schema";
|
|
25
|
+
metaSchema?: Record<string, "string" | "number" | "boolean" | "null">;
|
|
33
26
|
}
|
|
34
27
|
export interface StringifyOptions {
|
|
35
|
-
/**
|
|
36
|
-
* If true, omit empty sections when converting JSON -> FlexMD.
|
|
37
|
-
* Default: true
|
|
38
|
-
*/
|
|
39
28
|
skipEmpty?: boolean;
|
|
40
|
-
/**
|
|
41
|
-
* Which meta keys should be rendered as comma-separated lists if arrays.
|
|
42
|
-
* Default: ["tags", "refs"]
|
|
43
|
-
*/
|
|
44
29
|
arrayMetaKeys?: string[];
|
|
45
|
-
/**
|
|
46
|
-
* Preferred fence marker. Default: "```"
|
|
47
|
-
*/
|
|
48
30
|
fence?: "```" | "~~~";
|
|
49
31
|
}
|
|
50
32
|
export interface FlexValidationError {
|
|
@@ -56,3 +38,139 @@ export interface FlexValidationResult {
|
|
|
56
38
|
valid: boolean;
|
|
57
39
|
errors: FlexValidationError[];
|
|
58
40
|
}
|
|
41
|
+
export type ResponseKind = "flexmd" | "issues" | "markdown";
|
|
42
|
+
export type Enforcement = "ignore" | "warn" | "error";
|
|
43
|
+
export interface ValidationPolicy {
|
|
44
|
+
missingSection?: Enforcement;
|
|
45
|
+
emptyRequiredSection?: Enforcement;
|
|
46
|
+
wrongSectionKind?: Enforcement;
|
|
47
|
+
containerMissing?: Enforcement;
|
|
48
|
+
containerMultiple?: Enforcement;
|
|
49
|
+
containerOutsideText?: Enforcement;
|
|
50
|
+
duplicateSection?: Enforcement;
|
|
51
|
+
malformedTable?: Enforcement;
|
|
52
|
+
malformedOrderedTable?: Enforcement;
|
|
53
|
+
noneIsAcceptableContent?: boolean;
|
|
54
|
+
}
|
|
55
|
+
export type Severity = "info" | "warn" | "error";
|
|
56
|
+
export type IssueCode = "ISSUES_ENVELOPE_PRESENT" | "CONTAINER_MISSING" | "CONTAINER_MULTIPLE" | "CONTAINER_OUTSIDE_TEXT" | "MISSING_SECTION" | "EMPTY_REQUIRED_SECTION" | "DUPLICATE_SECTION" | "WRONG_SECTION_KIND" | "MALFORMED_TABLE" | "MALFORMED_ORDERED_TABLE";
|
|
57
|
+
export interface ValidationIssue {
|
|
58
|
+
code: IssueCode;
|
|
59
|
+
severity: Severity;
|
|
60
|
+
message: string;
|
|
61
|
+
sectionName?: string;
|
|
62
|
+
span?: {
|
|
63
|
+
start: number;
|
|
64
|
+
end: number;
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
export interface ValidationResult {
|
|
68
|
+
ok: boolean;
|
|
69
|
+
level: 0 | 1 | 2 | 3;
|
|
70
|
+
issues: ValidationIssue[];
|
|
71
|
+
stats?: {
|
|
72
|
+
detectedKind: "markdown" | "issues" | "sectioned" | "fenced";
|
|
73
|
+
sectionCount: number;
|
|
74
|
+
missingRequired: string[];
|
|
75
|
+
duplicates: string[];
|
|
76
|
+
container: {
|
|
77
|
+
fenceCount: number;
|
|
78
|
+
hasOutsideText: boolean;
|
|
79
|
+
fenceLangs: string[];
|
|
80
|
+
};
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
export type SectionKind = "text" | "list" | "ordered_list" | "table" | "ordered_table";
|
|
84
|
+
export interface OutputSectionSpec {
|
|
85
|
+
name: string;
|
|
86
|
+
kind?: SectionKind;
|
|
87
|
+
required?: boolean;
|
|
88
|
+
columns?: string[];
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* @deprecated Use OutputSectionSpec
|
|
92
|
+
*/
|
|
93
|
+
export interface OfsSection extends OutputSectionSpec {
|
|
94
|
+
hint?: string;
|
|
95
|
+
emptyAllowed?: boolean;
|
|
96
|
+
}
|
|
97
|
+
export interface OfsTable {
|
|
98
|
+
columns: string[];
|
|
99
|
+
kind: "table" | "ordered_table";
|
|
100
|
+
by?: string;
|
|
101
|
+
required?: boolean;
|
|
102
|
+
}
|
|
103
|
+
export interface OutputFormatSpec {
|
|
104
|
+
sections: OutputSectionSpec[];
|
|
105
|
+
emptySectionValue?: string;
|
|
106
|
+
descriptorType?: "output_format_spec";
|
|
107
|
+
format?: "markdown";
|
|
108
|
+
sectionOrderMatters?: boolean;
|
|
109
|
+
tablesOptional?: boolean;
|
|
110
|
+
tables?: OfsTable[];
|
|
111
|
+
}
|
|
112
|
+
export interface MdNode {
|
|
113
|
+
title: string;
|
|
114
|
+
level: number;
|
|
115
|
+
key: string;
|
|
116
|
+
id?: string;
|
|
117
|
+
content_md: string;
|
|
118
|
+
children: MdNode[];
|
|
119
|
+
}
|
|
120
|
+
export interface MdOutline {
|
|
121
|
+
type: "md_outline";
|
|
122
|
+
nodes: MdNode[];
|
|
123
|
+
}
|
|
124
|
+
export interface ListItem {
|
|
125
|
+
text: string;
|
|
126
|
+
index?: number;
|
|
127
|
+
children: ListItem[];
|
|
128
|
+
}
|
|
129
|
+
export interface ParsedList {
|
|
130
|
+
kind: "list";
|
|
131
|
+
ordered: boolean;
|
|
132
|
+
items: ListItem[];
|
|
133
|
+
}
|
|
134
|
+
export interface ParsedTable {
|
|
135
|
+
kind: "table" | "ordered_table";
|
|
136
|
+
by?: string;
|
|
137
|
+
columns: string[];
|
|
138
|
+
rows: string[][];
|
|
139
|
+
}
|
|
140
|
+
export interface ExtractedResult {
|
|
141
|
+
outline: MdOutline;
|
|
142
|
+
sectionsByName: Record<string, {
|
|
143
|
+
nodeKey: string;
|
|
144
|
+
nodeLevel: number;
|
|
145
|
+
md: string;
|
|
146
|
+
list?: ParsedList;
|
|
147
|
+
}>;
|
|
148
|
+
tables: ParsedTable[];
|
|
149
|
+
}
|
|
150
|
+
export interface ProcessResponseResult {
|
|
151
|
+
ok: boolean;
|
|
152
|
+
strictness: any;
|
|
153
|
+
usedContainer: boolean;
|
|
154
|
+
innerMarkdown: string;
|
|
155
|
+
validation: ValidationResult;
|
|
156
|
+
extracted?: ExtractedResult;
|
|
157
|
+
issues: ValidationIssue[];
|
|
158
|
+
issuesEnvelope?: IssuesEnvelope;
|
|
159
|
+
}
|
|
160
|
+
export type DetectedKind = "flexmd_fence" | "flexdoc_json_fence" | "raw_flexmd" | "markdown_snippet" | "none";
|
|
161
|
+
export interface DetectedObject {
|
|
162
|
+
kind: DetectedKind;
|
|
163
|
+
confidence: number;
|
|
164
|
+
start: number;
|
|
165
|
+
end: number;
|
|
166
|
+
raw: string;
|
|
167
|
+
inner?: string;
|
|
168
|
+
}
|
|
169
|
+
export interface IssuesEnvelope {
|
|
170
|
+
isIssuesEnvelope: boolean;
|
|
171
|
+
sections: Record<string, {
|
|
172
|
+
heading: string;
|
|
173
|
+
body: string;
|
|
174
|
+
bullets: string[];
|
|
175
|
+
}>;
|
|
176
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { Enforcement, SemiStrictPolicy } from "../strictness/types.js";
|
|
2
|
+
import { ValidationIssue } from "./types.js";
|
|
3
|
+
export declare function enforcementToSeverity(e: Enforcement): "error" | "warning";
|
|
4
|
+
/**
|
|
5
|
+
* Decide whether to emit an issue:
|
|
6
|
+
* - "ignore" => return null
|
|
7
|
+
* - "warn"/"error" => return ValidationIssue with chosen severity
|
|
8
|
+
*/
|
|
9
|
+
export declare function makeIssue(policy: SemiStrictPolicy | undefined, key: keyof SemiStrictPolicy, fallback: Enforcement, issue: Omit<ValidationIssue, "severity">): ValidationIssue | null;
|
|
10
|
+
export declare function hasErrors(issues: ValidationIssue[]): boolean;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export function enforcementToSeverity(e) {
|
|
2
|
+
return e === "error" ? "error" : "warning";
|
|
3
|
+
}
|
|
4
|
+
/**
|
|
5
|
+
* Decide whether to emit an issue:
|
|
6
|
+
* - "ignore" => return null
|
|
7
|
+
* - "warn"/"error" => return ValidationIssue with chosen severity
|
|
8
|
+
*/
|
|
9
|
+
export function makeIssue(policy, key, fallback, issue) {
|
|
10
|
+
const enforcement = (policy?.[key] ?? fallback);
|
|
11
|
+
if (enforcement === "ignore")
|
|
12
|
+
return null;
|
|
13
|
+
return { severity: enforcementToSeverity(enforcement), ...issue };
|
|
14
|
+
}
|
|
15
|
+
export function hasErrors(issues) {
|
|
16
|
+
return issues.some(i => i.severity === "error");
|
|
17
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export type ValidationSeverity = "error" | "warning";
|
|
2
|
+
export interface ValidationIssue {
|
|
3
|
+
severity: ValidationSeverity;
|
|
4
|
+
code: string;
|
|
5
|
+
message: string;
|
|
6
|
+
path?: string;
|
|
7
|
+
}
|
|
8
|
+
export interface ValidationResult {
|
|
9
|
+
ok: boolean;
|
|
10
|
+
issues: ValidationIssue[];
|
|
11
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|