as-test 1.1.9 → 1.1.10

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,9 @@
1
1
  # Change Log
2
2
 
3
+ ## 2026-05-19 - v1.1.10
4
+
5
+ - feat: when the user already declares `--transform json-as/...` in `buildOptions.args` or in their referenced `asconfig.json` (top-level `options.transform`, any `targets.*.transform`, or via a single level of `extends`), as-test no longer adds its own auto-include — letting users bring their own json-as version or load path. Detection matches bare specifiers (`json-as`, `json-as/transform`), absolute paths, and `./node_modules/...` paths.
6
+
3
7
  ## 2026-05-19 - v1.1.9
4
8
 
5
9
  - fix: spec files that share a basename across subdirectories (e.g. `sqli/flags.spec.ts` and `sqli_v2/flags.spec.ts`) now build to their disambiguated artifact names across `ast test`, `ast run`, and `ast fuzz` — even when only one of them is being built. Previously the single-file build paths, the selector-filtered top-level build, the per-mode test/run dispatch, the plan listing, and the fuzz runner all computed duplicates from a local (and often single-element) file list, never matched anything, and clobbered each other into a single `flags.spec.wasm` / `parser.fuzz.wasm`; the runner then reported `bindings artifact not found`. Every call site now computes the duplicate set against the full configured input glob (`config.input` for tests/runs, `config.fuzz.input` when `overrides.kind === "fuzz"`), matching the runner's lookup behavior.
@@ -1,4 +1,4 @@
1
- import { existsSync } from "fs";
1
+ import { existsSync, readFileSync } from "fs";
2
2
  import { glob } from "glob";
3
3
  import chalk from "chalk";
4
4
  import { spawn } from "child_process";
@@ -592,7 +592,10 @@ function getDefaultBuildArgs(config, featureToggles) {
592
592
  const buildArgs = [];
593
593
  const tryAsEnabled = resolveTryAsEnabled(featureToggles.tryAs);
594
594
  buildArgs.push("--transform", "as-test/transform");
595
- if (resolveProjectModule("json-as/transform")) {
595
+ if (
596
+ resolveProjectModule("json-as/transform") &&
597
+ !userSuppliesJsonAsTransform(config)
598
+ ) {
596
599
  buildArgs.push("--transform", "json-as/transform");
597
600
  }
598
601
  if (tryAsEnabled) {
@@ -634,6 +637,74 @@ function getDefaultBuildArgs(config, featureToggles) {
634
637
  }
635
638
  return buildArgs;
636
639
  }
640
+ // Treats anything whose path contains a "json-as" path component as a
641
+ // user-supplied json-as transform. Matches bare specifiers, subpath specifiers,
642
+ // absolute paths, and ./node_modules paths.
643
+ const JSON_AS_TRANSFORM_PATTERN = /(?:^|[\\/])json-as(?:[\\/@]|$)/;
644
+ function userSuppliesJsonAsTransform(config) {
645
+ for (const raw of config.buildOptions.args) {
646
+ if (!raw.length) continue;
647
+ const tokens = tokenizeCommand(raw);
648
+ for (let i = 0; i < tokens.length; i++) {
649
+ const token = tokens[i];
650
+ if (token == "--transform") {
651
+ const value = tokens[i + 1];
652
+ if (value && JSON_AS_TRANSFORM_PATTERN.test(value)) return true;
653
+ } else if (token.startsWith("--transform=")) {
654
+ const value = token.slice("--transform=".length);
655
+ if (value && JSON_AS_TRANSFORM_PATTERN.test(value)) return true;
656
+ }
657
+ }
658
+ }
659
+ if (config.config && config.config !== "none" && existsSync(config.config)) {
660
+ if (asconfigDeclaresJsonAs(config.config, new Set())) return true;
661
+ }
662
+ return false;
663
+ }
664
+ function asconfigDeclaresJsonAs(configFile, seen) {
665
+ const resolved = path.resolve(configFile);
666
+ if (seen.has(resolved)) return false;
667
+ seen.add(resolved);
668
+ let parsed;
669
+ try {
670
+ parsed = JSON.parse(readFileSync(resolved, "utf8"));
671
+ } catch {
672
+ return false;
673
+ }
674
+ if (!parsed || typeof parsed != "object") return false;
675
+ const obj = parsed;
676
+ if (transformsContainJsonAs(obj.options)) return true;
677
+ if (transformsContainJsonAs(obj)) return true;
678
+ const targets = obj.targets;
679
+ if (targets && typeof targets == "object" && !Array.isArray(targets)) {
680
+ for (const value of Object.values(targets)) {
681
+ if (transformsContainJsonAs(value)) return true;
682
+ }
683
+ }
684
+ const extendsValue = obj.extends;
685
+ if (typeof extendsValue == "string" && extendsValue.length) {
686
+ const parentPath = path.resolve(path.dirname(resolved), extendsValue);
687
+ if (existsSync(parentPath) && asconfigDeclaresJsonAs(parentPath, seen)) {
688
+ return true;
689
+ }
690
+ }
691
+ return false;
692
+ }
693
+ function transformsContainJsonAs(value) {
694
+ if (!value || typeof value != "object") return false;
695
+ const transform = value.transform;
696
+ if (typeof transform == "string") {
697
+ return JSON_AS_TRANSFORM_PATTERN.test(transform);
698
+ }
699
+ if (Array.isArray(transform)) {
700
+ for (const item of transform) {
701
+ if (typeof item == "string" && JSON_AS_TRANSFORM_PATTERN.test(item)) {
702
+ return true;
703
+ }
704
+ }
705
+ }
706
+ return false;
707
+ }
637
708
  function resolveTryAsEnabled(override) {
638
709
  const installed = hasTryAsRuntime();
639
710
  if (override === false) return false;
package/bin/index.js CHANGED
@@ -247,7 +247,7 @@ function info() {
247
247
  console.log("");
248
248
  console.log(
249
249
  chalk.dim(
250
- "If this tool provides value, please consider sponsoring my open-source work! https://jairus.dev/sponsor",
250
+ "If this tool provides value, please consider sponsoring my open-source work! https://github.com/sponsors/JairusSW",
251
251
  ) + "\n",
252
252
  );
253
253
  console.log(
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "as-test",
3
- "version": "1.1.9",
3
+ "version": "1.1.10",
4
4
  "author": "Jairus Tanaka",
5
5
  "repository": {
6
6
  "type": "git",