@brandlab-digital/conformance 1.0.0-rc.37 → 1.0.0-rc.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.d.ts +3 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +95 -47
- package/dist/cli.js.map +1 -1
- package/dist/legacy-architecture-contracts.d.ts +31 -0
- package/dist/legacy-architecture-contracts.d.ts.map +1 -0
- package/dist/legacy-architecture-contracts.js +49 -0
- package/dist/legacy-architecture-contracts.js.map +1 -0
- package/dist/locations.d.ts +63 -0
- package/dist/locations.d.ts.map +1 -0
- package/dist/locations.js +105 -0
- package/dist/locations.js.map +1 -0
- package/dist/project-config-v2-contract.d.ts +32 -0
- package/dist/project-config-v2-contract.d.ts.map +1 -0
- package/dist/project-config-v2-contract.js +926 -0
- package/dist/project-config-v2-contract.js.map +1 -0
- package/dist/project-config-v3.d.ts +43 -0
- package/dist/project-config-v3.d.ts.map +1 -0
- package/dist/project-config-v3.js +2876 -0
- package/dist/project-config-v3.js.map +1 -0
- package/dist/project-config.d.ts +3 -0
- package/dist/project-config.d.ts.map +1 -0
- package/dist/project-config.js +3 -0
- package/dist/project-config.js.map +1 -0
- package/dist/project.d.ts +24 -19
- package/dist/project.d.ts.map +1 -1
- package/dist/project.js +1070 -444
- package/dist/project.js.map +1 -1
- package/dist/release-catalog.d.ts +4 -0
- package/dist/release-catalog.d.ts.map +1 -0
- package/dist/release-catalog.js +506 -0
- package/dist/release-catalog.js.map +1 -0
- package/dist/release-contract-compatibility.d.ts +76 -0
- package/dist/release-contract-compatibility.d.ts.map +1 -0
- package/dist/release-contract-compatibility.js +91 -0
- package/dist/release-contract-compatibility.js.map +1 -0
- package/dist/release-manifest.d.ts +82 -29
- package/dist/release-manifest.d.ts.map +1 -1
- package/dist/release-manifest.js +348 -141
- package/dist/release-manifest.js.map +1 -1
- package/dist/schema-hygiene.d.ts +26 -0
- package/dist/schema-hygiene.d.ts.map +1 -0
- package/dist/schema-hygiene.js +28 -0
- package/dist/schema-hygiene.js.map +1 -0
- package/dist/source-safety-contracts.d.ts +20 -0
- package/dist/source-safety-contracts.d.ts.map +1 -0
- package/dist/source-safety-contracts.js +60 -0
- package/dist/source-safety-contracts.js.map +1 -0
- package/dist/vitest.d.ts +110 -0
- package/dist/vitest.d.ts.map +1 -0
- package/dist/vitest.js +2678 -0
- package/dist/vitest.js.map +1 -0
- package/package.json +22 -11
- package/dist/current-release.d.ts +0 -3
- package/dist/current-release.d.ts.map +0 -1
- package/dist/current-release.js +0 -54
- package/dist/current-release.js.map +0 -1
- package/dist/rendered-content.d.ts +0 -36
- package/dist/rendered-content.d.ts.map +0 -1
- package/dist/rendered-content.js +0 -146
- package/dist/rendered-content.js.map +0 -1
- package/dist/verification-policy.d.ts +0 -162
- package/dist/verification-policy.d.ts.map +0 -1
- package/dist/verification-policy.js +0 -309
- package/dist/verification-policy.js.map +0 -1
package/dist/cli.d.ts
CHANGED
|
@@ -3,6 +3,9 @@ import { type BrandlabConformanceMode } from "./project.js";
|
|
|
3
3
|
interface CliOptions {
|
|
4
4
|
root: string;
|
|
5
5
|
installedRelease?: string | null;
|
|
6
|
+
targetRelease?: string | null;
|
|
7
|
+
supportPolicyPath: string | null;
|
|
8
|
+
releaseManifestPaths: string[];
|
|
6
9
|
mode: BrandlabConformanceMode;
|
|
7
10
|
json: boolean;
|
|
8
11
|
help: boolean;
|
|
@@ -13,6 +16,5 @@ interface CliIo {
|
|
|
13
16
|
}
|
|
14
17
|
export declare function parseBrandlabConformanceArgs(argv: readonly string[]): CliOptions;
|
|
15
18
|
export declare function runBrandlabConformanceCli(argv: readonly string[], io?: CliIo): number;
|
|
16
|
-
export declare function isBrandlabConformanceCliEntrypoint(moduleUrl: string, argvPath: string | undefined): boolean;
|
|
17
19
|
export {};
|
|
18
20
|
//# sourceMappingURL=cli.d.ts.map
|
package/dist/cli.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AAIA,OAAO,EAGL,KAAK,uBAAuB,EAE7B,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AAIA,OAAO,EAGL,KAAK,uBAAuB,EAE7B,MAAM,cAAc,CAAC;AAOtB,UAAU,UAAU;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,gBAAgB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,oBAAoB,EAAE,MAAM,EAAE,CAAC;IAC/B,IAAI,EAAE,uBAAuB,CAAC;IAC9B,IAAI,EAAE,OAAO,CAAC;IACd,IAAI,EAAE,OAAO,CAAC;CACf;AAED,UAAU,KAAK;IACb,MAAM,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAChC,MAAM,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;CACjC;AAeD,wBAAgB,4BAA4B,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG,UAAU,CAgDhF;AAED,wBAAgB,yBAAyB,CACvC,IAAI,EAAE,SAAS,MAAM,EAAE,EACvB,EAAE,GAAE,KAGH,GACA,MAAM,CAqCR"}
|
package/dist/cli.js
CHANGED
|
@@ -1,47 +1,58 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import {
|
|
3
|
-
import { resolve } from "node:path";
|
|
4
|
-
import {
|
|
2
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
3
|
+
import { dirname, isAbsolute, resolve } from "node:path";
|
|
4
|
+
import { pathToFileURL } from "node:url";
|
|
5
5
|
import { evaluateBrandlabProject, shouldFailBrandlabConformance, } from "./project.js";
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
Runs the current objective verification checks for one project.
|
|
6
|
+
import { compareBrandlabSemver, } from "./release-manifest.js";
|
|
7
|
+
const HELP = `Brandlab version-aware conformance
|
|
9
8
|
|
|
10
9
|
Usage:
|
|
11
|
-
brandlab-
|
|
10
|
+
brandlab-conformance --support-policy <path> [--root <path>]
|
|
12
11
|
[--installed-release <version|unadopted>]
|
|
13
|
-
[--
|
|
12
|
+
[--release-manifest <path>]...
|
|
13
|
+
[--target-release <version|none>] [--mode <local|ci|preflight>] [--json]
|
|
14
14
|
|
|
15
15
|
Exit status:
|
|
16
|
-
local/ci fail only for
|
|
17
|
-
preflight
|
|
18
|
-
|
|
19
|
-
Static verification reports tests, builds, browsers and deployments as not run
|
|
20
|
-
until real evidence is supplied.
|
|
16
|
+
local/ci fail only for installed-release maintenance blockers
|
|
17
|
+
preflight also fails for target-release migration blockers
|
|
21
18
|
`;
|
|
22
19
|
export function parseBrandlabConformanceArgs(argv) {
|
|
23
20
|
const parsed = {
|
|
24
21
|
root: process.cwd(),
|
|
22
|
+
supportPolicyPath: null,
|
|
23
|
+
releaseManifestPaths: [],
|
|
25
24
|
mode: "local",
|
|
26
25
|
json: false,
|
|
27
26
|
help: false,
|
|
28
27
|
};
|
|
29
28
|
for (let index = 0; index < argv.length; index += 1) {
|
|
30
29
|
const argument = argv[index];
|
|
31
|
-
if (argument === "--help" || argument === "-h")
|
|
30
|
+
if (argument === "--help" || argument === "-h") {
|
|
32
31
|
parsed.help = true;
|
|
33
|
-
|
|
32
|
+
}
|
|
33
|
+
else if (argument === "--json") {
|
|
34
34
|
parsed.json = true;
|
|
35
|
+
}
|
|
35
36
|
else if (argument === "--root") {
|
|
36
37
|
parsed.root = resolve(requireValue(argv, ++index, "--root"));
|
|
37
38
|
}
|
|
39
|
+
else if (argument === "--support-policy") {
|
|
40
|
+
parsed.supportPolicyPath = resolve(requireValue(argv, ++index, "--support-policy"));
|
|
41
|
+
}
|
|
42
|
+
else if (argument === "--release-manifest") {
|
|
43
|
+
parsed.releaseManifestPaths.push(resolve(requireValue(argv, ++index, "--release-manifest")));
|
|
44
|
+
}
|
|
38
45
|
else if (argument === "--installed-release") {
|
|
39
46
|
const value = requireValue(argv, ++index, "--installed-release");
|
|
40
47
|
parsed.installedRelease = value === "unadopted" ? null : value;
|
|
41
48
|
}
|
|
49
|
+
else if (argument === "--target-release") {
|
|
50
|
+
const value = requireValue(argv, ++index, "--target-release");
|
|
51
|
+
parsed.targetRelease = value === "none" ? null : value;
|
|
52
|
+
}
|
|
42
53
|
else if (argument === "--mode") {
|
|
43
54
|
const value = requireValue(argv, ++index, "--mode");
|
|
44
|
-
if (
|
|
55
|
+
if (value !== "local" && value !== "ci" && value !== "preflight") {
|
|
45
56
|
throw new Error(`Invalid --mode ${value}.`);
|
|
46
57
|
}
|
|
47
58
|
parsed.mode = value;
|
|
@@ -50,6 +61,9 @@ export function parseBrandlabConformanceArgs(argv) {
|
|
|
50
61
|
throw new Error(`Unknown argument ${argument}.`);
|
|
51
62
|
}
|
|
52
63
|
}
|
|
64
|
+
if (!parsed.help && parsed.supportPolicyPath === null) {
|
|
65
|
+
throw new Error("--support-policy is required.");
|
|
66
|
+
}
|
|
53
67
|
return parsed;
|
|
54
68
|
}
|
|
55
69
|
export function runBrandlabConformanceCli(argv, io = {
|
|
@@ -62,10 +76,23 @@ export function runBrandlabConformanceCli(argv, io = {
|
|
|
62
76
|
io.stdout(HELP);
|
|
63
77
|
return 0;
|
|
64
78
|
}
|
|
79
|
+
const supportPolicy = loadSupportPolicy(options.supportPolicyPath);
|
|
80
|
+
const policyManifestPaths = resolveSupportPolicyReleaseManifestPaths(options.supportPolicyPath, supportPolicy);
|
|
81
|
+
const releaseManifests = [
|
|
82
|
+
...new Set([
|
|
83
|
+
...policyManifestPaths,
|
|
84
|
+
...options.releaseManifestPaths,
|
|
85
|
+
]),
|
|
86
|
+
]
|
|
87
|
+
.map(loadReleaseManifest)
|
|
88
|
+
.sort((left, right) => compareBrandlabSemver(left.releaseVersion, right.releaseVersion));
|
|
65
89
|
const result = evaluateBrandlabProject({
|
|
66
90
|
root: options.root,
|
|
67
91
|
installedRelease: options.installedRelease,
|
|
92
|
+
targetRelease: options.targetRelease,
|
|
68
93
|
mode: options.mode,
|
|
94
|
+
releaseManifests,
|
|
95
|
+
supportPolicy,
|
|
69
96
|
});
|
|
70
97
|
io.stdout(options.json ? `${JSON.stringify(result, null, 2)}\n` : formatResult(result));
|
|
71
98
|
return shouldFailBrandlabConformance(result) ? 1 : 0;
|
|
@@ -75,33 +102,64 @@ export function runBrandlabConformanceCli(argv, io = {
|
|
|
75
102
|
return 2;
|
|
76
103
|
}
|
|
77
104
|
}
|
|
105
|
+
function loadSupportPolicy(path) {
|
|
106
|
+
if (path === null)
|
|
107
|
+
throw new Error("--support-policy is required.");
|
|
108
|
+
try {
|
|
109
|
+
return JSON.parse(readFileSync(path, "utf8"));
|
|
110
|
+
}
|
|
111
|
+
catch (error) {
|
|
112
|
+
const detail = error instanceof Error ? error.message : String(error);
|
|
113
|
+
throw new Error(`Unable to load support policy from ${path}: ${detail}`);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
function loadReleaseManifest(path) {
|
|
117
|
+
try {
|
|
118
|
+
return JSON.parse(readFileSync(path, "utf8"));
|
|
119
|
+
}
|
|
120
|
+
catch (error) {
|
|
121
|
+
const detail = error instanceof Error ? error.message : String(error);
|
|
122
|
+
throw new Error(`Unable to load release manifest from ${path}: ${detail}`);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
function resolveSupportPolicyReleaseManifestPaths(supportPolicyPath, supportPolicy) {
|
|
126
|
+
if (supportPolicyPath === null)
|
|
127
|
+
throw new Error("--support-policy is required.");
|
|
128
|
+
const references = Object.values(supportPolicy.releases ?? {}).map((release) => release?.manifest);
|
|
129
|
+
if (references.length === 0 ||
|
|
130
|
+
references.some((reference) => typeof reference !== "string" ||
|
|
131
|
+
reference.length === 0 ||
|
|
132
|
+
isAbsolute(reference) ||
|
|
133
|
+
reference.includes("\\") ||
|
|
134
|
+
reference.split("/").some((segment) => segment === ".."))) {
|
|
135
|
+
throw new Error("Support policy must use safe relative immutable release-manifest paths.");
|
|
136
|
+
}
|
|
137
|
+
let candidateRoot = dirname(supportPolicyPath);
|
|
138
|
+
while (true) {
|
|
139
|
+
const candidates = references.map((reference) => resolve(candidateRoot, reference));
|
|
140
|
+
if (candidates.every((candidate) => existsSync(candidate)))
|
|
141
|
+
return candidates;
|
|
142
|
+
const parent = dirname(candidateRoot);
|
|
143
|
+
if (parent === candidateRoot)
|
|
144
|
+
break;
|
|
145
|
+
candidateRoot = parent;
|
|
146
|
+
}
|
|
147
|
+
throw new Error(`Cannot resolve every support-policy release manifest from ${supportPolicyPath}.`);
|
|
148
|
+
}
|
|
78
149
|
function formatResult(result) {
|
|
79
|
-
const externalChecks = result.verification.checks.filter((check) => check.status === "not_run");
|
|
80
|
-
const staticStatus = result.verification.summary.blockers > 0
|
|
81
|
-
? "blocked"
|
|
82
|
-
: result.verification.summary.warnings > 0
|
|
83
|
-
? "warning"
|
|
84
|
-
: "pass";
|
|
85
150
|
const lines = [
|
|
86
|
-
"Brandlab
|
|
151
|
+
"Brandlab conformance",
|
|
87
152
|
`installed: ${result.installedRelease ?? "unadopted"}`,
|
|
88
|
-
`
|
|
89
|
-
`
|
|
90
|
-
`
|
|
91
|
-
|
|
92
|
-
: "complete"}`,
|
|
93
|
-
`findings: ${formatSummary(result.verification.summary)}`,
|
|
153
|
+
`target: ${result.targetRelease ?? "none"}`,
|
|
154
|
+
`maintenance: ${formatSummary(result.maintenance)}`,
|
|
155
|
+
`migration: ${formatSummary(result.migration)}`,
|
|
156
|
+
`advisory: ${formatSummary(result.advisory)}`,
|
|
94
157
|
];
|
|
95
|
-
for (const
|
|
96
|
-
if (family.status === "pass")
|
|
97
|
-
continue;
|
|
98
|
-
lines.push(`[${family.status}] ${family.title}: ${family.blockers} blocker(s), ${family.warnings} warning(s)`);
|
|
99
|
-
}
|
|
100
|
-
for (const finding of result.operationalFindings) {
|
|
158
|
+
for (const finding of result.findings) {
|
|
101
159
|
const location = finding.path
|
|
102
160
|
? ` (${finding.path}${finding.line ? `:${finding.line}` : ""})`
|
|
103
161
|
: "";
|
|
104
|
-
lines.push(`[${finding.
|
|
162
|
+
lines.push(`[${finding.classification}/${finding.severity}] ${finding.ruleId}${location}: ${finding.actual}`);
|
|
105
163
|
}
|
|
106
164
|
return `${lines.join("\n")}\n`;
|
|
107
165
|
}
|
|
@@ -114,17 +172,7 @@ function requireValue(argv, index, argument) {
|
|
|
114
172
|
throw new Error(`${argument} requires a value.`);
|
|
115
173
|
return value;
|
|
116
174
|
}
|
|
117
|
-
|
|
118
|
-
if (!argvPath)
|
|
119
|
-
return false;
|
|
120
|
-
try {
|
|
121
|
-
return realpathSync(fileURLToPath(moduleUrl)) === realpathSync(resolve(argvPath));
|
|
122
|
-
}
|
|
123
|
-
catch {
|
|
124
|
-
return false;
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
if (isBrandlabConformanceCliEntrypoint(import.meta.url, process.argv[1])) {
|
|
175
|
+
if (process.argv[1] && import.meta.url === pathToFileURL(resolve(process.argv[1])).href) {
|
|
128
176
|
process.exitCode = runBrandlabConformanceCli(process.argv.slice(2));
|
|
129
177
|
}
|
|
130
178
|
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { type BrandlabArchitectureConfigLike, type BrandlabArchitectureIssue, type BrandlabArchitectureReport } from "./vitest.js";
|
|
2
|
+
export type BrandlabLegacyArchitectureContract = "architecture-v1" | "architecture-v2";
|
|
3
|
+
export interface BrandlabLegacyArchitectureInspection {
|
|
4
|
+
contract: BrandlabLegacyArchitectureContract;
|
|
5
|
+
rulesetId: string;
|
|
6
|
+
report: BrandlabArchitectureReport;
|
|
7
|
+
issues: readonly BrandlabArchitectureIssue[];
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Architecture v1 made only contract presence operationally blocking. The
|
|
11
|
+
* deeper architecture diagnosis existed, but did not become maintenance debt
|
|
12
|
+
* until architecture v2.
|
|
13
|
+
*/
|
|
14
|
+
export declare const BRANDLAB_LEGACY_ARCHITECTURE_V1_RULESET_ID = "legacy-architecture-v1-config-presence@6e9dfbd25280f1092b6d88c71c4164e5e9a53d4e";
|
|
15
|
+
/**
|
|
16
|
+
* The v2 evaluator source is identical in Alpha.18, Alpha.19, Alpha.23 and
|
|
17
|
+
* RC.1. The evaluator depends on constants and helpers throughout vitest.ts,
|
|
18
|
+
* so that entire source module is the deliberate freeze boundary. Its digest
|
|
19
|
+
* is pinned by project.test.ts; later edits must introduce a new contract or
|
|
20
|
+
* immutable snapshot instead of silently becoming historical maintenance.
|
|
21
|
+
*/
|
|
22
|
+
export declare const BRANDLAB_LEGACY_ARCHITECTURE_V2_RULESET_ID = "legacy-architecture-v2@sha256:5f4979b80552b98b9bb558a3bbce12001bf354b05ea9b979c638c2d1a6c4cdac";
|
|
23
|
+
export declare const BRANDLAB_LEGACY_ARCHITECTURE_V2_SOURCE_SHA256 = "5f4979b80552b98b9bb558a3bbce12001bf354b05ea9b979c638c2d1a6c4cdac";
|
|
24
|
+
export declare function inspectLegacyArchitectureContract(options: {
|
|
25
|
+
root: string;
|
|
26
|
+
architecture: BrandlabArchitectureConfigLike | null | undefined;
|
|
27
|
+
contract: BrandlabLegacyArchitectureContract;
|
|
28
|
+
}): BrandlabLegacyArchitectureInspection;
|
|
29
|
+
export declare function legacyArchitectureRulesetId(contract: string | null | undefined): string | null;
|
|
30
|
+
export declare function targetOnlyLegacyArchitectureIssues(installed: BrandlabLegacyArchitectureInspection | null, target: BrandlabLegacyArchitectureInspection): readonly BrandlabArchitectureIssue[];
|
|
31
|
+
//# sourceMappingURL=legacy-architecture-contracts.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"legacy-architecture-contracts.d.ts","sourceRoot":"","sources":["../src/legacy-architecture-contracts.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,8BAA8B,EACnC,KAAK,yBAAyB,EAC9B,KAAK,0BAA0B,EAChC,MAAM,aAAa,CAAC;AAErB,MAAM,MAAM,kCAAkC,GAC1C,iBAAiB,GACjB,iBAAiB,CAAC;AAEtB,MAAM,WAAW,oCAAoC;IACnD,QAAQ,EAAE,kCAAkC,CAAC;IAC7C,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,0BAA0B,CAAC;IACnC,MAAM,EAAE,SAAS,yBAAyB,EAAE,CAAC;CAC9C;AAED;;;;GAIG;AACH,eAAO,MAAM,0CAA0C,oFAC4B,CAAC;AAEpF;;;;;;GAMG;AACH,eAAO,MAAM,0CAA0C,mGAC2C,CAAC;AAEnG,eAAO,MAAM,6CAA6C,qEACU,CAAC;AAMrE,wBAAgB,iCAAiC,CAAC,OAAO,EAAE;IACzD,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,8BAA8B,GAAG,IAAI,GAAG,SAAS,CAAC;IAChE,QAAQ,EAAE,kCAAkC,CAAC;CAC9C,GAAG,oCAAoC,CAevC;AAED,wBAAgB,2BAA2B,CACzC,QAAQ,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAClC,MAAM,GAAG,IAAI,CAQf;AAED,wBAAgB,kCAAkC,CAChD,SAAS,EAAE,oCAAoC,GAAG,IAAI,EACtD,MAAM,EAAE,oCAAoC,GAC3C,SAAS,yBAAyB,EAAE,CAKtC"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { evaluateBrandlabArchitecture, } from "./vitest.js";
|
|
2
|
+
/**
|
|
3
|
+
* Architecture v1 made only contract presence operationally blocking. The
|
|
4
|
+
* deeper architecture diagnosis existed, but did not become maintenance debt
|
|
5
|
+
* until architecture v2.
|
|
6
|
+
*/
|
|
7
|
+
export const BRANDLAB_LEGACY_ARCHITECTURE_V1_RULESET_ID = "legacy-architecture-v1-config-presence@6e9dfbd25280f1092b6d88c71c4164e5e9a53d4e";
|
|
8
|
+
/**
|
|
9
|
+
* The v2 evaluator source is identical in Alpha.18, Alpha.19, Alpha.23 and
|
|
10
|
+
* RC.1. The evaluator depends on constants and helpers throughout vitest.ts,
|
|
11
|
+
* so that entire source module is the deliberate freeze boundary. Its digest
|
|
12
|
+
* is pinned by project.test.ts; later edits must introduce a new contract or
|
|
13
|
+
* immutable snapshot instead of silently becoming historical maintenance.
|
|
14
|
+
*/
|
|
15
|
+
export const BRANDLAB_LEGACY_ARCHITECTURE_V2_RULESET_ID = "legacy-architecture-v2@sha256:5f4979b80552b98b9bb558a3bbce12001bf354b05ea9b979c638c2d1a6c4cdac";
|
|
16
|
+
export const BRANDLAB_LEGACY_ARCHITECTURE_V2_SOURCE_SHA256 = "5f4979b80552b98b9bb558a3bbce12001bf354b05ea9b979c638c2d1a6c4cdac";
|
|
17
|
+
const V1_MAINTENANCE_RULE_IDS = new Set([
|
|
18
|
+
"brandlab-architecture-config-missing",
|
|
19
|
+
]);
|
|
20
|
+
export function inspectLegacyArchitectureContract(options) {
|
|
21
|
+
const report = evaluateBrandlabArchitecture({
|
|
22
|
+
root: options.root,
|
|
23
|
+
architecture: options.architecture,
|
|
24
|
+
});
|
|
25
|
+
return {
|
|
26
|
+
contract: options.contract,
|
|
27
|
+
rulesetId: options.contract === "architecture-v1"
|
|
28
|
+
? BRANDLAB_LEGACY_ARCHITECTURE_V1_RULESET_ID
|
|
29
|
+
: BRANDLAB_LEGACY_ARCHITECTURE_V2_RULESET_ID,
|
|
30
|
+
report,
|
|
31
|
+
issues: options.contract === "architecture-v1"
|
|
32
|
+
? report.issues.filter((issue) => V1_MAINTENANCE_RULE_IDS.has(issue.code))
|
|
33
|
+
: report.issues,
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
export function legacyArchitectureRulesetId(contract) {
|
|
37
|
+
if (contract === "architecture-v1") {
|
|
38
|
+
return BRANDLAB_LEGACY_ARCHITECTURE_V1_RULESET_ID;
|
|
39
|
+
}
|
|
40
|
+
if (contract === "architecture-v2") {
|
|
41
|
+
return BRANDLAB_LEGACY_ARCHITECTURE_V2_RULESET_ID;
|
|
42
|
+
}
|
|
43
|
+
return null;
|
|
44
|
+
}
|
|
45
|
+
export function targetOnlyLegacyArchitectureIssues(installed, target) {
|
|
46
|
+
const installedRuleIds = new Set((installed?.issues ?? []).map((issue) => issue.code));
|
|
47
|
+
return target.issues.filter((issue) => !installedRuleIds.has(issue.code));
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=legacy-architecture-contracts.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"legacy-architecture-contracts.js","sourceRoot":"","sources":["../src/legacy-architecture-contracts.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,4BAA4B,GAI7B,MAAM,aAAa,CAAC;AAarB;;;;GAIG;AACH,MAAM,CAAC,MAAM,0CAA0C,GACrD,iFAAiF,CAAC;AAEpF;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,0CAA0C,GACrD,gGAAgG,CAAC;AAEnG,MAAM,CAAC,MAAM,6CAA6C,GACxD,kEAAkE,CAAC;AAErE,MAAM,uBAAuB,GAAG,IAAI,GAAG,CAAC;IACtC,sCAAsC;CACvC,CAAC,CAAC;AAEH,MAAM,UAAU,iCAAiC,CAAC,OAIjD;IACC,MAAM,MAAM,GAAG,4BAA4B,CAAC;QAC1C,IAAI,EAAE,OAAO,CAAC,IAAI;QAClB,YAAY,EAAE,OAAO,CAAC,YAAY;KACnC,CAAC,CAAC;IACH,OAAO;QACL,QAAQ,EAAE,OAAO,CAAC,QAAQ;QAC1B,SAAS,EAAE,OAAO,CAAC,QAAQ,KAAK,iBAAiB;YAC/C,CAAC,CAAC,0CAA0C;YAC5C,CAAC,CAAC,0CAA0C;QAC9C,MAAM;QACN,MAAM,EAAE,OAAO,CAAC,QAAQ,KAAK,iBAAiB;YAC5C,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,uBAAuB,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YAC1E,CAAC,CAAC,MAAM,CAAC,MAAM;KAClB,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,2BAA2B,CACzC,QAAmC;IAEnC,IAAI,QAAQ,KAAK,iBAAiB,EAAE,CAAC;QACnC,OAAO,0CAA0C,CAAC;IACpD,CAAC;IACD,IAAI,QAAQ,KAAK,iBAAiB,EAAE,CAAC;QACnC,OAAO,0CAA0C,CAAC;IACpD,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,UAAU,kCAAkC,CAChD,SAAsD,EACtD,MAA4C;IAE5C,MAAM,gBAAgB,GAAG,IAAI,GAAG,CAC9B,CAAC,SAAS,EAAE,MAAM,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CACrD,CAAC;IACF,OAAO,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,gBAAgB,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC;AAC5E,CAAC"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Location-page conformance rules (Brandlab Location Pages Standard §11).
|
|
3
|
+
*
|
|
4
|
+
* These checks are heuristics over project source text and sitemap output.
|
|
5
|
+
* They are deliberately conservative: each rule documents its escape hatch so
|
|
6
|
+
* a compliant pattern is never impossible, only explicit.
|
|
7
|
+
*/
|
|
8
|
+
import type { SourcePattern, SourcePatternMatch, SourceTextFile } from "./vitest.js";
|
|
9
|
+
export declare const BRANDLAB_LOCATION_FORBIDDEN_SOURCE_PATTERNS: readonly SourcePattern[];
|
|
10
|
+
/**
|
|
11
|
+
* Flags `approvedIndexable*` assignments whose value is produced by code
|
|
12
|
+
* (call/map/flatMap) instead of an explicit literal list (standard §7.4).
|
|
13
|
+
*
|
|
14
|
+
* Escape hatch: statements that reference an identifier containing "frozen"
|
|
15
|
+
* are allowed — that is the documented snapshot pattern (an explicit,
|
|
16
|
+
* human-edited literal module filtered into record shape).
|
|
17
|
+
*/
|
|
18
|
+
export declare function findGeneratedServiceLocationApprovals(files: readonly SourceTextFile[]): SourcePatternMatch[];
|
|
19
|
+
export interface LocationLinkDumpOptions {
|
|
20
|
+
files: readonly SourceTextFile[];
|
|
21
|
+
/** Path prefixes that identify location URLs, e.g. ['/locations/']. */
|
|
22
|
+
locationPathPrefixes: readonly string[];
|
|
23
|
+
/** Only files whose path matches are checked. Default: footer/nav components. */
|
|
24
|
+
filePathPattern?: RegExp;
|
|
25
|
+
/** Maximum location links allowed per matching file. Default 20 (≈ regions, never all suburbs). */
|
|
26
|
+
maxLinks?: number;
|
|
27
|
+
}
|
|
28
|
+
export interface LocationLinkDumpFinding {
|
|
29
|
+
file: string;
|
|
30
|
+
linkCount: number;
|
|
31
|
+
maxLinks: number;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Flags footer/nav components that link a suburb dump (standard §6.6 — nav
|
|
35
|
+
* and footer carry region links only; "blocks of text that list cities and
|
|
36
|
+
* regions" is Google's own keyword-stuffing example).
|
|
37
|
+
*/
|
|
38
|
+
export declare function findLocationLinkDumps({ files, locationPathPrefixes, filePathPattern, maxLinks, }: LocationLinkDumpOptions): LocationLinkDumpFinding[];
|
|
39
|
+
/**
|
|
40
|
+
* Copy-hygiene patterns for location data modules (standard §3.8). Applied to
|
|
41
|
+
* `src/data/locations/**` and `src/data/serviceLocations/**` rendered-string
|
|
42
|
+
* sources: unresolved tokens and template wording must never reach a
|
|
43
|
+
* customer-facing surface.
|
|
44
|
+
*/
|
|
45
|
+
export declare const BRANDLAB_LOCATION_COPY_PATTERNS: readonly SourcePattern[];
|
|
46
|
+
export interface LocationUrlShareOptions {
|
|
47
|
+
/** All sitemap entry URLs (absolute or root-relative). */
|
|
48
|
+
urls: readonly string[];
|
|
49
|
+
/** Predicate identifying location-family URLs. */
|
|
50
|
+
isLocationUrl: (url: string) => boolean;
|
|
51
|
+
/** Warn when location URLs exceed this share of all URLs. Default 0.4 (standard §8.8). */
|
|
52
|
+
maxShare?: number;
|
|
53
|
+
}
|
|
54
|
+
export interface LocationUrlShareResult {
|
|
55
|
+
locationUrlCount: number;
|
|
56
|
+
totalUrlCount: number;
|
|
57
|
+
share: number;
|
|
58
|
+
maxShare: number;
|
|
59
|
+
exceeded: boolean;
|
|
60
|
+
}
|
|
61
|
+
/** Volume alarm for location-heavy sitemaps (standard §8.8). */
|
|
62
|
+
export declare function evaluateLocationUrlShare({ urls, isLocationUrl, maxShare, }: LocationUrlShareOptions): LocationUrlShareResult;
|
|
63
|
+
//# sourceMappingURL=locations.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"locations.d.ts","sourceRoot":"","sources":["../src/locations.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,KAAK,EAAE,aAAa,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAErF,eAAO,MAAM,2CAA2C,EAAE,SAAS,aAAa,EAkB/E,CAAC;AAEF;;;;;;;GAOG;AACH,wBAAgB,qCAAqC,CACnD,KAAK,EAAE,SAAS,cAAc,EAAE,GAC/B,kBAAkB,EAAE,CAuBtB;AAED,MAAM,WAAW,uBAAuB;IACtC,KAAK,EAAE,SAAS,cAAc,EAAE,CAAC;IACjC,uEAAuE;IACvE,oBAAoB,EAAE,SAAS,MAAM,EAAE,CAAC;IACxC,iFAAiF;IACjF,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,mGAAmG;IACnG,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,uBAAuB;IACtC,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,EACpC,KAAK,EACL,oBAAoB,EACpB,eAAiC,EACjC,QAAa,GACd,EAAE,uBAAuB,GAAG,uBAAuB,EAAE,CAiBrD;AAED;;;;;GAKG;AACH,eAAO,MAAM,+BAA+B,EAAE,SAAS,aAAa,EAcnE,CAAC;AAEF,MAAM,WAAW,uBAAuB;IACtC,0DAA0D;IAC1D,IAAI,EAAE,SAAS,MAAM,EAAE,CAAC;IACxB,kDAAkD;IAClD,aAAa,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC;IACxC,0FAA0F;IAC1F,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,sBAAsB;IACrC,gBAAgB,EAAE,MAAM,CAAC;IACzB,aAAa,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED,gEAAgE;AAChE,wBAAgB,wBAAwB,CAAC,EACvC,IAAI,EACJ,aAAa,EACb,QAAc,GACf,EAAE,uBAAuB,GAAG,sBAAsB,CAYlD"}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
export const BRANDLAB_LOCATION_FORBIDDEN_SOURCE_PATTERNS = [
|
|
2
|
+
{
|
|
3
|
+
// Rating markup about the business/its services is never emitted
|
|
4
|
+
// (standard §6.2). Matches emission sites, not prose/comments.
|
|
5
|
+
name: "self-serving rating schema emission",
|
|
6
|
+
pattern: /['"]@type['"]\s*:\s*['"](?:AggregateRating|Review)['"]/,
|
|
7
|
+
},
|
|
8
|
+
{
|
|
9
|
+
name: "self-serving rating schema builder",
|
|
10
|
+
pattern: /\bbuild(?:Service)?(?:AggregateRating|Rating|Review)Schema\b/,
|
|
11
|
+
},
|
|
12
|
+
{
|
|
13
|
+
// Named constant reused as every sitemap entry's lastModified defeats
|
|
14
|
+
// the freshness signal (standard §6.3). Use per-record
|
|
15
|
+
// lastSubstantialUpdate dates instead.
|
|
16
|
+
name: "constant sitemap lastModified",
|
|
17
|
+
pattern: /lastModified\s*:\s*SITEMAP_LAST_MODIFIED\b/,
|
|
18
|
+
},
|
|
19
|
+
];
|
|
20
|
+
/**
|
|
21
|
+
* Flags `approvedIndexable*` assignments whose value is produced by code
|
|
22
|
+
* (call/map/flatMap) instead of an explicit literal list (standard §7.4).
|
|
23
|
+
*
|
|
24
|
+
* Escape hatch: statements that reference an identifier containing "frozen"
|
|
25
|
+
* are allowed — that is the documented snapshot pattern (an explicit,
|
|
26
|
+
* human-edited literal module filtered into record shape).
|
|
27
|
+
*/
|
|
28
|
+
export function findGeneratedServiceLocationApprovals(files) {
|
|
29
|
+
const matches = [];
|
|
30
|
+
const assignment = /\bapprovedIndexable\w*\s*[:=]/;
|
|
31
|
+
const generated = /[:=][^;\n]*(?:\.flatMap\(|\.map\(|\w+\(\s*\))/;
|
|
32
|
+
for (const file of files) {
|
|
33
|
+
const lines = file.text.split("\n");
|
|
34
|
+
lines.forEach((line, index) => {
|
|
35
|
+
if (!assignment.test(line))
|
|
36
|
+
return;
|
|
37
|
+
if (/frozen/i.test(line))
|
|
38
|
+
return;
|
|
39
|
+
if (!generated.test(line))
|
|
40
|
+
return;
|
|
41
|
+
matches.push({
|
|
42
|
+
file: file.path,
|
|
43
|
+
patternName: "generated service-location approvals",
|
|
44
|
+
line: index + 1,
|
|
45
|
+
column: line.search(assignment) + 1,
|
|
46
|
+
text: line.trim(),
|
|
47
|
+
});
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
return matches;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Flags footer/nav components that link a suburb dump (standard §6.6 — nav
|
|
54
|
+
* and footer carry region links only; "blocks of text that list cities and
|
|
55
|
+
* regions" is Google's own keyword-stuffing example).
|
|
56
|
+
*/
|
|
57
|
+
export function findLocationLinkDumps({ files, locationPathPrefixes, filePathPattern = /(footer|nav)/i, maxLinks = 20, }) {
|
|
58
|
+
const findings = [];
|
|
59
|
+
for (const file of files) {
|
|
60
|
+
if (!filePathPattern.test(file.path))
|
|
61
|
+
continue;
|
|
62
|
+
let linkCount = 0;
|
|
63
|
+
for (const prefix of locationPathPrefixes) {
|
|
64
|
+
linkCount += file.text.split(prefix).length - 1;
|
|
65
|
+
}
|
|
66
|
+
if (linkCount > maxLinks) {
|
|
67
|
+
findings.push({ file: file.path, linkCount, maxLinks });
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
return findings;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Copy-hygiene patterns for location data modules (standard §3.8). Applied to
|
|
74
|
+
* `src/data/locations/**` and `src/data/serviceLocations/**` rendered-string
|
|
75
|
+
* sources: unresolved tokens and template wording must never reach a
|
|
76
|
+
* customer-facing surface.
|
|
77
|
+
*/
|
|
78
|
+
export const BRANDLAB_LOCATION_COPY_PATTERNS = [
|
|
79
|
+
{
|
|
80
|
+
name: "unresolved bracket token",
|
|
81
|
+
pattern: /\[(?:Suburb|Region|Location|Service|Business Name|Phone|Email)\]/,
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
name: "unresolved curly token in string",
|
|
85
|
+
pattern: /['"`][^'"`\n]*\{(?:suburb|region|location|service)\}[^'"`\n]*['"`]/,
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
name: "template wording",
|
|
89
|
+
pattern: /\b(?:lorem ipsum|placeholder copy|copy goes here|content goes here|insert copy|TODO copy|sample copy|starter copy|boilerplate copy)\b/i,
|
|
90
|
+
},
|
|
91
|
+
];
|
|
92
|
+
/** Volume alarm for location-heavy sitemaps (standard §8.8). */
|
|
93
|
+
export function evaluateLocationUrlShare({ urls, isLocationUrl, maxShare = 0.4, }) {
|
|
94
|
+
const totalUrlCount = urls.length;
|
|
95
|
+
const locationUrlCount = urls.filter((url) => isLocationUrl(url)).length;
|
|
96
|
+
const share = totalUrlCount === 0 ? 0 : locationUrlCount / totalUrlCount;
|
|
97
|
+
return {
|
|
98
|
+
locationUrlCount,
|
|
99
|
+
totalUrlCount,
|
|
100
|
+
share,
|
|
101
|
+
maxShare,
|
|
102
|
+
exceeded: share > maxShare,
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
//# sourceMappingURL=locations.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"locations.js","sourceRoot":"","sources":["../src/locations.ts"],"names":[],"mappings":"AASA,MAAM,CAAC,MAAM,2CAA2C,GAA6B;IACnF;QACE,iEAAiE;QACjE,+DAA+D;QAC/D,IAAI,EAAE,qCAAqC;QAC3C,OAAO,EAAE,wDAAwD;KAClE;IACD;QACE,IAAI,EAAE,oCAAoC;QAC1C,OAAO,EAAE,8DAA8D;KACxE;IACD;QACE,sEAAsE;QACtE,uDAAuD;QACvD,uCAAuC;QACvC,IAAI,EAAE,+BAA+B;QACrC,OAAO,EAAE,4CAA4C;KACtD;CACF,CAAC;AAEF;;;;;;;GAOG;AACH,MAAM,UAAU,qCAAqC,CACnD,KAAgC;IAEhC,MAAM,OAAO,GAAyB,EAAE,CAAC;IACzC,MAAM,UAAU,GAAG,+BAA+B,CAAC;IACnD,MAAM,SAAS,GAAG,+CAA+C,CAAC;IAElE,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QACpC,KAAK,CAAC,OAAO,CAAC,CAAC,IAAY,EAAE,KAAa,EAAE,EAAE;YAC5C,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC;gBAAE,OAAO;YACnC,IAAI,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC;gBAAE,OAAO;YACjC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC;gBAAE,OAAO;YAElC,OAAO,CAAC,IAAI,CAAC;gBACX,IAAI,EAAE,IAAI,CAAC,IAAI;gBACf,WAAW,EAAE,sCAAsC;gBACnD,IAAI,EAAE,KAAK,GAAG,CAAC;gBACf,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,GAAG,CAAC;gBACnC,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE;aAClB,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC;AAkBD;;;;GAIG;AACH,MAAM,UAAU,qBAAqB,CAAC,EACpC,KAAK,EACL,oBAAoB,EACpB,eAAe,GAAG,eAAe,EACjC,QAAQ,GAAG,EAAE,GACW;IACxB,MAAM,QAAQ,GAA8B,EAAE,CAAC;IAE/C,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC;YAAE,SAAS;QAE/C,IAAI,SAAS,GAAG,CAAC,CAAC;QAClB,KAAK,MAAM,MAAM,IAAI,oBAAoB,EAAE,CAAC;YAC1C,SAAS,IAAI,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC;QAClD,CAAC;QAED,IAAI,SAAS,GAAG,QAAQ,EAAE,CAAC;YACzB,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,CAAC,CAAC;QAC1D,CAAC;IACH,CAAC;IAED,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,MAAM,+BAA+B,GAA6B;IACvE;QACE,IAAI,EAAE,0BAA0B;QAChC,OAAO,EAAE,kEAAkE;KAC5E;IACD;QACE,IAAI,EAAE,kCAAkC;QACxC,OAAO,EAAE,oEAAoE;KAC9E;IACD;QACE,IAAI,EAAE,kBAAkB;QACxB,OAAO,EACL,wIAAwI;KAC3I;CACF,CAAC;AAmBF,gEAAgE;AAChE,MAAM,UAAU,wBAAwB,CAAC,EACvC,IAAI,EACJ,aAAa,EACb,QAAQ,GAAG,GAAG,GACU;IACxB,MAAM,aAAa,GAAG,IAAI,CAAC,MAAM,CAAC;IAClC,MAAM,gBAAgB,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC;IACzE,MAAM,KAAK,GAAG,aAAa,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,gBAAgB,GAAG,aAAa,CAAC;IAEzE,OAAO;QACL,gBAAgB;QAChB,aAAa;QACb,KAAK;QACL,QAAQ;QACR,QAAQ,EAAE,KAAK,GAAG,QAAQ;KAC3B,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
export declare const BRANDLAB_CONFIG_V2_RULESET_ID = "project-config-v2@1.0.0-rc.1:5d6c4a9a27abd65e5a8e55d5f66145ff499ead7d";
|
|
2
|
+
export declare const BRANDLAB_CONFIG_V2_PROFILES: readonly ["next-local-service", "next-root-level", "next-static-legacy", "legacy-php"];
|
|
3
|
+
export interface InspectedBrandlabProjectConfig {
|
|
4
|
+
projectId: string;
|
|
5
|
+
profile: (typeof BRANDLAB_CONFIG_V2_PROFILES)[number];
|
|
6
|
+
routes: {
|
|
7
|
+
families: readonly string[];
|
|
8
|
+
};
|
|
9
|
+
capabilities: {
|
|
10
|
+
blogAdapter: string | null;
|
|
11
|
+
contactEnabled: boolean;
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
export interface BrandlabConfigV2Issue {
|
|
15
|
+
ruleId: string;
|
|
16
|
+
surface: string;
|
|
17
|
+
severity: "blocker" | "warning" | "info";
|
|
18
|
+
evidenceKind: "static" | "behavioural" | "runtime";
|
|
19
|
+
path?: string;
|
|
20
|
+
line?: number;
|
|
21
|
+
expected: string;
|
|
22
|
+
actual: string;
|
|
23
|
+
remediation: string;
|
|
24
|
+
}
|
|
25
|
+
export interface BrandlabConfigV2Inspection {
|
|
26
|
+
config: InspectedBrandlabProjectConfig | null;
|
|
27
|
+
imports: ReadonlySet<string>;
|
|
28
|
+
executableImports: ReadonlySet<string>;
|
|
29
|
+
issues: BrandlabConfigV2Issue[];
|
|
30
|
+
}
|
|
31
|
+
export declare function inspectBrandlabConfigV2(root: string): BrandlabConfigV2Inspection;
|
|
32
|
+
//# sourceMappingURL=project-config-v2-contract.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"project-config-v2-contract.d.ts","sourceRoot":"","sources":["../src/project-config-v2-contract.ts"],"names":[],"mappings":"AAYA,eAAO,MAAM,6BAA6B,0EAC+B,CAAC;AAE1E,eAAO,MAAM,2BAA2B,wFAK9B,CAAC;AA0CX,MAAM,WAAW,8BAA8B;IAC7C,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,CAAC,OAAO,2BAA2B,CAAC,CAAC,MAAM,CAAC,CAAC;IACtD,MAAM,EAAE;QACN,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAC;KAC7B,CAAC;IACF,YAAY,EAAE;QACZ,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;QAC3B,cAAc,EAAE,OAAO,CAAC;KACzB,CAAC;CACH;AAED,MAAM,WAAW,qBAAqB;IACpC,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,SAAS,GAAG,SAAS,GAAG,MAAM,CAAC;IACzC,YAAY,EAAE,QAAQ,GAAG,aAAa,GAAG,SAAS,CAAC;IACnD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,0BAA0B;IACzC,MAAM,EAAE,8BAA8B,GAAG,IAAI,CAAC;IAC9C,OAAO,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IAC7B,iBAAiB,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IACvC,MAAM,EAAE,qBAAqB,EAAE,CAAC;CACjC;AAqDD,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,MAAM,GAAG,0BAA0B,CA2FhF"}
|