@ploaness/governance 1.0.0 → 1.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.
- package/dist/a11y-hit-target.d.ts +35 -0
- package/dist/a11y-hit-target.d.ts.map +1 -0
- package/dist/a11y-hit-target.js +82 -0
- package/dist/a11y-hit-target.js.map +1 -0
- package/dist/a11y-incomplete.d.ts +18 -0
- package/dist/a11y-incomplete.d.ts.map +1 -0
- package/dist/a11y-incomplete.js +65 -0
- package/dist/a11y-incomplete.js.map +1 -0
- package/dist/access-boundary.d.ts +62 -6
- package/dist/access-boundary.d.ts.map +1 -1
- package/dist/access-boundary.js +201 -6
- package/dist/access-boundary.js.map +1 -1
- package/dist/admin-view-coverage.d.ts +25 -0
- package/dist/admin-view-coverage.d.ts.map +1 -0
- package/dist/admin-view-coverage.js +74 -0
- package/dist/admin-view-coverage.js.map +1 -0
- package/dist/asset-policy.d.ts.map +1 -1
- package/dist/asset-policy.js +1 -23
- package/dist/asset-policy.js.map +1 -1
- package/dist/axe-coverage.d.ts +40 -0
- package/dist/axe-coverage.d.ts.map +1 -0
- package/dist/axe-coverage.js +62 -0
- package/dist/axe-coverage.js.map +1 -0
- package/dist/banned-typography.d.ts.map +1 -1
- package/dist/banned-typography.js +26 -0
- package/dist/banned-typography.js.map +1 -1
- package/dist/blocklist-entries.d.ts +36 -0
- package/dist/blocklist-entries.d.ts.map +1 -0
- package/dist/blocklist-entries.js +338 -0
- package/dist/blocklist-entries.js.map +1 -0
- package/dist/blocklist.d.ts +91 -0
- package/dist/blocklist.d.ts.map +1 -0
- package/dist/blocklist.js +187 -0
- package/dist/blocklist.js.map +1 -0
- package/dist/build-diagnosis.d.ts +10 -0
- package/dist/build-diagnosis.d.ts.map +1 -0
- package/dist/build-diagnosis.js +38 -0
- package/dist/build-diagnosis.js.map +1 -0
- package/dist/container-failure.d.ts.map +1 -1
- package/dist/container-failure.js +1 -18
- package/dist/container-failure.js.map +1 -1
- package/dist/container-files.d.ts +16 -0
- package/dist/container-files.d.ts.map +1 -1
- package/dist/container-files.js +23 -8
- package/dist/container-files.js.map +1 -1
- package/dist/container-images.d.ts +43 -0
- package/dist/container-images.d.ts.map +1 -0
- package/dist/container-images.js +157 -0
- package/dist/container-images.js.map +1 -0
- package/dist/dependency-freshness.d.ts +8 -0
- package/dist/dependency-freshness.d.ts.map +1 -1
- package/dist/dependency-freshness.js +2 -18
- package/dist/dependency-freshness.js.map +1 -1
- package/dist/doc-blocks.d.ts.map +1 -1
- package/dist/doc-blocks.js +1 -13
- package/dist/doc-blocks.js.map +1 -1
- package/dist/document-references.d.ts.map +1 -1
- package/dist/document-references.js +7 -1
- package/dist/document-references.js.map +1 -1
- package/dist/editorconfig-policy.d.ts +7 -0
- package/dist/editorconfig-policy.d.ts.map +1 -1
- package/dist/editorconfig-policy.js +19 -12
- package/dist/editorconfig-policy.js.map +1 -1
- package/dist/environment-coherence.d.ts +87 -0
- package/dist/environment-coherence.d.ts.map +1 -0
- package/dist/environment-coherence.js +128 -0
- package/dist/environment-coherence.js.map +1 -0
- package/dist/environment-files.d.ts.map +1 -1
- package/dist/environment-files.js +1 -19
- package/dist/environment-files.js.map +1 -1
- package/dist/file-roles.d.ts +7 -2
- package/dist/file-roles.d.ts.map +1 -1
- package/dist/file-roles.js +10 -9
- package/dist/file-roles.js.map +1 -1
- package/dist/freshness-repair.d.ts +82 -0
- package/dist/freshness-repair.d.ts.map +1 -0
- package/dist/freshness-repair.js +91 -0
- package/dist/freshness-repair.js.map +1 -0
- package/dist/generated-denial.d.ts.map +1 -1
- package/dist/generated-denial.js +1 -9
- package/dist/generated-denial.js.map +1 -1
- package/dist/generated-drift.d.ts +18 -0
- package/dist/generated-drift.d.ts.map +1 -0
- package/dist/generated-drift.js +24 -0
- package/dist/generated-drift.js.map +1 -0
- package/dist/harness-package.d.ts +13 -0
- package/dist/harness-package.d.ts.map +1 -0
- package/dist/harness-package.js +20 -0
- package/dist/harness-package.js.map +1 -0
- package/dist/history-policy.d.ts.map +1 -1
- package/dist/history-policy.js +1 -7
- package/dist/history-policy.js.map +1 -1
- package/dist/image-assets.d.ts.map +1 -1
- package/dist/image-assets.js +1 -10
- package/dist/image-assets.js.map +1 -1
- package/dist/index.d.ts +22 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +22 -1
- package/dist/index.js.map +1 -1
- package/dist/install-policy.d.ts +21 -0
- package/dist/install-policy.d.ts.map +1 -1
- package/dist/install-policy.js +53 -1
- package/dist/install-policy.js.map +1 -1
- package/dist/jsx-accessibility-scope.d.ts +17 -0
- package/dist/jsx-accessibility-scope.d.ts.map +1 -0
- package/dist/jsx-accessibility-scope.js +36 -0
- package/dist/jsx-accessibility-scope.js.map +1 -0
- package/dist/jsx-accessibility.d.ts +13 -0
- package/dist/jsx-accessibility.d.ts.map +1 -0
- package/dist/jsx-accessibility.js +188 -0
- package/dist/jsx-accessibility.js.map +1 -0
- package/dist/network-policy.d.ts.map +1 -1
- package/dist/network-policy.js +1 -12
- package/dist/network-policy.js.map +1 -1
- package/dist/oxlint-policy.d.ts +16 -0
- package/dist/oxlint-policy.d.ts.map +1 -0
- package/dist/oxlint-policy.js +28 -0
- package/dist/oxlint-policy.js.map +1 -0
- package/dist/oxlint-report.d.ts +29 -0
- package/dist/oxlint-report.d.ts.map +1 -0
- package/dist/oxlint-report.js +84 -0
- package/dist/oxlint-report.js.map +1 -0
- package/dist/oxlint-scope.d.ts +13 -0
- package/dist/oxlint-scope.d.ts.map +1 -0
- package/dist/oxlint-scope.js +46 -0
- package/dist/oxlint-scope.js.map +1 -0
- package/dist/oxlint-suppressions.d.ts +17 -0
- package/dist/oxlint-suppressions.d.ts.map +1 -0
- package/dist/oxlint-suppressions.js +72 -0
- package/dist/oxlint-suppressions.js.map +1 -0
- package/dist/paired-assets.d.ts.map +1 -1
- package/dist/paired-assets.js.map +1 -1
- package/dist/payload-access.d.ts +6 -0
- package/dist/payload-access.d.ts.map +1 -1
- package/dist/payload-access.js +188 -57
- package/dist/payload-access.js.map +1 -1
- package/dist/payload-configs.d.ts +23 -0
- package/dist/payload-configs.d.ts.map +1 -0
- package/dist/payload-configs.js +96 -0
- package/dist/payload-configs.js.map +1 -0
- package/dist/payload-defaults.d.ts +128 -0
- package/dist/payload-defaults.d.ts.map +1 -0
- package/dist/payload-defaults.js +295 -0
- package/dist/payload-defaults.js.map +1 -0
- package/dist/payload-field-access.d.ts +4 -0
- package/dist/payload-field-access.d.ts.map +1 -0
- package/dist/payload-field-access.js +51 -0
- package/dist/payload-field-access.js.map +1 -0
- package/dist/payload-policy.d.ts +13 -0
- package/dist/payload-policy.d.ts.map +1 -1
- package/dist/payload-policy.js +171 -32
- package/dist/payload-policy.js.map +1 -1
- package/dist/payload-source.js +2 -2
- package/dist/payload-source.js.map +1 -1
- package/dist/relationship-cleanup.d.ts +18 -0
- package/dist/relationship-cleanup.d.ts.map +1 -0
- package/dist/relationship-cleanup.js +96 -0
- package/dist/relationship-cleanup.js.map +1 -0
- package/dist/release-age.d.ts.map +1 -1
- package/dist/release-age.js +1 -16
- package/dist/release-age.js.map +1 -1
- package/dist/request-limits.d.ts.map +1 -1
- package/dist/request-limits.js +1 -11
- package/dist/request-limits.js.map +1 -1
- package/dist/route-coverage.d.ts +27 -0
- package/dist/route-coverage.d.ts.map +1 -0
- package/dist/route-coverage.js +57 -0
- package/dist/route-coverage.js.map +1 -0
- package/dist/route-map.d.ts +65 -0
- package/dist/route-map.d.ts.map +1 -0
- package/dist/route-map.js +168 -0
- package/dist/route-map.js.map +1 -0
- package/dist/run-plan.d.ts.map +1 -1
- package/dist/run-plan.js +1 -19
- package/dist/run-plan.js.map +1 -1
- package/dist/secret-policy.d.ts.map +1 -1
- package/dist/secret-policy.js +5 -15
- package/dist/secret-policy.js.map +1 -1
- package/dist/settings-layering.d.ts +8 -30
- package/dist/settings-layering.d.ts.map +1 -1
- package/dist/settings-layering.js +19 -48
- package/dist/settings-layering.js.map +1 -1
- package/dist/settings.d.ts +19 -2
- package/dist/settings.d.ts.map +1 -1
- package/dist/settings.js +5 -1
- package/dist/settings.js.map +1 -1
- package/dist/source-security.d.ts +4 -0
- package/dist/source-security.d.ts.map +1 -0
- package/dist/source-security.js +56 -0
- package/dist/source-security.js.map +1 -0
- package/dist/source-text.d.ts +16 -0
- package/dist/source-text.d.ts.map +1 -1
- package/dist/source-text.js +46 -16
- package/dist/source-text.js.map +1 -1
- package/dist/toolchain-pins.d.ts.map +1 -1
- package/dist/toolchain-pins.js +2 -19
- package/dist/toolchain-pins.js.map +1 -1
- package/dist/version-policy.d.ts +7 -8
- package/dist/version-policy.d.ts.map +1 -1
- package/dist/version-policy.js +46 -26
- package/dist/version-policy.js.map +1 -1
- package/dist/vulnerability-policy.d.ts.map +1 -1
- package/dist/vulnerability-policy.js +1 -11
- package/dist/vulnerability-policy.js.map +1 -1
- package/dist/wiring-policy.d.ts.map +1 -1
- package/dist/wiring-policy.js +4 -1
- package/dist/wiring-policy.js.map +1 -1
- package/dist/wiring-violation.d.ts.map +1 -1
- package/dist/wiring-violation.js +1 -6
- package/dist/wiring-violation.js.map +1 -1
- package/dist/workspace-policy.d.ts.map +1 -1
- package/dist/workspace-policy.js +3 -9
- package/dist/workspace-policy.js.map +1 -1
- package/dist/yaml-blocks.d.ts +10 -0
- package/dist/yaml-blocks.d.ts.map +1 -1
- package/dist/yaml-blocks.js +20 -0
- package/dist/yaml-blocks.js.map +1 -1
- package/package.json +2 -2
- package/dist/url-safety.d.ts +0 -12
- package/dist/url-safety.d.ts.map +0 -1
- package/dist/url-safety.js +0 -58
- package/dist/url-safety.js.map +0 -1
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/** A page a project's file tree declares, and the address it answers at. */
|
|
2
|
+
export interface DeclaredRoute {
|
|
3
|
+
/** The file declaring it, relative to the member root. */
|
|
4
|
+
readonly file: string;
|
|
5
|
+
/** The address, with dynamic segments left in their file-tree spelling. */
|
|
6
|
+
readonly route: string;
|
|
7
|
+
/** Whether that address carries a dynamic segment, and so names a family rather than one page. */
|
|
8
|
+
readonly isDynamic: boolean;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Which directory holds the application's routes.
|
|
12
|
+
*
|
|
13
|
+
* Chosen from the conventional two rather than searched for, and confirmed by the root layout Next.js
|
|
14
|
+
* requires, so a library with a `src/app` module of its own is not mistaken for an application.
|
|
15
|
+
* @param paths every file of the member, relative to its root, separated by forward slashes.
|
|
16
|
+
* @returns the app directory, or nothing when the member declares no routes.
|
|
17
|
+
*/
|
|
18
|
+
export declare const appRootOf: (paths: readonly string[]) => string | undefined;
|
|
19
|
+
/**
|
|
20
|
+
* Strip a trailing slash, so an address written with one and an address written without are one.
|
|
21
|
+
*
|
|
22
|
+
* The crawl records whatever `URL.pathname` gave it and a link may be written either way, while a file
|
|
23
|
+
* tree never produces a trailing slash at all. Comparing the two without this reports every page of a
|
|
24
|
+
* project that sets `trailingSlash`.
|
|
25
|
+
* @param route the address to normalise.
|
|
26
|
+
* @returns the address without its trailing slash, and the root route unchanged.
|
|
27
|
+
*/
|
|
28
|
+
export declare const normalisedRoute: (route: string) => string;
|
|
29
|
+
/**
|
|
30
|
+
* The address one file answers at, if it declares a page at all.
|
|
31
|
+
* @param file the file, relative to the app directory.
|
|
32
|
+
* @returns the declared route, or nothing when the file declares no independently reachable address.
|
|
33
|
+
*/
|
|
34
|
+
export declare const declaredRouteOf: (file: string) => DeclaredRoute | undefined;
|
|
35
|
+
/**
|
|
36
|
+
* Every address a member's file tree declares.
|
|
37
|
+
*
|
|
38
|
+
* Deduplicated by address, because a parallel route's slot and the page beside it reduce to the same
|
|
39
|
+
* one and reporting it twice would ask a project to answer for the same page under two file names.
|
|
40
|
+
* @param paths every file of the member, relative to its root, separated by forward slashes.
|
|
41
|
+
* @param appRoot the app directory, as `appRootOf` chose it.
|
|
42
|
+
* @returns one entry per declared address, in the order the paths were given.
|
|
43
|
+
*/
|
|
44
|
+
export declare const declaredRoutesOf: (paths: readonly string[], appRoot: string) => readonly DeclaredRoute[];
|
|
45
|
+
/**
|
|
46
|
+
* The part of an address before its first dynamic segment.
|
|
47
|
+
*
|
|
48
|
+
* What a specification can be searched for when the address itself cannot be: a spec never contains
|
|
49
|
+
* `/posts/[slug]`, it contains `/posts/` and then a value.
|
|
50
|
+
* @param route the declared address.
|
|
51
|
+
* @returns the leading static part, which is the root route when the first segment is dynamic.
|
|
52
|
+
*/
|
|
53
|
+
export declare const staticPrefixOf: (route: string) => string;
|
|
54
|
+
/**
|
|
55
|
+
* Whether one visited address is a page the declared route produces.
|
|
56
|
+
*
|
|
57
|
+
* A static route matches itself. A dynamic one matches any address its segments admit, which is what
|
|
58
|
+
* lets the crawl answer for it: if the sweep scanned `/posts/hello`, the file behind `/posts/[slug]`
|
|
59
|
+
* has been scanned, whatever else it can also serve.
|
|
60
|
+
* @param route the declared address, dynamic segments in their file-tree spelling.
|
|
61
|
+
* @param visited an address the crawl reached.
|
|
62
|
+
* @returns true when scanning that address scanned this route.
|
|
63
|
+
*/
|
|
64
|
+
export declare const matchesRoute: (route: string, visited: string) => boolean;
|
|
65
|
+
//# sourceMappingURL=route-map.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"route-map.d.ts","sourceRoot":"","sources":["../src/route-map.ts"],"names":[],"mappings":"AAEA,4EAA4E;AAC5E,MAAM,WAAW,aAAa;IAC5B,0DAA0D;IAC1D,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,2EAA2E;IAC3E,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,kGAAkG;IAClG,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAA;CAC5B;AA8CD;;;;;;;GAOG;AACH,eAAO,MAAM,SAAS,GAAI,OAAO,SAAS,MAAM,EAAE,KAAG,MAAM,GAAG,SAG3D,CAAA;AAyBH;;;;;;;;GAQG;AACH,eAAO,MAAM,eAAe,GAAI,OAAO,MAAM,KAAG,MACoC,CAAA;AAEpF;;;;GAIG;AACH,eAAO,MAAM,eAAe,GAAI,MAAM,MAAM,KAAG,aAAa,GAAG,SAsB9D,CAAA;AAED;;;;;;;;GAQG;AACH,eAAO,MAAM,gBAAgB,GAC3B,OAAO,SAAS,MAAM,EAAE,EACxB,SAAS,MAAM,KACd,SAAS,aAAa,EAaxB,CAAA;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,cAAc,GAAI,OAAO,MAAM,KAAG,MAK9C,CAAA;AAmCD;;;;;;;;;GASG;AACH,eAAO,MAAM,YAAY,GAAI,OAAO,MAAM,EAAE,SAAS,MAAM,KAAG,OACL,CAAA"}
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
// Map Next.js route files to URL patterns for comparison with actual crawl results.
|
|
2
|
+
// Next.js reads a page from any of these; `pageExtensions` can add more, which is one of the reasons
|
|
3
|
+
// the module comment above declines to guess at a configured project.
|
|
4
|
+
const PAGE_FILES = new Set([
|
|
5
|
+
'page.tsx',
|
|
6
|
+
'page.ts',
|
|
7
|
+
'page.jsx',
|
|
8
|
+
'page.js',
|
|
9
|
+
'page.mdx',
|
|
10
|
+
]);
|
|
11
|
+
// A root layout is required of a Next.js application and of nothing else, so it is what tells an app
|
|
12
|
+
// directory apart from a directory that happens to be called `app`.
|
|
13
|
+
const ROOT_LAYOUTS = new Set([
|
|
14
|
+
'layout.tsx',
|
|
15
|
+
'layout.ts',
|
|
16
|
+
'layout.jsx',
|
|
17
|
+
'layout.js',
|
|
18
|
+
]);
|
|
19
|
+
// `src/app` first, because that is where a Payload application puts it and where a stray top-level
|
|
20
|
+
// `app/` is least likely to be mistaken for one.
|
|
21
|
+
const APP_ROOTS = ['src/app', 'app'];
|
|
22
|
+
const ROOT_ROUTE = '/';
|
|
23
|
+
const SEGMENT_SEPARATOR = '/';
|
|
24
|
+
// Whether a path is the ROOT layout of a candidate app directory. Next.js requires one, and allows it
|
|
25
|
+
// to sit inside route groups rather than at the top: a Payload application has no `src/app/layout.tsx`
|
|
26
|
+
// at all, because `(frontend)` and `(payload)` each carry their own. Requiring the top-level file
|
|
27
|
+
// found no app directory in the commonest project this harness governs, and the check then passed by
|
|
28
|
+
// doing nothing - which is the one way a rule like this fails that nobody notices.
|
|
29
|
+
const isRootLayout = (path, root) => {
|
|
30
|
+
const prefix = `${root}${SEGMENT_SEPARATOR}`;
|
|
31
|
+
if (!path.startsWith(prefix)) {
|
|
32
|
+
return false;
|
|
33
|
+
}
|
|
34
|
+
const segments = path.slice(prefix.length).split(SEGMENT_SEPARATOR);
|
|
35
|
+
const addressed = segments.filter((segment) => !isRouteGroup(segment));
|
|
36
|
+
return addressed.length === 1 && ROOT_LAYOUTS.has(addressed[0] ?? '');
|
|
37
|
+
};
|
|
38
|
+
/**
|
|
39
|
+
* Which directory holds the application's routes.
|
|
40
|
+
*
|
|
41
|
+
* Chosen from the conventional two rather than searched for, and confirmed by the root layout Next.js
|
|
42
|
+
* requires, so a library with a `src/app` module of its own is not mistaken for an application.
|
|
43
|
+
* @param paths every file of the member, relative to its root, separated by forward slashes.
|
|
44
|
+
* @returns the app directory, or nothing when the member declares no routes.
|
|
45
|
+
*/
|
|
46
|
+
export const appRootOf = (paths) => APP_ROOTS.find((root) => paths.some((path) => isRootLayout(path, root)));
|
|
47
|
+
// A segment wholly inside parentheses is a route group: it organises the tree and contributes nothing
|
|
48
|
+
// to the address. `(.)photo` is not one - it is an intercepting route, and it opens with a parenthesis
|
|
49
|
+
// without closing on one, which is exactly what tells the two apart.
|
|
50
|
+
const isRouteGroup = (segment) => segment.startsWith('(') && segment.endsWith(')');
|
|
51
|
+
// `(.)`, `(..)`, `(...)` and `(..)(..)`, each followed by the segment being intercepted. A file behind
|
|
52
|
+
// one of these declares no independently reachable address: on a hard navigation the INTERCEPTED route
|
|
53
|
+
// renders instead, and that route has a declaration of its own. So the file is skipped rather than
|
|
54
|
+
// mapped to an address no server serves.
|
|
55
|
+
const isIntercepting = (segment) => segment.startsWith('(') && !segment.endsWith(')');
|
|
56
|
+
// A slot of a parallel route. Its own `page` file is the slot's default content, rendered by the
|
|
57
|
+
// parent's layout rather than at an address of its own, so the segment is dropped and the address that
|
|
58
|
+
// results is the parent's - which the parent already declares, and which the dedup below collapses.
|
|
59
|
+
const isParallelSlot = (segment) => segment.startsWith('@');
|
|
60
|
+
// Next.js serves nothing from a folder whose name opens with an underscore.
|
|
61
|
+
const isPrivate = (segment) => segment.startsWith('_');
|
|
62
|
+
const isDynamicSegment = (segment) => segment.startsWith('[') && segment.endsWith(']');
|
|
63
|
+
/**
|
|
64
|
+
* Strip a trailing slash, so an address written with one and an address written without are one.
|
|
65
|
+
*
|
|
66
|
+
* The crawl records whatever `URL.pathname` gave it and a link may be written either way, while a file
|
|
67
|
+
* tree never produces a trailing slash at all. Comparing the two without this reports every page of a
|
|
68
|
+
* project that sets `trailingSlash`.
|
|
69
|
+
* @param route the address to normalise.
|
|
70
|
+
* @returns the address without its trailing slash, and the root route unchanged.
|
|
71
|
+
*/
|
|
72
|
+
export const normalisedRoute = (route) => route.length > 1 && route.endsWith(SEGMENT_SEPARATOR) ? route.slice(0, -1) : route;
|
|
73
|
+
/**
|
|
74
|
+
* The address one file answers at, if it declares a page at all.
|
|
75
|
+
* @param file the file, relative to the app directory.
|
|
76
|
+
* @returns the declared route, or nothing when the file declares no independently reachable address.
|
|
77
|
+
*/
|
|
78
|
+
export const declaredRouteOf = (file) => {
|
|
79
|
+
const parts = file.split(SEGMENT_SEPARATOR);
|
|
80
|
+
if (!PAGE_FILES.has(parts.at(-1) ?? '')) {
|
|
81
|
+
return undefined;
|
|
82
|
+
}
|
|
83
|
+
const directories = parts.slice(0, -1);
|
|
84
|
+
if (directories.some((segment) => isPrivate(segment) || isIntercepting(segment))) {
|
|
85
|
+
return undefined;
|
|
86
|
+
}
|
|
87
|
+
const addressed = directories.filter((segment) => !(isRouteGroup(segment) || isParallelSlot(segment)));
|
|
88
|
+
return {
|
|
89
|
+
file,
|
|
90
|
+
route: addressed.length === 0
|
|
91
|
+
? ROOT_ROUTE
|
|
92
|
+
: `${SEGMENT_SEPARATOR}${addressed.join(SEGMENT_SEPARATOR)}`,
|
|
93
|
+
isDynamic: addressed.some((segment) => isDynamicSegment(segment)),
|
|
94
|
+
};
|
|
95
|
+
};
|
|
96
|
+
/**
|
|
97
|
+
* Every address a member's file tree declares.
|
|
98
|
+
*
|
|
99
|
+
* Deduplicated by address, because a parallel route's slot and the page beside it reduce to the same
|
|
100
|
+
* one and reporting it twice would ask a project to answer for the same page under two file names.
|
|
101
|
+
* @param paths every file of the member, relative to its root, separated by forward slashes.
|
|
102
|
+
* @param appRoot the app directory, as `appRootOf` chose it.
|
|
103
|
+
* @returns one entry per declared address, in the order the paths were given.
|
|
104
|
+
*/
|
|
105
|
+
export const declaredRoutesOf = (paths, appRoot) => {
|
|
106
|
+
const prefix = `${appRoot}${SEGMENT_SEPARATOR}`;
|
|
107
|
+
const declared = paths.flatMap((file) => {
|
|
108
|
+
if (!file.startsWith(prefix)) {
|
|
109
|
+
return [];
|
|
110
|
+
}
|
|
111
|
+
const found = declaredRouteOf(file.slice(prefix.length));
|
|
112
|
+
return found === undefined ? [] : [{ ...found, file }];
|
|
113
|
+
});
|
|
114
|
+
return declared.filter((route, index) => declared.findIndex((other) => other.route === route.route) === index);
|
|
115
|
+
};
|
|
116
|
+
/**
|
|
117
|
+
* The part of an address before its first dynamic segment.
|
|
118
|
+
*
|
|
119
|
+
* What a specification can be searched for when the address itself cannot be: a spec never contains
|
|
120
|
+
* `/posts/[slug]`, it contains `/posts/` and then a value.
|
|
121
|
+
* @param route the declared address.
|
|
122
|
+
* @returns the leading static part, which is the root route when the first segment is dynamic.
|
|
123
|
+
*/
|
|
124
|
+
export const staticPrefixOf = (route) => {
|
|
125
|
+
const segments = route.split(SEGMENT_SEPARATOR).slice(1);
|
|
126
|
+
const upTo = segments.findIndex((segment) => isDynamicSegment(segment));
|
|
127
|
+
const kept = upTo === -1 ? segments : segments.slice(0, upTo);
|
|
128
|
+
return kept.length === 0 ? ROOT_ROUTE : `${SEGMENT_SEPARATOR}${kept.join(SEGMENT_SEPARATOR)}`;
|
|
129
|
+
};
|
|
130
|
+
// An address as the segments it is made of, with the leading slash and any trailing one gone. The root
|
|
131
|
+
// route is no segments at all, which is what lets an optional catch-all match it.
|
|
132
|
+
const segmentsOf = (route) => normalisedRoute(route)
|
|
133
|
+
.split(SEGMENT_SEPARATOR)
|
|
134
|
+
.filter((segment) => segment !== '');
|
|
135
|
+
const isCatchAll = (segment) => segment.startsWith('[...') && segment.endsWith(']');
|
|
136
|
+
const isOptionalCatchAll = (segment) => segment.startsWith('[[...') && segment.endsWith(']]');
|
|
137
|
+
// Segment by segment, because a catch-all is the only one whose width is not one and Next.js allows it
|
|
138
|
+
// only in the last position. Written as a recursion rather than a regular expression: the address a
|
|
139
|
+
// project declares is attacker-adjacent text in no sense, but a pattern built by concatenation is one
|
|
140
|
+
// nobody can read afterwards, and the whole point of this module is that its edge cases are legible.
|
|
141
|
+
const matchesSegments = (pattern, actual) => {
|
|
142
|
+
const [head, ...rest] = pattern;
|
|
143
|
+
if (head === undefined) {
|
|
144
|
+
return actual.length === 0;
|
|
145
|
+
}
|
|
146
|
+
if (isOptionalCatchAll(head)) {
|
|
147
|
+
return true;
|
|
148
|
+
}
|
|
149
|
+
if (isCatchAll(head)) {
|
|
150
|
+
return actual.length > 0;
|
|
151
|
+
}
|
|
152
|
+
if (isDynamicSegment(head)) {
|
|
153
|
+
return actual.length > 0 && matchesSegments(rest, actual.slice(1));
|
|
154
|
+
}
|
|
155
|
+
return actual[0] === head && matchesSegments(rest, actual.slice(1));
|
|
156
|
+
};
|
|
157
|
+
/**
|
|
158
|
+
* Whether one visited address is a page the declared route produces.
|
|
159
|
+
*
|
|
160
|
+
* A static route matches itself. A dynamic one matches any address its segments admit, which is what
|
|
161
|
+
* lets the crawl answer for it: if the sweep scanned `/posts/hello`, the file behind `/posts/[slug]`
|
|
162
|
+
* has been scanned, whatever else it can also serve.
|
|
163
|
+
* @param route the declared address, dynamic segments in their file-tree spelling.
|
|
164
|
+
* @param visited an address the crawl reached.
|
|
165
|
+
* @returns true when scanning that address scanned this route.
|
|
166
|
+
*/
|
|
167
|
+
export const matchesRoute = (route, visited) => matchesSegments(segmentsOf(route), segmentsOf(visited));
|
|
168
|
+
//# sourceMappingURL=route-map.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"route-map.js","sourceRoot":"","sources":["../src/route-map.ts"],"names":[],"mappings":"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"}
|
package/dist/run-plan.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"run-plan.d.ts","sourceRoot":"","sources":["../src/run-plan.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"run-plan.d.ts","sourceRoot":"","sources":["../src/run-plan.ts"],"names":[],"mappings":"AAEA,+CAA+C;AAC/C,MAAM,MAAM,SAAS,GAAG,YAAY,GAAG,SAAS,GAAG,SAAS,CAAA;AAE5D,0DAA0D;AAC1D,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;IACnB,QAAQ,CAAC,KAAK,EAAE,SAAS,CAAA;IACzB,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAA;CAC7B;AAED,qEAAqE;AACrE,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAA;CAC5B;AAED,qFAAqF;AACrF,MAAM,WAAW,QAAQ;IACvB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,mEAAmE;IACnE,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAA;CACpC;AAuBD;;;;;;;;;;GAUG;AACH,eAAO,MAAM,SAAS,GACpB,OAAO,SAAS,cAAc,EAAE,EAChC,SAAS,SAAS,gBAAgB,EAAE,EACpC,YAAY,OAAO,KAClB,SAAS,QAAQ,EAGgE,CAAA"}
|
package/dist/run-plan.js
CHANGED
|
@@ -1,22 +1,4 @@
|
|
|
1
|
-
//
|
|
2
|
-
//
|
|
3
|
-
// The order is a rule, not an implementation detail: it decides which finding a project sees first, and
|
|
4
|
-
// the reasoning behind it is stated in the guide - the structural gates that catch a mis-wired project
|
|
5
|
-
// run before the analyzers whose output is harder to read, the tracked-tree fingerprint brackets
|
|
6
|
-
// everything that could rewrite a file, and the two preconditions lead because a survey of findings
|
|
7
|
-
// below either would be a list of verdicts about nothing.
|
|
8
|
-
//
|
|
9
|
-
// Registry order IS run order, and this module deliberately adds no second ordering rule on top of it.
|
|
10
|
-
// Grouping the run by member instead - every gate for one member, then the next - reads better in a
|
|
11
|
-
// multi-member report, and it was the first design here. It was dropped because it also reorders a
|
|
12
|
-
// SINGLE-member run, which is every consumer that exists today: `conventions` would overtake `eslint`,
|
|
13
|
-
// the container gates would move to the end, and a project's first finding could change without one
|
|
14
|
-
// rule changing. Making workspaces work is not a licence to renumber the run for projects that have no
|
|
15
|
-
// workspace. A repository with one member therefore produces exactly the sequence that shipped before
|
|
16
|
-
// members existed, and that equality is pinned by a spec rather than argued.
|
|
17
|
-
//
|
|
18
|
-
// The cost is that a multi-member run interleaves members gate by gate. The report layer answers that by
|
|
19
|
-
// labelling each step with its member, which costs a single-member run nothing because it has none.
|
|
1
|
+
// Expand gates in registry order across their applicable members; tree verification remains last.
|
|
20
2
|
// A package-scope gate asks about every member; a payload-scope gate asks only about the members that
|
|
21
3
|
// are Payload applications. Derived from what the member declares rather than from anything it opts
|
|
22
4
|
// into, so a project cannot silence the Payload rules by describing itself differently.
|
package/dist/run-plan.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"run-plan.js","sourceRoot":"","sources":["../src/run-plan.ts"],"names":[],"mappings":"AAAA,
|
|
1
|
+
{"version":3,"file":"run-plan.js","sourceRoot":"","sources":["../src/run-plan.ts"],"names":[],"mappings":"AAAA,kGAAkG;AAyBlG,sGAAsG;AACtG,oGAAoG;AACpG,wFAAwF;AACxF,MAAM,UAAU,GAAG,CACjB,IAAoB,EACpB,OAAoC,EACP,EAAE,CAC/B,IAAI,CAAC,KAAK,KAAK,SAAS;IACtB,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,MAAwB,EAAW,EAAE,CAAC,MAAM,CAAC,SAAS,CAAC;IACzE,CAAC,CAAC,OAAO,CAAA;AAEb,MAAM,QAAQ,GAAG,CACf,IAAoB,EACpB,OAAoC,EACf,EAAE,CACvB,IAAI,CAAC,KAAK,KAAK,YAAY;IACzB,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC;IAC1C,CAAC,CAAC,UAAU,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,GAAG,CAC3B,CAAC,MAAwB,EAAY,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,CAAC,IAAI,EAAE,CAAC,CACnF,CAAA;AAEP;;;;;;;;;;GAUG;AACH,MAAM,CAAC,MAAM,SAAS,GAAG,CACvB,KAAgC,EAChC,OAAoC,EACpC,UAAmB,EACE,EAAE,CACvB,KAAK;KACF,MAAM,CAAC,CAAC,IAAoB,EAAW,EAAE,CAAC,UAAU,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC;KACzE,OAAO,CAAC,CAAC,IAAoB,EAAuB,EAAE,CAAC,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"secret-policy.d.ts","sourceRoot":"","sources":["../src/secret-policy.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"secret-policy.d.ts","sourceRoot":"","sources":["../src/secret-policy.ts"],"names":[],"mappings":"AAGA,qEAAqE;AACrE,MAAM,WAAW,eAAe;IAC9B,uDAAuD;IACvD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CACxB;AA2CD;;;;GAIG;AACH,eAAO,MAAM,oBAAoB,GAAI,YAAY,SAAS,eAAe,EAAE,KAAG,MAiB7E,CAAA"}
|
package/dist/secret-policy.js
CHANGED
|
@@ -1,14 +1,4 @@
|
|
|
1
|
-
//
|
|
2
|
-
//
|
|
3
|
-
// The standard requires a repository to list every fake credential it commits as a test fixture, and
|
|
4
|
-
// requires the secret scan to fail on anything outside that list. Until now there was no way to satisfy
|
|
5
|
-
// both: `.gitleaks.toml` is a forbidden managed path, precisely so a project cannot weaken the scanner's
|
|
6
|
-
// own rules, and no setting replaced it. A project with a fixture credential could not pass at all.
|
|
7
|
-
//
|
|
8
|
-
// The resolution keeps the file forbidden and makes the allowlist data instead. ploaness renders the
|
|
9
|
-
// scanner's configuration itself, outside the working tree, from entries the project declares. The
|
|
10
|
-
// rendered config always extends the tool's default rules, so a declared entry can only add a named
|
|
11
|
-
// exception and can never replace or disable what the scanner already looks for.
|
|
1
|
+
// Allow declared fake credentials without replacing scanner rules or narrowing unrelated files.
|
|
12
2
|
import { escapeForRegex } from './text-escapes.js';
|
|
13
3
|
// The characters a TOML basic string cannot carry literally: its two delimiters, and every control
|
|
14
4
|
// character. Named by code point rather than written out, for the reason `banned-typography.ts` gives:
|
|
@@ -24,15 +14,15 @@ const NAMED_ESCAPES = new Map([
|
|
|
24
14
|
['\r', String.raw `\r`],
|
|
25
15
|
['\t', String.raw `\t`],
|
|
26
16
|
]);
|
|
27
|
-
//
|
|
28
|
-
//
|
|
29
|
-
// a branch no input can reach.
|
|
17
|
+
// `?? Number.NaN` rather than an `undefined` branch: `codePointAt` is typed as possibly undefined, but
|
|
18
|
+
// the caller spreads a string into code points so no character here is empty. NaN keeps the comparison
|
|
19
|
+
// below false, so the character passes through as itself without a branch no input can reach.
|
|
30
20
|
const escapeCharacter = (character) => {
|
|
31
21
|
const named = NAMED_ESCAPES.get(character);
|
|
32
22
|
if (named !== undefined) {
|
|
33
23
|
return named;
|
|
34
24
|
}
|
|
35
|
-
const codePoint =
|
|
25
|
+
const codePoint = character.codePointAt(0) ?? Number.NaN;
|
|
36
26
|
return codePoint < FIRST_PRINTABLE ? String.raw `\u${asHex(codePoint)}` : character;
|
|
37
27
|
};
|
|
38
28
|
// A basic TOML string, which is the only string form that escapes anything. Both fields go through it.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"secret-policy.js","sourceRoot":"","sources":["../src/secret-policy.ts"],"names":[],"mappings":"AAAA,
|
|
1
|
+
{"version":3,"file":"secret-policy.js","sourceRoot":"","sources":["../src/secret-policy.ts"],"names":[],"mappings":"AAAA,gGAAgG;AAChG,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAA;AASlD,mGAAmG;AACnG,uGAAuG;AACvG,wFAAwF;AACxF,MAAM,eAAe,GAAW,IAAI,CAAA;AACpC,MAAM,SAAS,GAAW,EAAE,CAAA;AAC5B,MAAM,qBAAqB,GAAW,CAAC,CAAA;AAEvC,MAAM,KAAK,GAAG,CAAC,SAAiB,EAAU,EAAE,CAC1C,SAAS,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,QAAQ,CAAC,qBAAqB,EAAE,GAAG,CAAC,CAAA;AAEpE,MAAM,aAAa,GAAgC,IAAI,GAAG,CAAC;IACzD,CAAC,IAAI,EAAE,MAAM,CAAC;IACd,CAAC,GAAG,EAAE,MAAM,CAAC,GAAG,CAAA,IAAI,CAAC;IACrB,CAAC,IAAI,EAAE,MAAM,CAAC,GAAG,CAAA,IAAI,CAAC;IACtB,CAAC,IAAI,EAAE,MAAM,CAAC,GAAG,CAAA,IAAI,CAAC;IACtB,CAAC,IAAI,EAAE,MAAM,CAAC,GAAG,CAAA,IAAI,CAAC;CACvB,CAAC,CAAA;AAEF,uGAAuG;AACvG,uGAAuG;AACvG,8FAA8F;AAC9F,MAAM,eAAe,GAAG,CAAC,SAAiB,EAAU,EAAE;IACpD,MAAM,KAAK,GAAuB,aAAa,CAAC,GAAG,CAAC,SAAS,CAAC,CAAA;IAC9D,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QACxB,OAAO,KAAK,CAAA;IACd,CAAC;IACD,MAAM,SAAS,GAAW,SAAS,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,MAAM,CAAC,GAAG,CAAA;IAChE,OAAO,SAAS,GAAG,eAAe,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAA,KAAK,KAAK,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,CAAA;AACpF,CAAC,CAAA;AAED,uGAAuG;AACvG,EAAE;AACF,oGAAoG;AACpG,mGAAmG;AACnG,kGAAkG;AAClG,mGAAmG;AACnG,MAAM,aAAa,GAAG,CAAC,KAAa,EAAU,EAAE;AAC9C,iGAAiG;AACjG,sFAAsF;AACtF,CAAC,GAAG,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,SAAiB,EAAU,EAAE,CAAC,eAAe,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;AAEpF;;;;GAIG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,UAAsC,EAAU,EAAE;IACrF,MAAM,MAAM,GAAW;QACrB,mGAAmG;QACnG,2EAA2E;QAC3E,UAAU;QACV,mBAAmB;QACnB,EAAE;KACH,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IACZ,MAAM,MAAM,GAAsB,UAAU,CAAC,GAAG,CAAC,CAAC,SAA0B,EAAU,EAAE,CACtF;QACE,gBAAgB;QAChB,kBAAkB,aAAa,CAAC,SAAS,CAAC,MAAM,CAAC,GAAG;QACpD,cAAc,aAAa,CAAC,cAAc,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,KAAK;QAChE,EAAE;KACH,CAAC,IAAI,CAAC,IAAI,CAAC,CACb,CAAA;IACD,OAAO,CAAC,MAAM,EAAE,GAAG,MAAM,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;AACvC,CAAC,CAAA"}
|
|
@@ -7,39 +7,17 @@ import { type DeclaredExclusion, type Settings } from './settings.js';
|
|
|
7
7
|
*/
|
|
8
8
|
export declare const layerSettingBlocks: (base: Record<string, unknown>, overlay: Record<string, unknown>) => Record<string, unknown>;
|
|
9
9
|
/**
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
* when the repository-scope gate walks past `apps/web/src/generated/`, and a generated directory a
|
|
15
|
-
* project correctly excused starts failing the typography ban.
|
|
16
|
-
*
|
|
17
|
-
* An UNANCHORED pattern is left alone, deliberately. `importMap\.js$` already matches at any depth, and
|
|
18
|
-
* prefixing it would narrow it to one member - so the rule errs toward a pattern that matches too much
|
|
19
|
-
* at repository scope rather than one that silently stops matching. Too wide is the safe direction here:
|
|
20
|
-
* a repository-scope gate that skips one extra path reports one fewer finding, while a narrowed pattern
|
|
21
|
-
* reports a project for a file it had already accounted for.
|
|
22
|
-
* @param memberPath the member's repo-relative path, `.` for the member at the root.
|
|
23
|
-
* @param entry the exclusion as the member declared it.
|
|
24
|
-
* @returns the exclusion as the repository-scope gates must read it.
|
|
10
|
+
* Preserve a regex's package-relative meaning when repository gates read member exclusions.
|
|
11
|
+
* @param memberPath the declaring package's repository-relative path.
|
|
12
|
+
* @param entry the original exclusion.
|
|
13
|
+
* @returns a scoped regex, a rebased glob, or the unchanged root/route declaration.
|
|
25
14
|
*/
|
|
26
15
|
export declare const rebaseExclusion: (memberPath: string, entry: DeclaredExclusion) => DeclaredExclusion;
|
|
27
16
|
/**
|
|
28
|
-
*
|
|
29
|
-
*
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
-
* decisions THIS package made, and every consumer of it judges the declarer. Layering it made a member
|
|
33
|
-
* answer for the repository's declarations, so a workspace root that correctly excused its Vale detector
|
|
34
|
-
* definitions - whose content IS the character the ban detects - had every member report that exclusion
|
|
35
|
-
* as reaching nothing, because no member contains the file. One correct declaration, two gates failed,
|
|
36
|
-
* and nothing a member could edit would have fixed it.
|
|
37
|
-
*
|
|
38
|
-
* The mirror direction was already handled: `rebaseExclusion` moves a member's exclusion up into the
|
|
39
|
-
* repository's path space. This is the same seam read downward.
|
|
40
|
-
* @param repositoryBlock the raw `ploaness` block of the repository root.
|
|
41
|
-
* @param ownBlock the raw `ploaness` block of the member itself.
|
|
42
|
-
* @returns the member's settings, inheriting values and owning declarations.
|
|
17
|
+
* Inherit effective values while retaining only the member's own declarations for reach checks.
|
|
18
|
+
* @param repositoryBlock the root settings before defaults.
|
|
19
|
+
* @param ownBlock the member settings before defaults.
|
|
20
|
+
* @returns effective settings and the member's declared exclusions.
|
|
43
21
|
*/
|
|
44
22
|
export declare const readMemberSettings: (repositoryBlock: Record<string, unknown>, ownBlock: Record<string, unknown>) => Settings;
|
|
45
23
|
//# sourceMappingURL=settings-layering.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"settings-layering.d.ts","sourceRoot":"","sources":["../src/settings-layering.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"settings-layering.d.ts","sourceRoot":"","sources":["../src/settings-layering.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,iBAAiB,EAAmB,KAAK,QAAQ,EAAE,MAAM,eAAe,CAAA;AAoEtF;;;;;GAKG;AACH,eAAO,MAAM,kBAAkB,GAC7B,MAAM,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAC/B,MAAM,CAAC,MAAM,EAAE,OAAO,CAUxB,CAAA;AAED;;;;;GAKG;AACH,eAAO,MAAM,eAAe,GAC1B,YAAY,MAAM,EAClB,OAAO,iBAAiB,KACvB,iBAWF,CAAA;AAED;;;;;GAKG;AACH,eAAO,MAAM,kBAAkB,GAC7B,iBAAiB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACxC,UAAU,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAChC,QAGD,CAAA"}
|
|
@@ -1,13 +1,4 @@
|
|
|
1
|
-
//
|
|
2
|
-
//
|
|
3
|
-
// A workspace declares some facts once and some per package. Which is which is not uniform, and reading
|
|
4
|
-
// it wrong is silent either way: concatenating two `pretest` commands would run a mangled argv, while
|
|
5
|
-
// letting a member REPLACE `sourceRoots` would narrow the scope the harness refuses to narrow.
|
|
6
|
-
//
|
|
7
|
-
// Layering happens on the RAW blocks, before any default is applied. Merging defaulted objects instead
|
|
8
|
-
// would make "declared nothing" indistinguishable from "declared exactly the default", so a repository
|
|
9
|
-
// that declared a stricter bundle budget would be silently overwritten by every member that declared
|
|
10
|
-
// none.
|
|
1
|
+
// Layer raw declarations before defaults, preserving inherited constraints and each member's ownership.
|
|
11
2
|
import { asRecord, isArray } from './json-shapes.js';
|
|
12
3
|
import { readRawSettings } from './settings.js';
|
|
13
4
|
/** Keys where a member ADDS to what the repository declared, the way `sourceRoots` always has. */
|
|
@@ -23,6 +14,7 @@ const ADDITIVE = new Set([
|
|
|
23
14
|
'auxiliaryServers',
|
|
24
15
|
'accessibilitySkipRoutes',
|
|
25
16
|
'frameworkGlue',
|
|
17
|
+
'generatedArtefacts',
|
|
26
18
|
'pureLogicRoots',
|
|
27
19
|
]);
|
|
28
20
|
// Keys where only a smaller number is honoured. A member may hold itself to more than the repository
|
|
@@ -44,18 +36,21 @@ const mergeArrays = (base, overlay) => [
|
|
|
44
36
|
...(isArray(base) ? base : []),
|
|
45
37
|
...(isArray(overlay) ? overlay : []),
|
|
46
38
|
];
|
|
47
|
-
const
|
|
48
|
-
|
|
49
|
-
|
|
39
|
+
const isValidCeiling = (key, value) => typeof value === 'number' &&
|
|
40
|
+
Number.isSafeInteger(value) &&
|
|
41
|
+
(key === 'maxSuppressions' ? value >= 0 : value > 0);
|
|
42
|
+
const smaller = (key, base, overlay) => {
|
|
43
|
+
if (!isValidCeiling(key, base)) {
|
|
44
|
+
return isValidCeiling(key, overlay) ? overlay : undefined;
|
|
50
45
|
}
|
|
51
|
-
return
|
|
46
|
+
return isValidCeiling(key, overlay) ? Math.min(base, overlay) : base;
|
|
52
47
|
};
|
|
53
48
|
const mergeValue = (key, base, overlay) => {
|
|
54
49
|
if (ADDITIVE.has(key)) {
|
|
55
50
|
return mergeArrays(base, overlay);
|
|
56
51
|
}
|
|
57
52
|
if (STRICTEST_NUMBER.has(key)) {
|
|
58
|
-
return smaller(base, overlay);
|
|
53
|
+
return smaller(key, base, overlay);
|
|
59
54
|
}
|
|
60
55
|
if (REPLACED.has(key)) {
|
|
61
56
|
return overlay ?? base;
|
|
@@ -80,21 +75,10 @@ export const layerSettingBlocks = (base, overlay) => {
|
|
|
80
75
|
]));
|
|
81
76
|
};
|
|
82
77
|
/**
|
|
83
|
-
*
|
|
84
|
-
*
|
|
85
|
-
*
|
|
86
|
-
*
|
|
87
|
-
* when the repository-scope gate walks past `apps/web/src/generated/`, and a generated directory a
|
|
88
|
-
* project correctly excused starts failing the typography ban.
|
|
89
|
-
*
|
|
90
|
-
* An UNANCHORED pattern is left alone, deliberately. `importMap\.js$` already matches at any depth, and
|
|
91
|
-
* prefixing it would narrow it to one member - so the rule errs toward a pattern that matches too much
|
|
92
|
-
* at repository scope rather than one that silently stops matching. Too wide is the safe direction here:
|
|
93
|
-
* a repository-scope gate that skips one extra path reports one fewer finding, while a narrowed pattern
|
|
94
|
-
* reports a project for a file it had already accounted for.
|
|
95
|
-
* @param memberPath the member's repo-relative path, `.` for the member at the root.
|
|
96
|
-
* @param entry the exclusion as the member declared it.
|
|
97
|
-
* @returns the exclusion as the repository-scope gates must read it.
|
|
78
|
+
* Preserve a regex's package-relative meaning when repository gates read member exclusions.
|
|
79
|
+
* @param memberPath the declaring package's repository-relative path.
|
|
80
|
+
* @param entry the original exclusion.
|
|
81
|
+
* @returns a scoped regex, a rebased glob, or the unchanged root/route declaration.
|
|
98
82
|
*/
|
|
99
83
|
export const rebaseExclusion = (memberPath, entry) => {
|
|
100
84
|
if (memberPath === '.') {
|
|
@@ -106,26 +90,13 @@ export const rebaseExclusion = (memberPath, entry) => {
|
|
|
106
90
|
if (entry.kind === 'glob') {
|
|
107
91
|
return { ...entry, pattern: `${memberPath}/${entry.pattern}` };
|
|
108
92
|
}
|
|
109
|
-
return entry
|
|
110
|
-
? { ...entry, pattern: `^${memberPath}/${entry.pattern.slice(1)}` }
|
|
111
|
-
: entry;
|
|
93
|
+
return { ...entry, memberPath };
|
|
112
94
|
};
|
|
113
95
|
/**
|
|
114
|
-
*
|
|
115
|
-
*
|
|
116
|
-
*
|
|
117
|
-
*
|
|
118
|
-
* decisions THIS package made, and every consumer of it judges the declarer. Layering it made a member
|
|
119
|
-
* answer for the repository's declarations, so a workspace root that correctly excused its Vale detector
|
|
120
|
-
* definitions - whose content IS the character the ban detects - had every member report that exclusion
|
|
121
|
-
* as reaching nothing, because no member contains the file. One correct declaration, two gates failed,
|
|
122
|
-
* and nothing a member could edit would have fixed it.
|
|
123
|
-
*
|
|
124
|
-
* The mirror direction was already handled: `rebaseExclusion` moves a member's exclusion up into the
|
|
125
|
-
* repository's path space. This is the same seam read downward.
|
|
126
|
-
* @param repositoryBlock the raw `ploaness` block of the repository root.
|
|
127
|
-
* @param ownBlock the raw `ploaness` block of the member itself.
|
|
128
|
-
* @returns the member's settings, inheriting values and owning declarations.
|
|
96
|
+
* Inherit effective values while retaining only the member's own declarations for reach checks.
|
|
97
|
+
* @param repositoryBlock the root settings before defaults.
|
|
98
|
+
* @param ownBlock the member settings before defaults.
|
|
99
|
+
* @returns effective settings and the member's declared exclusions.
|
|
129
100
|
*/
|
|
130
101
|
export const readMemberSettings = (repositoryBlock, ownBlock) => ({
|
|
131
102
|
...readRawSettings(layerSettingBlocks(repositoryBlock, ownBlock)),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"settings-layering.js","sourceRoot":"","sources":["../src/settings-layering.ts"],"names":[],"mappings":"AAAA,
|
|
1
|
+
{"version":3,"file":"settings-layering.js","sourceRoot":"","sources":["../src/settings-layering.ts"],"names":[],"mappings":"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"}
|
package/dist/settings.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type RolePattern } from './file-roles.js';
|
|
1
2
|
import type { SecretException } from './secret-policy.js';
|
|
2
3
|
import type { VulnerabilityException } from './vulnerability-policy.js';
|
|
3
4
|
/**
|
|
@@ -8,6 +9,8 @@ import type { VulnerabilityException } from './vulnerability-policy.js';
|
|
|
8
9
|
export type ExclusionKind = 'regex' | 'glob' | 'route';
|
|
9
10
|
/** One exclusion a project declared, and the file role it claims. */
|
|
10
11
|
export interface DeclaredExclusion {
|
|
12
|
+
/** Internal scope retained when a repository gate reads a member-owned regex. */
|
|
13
|
+
readonly memberPath?: string;
|
|
11
14
|
/** Which setting it came from, so a finding can name it. */
|
|
12
15
|
readonly setting: string;
|
|
13
16
|
readonly pattern: string;
|
|
@@ -29,6 +32,20 @@ export interface PublicAccess {
|
|
|
29
32
|
/** The operation granted: create, read, update, or delete. */
|
|
30
33
|
readonly operation: string;
|
|
31
34
|
readonly reason: string;
|
|
35
|
+
/**
|
|
36
|
+
* The fields of that entity a stranger reaches through this operation, each named by the path that
|
|
37
|
+
* reaches it (`sessions.id`), and `*` for the map Payload collapsed because every field was open.
|
|
38
|
+
*
|
|
39
|
+
* One entry carries the whole list rather than one entry per field, because a public collection has
|
|
40
|
+
* as many readable fields as it has columns and a list of twelve declarations sharing one reason is
|
|
41
|
+
* a list nobody rereads. A field absent from the list is undeclared, so adding a column to a public
|
|
42
|
+
* collection reopens the finding, which is the moment worth stopping at.
|
|
43
|
+
*
|
|
44
|
+
* A path ending in `.**` (`sizes.**`) declares that group and every field beneath it, including one
|
|
45
|
+
* added there later, which is the trade that form makes; `**` anywhere else is a literal name that
|
|
46
|
+
* matches nothing.
|
|
47
|
+
*/
|
|
48
|
+
readonly fields?: readonly string[];
|
|
32
49
|
}
|
|
33
50
|
/** A managed path a project has taken over from the catalogue, with the reason it did so. */
|
|
34
51
|
export interface UnmanagedAsset {
|
|
@@ -65,7 +82,7 @@ export interface Settings {
|
|
|
65
82
|
/** Managed paths the project owns instead, each with a recorded reason. */
|
|
66
83
|
readonly unmanagedAssets: readonly UnmanagedAsset[];
|
|
67
84
|
/** Repo-relative path patterns exempt from the typography ban (generated files only). */
|
|
68
|
-
readonly typographyExclusions: readonly
|
|
85
|
+
readonly typographyExclusions: readonly RolePattern[];
|
|
69
86
|
/**
|
|
70
87
|
* Paths holding framework-generated scaffolding, which the lint pass relaxes rather than judges.
|
|
71
88
|
*
|
|
@@ -97,7 +114,7 @@ export interface Settings {
|
|
|
97
114
|
/** Every exclusion the project declared, honoured or not, so a gate can judge them. */
|
|
98
115
|
readonly declaredExclusions: readonly DeclaredExclusion[];
|
|
99
116
|
/** Repo-relative path patterns exempt from the hand-written-JavaScript ban. */
|
|
100
|
-
readonly javascriptAllowlist: readonly
|
|
117
|
+
readonly javascriptAllowlist: readonly RolePattern[];
|
|
101
118
|
/** Glob patterns excluded from coverage measurement, by role rather than by convenience. */
|
|
102
119
|
readonly coverageExclude: readonly string[];
|
|
103
120
|
/** Ceiling for total gzipped client JavaScript, in bytes. */
|
package/dist/settings.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"settings.d.ts","sourceRoot":"","sources":["../src/settings.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"settings.d.ts","sourceRoot":"","sources":["../src/settings.ts"],"names":[],"mappings":"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"}
|
package/dist/settings.js
CHANGED
|
@@ -161,8 +161,12 @@ const asPublicAccess = (raw) => isArray(raw)
|
|
|
161
161
|
const entity = asText(record['entity']).trim();
|
|
162
162
|
const operation = asText(record['operation']).trim();
|
|
163
163
|
const reason = asText(record['reason']).trim();
|
|
164
|
+
// `fields` is optional, so a malformed one falls back to declaring no field rather than
|
|
165
|
+
// dropping the entry: the entity-level grant it also carries was stated correctly, and
|
|
166
|
+
// discarding that would report a finding the project did answer.
|
|
167
|
+
const fields = asStringArray(record['fields'], []);
|
|
164
168
|
return entity.length > 0 && operation.length > 0 && reason.length > 0
|
|
165
|
-
? [{ entity, operation, reason }]
|
|
169
|
+
? [{ entity, operation, reason, fields }]
|
|
166
170
|
: [];
|
|
167
171
|
})
|
|
168
172
|
: [];
|