@design.estate/wcctools 6.0.0 → 6.2.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 (202) hide show
  1. package/changelog.md +33 -0
  2. package/dist_shell/bundle.js +405 -368
  3. package/dist_shell/bundle.js.map +1 -1
  4. package/dist_shell/bundle.js.third-party-notices.json +52 -0
  5. package/dist_shell/bundle.js.third-party-notices.txt +107 -1
  6. package/dist_shell/index.html +1 -1
  7. package/dist_ts/00_commitinfo_data.js +1 -1
  8. package/dist_ts/classes.bundlestatus.d.ts +36 -0
  9. package/dist_ts/classes.bundlestatus.js +110 -0
  10. package/dist_ts/classes.devapi.d.ts +3 -0
  11. package/dist_ts/classes.devapi.js +8 -1
  12. package/dist_ts/classes.devserver.d.ts +45 -10
  13. package/dist_ts/classes.devserver.js +123 -49
  14. package/dist_ts/cli.js +12 -3
  15. package/dist_ts/index.d.ts +0 -2
  16. package/dist_ts/index.js +1 -3
  17. package/dist_ts/plugins.d.ts +7 -2
  18. package/dist_ts/plugins.js +9 -3
  19. package/dist_ts/standards/baselines.d.ts +27 -0
  20. package/dist_ts/standards/baselines.js +83 -0
  21. package/dist_ts/standards/checker.d.ts +21 -0
  22. package/dist_ts/standards/checker.js +88 -0
  23. package/dist_ts/standards/classes.gitrepo.d.ts +13 -0
  24. package/dist_ts/standards/classes.gitrepo.js +43 -0
  25. package/dist_ts/standards/classes.sourceedits.d.ts +15 -0
  26. package/dist_ts/standards/classes.sourceedits.js +54 -0
  27. package/dist_ts/standards/classes.standardfixer.d.ts +40 -0
  28. package/dist_ts/standards/classes.standardfixer.js +210 -0
  29. package/dist_ts/standards/classes.standardproject.d.ts +80 -0
  30. package/dist_ts/standards/classes.standardproject.js +195 -0
  31. package/dist_ts/standards/classes.standardtree.d.ts +56 -0
  32. package/dist_ts/standards/classes.standardtree.js +207 -0
  33. package/dist_ts/standards/cli.d.ts +7 -0
  34. package/dist_ts/standards/cli.js +89 -0
  35. package/dist_ts/standards/config.d.ts +33 -0
  36. package/dist_ts/standards/config.js +139 -0
  37. package/dist_ts/standards/errors.d.ts +9 -0
  38. package/dist_ts/standards/errors.js +17 -0
  39. package/dist_ts/standards/helpers.ast.d.ts +56 -0
  40. package/dist_ts/standards/helpers.ast.js +172 -0
  41. package/dist_ts/standards/helpers.paths.d.ts +36 -0
  42. package/dist_ts/standards/helpers.paths.js +86 -0
  43. package/dist_ts/standards/index.d.ts +14 -0
  44. package/dist_ts/standards/index.js +15 -0
  45. package/dist_ts/standards/output.d.ts +7 -0
  46. package/dist_ts/standards/output.js +57 -0
  47. package/dist_ts/standards/ratchet.d.ts +15 -0
  48. package/dist_ts/standards/ratchet.js +45 -0
  49. package/dist_ts/standards/rule.d.ts +50 -0
  50. package/dist_ts/standards/rule.js +9 -0
  51. package/dist_ts/standards/rules/barrel.element-index.d.ts +7 -0
  52. package/dist_ts/standards/rules/barrel.element-index.js +108 -0
  53. package/dist_ts/standards/rules/barrel.no-demo-export.d.ts +3 -0
  54. package/dist_ts/standards/rules/barrel.no-demo-export.js +29 -0
  55. package/dist_ts/standards/rules/demo.fixture-not-exported.d.ts +3 -0
  56. package/dist_ts/standards/rules/demo.fixture-not-exported.js +29 -0
  57. package/dist_ts/standards/rules/demo.groups.d.ts +6 -0
  58. package/dist_ts/standards/rules/demo.groups.js +72 -0
  59. package/dist_ts/standards/rules/demo.required.d.ts +3 -0
  60. package/dist_ts/standards/rules/demo.required.js +48 -0
  61. package/dist_ts/standards/rules/demo.separate-file.d.ts +3 -0
  62. package/dist_ts/standards/rules/demo.separate-file.js +38 -0
  63. package/dist_ts/standards/rules/demo.shape.d.ts +3 -0
  64. package/dist_ts/standards/rules/demo.shape.js +38 -0
  65. package/dist_ts/standards/rules/docs.component-index.d.ts +8 -0
  66. package/dist_ts/standards/rules/docs.component-index.js +84 -0
  67. package/dist_ts/standards/rules/element.exported.d.ts +3 -0
  68. package/dist_ts/standards/rules/element.exported.js +33 -0
  69. package/dist_ts/standards/rules/element.literal-tag.d.ts +3 -0
  70. package/dist_ts/standards/rules/element.literal-tag.js +30 -0
  71. package/dist_ts/standards/rules/element.reachable.d.ts +3 -0
  72. package/dist_ts/standards/rules/element.reachable.js +48 -0
  73. package/dist_ts/standards/rules/element.tag-map.d.ts +3 -0
  74. package/dist_ts/standards/rules/element.tag-map.js +83 -0
  75. package/dist_ts/standards/rules/i18n.literals.d.ts +3 -0
  76. package/dist_ts/standards/rules/i18n.literals.js +52 -0
  77. package/dist_ts/standards/rules/index.d.ts +12 -0
  78. package/dist_ts/standards/rules/index.js +83 -0
  79. package/dist_ts/standards/rules/layout.element-folder.d.ts +3 -0
  80. package/dist_ts/standards/rules/layout.element-folder.js +47 -0
  81. package/dist_ts/standards/rules/layout.entry-file-name.d.ts +3 -0
  82. package/dist_ts/standards/rules/layout.entry-file-name.js +71 -0
  83. package/dist_ts/standards/rules/layout.entry.d.ts +3 -0
  84. package/dist_ts/standards/rules/layout.entry.js +38 -0
  85. package/dist_ts/standards/rules/layout.group-folder.d.ts +3 -0
  86. package/dist_ts/standards/rules/layout.group-folder.js +22 -0
  87. package/dist_ts/standards/rules/layout.shared-00.d.ts +3 -0
  88. package/dist_ts/standards/rules/layout.shared-00.js +36 -0
  89. package/dist_ts/standards/rules/naming.class-matches-tag.d.ts +3 -0
  90. package/dist_ts/standards/rules/naming.class-matches-tag.js +26 -0
  91. package/dist_ts/standards/rules/naming.lowercase-files.d.ts +3 -0
  92. package/dist_ts/standards/rules/naming.lowercase-files.js +26 -0
  93. package/dist_ts/standards/rules/naming.tag-prefix.d.ts +3 -0
  94. package/dist_ts/standards/rules/naming.tag-prefix.js +23 -0
  95. package/dist_ts/standards/rules/props.accessor.d.ts +3 -0
  96. package/dist_ts/standards/rules/props.accessor.js +35 -0
  97. package/dist_ts/standards/rules/props.object-no-attribute.d.ts +3 -0
  98. package/dist_ts/standards/rules/props.object-no-attribute.js +42 -0
  99. package/dist_ts/standards/rules/props.reflect-primitive.d.ts +5 -0
  100. package/dist_ts/standards/rules/props.reflect-primitive.js +41 -0
  101. package/dist_ts/standards/rules/props.typed.d.ts +6 -0
  102. package/dist_ts/standards/rules/props.typed.js +64 -0
  103. package/dist_ts/standards/rules/shared.d.ts +38 -0
  104. package/dist_ts/standards/rules/shared.js +103 -0
  105. package/dist_ts/standards/rules/style.bdtheme.d.ts +5 -0
  106. package/dist_ts/standards/rules/style.bdtheme.js +28 -0
  107. package/dist_ts_interfaces/index.d.ts +1 -0
  108. package/dist_ts_interfaces/index.js +2 -1
  109. package/dist_ts_interfaces/requests.d.ts +35 -0
  110. package/dist_ts_interfaces/standard.d.ts +93 -0
  111. package/dist_ts_interfaces/standard.js +6 -0
  112. package/dist_ts_shell/bundlestatus.d.ts +15 -0
  113. package/dist_ts_shell/bundlestatus.js +64 -0
  114. package/dist_ts_shell/elements/wcc-contextmenu.d.ts +3 -0
  115. package/dist_ts_shell/elements/wcc-contextmenu.js +18 -3
  116. package/dist_ts_shell/elements/wcc-preview-frame.d.ts +6 -0
  117. package/dist_ts_shell/elements/wcc-preview-frame.js +50 -2
  118. package/dist_ts_shell/elements/wcc-shell.d.ts +15 -0
  119. package/dist_ts_shell/elements/wcc-shell.js +45 -3
  120. package/dist_ts_shell/plugins.d.ts +2 -1
  121. package/dist_ts_shell/plugins.js +3 -2
  122. package/dist_ts_web/00_commitinfo_data.js +1 -1
  123. package/package.json +8 -3
  124. package/readme.md +40 -3
  125. package/ts/00_commitinfo_data.ts +1 -1
  126. package/ts/classes.bundlestatus.ts +123 -0
  127. package/ts/classes.devapi.ts +9 -0
  128. package/ts/classes.devserver.ts +127 -47
  129. package/ts/cli.ts +12 -2
  130. package/ts/index.ts +0 -2
  131. package/ts/plugins.ts +10 -2
  132. package/ts/standards/baselines.ts +100 -0
  133. package/ts/standards/checker.ts +114 -0
  134. package/ts/standards/classes.gitrepo.ts +48 -0
  135. package/ts/standards/classes.sourceedits.ts +58 -0
  136. package/ts/standards/classes.standardfixer.ts +234 -0
  137. package/ts/standards/classes.standardproject.ts +250 -0
  138. package/ts/standards/classes.standardtree.ts +220 -0
  139. package/ts/standards/cli.ts +86 -0
  140. package/ts/standards/config.ts +160 -0
  141. package/ts/standards/errors.ts +18 -0
  142. package/ts/standards/helpers.ast.ts +208 -0
  143. package/ts/standards/helpers.paths.ts +119 -0
  144. package/ts/standards/index.ts +22 -0
  145. package/ts/standards/output.ts +65 -0
  146. package/ts/standards/ratchet.ts +63 -0
  147. package/ts/standards/rule.ts +58 -0
  148. package/ts/standards/rules/barrel.element-index.ts +112 -0
  149. package/ts/standards/rules/barrel.no-demo-export.ts +30 -0
  150. package/ts/standards/rules/demo.fixture-not-exported.ts +30 -0
  151. package/ts/standards/rules/demo.groups.ts +74 -0
  152. package/ts/standards/rules/demo.required.ts +49 -0
  153. package/ts/standards/rules/demo.separate-file.ts +40 -0
  154. package/ts/standards/rules/demo.shape.ts +42 -0
  155. package/ts/standards/rules/docs.component-index.ts +88 -0
  156. package/ts/standards/rules/element.exported.ts +35 -0
  157. package/ts/standards/rules/element.literal-tag.ts +30 -0
  158. package/ts/standards/rules/element.reachable.ts +49 -0
  159. package/ts/standards/rules/element.tag-map.ts +87 -0
  160. package/ts/standards/rules/i18n.literals.ts +58 -0
  161. package/ts/standards/rules/index.ts +87 -0
  162. package/ts/standards/rules/layout.element-folder.ts +49 -0
  163. package/ts/standards/rules/layout.entry-file-name.ts +73 -0
  164. package/ts/standards/rules/layout.entry.ts +40 -0
  165. package/ts/standards/rules/layout.group-folder.ts +23 -0
  166. package/ts/standards/rules/layout.shared-00.ts +37 -0
  167. package/ts/standards/rules/naming.class-matches-tag.ts +27 -0
  168. package/ts/standards/rules/naming.lowercase-files.ts +27 -0
  169. package/ts/standards/rules/naming.tag-prefix.ts +24 -0
  170. package/ts/standards/rules/props.accessor.ts +37 -0
  171. package/ts/standards/rules/props.object-no-attribute.ts +45 -0
  172. package/ts/standards/rules/props.reflect-primitive.ts +44 -0
  173. package/ts/standards/rules/props.typed.ts +70 -0
  174. package/ts/standards/rules/shared.ts +127 -0
  175. package/ts/standards/rules/style.bdtheme.ts +31 -0
  176. package/ts_interfaces/bridge.ts +95 -0
  177. package/ts_interfaces/catalog.ts +37 -0
  178. package/ts_interfaces/index.ts +4 -0
  179. package/ts_interfaces/plugins.ts +3 -0
  180. package/ts_interfaces/requests.ts +65 -0
  181. package/ts_interfaces/standard.ts +103 -0
  182. package/ts_shared/index.ts +1 -0
  183. package/ts_shared/plugins.ts +3 -0
  184. package/ts_shared/previewroute.ts +58 -0
  185. package/ts_shell/bundlestatus.ts +68 -0
  186. package/ts_shell/elements/wcc-contextmenu.ts +306 -0
  187. package/ts_shell/elements/wcc-preview-frame.ts +167 -0
  188. package/ts_shell/elements/wcc-properties.ts +998 -0
  189. package/ts_shell/elements/wcc-record-button.ts +108 -0
  190. package/ts_shell/elements/wcc-recording-panel.ts +1005 -0
  191. package/ts_shell/elements/wcc-shell.ts +485 -0
  192. package/ts_shell/elements/wcc-sidebar.ts +1419 -0
  193. package/ts_shell/index.html +21 -0
  194. package/ts_shell/index.ts +4 -0
  195. package/ts_shell/plugins.ts +12 -0
  196. package/ts_shell/previewconnection.ts +103 -0
  197. package/ts_shell/services/recorder.service.ts +451 -0
  198. package/ts_shell/types/dom-mediacapture-stub/index.d.ts +12 -0
  199. package/ts_shell/types/dom-mediacapture-stub/package.json +6 -0
  200. package/ts_shell/types/dom-webcodecs-stub/index.d.ts +2 -0
  201. package/ts_shell/types/dom-webcodecs-stub/package.json +6 -0
  202. package/ts_web/00_commitinfo_data.ts +1 -1
@@ -0,0 +1,57 @@
1
+ import * as plugins from '../plugins.js';
2
+ const isShown = (findingArg, verboseArg) => verboseArg || (!findingArg.covered && findingArg.severity !== 'info');
3
+ /** The text form of a check report: findings grouped by file, then a summary. */
4
+ export const renderStandardReport = (reportArg, verboseArg) => {
5
+ const lines = [];
6
+ let currentFile = null;
7
+ for (const finding of reportArg.findings.filter((findingArg) => isShown(findingArg, verboseArg))) {
8
+ if (finding.file !== currentFile) {
9
+ if (currentFile !== null) {
10
+ lines.push('');
11
+ }
12
+ lines.push(finding.file);
13
+ currentFile = finding.file;
14
+ }
15
+ const notes = [finding.fixable ? 'fixable' : '', finding.covered ? `covered by the ${finding.covered}` : ''].filter(Boolean);
16
+ lines.push(` ${finding.line}:${finding.column} ${finding.severity} ${finding.ruleId} ${finding.message}${notes.length ? ` (${notes.join(', ')})` : ''}`);
17
+ }
18
+ if (verboseArg && reportArg.baselineSlack.length > 0) {
19
+ lines.push('', 'Below their baseline:');
20
+ for (const slack of reportArg.baselineSlack) {
21
+ lines.push(` ${slack.ruleId} ${slack.file} ${slack.baseline} → ${slack.current}`);
22
+ }
23
+ }
24
+ const count = (predicateArg) => reportArg.findings.filter(predicateArg).length;
25
+ const failing = count((findingArg) => findingArg.severity === 'error' && !findingArg.covered);
26
+ const warnings = count((findingArg) => findingArg.severity === 'warn' && !findingArg.covered);
27
+ const infos = count((findingArg) => findingArg.severity === 'info' && !findingArg.covered);
28
+ const allowlisted = count((findingArg) => findingArg.covered === 'allowlist');
29
+ const baselined = count((findingArg) => findingArg.covered === 'baseline');
30
+ if (lines.length > 0) {
31
+ lines.push('');
32
+ }
33
+ lines.push(`wcctools check (${reportArg.profile}): ${failing} error(s), ${warnings} warning(s), ${infos} info; `
34
+ + `${allowlisted} allowlisted, ${baselined} within baselines, ${reportArg.baselineSlack.length} file(s) below their baseline — ${reportArg.ok ? 'ok' : 'failed'}`);
35
+ return lines;
36
+ };
37
+ /** The text form of a fix result: the changes, then the check that remains. */
38
+ export const renderFixResult = (resultArg, verboseArg) => {
39
+ const { plan } = resultArg;
40
+ const lines = [resultArg.dryRun ? 'wcctools fix --dry-run would make these changes:' : 'wcctools fix made these changes:'];
41
+ for (const move of plan.moves) {
42
+ lines.push(` git mv ${move.from} ${move.to}`);
43
+ }
44
+ for (const file of plan.created) {
45
+ lines.push(` create ${file}`);
46
+ }
47
+ for (const edited of plan.edited) {
48
+ lines.push(` edit ${edited.file} (${edited.ruleIds.join(', ')})`);
49
+ }
50
+ if (plan.moves.length + plan.created.length + plan.edited.length === 0) {
51
+ lines.push(' nothing to fix');
52
+ }
53
+ lines.push('', resultArg.dryRun ? 'Remaining after the fix:' : 'Remaining:');
54
+ lines.push(...renderStandardReport(resultArg.remaining, verboseArg));
55
+ return lines;
56
+ };
57
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib3V0cHV0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vdHMvc3RhbmRhcmRzL291dHB1dC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssT0FBTyxNQUFNLGVBQWUsQ0FBQztBQUt6QyxNQUFNLE9BQU8sR0FBRyxDQUFDLFVBQTRCLEVBQUUsVUFBbUIsRUFBVyxFQUFFLENBQzdFLFVBQVUsSUFBSSxDQUFDLENBQUMsVUFBVSxDQUFDLE9BQU8sSUFBSSxVQUFVLENBQUMsUUFBUSxLQUFLLE1BQU0sQ0FBQyxDQUFDO0FBRXhFLGlGQUFpRjtBQUNqRixNQUFNLENBQUMsTUFBTSxvQkFBb0IsR0FBRyxDQUFDLFNBQTBCLEVBQUUsVUFBbUIsRUFBWSxFQUFFO0lBQ2hHLE1BQU0sS0FBSyxHQUFhLEVBQUUsQ0FBQztJQUMzQixJQUFJLFdBQVcsR0FBa0IsSUFBSSxDQUFDO0lBQ3RDLEtBQUssTUFBTSxPQUFPLElBQUksU0FBUyxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsQ0FBQyxVQUFVLEVBQUUsRUFBRSxDQUFDLE9BQU8sQ0FBQyxVQUFVLEVBQUUsVUFBVSxDQUFDLENBQUMsRUFBRSxDQUFDO1FBQ2pHLElBQUksT0FBTyxDQUFDLElBQUksS0FBSyxXQUFXLEVBQUUsQ0FBQztZQUNqQyxJQUFJLFdBQVcsS0FBSyxJQUFJLEVBQUUsQ0FBQztnQkFDekIsS0FBSyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQztZQUNqQixDQUFDO1lBQ0QsS0FBSyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUM7WUFDekIsV0FBVyxHQUFHLE9BQU8sQ0FBQyxJQUFJLENBQUM7UUFDN0IsQ0FBQztRQUNELE1BQU0sS0FBSyxHQUFHLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsT0FBTyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMs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
@@ -0,0 +1,15 @@
1
+ import * as plugins from '../plugins.js';
2
+ import { type IBaselineRaise } from './baselines.js';
3
+ import type { IOpenedStandardConfig } from './config.js';
4
+ export interface IBaselineRunResult {
5
+ /** The check with the configuration as it is after the run. */
6
+ report: plugins.interfaces.IStandardReport;
7
+ /** Files per rule written to the baselines; 0 when nothing was written. */
8
+ writtenFiles: number;
9
+ /** For --update-baseline: counts that would have to grow; the update was refused when not empty. */
10
+ raised: IBaselineRaise[];
11
+ }
12
+ /** `wcctools check --init-baseline`: records the current error counts; only while no baseline exists. */
13
+ export declare const initBaselines: (rootDirArg: string, openedArg: IOpenedStandardConfig) => Promise<IBaselineRunResult>;
14
+ /** `wcctools check --update-baseline`: lowers counts to the current ones, removes zeros, refuses to raise any. */
15
+ export declare const updateBaselines: (rootDirArg: string, openedArg: IOpenedStandardConfig) => Promise<IBaselineRunResult>;
@@ -0,0 +1,45 @@
1
+ import * as plugins from '../plugins.js';
2
+ import { initialBaselines, updatedBaselines } from './baselines.js';
3
+ import { checkStandard } from './checker.js';
4
+ import { loadStandardProject } from './classes.standardproject.js';
5
+ import { StandardUsageError } from './errors.js';
6
+ const hasBaselines = (configArg) => Object.values(configArg.baselines ?? {}).some((countsArg) => Object.keys(countsArg).length > 0);
7
+ const withBaselines = (configArg, baselinesArg) => {
8
+ const config = { ...configArg };
9
+ delete config.baselines;
10
+ return Object.keys(baselinesArg).length > 0 ? { ...config, baselines: baselinesArg } : config;
11
+ };
12
+ const countFiles = (baselinesArg) => Object.values(baselinesArg).reduce((sumArg, countsArg) => sumArg + Object.keys(countsArg).length, 0);
13
+ /** `wcctools check --init-baseline`: records the current error counts; only while no baseline exists. */
14
+ export const initBaselines = async (rootDirArg, openedArg) => {
15
+ const { loaded, writer } = openedArg;
16
+ if (hasBaselines(loaded.config)) {
17
+ throw new StandardUsageError('standard.baselines already exist; lower them with --update-baseline');
18
+ }
19
+ const project = await loadStandardProject(rootDirArg);
20
+ const baselines = initialBaselines(checkStandard(project, loaded));
21
+ const config = withBaselines(loaded.config, baselines);
22
+ if (countFiles(baselines) > 0) {
23
+ await writer.writeStandardConfig(config);
24
+ }
25
+ return { report: checkStandard(project, { ...loaded, config }), writtenFiles: countFiles(baselines), raised: [] };
26
+ };
27
+ /** `wcctools check --update-baseline`: lowers counts to the current ones, removes zeros, refuses to raise any. */
28
+ export const updateBaselines = async (rootDirArg, openedArg) => {
29
+ const { loaded, writer } = openedArg;
30
+ if (!hasBaselines(loaded.config)) {
31
+ throw new StandardUsageError('standard.baselines do not exist; record them with --init-baseline');
32
+ }
33
+ const project = await loadStandardProject(rootDirArg);
34
+ const report = checkStandard(project, loaded);
35
+ const { baselines, raised } = updatedBaselines(report, loaded.config.baselines);
36
+ if (raised.length > 0) {
37
+ return { report, writtenFiles: 0, raised };
38
+ }
39
+ const config = withBaselines(loaded.config, baselines);
40
+ if (JSON.stringify(config) !== JSON.stringify(loaded.config)) {
41
+ await writer.writeStandardConfig(config);
42
+ }
43
+ return { report: checkStandard(project, { ...loaded, config }), writtenFiles: countFiles(baselines), raised };
44
+ };
45
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmF0Y2hldC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3RzL3N0YW5kYXJkcy9yYXRjaGV0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxPQUFPLE1BQU0sZUFBZSxDQUFDO0FBQ3pDLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxnQkFBZ0IsRUFBdUIsTUFBTSxnQkFBZ0IsQ0FBQztBQUN6RixPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sY0FBYyxDQUFDO0FBQzdDLE9BQU8sRUFBRSxtQkFBbUIsRUFBRSxNQUFNLDhCQUE4QixDQUFDO0FBRW5FLE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLGFBQWEsQ0FBQztBQWFqRCxNQUFNLFlBQVksR0FBRyxDQUFDLFNBQTBCLEVBQVcsRUFBRSxDQUMzRCxNQUFNLENBQUMsTUFBTSxDQUFDLFNBQVMsQ0FBQyxTQUFTLElBQUksRUFBRSxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsU0FBUyxFQUFFLEVBQUUsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUMsQ0FBQztBQUVsRyxNQUFNLGFBQWEsR0FBRyxDQUFDLFNBQTBCLEVBQUUsWUFBdUQsRUFBbUIsRUFBRTtJQUM3SCxNQUFNLE1BQU0sR0FBb0IsRUFBRSxHQUFHLFNBQVMsRUFBRSxDQUFDO0lBQ2pELE9BQU8sTUFBTSxDQUFDLFNBQVMsQ0FBQztJQUN4QixPQUFPLE1BQU0sQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxHQUFHLE1BQU0sRUFBRSxTQUFTLEVBQUUsWUFBWSxFQUFFLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQztBQUNoRyxDQUFDLENBQUM7QUFFRixNQUFNLFVBQVUsR0FBRyxDQUFDLFlBQXVELEVBQVUsRUFBRSxDQUNyRixNQUFNLENBQUMsTUFBTSxDQUFDLFlBQVks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
@@ -0,0 +1,50 @@
1
+ import * as plugins from '../plugins.js';
2
+ import type { StandardProject } from './classes.standardproject.js';
3
+ type TStandardProfile = plugins.interfaces.TStandardProfile;
4
+ type TStandardSeverity = plugins.interfaces.TStandardSeverity;
5
+ /** Collects the changes of one fix run of one rule; the fixer applies them to its in-memory tree. */
6
+ export interface IFixBuilder {
7
+ /** Replaces the span [start, end) of a file's current text. Identical edits are applied once. */
8
+ edit(fileArg: string, startArg: number, endArg: number, textArg: string): void;
9
+ /** Creates a file; skipped when the path exists. */
10
+ create(fileArg: string, textArg: string): void;
11
+ /** Moves a file (`git mv`) and rewrites every relative module specifier that resolves to it. */
12
+ move(fromArg: string, toArg: string): void;
13
+ /**
14
+ * In this run's moves, `export … from` declarations of barrels (index.ts) that resolve to `targetArg`
15
+ * point at `barrelTargetArg` instead, e.g. at the new element folder's index.ts.
16
+ */
17
+ redirectBarrelExports(targetArg: string, barrelTargetArg: string): void;
18
+ }
19
+ export type TFixAction = (builderArg: IFixBuilder) => void;
20
+ export interface IRuleFinding {
21
+ file: string;
22
+ /** Offset in the file's text; 0 for file-level findings and for files that do not exist. */
23
+ position: number;
24
+ message: string;
25
+ /** Allowlist key: '<file>#<member>' or '<file>'. */
26
+ key: string;
27
+ /** Set when `wcctools fix` resolves the finding. */
28
+ fix?: TFixAction;
29
+ }
30
+ export interface IRuleContext {
31
+ project: StandardProject;
32
+ config: plugins.interfaces.IStandardConfig;
33
+ profile: TStandardProfile;
34
+ }
35
+ /** One rule of docs/standard.md. */
36
+ export interface IStandardRule {
37
+ id: string;
38
+ /** Severity per profile; a rule without a `base` severity belongs to `dees` only. `dees` falls back to `base`. */
39
+ severity: {
40
+ base?: TStandardSeverity;
41
+ dees?: TStandardSeverity;
42
+ };
43
+ fixMode: plugins.interfaces.TStandardFixMode;
44
+ /** Categories an allowlist entry may use; absent when the rule takes no allowlist. */
45
+ allowlistCategories?: readonly string[];
46
+ detect(contextArg: IRuleContext): IRuleFinding[];
47
+ }
48
+ /** The rule's severity in a profile, or null when the rule is not part of it. */
49
+ export declare const severityIn: (ruleArg: IStandardRule, profileArg: TStandardProfile) => TStandardSeverity | null;
50
+ export {};
@@ -0,0 +1,9 @@
1
+ import * as plugins from '../plugins.js';
2
+ /** The rule's severity in a profile, or null when the rule is not part of it. */
3
+ export const severityIn = (ruleArg, profileArg) => {
4
+ if (profileArg === 'dees') {
5
+ return ruleArg.severity.dees ?? ruleArg.severity.base ?? null;
6
+ }
7
+ return ruleArg.severity.base ?? null;
8
+ };
9
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicnVsZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3RzL3N0YW5kYXJkcy9ydWxlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxPQUFPLE1BQU0sZUFBZSxDQUFDO0FBbUR6QyxpRkFBaUY7QUFDakYsTUFBTSxDQUFDLE1BQU0sVUFBVSxHQUFHLENBQUMsT0FBc0IsRUFBRSxVQUE0QixFQUE0QixFQUFFO0lBQzNHLElBQUksVUFBVSxLQUFLLE1BQU0sRUFBRSxDQUFDO1FBQzFCLE9BQU8sT0FBTyxDQUFDLFFBQVEsQ0FBQyxJQUFJLElBQUksT0FBTyxDQUFDLFFBQVEsQ0FBQyxJQUFJLElBQUksSUFBSSxDQUFDO0lBQ2hFLENBQUM7SUFDRCxPQUFPLE9BQU8sQ0FBQyxRQUFRLENBQUMsSUFBSSxJQUFJLElBQUksQ0FBQztBQUN2QyxDQUFDLENBQUMifQ==
@@ -0,0 +1,7 @@
1
+ import type { IStandardRule } from '../rule.js';
2
+ /**
3
+ * An element folder has `index.ts` re-exporting the entry file (and `types.ts`); a group folder's
4
+ * `index.ts` re-exports each element folder's `index.ts`; `ts_web/elements/index.ts` re-exports each
5
+ * group or element folder.
6
+ */
7
+ export declare const barrelElementIndexRule: IStandardRule;
@@ -0,0 +1,108 @@
1
+ import { baseOf, dirOf, specifierFor } from '../helpers.paths.js';
2
+ import { addReexport, catalogElements, elementsDir, isInElementFolder } from './shared.js';
3
+ /**
4
+ * An element folder has `index.ts` re-exporting the entry file (and `types.ts`); a group folder's
5
+ * `index.ts` re-exports each element folder's `index.ts`; `ts_web/elements/index.ts` re-exports each
6
+ * group or element folder.
7
+ */
8
+ export const barrelElementIndexRule = {
9
+ id: 'barrel/element-index',
10
+ severity: { base: 'warn' },
11
+ fixMode: 'auto',
12
+ detect: ({ project }) => {
13
+ const findings = new Map();
14
+ const add = (findingArg) => {
15
+ const id = `${findingArg.file}|${findingArg.message}`;
16
+ if (!findings.has(id)) {
17
+ findings.set(id, findingArg);
18
+ }
19
+ };
20
+ const folderElements = catalogElements(project).filter(isInElementFolder);
21
+ const folders = [...new Set(folderElements.map((elementArg) => dirOf(elementArg.file)))].sort();
22
+ const groupsWithFolders = new Set();
23
+ for (const element of folderElements) {
24
+ const folder = dirOf(element.file);
25
+ const index = `${folder}/index.ts`;
26
+ const types = `${folder}/types.ts`;
27
+ if (!project.files.has(index)) {
28
+ const exported = [element.file, ...(project.files.has(types) ? [types] : [])];
29
+ add({
30
+ file: index,
31
+ position: 0,
32
+ key: index,
33
+ message: `${folder}/ has no index.ts`,
34
+ fix: (builderArg) => builderArg.create(index, exported.map((fileArg) => `export * from '${specifierFor(index, fileArg, 'js')}';\n`).join('')),
35
+ });
36
+ continue;
37
+ }
38
+ for (const required of [element.file, types]) {
39
+ if (!project.files.has(required) || project.reexports(index).some((reexportArg) => reexportArg.target === required)) {
40
+ continue;
41
+ }
42
+ add({
43
+ file: index,
44
+ position: 0,
45
+ key: index,
46
+ message: `${index} does not re-export ./${baseOf(required)}`,
47
+ fix: (builderArg) => addReexport(builderArg, project, index, required),
48
+ });
49
+ }
50
+ const parent = dirOf(folder);
51
+ const parentIndex = `${parent}/index.ts`;
52
+ if (parent !== elementsDir) {
53
+ groupsWithFolders.add(parent);
54
+ }
55
+ if (!project.files.has(parentIndex)) {
56
+ if (parent === elementsDir) {
57
+ continue;
58
+ }
59
+ const groupFolders = folders.filter((folderArg) => dirOf(folderArg) === parent);
60
+ add({
61
+ file: parentIndex,
62
+ position: 0,
63
+ key: parentIndex,
64
+ message: `${parent}/ has no index.ts`,
65
+ fix: (builderArg) => builderArg.create(parentIndex, groupFolders.map((folderArg) => `export * from '${specifierFor(parentIndex, `${folderArg}/index.ts`, 'js')}';\n`).join('')),
66
+ });
67
+ continue;
68
+ }
69
+ const parentReexports = project.reexports(parentIndex);
70
+ if (parentReexports.some((reexportArg) => reexportArg.target === index)) {
71
+ continue;
72
+ }
73
+ const inside = parentReexports.filter((reexportArg) => reexportArg.target?.startsWith(`${folder}/`));
74
+ const finding = {
75
+ file: parentIndex,
76
+ position: inside[0]?.statement.getStart() ?? 0,
77
+ key: parentIndex,
78
+ message: `${parentIndex} does not re-export ${baseOf(folder)}/index.ts`,
79
+ };
80
+ if (inside.length === 0) {
81
+ finding.fix = (builderArg) => addReexport(builderArg, project, parentIndex, index);
82
+ }
83
+ else if (inside.length === 1) {
84
+ const literal = inside[0].statement.moduleSpecifier;
85
+ finding.fix = (builderArg) => builderArg.edit(parentIndex, literal.getStart() + 1, literal.end - 1, specifierFor(parentIndex, index, 'js'));
86
+ }
87
+ add(finding);
88
+ }
89
+ const elementsIndex = `${elementsDir}/index.ts`;
90
+ if (project.files.has(elementsIndex)) {
91
+ for (const group of [...groupsWithFolders].sort()) {
92
+ const groupIndex = `${group}/index.ts`;
93
+ if (!project.files.has(groupIndex) || project.reexports(elementsIndex).some((reexportArg) => reexportArg.target === groupIndex)) {
94
+ continue;
95
+ }
96
+ add({
97
+ file: elementsIndex,
98
+ position: 0,
99
+ key: elementsIndex,
100
+ message: `${elementsIndex} does not re-export ${baseOf(group)}/index.ts`,
101
+ fix: (builderArg) => addReexport(builderArg, project, elementsIndex, groupIndex),
102
+ });
103
+ }
104
+ }
105
+ return [...findings.values()];
106
+ },
107
+ };
108
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmFycmVsLmVsZW1lbnQtaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi90cy9zdGFuZGFyZHMvcnVsZXMvYmFycmVsLmVsZW1lbnQtaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQUUsWUFBWSxFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFFbEUsT0FBTyxFQUFFLFdBQVcsRUFBRSxlQUFlLEVBQUUsV0FBVyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sYUFBYSxDQUFDO0FBRTNGOzs7O0dBSUc7QUFDSCxNQUFNLENBQUMsTUFBTSxzQkFBc0IsR0FBa0I7SUFDbkQsRUFBRSxFQUFFLHNCQUFzQjtJQUMxQixRQUFRLEVBQUUsRUFBRSxJQUFJLEVBQUUsTUFBTSxFQUFFO0lBQzFCLE9BQU8sRUFBRSxNQUFNO0lBQ2YsTUFBTSxFQUFFLENBQUMsRUFBRSxPQUFPLEVBQUUsRUFBRSxFQUFFO1FBQ3RCLE1BQU0sUUFBUSxHQUFHLElBQUksR0FBRyxFQUF3QixDQUFDO1FBQ2pELE1BQU0sR0FBRyxHQUFHLENBQUMsVUFBd0IsRUFBUSxFQUFFO1lBQzdDLE1BQU0sRUFBRSxHQUFHLEdBQUcsVUFBVSxDQUFDLElBQUksSUFBSSxVQUFVLENBQUMsT0FBTyxFQUFFLENBQUM7WUFDdEQsSUFBSSxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQztnQkFDdEIsUUFBUSxDQUFDLEdBQUcsQ0FBQyxFQUFFLEVBQUUsVUFBVSxDQUFDLENBQUM7WUFDL0IsQ0FBQztRQUNILENBQUMsQ0FBQztRQUNGLE1BQU0sY0FBYyxHQUFHLGVBQWUsQ0FBQyxPQUFPLENBQUMsQ0FBQyxNQUFNLENBQUMsaUJBQWlCLENBQUMsQ0FBQztRQUMxRSxNQUFNLE9BQU8sR0FBRyxDQUFDLEdBQUcsSUFBSSxHQUFHLENBQUMsY0FBYyxDQUFDLEdBQUcsQ0FBQyxDQUFDLFVB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
@@ -0,0 +1,3 @@
1
+ import type { IStandardRule } from '../rule.js';
2
+ /** No barrel exports a demo file. */
3
+ export declare const barrelNoDemoExportRule: IStandardRule;
@@ -0,0 +1,29 @@
1
+ import { baseOf, isDemoFile } from '../helpers.paths.js';
2
+ import { removeStatement } from './shared.js';
3
+ /** No barrel exports a demo file. */
4
+ export const barrelNoDemoExportRule = {
5
+ id: 'barrel/no-demo-export',
6
+ severity: { base: 'error' },
7
+ fixMode: 'auto',
8
+ detect: ({ project }) => {
9
+ const findings = [];
10
+ for (const file of project.webFiles) {
11
+ if (baseOf(file) !== 'index.ts') {
12
+ continue;
13
+ }
14
+ for (const reexport of project.reexports(file)) {
15
+ if (reexport.target && isDemoFile(reexport.target)) {
16
+ findings.push({
17
+ file,
18
+ position: reexport.statement.getStart(),
19
+ key: file,
20
+ message: `${file} exports the demo file ${reexport.target}`,
21
+ fix: (builderArg) => removeStatement(builderArg, file, reexport.statement),
22
+ });
23
+ }
24
+ }
25
+ }
26
+ return findings;
27
+ },
28
+ };
29
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmFycmVsLm5vLWRlbW8tZXhwb3J0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vdHMvc3RhbmRhcmRzL3J1bGVzL2JhcnJlbC5uby1kZW1vLWV4cG9ydC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsTUFBTSxFQUFFLFVBQVUsRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBRXpELE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSxhQUFhLENBQUM7QUFFOUMscUNBQXFDO0FBQ3JDLE1BQU0sQ0FBQyxNQUFNLHNCQUFzQixHQUFrQjtJQUNuRCxFQUFFLEVBQUUsdUJBQXVCO0lBQzNCLFFBQVEsRUFBRSxFQUFFLElBQUksRUFBRSxPQUFPLEVBQUU7SUFDM0IsT0FBTyxFQUFFLE1BQU07SUFDZixNQUFNLEVBQUUsQ0FBQyxFQUFFLE9BQU8sRUFBRSxFQUFFLEVBQUU7UUFDdEIsTUFBTSxRQUFRLEdBQW1CLEVBQUUsQ0FBQztRQUNwQyxLQUFLLE1BQU0sSUFBSSxJQUFJLE9BQU8sQ0FBQyxRQUFRLEVBQUUsQ0FBQztZQUNwQyxJQUFJLE1BQU0sQ0FBQyxJQUFJLENBQUMsS0FBSyxVQUFVLEVBQUUsQ0FBQztnQkFDaEMsU0FBUztZQUNYLENBQUM7WUFDRCxLQUFLLE1BQU0sUUFBUSxJQUFJLE9BQU8sQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQztnQkFDL0MsSUFBSSxRQUFRLENBQUMsTUFBTSxJQUFJLFVBQVUsQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQztvQkFDbkQsUUFBUSxDQUFDLElBQUksQ0FBQzt3QkFDWixJQUFJO3dCQUNKLFFBQVEsRUFBRSxRQUFRLENBQUMsU0FBUyxDQUFDLFFBQVEsRUFBRTt3QkFDdkMsR0FBRyxFQUFFLElBQUk7d0JBQ1QsT0FBTyxFQUFFLEdBQUcsSUFBSSwwQkFBMEIsUUFBUSxDQUFDLE1BQU0sRUFBRTt3QkFDM0QsR0FBRyxFQUFFLENBQUMsVUFBVSxFQUFFLEVBQUUsQ0FBQyxlQUFlLENBQUMsVUFBVSxFQUFFLElBQUksRUFBRSxRQUFRLENBQUMsU0FBUyxDQUFDO3FCQUMzRSxDQUFDLENBQUM7Z0JBQ0wsQ0FBQztZQUNILENBQUM7UUFDSCxDQUFDO1FBQ0QsT0FBTyxRQUFRLENBQUM7SUFDbEIsQ0FBQztDQUNGLENBQUMifQ==
@@ -0,0 +1,3 @@
1
+ import type { IStandardRule } from '../rule.js';
2
+ /** Elements declared in demo files are not reachable from `ts_web/elements/index.ts`. */
3
+ export declare const demoFixtureNotExportedRule: IStandardRule;
@@ -0,0 +1,29 @@
1
+ import { elementsBarrel } from '../classes.standardproject.js';
2
+ import { elementKey, removeStatement } from './shared.js';
3
+ /** Elements declared in demo files are not reachable from `ts_web/elements/index.ts`. */
4
+ export const demoFixtureNotExportedRule = {
5
+ id: 'demo/fixture-not-exported',
6
+ severity: { base: 'warn' },
7
+ fixMode: 'auto',
8
+ detect: ({ project }) => {
9
+ const findings = [];
10
+ const reached = project.reachableFrom(elementsBarrel);
11
+ for (const element of project.elements) {
12
+ if (!element.inDemoFile || !reached.has(element.file)) {
13
+ continue;
14
+ }
15
+ const exporters = [...reached].flatMap((fileArg) => project.reexports(fileArg)).filter((reexportArg) => reexportArg.target === element.file);
16
+ findings.push({
17
+ file: element.file,
18
+ position: element.decoratorCall.getStart(),
19
+ key: elementKey(element),
20
+ message: `fixture element <${element.tag ?? '?'}> in a demo file is reachable from ${elementsBarrel}`,
21
+ fix: exporters.length > 0
22
+ ? (builderArg) => exporters.forEach((reexportArg) => removeStatement(builderArg, reexportArg.file, reexportArg.statement))
23
+ : undefined,
24
+ });
25
+ }
26
+ return findings;
27
+ },
28
+ };
29
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGVtby5maXh0dXJlLW5vdC1leHBvcnRlZC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3RzL3N0YW5kYXJkcy9ydWxlcy9kZW1vLmZpeHR1cmUtbm90LWV4cG9ydGVkLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSwrQkFBK0IsQ0FBQztBQUUvRCxPQUFPLEVBQUUsVUFBVSxFQUFFLGVBQWUsRUFBRSxNQUFNLGFBQWEsQ0FBQztBQUUxRCx5RkFBeUY7QUFDekYsTUFBTSxDQUFDLE1BQU0sMEJBQTBCLEdBQWtCO0lBQ3ZELEVBQUUsRUFBRSwyQkFBMkI7SUFDL0IsUUFBUSxFQUFFLEVBQUUsSUFBSSxFQUFFLE1BQU0sRUFBRTtJQUMxQixPQUFPLEVBQUUsTUFBTTtJQUNmLE1BQU0sRUFBRSxDQUFDLEVBQUUsT0FBTyxFQUFFLEVBQUUsRUFBRTtRQUN0QixNQUFNLFFBQVEsR0FBbUIsRUFBRSxDQUFDO1FBQ3BDLE1BQU0sT0FBTyxHQUFHLE9BQU8sQ0FBQyxhQUFhLENBQUMsY0FBYyxDQUFDLENBQUM7UUFDdEQsS0FBSyxNQUFNLE9BQU8sSUFBSSxPQUFPLENBQUMsUUFBUSxFQUFFLENBQUM7WUFDdkMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxVQUFVLElBQUksQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDO2dCQUN0RCxTQUFTO1lBQ1gsQ0FBQztZQUNELE1BQU0sU0FBUyxHQUFHLENBQUMsR0FBRyxPQUFPLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxPQUFPLEVBQUUsRUFBRSxDQUFDLE9BQU8sQ0FBQyxTQUFTLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxXQUFXLEVBQUUsRUFBRSxDQUFDLFdBQVcsQ0FBQyxNQUFNLEtBQUssT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDO1lBQzdJLFFBQVEsQ0FBQyxJQUFJLENBQUM7Z0JBQ1osSUFBSSxFQUFFLE9BQU8sQ0FBQyxJQUFJO2dCQUNsQixRQUFRLEVBQUUsT0FBTyxDQUFDLGFBQWEsQ0FBQyxRQUFRLEVBQUU7Z0JBQzFDLEdBQUcsRUFBRSxVQUFVLENBQUMsT0FBTyxDQUFDO2dCQUN4QixPQUFPLEVBQUUsb0JBQW9CLE9BQU8sQ0FBQyxHQUFHLElBQUksR0FBRyxzQ0FBc0MsY0FBYyxFQUFFO2dCQUNyRyxHQUFHLEVBQUUsU0FBUyxDQUFDLE1BQU0sR0FBRyxDQUFDO29CQUN2QixDQUFDLENBQUMsQ0FBQyxVQUFVLEVBQUUsRUFBRSxDQUFDLFNBQVMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxXQUFXLEVBQUUsRUFBRSxDQUFDLGVBQWUsQ0FBQyxVQUFVLEVBQUUsV0FBVyxDQUFDLElBQUksRUFBRSxXQUFXLENBQUMsU0FBUyxDQUFDLENBQUM7b0JBQzFILENBQUMsQ0FBQyxTQUFTO2FBQ2QsQ0FBQyxDQUFDO1FBQ0wsQ0FBQztRQUNELE9BQU8sUUFBUSxDQUFDO0lBQ2xCLENBQUM7Q0FDRixDQUFDIn0=
@@ -0,0 +1,6 @@
1
+ import type { IStandardRule } from '../rule.js';
2
+ /**
3
+ * An element with a demo declares `static demoGroups`, a non-empty string or array of non-empty strings.
4
+ * dees: the first entry is `standard.groupNames[<area>]` of the element's `00group-<area>`.
5
+ */
6
+ export declare const demoGroupsRule: IStandardRule;
@@ -0,0 +1,72 @@
1
+ import * as plugins from '../../plugins.js';
2
+ import * as ast from '../helpers.ast.js';
3
+ import { catalogElements, elementKey, groupAreaOf, nextLineStart } from './shared.js';
4
+ const ts = plugins.typescript;
5
+ const quote = (textArg) => `'${textArg.replace(/\\/g, '\\\\').replace(/'/g, "\\'")}'`;
6
+ /**
7
+ * An element with a demo declares `static demoGroups`, a non-empty string or array of non-empty strings.
8
+ * dees: the first entry is `standard.groupNames[<area>]` of the element's `00group-<area>`.
9
+ */
10
+ export const demoGroupsRule = {
11
+ id: 'demo/groups',
12
+ severity: { base: 'warn' },
13
+ fixMode: 'auto',
14
+ detect: ({ project, config, profile }) => {
15
+ const findings = [];
16
+ for (const element of catalogElements(project)) {
17
+ const demo = ast.findStaticProperty(element.classNode, 'demo');
18
+ if (!demo) {
19
+ continue;
20
+ }
21
+ const area = profile === 'dees' ? groupAreaOf(element.file) : null;
22
+ const expected = area ? config.groupNames?.[area] ?? null : null;
23
+ const base = { file: element.file, key: elementKey(element) };
24
+ const member = ast.findStaticProperty(element.classNode, 'demoGroups');
25
+ const text = element.sourceFile.text;
26
+ if (!member) {
27
+ const finding = { ...base, position: demo.getStart(), message: `${element.className ?? '?'} has a demo but no static demoGroups` };
28
+ if (expected) {
29
+ const at = nextLineStart(text, demo.end);
30
+ finding.fix = (builderArg) => builderArg.edit(element.file, at, at, `${ast.indentationAt(text, demo.getStart())}public static demoGroups = [${quote(expected)}];\n`);
31
+ }
32
+ findings.push(finding);
33
+ continue;
34
+ }
35
+ const initializer = member.initializer;
36
+ let entries = null;
37
+ if (initializer && ast.isStringLiteralLike(initializer)) {
38
+ entries = [initializer.text];
39
+ }
40
+ else if (initializer && ts.isArrayLiteralExpression(initializer) && initializer.elements.every(ast.isStringLiteralLike)) {
41
+ entries = initializer.elements.map((entryArg) => entryArg.text);
42
+ }
43
+ else if (!initializer || ts.isArrayLiteralExpression(initializer) || ts.isLiteralExpression(initializer)) {
44
+ findings.push({ ...base, position: member.getStart(), message: `static demoGroups of ${element.className ?? '?'} is not a string or an array of strings` });
45
+ continue;
46
+ }
47
+ if (entries && (entries.length === 0 || entries.some((entryArg) => entryArg.length === 0))) {
48
+ findings.push({ ...base, position: member.getStart(), message: `static demoGroups of ${element.className ?? '?'} is empty or has an empty entry` });
49
+ continue;
50
+ }
51
+ if (profile !== 'dees' || !area || !entries) {
52
+ continue;
53
+ }
54
+ if (!expected) {
55
+ findings.push({ ...base, position: member.getStart(), message: `standard.groupNames has no display name for the area '${area}'` });
56
+ continue;
57
+ }
58
+ if (entries[0] !== expected) {
59
+ const target = initializer;
60
+ const reordered = [expected, ...entries.filter((entryArg) => entryArg !== expected)];
61
+ findings.push({
62
+ ...base,
63
+ position: member.getStart(),
64
+ message: `the first demo group of ${element.className ?? '?'} is ${quote(entries[0])}; expected ${quote(expected)} (00group-${area})`,
65
+ fix: (builderArg) => builderArg.edit(element.file, target.getStart(), target.end, `[${reordered.map(quote).join(', ')}]`),
66
+ });
67
+ }
68
+ }
69
+ return findings;
70
+ },
71
+ };
72
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGVtby5ncm91cHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi90cy9zdGFuZGFyZHMvcnVsZXMvZGVtby5ncm91cHMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxLQUFLLE9BQU8sTUFBTSxrQkFBa0IsQ0FBQztBQUM1QyxPQUFPLEtBQUssR0FBRyxNQUFNLG1CQUFtQixDQUFDO0FBRXpDLE9BQU8sRUFBRSxlQUFlLEVBQUUsVUFBVSxFQUFFLFdBQVcsRUFBRSxhQUFhLEVBQUUsTUFBTSxhQUFhLENBQUM7QUFFdEYsTUFBTSxFQUFFLEdBQUcsT0FBTyxDQUFDLFVBQVUsQ0FBQztBQUU5QixNQUFNLEtBQUssR0FBRyxDQUFDLE9BQWUsRUFBVSxFQUFFLENBQUMsSUFBSSxPQUFPLENBQUMsT0FBTyxDQUFDLEtBQUssRUFBRSxNQUFNLENBQUMsQ0FBQyxPQUFPLENBQUMsSUFBSSxFQUFFLEtBQUssQ0FBQyxHQUFHLENBQUM7QUFFdEc7OztHQUdHO0FBQ0gsTUFBTSxDQUFDLE1BQU0sY0FBYyxHQUFrQjtJQUMzQyxFQUFFLEVBQUUsYUFBYTtJQUNqQixRQUFRLEVBQUUsRUFBRSxJQUFJLEVBQUUsTUFBTSxFQUFFO0lBQzFCLE9BQU8sRUFBRSxNQUFNO0lBQ2YsTUFBTSxFQUFFLENBQUMsRUFBRSxPQUFPLEVBQUUsTUFBTSxFQUFFLE9BQU8sRUFBRSxFQUFFLEVBQUU7UUFDdkMsTUFBTSxRQUFRLEdBQW1CLEVBQUUsQ0FBQztRQUNwQyxLQUFLLE1BQU0sT0FBTyxJQUFJLGVBQWUsQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDO1lBQy9DLE1BQU0sSUFBSSxHQUFHLEdBQUcsQ0FBQyxrQkFBa0IsQ0FBQyxPQUFPLENBQUMsU0FBUyxFQUFFLE1BQU0sQ0FBQyxDQUFDO1lBQy9ELElBQUksQ0FBQyxJQUFJLEVBQUUsQ0FBQztnQkFDVixTQUFTO1lBQ1gsQ0FBQztZQUNELE1BQU0sSUFBSSxHQUFHLE9BQU8sS0FBSyxN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
@@ -0,0 +1,3 @@
1
+ import type { IStandardRule } from '../rule.js';
2
+ /** Every exported element has `static demo`. The opt-in fix writes a stub that renders the bare tag. */
3
+ export declare const demoRequiredRule: IStandardRule;
@@ -0,0 +1,48 @@
1
+ import * as ast from '../helpers.ast.js';
2
+ import { dirOf } from '../helpers.paths.js';
3
+ import { catalogElements, elementKey, isCustomElementName } from './shared.js';
4
+ /** Every exported element has `static demo`. The opt-in fix writes a stub that renders the bare tag. */
5
+ export const demoRequiredRule = {
6
+ id: 'demo/required',
7
+ severity: { base: 'warn' },
8
+ fixMode: 'opt-in',
9
+ allowlistCategories: ['subcomponent', 'base'],
10
+ detect: ({ project }) => {
11
+ const findings = [];
12
+ const elements = catalogElements(project);
13
+ for (const element of elements) {
14
+ if (!element.exported || ast.findStaticProperty(element.classNode, 'demo')) {
15
+ continue;
16
+ }
17
+ const finding = {
18
+ file: element.file,
19
+ position: element.decoratorCall.getStart(),
20
+ key: elementKey(element),
21
+ message: `${element.className ?? '?'} (<${element.tag ?? '?'}>) has no static demo`,
22
+ };
23
+ const sourceFile = element.sourceFile;
24
+ // The stub's file name and markup come from the tag: only a valid custom element name is usable.
25
+ const usableTag = element.tag && isCustomElementName(element.tag) ? element.tag : null;
26
+ const demoFile = usableTag ? `${dirOf(element.file)}/${usableTag}.demo.ts` : null;
27
+ const firstMember = element.classNode.members[0];
28
+ const alone = elements.filter((otherArg) => otherArg.file === element.file).length === 1;
29
+ if (usableTag && demoFile && element.className && firstMember && alone && !project.exists(demoFile) && !/\bdemoFunc\b/.test(sourceFile.text)) {
30
+ const tag = usableTag;
31
+ const customElementSource = ast.importSourceOf(sourceFile, 'customElement');
32
+ const htmlSource = ast.importSourceOf(sourceFile, 'html')
33
+ ?? (customElementSource && customElementSource !== 'lit/decorators.js' ? customElementSource : 'lit');
34
+ const text = sourceFile.text;
35
+ const importAt = ast.afterLastImport(sourceFile);
36
+ finding.fix = (builderArg) => {
37
+ builderArg.create(demoFile, `import { html } from '${htmlSource}';\n\nexport const demoFunc = () => html\`<${tag}></${tag}>\`;\n`);
38
+ builderArg.edit(element.file, importAt, importAt, `import { demoFunc } from './${tag}.demo.js';\n`);
39
+ const lineStart = text.lastIndexOf('\n', firstMember.getStart() - 1) + 1;
40
+ builderArg.edit(element.file, lineStart, lineStart, `${ast.indentationAt(text, firstMember.getStart())}public static demo = demoFunc;\n`);
41
+ };
42
+ }
43
+ findings.push(finding);
44
+ }
45
+ return findings;
46
+ },
47
+ };
48
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGVtby5yZXF1aXJlZC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3RzL3N0YW5kYXJkcy9ydWxlcy9kZW1vLnJlcXVpcmVkLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxHQUFHLE1BQU0sbUJBQW1CLENBQUM7QUFDekMsT0FBTyxFQUFFLEtBQUssRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBRTVDLE9BQU8sRUFBRSxlQUFlLEVBQUUsVUFBVSxFQUFFLG1CQUFtQixFQUFFLE1BQU0sYUFBYSxDQUFDO0FBRS9FLHdHQUF3RztBQUN4RyxNQUFNLENBQUMsTUFBTSxnQkFBZ0IsR0FBa0I7SUFDN0MsRUFBRSxFQUFFLGVBQWU7SUFDbkIsUUFBUSxFQUFFLEVBQUUsSUFBSSxFQUFFLE1BQU0sRUFBRTtJQUMxQixPQUFPLEVBQUUsUUFBUTtJQUNqQixtQkFBbUIsRUFBRSxDQUFDLGNBQWMsRUFBRSxNQUFNLENBQUM7SUFDN0MsTUFBTSxFQUFFLENBQUMsRUFBRSxPQUFPLEVBQUUsRUFBRSxFQUFFO1FBQ3RCLE1BQU0sUUFBUSxHQUFtQixFQUFFLENBQUM7UUFDcEMsTUFBTSxRQUFRLEdBQUcsZUFBZSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQzFDLEtBQUssTUFBTSxPQUFPLElBQUksUUFBUSxFQUFFLENBQUM7WUFDL0IsSUFBSSxDQUFDLE9BQU8sQ0FBQyxRQUFRLElBQUksR0FBRyxDQUFDLGtCQUFrQixDQUFDLE9BQU8sQ0FBQyxTQUFTLEVBQUUsTUFBTSxDQUFDLEVBQUUsQ0FBQztnQkFDM0UsU0FBUztZQUNYLENBQUM7WUFDRCxNQUFNLE9BQU8sR0FBaUI7Z0JBQzVCLElBQUksRUFBRSxPQUFPLENBQUMsSUFBSTtnQkFDbEIsUUFBUSxFQUFFLE9BQU8sQ0FBQyxhQUFhLENBQUMsUUFBUSxFQUFFO2dCQUMxQyxHQUFHLEVBQUUsVUFBVSxDQUFDLE9BQU8sQ0FBQztnQkFDeEIsT0FBTyxFQUFFLEdBQUcs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
@@ -0,0 +1,3 @@
1
+ import type { IStandardRule } from '../rule.js';
2
+ /** `static demo` refers to an export of the element's demo file. Report-only in 6.1. */
3
+ export declare const demoSeparateFileRule: IStandardRule;
@@ -0,0 +1,38 @@
1
+ import * as plugins from '../../plugins.js';
2
+ import * as ast from '../helpers.ast.js';
3
+ import { isDemoFile, resolveSpecifier } from '../helpers.paths.js';
4
+ import { catalogElements, elementKey, rootIdentifier } from './shared.js';
5
+ const ts = plugins.typescript;
6
+ /** `static demo` refers to an export of the element's demo file. Report-only in 6.1. */
7
+ export const demoSeparateFileRule = {
8
+ id: 'demo/separate-file',
9
+ severity: { base: 'warn', dees: 'error' },
10
+ fixMode: 'none',
11
+ detect: ({ project }) => {
12
+ const findings = [];
13
+ for (const element of catalogElements(project)) {
14
+ const member = ast.findStaticProperty(element.classNode, 'demo');
15
+ if (!member?.initializer) {
16
+ continue;
17
+ }
18
+ const initializer = member.initializer;
19
+ const references = ts.isArrayLiteralExpression(initializer) ? [...initializer.elements] : [initializer];
20
+ const separate = references.length > 0 && references.every((referenceArg) => {
21
+ const identifier = rootIdentifier(referenceArg);
22
+ const source = identifier ? ast.importSourceOf(element.sourceFile, identifier) : null;
23
+ const resolved = source ? resolveSpecifier(element.file, source, (fileArg) => project.files.has(fileArg)) : null;
24
+ return !!resolved && isDemoFile(resolved.target);
25
+ });
26
+ if (!separate) {
27
+ findings.push({
28
+ file: element.file,
29
+ position: member.getStart(),
30
+ key: elementKey(element),
31
+ message: `static demo of ${element.className ?? '?'} is not imported from its demo file (${element.tag ?? '<tag>'}.demo.ts)`,
32
+ });
33
+ }
34
+ }
35
+ return findings;
36
+ },
37
+ };
38
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGVtby5zZXBhcmF0ZS1maWxlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vdHMvc3RhbmRhcmRzL3J1bGVzL2RlbW8uc2VwYXJhdGUtZmlsZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssT0FBTyxNQUFNLGtCQUFrQixDQUFDO0FBQzVDLE9BQU8sS0FBSyxHQUFHLE1BQU0sbUJBQW1CLENBQUM7QUFDekMsT0FBTyxFQUFFLFVBQVUsRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBRW5FLE9BQU8sRUFBRSxlQUFlLEVBQUUsVUFBVSxFQUFFLGNBQWMsRUFBRSxNQUFNLGFBQWEsQ0FBQztBQUUxRSxNQUFNLEVBQUUsR0FBRyxPQUFPLENBQUMsVUFBVSxDQUFDO0FBRTlCLHdGQUF3RjtBQUN4RixNQUFNLENBQUMsTUFBTSxvQkFBb0IsR0FBa0I7SUFDakQsRUFBRSxFQUFFLG9CQUFvQjtJQUN4QixRQUFRLEVBQUUsRUFBRSxJQUFJLEVBQUUsTUFBTSxFQUFFLElBQUksRUFBRSxPQUFPLEVBQUU7SUFDekMsT0FBTyxFQUFFLE1BQU07SUFDZixNQUFNLEVBQUUsQ0FBQyxFQUFFLE9BQU8sRUFBRSxFQUFFLEVBQUU7UUFDdEIsTUFBTSxRQUFRLEdBQW1CLEVBQUUsQ0FBQztRQUNwQyxLQUFLLE1BQU0sT0FBTyxJQUFJLGVBQWUsQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDO1lBQy9DLE1BQU0sTUFBTSxHQUFHLEdBQUcsQ0FBQyxrQkFBa0IsQ0FBQyxPQUFPLENBQUMsU0FBUyxFQUFFLE1BQU0sQ0FBQyxDQUFDO1lBQ2pFLElBQUksQ0FBQyxNQUFNLEVBQUUsV0FBVyxFQUFFLENBQUM7Z0JBQ3pCLFNBQVM7WUFDWCxDQUFDO1lBQ0QsTUFBTSxXQUFXLEdBQUcsTUFBTSxDQUFDLFdBQVcsQ0FBQztZQUN2QyxNQUFNLFVBQVUsR0FBRyxFQUFFLENBQUMsd0JBQXdCLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxXQUFXLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsV0FBVyxDQUFDLENBQUM7WUFDeEcsTUFBTSxRQUFRLEdBQUcsVUFBVSxDQUFDLE1BQU0sR0FBRyxDQUFDLElBQUksVUFBVSxDQUFDLEtBQUssQ0FBQyxDQUFDLFlBQVksRUFBRSxFQUFFO2dCQUMxRSxNQUFNLFVBQVUsR0FBRyxjQUFjLENBQUMsWUFBWSxDQUFDLENBQUM7Z0JBQ2hELE1BQU0sTUFBTSxHQUFHLFVBQVUsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLGNBQWMsQ0FBQyxPQUFPLENBQUMsVUFBVSxFQUFFLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUM7Z0JBQ3RGLE1BQU0sUUFBUSxHQUFHLE1BQU0sQ0FBQyxDQUFDLENBQUMsZ0JBQWdCLENBQUMsT0FBTyxDQUFDLElBQUksRUFBRSxNQUFNLEVBQUUsQ0FBQyxPQUFPLEVBQUUsRUFBRSxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQztnQkFDakgsT0FBTyxDQUFDLENBQUMsUUFBUSxJQUFJLFVBQVUsQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLENBQUM7WUFDbkQsQ0FBQyxDQUFDLENBQUM7WUFDSCxJQUFJLENBQUMsUUFBUSxFQUFFLENBQUM7Z0JBQ2QsUUFBUSxDQUFDLElBQUksQ0FBQztvQkFDWixJQUFJLEVBQUUsT0FBTyxDQUFDLElBQUk7b0JBQ2xCLFFBQVEsRUFBRSxNQUFNLENBQUMsUUFBUSxFQUFFO29CQUMzQixHQUFHLEVBQUUsVUFBVSxDQUFDLE9BQU8sQ0FBQztvQkFDeEIsT0FBTyxFQUFFLGtCQUFrQixPQUFPLENBQUMsU0FBUyxJQUFJLEdBQUcsd0NBQXdDLE9BQU8sQ0FBQyxHQUFHLElBQUksT0FBTyxXQUFXO2lCQUM3SCxDQUFDLENBQUM7WUFDTCxDQUFDO1FBQ0gsQ0FBQztRQUNELE9BQU8sUUFBUSxDQUFDO0lBQ2xCLENBQUM7Q0FDRixDQUFDIn0=
@@ -0,0 +1,3 @@
1
+ import type { IStandardRule } from '../rule.js';
2
+ /** `static demo` is a function or a non-empty array of functions. */
3
+ export declare const demoShapeRule: IStandardRule;