webanvil 0.0.11 → 0.0.12

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/README.md CHANGED
@@ -56,17 +56,17 @@ wa typecheck # type-check the project
56
56
  What it includes
57
57
  ----------------
58
58
 
59
- | Project job | WebAnvil command | Tool |
60
- | -------------------------- | ---------------------------------- | -------------------------------- |
61
- | Web builds and development | `wa build`, `wa dev`, `wa preview` | Vite |
62
- | Node builds and watch mode | `wa build`, `wa dev` | Rolldown |
63
- | Design-system Storybook | `wa build`, `wa dev`, `wa preview` | Storybook |
64
- | Tracked output cleanup | `wa clean` | WebAnvil |
65
- | Static checks | `wa check` | Oxfmt, Oxlint, TypeScript Native |
66
- | Tests | `wa test` | Vitest |
67
- | Linting | `wa lint` | Oxlint |
68
- | Formatting | `wa format` | Oxfmt |
69
- | Type checking | `wa typecheck` | TypeScript Native |
59
+ | Project job | WebAnvil command | Tool |
60
+ | -------------------------- | ---------------------------------- | ------------------------------------------------- |
61
+ | Web builds and development | `wa build`, `wa dev`, `wa preview` | Vite |
62
+ | Node builds and watch mode | `wa build`, `wa dev` | Rolldown |
63
+ | Design-system Storybook | `wa build`, `wa dev`, `wa preview` | Storybook |
64
+ | Tracked output cleanup | `wa clean` | WebAnvil |
65
+ | Static checks | `wa check` | Oxfmt, Oxlint, TypeScript Native, or svelte-check |
66
+ | Tests | `wa test` | Vitest |
67
+ | Linting | `wa lint` | Oxlint |
68
+ | Formatting | `wa format` | Oxfmt |
69
+ | Type checking | `wa typecheck` | TypeScript Native or svelte-check |
70
70
 
71
71
  Getting started
72
72
  ---------------
@@ -124,6 +124,12 @@ first failure. It is read-only by default. Use `wa check --fix` to format files
124
124
  and apply safe lint fixes before type checking. Tests stay separate under
125
125
  `wa test`.
126
126
 
127
+ For a Svelte project, add `svelte-check` to the package's `devDependencies`.
128
+ Then `wa typecheck` and `wa check` use it for project-wide diagnostics through
129
+ the package's `tsconfig.json`. WebAnvil otherwise uses TypeScript Native.
130
+ Explicit file paths such as `wa typecheck src/file.ts` always use TypeScript
131
+ Native because `svelte-check` checks a project rather than individual files.
132
+
127
133
  ### A web app
128
134
 
129
135
  Set the build mode to `"web"` and point it at an HTML entry point. `wa dev` starts Vite's development server, `wa build` produces a production bundle, and `wa preview` serves that bundle locally.
@@ -132,6 +132,11 @@ const supportedTools = {
132
132
  bin: "tsgo"
133
133
  }
134
134
  };
135
+ const optionalTools = { "svelte-check": {
136
+ packageName: "svelte-check",
137
+ range: ">=4 <5",
138
+ bin: "svelte-check"
139
+ } };
135
140
  const dependencyFields = [
136
141
  "dependencies",
137
142
  "devDependencies",
@@ -318,6 +323,7 @@ const loadResolvedTool = async (name, definition, anchor, source) => {
318
323
  var Toolchain = class {
319
324
  cwd;
320
325
  #tools = /* @__PURE__ */ new Map();
326
+ #optionalTools = /* @__PURE__ */ new Map();
321
327
  constructor(cwd = process.cwd()) {
322
328
  this.cwd = resolve$1(cwd);
323
329
  }
@@ -328,6 +334,13 @@ var Toolchain = class {
328
334
  this.#tools.set(name, selected);
329
335
  return selected;
330
336
  }
337
+ resolveOptional(name) {
338
+ const existing = this.#optionalTools.get(name);
339
+ if (existing !== void 0) return existing;
340
+ const selected = this.#resolveOptional(name);
341
+ this.#optionalTools.set(name, selected);
342
+ return selected;
343
+ }
331
344
  async #resolve(name) {
332
345
  const definition = supportedTools[name];
333
346
  const declaration = await findDeclaration(this.cwd, definition.packageName);
@@ -335,6 +348,12 @@ var Toolchain = class {
335
348
  const webanvilPackageRoot = dirname$1(await findContainingManifest(fileURLToPath(import.meta.url)));
336
349
  return loadResolvedTool(name, definition, webanvilPackageRoot, "webanvil");
337
350
  }
351
+ async #resolveOptional(name) {
352
+ const definition = optionalTools[name];
353
+ const declaration = await findDeclaration(this.cwd, definition.packageName);
354
+ if (declaration === void 0) return;
355
+ return loadResolvedTool(name, definition, declaration.directory, "project");
356
+ }
338
357
  };
339
358
  const formatResolvedTool = (tool) => `${tool.packageName} ${tool.version} (${tool.source})`;
340
359
  const declarationDefaults = {
@@ -1078,9 +1097,20 @@ const useTool = async (name, toolchain = new Toolchain(process.cwd())) => {
1078
1097
  }
1079
1098
  return tool;
1080
1099
  };
1100
+ const useOptionalTool = async (name, toolchain = new Toolchain(process.cwd())) => {
1101
+ const tool = await toolchain.resolveOptional(name);
1102
+ if (tool === void 0) return;
1103
+ const identity = `${tool.packageRoot}:${tool.version}`;
1104
+ if (!announced.has(identity)) {
1105
+ announced.add(identity);
1106
+ logger.info(`Using ${formatResolvedTool(tool)}`);
1107
+ }
1108
+ return tool;
1109
+ };
1081
1110
  const useToolApi = async (name, subpath, toolchain = new Toolchain(process.cwd())) => (await useTool(name, toolchain)).import(subpath);
1082
1111
  const useToolExecutable = async (name, toolchain = new Toolchain(process.cwd())) => {
1083
- const tool = await useTool(name, toolchain);
1112
+ const tool = name === "svelte-check" ? await useOptionalTool(name, toolchain) : await useTool(name, toolchain);
1113
+ if (tool === void 0) throw new Error(`${name} is not declared by the active project or workspace`);
1084
1114
  if (tool.executable === void 0) throw new Error(`${tool.packageName} does not expose an executable`);
1085
1115
  return tool.executable;
1086
1116
  };
@@ -1521,7 +1551,7 @@ const rebaseOxlintConfig = (config, cwd, configDirectory) => ({
1521
1551
  }) } : {}
1522
1552
  });
1523
1553
  const runTool = async (name, arguments_, config) => {
1524
- if (name !== "tsgo" && await hasOxcConfig(name)) config = void 0;
1554
+ if ((name === "oxfmt" || name === "oxlint") && await hasOxcConfig(name)) config = void 0;
1525
1555
  const executable = await useToolExecutable(name === "tsgo" ? "typescript-native" : name);
1526
1556
  const cwd = process.cwd();
1527
1557
  const configDirectory = join(cwd, ".webanvil");
@@ -1532,7 +1562,7 @@ const runTool = async (name, arguments_, config) => {
1532
1562
  const generatedConfig = configWithoutIgnores === void 0 || configPath === void 0 ? configWithoutIgnores : name === "oxfmt" ? rebaseOxfmtConfig(configWithoutIgnores, cwd, configDirectory) : rebaseOxlintConfig(configWithoutIgnores, cwd, configDirectory);
1533
1563
  const ignoreArguments = name === "oxfmt" ? ignorePatterns.map((pattern) => pattern.startsWith("!") ? pattern.slice(1) : `!${pattern}`) : ignorePatterns.flatMap((pattern) => ["--ignore-pattern", pattern]);
1534
1564
  const internalIgnoreArguments = name === "oxfmt" ? ["!**/.webanvil/**"] : ["--ignore-pattern", ".webanvil/**"];
1535
- const toolArguments = name === "tsgo" ? arguments_ : [
1565
+ const toolArguments = name === "tsgo" || name === "svelte-check" ? arguments_ : [
1536
1566
  ...configPath === void 0 ? [] : ["--config", configPath],
1537
1567
  ...ignoreArguments,
1538
1568
  ...internalIgnoreArguments,
@@ -1594,9 +1624,10 @@ const typecheckArguments = async (paths) => {
1594
1624
  ];
1595
1625
  return getTsconfig(process.cwd(), { typescriptVersion: false })?.config.references?.length ? ["-b", "--noEmit"] : ["--noEmit"];
1596
1626
  };
1597
- const typecheck = async (paths) => {
1598
- logger.start("Type checking");
1599
- await runTool("tsgo", await typecheckArguments(paths));
1627
+ const typecheck = async (paths, options) => {
1628
+ const svelteCheck = paths.length === 0 ? options === void 0 ? await useOptionalTool("svelte-check") : options.svelteCheck : void 0;
1629
+ logger.start(svelteCheck === void 0 ? "Type checking" : "Checking Svelte");
1630
+ await runTool(svelteCheck === void 0 ? "tsgo" : "svelte-check", svelteCheck === void 0 ? await typecheckArguments(paths) : []);
1600
1631
  logger.success("Type check passed");
1601
1632
  };
1602
1633
  var typecheck_default = defineCommand({
@@ -1609,23 +1640,25 @@ const fix = defineOption({
1609
1640
  description: "Format files and apply safe lint fixes.",
1610
1641
  arity: 0
1611
1642
  });
1612
- const checkProject = async (fixFiles = false, config = {}) => {
1643
+ const checkProject = async (fixFiles = false, config = {}, typecheckOptions) => {
1613
1644
  await format([], !fixFiles, config.format);
1614
1645
  await lint([], fixFiles, config.lint);
1615
- await typecheck([]);
1646
+ if (typecheckOptions === void 0) await typecheck([]);
1647
+ else await typecheck([], typecheckOptions);
1616
1648
  };
1617
1649
  var check_default = defineCommand({
1618
1650
  name: "check",
1619
1651
  description: "Check formatting, linting, and types, stopping at the first failure.",
1620
1652
  options: [fix],
1621
1653
  run: async ({ fix }) => {
1622
- await Promise.all([
1654
+ const [svelteCheck] = await Promise.all([
1655
+ useOptionalTool("svelte-check"),
1623
1656
  useTool("oxfmt"),
1624
- useTool("oxlint"),
1625
- useTool("typescript-native")
1657
+ useTool("oxlint")
1626
1658
  ]);
1659
+ if (svelteCheck === void 0) await useTool("typescript-native");
1627
1660
  const { config } = await loadConfig();
1628
- await checkProject(fix, config);
1661
+ await checkProject(fix, config, { svelteCheck });
1629
1662
  }
1630
1663
  });
1631
1664
  const clean = async () => {
package/dist/index.d.mts CHANGED
@@ -36,9 +36,11 @@ declare const isWebAnvilPlugin: (plugin: unknown) => plugin is WebAnvilPlugin;
36
36
  declare const resolveRolldownPlugins: (plugins: WebAnvilPlugin[]) => Plugin[];
37
37
  declare const resolveVitePlugins: (plugins: WebAnvilPlugin[]) => PluginOption[];
38
38
  type ToolName = "vite" | "vitest" | "rolldown" | "oxlint" | "oxfmt" | "storybook" | "typescript" | "typescript-native";
39
+ type OptionalToolName = "svelte-check";
40
+ type AnyToolName = ToolName | OptionalToolName;
39
41
  type ToolSource = "project" | "webanvil";
40
42
  type ResolvedTool = {
41
- name: ToolName;
43
+ name: AnyToolName;
42
44
  packageName: string;
43
45
  version: string;
44
46
  source: ToolSource;
@@ -51,6 +53,7 @@ declare class Toolchain {
51
53
  readonly cwd: string;
52
54
  constructor(cwd?: string);
53
55
  resolve(name: ToolName): Promise<ResolvedTool>;
56
+ resolveOptional(name: OptionalToolName): Promise<ResolvedTool | undefined>;
54
57
  }
55
58
  type DeclarationLogger = {
56
59
  info: (...arguments_: unknown[]) => void;
@@ -372,8 +375,17 @@ declare const _default: import("cmdore").Command<readonly [{
372
375
  readonly name: "entry";
373
376
  readonly description: "Web entry or Node public root; unbundled Node builds emit its reachable graph with preserveModules.";
374
377
  }]>;
378
+ type TypecheckOptions = {
379
+ svelteCheck: ResolvedTool | undefined;
380
+ };
381
+ declare const typecheck: (paths: string[], options?: TypecheckOptions) => Promise<void>;
382
+ declare const _default$8: import("cmdore").Command<readonly import("cmdore").Option[], readonly [{
383
+ readonly name: "paths";
384
+ readonly description: "Files or directories to check.";
385
+ readonly variadic: true;
386
+ }]>;
375
387
  type CheckConfig = Pick<UserConfig, "format" | "lint">;
376
- declare const checkProject: (fixFiles?: boolean, config?: CheckConfig) => Promise<void>;
388
+ declare const checkProject: (fixFiles?: boolean, config?: CheckConfig, typecheckOptions?: TypecheckOptions) => Promise<void>;
377
389
  declare const _default$1: import("cmdore").Command<readonly [{
378
390
  readonly name: "fix";
379
391
  readonly description: "Format files and apply safe lint fixes.";
@@ -544,12 +556,6 @@ declare const _default$7: import("cmdore").Command<readonly [{
544
556
  readonly description: "Test files or names to run.";
545
557
  readonly variadic: true;
546
558
  }]>;
547
- declare const typecheck: (paths: string[]) => Promise<void>;
548
- declare const _default$8: import("cmdore").Command<readonly import("cmdore").Option[], readonly [{
549
- readonly name: "paths";
550
- readonly description: "Files or directories to check.";
551
- readonly variadic: true;
552
- }]>;
553
559
  declare const bundle$1: {
554
560
  readonly name: "bundle";
555
561
  readonly description: "Bundle the Node public roots; without it, emit their reachable graph with preserveModules.";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "webanvil",
3
- "version": "0.0.11",
3
+ "version": "0.0.12",
4
4
  "description": "A unified CLI for building, testing, linting, formatting, and type-checking JavaScript and TypeScript projects.",
5
5
  "keywords": [
6
6
  "build-tool",