@hominis/fireforge 0.9.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 +7 -0
- package/LICENSE.md +294 -0
- package/README.md +435 -0
- package/dist/bin/fireforge.d.ts +10 -0
- package/dist/bin/fireforge.js +29 -0
- package/dist/src/cli.d.ts +33 -0
- package/dist/src/cli.js +180 -0
- package/dist/src/commands/bootstrap.d.ts +9 -0
- package/dist/src/commands/bootstrap.js +73 -0
- package/dist/src/commands/build.d.ts +11 -0
- package/dist/src/commands/build.js +102 -0
- package/dist/src/commands/config.d.ts +13 -0
- package/dist/src/commands/config.js +135 -0
- package/dist/src/commands/discard.d.ts +12 -0
- package/dist/src/commands/discard.js +84 -0
- package/dist/src/commands/doctor.d.ts +18 -0
- package/dist/src/commands/doctor.js +356 -0
- package/dist/src/commands/download.d.ts +11 -0
- package/dist/src/commands/download.js +127 -0
- package/dist/src/commands/export-all.d.ts +11 -0
- package/dist/src/commands/export-all.js +122 -0
- package/dist/src/commands/export-shared.d.ts +48 -0
- package/dist/src/commands/export-shared.js +208 -0
- package/dist/src/commands/export.d.ts +13 -0
- package/dist/src/commands/export.js +178 -0
- package/dist/src/commands/furnace/apply.d.ts +7 -0
- package/dist/src/commands/furnace/apply.js +80 -0
- package/dist/src/commands/furnace/create.d.ts +8 -0
- package/dist/src/commands/furnace/create.js +377 -0
- package/dist/src/commands/furnace/deploy.d.ts +8 -0
- package/dist/src/commands/furnace/deploy.js +338 -0
- package/dist/src/commands/furnace/diff.d.ts +7 -0
- package/dist/src/commands/furnace/diff.js +119 -0
- package/dist/src/commands/furnace/index.d.ts +16 -0
- package/dist/src/commands/furnace/index.js +121 -0
- package/dist/src/commands/furnace/list.d.ts +5 -0
- package/dist/src/commands/furnace/list.js +65 -0
- package/dist/src/commands/furnace/override.d.ts +8 -0
- package/dist/src/commands/furnace/override.js +188 -0
- package/dist/src/commands/furnace/preview.d.ts +7 -0
- package/dist/src/commands/furnace/preview.js +96 -0
- package/dist/src/commands/furnace/remove.d.ts +8 -0
- package/dist/src/commands/furnace/remove.js +159 -0
- package/dist/src/commands/furnace/scan.d.ts +5 -0
- package/dist/src/commands/furnace/scan.js +112 -0
- package/dist/src/commands/furnace/status.d.ts +7 -0
- package/dist/src/commands/furnace/status.js +137 -0
- package/dist/src/commands/furnace/validate.d.ts +6 -0
- package/dist/src/commands/furnace/validate.js +91 -0
- package/dist/src/commands/furnace/validation-output.d.ts +7 -0
- package/dist/src/commands/furnace/validation-output.js +22 -0
- package/dist/src/commands/import.d.ts +11 -0
- package/dist/src/commands/import.js +241 -0
- package/dist/src/commands/lint.d.ts +10 -0
- package/dist/src/commands/lint.js +118 -0
- package/dist/src/commands/package.d.ts +11 -0
- package/dist/src/commands/package.js +80 -0
- package/dist/src/commands/re-export.d.ts +12 -0
- package/dist/src/commands/re-export.js +242 -0
- package/dist/src/commands/rebase/abort.d.ts +7 -0
- package/dist/src/commands/rebase/abort.js +49 -0
- package/dist/src/commands/rebase/confirm.d.ts +18 -0
- package/dist/src/commands/rebase/confirm.js +33 -0
- package/dist/src/commands/rebase/continue.d.ts +7 -0
- package/dist/src/commands/rebase/continue.js +81 -0
- package/dist/src/commands/rebase/index.d.ts +22 -0
- package/dist/src/commands/rebase/index.js +127 -0
- package/dist/src/commands/rebase/patch-loop.d.ts +9 -0
- package/dist/src/commands/rebase/patch-loop.js +135 -0
- package/dist/src/commands/rebase/summary.d.ts +12 -0
- package/dist/src/commands/rebase/summary.js +43 -0
- package/dist/src/commands/rebase.d.ts +4 -0
- package/dist/src/commands/rebase.js +6 -0
- package/dist/src/commands/register.d.ts +13 -0
- package/dist/src/commands/register.js +67 -0
- package/dist/src/commands/reset.d.ts +11 -0
- package/dist/src/commands/reset.js +83 -0
- package/dist/src/commands/resolve.d.ts +9 -0
- package/dist/src/commands/resolve.js +124 -0
- package/dist/src/commands/run.d.ts +9 -0
- package/dist/src/commands/run.js +91 -0
- package/dist/src/commands/setup-support.d.ts +23 -0
- package/dist/src/commands/setup-support.js +310 -0
- package/dist/src/commands/setup.d.ts +11 -0
- package/dist/src/commands/setup.js +94 -0
- package/dist/src/commands/status.d.ts +11 -0
- package/dist/src/commands/status.js +268 -0
- package/dist/src/commands/test.d.ts +12 -0
- package/dist/src/commands/test.js +182 -0
- package/dist/src/commands/token-coverage.d.ts +5 -0
- package/dist/src/commands/token-coverage.js +57 -0
- package/dist/src/commands/token.d.ts +14 -0
- package/dist/src/commands/token.js +121 -0
- package/dist/src/commands/watch.d.ts +9 -0
- package/dist/src/commands/watch.js +112 -0
- package/dist/src/commands/wire.d.ts +13 -0
- package/dist/src/commands/wire.js +149 -0
- package/dist/src/core/ast-utils.d.ts +47 -0
- package/dist/src/core/ast-utils.js +57 -0
- package/dist/src/core/brand-validation.d.ts +7 -0
- package/dist/src/core/brand-validation.js +15 -0
- package/dist/src/core/branding.d.ts +49 -0
- package/dist/src/core/branding.js +229 -0
- package/dist/src/core/browser-wire.d.ts +40 -0
- package/dist/src/core/browser-wire.js +66 -0
- package/dist/src/core/build-prepare.d.ts +25 -0
- package/dist/src/core/build-prepare.js +93 -0
- package/dist/src/core/config-mutate.d.ts +15 -0
- package/dist/src/core/config-mutate.js +51 -0
- package/dist/src/core/config-paths.d.ts +28 -0
- package/dist/src/core/config-paths.js +65 -0
- package/dist/src/core/config-state.d.ts +28 -0
- package/dist/src/core/config-state.js +152 -0
- package/dist/src/core/config-validate.d.ts +11 -0
- package/dist/src/core/config-validate.js +141 -0
- package/dist/src/core/config.d.ts +39 -0
- package/dist/src/core/config.js +70 -0
- package/dist/src/core/file-lock.d.ts +11 -0
- package/dist/src/core/file-lock.js +80 -0
- package/dist/src/core/firefox-archive.d.ts +40 -0
- package/dist/src/core/firefox-archive.js +63 -0
- package/dist/src/core/firefox-cache.d.ts +23 -0
- package/dist/src/core/firefox-cache.js +134 -0
- package/dist/src/core/firefox-download.d.ts +21 -0
- package/dist/src/core/firefox-download.js +129 -0
- package/dist/src/core/firefox-extract.d.ts +21 -0
- package/dist/src/core/firefox-extract.js +53 -0
- package/dist/src/core/firefox.d.ts +34 -0
- package/dist/src/core/firefox.js +78 -0
- package/dist/src/core/furnace-apply-helpers.d.ts +21 -0
- package/dist/src/core/furnace-apply-helpers.js +244 -0
- package/dist/src/core/furnace-apply.d.ts +16 -0
- package/dist/src/core/furnace-apply.js +147 -0
- package/dist/src/core/furnace-config.d.ts +94 -0
- package/dist/src/core/furnace-config.js +372 -0
- package/dist/src/core/furnace-constants.d.ts +4 -0
- package/dist/src/core/furnace-constants.js +6 -0
- package/dist/src/core/furnace-registration-ast.d.ts +24 -0
- package/dist/src/core/furnace-registration-ast.js +218 -0
- package/dist/src/core/furnace-registration-remove.d.ts +14 -0
- package/dist/src/core/furnace-registration-remove.js +89 -0
- package/dist/src/core/furnace-registration-validate.d.ts +20 -0
- package/dist/src/core/furnace-registration-validate.js +40 -0
- package/dist/src/core/furnace-registration.d.ts +29 -0
- package/dist/src/core/furnace-registration.js +96 -0
- package/dist/src/core/furnace-rollback.d.ts +20 -0
- package/dist/src/core/furnace-rollback.js +66 -0
- package/dist/src/core/furnace-scanner.d.ts +40 -0
- package/dist/src/core/furnace-scanner.js +143 -0
- package/dist/src/core/furnace-stories.d.ts +37 -0
- package/dist/src/core/furnace-stories.js +185 -0
- package/dist/src/core/furnace-validate-accessibility.d.ts +6 -0
- package/dist/src/core/furnace-validate-accessibility.js +32 -0
- package/dist/src/core/furnace-validate-checks.d.ts +4 -0
- package/dist/src/core/furnace-validate-checks.js +7 -0
- package/dist/src/core/furnace-validate-compatibility.d.ts +6 -0
- package/dist/src/core/furnace-validate-compatibility.js +57 -0
- package/dist/src/core/furnace-validate-helpers.d.ts +28 -0
- package/dist/src/core/furnace-validate-helpers.js +129 -0
- package/dist/src/core/furnace-validate-registration.d.ts +37 -0
- package/dist/src/core/furnace-validate-registration.js +220 -0
- package/dist/src/core/furnace-validate-structure.d.ts +6 -0
- package/dist/src/core/furnace-validate-structure.js +66 -0
- package/dist/src/core/furnace-validate.d.ts +16 -0
- package/dist/src/core/furnace-validate.js +103 -0
- package/dist/src/core/git-base.d.ts +47 -0
- package/dist/src/core/git-base.js +50 -0
- package/dist/src/core/git-diff.d.ts +63 -0
- package/dist/src/core/git-diff.js +246 -0
- package/dist/src/core/git-file-ops.d.ts +65 -0
- package/dist/src/core/git-file-ops.js +141 -0
- package/dist/src/core/git-status.d.ts +65 -0
- package/dist/src/core/git-status.js +163 -0
- package/dist/src/core/git.d.ts +113 -0
- package/dist/src/core/git.js +363 -0
- package/dist/src/core/license-headers.d.ts +36 -0
- package/dist/src/core/license-headers.js +83 -0
- package/dist/src/core/mach-build-artifacts.d.ts +29 -0
- package/dist/src/core/mach-build-artifacts.js +117 -0
- package/dist/src/core/mach-mozconfig.d.ts +17 -0
- package/dist/src/core/mach-mozconfig.js +50 -0
- package/dist/src/core/mach-python.d.ts +16 -0
- package/dist/src/core/mach-python.js +126 -0
- package/dist/src/core/mach.d.ts +106 -0
- package/dist/src/core/mach.js +166 -0
- package/dist/src/core/manifest-helpers.d.ts +25 -0
- package/dist/src/core/manifest-helpers.js +96 -0
- package/dist/src/core/manifest-register.d.ts +30 -0
- package/dist/src/core/manifest-register.js +65 -0
- package/dist/src/core/manifest-rules.d.ts +39 -0
- package/dist/src/core/manifest-rules.js +151 -0
- package/dist/src/core/manifest-tokenizers.d.ts +34 -0
- package/dist/src/core/manifest-tokenizers.js +84 -0
- package/dist/src/core/parser-fallback.d.ts +36 -0
- package/dist/src/core/parser-fallback.js +43 -0
- package/dist/src/core/patch-apply-fuzz.d.ts +29 -0
- package/dist/src/core/patch-apply-fuzz.js +70 -0
- package/dist/src/core/patch-apply.d.ts +46 -0
- package/dist/src/core/patch-apply.js +235 -0
- package/dist/src/core/patch-export.d.ts +99 -0
- package/dist/src/core/patch-export.js +314 -0
- package/dist/src/core/patch-files.d.ts +11 -0
- package/dist/src/core/patch-files.js +51 -0
- package/dist/src/core/patch-lint.d.ts +72 -0
- package/dist/src/core/patch-lint.js +403 -0
- package/dist/src/core/patch-lock.d.ts +8 -0
- package/dist/src/core/patch-lock.js +29 -0
- package/dist/src/core/patch-manifest-consistency.d.ts +24 -0
- package/dist/src/core/patch-manifest-consistency.js +135 -0
- package/dist/src/core/patch-manifest-io.d.ts +36 -0
- package/dist/src/core/patch-manifest-io.js +77 -0
- package/dist/src/core/patch-manifest-query.d.ts +48 -0
- package/dist/src/core/patch-manifest-query.js +124 -0
- package/dist/src/core/patch-manifest-validate.d.ts +22 -0
- package/dist/src/core/patch-manifest-validate.js +72 -0
- package/dist/src/core/patch-manifest.d.ts +11 -0
- package/dist/src/core/patch-manifest.js +12 -0
- package/dist/src/core/patch-parse.d.ts +43 -0
- package/dist/src/core/patch-parse.js +143 -0
- package/dist/src/core/patch-transform.d.ts +21 -0
- package/dist/src/core/patch-transform.js +138 -0
- package/dist/src/core/rebase-session.d.ts +47 -0
- package/dist/src/core/rebase-session.js +65 -0
- package/dist/src/core/register-browser-content.d.ts +11 -0
- package/dist/src/core/register-browser-content.js +116 -0
- package/dist/src/core/register-module.d.ts +11 -0
- package/dist/src/core/register-module.js +76 -0
- package/dist/src/core/register-shared-css.d.ts +11 -0
- package/dist/src/core/register-shared-css.js +117 -0
- package/dist/src/core/register-test-manifest.d.ts +18 -0
- package/dist/src/core/register-test-manifest.js +99 -0
- package/dist/src/core/state-file.d.ts +4 -0
- package/dist/src/core/state-file.js +25 -0
- package/dist/src/core/token-coverage.d.ts +12 -0
- package/dist/src/core/token-coverage.js +74 -0
- package/dist/src/core/token-manager.d.ts +55 -0
- package/dist/src/core/token-manager.js +387 -0
- package/dist/src/core/wire-destroy.d.ts +21 -0
- package/dist/src/core/wire-destroy.js +103 -0
- package/dist/src/core/wire-dom-fragment.d.ts +23 -0
- package/dist/src/core/wire-dom-fragment.js +129 -0
- package/dist/src/core/wire-init.d.ts +23 -0
- package/dist/src/core/wire-init.js +201 -0
- package/dist/src/core/wire-subscript.d.ts +20 -0
- package/dist/src/core/wire-subscript.js +134 -0
- package/dist/src/core/wire-targets.d.ts +7 -0
- package/dist/src/core/wire-targets.js +9 -0
- package/dist/src/core/wire-utils.d.ts +88 -0
- package/dist/src/core/wire-utils.js +279 -0
- package/dist/src/errors/base.d.ts +60 -0
- package/dist/src/errors/base.js +87 -0
- package/dist/src/errors/build.d.ts +52 -0
- package/dist/src/errors/build.js +114 -0
- package/dist/src/errors/codes.d.ts +29 -0
- package/dist/src/errors/codes.js +30 -0
- package/dist/src/errors/config.d.ts +31 -0
- package/dist/src/errors/config.js +61 -0
- package/dist/src/errors/download.d.ts +42 -0
- package/dist/src/errors/download.js +95 -0
- package/dist/src/errors/furnace.d.ts +10 -0
- package/dist/src/errors/furnace.js +22 -0
- package/dist/src/errors/git.d.ts +41 -0
- package/dist/src/errors/git.js +99 -0
- package/dist/src/errors/patch.d.ts +10 -0
- package/dist/src/errors/patch.js +26 -0
- package/dist/src/errors/rebase.d.ts +20 -0
- package/dist/src/errors/rebase.js +30 -0
- package/dist/src/index.d.ts +21 -0
- package/dist/src/index.js +21 -0
- package/dist/src/types/cli.d.ts +14 -0
- package/dist/src/types/cli.js +2 -0
- package/dist/src/types/commands/index.d.ts +6 -0
- package/dist/src/types/commands/index.js +6 -0
- package/dist/src/types/commands/options.d.ts +239 -0
- package/dist/src/types/commands/options.js +6 -0
- package/dist/src/types/commands/patches.d.ts +89 -0
- package/dist/src/types/commands/patches.js +6 -0
- package/dist/src/types/commands/project.d.ts +71 -0
- package/dist/src/types/commands/project.js +6 -0
- package/dist/src/types/config.d.ts +101 -0
- package/dist/src/types/config.js +2 -0
- package/dist/src/types/furnace.d.ts +158 -0
- package/dist/src/types/furnace.js +2 -0
- package/dist/src/types/index.d.ts +6 -0
- package/dist/src/types/index.js +6 -0
- package/dist/src/utils/errors.d.ts +2 -0
- package/dist/src/utils/errors.js +15 -0
- package/dist/src/utils/fs.d.ts +72 -0
- package/dist/src/utils/fs.js +179 -0
- package/dist/src/utils/logger.d.ts +58 -0
- package/dist/src/utils/logger.js +120 -0
- package/dist/src/utils/options.d.ts +8 -0
- package/dist/src/utils/options.js +16 -0
- package/dist/src/utils/package-root.d.ts +10 -0
- package/dist/src/utils/package-root.js +53 -0
- package/dist/src/utils/parse.d.ts +110 -0
- package/dist/src/utils/parse.js +200 -0
- package/dist/src/utils/paths.d.ts +10 -0
- package/dist/src/utils/paths.js +43 -0
- package/dist/src/utils/platform.d.ts +38 -0
- package/dist/src/utils/platform.js +56 -0
- package/dist/src/utils/process.d.ts +80 -0
- package/dist/src/utils/process.js +188 -0
- package/dist/src/utils/regex.d.ts +24 -0
- package/dist/src/utils/regex.js +40 -0
- package/dist/src/utils/validation.d.ts +133 -0
- package/dist/src/utils/validation.js +250 -0
- package/package.json +106 -0
- package/templates/configs/common.mozconfig +24 -0
- package/templates/configs/darwin.mozconfig +10 -0
- package/templates/configs/linux.mozconfig +12 -0
- package/templates/configs/win32.mozconfig +14 -0
- package/templates/licenses/0BSD.md +14 -0
- package/templates/licenses/EUPL-1.2.md +294 -0
- package/templates/licenses/GPL-2.0-or-later.md +339 -0
- package/templates/licenses/MPL-2.0.md +383 -0
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
// SPDX-License-Identifier: EUPL-1.2
|
|
2
|
+
import { readdir } from 'node:fs/promises';
|
|
3
|
+
import { join } from 'node:path';
|
|
4
|
+
import { ensureDir, pathExists, removeDir, removeFile, writeText } from '../utils/fs.js';
|
|
5
|
+
import { getProjectPaths, loadConfig } from './config.js';
|
|
6
|
+
import { loadFurnaceConfig } from './furnace-config.js';
|
|
7
|
+
import { DEFAULT_LICENSE, getLicenseHeader } from './license-headers.js';
|
|
8
|
+
/** MPL-2.0 license header used in generated story files for Firefox-derived components */
|
|
9
|
+
const MPL_LICENSE_HEADER = getLicenseHeader('MPL-2.0', 'js');
|
|
10
|
+
/** Title category for each component type */
|
|
11
|
+
const TITLE_CATEGORIES = {
|
|
12
|
+
stock: 'Design System/Stock',
|
|
13
|
+
override: 'Design System/Overrides',
|
|
14
|
+
custom: 'Design System/Custom',
|
|
15
|
+
};
|
|
16
|
+
/**
|
|
17
|
+
* Derives a human-readable display name from a component tag name.
|
|
18
|
+
*
|
|
19
|
+
* Removes the `moz-` prefix, splits on hyphens, capitalises each word,
|
|
20
|
+
* and joins with spaces.
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* generateDisplayName("moz-button") // "Button"
|
|
24
|
+
* generateDisplayName("moz-message-bar") // "Message Bar"
|
|
25
|
+
*
|
|
26
|
+
* @param tagName - Component tag name (e.g. "moz-button")
|
|
27
|
+
* @returns Display name (e.g. "Button")
|
|
28
|
+
*/
|
|
29
|
+
function generateDisplayName(tagName) {
|
|
30
|
+
const withoutPrefix = tagName.replace(/^moz-/, '');
|
|
31
|
+
return withoutPrefix
|
|
32
|
+
.split('-')
|
|
33
|
+
.map((word) => word.charAt(0).toUpperCase() + word.slice(1))
|
|
34
|
+
.join(' ');
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Generates the full content of a Storybook `.stories.mjs` file for a
|
|
38
|
+
* Furnace component.
|
|
39
|
+
*
|
|
40
|
+
* @param tagName - Component tag name (e.g. "moz-button")
|
|
41
|
+
* @param displayName - Human-readable name (e.g. "Button")
|
|
42
|
+
* @param type - Component classification (stock, override, custom)
|
|
43
|
+
* @returns Complete story file content
|
|
44
|
+
*/
|
|
45
|
+
export function generateStoryContent(tagName, displayName, type, licenseHeader = MPL_LICENSE_HEADER, modulePath) {
|
|
46
|
+
const category = TITLE_CATEGORIES[type];
|
|
47
|
+
// Derive chrome:// URI from modulePath if provided, otherwise default to elements/ path
|
|
48
|
+
let chromeUri;
|
|
49
|
+
if (modulePath) {
|
|
50
|
+
if (modulePath.startsWith('toolkit/content/')) {
|
|
51
|
+
chromeUri = modulePath.replace(/^toolkit\/content\//, 'chrome://global/content/');
|
|
52
|
+
}
|
|
53
|
+
else if (modulePath.startsWith('browser/base/content/')) {
|
|
54
|
+
chromeUri = modulePath.replace(/^browser\/base\/content\//, 'chrome://browser/content/');
|
|
55
|
+
}
|
|
56
|
+
else {
|
|
57
|
+
chromeUri = `chrome://global/content/${modulePath}`;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
else {
|
|
61
|
+
chromeUri = `chrome://global/content/elements/${tagName}.mjs`;
|
|
62
|
+
}
|
|
63
|
+
return `${licenseHeader}
|
|
64
|
+
|
|
65
|
+
import { html } from "chrome://global/content/vendor/lit.all.mjs";
|
|
66
|
+
// The component import triggers customElements.define
|
|
67
|
+
import "${chromeUri}";
|
|
68
|
+
|
|
69
|
+
export default {
|
|
70
|
+
title: "${category}/${displayName}",
|
|
71
|
+
component: "${tagName}",
|
|
72
|
+
argTypes: {},
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
const Template = (args) => html\`<${tagName}></${tagName}>\`;
|
|
76
|
+
|
|
77
|
+
export const Default = Template.bind({});
|
|
78
|
+
Default.args = {};
|
|
79
|
+
`;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Returns the path to the Storybook stories directory in the engine.
|
|
83
|
+
*
|
|
84
|
+
* @param engineDir - Path to the Firefox engine source root
|
|
85
|
+
* @returns Absolute path to `browser/components/storybook/stories/`
|
|
86
|
+
*/
|
|
87
|
+
export function getStoriesDir(engineDir) {
|
|
88
|
+
return join(engineDir, 'browser', 'components', 'storybook', 'stories');
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Synchronises Storybook story files for all Furnace-managed components.
|
|
92
|
+
*
|
|
93
|
+
* - Stock components: story created only if not already present.
|
|
94
|
+
* - Override components: story always regenerated.
|
|
95
|
+
* - Custom components: story always regenerated.
|
|
96
|
+
* - Stale story files (for components no longer in furnace.json) are removed.
|
|
97
|
+
*
|
|
98
|
+
* @param root - Root directory of the project
|
|
99
|
+
* @returns Summary of created, updated, and removed story files
|
|
100
|
+
*/
|
|
101
|
+
export async function syncStories(root) {
|
|
102
|
+
const config = await loadFurnaceConfig(root);
|
|
103
|
+
const forgeConfig = await loadConfig(root);
|
|
104
|
+
const license = forgeConfig.license ?? DEFAULT_LICENSE;
|
|
105
|
+
const customLicenseHeader = getLicenseHeader(license, 'js');
|
|
106
|
+
const { engine: engineDir } = getProjectPaths(root);
|
|
107
|
+
const storiesDir = join(getStoriesDir(engineDir), 'furnace');
|
|
108
|
+
await ensureDir(storiesDir);
|
|
109
|
+
const result = { created: [], updated: [], removed: [] };
|
|
110
|
+
const expectedFiles = new Set();
|
|
111
|
+
// --- Stock components (only create if missing) ---
|
|
112
|
+
for (const tagName of config.stock) {
|
|
113
|
+
const filename = `${tagName}.stories.mjs`;
|
|
114
|
+
expectedFiles.add(filename);
|
|
115
|
+
const filePath = join(storiesDir, filename);
|
|
116
|
+
if (await pathExists(filePath)) {
|
|
117
|
+
continue;
|
|
118
|
+
}
|
|
119
|
+
const displayName = generateDisplayName(tagName);
|
|
120
|
+
const content = generateStoryContent(tagName, displayName, 'stock');
|
|
121
|
+
await writeText(filePath, content);
|
|
122
|
+
result.created.push(filename);
|
|
123
|
+
}
|
|
124
|
+
// --- Override components (always regenerate) ---
|
|
125
|
+
for (const name of Object.keys(config.overrides)) {
|
|
126
|
+
const filename = `${name}.stories.mjs`;
|
|
127
|
+
expectedFiles.add(filename);
|
|
128
|
+
const filePath = join(storiesDir, filename);
|
|
129
|
+
const existed = await pathExists(filePath);
|
|
130
|
+
const displayName = generateDisplayName(name);
|
|
131
|
+
const content = generateStoryContent(name, displayName, 'override', customLicenseHeader);
|
|
132
|
+
await writeText(filePath, content);
|
|
133
|
+
if (existed) {
|
|
134
|
+
result.updated.push(filename);
|
|
135
|
+
}
|
|
136
|
+
else {
|
|
137
|
+
result.created.push(filename);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
// --- Custom components (always regenerate, use project license) ---
|
|
141
|
+
for (const name of Object.keys(config.custom)) {
|
|
142
|
+
const filename = `${name}.stories.mjs`;
|
|
143
|
+
expectedFiles.add(filename);
|
|
144
|
+
const filePath = join(storiesDir, filename);
|
|
145
|
+
const existed = await pathExists(filePath);
|
|
146
|
+
const displayName = generateDisplayName(name);
|
|
147
|
+
const content = generateStoryContent(name, displayName, 'custom', customLicenseHeader);
|
|
148
|
+
await writeText(filePath, content);
|
|
149
|
+
if (existed) {
|
|
150
|
+
result.updated.push(filename);
|
|
151
|
+
}
|
|
152
|
+
else {
|
|
153
|
+
result.created.push(filename);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
// --- Remove stale story files ---
|
|
157
|
+
const entries = await readdir(storiesDir, { withFileTypes: true });
|
|
158
|
+
for (const entry of entries) {
|
|
159
|
+
if (!entry.isFile() || !entry.name.endsWith('.stories.mjs')) {
|
|
160
|
+
continue;
|
|
161
|
+
}
|
|
162
|
+
if (!expectedFiles.has(entry.name)) {
|
|
163
|
+
await removeFile(join(storiesDir, entry.name));
|
|
164
|
+
result.removed.push(entry.name);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
return result;
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Removes the entire `stories/furnace/` directory from the engine.
|
|
171
|
+
*
|
|
172
|
+
* @param engineDir - Path to the Firefox engine source root
|
|
173
|
+
* @returns Number of files that were removed
|
|
174
|
+
*/
|
|
175
|
+
export async function cleanStories(engineDir) {
|
|
176
|
+
const storiesDir = join(getStoriesDir(engineDir), 'furnace');
|
|
177
|
+
if (!(await pathExists(storiesDir))) {
|
|
178
|
+
return 0;
|
|
179
|
+
}
|
|
180
|
+
const entries = await readdir(storiesDir, { withFileTypes: true });
|
|
181
|
+
const count = entries.filter((e) => e.isFile()).length;
|
|
182
|
+
await removeDir(storiesDir);
|
|
183
|
+
return count;
|
|
184
|
+
}
|
|
185
|
+
//# sourceMappingURL=furnace-stories.js.map
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { ValidationIssue } from '../types/furnace.js';
|
|
2
|
+
/**
|
|
3
|
+
* Validates accessibility patterns in a component's .mjs file.
|
|
4
|
+
* Checks for ARIA roles, keyboard handlers, l10n, and focus delegation.
|
|
5
|
+
*/
|
|
6
|
+
export declare function validateAccessibility(componentDir: string, tagName: string): Promise<ValidationIssue[]>;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
// SPDX-License-Identifier: EUPL-1.2
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
import { pathExists, readText } from '../utils/fs.js';
|
|
4
|
+
import { containsHardcodedTemplateText, createIssue, hasAriaRole, hasDelegatesFocusEnabled, hasTemplateClickHandler, hasTemplateKeyboardHandler, } from './furnace-validate-helpers.js';
|
|
5
|
+
/**
|
|
6
|
+
* Validates accessibility patterns in a component's .mjs file.
|
|
7
|
+
* Checks for ARIA roles, keyboard handlers, l10n, and focus delegation.
|
|
8
|
+
*/
|
|
9
|
+
export async function validateAccessibility(componentDir, tagName) {
|
|
10
|
+
const mjsPath = join(componentDir, `${tagName}.mjs`);
|
|
11
|
+
if (!(await pathExists(mjsPath)))
|
|
12
|
+
return [];
|
|
13
|
+
const content = await readText(mjsPath);
|
|
14
|
+
const issues = [];
|
|
15
|
+
if (!hasAriaRole(content)) {
|
|
16
|
+
issues.push(createIssue(tagName, 'warning', 'no-aria-role', 'No ARIA role attribute found. Consider adding role= for screen reader support.'));
|
|
17
|
+
}
|
|
18
|
+
const hasClick = hasTemplateClickHandler(content);
|
|
19
|
+
const hasKeyboardHandler = hasTemplateKeyboardHandler(content);
|
|
20
|
+
if (hasClick && !hasKeyboardHandler) {
|
|
21
|
+
issues.push(createIssue(tagName, 'warning', 'no-keyboard-handler', 'Interactive element has @click but no keyboard event handler (@keydown/@keypress/@keyup).'));
|
|
22
|
+
}
|
|
23
|
+
if (containsHardcodedTemplateText(content)) {
|
|
24
|
+
issues.push(createIssue(tagName, 'warning', 'hardcoded-text', 'Possible hardcoded string found. Use data-l10n-id for localization.'));
|
|
25
|
+
}
|
|
26
|
+
const isInteractive = hasClick || hasKeyboardHandler;
|
|
27
|
+
if (isInteractive && !hasDelegatesFocusEnabled(content)) {
|
|
28
|
+
issues.push(createIssue(tagName, 'warning', 'no-delegates-focus', 'Interactive component without delegatesFocus in shadowRootOptions. Focus may not delegate to inner elements.'));
|
|
29
|
+
}
|
|
30
|
+
return issues;
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=furnace-validate-accessibility.js.map
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export { validateAccessibility } from './furnace-validate-accessibility.js';
|
|
2
|
+
export { validateCompatibility } from './furnace-validate-compatibility.js';
|
|
3
|
+
export { checkRegistrationConsistency, validateJarMnEntries, validateRegistrationPatterns, validateTokenLink, } from './furnace-validate-registration.js';
|
|
4
|
+
export { validateStructure } from './furnace-validate-structure.js';
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
// SPDX-License-Identifier: EUPL-1.2
|
|
2
|
+
// Re-export all validation checks from their focused modules.
|
|
3
|
+
export { validateAccessibility } from './furnace-validate-accessibility.js';
|
|
4
|
+
export { validateCompatibility } from './furnace-validate-compatibility.js';
|
|
5
|
+
export { checkRegistrationConsistency, validateJarMnEntries, validateRegistrationPatterns, validateTokenLink, } from './furnace-validate-registration.js';
|
|
6
|
+
export { validateStructure } from './furnace-validate-structure.js';
|
|
7
|
+
//# sourceMappingURL=furnace-validate-checks.js.map
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { ComponentType, FurnaceConfig, ValidationIssue } from '../types/furnace.js';
|
|
2
|
+
/**
|
|
3
|
+
* Validates compatibility patterns in a component's .mjs and .css files.
|
|
4
|
+
* Checks imports, class hierarchy, registration, and design tokens.
|
|
5
|
+
*/
|
|
6
|
+
export declare function validateCompatibility(componentDir: string, tagName: string, type: ComponentType, config?: FurnaceConfig, root?: string): Promise<ValidationIssue[]>;
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
// SPDX-License-Identifier: EUPL-1.2
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
import { pathExists, readText } from '../utils/fs.js';
|
|
4
|
+
import { hasRawCssColors } from '../utils/regex.js';
|
|
5
|
+
import { classExtendsMozLitElement, collectCssVariableReferences, createIssue, getTokenPrefixContext, hasCustomElementDefineCall, hasRelativeModuleImport, stripCssBlockComments, } from './furnace-validate-helpers.js';
|
|
6
|
+
async function validateMjsCompatibility(mjsPath, tagName) {
|
|
7
|
+
if (!(await pathExists(mjsPath)))
|
|
8
|
+
return [];
|
|
9
|
+
const mjsContent = await readText(mjsPath);
|
|
10
|
+
const issues = [];
|
|
11
|
+
if (hasRelativeModuleImport(mjsContent)) {
|
|
12
|
+
issues.push(createIssue(tagName, 'error', 'relative-import', 'Imports must use chrome:// URIs, not relative paths.'));
|
|
13
|
+
}
|
|
14
|
+
if (!hasCustomElementDefineCall(mjsContent)) {
|
|
15
|
+
issues.push(createIssue(tagName, 'error', 'no-custom-element-define', 'Missing customElements.define() call. Component will not be registered.'));
|
|
16
|
+
}
|
|
17
|
+
if (!classExtendsMozLitElement(mjsContent)) {
|
|
18
|
+
issues.push(createIssue(tagName, 'error', 'not-moz-lit-element', 'Component class must extend MozLitElement.'));
|
|
19
|
+
}
|
|
20
|
+
return issues;
|
|
21
|
+
}
|
|
22
|
+
async function validateCssCompatibility(cssPath, tagName, type, config, root) {
|
|
23
|
+
if (!(await pathExists(cssPath)))
|
|
24
|
+
return [];
|
|
25
|
+
const rawCss = await readText(cssPath);
|
|
26
|
+
const cssContent = stripCssBlockComments(rawCss);
|
|
27
|
+
const issues = [];
|
|
28
|
+
if (hasRawCssColors(cssContent)) {
|
|
29
|
+
issues.push(createIssue(tagName, 'error', 'raw-color-value', 'Raw color value found. Use CSS custom properties (var(--...)) for design token consistency.'));
|
|
30
|
+
}
|
|
31
|
+
if (config?.tokenPrefix) {
|
|
32
|
+
const { allowlist, inheritedOverrideVars } = await getTokenPrefixContext(tagName, type, config, root);
|
|
33
|
+
for (const prop of collectCssVariableReferences(cssContent)) {
|
|
34
|
+
if (!prop.startsWith(config.tokenPrefix) &&
|
|
35
|
+
!allowlist.has(prop) &&
|
|
36
|
+
!inheritedOverrideVars.has(prop)) {
|
|
37
|
+
issues.push(createIssue(tagName, 'error', 'token-prefix-violation', `CSS references var(${prop}) which does not match the required token prefix "${config.tokenPrefix}". Use a design token or add to tokenAllowlist.`));
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
return issues;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Validates compatibility patterns in a component's .mjs and .css files.
|
|
45
|
+
* Checks imports, class hierarchy, registration, and design tokens.
|
|
46
|
+
*/
|
|
47
|
+
export async function validateCompatibility(componentDir, tagName, type, config, root) {
|
|
48
|
+
const issues = [];
|
|
49
|
+
const mjsPath = join(componentDir, `${tagName}.mjs`);
|
|
50
|
+
const cssPath = join(componentDir, `${tagName}.css`);
|
|
51
|
+
const mjsIssues = await validateMjsCompatibility(mjsPath, tagName);
|
|
52
|
+
issues.push(...mjsIssues);
|
|
53
|
+
const cssIssues = await validateCssCompatibility(cssPath, tagName, type, config, root);
|
|
54
|
+
issues.push(...cssIssues);
|
|
55
|
+
return issues;
|
|
56
|
+
}
|
|
57
|
+
//# sourceMappingURL=furnace-validate-compatibility.js.map
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { ComponentType, FurnaceConfig, ValidationIssue } from '../types/furnace.js';
|
|
2
|
+
/** Creates a normalized validation issue object. */
|
|
3
|
+
export declare function createIssue(component: string, severity: ValidationIssue['severity'], check: ValidationIssue['check'], message: string): ValidationIssue;
|
|
4
|
+
/** Detects whether template or script content assigns an ARIA role. */
|
|
5
|
+
export declare function hasAriaRole(content: string): boolean;
|
|
6
|
+
/** Detects Lit-style template click handlers. */
|
|
7
|
+
export declare function hasTemplateClickHandler(content: string): boolean;
|
|
8
|
+
/** Detects Lit-style template keyboard handlers. */
|
|
9
|
+
export declare function hasTemplateKeyboardHandler(content: string): boolean;
|
|
10
|
+
/** Detects hardcoded user-visible template text that should usually be localized. */
|
|
11
|
+
export declare function containsHardcodedTemplateText(content: string): boolean;
|
|
12
|
+
/** Detects whether a component opts into shadow-root focus delegation. */
|
|
13
|
+
export declare function hasDelegatesFocusEnabled(content: string): boolean;
|
|
14
|
+
/** Removes CSS block comments before running simple string-based checks. */
|
|
15
|
+
export declare function stripCssBlockComments(content: string): string;
|
|
16
|
+
/** Detects relative ES module imports in a component module file. */
|
|
17
|
+
export declare function hasRelativeModuleImport(mjsContent: string): boolean;
|
|
18
|
+
/** Detects whether a module defines a custom element at runtime. */
|
|
19
|
+
export declare function hasCustomElementDefineCall(mjsContent: string): boolean;
|
|
20
|
+
/** Checks whether a declared component class extends MozLitElement. */
|
|
21
|
+
export declare function classExtendsMozLitElement(mjsContent: string): boolean;
|
|
22
|
+
/** Collects CSS custom property references used via var(--token-name). */
|
|
23
|
+
export declare function collectCssVariableReferences(cssContent: string): string[];
|
|
24
|
+
/** Builds token-validation context from the config allowlist and inherited override CSS. */
|
|
25
|
+
export declare function getTokenPrefixContext(tagName: string, type: ComponentType, config: FurnaceConfig, root: string | undefined): Promise<{
|
|
26
|
+
allowlist: Set<string>;
|
|
27
|
+
inheritedOverrideVars: Set<string>;
|
|
28
|
+
}>;
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
// SPDX-License-Identifier: EUPL-1.2
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
import { pathExists, readText } from '../utils/fs.js';
|
|
4
|
+
import { getProjectPaths } from './config.js';
|
|
5
|
+
/** Creates a normalized validation issue object. */
|
|
6
|
+
export function createIssue(component, severity, check, message) {
|
|
7
|
+
return { component, severity, check, message };
|
|
8
|
+
}
|
|
9
|
+
/** Detects whether template or script content assigns an ARIA role. */
|
|
10
|
+
export function hasAriaRole(content) {
|
|
11
|
+
return (/role\s*=\s*["']/.test(content) ||
|
|
12
|
+
/\.role\s*=/.test(content) ||
|
|
13
|
+
/setAttribute\(\s*["']role["']/.test(content));
|
|
14
|
+
}
|
|
15
|
+
/** Detects Lit-style template click handlers. */
|
|
16
|
+
export function hasTemplateClickHandler(content) {
|
|
17
|
+
return /@click\s*=\s*\$\{/.test(content);
|
|
18
|
+
}
|
|
19
|
+
/** Detects Lit-style template keyboard handlers. */
|
|
20
|
+
export function hasTemplateKeyboardHandler(content) {
|
|
21
|
+
return /@key(down|press|up)\s*=\s*\$\{/.test(content);
|
|
22
|
+
}
|
|
23
|
+
function isSymbolOnlyText(text) {
|
|
24
|
+
return Array.from(text).every((character) => {
|
|
25
|
+
const code = character.codePointAt(0) ?? 0;
|
|
26
|
+
return code > 0xff || '+-*=<>|/\\^~@#&!?%'.includes(character);
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
function isWithinLocalizedElement(content, matchIndex) {
|
|
30
|
+
const contentBefore = content.slice(0, matchIndex + 1);
|
|
31
|
+
const lastTagOpen = contentBefore.lastIndexOf('<');
|
|
32
|
+
if (lastTagOpen === -1) {
|
|
33
|
+
return false;
|
|
34
|
+
}
|
|
35
|
+
const tagContent = contentBefore.slice(lastTagOpen, matchIndex + 1);
|
|
36
|
+
return /data-l10n-id\s*=/.test(tagContent);
|
|
37
|
+
}
|
|
38
|
+
/** Detects hardcoded user-visible template text that should usually be localized. */
|
|
39
|
+
export function containsHardcodedTemplateText(content) {
|
|
40
|
+
if (/furnace-ignore:\s*hardcoded-text/.test(content)) {
|
|
41
|
+
return false;
|
|
42
|
+
}
|
|
43
|
+
const textPattern = />([^<$\s][^<$]*)</g;
|
|
44
|
+
let textMatch;
|
|
45
|
+
while ((textMatch = textPattern.exec(content)) !== null) {
|
|
46
|
+
const text = textMatch[1]?.trim() ?? '';
|
|
47
|
+
if (/\$\{/.test(text)) {
|
|
48
|
+
continue;
|
|
49
|
+
}
|
|
50
|
+
if (Array.from(text).length <= 1) {
|
|
51
|
+
continue;
|
|
52
|
+
}
|
|
53
|
+
if (isSymbolOnlyText(text)) {
|
|
54
|
+
continue;
|
|
55
|
+
}
|
|
56
|
+
if (isWithinLocalizedElement(content, textMatch.index)) {
|
|
57
|
+
continue;
|
|
58
|
+
}
|
|
59
|
+
return true;
|
|
60
|
+
}
|
|
61
|
+
return false;
|
|
62
|
+
}
|
|
63
|
+
/** Detects whether a component opts into shadow-root focus delegation. */
|
|
64
|
+
export function hasDelegatesFocusEnabled(content) {
|
|
65
|
+
return /shadowRootOptions[\s\S]*?delegatesFocus\s*:\s*true/.test(content);
|
|
66
|
+
}
|
|
67
|
+
/** Removes CSS block comments before running simple string-based checks. */
|
|
68
|
+
export function stripCssBlockComments(content) {
|
|
69
|
+
return content.replace(/\/\*[\s\S]*?\*\//g, '');
|
|
70
|
+
}
|
|
71
|
+
/** Detects relative ES module imports in a component module file. */
|
|
72
|
+
export function hasRelativeModuleImport(mjsContent) {
|
|
73
|
+
return (/^\s*import\s.*from\s+["']\.\.?\//m.test(mjsContent) ||
|
|
74
|
+
/^\s*import\s+["']\.\.?\//m.test(mjsContent));
|
|
75
|
+
}
|
|
76
|
+
/** Detects whether a module defines a custom element at runtime. */
|
|
77
|
+
export function hasCustomElementDefineCall(mjsContent) {
|
|
78
|
+
return /customElements\.define\s*\(/.test(mjsContent);
|
|
79
|
+
}
|
|
80
|
+
/** Checks whether a declared component class extends MozLitElement. */
|
|
81
|
+
export function classExtendsMozLitElement(mjsContent) {
|
|
82
|
+
const hasClassDeclaration = /class\s+\w+\s+extends\s+/.test(mjsContent);
|
|
83
|
+
if (!hasClassDeclaration) {
|
|
84
|
+
return true;
|
|
85
|
+
}
|
|
86
|
+
return /class\s+\w+\s+extends\s+MozLitElement\b/.test(mjsContent);
|
|
87
|
+
}
|
|
88
|
+
/** Collects CSS custom property references used via var(--token-name). */
|
|
89
|
+
export function collectCssVariableReferences(cssContent) {
|
|
90
|
+
const referencedVariables = [];
|
|
91
|
+
const variablePattern = /var\(\s*(--[\w-]+)/g;
|
|
92
|
+
let match;
|
|
93
|
+
while ((match = variablePattern.exec(cssContent)) !== null) {
|
|
94
|
+
const variableName = match[1];
|
|
95
|
+
if (variableName) {
|
|
96
|
+
referencedVariables.push(variableName);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
return referencedVariables;
|
|
100
|
+
}
|
|
101
|
+
async function collectInheritedOverrideVariables(tagName, config, root) {
|
|
102
|
+
const inheritedVariables = new Set();
|
|
103
|
+
const basePath = config.overrides[tagName]?.basePath;
|
|
104
|
+
if (!basePath) {
|
|
105
|
+
return inheritedVariables;
|
|
106
|
+
}
|
|
107
|
+
const { engine: engineDir } = getProjectPaths(root);
|
|
108
|
+
const originalCssPath = join(engineDir, basePath, `${tagName}.css`);
|
|
109
|
+
if (!(await pathExists(originalCssPath))) {
|
|
110
|
+
return inheritedVariables;
|
|
111
|
+
}
|
|
112
|
+
const originalCssContent = stripCssBlockComments(await readText(originalCssPath));
|
|
113
|
+
for (const variableName of collectCssVariableReferences(originalCssContent)) {
|
|
114
|
+
inheritedVariables.add(variableName);
|
|
115
|
+
}
|
|
116
|
+
return inheritedVariables;
|
|
117
|
+
}
|
|
118
|
+
/** Builds token-validation context from the config allowlist and inherited override CSS. */
|
|
119
|
+
export async function getTokenPrefixContext(tagName, type, config, root) {
|
|
120
|
+
const allowlist = new Set(config.tokenAllowlist ?? []);
|
|
121
|
+
if (type !== 'override' || !root) {
|
|
122
|
+
return { allowlist, inheritedOverrideVars: new Set() };
|
|
123
|
+
}
|
|
124
|
+
return {
|
|
125
|
+
allowlist,
|
|
126
|
+
inheritedOverrideVars: await collectInheritedOverrideVariables(tagName, config, root),
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
//# sourceMappingURL=furnace-validate-helpers.js.map
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import type { CustomComponentConfig, FurnaceConfig, RegistrationStatus, ValidationIssue } from '../types/furnace.js';
|
|
2
|
+
/**
|
|
3
|
+
* Validates that all Furnace-managed .mjs components are registered in the
|
|
4
|
+
* DOMContentLoaded/importESModule block (Pattern B), not the loadSubScript
|
|
5
|
+
* block (Pattern A).
|
|
6
|
+
*
|
|
7
|
+
* @param root - Project root directory
|
|
8
|
+
* @param config - Furnace configuration
|
|
9
|
+
* @returns Array of validation issues for mis-placed registrations
|
|
10
|
+
*/
|
|
11
|
+
export declare function validateRegistrationPatterns(root: string, config: FurnaceConfig): Promise<ValidationIssue[]>;
|
|
12
|
+
/**
|
|
13
|
+
* Checks registration consistency for a single custom component.
|
|
14
|
+
*
|
|
15
|
+
* Compares source files, engine target files, jar.mn entries, and
|
|
16
|
+
* customElements.js registration for a given component.
|
|
17
|
+
*
|
|
18
|
+
* @param root - Project root directory
|
|
19
|
+
* @param name - Component tag name
|
|
20
|
+
* @param config - Custom component configuration
|
|
21
|
+
* @returns Registration status with per-check booleans and drift info
|
|
22
|
+
*/
|
|
23
|
+
export declare function checkRegistrationConsistency(root: string, name: string, config: CustomComponentConfig): Promise<RegistrationStatus>;
|
|
24
|
+
/**
|
|
25
|
+
* Validates that each custom component with `register: true` has its .mjs and
|
|
26
|
+
* .css entries in jar.mn.
|
|
27
|
+
*
|
|
28
|
+
* @param root - Project root directory
|
|
29
|
+
* @param config - Furnace configuration
|
|
30
|
+
* @returns Array of validation issues for missing jar.mn entries
|
|
31
|
+
*/
|
|
32
|
+
export declare function validateJarMnEntries(root: string, config: FurnaceConfig): Promise<ValidationIssue[]>;
|
|
33
|
+
/**
|
|
34
|
+
* Validates that components using design tokens have the tokens CSS
|
|
35
|
+
* linked in browser.xhtml. Without the link, tokens silently resolve to nothing.
|
|
36
|
+
*/
|
|
37
|
+
export declare function validateTokenLink(componentDir: string, tagName: string, root: string, tokenPrefix?: string): Promise<ValidationIssue[]>;
|