@wix/origami-lint 1.34.3 → 1.34.4
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/dist/rules/page-structure.js +19 -17
- package/package.json +2 -2
|
@@ -6,6 +6,8 @@
|
|
|
6
6
|
// recognized by import source (rulesApi.getType), so renaming an import doesn't matter.
|
|
7
7
|
// Checked in every file, pages and global components alike:
|
|
8
8
|
// - Structure returns one element, with a string id (tracker CONV-runValidation.ts:9);
|
|
9
|
+
// - every section, wherever it sits (a page's, a global component's top one, one nested lower down), holds exactly one
|
|
10
|
+
// <InternalContainer> and nothing else: the site's own build refuses anything else (rule S2-SECTION-001, tracker OUR-001);
|
|
9
11
|
// - a <Page> is only ever the top of its own page: one held by another element is refused at save (rule card P1-R16);
|
|
10
12
|
// - the header and footer sit outside every <InternalContainer>: inside one, that container can no longer be deleted in the
|
|
11
13
|
// editor (rule card P1-R03). Both the HeaderSection / FooterSection tags and a page's reference to the global ones;
|
|
@@ -38,6 +40,8 @@ export default defineRule({
|
|
|
38
40
|
if (isLandmark(input.node, input.rulesApi))
|
|
39
41
|
hasSectionInLandmark(input);
|
|
40
42
|
hasOnlyElements(input);
|
|
43
|
+
if (isSection(input.node, input.rulesApi))
|
|
44
|
+
hasOneInternalContainer(input.node, input);
|
|
41
45
|
hasLayerArrays(input);
|
|
42
46
|
isNotNestedPage(input);
|
|
43
47
|
isOutsideInternalContainers(input);
|
|
@@ -50,8 +54,7 @@ export default defineRule({
|
|
|
50
54
|
return;
|
|
51
55
|
if (!startsWithPage(input))
|
|
52
56
|
return;
|
|
53
|
-
|
|
54
|
-
hasOneInternalContainer(section, input);
|
|
57
|
+
checkPageChildren(input);
|
|
55
58
|
},
|
|
56
59
|
},
|
|
57
60
|
});
|
|
@@ -94,29 +97,25 @@ function startsWithPage({ node, rulesApi, report }) {
|
|
|
94
97
|
report({ loc: getLoc(node, rulesApi), message: `A page must start with <Page>, found ${describe(node, rulesApi)}.` });
|
|
95
98
|
return false;
|
|
96
99
|
}
|
|
97
|
-
/** <Page>
|
|
98
|
-
function
|
|
99
|
-
const sections = [];
|
|
100
|
+
/** Reports text and {…} directly in <Page> (CONV-parseJsx.ts:1668). Any component is accepted there: a section, the page's <Background>, a pinned element, as the import accepts it. */
|
|
101
|
+
function checkPageChildren({ node: page, rulesApi, report }) {
|
|
100
102
|
for (const child of getStructuralChildren(page, rulesApi)) {
|
|
101
|
-
if (child.type === 'JSXElement')
|
|
102
|
-
const type = rulesApi.getType(child);
|
|
103
|
-
if (type && SECTIONS.includes(type))
|
|
104
|
-
sections.push(child);
|
|
103
|
+
if (child.type === 'JSXElement')
|
|
105
104
|
continue;
|
|
106
|
-
}
|
|
107
105
|
report({ loc: getLoc(page, rulesApi), message: `<Page> has ${describe(child, rulesApi)} as a child. Only elements go directly inside <Page>: a section, or a component pinned to the page (tracker CONV-parseJsx.ts:1668).` });
|
|
108
106
|
}
|
|
109
|
-
return sections;
|
|
110
107
|
}
|
|
111
|
-
/** Reports a section that doesn't hold exactly one <InternalContainer>, and nothing else. A wrapper in it
|
|
108
|
+
/** Reports a section, anywhere in the file, that doesn't hold exactly one <InternalContainer>, and nothing else (S2-SECTION-001, OUR-001). A wrapper in it
|
|
109
|
+
* that holds the wrong number of elements is reported by its own step first; text and {…} count only where hasOnlyElements leaves them to this step. */
|
|
112
110
|
function hasOneInternalContainer(section, { rulesApi, report }) {
|
|
113
111
|
if (rulesApi.getChildren(section).some((child) => child.type === 'JSXElement' && isWrapper(child, rulesApi) && !holdsOne(child)))
|
|
114
112
|
return;
|
|
115
|
-
const
|
|
113
|
+
const reportsText = isRootTreeHolder(section, rulesApi);
|
|
114
|
+
const inside = getStructuralChildren(section, rulesApi).filter((child) => reportsText || child.type === 'JSXElement');
|
|
116
115
|
if (inside.length === 1 && inside[0].type === 'JSXElement' && rulesApi.getType(inside[0]) === 'innerElement')
|
|
117
116
|
return;
|
|
118
117
|
const name = rulesApi.getId(section) ?? `<${rulesApi.getTagName(section)}>`;
|
|
119
|
-
report({ loc: getLoc(section, rulesApi), message: `Section ${name} must contain exactly one <InternalContainer>, found: ${inside.map((child) => describe(child, rulesApi)).join(', ') || 'nothing'}.` });
|
|
118
|
+
report({ loc: getLoc(section, rulesApi), message: `Section ${name} must contain exactly one <InternalContainer>, found: ${inside.map((child) => describe(child, rulesApi)).join(', ') || 'nothing'}. Put the section's content inside its one <InternalContainer> (rule S2-SECTION-001).` });
|
|
120
119
|
}
|
|
121
120
|
/** Reports a <Page> held by another element (P1-R16), unless the root steps above report that placement already (a section's children). */
|
|
122
121
|
function isNotNestedPage({ node, rulesApi, report }) {
|
|
@@ -250,6 +249,11 @@ function describe(child, rulesApi) {
|
|
|
250
249
|
return `<${rulesApi.getTagName(child)}>`;
|
|
251
250
|
return child.type === 'JSXText' ? 'text' : 'a {…} expression';
|
|
252
251
|
}
|
|
252
|
+
/** Section, HeaderSection, FooterSection (by import source); not a page's reference to a global one. */
|
|
253
|
+
function isSection(node, rulesApi) {
|
|
254
|
+
const type = rulesApi.getType(node);
|
|
255
|
+
return type !== null && SECTIONS.includes(type);
|
|
256
|
+
}
|
|
253
257
|
function isLandmark(node, rulesApi) {
|
|
254
258
|
const type = rulesApi.getType(node);
|
|
255
259
|
return type === 'headerLandmark' || type === 'footerLandmark';
|
|
@@ -259,10 +263,8 @@ function hasSectionInLandmark(input) {
|
|
|
259
263
|
const { node, rulesApi, report } = input;
|
|
260
264
|
const expected = rulesApi.getType(node) === 'headerLandmark' ? 'header' : 'footer';
|
|
261
265
|
const children = getStructuralChildren(node, rulesApi);
|
|
262
|
-
if (children.length === 1 && children[0].type === 'JSXElement' && rulesApi.getType(children[0]) === expected)
|
|
263
|
-
hasOneInternalContainer(children[0], input);
|
|
266
|
+
if (children.length === 1 && children[0].type === 'JSXElement' && rulesApi.getType(children[0]) === expected)
|
|
264
267
|
return;
|
|
265
|
-
}
|
|
266
268
|
report({ loc: getLoc(node, rulesApi), message: `<${rulesApi.getTagName(node)}> must contain exactly one ${expected === 'header' ? 'HeaderSection' : 'FooterSection'}.` });
|
|
267
269
|
}
|
|
268
270
|
function receivesInstanceId(node) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wix/origami-lint",
|
|
3
|
-
"version": "1.34.
|
|
3
|
+
"version": "1.34.4",
|
|
4
4
|
"description": "Offline lint for an exported Origami site: lints the pages that changed since the last passing run",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -51,5 +51,5 @@
|
|
|
51
51
|
]
|
|
52
52
|
}
|
|
53
53
|
},
|
|
54
|
-
"falconPackageHash": "
|
|
54
|
+
"falconPackageHash": "dae194e28b366afdeb725197b97b0f1659346d4dbe5cea8e1659dab4"
|
|
55
55
|
}
|