@hawkeyexl/manni 0.3.0 → 1.0.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/dist/cli.js CHANGED
@@ -3,7 +3,7 @@ import {
3
3
  buildProgram,
4
4
  fail,
5
5
  runIfMain
6
- } from "./chunk-BKJOQHWN.js";
6
+ } from "./chunk-FL75S2L4.js";
7
7
  import {
8
8
  ToolError,
9
9
  escapeWorkflowCommandMessage,
@@ -13,8 +13,9 @@ import {
13
13
  palette,
14
14
  programName,
15
15
  readConfigFile,
16
+ selectCollections,
16
17
  shouldColor
17
- } from "./chunk-7M2YOXVG.js";
18
+ } from "./chunk-IRHWILCO.js";
18
19
 
19
20
  // src/cli.ts
20
21
  import { Command as Command2 } from "commander";
@@ -178,6 +179,48 @@ async function crawl(opts, analyzer) {
178
179
  return { pages, discovered: frontier.length, skipped, duplicates };
179
180
  }
180
181
 
182
+ // src/a11y/core/seeds.ts
183
+ var NO_SEEDS_MESSAGE = "No URLs to check. Pass one or more, set url: on a collection, or set a11y.urls in manni.config.yaml.";
184
+ var CONFIG_NAME = "manni.config.yaml";
185
+ function resolveSeeds(sources) {
186
+ const { urls, collections: names, declared } = sources;
187
+ if (names.length > 0) {
188
+ if (urls.length > 0) {
189
+ throw new A11yError(
190
+ "--collection selects a configured collection; it cannot be combined with URLs."
191
+ );
192
+ }
193
+ if (sources.source == null && declared.length === 0) {
194
+ throw new A11yError("--collection needs a config file to select from.");
195
+ }
196
+ const selected = selectCollections(
197
+ declared,
198
+ names,
199
+ sources.source ?? CONFIG_NAME,
200
+ (message) => new A11yError(message)
201
+ );
202
+ const seeds = [];
203
+ for (const collection of selected) {
204
+ if (collection.url === void 0) {
205
+ throw new A11yError(`collection "${collection.name}" has no url: to check.`);
206
+ }
207
+ seeds.push(collection.url);
208
+ }
209
+ return unique(seeds);
210
+ }
211
+ if (urls.length > 0) return [...urls];
212
+ const configUrls = sources.configUrls ?? [];
213
+ if (configUrls.length > 0) return [...configUrls];
214
+ const published = unique(
215
+ declared.flatMap((collection) => collection.url === void 0 ? [] : [collection.url])
216
+ );
217
+ if (published.length > 0) return published;
218
+ throw new A11yError(NO_SEEDS_MESSAGE);
219
+ }
220
+ function unique(values) {
221
+ return [...new Set(values)];
222
+ }
223
+
181
224
  // src/a11y/core/sitemap.ts
182
225
  import { DOMParser } from "@xmldom/xmldom";
183
226
  var MAX_INDEX_DEPTH = 3;
@@ -311,9 +354,7 @@ async function runCheck(opts, deps) {
311
354
  const { analyzer } = deps;
312
355
  try {
313
356
  if (opts.urls.length === 0) {
314
- throw new A11yError(
315
- "No URLs to check. Pass one or more, or set `a11y.urls` in manni.config.yaml."
316
- );
357
+ throw new A11yError(NO_SEEDS_MESSAGE);
317
358
  }
318
359
  for (const url of opts.urls) {
319
360
  if (!isHttpUrl(url)) throw new A11yError(`Not an http(s) URL: "${url}".`);
@@ -497,8 +538,12 @@ var CONFIG_FILE = {
497
538
  };
498
539
  async function loadA11yConfig(cwd, explicitPath) {
499
540
  const file = explicitPath === void 0 ? await findConfigFile(cwd, CONFIG_FILE) : await readConfigFile(explicitPath, cwd, CONFIG_FILE);
500
- if (file === null) return { config: {}, source: null };
501
- return { config: parseA11yConfig(file.value, file.source), source: file.source };
541
+ if (file === null) return { config: {}, source: null, collections: [] };
542
+ return {
543
+ config: parseA11yConfig(file.value, file.source),
544
+ source: file.source,
545
+ collections: file.collections
546
+ };
502
547
  }
503
548
  function parseA11yConfig(value, source) {
504
549
  if (value == null) return {};
@@ -783,6 +828,9 @@ function truncateMiddle(text, room) {
783
828
  }
784
829
 
785
830
  // src/a11y/cli.ts
831
+ function collect(value, prev) {
832
+ return prev.concat([value]);
833
+ }
786
834
  function splitList(value) {
787
835
  return value.split(",").map((s) => s.trim()).filter(Boolean);
788
836
  }
@@ -824,7 +872,7 @@ function buildProgram2() {
824
872
  program.name("a11y").description("Crawl a site and check every page for accessibility violations with axe-core").version(package_default.version, "-V, --version").option("--no-color", "disable colored output").showHelpAfterError("(add --help for usage)").exitOverride();
825
873
  program.command("check").description("Crawl from the given URLs and check every page with axe-core").argument(
826
874
  "[urls...]",
827
- "http(s) seed URLs; falls back to a11y.urls in manni.config.yaml"
875
+ "http(s) seed URLs; falls back to a collection's url: or a11y.urls in manni.config.yaml"
828
876
  ).option("-f, --format <format>", `output: ${A11Y_FORMAT_LIST}`, "pretty").option("--no-crawl", "check exactly the given URLs: no sitemap, no link following").option(
829
877
  "--max-pages <n>",
830
878
  "cap on pages checked; the rest are reported as skipped (default: no cap)"
@@ -836,7 +884,12 @@ function buildProgram2() {
836
884
  "--timeout <ms>",
837
885
  "per-page navigation timeout in milliseconds",
838
886
  String(CHECK_DEFAULTS.timeout)
839
- ).option("-q, --quiet", "in pretty output, hide pages with no violations").option("--progress", "report progress on stderr (default: only on a terminal)").option("--no-progress", "never report progress").option("-c, --config <path>", "path to a manni config file").option("--no-config", "ignore any discovered config file").action(async (urls, options, command) => {
887
+ ).option("-q, --quiet", "in pretty output, hide pages with no violations").option("--progress", "report progress on stderr (default: only on a terminal)").option("--no-progress", "never report progress").option(
888
+ "--collection <name>",
889
+ "configured collection to run over; repeatable",
890
+ collect,
891
+ []
892
+ ).option("-c, --config <path>", "path to a manni config file").option("--no-config", "ignore any discovered config file").action(async (urls, options, command) => {
840
893
  let clearProgress = () => void 0;
841
894
  try {
842
895
  const typed = (name) => command.getOptionValueSource(name) === "cli";
@@ -847,14 +900,21 @@ function buildProgram2() {
847
900
  const severity = assertSeverity(options.severity);
848
901
  const maxPages = options.maxPages === void 0 ? void 0 : positiveInteger(options.maxPages, "--max-pages");
849
902
  const timeout = positiveInteger(options.timeout, "--timeout");
850
- const loaded = options.config === false ? { config: {}, source: null } : await loadA11yConfig(process.cwd(), options.config);
903
+ const loaded = options.config === false ? { config: {}, source: null, collections: [] } : await loadA11yConfig(process.cwd(), options.config);
851
904
  const cfg = loaded.config;
905
+ const seeds = resolveSeeds({
906
+ urls,
907
+ collections: options.collection,
908
+ ...cfg.urls === void 0 ? {} : { configUrls: cfg.urls },
909
+ declared: loaded.collections,
910
+ source: loaded.source
911
+ });
852
912
  const parent = command.parent ?? command;
853
913
  const progress = resolveProgress(parent, options.progress);
854
914
  clearProgress = progress.clear;
855
915
  const run = await runCheck(
856
916
  {
857
- urls: urls.length > 0 ? urls : cfg.urls ?? [],
917
+ urls: seeds,
858
918
  crawl: typed("crawl") ? options.crawl : cfg.crawl ?? CHECK_DEFAULTS.crawl,
859
919
  // Typed flag > config key > no cap. There is no default to fall to.
860
920
  maxPages: maxPages ?? cfg.maxPages,