markdown-flavor-detection 0.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.
Files changed (47) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +7 -0
  3. package/dist/fg-config-resolution.d.ts +39 -0
  4. package/dist/fg-config-resolution.d.ts.map +1 -0
  5. package/dist/fg-config-resolution.js +200 -0
  6. package/dist/fg-config-resolution.js.map +1 -0
  7. package/dist/fgattributes.d.ts +26 -0
  8. package/dist/fgattributes.d.ts.map +1 -0
  9. package/dist/fgattributes.js +126 -0
  10. package/dist/fgattributes.js.map +1 -0
  11. package/dist/fgignore.d.ts +8 -0
  12. package/dist/fgignore.d.ts.map +1 -0
  13. package/dist/fgignore.js +35 -0
  14. package/dist/fgignore.js.map +1 -0
  15. package/dist/flavor-resolution.d.ts +32 -0
  16. package/dist/flavor-resolution.d.ts.map +1 -0
  17. package/dist/flavor-resolution.js +56 -0
  18. package/dist/flavor-resolution.js.map +1 -0
  19. package/dist/flavors.d.ts +15 -0
  20. package/dist/flavors.d.ts.map +1 -0
  21. package/dist/flavors.js +44 -0
  22. package/dist/flavors.js.map +1 -0
  23. package/dist/index.d.ts +8 -0
  24. package/dist/index.d.ts.map +1 -0
  25. package/dist/index.js +8 -0
  26. package/dist/index.js.map +1 -0
  27. package/dist/node.d.ts +13 -0
  28. package/dist/node.d.ts.map +1 -0
  29. package/dist/node.js +65 -0
  30. package/dist/node.js.map +1 -0
  31. package/dist/path-confinement.d.ts +5 -0
  32. package/dist/path-confinement.d.ts.map +1 -0
  33. package/dist/path-confinement.js +112 -0
  34. package/dist/path-confinement.js.map +1 -0
  35. package/dist/patterns.d.ts +7 -0
  36. package/dist/patterns.d.ts.map +1 -0
  37. package/dist/patterns.js +229 -0
  38. package/dist/patterns.js.map +1 -0
  39. package/dist/structured-profiles.d.ts +22 -0
  40. package/dist/structured-profiles.d.ts.map +1 -0
  41. package/dist/structured-profiles.js +150 -0
  42. package/dist/structured-profiles.js.map +1 -0
  43. package/dist/syntax-inference.d.ts +4 -0
  44. package/dist/syntax-inference.d.ts.map +1 -0
  45. package/dist/syntax-inference.js +75 -0
  46. package/dist/syntax-inference.js.map +1 -0
  47. package/package.json +26 -0
@@ -0,0 +1,150 @@
1
+ export const STRUCTURED_MARKDOWN_PROFILE_IDS = [
2
+ 'keep-a-changelog',
3
+ 'common-changelog',
4
+ 'madr',
5
+ ];
6
+ export function isStructuredMarkdownProfileId(value) {
7
+ return (typeof value === 'string' &&
8
+ STRUCTURED_MARKDOWN_PROFILE_IDS.includes(value));
9
+ }
10
+ export function isStructuredProfileSelection(value) {
11
+ return (value === 'auto' ||
12
+ value === 'none' ||
13
+ (Array.isArray(value) && isValidStructuredProfileList(value)));
14
+ }
15
+ export function isValidStructuredProfileList(value) {
16
+ const seen = new Set();
17
+ for (const item of value) {
18
+ if (!isStructuredMarkdownProfileId(item) || seen.has(item)) {
19
+ return false;
20
+ }
21
+ seen.add(item);
22
+ }
23
+ return !(seen.has('keep-a-changelog') && seen.has('common-changelog'));
24
+ }
25
+ export function resolveStructuredProfiles(input) {
26
+ if (Array.isArray(input.selection)) {
27
+ return {
28
+ structuredProfiles: input.selection,
29
+ structuredProfileSource: 'explicit-selection',
30
+ };
31
+ }
32
+ if (input.selection === 'none') {
33
+ return { structuredProfiles: [], structuredProfileSource: 'none' };
34
+ }
35
+ if (Array.isArray(input.fgAttributesSelection)) {
36
+ return {
37
+ structuredProfiles: input.fgAttributesSelection,
38
+ structuredProfileSource: 'fgattributes',
39
+ };
40
+ }
41
+ if (input.fgAttributesSelection === 'none') {
42
+ return { structuredProfiles: [], structuredProfileSource: 'none' };
43
+ }
44
+ return {
45
+ structuredProfiles: inferStructuredProfiles(input),
46
+ structuredProfileSource: 'structured-profile-inference',
47
+ };
48
+ }
49
+ export function inferStructuredProfiles(input) {
50
+ const sample = (input.syntaxText ?? '').slice(0, 64 * 1024);
51
+ const profiles = [];
52
+ const changelog = inferChangelogProfile(input.path, sample);
53
+ if (changelog) {
54
+ profiles.push(changelog);
55
+ }
56
+ if (hasMadrEvidence(input.path, sample)) {
57
+ profiles.push('madr');
58
+ }
59
+ return profiles;
60
+ }
61
+ function inferChangelogProfile(path, text) {
62
+ if (!/CHANGELOG\.md$/i.test(path)) {
63
+ return undefined;
64
+ }
65
+ const first = firstHeading(text);
66
+ if (first?.level !== 1 || first.text !== 'Changelog') {
67
+ return undefined;
68
+ }
69
+ const hasUnreleased = /^##\s+\[?Unreleased\]?\s*$/im.test(text);
70
+ const categories = headingTexts(text, 3);
71
+ const categorySet = new Set(categories);
72
+ const keepCategories = ['Added', 'Changed', 'Deprecated', 'Removed', 'Fixed', 'Security'].filter((category) => categorySet.has(category));
73
+ const hasKeepOnlyCategory = categorySet.has('Deprecated') || categorySet.has('Security');
74
+ if (hasUnreleased && keepCategories.length >= 2) {
75
+ return 'keep-a-changelog';
76
+ }
77
+ if (hasKeepOnlyCategory && keepCategories.length >= 2) {
78
+ return 'keep-a-changelog';
79
+ }
80
+ if (hasCommonChangelogReleaseBlock(text)) {
81
+ return 'common-changelog';
82
+ }
83
+ if (/^##\s+\[\d+\.\d+\.\d+[^\]\n]*\]\s+-\s+\d{4}-\d{2}-\d{2}\s*$/im.test(text) &&
84
+ keepCategories.length >= 2) {
85
+ return 'keep-a-changelog';
86
+ }
87
+ return undefined;
88
+ }
89
+ function hasCommonChangelogReleaseBlock(text) {
90
+ const commonCategories = ['Changed', 'Added', 'Removed', 'Fixed'];
91
+ return releaseBlocks(text).some((block) => /^\[?\d+\.\d+\.\d+[^\]\n]*\]?\s+-\s+\d{4}-\d{2}-\d{2}\s*$/i.test(block.heading) &&
92
+ sameStringList(headingTexts(block.text, 3), commonCategories) &&
93
+ /-\s+.+\(\[[^\]]+\]\([^)]+\)\)/.test(block.text) &&
94
+ (/\*\*Breaking:\*\*/.test(block.text) || /-\s+[A-Za-z][\w -]+:\s+/.test(block.text)));
95
+ }
96
+ function releaseBlocks(text) {
97
+ const headingMatches = [...text.matchAll(/^##\s+(.+?)\s*$/gim)];
98
+ return headingMatches.map((match, index) => {
99
+ const next = headingMatches[index + 1];
100
+ return {
101
+ heading: match[1].trim(),
102
+ text: text.slice(match.index, next?.index),
103
+ };
104
+ });
105
+ }
106
+ function sameStringList(left, right) {
107
+ return left.length === right.length && left.every((value, index) => value === right[index]);
108
+ }
109
+ function firstHeading(text) {
110
+ let body = text;
111
+ if (body.startsWith('---')) {
112
+ const closing = body.indexOf('\n---', 3);
113
+ if (closing >= 0) {
114
+ body = body.slice(closing + 4);
115
+ }
116
+ }
117
+ const match = /^(#{1,6})\s+(.+?)\s*$/m.exec(body);
118
+ if (match === null)
119
+ return undefined;
120
+ return { level: match[1].length, text: match[2].trim() };
121
+ }
122
+ function hasMadrEvidence(path, text) {
123
+ const normalizedPath = path.replace(/\\/g, '/');
124
+ const hasPath = /(^|\/)(docs\/decisions|decisions)\//i.test(normalizedPath);
125
+ const hasFilename = /\/\d{4}-[a-z0-9]+(?:-[a-z0-9]+)*\.md$/i.test(normalizedPath);
126
+ if (!hasPath && !hasFilename) {
127
+ return false;
128
+ }
129
+ const headings = new Set(headingTexts(text, 2));
130
+ const madrHeadingCount = [
131
+ 'Context and Problem Statement',
132
+ 'Considered Options',
133
+ 'Decision Outcome',
134
+ ].filter((heading) => headings.has(heading)).length;
135
+ const hasMetadata = /^---[\s\S]*\b(status|date|decision-makers|consulted|informed)\s*:/m.test(text);
136
+ const hasOptionEvidence = /\b(Good|Neutral|Bad), because\b/.test(text);
137
+ return madrHeadingCount >= 2 && (hasMetadata || hasOptionEvidence || (hasPath && hasFilename));
138
+ }
139
+ function headingTexts(text, level) {
140
+ const result = [];
141
+ for (const rawLine of text.split('\n')) {
142
+ const line = rawLine.replace(/\r$/, '');
143
+ const match = /^(#{1,6})\s+(.+?)\s*$/.exec(line);
144
+ if (match !== null && match[1].length === level) {
145
+ result.push(match[2].trim());
146
+ }
147
+ }
148
+ return result;
149
+ }
150
+ //# sourceMappingURL=structured-profiles.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"structured-profiles.js","sourceRoot":"","sources":["../src/structured-profiles.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import type { MarkdownFlavorId } from './flavors.js';
2
+ /** Infer a Markdown flavor only from strong, low-ambiguity syntax evidence. */
3
+ export declare function inferMarkdownFlavorFromSyntax(text: string | undefined): MarkdownFlavorId | undefined;
4
+ //# sourceMappingURL=syntax-inference.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"syntax-inference.d.ts","sourceRoot":"","sources":["../src/syntax-inference.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAIrD,+EAA+E;AAC/E,wBAAgB,6BAA6B,CAC3C,IAAI,EAAE,MAAM,GAAG,SAAS,GACvB,gBAAgB,GAAG,SAAS,CAmC9B"}
@@ -0,0 +1,75 @@
1
+ const MAX_SYNTAX_SAMPLE_BYTES = 64 * 1024;
2
+ /** Infer a Markdown flavor only from strong, low-ambiguity syntax evidence. */
3
+ export function inferMarkdownFlavorFromSyntax(text) {
4
+ if (!text) {
5
+ return undefined;
6
+ }
7
+ const sample = text.slice(0, MAX_SYNTAX_SAMPLE_BYTES);
8
+ if (hasMdxEvidence(sample)) {
9
+ return 'mdx';
10
+ }
11
+ if (hasRMarkdownEvidence(sample)) {
12
+ return 'r-markdown';
13
+ }
14
+ if (hasStackOverflowEvidence(sample)) {
15
+ return 'stack-overflow';
16
+ }
17
+ if (hasRedditEvidence(sample)) {
18
+ return 'reddit';
19
+ }
20
+ if (hasGlfmEvidence(sample)) {
21
+ return 'glfm';
22
+ }
23
+ if (hasMultiMarkdownEvidence(sample)) {
24
+ return 'multimarkdown';
25
+ }
26
+ if (hasPandocEvidence(sample)) {
27
+ return 'pandoc';
28
+ }
29
+ if (hasKramdownEvidence(sample)) {
30
+ return 'kramdown';
31
+ }
32
+ if (hasMarkdownExtraEvidence(sample)) {
33
+ return 'markdown-extra';
34
+ }
35
+ return undefined;
36
+ }
37
+ function hasMdxEvidence(text) {
38
+ return (/(^|\n)\s*(import|export)\s+[\s\S]*?\n/.test(text) &&
39
+ /<[A-Z][A-Za-z0-9]*(?:\s|>|\/>)/.test(text));
40
+ }
41
+ function hasRMarkdownEvidence(text) {
42
+ return /(^|\n)```\{[a-zA-Z]+(?:\s+[^}]*)?\}/.test(text) || /`r\s+[^`]+`/.test(text);
43
+ }
44
+ function hasStackOverflowEvidence(text) {
45
+ return (/\[(?:meta-)?tag:[^\]]+\]/.test(text) ||
46
+ /<!--\s*language(?:-all)?:\s*[^-]+-->/.test(text) ||
47
+ /(^|\n)```\s+lang-[\w-]+/.test(text));
48
+ }
49
+ function hasRedditEvidence(text) {
50
+ return />![\s\S]*?!<|(\s|^)\^\([^)]+\)/.test(text) && /\b[ru]\/[A-Za-z0-9_]+\b/.test(text);
51
+ }
52
+ function hasGlfmEvidence(text) {
53
+ return (/\[\[_TOC_\]\]/.test(text) ||
54
+ /(^|\n)\s*[-*]\s+\[~\]\s+/.test(text) ||
55
+ /(^|\s)(?:[#!&]\d+|[A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+#\d+)(?=\s|[.,;)]|$)/.test(text));
56
+ }
57
+ function hasPandocEvidence(text) {
58
+ return (/(^|\n)%\s+\S/.test(text) ||
59
+ /(^|\s)\[@[A-Za-z][\w:-]*(?:[,;\]\s])/.test(text) ||
60
+ /(^|\s)@[A-Za-z][\w:-]*(?=\s|[.,;)\]])/.test(text) ||
61
+ /(^|\n):::\s*\{[^}]+\}/.test(text));
62
+ }
63
+ function hasMultiMarkdownEvidence(text) {
64
+ return (/^(Title|Author|Date|Keywords):\s+\S/m.test(text) &&
65
+ (/(^|\n)#[^\n]+\[[A-Za-z][\w:-]+\]/.test(text) ||
66
+ /\[#[-\w:]+\]:/.test(text) ||
67
+ /\[[^\]]+\]\[\]/.test(text)));
68
+ }
69
+ function hasKramdownEvidence(text) {
70
+ return /(^|\n)\s*\{:\s*[.#][^}]+\}/.test(text) || /(^|\n)#{1,6}[^\n]+\{#[^}]+\}/.test(text);
71
+ }
72
+ function hasMarkdownExtraEvidence(text) {
73
+ return /^\*\[[^\]]+\]:\s+\S/m.test(text) && /(^|\n)\s*\{#[^}]+\}/.test(text);
74
+ }
75
+ //# sourceMappingURL=syntax-inference.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"syntax-inference.js","sourceRoot":"","sources":["../src/syntax-inference.ts"],"names":[],"mappings":"AAEA,MAAM,uBAAuB,GAAG,EAAE,GAAG,IAAI,CAAC;AAE1C,+EAA+E;AAC/E,MAAM,UAAU,6BAA6B,CAC3C,IAAwB;IAExB,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,uBAAuB,CAAC,CAAC;IAEtD,IAAI,cAAc,CAAC,MAAM,CAAC,EAAE,CAAC;QAC3B,OAAO,KAAK,CAAC;IACf,CAAC;IACD,IAAI,oBAAoB,CAAC,MAAM,CAAC,EAAE,CAAC;QACjC,OAAO,YAAY,CAAC;IACtB,CAAC;IACD,IAAI,wBAAwB,CAAC,MAAM,CAAC,EAAE,CAAC;QACrC,OAAO,gBAAgB,CAAC;IAC1B,CAAC;IACD,IAAI,iBAAiB,CAAC,MAAM,CAAC,EAAE,CAAC;QAC9B,OAAO,QAAQ,CAAC;IAClB,CAAC;IACD,IAAI,eAAe,CAAC,MAAM,CAAC,EAAE,CAAC;QAC5B,OAAO,MAAM,CAAC;IAChB,CAAC;IACD,IAAI,wBAAwB,CAAC,MAAM,CAAC,EAAE,CAAC;QACrC,OAAO,eAAe,CAAC;IACzB,CAAC;IACD,IAAI,iBAAiB,CAAC,MAAM,CAAC,EAAE,CAAC;QAC9B,OAAO,QAAQ,CAAC;IAClB,CAAC;IACD,IAAI,mBAAmB,CAAC,MAAM,CAAC,EAAE,CAAC;QAChC,OAAO,UAAU,CAAC;IACpB,CAAC;IACD,IAAI,wBAAwB,CAAC,MAAM,CAAC,EAAE,CAAC;QACrC,OAAO,gBAAgB,CAAC;IAC1B,CAAC;IAED,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,SAAS,cAAc,CAAC,IAAY;IAClC,OAAO,CACL,uCAAuC,CAAC,IAAI,CAAC,IAAI,CAAC;QAClD,gCAAgC,CAAC,IAAI,CAAC,IAAI,CAAC,CAC5C,CAAC;AACJ,CAAC;AAED,SAAS,oBAAoB,CAAC,IAAY;IACxC,OAAO,qCAAqC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACtF,CAAC;AAED,SAAS,wBAAwB,CAAC,IAAY;IAC5C,OAAO,CACL,0BAA0B,CAAC,IAAI,CAAC,IAAI,CAAC;QACrC,sCAAsC,CAAC,IAAI,CAAC,IAAI,CAAC;QACjD,yBAAyB,CAAC,IAAI,CAAC,IAAI,CAAC,CACrC,CAAC;AACJ,CAAC;AAED,SAAS,iBAAiB,CAAC,IAAY;IACrC,OAAO,gCAAgC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,yBAAyB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC7F,CAAC;AAED,SAAS,eAAe,CAAC,IAAY;IACnC,OAAO,CACL,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC;QAC1B,0BAA0B,CAAC,IAAI,CAAC,IAAI,CAAC;QACrC,wEAAwE,CAAC,IAAI,CAAC,IAAI,CAAC,CACpF,CAAC;AACJ,CAAC;AAED,SAAS,iBAAiB,CAAC,IAAY;IACrC,OAAO,CACL,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC;QACzB,sCAAsC,CAAC,IAAI,CAAC,IAAI,CAAC;QACjD,uCAAuC,CAAC,IAAI,CAAC,IAAI,CAAC;QAClD,uBAAuB,CAAC,IAAI,CAAC,IAAI,CAAC,CACnC,CAAC;AACJ,CAAC;AAED,SAAS,wBAAwB,CAAC,IAAY;IAC5C,OAAO,CACL,sCAAsC,CAAC,IAAI,CAAC,IAAI,CAAC;QACjD,CAAC,kCAAkC,CAAC,IAAI,CAAC,IAAI,CAAC;YAC5C,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC;YAC1B,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAC/B,CAAC;AACJ,CAAC;AAED,SAAS,mBAAmB,CAAC,IAAY;IACvC,OAAO,4BAA4B,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,8BAA8B,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC9F,CAAC;AAED,SAAS,wBAAwB,CAAC,IAAY;IAC5C,OAAO,sBAAsB,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,qBAAqB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC/E,CAAC"}
package/package.json ADDED
@@ -0,0 +1,26 @@
1
+ {
2
+ "name": "markdown-flavor-detection",
3
+ "version": "0.0.0",
4
+ "type": "module",
5
+ "description": "Shared Markdown flavor detection and Flavor Grenade config resolution",
6
+ "license": "MIT",
7
+ "exports": {
8
+ ".": {
9
+ "types": "./dist/index.d.ts",
10
+ "import": "./dist/index.js"
11
+ },
12
+ "./node": {
13
+ "types": "./dist/node.d.ts",
14
+ "import": "./dist/node.js"
15
+ }
16
+ },
17
+ "types": "./dist/index.d.ts",
18
+ "files": [
19
+ "dist/",
20
+ "README.md",
21
+ "LICENSE"
22
+ ],
23
+ "publishConfig": {
24
+ "access": "public"
25
+ }
26
+ }