@zappie/check 0.1.3 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,31 @@
1
1
  # @zappie/check
2
2
 
3
+ ## 0.2.1
4
+
5
+ ### Patch Changes
6
+
7
+ - edfc401: Audit storefront dependencies and widen secret scanning to tracked files, Worker output, server bundles and optional Git history.
8
+ - Updated dependencies [edfc401]
9
+ - @zappie/sdk@0.1.11
10
+
11
+ ## 0.2.0
12
+
13
+ ### Minor Changes
14
+
15
+ - 79deec3: Hold every template to the same accessibility, semantics, performance and CSS bar.
16
+
17
+ - `eslint-plugin-zappie`: `zappie/no-lazy-overlay` reports `React.lazy` and `Suspense` and points at `deferred()` from `@zappie/foundations`. It is an error in `recommended`.
18
+ - `@zappie/check`: `lint` fails when a project turns down a `jsx-a11y` rule from `recommended`. A new `css` step reports `css/important` and `css/class-patch` as errors, and `css/duplicate-keyframes`, `css/duplicate-selector`, `css/arbitrary-token`, `css/literal-token`, `css/unused-custom-property`, `css/reduced-motion` and `css/unreadable` as warnings.
19
+ - `@zappie/verify`: V13 fails on a missing main landmark, a page without exactly one h1, a dialog without a name, a positive tabindex, a phone control under 44×44 px and focus that doesn't return after the item or cart closes. V16 times each marked overlay from tap to first paint on a phone profile. V17 checks each marked overlay's focus, Escape and scroll lock. Both are skipped while a menu has no overlay markers. V14 records `menuCssKbGz`. `findRegressions` compares two reports' metrics.
20
+ - `@zappie/starter`: menu controls are at least 44×44 px on a phone.
21
+
22
+ ### Patch Changes
23
+
24
+ - Updated dependencies [4f3cdc3]
25
+ - Updated dependencies [79deec3]
26
+ - @zappie/sdk@0.1.8
27
+ - eslint-plugin-zappie@0.2.0
28
+
3
29
  ## 0.1.3
4
30
 
5
31
  ### Patch Changes
package/README.md CHANGED
@@ -15,16 +15,55 @@ npx zappie check
15
15
  | ----------- | ------------------------------------------------------------------------------------------- |
16
16
  | `config` | `zappie.config.ts` and `theme.json`, against the SDK and token rules |
17
17
  | `allowlist` | Every npm dependency is on Zappie's package allowlist or in `packages.allow` in your config |
18
- | `lint` | The `eslint-plugin-zappie` rules |
18
+ | `audit` | High and critical dependency advisories, with critical findings enforced on request |
19
+ | `lint` | The `eslint-plugin-zappie` rules and the `jsx-a11y` accessibility baseline |
19
20
  | `types` | A TypeScript check of the project |
20
21
  | `test` | Your project's tests |
21
22
  | `build` | A production build |
22
23
  | `secrets` | No secret keys or tokens in your source or build |
23
24
  | `readiness` | Initial route discovery is enabled, or the config records why the site opts out |
24
25
  | `budgets` | Built JavaScript and CSS sizes, against Zappie's default budgets or the ones in your config |
26
+ | `css` | Your source CSS and class names, and the built client CSS, for the problems below |
27
+
28
+ ### CSS problems
29
+
30
+ | Code | Level | What it catches |
31
+ | ---------------------------- | ------- | ------------------------------------------------------------------------------------------------------- |
32
+ | `css/important` | Error | `!important` in source CSS or `@apply`, or an important utility such as `p-4!` or `!p-4` |
33
+ | `css/class-patch` | Error | A selector that matches a class attribute, such as `[class*="bg-white"]`. Dark mode goes through tokens |
34
+ | `css/duplicate-keyframes` | Warning | Two `@keyframes` with the same frames under different names, or one name defined twice |
35
+ | `css/duplicate-selector` | Warning | A selector, or a selector list, styled by more than one source rule in the same context |
36
+ | `css/arbitrary-token` | Warning | An arbitrary utility that restates a token from your `@theme`, such as `text-[hsl(var(--foreground))]` |
37
+ | `css/literal-token` | Warning | A plain CSS colour, radius or shadow that equals a token your CSS defines |
38
+ | `css/unused-custom-property` | Warning | A custom property your CSS defines that no CSS, source or built script reads |
39
+ | `css/reduced-motion` | Warning | An animation or transition with no `prefers-reduced-motion` path |
40
+ | `css/unreadable` | Warning | A CSS file that can't be parsed |
41
+
42
+ Warnings don't fail the step. A reviewed `!important` passes with `/* zappie-allow-important: <reason> */` on the same line. Declarations inside `@media (prefers-reduced-motion: reduce)` may use `!important`.
25
43
 
26
44
  Add `--json` for a machine-readable result. Its shape is the JSON Schema at `@zappie/check/schema/check-result.v1.json`.
27
45
 
46
+ Dependency auditing defaults to `--audit=report`. Use `--audit=off` when the registry is unavailable or `--audit=enforce` to fail on an unacknowledged critical advisory. A high or critical advisory with no fixed version can be acknowledged for at most 90 days:
47
+
48
+ ```ts
49
+ export default defineConfig({
50
+ // ...
51
+ audit: {
52
+ ignore: [
53
+ {
54
+ id: "GHSA-abcd-1234-5678",
55
+ reason: "The maintainer has not published a fixed release",
56
+ until: "2026-11-30",
57
+ },
58
+ ],
59
+ },
60
+ });
61
+ ```
62
+
63
+ An unreadable or missing lockfile, registry failure, timeout, or unsupported Yarn or Bun project is reported as `audit/unavailable`. Report mode keeps checking and enforce mode fails. Invalid or expired acknowledgements are reported without hiding the advisory or stopping later checks.
64
+
65
+ Pass `--history` to include committed Git history in the secret scan. The normal scan covers every tracked file plus generated files under `workers/**`, `build/client/**` and `build/server/**`.
66
+
28
67
  ## From code
29
68
 
30
69
  ```ts
package/dist/index.d.ts CHANGED
@@ -5,8 +5,22 @@ type CheckProblem = {
5
5
  line?: number;
6
6
  message: string;
7
7
  fix: string | null;
8
+ advisory?: AuditAdvisory;
8
9
  };
9
- type CheckStepName = "config" | "allowlist" | "lint" | "types" | "test" | "build" | "secrets" | "readiness" | "budgets";
10
+ type AuditMode = "off" | "report" | "enforce";
11
+ type AuditAdvisory = {
12
+ id: string;
13
+ package: string;
14
+ severity: "high" | "critical";
15
+ vulnerableVersion: string;
16
+ fixedVersion: string | null;
17
+ fixCommand?: string;
18
+ upgradePackage?: string;
19
+ upgradeVersion?: string;
20
+ ignored: boolean;
21
+ ignoredUntil?: string;
22
+ };
23
+ type CheckStepName = "config" | "allowlist" | "audit" | "lint" | "types" | "test" | "build" | "secrets" | "readiness" | "budgets" | "css";
10
24
  type CheckStep = {
11
25
  name: CheckStepName;
12
26
  result: CheckResultValue;
@@ -21,6 +35,8 @@ type CheckOptions = {
21
35
  cwd: string;
22
36
  all?: boolean;
23
37
  packageManager: PackageManager;
38
+ audit?: AuditMode;
39
+ history?: boolean;
24
40
  signal?: AbortSignal;
25
41
  };
26
42
  type StepOptions = Omit<CheckOptions, "all">;
@@ -31,6 +47,26 @@ type AllowlistSource = {
31
47
  declare const BUILTIN_ALLOWLIST_SOURCE: AllowlistSource;
32
48
  declare function checkAllowlist({ cwd, signal }: StepOptions, source?: AllowlistSource): Promise<CheckStep>;
33
49
 
50
+ type CommandResult = {
51
+ code: number;
52
+ stdout: string;
53
+ stderr: string;
54
+ };
55
+ declare function command(executable: string, args: string[], cwd: string, signal?: AbortSignal): Promise<CommandResult>;
56
+
57
+ type AuditIgnore = {
58
+ id: string;
59
+ reason: string;
60
+ until: string;
61
+ };
62
+ type AuditDependencies = {
63
+ run?: typeof command;
64
+ timeoutMs?: number;
65
+ };
66
+ declare function checkAudit(options: StepOptions, dependencies?: AuditDependencies): Promise<CheckStep>;
67
+ declare function evaluateAudit(advisories: AuditAdvisory[], mode: "report" | "enforce", ignores?: AuditIgnore[], file?: string): CheckStep;
68
+ declare function parseAuditOutput(manager: PackageManager, source: string): AuditAdvisory[];
69
+
34
70
  declare function checkBudgets({ cwd, signal, }: StepOptions): Promise<CheckStep>;
35
71
 
36
72
  declare function checkBuild({ cwd, packageManager, signal, }: StepOptions): Promise<CheckStep>;
@@ -44,6 +80,28 @@ declare function supportsTypeScriptImport(version?: string): boolean;
44
80
  declare function loadConfig(cwd: string): Promise<LoadedConfig>;
45
81
  declare function checkConfig({ cwd, signal, }: StepOptions): Promise<CheckStep>;
46
82
 
83
+ declare function checkCss({ cwd, signal, }: StepOptions): Promise<CheckStep>;
84
+
85
+ type TextFile = {
86
+ file: string;
87
+ text: string;
88
+ };
89
+ type CssInputs = {
90
+ /** CSS the project authors. */
91
+ sourceCss: TextFile[];
92
+ /** Script and markup that can hold class strings or read custom properties. */
93
+ sourceCode: TextFile[];
94
+ /** Client CSS the build emitted, Tailwind's generated rules among it. */
95
+ builtCss: TextFile[];
96
+ /** Client JavaScript the build emitted; it can read custom properties too. */
97
+ builtCode: TextFile[];
98
+ };
99
+
100
+ type CssCode = "css/important" | "css/duplicate-keyframes" | "css/duplicate-selector" | "css/arbitrary-token" | "css/unused-custom-property" | "css/reduced-motion" | "css/class-patch" | "css/literal-token" | "css/unreadable";
101
+ /** These codes fail the step. The other codes warn for one release. */
102
+ declare const CSS_ERRORS: ReadonlySet<CssCode>;
103
+ declare function analyseCss(inputs: CssInputs): CheckProblem[];
104
+
47
105
  declare function checkLint({ cwd, signal, }: StepOptions): Promise<CheckStep>;
48
106
 
49
107
  declare function checkReadiness({ cwd, signal, }: StepOptions): Promise<CheckStep>;
@@ -54,11 +112,13 @@ declare const SECRET_FILE_SIZE_CAP: number;
54
112
  type SecretFinding = CheckProblem & {
55
113
  severity: "error" | "warning";
56
114
  };
57
- declare function scanSecrets(dir: string): Promise<SecretFinding[]>;
58
- declare function checkSecrets({ cwd, signal, }: StepOptions): Promise<CheckStep>;
115
+ declare function scanSecrets(dir: string, options?: {
116
+ history?: boolean;
117
+ }): Promise<SecretFinding[]>;
118
+ declare function checkSecrets({ cwd, history, signal, }: StepOptions): Promise<CheckStep>;
59
119
 
60
120
  declare function checkTests({ cwd, packageManager, signal, }: StepOptions): Promise<CheckStep>;
61
121
 
62
122
  declare function checkTypes(options: StepOptions): Promise<CheckStep>;
63
123
 
64
- export { type AllowlistSource, BUILTIN_ALLOWLIST_SOURCE, type CheckOptions, type CheckProblem, type CheckResult, type CheckResultValue, type CheckStep, type CheckStepName, type PackageManager, SECRET_FILE_SIZE_CAP, type SecretFinding, type StepOptions, checkAllowlist, checkBudgets, checkBuild, checkConfig, checkLint, checkReadiness, checkSecrets, checkTests, checkTypes, loadConfig, runCheck, scanSecrets, supportsTypeScriptImport };
124
+ export { type AllowlistSource, type AuditAdvisory, type AuditIgnore, type AuditMode, BUILTIN_ALLOWLIST_SOURCE, CSS_ERRORS, type CheckOptions, type CheckProblem, type CheckResult, type CheckResultValue, type CheckStep, type CheckStepName, type CssCode, type CssInputs, type PackageManager, SECRET_FILE_SIZE_CAP, type SecretFinding, type StepOptions, type TextFile, analyseCss, checkAllowlist, checkAudit, checkBudgets, checkBuild, checkConfig, checkCss, checkLint, checkReadiness, checkSecrets, checkTests, checkTypes, evaluateAudit, loadConfig, parseAuditOutput, runCheck, scanSecrets, supportsTypeScriptImport };