@wix/origami-lint 1.34.11 → 1.34.13
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/page-model/index.js +1 -1
- package/dist/rules/project/home-page-folder.js +54 -0
- package/dist/rules/project/index.js +2 -1
- package/dist/rules/site-app/global-styles.js +1 -6
- package/dist/rules-api/index.js +1 -1
- package/dist/shared/css.js +5 -0
- package/dist/shared/site-files-tree-mapping.js +2 -0
- package/package.json +2 -2
package/dist/page-model/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// Part 2 — page model: which pages to lint, and one page's model (its components, each with its CSS).
|
|
2
2
|
export * from "./model.js";
|
|
3
3
|
export { buildPageModel } from "./build-page-model.js";
|
|
4
|
-
export { findPagesToLint, JSX_FILES } from "./pages.js";
|
|
4
|
+
export { findPages, findPagesToLint, JSX_FILES } from "./pages.js";
|
|
5
5
|
export { readPage } from "./read-page.js";
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
// The home page folder (tracker OUR-035, CONV-unitPath.ts:89): exactly one folder in parentheses, pages/(<slug>), directly
|
|
2
|
+
// under pages/, and no other folder in parentheses in pages/ or popups/. `origami import-site` stops without exactly one
|
|
3
|
+
// home folder and refuses a nested one; the converter refuses a popup folder in parentheses.
|
|
4
|
+
import { findPages } from "../../page-model/index.js";
|
|
5
|
+
import { PAGES_FOLDER, POPUPS_FOLDER } from "../../shared/site-files-tree-mapping.js";
|
|
6
|
+
import { defineProjectRule } from "./define-project-rule.js";
|
|
7
|
+
const EXPECTED_ONE_HOME = `Expected exactly one home page folder "pages/(<slug>)" in ${PAGES_FOLDER}`;
|
|
8
|
+
export const NO_HOME = `${EXPECTED_ONE_HOME}; found 0. Name the home page's folder in parentheses, directly under ${PAGES_FOLDER}, like ${PAGES_FOLDER}/(home) (rule P2-R01; tracker OUR-035). The import stops without it.`;
|
|
9
|
+
export const moreHomes = (count, folder) => `${EXPECTED_ONE_HOME}; found ${count}. Keep the parentheses on the home page's folder only: rename ${folder} to ${withoutParentheses(folder)} (rule P2-R01; tracker OUR-035).`;
|
|
10
|
+
export const onlyHomeInParentheses = (folder) => `Only the home page is written in parentheses, directly under ${PAGES_FOLDER}/. Rename ${folder} to ${withoutParentheses(folder)} (rule P2-R23; tracker CONV-unitPath.ts:89).`;
|
|
11
|
+
/** A home page's folder: its name in parentheses, `(home)`. */
|
|
12
|
+
const HOME_FOLDER = /^\(.+\)$/;
|
|
13
|
+
export default defineProjectRule({
|
|
14
|
+
name: 'home-page-folder',
|
|
15
|
+
editors: ['studio2'],
|
|
16
|
+
check: (project) => [...checkOneHome(project), ...checkNoNestedHome(project), ...checkNoPopupInParentheses(project)],
|
|
17
|
+
});
|
|
18
|
+
// ── the steps ──
|
|
19
|
+
/** Reports no home folder at the top of pages/, or more than one (each after the first). */
|
|
20
|
+
function checkOneHome(project) {
|
|
21
|
+
const homes = getPages(project).filter((page) => page.folders.length === 1 && HOME_FOLDER.test(page.folders[0]));
|
|
22
|
+
if (homes.length === 0)
|
|
23
|
+
return [{ file: PAGES_FOLDER, message: NO_HOME }];
|
|
24
|
+
return homes.slice(1).map((home) => ({ file: home.jsxFile, message: moreHomes(homes.length, home.folders[0]) }));
|
|
25
|
+
}
|
|
26
|
+
/** Reports every page with a folder in parentheses below the top of pages/ on its path, as import-site refuses them. */
|
|
27
|
+
function checkNoNestedHome(project) {
|
|
28
|
+
return getPages(project).flatMap((page) => {
|
|
29
|
+
const nested = page.folders.slice(1).find((folder) => HOME_FOLDER.test(folder));
|
|
30
|
+
return nested ? [{ file: page.jsxFile, message: onlyHomeInParentheses(nested) }] : [];
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
/** Reports each folder in parentheses under popups/, once, as the converter refuses them. */
|
|
34
|
+
function checkNoPopupInParentheses(project) {
|
|
35
|
+
const folders = new Set();
|
|
36
|
+
for (const file of project.files.filter((file) => file.startsWith(`${POPUPS_FOLDER}/`))) {
|
|
37
|
+
const segments = file.slice(`${POPUPS_FOLDER}/`.length).split('/').slice(0, -1);
|
|
38
|
+
const index = segments.findIndex((segment) => HOME_FOLDER.test(segment));
|
|
39
|
+
if (index !== -1)
|
|
40
|
+
folders.add(`${POPUPS_FOLDER}/${segments.slice(0, index + 1).join('/')}`);
|
|
41
|
+
}
|
|
42
|
+
return [...folders].sort().map((folder) => ({ file: folder, message: onlyHomeInParentheses(folder.slice(folder.lastIndexOf('/') + 1)) }));
|
|
43
|
+
}
|
|
44
|
+
/** The site's pages under pages/, sorted by path. */
|
|
45
|
+
function getPages(project) {
|
|
46
|
+
return findPages([...project.files], [...project.files])
|
|
47
|
+
.filter((jsxFile) => jsxFile.startsWith(`${PAGES_FOLDER}/`))
|
|
48
|
+
.sort()
|
|
49
|
+
.map((jsxFile) => ({ jsxFile, folders: jsxFile.slice(`${PAGES_FOLDER}/`.length).split('/').slice(0, -1) }));
|
|
50
|
+
}
|
|
51
|
+
/** '(team)' → 'team'. */
|
|
52
|
+
function withoutParentheses(folder) {
|
|
53
|
+
return folder.slice(1, -1);
|
|
54
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { BREAKPOINT_AT_RULES, createCssFileReporter, describeAtRule, getCssChildren, getDashedId, getSegmentClass, getSelectorSegments, isCssIdentifier, isSafeCssIdentifier } from "../../rules-api/index.js";
|
|
1
|
+
import { BREAKPOINT_AT_RULES, createCssFileReporter, describeAtRule, getCssChildren, getDashedId, getMixinId, getSegmentClass, getSelectorSegments, isCssIdentifier, isSafeCssIdentifier } from "../../rules-api/index.js";
|
|
2
2
|
import { defineRule } from "./define-rule.js";
|
|
3
3
|
export default defineRule({
|
|
4
4
|
name: 'global-styles',
|
|
@@ -150,11 +150,6 @@ function checkLinkOrValues(group, linkedParts, reportInFile) {
|
|
|
150
150
|
reportInFile(first.node, `\`@mixin --${first.mixin}\` styles \`${part}\` but links no global style there: add \`& ${part} { @apply --<child> }\` and move the values to that child's @mixin (tracker CONV-styleParser.ts:698).`);
|
|
151
151
|
}
|
|
152
152
|
// ── reading a mixin ──
|
|
153
|
-
/** The id a `@mixin` declares (`--btn` → 'btn'), or null when it isn't one dashed identifier. */
|
|
154
|
-
function getMixinId(mixin) {
|
|
155
|
-
const id = getDashedId(mixin.params);
|
|
156
|
-
return id !== undefined && isSafeCssIdentifier(id) ? id : null;
|
|
157
|
-
}
|
|
158
153
|
/** The mixin's one `@result` with no params and a block, beside nothing; undefined otherwise. */
|
|
159
154
|
function getResult(mixin) {
|
|
160
155
|
if (mixin.nodes === undefined)
|
package/dist/rules-api/index.js
CHANGED
|
@@ -3,4 +3,4 @@ export { createRulesApi, getOrCreateRulesApi } from "./rules-api.js";
|
|
|
3
3
|
export { createCssFileReporter, describeAtRule, reportCssProblem } from "./report.js";
|
|
4
4
|
export { bare, getAttribute, getExpression, getKey, getName, getObject, getProperties, getCallbackKind, getParamReadKind, getProperty, isBound, isOneEditAway, isReservedAttribute, isStructure, ownerOf, } from "../shared/utils.js";
|
|
5
5
|
export { BUILDERS, CALLBACK_PROP, DATA_KEY, EVENT_ATTRIBUTE, GLOBAL_SECTIONS, INSTANCE_PROPS, LAYER_ATTRIBUTES, RESERVED_ATTRIBUTES, RESERVED_ENTRY_KEYS, RUNTIME_ONLY_BUILDERS, RUNTIME_PACKAGE, SECTIONS, SHARED_COMP_ID, STRUCTURE, SYSTEM_PACKAGE, TRANSFORM_BUILDERS, TYPED_BUILDERS, WRAPPERS, } from "../shared/constants.js";
|
|
6
|
-
export { BREAKPOINT_AT_RULES, CONTENT_TARGET, getCssChildren, getDashedId, getSegmentClass, getSelectorSegments, isCssIdentifier, isPresetProperty, isSafeCssIdentifier, ORIGAMI_TARGETS, OVERFLOW_TARGET, PREAMBLE_LAYER, readSegment } from "../shared/css.js";
|
|
6
|
+
export { BREAKPOINT_AT_RULES, CONTENT_TARGET, getCssChildren, getDashedId, getMixinId, getSegmentClass, getSelectorSegments, isCssIdentifier, isPresetProperty, isSafeCssIdentifier, ORIGAMI_TARGETS, OVERFLOW_TARGET, PREAMBLE_LAYER, readSegment } from "../shared/css.js";
|
package/dist/shared/css.js
CHANGED
|
@@ -49,6 +49,11 @@ export const getCssChildren = (node) => (node.nodes ?? []).filter((child) => chi
|
|
|
49
49
|
export const isPresetProperty = (prop) => prop === '--preset' || prop.startsWith('--preset-');
|
|
50
50
|
/** The id a `@mixin` or `@apply` names: '--btn' → 'btn' (spaces around aside); undefined when its params aren't `--` and one word. */
|
|
51
51
|
export const getDashedId = (params) => DASHED_ID.exec(params.trim())?.[1];
|
|
52
|
+
/** The id a `@mixin` declares (`--btn` → 'btn'), or null when it isn't one dashed identifier. */
|
|
53
|
+
export function getMixinId(mixin) {
|
|
54
|
+
const id = getDashedId(mixin.params);
|
|
55
|
+
return id !== undefined && isSafeCssIdentifier(id) ? id : null;
|
|
56
|
+
}
|
|
52
57
|
/** Whether the import reads this as an identifier (cssSelectors.ts `isCssIdentifier`): letters, digits, - and _, not starting with a digit. */
|
|
53
58
|
export const isCssIdentifier = (id) => CSS_IDENT.test(id);
|
|
54
59
|
/** Whether the import takes this as a name (a mixin id, a preset path's part; cssSelectors.ts `isSafeCssIdentifier`): an identifier, not a reserved name. */
|
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
export const SITE_SRC = 'packages/site-app/src';
|
|
3
3
|
/** One page per folder; routes can be nested (about-us/team). */
|
|
4
4
|
export const PAGES_FOLDER = `${SITE_SRC}/pages`;
|
|
5
|
+
/** One popup per folder, directly under it (popups have no url, so no nesting). */
|
|
6
|
+
export const POPUPS_FOLDER = `${SITE_SRC}/popups`;
|
|
5
7
|
/** What every page shares: the global components, the menus, the theme. */
|
|
6
8
|
export const GLOBAL_FOLDER = `${SITE_SRC}/global`;
|
|
7
9
|
/** Inside src/: one global component per folder (the header, the footer, any other shared section). A page imports one from here. */
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wix/origami-lint",
|
|
3
|
-
"version": "1.34.
|
|
3
|
+
"version": "1.34.13",
|
|
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": {
|
|
@@ -52,5 +52,5 @@
|
|
|
52
52
|
]
|
|
53
53
|
}
|
|
54
54
|
},
|
|
55
|
-
"falconPackageHash": "
|
|
55
|
+
"falconPackageHash": "70a9ee3d299565f2869a89a7c2269513b67bdf6101e989b4545ecc19"
|
|
56
56
|
}
|