@salesforcedevs/sfdocs-liquid-lint-filtered-blocks 1.0.1-alpha.2 → 1.0.2-alpha.1

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 ADDED
@@ -0,0 +1,35 @@
1
+ # liquid-lint-filtered-blocks
2
+
3
+ This remark-lint plugin validates structural issues in Liquid filter blocks
4
+ (`{% englishonly %}` / `{% endenglishonly %}`, `{% future %}` / `{% endfuture %}`,
5
+ etc.) within sfdocs Markdown files.
6
+
7
+ ## What it checks
8
+
9
+ - **Redundant nesting**: a filter block inside another block of the same type is
10
+ redundant and likely a copy-paste mistake.
11
+ - **Entire file wrapped**: when all non-frontmatter content is inside a single
12
+ filter block, the topic should use `filters: [<tag>]` in the TOC instead.
13
+ - **Empty headings after removal**: headings outside a filter block whose entire
14
+ section body is inside that block would render as empty headings in filtered
15
+ builds.
16
+
17
+ ## Options
18
+
19
+ ```ts
20
+ {
21
+ filterTags?: string[]
22
+ }
23
+ ```
24
+
25
+ An array of Liquid filter tag names to validate (e.g. `["englishonly", "future"]`).
26
+ Each tag is checked independently.
27
+
28
+ ## Install & build
29
+
30
+ ```
31
+ yarn install && yarn build
32
+ ```
33
+
34
+ >> Release versioning and commits are automated via Lerna when you merge the
35
+ >> release PR.
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AA+HA,kBAA2C"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AA8GA,kBAA2C"}
package/dist/index.js CHANGED
@@ -6,24 +6,6 @@ const unified_lint_rule_1 = __importDefault(require("unified-lint-rule"));
6
6
  const unist_util_visit_1 = __importDefault(require("unist-util-visit"));
7
7
  const sfdocs_liquid_lint_utils_1 = require("@salesforcedevs/sfdocs-liquid-lint-utils");
8
8
  const SOURCE = 'sfdocs-liquid-lint:liquid-filtered-blocks';
9
- function findBlockRanges(content, tagName) {
10
- const ranges = [];
11
- const tagRe = new RegExp(`{%-?\\s*(${tagName}|end${tagName})\\s*-?%}`, 'g');
12
- const unmatchedOpeners = [];
13
- let match;
14
- while ((match = tagRe.exec(content)) !== null) {
15
- if (match[1] === tagName) {
16
- unmatchedOpeners.push(match.index);
17
- }
18
- else if (unmatchedOpeners.length > 0) {
19
- ranges.push({
20
- openStart: unmatchedOpeners.pop(),
21
- closeEnd: match.index + match[0].length,
22
- });
23
- }
24
- }
25
- return ranges;
26
- }
27
9
  function isInsideRange(offset, ranges) {
28
10
  return ranges.some(r => offset >= r.openStart && offset < r.closeEnd);
29
11
  }
@@ -73,19 +55,24 @@ function stripFilteredBlocks(section, allRanges, sectionOffset) {
73
55
  return result;
74
56
  }
75
57
  function validateTag(tree, file, raw, content, tagName) {
76
- const ranges = findBlockRanges(content, tagName);
58
+ const ranges = (0, sfdocs_liquid_lint_utils_1.findBlockRanges)(content, tagName);
77
59
  if (ranges.length === 0)
78
60
  return;
79
61
  for (const range of ranges) {
80
62
  if (isNestedBlock(range, ranges)) {
81
- file.message(`Redundant nested ${tagName} block already inside a ${tagName} block.`, (0, sfdocs_liquid_lint_utils_1.offsetToPosition)(raw, range.openStart));
63
+ if (tagName === 'englishonly') {
64
+ file.message(`Redundant nested englishonly block — already inside an englishonly block.`, (0, sfdocs_liquid_lint_utils_1.offsetToPosition)(raw, range.openStart));
65
+ }
66
+ else {
67
+ file.message(`Redundant nested ${tagName} block — already inside a ${tagName} block.`, (0, sfdocs_liquid_lint_utils_1.offsetToPosition)(raw, range.openStart));
68
+ }
82
69
  }
83
70
  }
84
71
  if (isEntireFileWrapped(content, ranges)) {
85
- file.message(`All content is inside ${tagName} block — use \`filters: [${tagName}]\` in TOC instead.`, (0, sfdocs_liquid_lint_utils_1.offsetToPosition)(raw, ranges[0].openStart));
72
+ file.message(`All content is inside ${tagName} block — use filters: [${tagName}] in TOC instead.`, (0, sfdocs_liquid_lint_utils_1.offsetToPosition)(raw, ranges[0].openStart));
86
73
  }
87
74
  for (const heading of findEmptyHeadings(tree, content, ranges)) {
88
- file.message(`Heading would have no content after ${tagName} block is removed.`, heading);
75
+ file.message(`Heading will have no content when the ${tagName} block is filtered out. Remove or adjust the heading.`, heading);
89
76
  }
90
77
  }
91
78
  function checkFilteredBlocks(tree, file, option) {
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@salesforcedevs/sfdocs-liquid-lint-filtered-blocks",
3
- "version": "1.0.1-alpha.2",
3
+ "version": "1.0.2-alpha.1",
4
4
  "description": "Validates structural issues in liquid filter blocks (englishonly, future, etc.).",
5
5
  "author": "SFDocs Team",
6
6
  "main": "dist/index.js",
@@ -14,7 +14,7 @@
14
14
  },
15
15
  "license": "MIT",
16
16
  "dependencies": {
17
- "@salesforcedevs/sfdocs-liquid-lint-utils": "1.0.2-alpha.2",
17
+ "@salesforcedevs/sfdocs-liquid-lint-utils": "1.0.3-alpha.1",
18
18
  "unified-lint-rule": "^1.0.6",
19
19
  "unist-util-visit": "^2.0.3",
20
20
  "vfile": "^4.2.1"
@@ -62,7 +62,7 @@ describe('sfdocs-lint:liquid-filtered-blocks', () => {
62
62
  const messages = run(md, { filterTags: ['englishonly'] }).messages;
63
63
  expect(messages).toHaveLength(1);
64
64
  expect(messages[0].message).toBe(
65
- 'Redundant nested englishonly block — already inside a englishonly block.',
65
+ 'Redundant nested englishonly block — already inside an englishonly block.',
66
66
  );
67
67
  expect(messages[0].source).toBe('sfdocs-liquid-lint');
68
68
  expect(messages[0].ruleId).toBe('liquid-filtered-blocks');
@@ -79,7 +79,7 @@ describe('sfdocs-lint:liquid-filtered-blocks', () => {
79
79
  const messages = run(md, { filterTags: ['englishonly'] }).messages;
80
80
  expect(messages).toHaveLength(1);
81
81
  expect(messages[0].message).toBe(
82
- 'All content is inside englishonly block — use `filters: [englishonly]` in TOC instead.',
82
+ 'All content is inside englishonly block — use filters: [englishonly] in TOC instead.',
83
83
  );
84
84
  });
85
85
 
@@ -97,7 +97,7 @@ describe('sfdocs-lint:liquid-filtered-blocks', () => {
97
97
  const messages = run(md, { filterTags: ['englishonly'] }).messages;
98
98
  expect(messages).toHaveLength(1);
99
99
  expect(messages[0].message).toBe(
100
- 'All content is inside englishonly block — use `filters: [englishonly]` in TOC instead.',
100
+ 'All content is inside englishonly block — use filters: [englishonly] in TOC instead.',
101
101
  );
102
102
  });
103
103
 
@@ -120,7 +120,7 @@ describe('sfdocs-lint:liquid-filtered-blocks', () => {
120
120
  const messages = run(md, { filterTags: ['englishonly'] }).messages;
121
121
  expect(messages).toHaveLength(1);
122
122
  expect(messages[0].message).toBe(
123
- 'Heading would have no content after englishonly block is removed.',
123
+ 'Heading will have no content when the englishonly block is filtered out. Remove or adjust the heading.',
124
124
  );
125
125
  });
126
126
 
package/src/index.ts CHANGED
@@ -1,34 +1,10 @@
1
1
  import rule from 'unified-lint-rule';
2
2
  import visit from 'unist-util-visit';
3
3
  import { VFile } from 'vfile';
4
- import { offsetToPosition, parseFrontmatter } from '@salesforcedevs/sfdocs-liquid-lint-utils';
4
+ import { offsetToPosition, parseFrontmatter, findBlockRanges, BlockRange } from '@salesforcedevs/sfdocs-liquid-lint-utils';
5
5
 
6
6
  const SOURCE = 'sfdocs-liquid-lint:liquid-filtered-blocks';
7
7
 
8
- interface BlockRange {
9
- openStart: number;
10
- closeEnd: number;
11
- }
12
-
13
- function findBlockRanges(content: string, tagName: string): BlockRange[] {
14
- const ranges: BlockRange[] = [];
15
- const tagRe = new RegExp(`{%-?\\s*(${tagName}|end${tagName})\\s*-?%}`, 'g');
16
- const unmatchedOpeners: number[] = [];
17
-
18
- let match: RegExpExecArray | null;
19
- while ((match = tagRe.exec(content)) !== null) {
20
- if (match[1] === tagName) {
21
- unmatchedOpeners.push(match.index);
22
- } else if (unmatchedOpeners.length > 0) {
23
- ranges.push({
24
- openStart: unmatchedOpeners.pop()!,
25
- closeEnd: match.index + match[0].length,
26
- });
27
- }
28
- }
29
- return ranges;
30
- }
31
-
32
8
  function isInsideRange(offset: number, ranges: BlockRange[]): boolean {
33
9
  return ranges.some(r => offset >= r.openStart && offset < r.closeEnd);
34
10
  }
@@ -88,23 +64,30 @@ function validateTag(tree: any, file: VFile, raw: string, content: string, tagNa
88
64
 
89
65
  for (const range of ranges) {
90
66
  if (isNestedBlock(range, ranges)) {
91
- file.message(
92
- `Redundant nested ${tagName} block — already inside a ${tagName} block.`,
93
- offsetToPosition(raw, range.openStart),
94
- );
67
+ if (tagName === 'englishonly') {
68
+ file.message(
69
+ `Redundant nested englishonly block — already inside an englishonly block.`,
70
+ offsetToPosition(raw, range.openStart),
71
+ );
72
+ } else {
73
+ file.message(
74
+ `Redundant nested ${tagName} block — already inside a ${tagName} block.`,
75
+ offsetToPosition(raw, range.openStart),
76
+ );
77
+ }
95
78
  }
96
79
  }
97
80
 
98
81
  if (isEntireFileWrapped(content, ranges)) {
99
82
  file.message(
100
- `All content is inside ${tagName} block — use \`filters: [${tagName}]\` in TOC instead.`,
83
+ `All content is inside ${tagName} block — use filters: [${tagName}] in TOC instead.`,
101
84
  offsetToPosition(raw, ranges[0].openStart),
102
85
  );
103
86
  }
104
87
 
105
88
  for (const heading of findEmptyHeadings(tree, content, ranges)) {
106
89
  file.message(
107
- `Heading would have no content after ${tagName} block is removed.`,
90
+ `Heading will have no content when the ${tagName} block is filtered out. Remove or adjust the heading.`,
108
91
  heading,
109
92
  );
110
93
  }