@design.estate/wcctools 6.0.0 → 6.1.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/changelog.md +13 -0
- package/dist_shell/bundle.js +3 -3
- package/dist_shell/bundle.js.map +1 -1
- package/dist_ts/00_commitinfo_data.js +1 -1
- package/dist_ts/cli.js +8 -2
- package/dist_ts/plugins.d.ts +7 -2
- package/dist_ts/plugins.js +9 -3
- package/dist_ts/standards/baselines.d.ts +27 -0
- package/dist_ts/standards/baselines.js +83 -0
- package/dist_ts/standards/checker.d.ts +21 -0
- package/dist_ts/standards/checker.js +88 -0
- package/dist_ts/standards/classes.gitrepo.d.ts +13 -0
- package/dist_ts/standards/classes.gitrepo.js +43 -0
- package/dist_ts/standards/classes.sourceedits.d.ts +15 -0
- package/dist_ts/standards/classes.sourceedits.js +54 -0
- package/dist_ts/standards/classes.standardfixer.d.ts +40 -0
- package/dist_ts/standards/classes.standardfixer.js +210 -0
- package/dist_ts/standards/classes.standardproject.d.ts +80 -0
- package/dist_ts/standards/classes.standardproject.js +195 -0
- package/dist_ts/standards/classes.standardtree.d.ts +56 -0
- package/dist_ts/standards/classes.standardtree.js +207 -0
- package/dist_ts/standards/cli.d.ts +7 -0
- package/dist_ts/standards/cli.js +89 -0
- package/dist_ts/standards/config.d.ts +33 -0
- package/dist_ts/standards/config.js +139 -0
- package/dist_ts/standards/errors.d.ts +9 -0
- package/dist_ts/standards/errors.js +17 -0
- package/dist_ts/standards/helpers.ast.d.ts +56 -0
- package/dist_ts/standards/helpers.ast.js +172 -0
- package/dist_ts/standards/helpers.paths.d.ts +36 -0
- package/dist_ts/standards/helpers.paths.js +86 -0
- package/dist_ts/standards/index.d.ts +14 -0
- package/dist_ts/standards/index.js +15 -0
- package/dist_ts/standards/output.d.ts +7 -0
- package/dist_ts/standards/output.js +57 -0
- package/dist_ts/standards/ratchet.d.ts +15 -0
- package/dist_ts/standards/ratchet.js +45 -0
- package/dist_ts/standards/rule.d.ts +50 -0
- package/dist_ts/standards/rule.js +9 -0
- package/dist_ts/standards/rules/barrel.element-index.d.ts +7 -0
- package/dist_ts/standards/rules/barrel.element-index.js +108 -0
- package/dist_ts/standards/rules/barrel.no-demo-export.d.ts +3 -0
- package/dist_ts/standards/rules/barrel.no-demo-export.js +29 -0
- package/dist_ts/standards/rules/demo.fixture-not-exported.d.ts +3 -0
- package/dist_ts/standards/rules/demo.fixture-not-exported.js +29 -0
- package/dist_ts/standards/rules/demo.groups.d.ts +6 -0
- package/dist_ts/standards/rules/demo.groups.js +72 -0
- package/dist_ts/standards/rules/demo.required.d.ts +3 -0
- package/dist_ts/standards/rules/demo.required.js +48 -0
- package/dist_ts/standards/rules/demo.separate-file.d.ts +3 -0
- package/dist_ts/standards/rules/demo.separate-file.js +38 -0
- package/dist_ts/standards/rules/demo.shape.d.ts +3 -0
- package/dist_ts/standards/rules/demo.shape.js +38 -0
- package/dist_ts/standards/rules/docs.component-index.d.ts +8 -0
- package/dist_ts/standards/rules/docs.component-index.js +84 -0
- package/dist_ts/standards/rules/element.exported.d.ts +3 -0
- package/dist_ts/standards/rules/element.exported.js +33 -0
- package/dist_ts/standards/rules/element.literal-tag.d.ts +3 -0
- package/dist_ts/standards/rules/element.literal-tag.js +30 -0
- package/dist_ts/standards/rules/element.reachable.d.ts +3 -0
- package/dist_ts/standards/rules/element.reachable.js +48 -0
- package/dist_ts/standards/rules/element.tag-map.d.ts +3 -0
- package/dist_ts/standards/rules/element.tag-map.js +83 -0
- package/dist_ts/standards/rules/i18n.literals.d.ts +3 -0
- package/dist_ts/standards/rules/i18n.literals.js +52 -0
- package/dist_ts/standards/rules/index.d.ts +12 -0
- package/dist_ts/standards/rules/index.js +83 -0
- package/dist_ts/standards/rules/layout.element-folder.d.ts +3 -0
- package/dist_ts/standards/rules/layout.element-folder.js +47 -0
- package/dist_ts/standards/rules/layout.entry-file-name.d.ts +3 -0
- package/dist_ts/standards/rules/layout.entry-file-name.js +71 -0
- package/dist_ts/standards/rules/layout.entry.d.ts +3 -0
- package/dist_ts/standards/rules/layout.entry.js +38 -0
- package/dist_ts/standards/rules/layout.group-folder.d.ts +3 -0
- package/dist_ts/standards/rules/layout.group-folder.js +22 -0
- package/dist_ts/standards/rules/layout.shared-00.d.ts +3 -0
- package/dist_ts/standards/rules/layout.shared-00.js +36 -0
- package/dist_ts/standards/rules/naming.class-matches-tag.d.ts +3 -0
- package/dist_ts/standards/rules/naming.class-matches-tag.js +26 -0
- package/dist_ts/standards/rules/naming.lowercase-files.d.ts +3 -0
- package/dist_ts/standards/rules/naming.lowercase-files.js +26 -0
- package/dist_ts/standards/rules/naming.tag-prefix.d.ts +3 -0
- package/dist_ts/standards/rules/naming.tag-prefix.js +23 -0
- package/dist_ts/standards/rules/props.accessor.d.ts +3 -0
- package/dist_ts/standards/rules/props.accessor.js +35 -0
- package/dist_ts/standards/rules/props.object-no-attribute.d.ts +3 -0
- package/dist_ts/standards/rules/props.object-no-attribute.js +42 -0
- package/dist_ts/standards/rules/props.reflect-primitive.d.ts +5 -0
- package/dist_ts/standards/rules/props.reflect-primitive.js +41 -0
- package/dist_ts/standards/rules/props.typed.d.ts +6 -0
- package/dist_ts/standards/rules/props.typed.js +64 -0
- package/dist_ts/standards/rules/shared.d.ts +38 -0
- package/dist_ts/standards/rules/shared.js +103 -0
- package/dist_ts/standards/rules/style.bdtheme.d.ts +5 -0
- package/dist_ts/standards/rules/style.bdtheme.js +28 -0
- package/dist_ts_interfaces/index.d.ts +1 -0
- package/dist_ts_interfaces/index.js +2 -1
- package/dist_ts_interfaces/standard.d.ts +93 -0
- package/dist_ts_interfaces/standard.js +6 -0
- package/dist_ts_web/00_commitinfo_data.js +1 -1
- package/package.json +4 -2
- package/readme.md +34 -1
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts/cli.ts +8 -1
- package/ts/plugins.ts +10 -2
- package/ts/standards/baselines.ts +100 -0
- package/ts/standards/checker.ts +114 -0
- package/ts/standards/classes.gitrepo.ts +48 -0
- package/ts/standards/classes.sourceedits.ts +58 -0
- package/ts/standards/classes.standardfixer.ts +234 -0
- package/ts/standards/classes.standardproject.ts +250 -0
- package/ts/standards/classes.standardtree.ts +220 -0
- package/ts/standards/cli.ts +86 -0
- package/ts/standards/config.ts +160 -0
- package/ts/standards/errors.ts +18 -0
- package/ts/standards/helpers.ast.ts +208 -0
- package/ts/standards/helpers.paths.ts +119 -0
- package/ts/standards/index.ts +22 -0
- package/ts/standards/output.ts +65 -0
- package/ts/standards/ratchet.ts +63 -0
- package/ts/standards/rule.ts +58 -0
- package/ts/standards/rules/barrel.element-index.ts +112 -0
- package/ts/standards/rules/barrel.no-demo-export.ts +30 -0
- package/ts/standards/rules/demo.fixture-not-exported.ts +30 -0
- package/ts/standards/rules/demo.groups.ts +74 -0
- package/ts/standards/rules/demo.required.ts +49 -0
- package/ts/standards/rules/demo.separate-file.ts +40 -0
- package/ts/standards/rules/demo.shape.ts +42 -0
- package/ts/standards/rules/docs.component-index.ts +88 -0
- package/ts/standards/rules/element.exported.ts +35 -0
- package/ts/standards/rules/element.literal-tag.ts +30 -0
- package/ts/standards/rules/element.reachable.ts +49 -0
- package/ts/standards/rules/element.tag-map.ts +87 -0
- package/ts/standards/rules/i18n.literals.ts +58 -0
- package/ts/standards/rules/index.ts +87 -0
- package/ts/standards/rules/layout.element-folder.ts +49 -0
- package/ts/standards/rules/layout.entry-file-name.ts +73 -0
- package/ts/standards/rules/layout.entry.ts +40 -0
- package/ts/standards/rules/layout.group-folder.ts +23 -0
- package/ts/standards/rules/layout.shared-00.ts +37 -0
- package/ts/standards/rules/naming.class-matches-tag.ts +27 -0
- package/ts/standards/rules/naming.lowercase-files.ts +27 -0
- package/ts/standards/rules/naming.tag-prefix.ts +24 -0
- package/ts/standards/rules/props.accessor.ts +37 -0
- package/ts/standards/rules/props.object-no-attribute.ts +45 -0
- package/ts/standards/rules/props.reflect-primitive.ts +44 -0
- package/ts/standards/rules/props.typed.ts +70 -0
- package/ts/standards/rules/shared.ts +127 -0
- package/ts/standards/rules/style.bdtheme.ts +31 -0
- package/ts_web/00_commitinfo_data.ts +1 -1
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import * as plugins from '../../plugins.js';
|
|
2
|
+
import * as ast from '../helpers.ast.js';
|
|
3
|
+
import { baseOf, dirOf, specifierFor } from '../helpers.paths.js';
|
|
4
|
+
import type { IStandardElement, IStandardProperty, StandardProject } from '../classes.standardproject.js';
|
|
5
|
+
import type { IFixBuilder } from '../rule.js';
|
|
6
|
+
|
|
7
|
+
const ts = plugins.typescript;
|
|
8
|
+
|
|
9
|
+
export const elementsDir = 'ts_web/elements';
|
|
10
|
+
|
|
11
|
+
/** `ts_web/elements/00group-<area>` or `ts_web/elements` itself. */
|
|
12
|
+
export const isElementParentDir = (dirArg: string): boolean =>
|
|
13
|
+
dirArg === elementsDir || /^ts_web\/elements\/00group-[^/]+$/.test(dirArg);
|
|
14
|
+
|
|
15
|
+
/** Names the HTML specification reserves; `customElements.define` rejects them. */
|
|
16
|
+
const reservedElementNames = ['annotation-xml', 'color-profile', 'font-face', 'font-face-src', 'font-face-uri', 'font-face-format', 'font-face-name', 'missing-glyph'];
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* A valid custom element name in the ASCII subset the standard allows: a lowercase letter first,
|
|
20
|
+
* then lowercase letters, digits, `-`, `.` and `_`, at least one `-`, and not a reserved name. Such
|
|
21
|
+
* a tag is also a safe file and folder name, so only these tags feed fixes that derive paths or code.
|
|
22
|
+
*/
|
|
23
|
+
export const isCustomElementName = (tagArg: string): boolean =>
|
|
24
|
+
/^[a-z][a-z0-9._-]*$/.test(tagArg) && tagArg.includes('-') && !reservedElementNames.includes(tagArg);
|
|
25
|
+
|
|
26
|
+
/** True when an element's entry file sits in its own element folder `…/<tag>/`. */
|
|
27
|
+
export const isInElementFolder = (elementArg: IStandardElement): boolean => {
|
|
28
|
+
const folder = dirOf(elementArg.file);
|
|
29
|
+
return !!elementArg.tag && baseOf(folder) === elementArg.tag && isElementParentDir(dirOf(folder));
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
/** The `<area>` of `ts_web/elements/00group-<area>/…`, or null. */
|
|
33
|
+
export const groupAreaOf = (fileArg: string): string | null => /^ts_web\/elements\/00group-([^/]+)\//.exec(fileArg)?.[1] ?? null;
|
|
34
|
+
|
|
35
|
+
/** Elements outside demo files: the catalog's own elements. */
|
|
36
|
+
export const catalogElements = (projectArg: StandardProject): IStandardElement[] =>
|
|
37
|
+
projectArg.elements.filter((elementArg) => !elementArg.inDemoFile);
|
|
38
|
+
|
|
39
|
+
/** Public `@property` members outside demo files. */
|
|
40
|
+
export const publicProperties = (projectArg: StandardProject): IStandardProperty[] =>
|
|
41
|
+
projectArg.properties.filter((propertyArg) => propertyArg.decorator === 'property' && propertyArg.isPublic && !propertyArg.inDemoFile);
|
|
42
|
+
|
|
43
|
+
export const elementKey = (elementArg: IStandardElement): string => `${elementArg.file}#${elementArg.className ?? elementArg.tag ?? '?'}`;
|
|
44
|
+
|
|
45
|
+
export const propertyKey = (propertyArg: IStandardProperty): string => `${propertyArg.file}#${propertyArg.name}`;
|
|
46
|
+
|
|
47
|
+
/** The type annotation of a property member without `undefined` and `null` union members. */
|
|
48
|
+
export const coreTypeOf = (propertyArg: IStandardProperty): ast.TTypeNode | null => {
|
|
49
|
+
const member = propertyArg.member;
|
|
50
|
+
const typeNode = ts.isPropertyDeclaration(member) ? member.type : undefined;
|
|
51
|
+
if (!typeNode) {
|
|
52
|
+
return null;
|
|
53
|
+
}
|
|
54
|
+
if (ts.isUnionTypeNode(typeNode)) {
|
|
55
|
+
const members = typeNode.types.filter((typeArg) =>
|
|
56
|
+
typeArg.kind !== ts.SyntaxKind.UndefinedKeyword
|
|
57
|
+
&& !(ts.isLiteralTypeNode(typeArg) && typeArg.literal.kind === ts.SyntaxKind.NullKeyword));
|
|
58
|
+
if (members.length === 1) {
|
|
59
|
+
return members[0];
|
|
60
|
+
}
|
|
61
|
+
return typeNode;
|
|
62
|
+
}
|
|
63
|
+
return typeNode;
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
export const isArrayTypeNode = (typeArg: ast.TTypeNode): boolean => {
|
|
67
|
+
if (ts.isArrayTypeNode(typeArg)) {
|
|
68
|
+
return true;
|
|
69
|
+
}
|
|
70
|
+
if (ts.isTypeOperatorNode(typeArg) && typeArg.operator === ts.SyntaxKind.ReadonlyKeyword) {
|
|
71
|
+
return ts.isArrayTypeNode(typeArg.type);
|
|
72
|
+
}
|
|
73
|
+
return ts.isTypeReferenceNode(typeArg) && ts.isIdentifier(typeArg.typeName) && ['Array', 'ReadonlyArray'].includes(typeArg.typeName.text);
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
/** The position at the start of the line after the last `export … from` statement, or at the end of the file. */
|
|
77
|
+
export const exportInsertionPoint = (sourceFileArg: ast.TSourceFile): { position: number; prefix: string } => {
|
|
78
|
+
let lastEnd = -1;
|
|
79
|
+
for (const statement of sourceFileArg.statements) {
|
|
80
|
+
if (ts.isExportDeclaration(statement)) {
|
|
81
|
+
lastEnd = statement.end;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
const text = sourceFileArg.text;
|
|
85
|
+
if (lastEnd === -1) {
|
|
86
|
+
return { position: text.length, prefix: text.length > 0 && !text.endsWith('\n') ? '\n' : '' };
|
|
87
|
+
}
|
|
88
|
+
const newline = text.indexOf('\n', lastEnd);
|
|
89
|
+
return newline === -1 ? { position: text.length, prefix: '\n' } : { position: newline + 1, prefix: '' };
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
/** Adds `export * from '<target>';` to a barrel. */
|
|
93
|
+
export const addReexport = (builderArg: IFixBuilder, projectArg: StandardProject, barrelArg: string, targetArg: string): void => {
|
|
94
|
+
const point = exportInsertionPoint(projectArg.sourceFile(barrelArg));
|
|
95
|
+
builderArg.edit(barrelArg, point.position, point.position, `${point.prefix}export * from '${specifierFor(barrelArg, targetArg, 'js')}';\n`);
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
/** Removes a whole statement including its line break; from the line start when only indentation precedes it. */
|
|
99
|
+
export const removeStatement = (builderArg: IFixBuilder, fileArg: string, statementArg: ast.TNode): void => {
|
|
100
|
+
const text = statementArg.getSourceFile().text;
|
|
101
|
+
let start = statementArg.getStart();
|
|
102
|
+
const lineStart = text.lastIndexOf('\n', start - 1) + 1;
|
|
103
|
+
if (/^[ \t]*$/.test(text.slice(lineStart, start))) {
|
|
104
|
+
start = lineStart;
|
|
105
|
+
}
|
|
106
|
+
let end = statementArg.end;
|
|
107
|
+
const rest = /^[ \t]*\r?\n/.exec(text.slice(end));
|
|
108
|
+
if (rest) {
|
|
109
|
+
end += rest[0].length;
|
|
110
|
+
}
|
|
111
|
+
builderArg.edit(fileArg, start, end, '');
|
|
112
|
+
};
|
|
113
|
+
|
|
114
|
+
/** The identifier a `static demo` value refers to at its root, e.g. `demoFunc` or `demos` in `demos.main`. */
|
|
115
|
+
export const rootIdentifier = (expressionArg: ast.TExpression): string | null => {
|
|
116
|
+
let current: ast.TExpression = expressionArg;
|
|
117
|
+
while (ts.isPropertyAccessExpression(current)) {
|
|
118
|
+
current = current.expression;
|
|
119
|
+
}
|
|
120
|
+
return ts.isIdentifier(current) ? current.text : null;
|
|
121
|
+
};
|
|
122
|
+
|
|
123
|
+
/** The start of the line following the line a position is on. */
|
|
124
|
+
export const nextLineStart = (textArg: string, positionArg: number): number => {
|
|
125
|
+
const newline = textArg.indexOf('\n', positionArg);
|
|
126
|
+
return newline === -1 ? textArg.length : newline + 1;
|
|
127
|
+
};
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import * as plugins from '../../plugins.js';
|
|
2
|
+
import * as ast from '../helpers.ast.js';
|
|
3
|
+
import type { IRuleFinding, IStandardRule } from '../rule.js';
|
|
4
|
+
|
|
5
|
+
const ts = plugins.typescript;
|
|
6
|
+
|
|
7
|
+
/** The one module that may call `bdTheme()`: the token bridge. */
|
|
8
|
+
export const bdThemeBridge = 'ts_web/elements/00theme.ts';
|
|
9
|
+
|
|
10
|
+
/** dees: no new `cssManager.bdTheme()` call outside `ts_web/elements/00theme.ts`. A ratchet: baselines only. */
|
|
11
|
+
export const styleBdThemeRule: IStandardRule = {
|
|
12
|
+
id: 'style/bdtheme',
|
|
13
|
+
severity: { dees: 'error' },
|
|
14
|
+
fixMode: 'none',
|
|
15
|
+
detect: ({ project }) => {
|
|
16
|
+
const findings: IRuleFinding[] = [];
|
|
17
|
+
for (const file of project.webFiles) {
|
|
18
|
+
if (file === bdThemeBridge) {
|
|
19
|
+
continue;
|
|
20
|
+
}
|
|
21
|
+
const visit = (nodeArg: ast.TNode): void => {
|
|
22
|
+
if (ts.isCallExpression(nodeArg) && ast.calleeName(nodeArg.expression) === 'bdTheme') {
|
|
23
|
+
findings.push({ file, position: nodeArg.getStart(), key: file, message: 'bdTheme() call; use --dees-* tokens' });
|
|
24
|
+
}
|
|
25
|
+
ts.forEachChild(nodeArg, visit);
|
|
26
|
+
};
|
|
27
|
+
visit(project.sourceFile(file));
|
|
28
|
+
}
|
|
29
|
+
return findings;
|
|
30
|
+
},
|
|
31
|
+
};
|
|
@@ -3,6 +3,6 @@
|
|
|
3
3
|
*/
|
|
4
4
|
export const commitinfo = {
|
|
5
5
|
name: '@design.estate/wcctools',
|
|
6
|
-
version: '6.
|
|
6
|
+
version: '6.1.0',
|
|
7
7
|
description: 'A set of web component tools for creating element catalogues, enabling the structured development and documentation of custom elements and pages.'
|
|
8
8
|
}
|