@fairfox/polly 0.40.0 → 0.47.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.
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Additional checks bundled into `pollyCorePlugin`.
3
+ *
4
+ * Each check here is a port of an existing `scripts/check-*.ts` script
5
+ * from polly's repo into the plugin contract. The original scripts
6
+ * remain on disk for back-compat with the existing pre-commit
7
+ * orchestrator (`scripts/check.ts`); the plugin path is the new way
8
+ * for downstream consumers (lingua, fairfox, warehouse-experiments)
9
+ * who do not want to copy the script verbatim.
10
+ *
11
+ * Out of scope for this release:
12
+ * - `polly:boundaries` issue text describes a workspace-dependency
13
+ * model (each package may only import from packages it lists in
14
+ * its `dependencies`). Polly itself is a single-package repo and
15
+ * uses directional zone bans (`src/` cannot import `tools/`,
16
+ * etc.); that model is what ships here. The workspace-dep model
17
+ * can be layered on as an additional configuration mode later.
18
+ */
19
+ import type { Check } from "../types";
20
+ export declare const additionalCoreChecks: Check<unknown>[];
@@ -0,0 +1,18 @@
1
+ /**
2
+ * `pollyCorePlugin` — the polly-provided core plugin.
3
+ *
4
+ * Wraps the four checks polly already ships in `@fairfox/polly/quality`
5
+ * into the new `Check` contract. The wrapping is purely adaptive: each
6
+ * underlying function (`checkNoAsCasting`, `checkNoRequire`,
7
+ * `checkSecrets`, `checkGitignoreCoversAllowlist`) keeps its existing
8
+ * exports unchanged, so consumers wiring those up by hand continue to
9
+ * work. The plugin path is the new way; the function path stays the
10
+ * same.
11
+ *
12
+ * The CSS family and shared-components live in a separate `polly-ui`
13
+ * plugin (#92–#94) because they belong to the styled-component
14
+ * contract polly-ui owns. Issue #98's scope is the four core checks.
15
+ */
16
+ import type { QualityPlugin } from "../types";
17
+ export declare const POLLY_CORE_VERSION = "0.45.0";
18
+ export declare const pollyCorePlugin: QualityPlugin;
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Three more checks bundled into `pollyCorePlugin`:
3
+ *
4
+ * - polly:forbidden-deps — import-graph ban list (#87)
5
+ * - polly:no-state-hooks — ban useState/useReducer/useSignal (#99)
6
+ * - polly:typographic-quotes — opt-in straight-vs-curly enforcement (#88)
7
+ *
8
+ * Each check is parameterised: defaults match polly's own pre-commit
9
+ * surface; consumers override via `polly.config.ts`. Test files are
10
+ * excluded by default for the import-walking checks since mocks and
11
+ * fixtures legitimately reference banned packages.
12
+ */
13
+ import type { Check } from "../types";
14
+ export declare const extraCoreChecks: Check<unknown>[];
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Import-graph checks for `pollyCorePlugin`:
3
+ *
4
+ * - polly:relative-imports — ban `../` imports beyond a depth threshold (#84)
5
+ * - polly:tsconfig-paths — ban `compilerOptions.paths` aliases (#84)
6
+ * - polly:no-raw-http — force HTTP through a canonical client (#86)
7
+ * - polly:types — multi-package tsc --noEmit orchestrator (#85)
8
+ *
9
+ * All four are parameterised. Defaults are silent or zero-impact unless a
10
+ * consumer opts in via `polly.config.ts`. Polly's own pre-commit pipeline
11
+ * does not currently run these — they exist primarily for downstream
12
+ * consumers (lingua, fairfox, warehouse-experiments) and ship under the
13
+ * core plugin namespace so adoption is one config-block change away.
14
+ */
15
+ import type { Check } from "../types";
16
+ export declare const importCoreChecks: Check<unknown>[];
@@ -0,0 +1,31 @@
1
+ /**
2
+ * `pollyUiPlugin` — the polly-ui-provided plugin (#89, #90, #91–#94).
3
+ *
4
+ * Re-homes the CSS conformance family and shared-components ban under a
5
+ * dedicated `polly-ui` namespace, and adds a new `no-inline-handlers`
6
+ * check for JSX event handlers. Every wrap reuses the underlying
7
+ * function from `tools/quality/src/css/*` and
8
+ * `tools/quality/src/check-shared-components.ts` so behaviour is
9
+ * identical to the pre-host invocation; only the integration surface
10
+ * changes.
11
+ *
12
+ * Out of scope for this release:
13
+ * - The data-action dispatcher *runtime* described in #90. The check
14
+ * ships here so a project can ban inline handlers today; the
15
+ * dispatcher needs a real Preact implementation that mounts near
16
+ * <OverlayRoot> and registers a delegated event listener, and that
17
+ * work belongs in `src/polly-ui/actions.tsx` rather than under the
18
+ * quality plugin host. The check on its own is useful — it forces
19
+ * the consumer to pick an alternative — and the runtime can land
20
+ * in a follow-up release without changing the check's id.
21
+ * - Registry-driven CSS validation. The four CSS checks currently
22
+ * parse polly-ui's CSS at scan time. The new
23
+ * `@fairfox/polly/ui/registry` (introduced alongside this plugin)
24
+ * exposes the canonical token + component lists as data, and a
25
+ * follow-up can swap the parse-time discovery for a registry
26
+ * lookup. The shape of the wraps does not change when that
27
+ * happens; only the inner implementation does.
28
+ */
29
+ import type { QualityPlugin } from "../types";
30
+ export declare const POLLY_UI_PLUGIN_VERSION = "0.46.0";
31
+ export declare const pollyUiPlugin: QualityPlugin;
@@ -0,0 +1,104 @@
1
+ /**
2
+ * Plugin-host contract for `@fairfox/polly/quality`.
3
+ *
4
+ * A `QualityPlugin` bundles a set of `Check`s under a namespace. The host
5
+ * loads one or more plugins from `polly.config.ts`, validates that each
6
+ * check's id is unique, and runs the requested set in parallel. A check
7
+ * declares the inputs it reads so the cache layer (see `cache.ts`) can
8
+ * compute a content-hash and skip re-execution when nothing has changed.
9
+ *
10
+ * Plugin and check ids are namespaced as `<plugin>:<name>`. Polly's own
11
+ * plugin uses the `polly` prefix; polly-ui will use `polly-ui`; consumer
12
+ * plugins use whatever prefix matches their package name.
13
+ */
14
+ /**
15
+ * Outcome of running a single check. The host aggregates these into a
16
+ * `RunReport` for the CLI. `cached` is true when the result came back from
17
+ * the on-disk cache without re-running the check body.
18
+ */
19
+ export type CheckRunResult = {
20
+ id: string;
21
+ ok: boolean;
22
+ durationMs: number;
23
+ cached: boolean;
24
+ /** Human-readable summary line (one violation per element, or status). */
25
+ messages: string[];
26
+ /** Raw error if the check threw; surfaces in CLI output. */
27
+ error?: string;
28
+ };
29
+ /**
30
+ * Context passed to a check at run time. The host fills in `rootDir`
31
+ * and `signal` (for cancellation) before invoking `run`.
32
+ */
33
+ export type CheckContext<TConfig = unknown> = {
34
+ /** Repository root the consumer is checking. */
35
+ rootDir: string;
36
+ /** Resolved configuration for this check (already validated). */
37
+ config: TConfig;
38
+ /** Aborted when the run is cancelled (CLI Ctrl-C, watch reload, etc.). */
39
+ signal?: AbortSignal;
40
+ };
41
+ /**
42
+ * A single check. The host calls `validate(config)` once at load time
43
+ * and `run(ctx)` once per execution. `filesRead(config)` is consulted by
44
+ * the cache before `run` — return the absolute paths whose content must
45
+ * invalidate a cached result.
46
+ */
47
+ export type Check<TConfig = unknown> = {
48
+ /** Namespaced id, e.g. `polly:no-as-casting`. */
49
+ id: string;
50
+ /** One-line description for `polly quality list`. */
51
+ description: string;
52
+ /**
53
+ * Validate user-supplied config. Return `null` for valid input or a
54
+ * non-empty array of error messages for invalid input. Errors are
55
+ * surfaced at load time, not at run time.
56
+ */
57
+ validate?: (config: unknown) => string[] | null;
58
+ /**
59
+ * Files whose content affects the result of this check. Returned as
60
+ * absolute paths (or paths relative to `rootDir`; the cache normalises).
61
+ * The host hashes these and skips `run` on cache hit.
62
+ */
63
+ filesRead?: (config: TConfig, rootDir: string) => Promise<string[]> | string[];
64
+ /**
65
+ * Environment variables and tool versions that contribute to the
66
+ * cache key alongside file content. Use this when the check's behaviour
67
+ * depends on something not captured by `filesRead` (e.g. a binary's
68
+ * version, an env var that flips a code path).
69
+ */
70
+ cacheKeyExtras?: (config: TConfig) => Record<string, string>;
71
+ /** Run the check. Throws are caught by the host and reported as failures. */
72
+ run: (ctx: CheckContext<TConfig>) => Promise<CheckOutcome>;
73
+ };
74
+ /**
75
+ * The body of a check returns either pass or fail with messages. The host
76
+ * adds id, duration, and cache status to produce a `CheckRunResult`.
77
+ */
78
+ export type CheckOutcome = {
79
+ ok: boolean;
80
+ messages: string[];
81
+ };
82
+ /**
83
+ * A plugin contributes a namespaced bundle of checks.
84
+ */
85
+ export type QualityPlugin = {
86
+ /** Namespace used as the prefix on every check id. */
87
+ name: string;
88
+ version: string;
89
+ checks: Check<unknown>[];
90
+ };
91
+ /**
92
+ * Per-check configuration map keyed by check id. The host pulls the
93
+ * matching entry out of `qualityConfig` and passes it as `ctx.config`.
94
+ */
95
+ export type QualityRunConfig = {
96
+ plugins: QualityPlugin[];
97
+ /** Per-check config keyed by check id (e.g. `"polly:no-as-casting"`). */
98
+ checks?: Record<string, unknown>;
99
+ };
100
+ export type RunReport = {
101
+ ok: boolean;
102
+ results: CheckRunResult[];
103
+ totalDurationMs: number;
104
+ };