@recursica/adapter-tester 5.1.3 → 5.2.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.
package/dist/cli.js CHANGED
@@ -1,12 +1,12 @@
1
1
  #!/usr/bin/env node
2
- import { spawn as _, spawnSync as W } from "node:child_process";
3
- import { readFileSync as S, mkdirSync as I, writeFileSync as x, existsSync as M } from "node:fs";
4
- import { dirname as j, join as a, resolve as $ } from "node:path";
5
- import { fileURLToPath as U, pathToFileURL as B } from "node:url";
2
+ import { spawn as I, spawnSync as W } from "node:child_process";
3
+ import { readFileSync as T, mkdirSync as M, writeFileSync as E, existsSync as U } from "node:fs";
4
+ import { dirname as N, join as a, resolve as $ } from "node:path";
5
+ import { fileURLToPath as G, pathToFileURL as B } from "node:url";
6
6
  import K from "express";
7
7
  import { createProxyMiddleware as X } from "http-proxy-middleware";
8
8
  import Y from "node:net";
9
- import { m as z } from "./mantineSourceOfTruth-BDJ5mfpd.js";
9
+ import { m as z } from "./mantineSourceOfTruth-CAKhcVCT.js";
10
10
  import { a as Q, i as Z } from "./index-DqQzFSAH.js";
11
11
  const ee = /\x1b\[[0-9;]*m/g, te = /Local:\s*(https?:\/\/localhost:\d+)/;
12
12
  function re(e) {
@@ -23,19 +23,19 @@ function re(e) {
23
23
  }
24
24
  function oe(e) {
25
25
  try {
26
- const t = JSON.parse(S(e, "utf8")).port;
26
+ const t = JSON.parse(T(e, "utf8")).port;
27
27
  return typeof t == "number" ? t : void 0;
28
28
  } catch {
29
29
  return;
30
30
  }
31
31
  }
32
32
  function se(e, t) {
33
- I(j(e), { recursive: !0 }), x(e, JSON.stringify({ port: t }));
33
+ M(N(e), { recursive: !0 }), E(e, JSON.stringify({ port: t }));
34
34
  }
35
35
  function ne(e, t) {
36
36
  return new Promise((r, o) => {
37
37
  var y, w;
38
- const s = _(e.command, {
38
+ const s = I(e.command, {
39
39
  cwd: e.cwd,
40
40
  stdio: "pipe",
41
41
  shell: !0
@@ -47,23 +47,23 @@ function ne(e, t) {
47
47
  `Timed out after ${t}ms waiting for ${e.name}'s Storybook to report its URL (no "Local: http://localhost:<port>" line seen in its output).`
48
48
  )
49
49
  ));
50
- }, t), f = (i, u) => {
51
- const p = i.toString();
52
- for (const c of p.split(`
50
+ }, t), p = (i, u) => {
51
+ const h = i.toString();
52
+ for (const c of h.split(`
53
53
  `))
54
54
  if (c.trim()) {
55
- const h = u ? `${e.name} SB ERROR` : `${e.name} SB`;
56
- (u ? console.error : console.log)(`[${h}] ${c.trim()}`);
55
+ const f = u ? `${e.name} SB ERROR` : `${e.name} SB`;
56
+ (u ? console.error : console.log)(`[${f}] ${c.trim()}`);
57
57
  }
58
58
  if (n) return;
59
- const v = p.replace(ee, "").match(te);
59
+ const v = h.replace(ee, "").match(te);
60
60
  if (v) {
61
61
  n = !0, clearTimeout(l);
62
- const c = v[1], h = Number(new URL(c).port);
63
- se(e.cacheFile, h), r({ url: c, port: h, process: s });
62
+ const c = v[1], f = Number(new URL(c).port);
63
+ se(e.cacheFile, f), r({ url: c, port: f, process: s });
64
64
  }
65
65
  };
66
- (y = s.stdout) == null || y.on("data", (i) => f(i, !1)), (w = s.stderr) == null || w.on("data", (i) => f(i, !0)), s.on("error", (i) => {
66
+ (y = s.stdout) == null || y.on("data", (i) => p(i, !1)), (w = s.stderr) == null || w.on("data", (i) => p(i, !0)), s.on("error", (i) => {
67
67
  n || (n = !0, clearTimeout(l), o(i));
68
68
  }), s.on("exit", (i) => {
69
69
  n || (n = !0, clearTimeout(l), o(
@@ -74,7 +74,7 @@ function ne(e, t) {
74
74
  });
75
75
  });
76
76
  }
77
- function E(e, t) {
77
+ function A(e, t) {
78
78
  return {
79
79
  name: e,
80
80
  command: t.command,
@@ -84,7 +84,7 @@ function E(e, t) {
84
84
  timeoutMs: t.timeout
85
85
  };
86
86
  }
87
- async function A(e) {
87
+ async function D(e) {
88
88
  if (e.reuseExistingServer) {
89
89
  const t = oe(e.cacheFile);
90
90
  if (t !== void 0 && await re(t))
@@ -98,10 +98,10 @@ async function A(e) {
98
98
  }
99
99
  return console.log(`[Dev Launcher] Launching Storybook for ${e.name}...`), ne(e, e.timeoutMs ?? 120 * 1e3);
100
100
  }
101
- const N = j(U(import.meta.url));
101
+ const _ = N(G(import.meta.url));
102
102
  function ie(e) {
103
103
  const t = process.platform === "darwin" ? "open" : process.platform === "win32" ? "start" : "xdg-open";
104
- console.log(`[Dev Launcher] Auto-launching browser: ${e}`), _(t, [e], { shell: process.platform === "win32" }).on(
104
+ console.log(`[Dev Launcher] Auto-launching browser: ${e}`), I(t, [e], { shell: process.platform === "win32" }).on(
105
105
  "error",
106
106
  (r) => {
107
107
  console.error("[Dev Launcher] Failed to auto-launch browser:", r);
@@ -114,26 +114,26 @@ async function ae(e, t, r = {}) {
114
114
  throw new Error(
115
115
  "adapter-tester dev mode requires exactly two targets: [sourceOfTruth, target] — check adapter-tester.config.json."
116
116
  );
117
- const f = r.port ?? 6010;
117
+ const p = r.port ?? 6010;
118
118
  console.log(
119
119
  `[Dev Launcher] Resolving ${o.name} and ${s.name} Storybooks...`
120
120
  );
121
121
  const [y, w] = await Promise.all([
122
- A(
123
- E(o.name, n)
122
+ D(
123
+ A(o.name, n)
124
124
  ),
125
- A(E(s.name, l))
125
+ D(A(s.name, l))
126
126
  ]);
127
127
  console.log("[Dev Launcher] Both Storybooks are active and responsive!");
128
128
  const i = [y.process, w.process].filter(
129
129
  (m) => m !== null
130
- ), u = K(), p = a(N, "../public"), v = a(N, "../report-header.txt");
131
- u.get("/", (m, b, T) => {
130
+ ), u = K(), h = a(_, "../public"), v = a(_, "../report-header.txt");
131
+ u.get("/", (m, b, k) => {
132
132
  if (m.query.path) {
133
- T();
133
+ k();
134
134
  return;
135
135
  }
136
- const q = S(a(p, "index.html"), "utf8").replace(
136
+ const S = T(a(h, "index.html"), "utf8").replace(
137
137
  "<head>",
138
138
  `<head>
139
139
  <script>window.__ADAPTER_TESTER__ = ${JSON.stringify({
@@ -142,14 +142,14 @@ async function ae(e, t, r = {}) {
142
142
  sourceOfTruthPort: y.port
143
143
  })};<\/script>`
144
144
  );
145
- b.send(q);
145
+ b.send(S);
146
146
  }), u.get("/report-header.txt", (m, b) => {
147
147
  if (e.reportHeader !== void 0) {
148
148
  b.type("text/plain").send(e.reportHeader);
149
149
  return;
150
150
  }
151
151
  try {
152
- b.type("text/plain").send(S(v, "utf8"));
152
+ b.type("text/plain").send(T(v, "utf8"));
153
153
  } catch {
154
154
  b.status(500).send("Error loading report-header.txt");
155
155
  }
@@ -162,7 +162,7 @@ async function ae(e, t, r = {}) {
162
162
  })
163
163
  );
164
164
  let c = !1;
165
- const h = () => {
165
+ const f = () => {
166
166
  if (!c) {
167
167
  c = !0, console.log(
168
168
  `
@@ -172,16 +172,16 @@ async function ae(e, t, r = {}) {
172
172
  process.exit(0);
173
173
  }
174
174
  };
175
- process.on("SIGINT", h), process.on("SIGTERM", h), u.listen(f, () => {
175
+ process.on("SIGINT", f), process.on("SIGTERM", f), u.listen(p, () => {
176
176
  console.log(`
177
177
  ====================================================
178
178
  🚀 Adapter Dev Mode proxy running at:
179
- http://localhost:${f}
179
+ http://localhost:${p}
180
180
  ====================================================
181
- `), ie(`http://localhost:${f}`);
181
+ `), ie(`http://localhost:${p}`);
182
182
  });
183
183
  }
184
- const ce = "http://json-schema.org/draft-07/schema#", de = "https://github.com/borderux/recursica/tree/main/packages/adapter-tester/src/adapter-tester.schema.json", ue = "adapter-tester.config.json", le = "Configuration for @recursica/adapter-tester. All fields are optional — an adapter repo with a normal `storybook` npm script needs no config file at all.", pe = "object", he = !1, fe = { $schema: { type: "string", description: 'Optional pointer to this schema for editor autocomplete, e.g. "https://raw.githubusercontent.com/borderux/recursica/main/packages/adapter-tester/src/adapter-tester.schema.json".' }, name: { type: "string", description: `Label for this project's own target. Defaults to the unscoped name in this project's package.json (e.g. "@recursica/some-adapter" -> "some-adapter").` }, storybook: { type: "object", additionalProperties: !1, description: "This project's own Storybook target.", properties: { port: { type: "integer", minimum: 1, maximum: 65535, description: "First-guess port only, not authoritative — the real port is auto-detected from this Storybook's own startup output, since Storybook silently falls back to an OS-assigned port whenever this one is taken. Auto-detected from this project's own `scripts.storybook` (a `-p <port>`/`--port <port>` flag) when omitted, falling back to 6006." }, command: { type: "string", description: "Command that boots the target's Storybook. Defaults to `npm run storybook`." }, cwd: { type: "string", description: 'Directory the command runs in, relative to the config file. Defaults to ".".' } } }, sourceOfTruth: { description: 'The comparison target. Defaults to `{ "type": "mantine-harness" }`.', oneOf: [{ type: "object", additionalProperties: !1, description: "Default mode: boots a throwaway harness that installs the published @recursica/adapter-mantine-v8 from npm — no monorepo checkout required.", properties: { type: { const: "mantine-harness" }, port: { type: "integer", minimum: 1, maximum: 65535, description: "First-guess port only, not authoritative — the real port is auto-detected from the throwaway harness's Storybook's own startup output." }, mantineAdapterVersion: { type: "string", description: "npm version/tag of @recursica/adapter-mantine-v8 to install in the harness. Defaults to `latest`." }, storybookTemplateVersion: { type: "string", description: "npm version/tag of @recursica/storybook-template to install in the harness. Defaults to `latest`." } } }, { type: "object", additionalProperties: !1, description: "Non-standard mode: points at an already-addressable Storybook — e.g. a sibling workspace package's own Storybook inside this monorepo.", required: ["type"], properties: { type: { const: "url" }, name: { type: "string", description: 'Label for the source-of-truth target. Defaults to "Mantine".' }, port: { type: "integer", minimum: 1, maximum: 65535, description: "First-guess port only, not authoritative — the real port is auto-detected from the source-of-truth Storybook's own startup output. Defaults to 6011." }, command: { type: "string", description: "Command that boots the source-of-truth Storybook. Defaults to `npm run storybook`." }, cwd: { type: "string", description: 'Directory the command runs in, relative to the config file. Defaults to ".".' } } }] }, isSourceOfTruthAdapter: { type: "boolean", description: "True only for the source-of-truth adapter's own config (mantine-adapter). Skips `sourceOfTruth` entirely — there's nothing above it to diverge from — and runs the own-drift golden check standalone, against just this project's own Storybook. Defaults to false." }, goldenThresholdPixels: { type: "number", minimum: 0, description: "Global visual diff threshold for the own-drift check (this project's live render vs. its own committed `test/golden/` image), in mismatched pixels, before a story is considered a failure. Same library/component on both sides, so this should stay tight. Defaults to 10. AI agents must not modify this field — see AGENT.md.", default: 10 }, sourceOfTruthThresholdPixels: { type: "number", minimum: 0, description: "Global visual diff threshold for the source-of-truth divergence check (this project's golden vs. the source-of-truth adapter's golden), in mismatched pixels, before a difference is flagged. Comparing across two different component libraries has legitimate structural variation (native control widgets, font rendering, etc.), so this is expected to be set much higher than `goldenThresholdPixels`. Ignored on the source-of-truth adapter's own config (`isSourceOfTruthAdapter: true`), which has no divergence check. Defaults to 3500. AI agents must not modify this field — see AGENT.md.", default: 3500 }, stories: { type: "object", additionalProperties: { type: "object", additionalProperties: !1, properties: { goldenThreshold: { type: "number", minimum: 0, description: "Diff threshold override for matching stories' own-drift check, in mismatched pixels. Overrides `goldenThresholdPixels`." }, sourceOfTruthThreshold: { type: "number", minimum: 0, description: "Diff threshold override for matching stories' source-of-truth divergence check, in mismatched pixels. Overrides `sourceOfTruthThresholdPixels`." }, exclude: { type: "boolean", description: "Skip matching stories entirely — no own-drift check, no divergence check, no golden captured. For stories that don't have a cross-adapter counterpart; use `excludeTitlePrefixes` to drop a whole title instead." } } }, description: "Per-story overrides, keyed by story id prefix (a story matches if its id equals the key or starts with it). When more than one key matches a story, the longest (most specific) key wins." }, excludeTitlePrefixes: { type: "array", items: { type: "string" }, description: "Storybook title prefixes to exclude from comparison, in addition to the built-in denylist (`Theme/*`, `Tokens/*`, `Introduction`)." }, reportHeader: { type: "string", description: 'Overrides the AI report header text shown in Dev Mode\'s "Full Report" export. Defaults to the contents of `report-header.txt`.' } }, me = {
184
+ const ce = "http://json-schema.org/draft-07/schema#", de = "https://github.com/borderux/recursica/tree/main/packages/adapter-tester/src/adapter-tester.schema.json", ue = "adapter-tester.config.json", le = "Configuration for @recursica/adapter-tester. All fields are optional — an adapter repo with a normal `storybook` npm script needs no config file at all.", pe = "object", he = !1, fe = { $schema: { type: "string", description: 'Optional pointer to this schema for editor autocomplete, e.g. "https://raw.githubusercontent.com/borderux/recursica/main/packages/adapter-tester/src/adapter-tester.schema.json".' }, name: { type: "string", description: `Label for this project's own target. Defaults to the unscoped name in this project's package.json (e.g. "@recursica/some-adapter" -> "some-adapter").` }, storybook: { type: "object", additionalProperties: !1, description: "This project's own Storybook target.", properties: { port: { type: "integer", minimum: 1, maximum: 65535, description: "First-guess port only, not authoritative — the real port is auto-detected from this Storybook's own startup output, since Storybook silently falls back to an OS-assigned port whenever this one is taken. Auto-detected from this project's own `scripts.storybook` (a `-p <port>`/`--port <port>` flag) when omitted, falling back to 6006." }, command: { type: "string", description: "Command that boots the target's Storybook. Defaults to `npm run storybook`." }, cwd: { type: "string", description: 'Directory the command runs in, relative to the config file. Defaults to ".".' } } }, sourceOfTruth: { description: 'The comparison target. Defaults to `{ "type": "mantine-harness" }`.', oneOf: [{ type: "object", additionalProperties: !1, description: "Default mode: boots a throwaway harness that installs the published @recursica/adapter-mantine-v8 from npm — no monorepo checkout required.", properties: { type: { const: "mantine-harness" }, port: { type: "integer", minimum: 1, maximum: 65535, description: "First-guess port only, not authoritative — the real port is auto-detected from the throwaway harness's Storybook's own startup output." }, mantineAdapterVersion: { type: "string", description: "npm version/tag of @recursica/adapter-mantine-v8 to install in the harness. Defaults to `latest`." }, storybookTemplateVersion: { type: "string", description: "npm version/tag of @recursica/storybook-template to install in the harness. Defaults to `latest`." }, tokensSource: { type: "string", enum: ["target", "mantine-package"], description: `Which Recursica token snapshot the harness's Mantine components render with. "target" (default): this project's own committed recursica_variables_scoped.css/recursica_tokens.json/recursica_brand.json/recursica_ui-kit.json — makes the divergence check mean exactly "given the same tokens this project is using, does it render the same as Mantine's own components," isolating adapter-mapping correctness from any token-snapshot drift between repos. "mantine-package": @recursica/adapter-mantine-v8's own bundled token files instead (whatever it was last published with) — also flags, as a side effect, a project whose own committed tokens have gone stale relative to Mantine's. Never the deprecated @recursica/official-release package.` } } }, { type: "object", additionalProperties: !1, description: "Non-standard mode: points at an already-addressable Storybook — e.g. a sibling workspace package's own Storybook inside this monorepo.", required: ["type"], properties: { type: { const: "url" }, name: { type: "string", description: 'Label for the source-of-truth target. Defaults to "Mantine".' }, port: { type: "integer", minimum: 1, maximum: 65535, description: "First-guess port only, not authoritative — the real port is auto-detected from the source-of-truth Storybook's own startup output. Defaults to 6011." }, command: { type: "string", description: "Command that boots the source-of-truth Storybook. Defaults to `npm run storybook`." }, cwd: { type: "string", description: 'Directory the command runs in, relative to the config file. Defaults to ".".' } } }] }, isSourceOfTruthAdapter: { type: "boolean", description: "True only for the source-of-truth adapter's own config (@recursica/adapter-mantine-v8). Skips `sourceOfTruth` entirely — there's nothing above it to diverge from — and runs the own-drift golden check standalone, against just this project's own Storybook. Defaults to false." }, goldenThresholdPixels: { type: "number", minimum: 0, description: "Global visual diff threshold for the own-drift check (this project's live render vs. its own committed `test/golden/` image), in mismatched pixels, before a story is considered a failure. Same library/component on both sides, so this should stay tight. Defaults to 10. AI agents must not modify this field — see AGENT.md.", default: 10 }, sourceOfTruthThresholdPixels: { type: "number", minimum: 0, description: "Global visual diff threshold for the source-of-truth divergence check (this project's golden vs. the source-of-truth adapter's golden), in mismatched pixels, before a difference is flagged. Comparing across two different component libraries has legitimate structural variation (native control widgets, font rendering, etc.), so this is expected to be set much higher than `goldenThresholdPixels`. Ignored on the source-of-truth adapter's own config (`isSourceOfTruthAdapter: true`), which has no divergence check. Defaults to 3500. AI agents must not modify this field — see AGENT.md.", default: 3500 }, stories: { type: "object", additionalProperties: { type: "object", additionalProperties: !1, properties: { goldenThreshold: { type: "number", minimum: 0, description: "Diff threshold override for matching stories' own-drift check, in mismatched pixels. Overrides `goldenThresholdPixels`." }, sourceOfTruthThreshold: { type: "number", minimum: 0, description: "Diff threshold override for matching stories' source-of-truth divergence check, in mismatched pixels. Overrides `sourceOfTruthThresholdPixels`." }, exclude: { type: "boolean", description: "Skip matching stories entirely — no own-drift check, no divergence check, no golden captured. For stories that don't have a cross-adapter counterpart; use `excludeTitlePrefixes` to drop a whole title instead." } } }, description: "Per-story overrides, keyed by story id prefix (a story matches if its id equals the key or starts with it). When more than one key matches a story, the longest (most specific) key wins." }, excludeTitlePrefixes: { type: "array", items: { type: "string" }, description: "Storybook title prefixes to exclude from comparison, in addition to the built-in denylist (`Theme/*`, `Tokens/*`, `Introduction`)." }, reportHeader: { type: "string", description: 'Overrides the AI report header text shown in Dev Mode\'s "Full Report" export. Defaults to the contents of `report-header.txt`.' } }, me = {
185
185
  $schema: ce,
186
186
  $id: de,
187
187
  title: ue,
@@ -189,9 +189,9 @@ const ce = "http://json-schema.org/draft-07/schema#", de = "https://github.com/b
189
189
  type: pe,
190
190
  additionalProperties: he,
191
191
  properties: fe
192
- }, ge = Z, G = new Q.Ajv({ allErrors: !0, strict: !0 });
193
- ge(G);
194
- const L = G.compile(me);
192
+ }, ge = Z, V = new Q.Ajv({ allErrors: !0, strict: !0 });
193
+ ge(V);
194
+ const L = V.compile(me);
195
195
  function ye(e, t) {
196
196
  if (L(e)) return;
197
197
  const r = (L.errors ?? []).map((o) => {
@@ -203,48 +203,48 @@ function ye(e, t) {
203
203
  throw new Error(`Invalid ${t}:
204
204
  ${r}`);
205
205
  }
206
- const we = "@recursica/adapter-mantine-v8", ve = "adapter-tester.config.json", F = "npm run storybook", be = 6006, R = 6011, C = "Mantine", Te = 10, Se = 3500;
207
- function V(e) {
206
+ const we = "@recursica/adapter-mantine-v8", ve = "adapter-tester.config.json", R = "npm run storybook", be = 6006, F = 6011, C = "Mantine", ke = 10, Te = 3500;
207
+ function H(e) {
208
208
  const t = a(e, "package.json");
209
- if (!M(t))
209
+ if (!U(t))
210
210
  throw new Error(
211
211
  `No package.json found in ${e} — run adapter-tester from the root of the project being tested.`
212
212
  );
213
- return JSON.parse(S(t, "utf8"));
213
+ return JSON.parse(T(t, "utf8"));
214
214
  }
215
- function ke(e) {
215
+ function Se(e) {
216
216
  var s;
217
- const r = (s = V(e).scripts) == null ? void 0 : s.storybook, o = r == null ? void 0 : r.match(/(?:-p|--port)[ =](\d+)/);
217
+ const r = (s = H(e).scripts) == null ? void 0 : s.storybook, o = r == null ? void 0 : r.match(/(?:-p|--port)[ =](\d+)/);
218
218
  return o ? Number(o[1]) : be;
219
219
  }
220
220
  function Oe(e) {
221
- const r = V(e).name;
221
+ const r = H(e).name;
222
222
  return r ? r.split("/").pop() : "Adapter";
223
223
  }
224
224
  function xe(e) {
225
225
  const t = a(e, ve);
226
- if (!M(t))
226
+ if (!U(t))
227
227
  return {};
228
- const r = JSON.parse(S(t, "utf8"));
228
+ const r = JSON.parse(T(t, "utf8"));
229
229
  return ye(r, t), r;
230
230
  }
231
231
  function Ee(e, t = {}) {
232
- var h, m, b;
232
+ var f, m, b;
233
233
  const r = xe(e), o = r.isSourceOfTruthAdapter ?? !1;
234
234
  if (t.mantineAdapterVersion && o)
235
235
  throw new Error(
236
236
  "--source-of-truth-version has no effect on the source-of-truth adapter's own config (isSourceOfTruthAdapter: true) — there's nothing to pin a version for."
237
237
  );
238
- const s = r.name ?? Oe(e), n = ((h = r.storybook) == null ? void 0 : h.port) ?? ke(e), l = ((m = r.storybook) == null ? void 0 : m.command) ?? F, f = $(e, ((b = r.storybook) == null ? void 0 : b.cwd) ?? "."), y = {
238
+ const s = r.name ?? Oe(e), n = ((f = r.storybook) == null ? void 0 : f.port) ?? Se(e), l = ((m = r.storybook) == null ? void 0 : m.command) ?? R, p = $(e, ((b = r.storybook) == null ? void 0 : b.cwd) ?? "."), y = {
239
239
  command: l,
240
240
  port: n,
241
- cwd: f,
241
+ cwd: p,
242
242
  reuseExistingServer: !process.env.CI,
243
243
  cacheFile: a(e, ".adapter-tester", "last-port-own.json"),
244
244
  timeout: 120 * 1e3
245
245
  }, w = {
246
- goldenThresholdPixels: r.goldenThresholdPixels ?? Te,
247
- sourceOfTruthThresholdPixels: r.sourceOfTruthThresholdPixels ?? Se,
246
+ goldenThresholdPixels: r.goldenThresholdPixels ?? ke,
247
+ sourceOfTruthThresholdPixels: r.sourceOfTruthThresholdPixels ?? Te,
248
248
  stories: r.stories,
249
249
  excludeTitlePrefixes: r.excludeTitlePrefixes,
250
250
  reportHeader: r.reportHeader,
@@ -254,7 +254,7 @@ function Ee(e, t = {}) {
254
254
  // to that package's own `test/golden/` (the same directory used when
255
255
  // that package runs adapter-tester directly), not a directory under
256
256
  // wherever this config file lives.
257
- goldenDir: a(f, "test", "golden"),
257
+ goldenDir: a(p, "test", "golden"),
258
258
  isSourceOfTruthAdapter: o,
259
259
  // Overwritten by the CLI from --update-golden/--approve-divergence.
260
260
  goldenMode: "check",
@@ -272,37 +272,42 @@ function Ee(e, t = {}) {
272
272
  const i = r.sourceOfTruth ?? {
273
273
  type: "mantine-harness"
274
274
  };
275
- let u, p, v, c;
275
+ let u, h, v, c;
276
276
  if (i.type === "url") {
277
277
  if (t.mantineAdapterVersion)
278
278
  throw new Error(
279
279
  `--source-of-truth-version has no effect with sourceOfTruth.type: "url" — that mode reads a sibling package's local checkout directly, not a published version.`
280
280
  );
281
- u = i.name ?? C, p = i.port ?? R;
282
- const T = $(e, i.cwd ?? ".");
281
+ u = i.name ?? C, h = i.port ?? F;
282
+ const k = $(e, i.cwd ?? ".");
283
283
  v = {
284
- command: i.command ?? F,
285
- port: p,
286
- cwd: T,
284
+ command: i.command ?? R,
285
+ port: h,
286
+ cwd: k,
287
287
  reuseExistingServer: !process.env.CI,
288
288
  cacheFile: a(e, ".adapter-tester", "last-port-source-of-truth.json"),
289
289
  timeout: 120 * 1e3
290
290
  }, c = {
291
291
  type: "local",
292
- dir: a(T, "test", "golden")
292
+ dir: a(k, "test", "golden")
293
293
  };
294
294
  } else {
295
- u = C, p = i.port ?? R;
296
- const T = t.mantineAdapterVersion ?? i.mantineAdapterVersion;
295
+ u = C, h = i.port ?? F;
296
+ const k = t.mantineAdapterVersion ?? i.mantineAdapterVersion, S = i.tokensSource ?? "target";
297
297
  v = z({
298
298
  dir: a(e, ".adapter-tester/mantine-harness"),
299
- port: p,
300
- mantineAdapterVersion: T,
301
- storybookTemplateVersion: i.storybookTemplateVersion
299
+ port: h,
300
+ mantineAdapterVersion: k,
301
+ storybookTemplateVersion: i.storybookTemplateVersion,
302
+ tokensSource: S,
303
+ // `ownCwd`, not `cwd` — the project actually being tested (same
304
+ // reasoning `goldenDir` above uses), source of the 4 token files
305
+ // copied into the harness when `tokensSource` is "target".
306
+ targetDir: p
302
307
  }), c = {
303
308
  type: "npm",
304
309
  packageName: we,
305
- versionSpec: T ?? "latest",
310
+ versionSpec: k ?? "latest",
306
311
  cacheDir: a(e, ".adapter-tester/mantine-golden-cache")
307
312
  };
308
313
  }
@@ -312,7 +317,7 @@ function Ee(e, t = {}) {
312
317
  targets: [
313
318
  {
314
319
  name: u,
315
- url: `http://localhost:${p}`,
320
+ url: `http://localhost:${h}`,
316
321
  sourceOfTruth: !0
317
322
  },
318
323
  { name: s, url: `http://localhost:${n}` }
@@ -325,29 +330,29 @@ function Ee(e, t = {}) {
325
330
  webServers: [v, y]
326
331
  };
327
332
  }
328
- const Ae = j(U(import.meta.url)), De = B(a(Ae, "testing.js")).href, d = process.argv.slice(2);
329
- let H;
330
- const k = d.indexOf("--source-of-truth-version");
331
- if (k !== -1) {
332
- const e = d[k + 1];
333
+ const Ae = N(G(import.meta.url)), De = B(a(Ae, "testing.js")).href, d = process.argv.slice(2);
334
+ let J;
335
+ const O = d.indexOf("--source-of-truth-version");
336
+ if (O !== -1) {
337
+ const e = d[O + 1];
333
338
  if (e === void 0 || e.startsWith("--"))
334
339
  throw new Error(
335
340
  "--source-of-truth-version requires a value, e.g. --source-of-truth-version 0.53.0"
336
341
  );
337
- H = e, d.splice(k, 2);
342
+ J = e, d.splice(O, 2);
338
343
  }
339
- let J;
340
- const O = d.indexOf("--story");
341
- if (O !== -1) {
342
- const e = d[O + 1];
344
+ let q;
345
+ const x = d.indexOf("--story");
346
+ if (x !== -1) {
347
+ const e = d[x + 1];
343
348
  if (e === void 0 || e.startsWith("--"))
344
349
  throw new Error(
345
350
  "--story requires a story id, e.g. --story ui-kit-button--loading"
346
351
  );
347
- J = e, d.splice(O, 2);
352
+ q = e, d.splice(x, 2);
348
353
  }
349
- const D = process.cwd(), { engineConfig: g, webServers: P } = Ee(D, {
350
- mantineAdapterVersion: H
354
+ const P = process.cwd(), { engineConfig: g, webServers: j } = Ee(P, {
355
+ mantineAdapterVersion: J
351
356
  });
352
357
  d.includes("--update-golden") ? g.goldenMode = "update-golden" : d.includes("--approve-divergence") && (g.goldenMode = "approve-divergence");
353
358
  if (d.includes("--divergence-only")) {
@@ -360,7 +365,7 @@ if (d.includes("--divergence-only")) {
360
365
  throw new Error(
361
366
  "--approve-divergence only makes sense with --divergence-only — there's nothing to approve without the divergence check running."
362
367
  );
363
- d.includes("--dry-run") && (console.log(JSON.stringify({ engineConfig: g, webServers: P }, null, 2)), process.exit(0));
368
+ d.includes("--dry-run") && (console.log(JSON.stringify({ engineConfig: g, webServers: j }, null, 2)), process.exit(0));
364
369
  const Pe = /* @__PURE__ */ new Set([
365
370
  "--dry-run",
366
371
  "--serve",
@@ -368,33 +373,33 @@ const Pe = /* @__PURE__ */ new Set([
368
373
  "--approve-divergence",
369
374
  "--divergence-only"
370
375
  ]), je = d.filter((e) => !Pe.has(e));
371
- $e().catch((e) => {
376
+ Ne().catch((e) => {
372
377
  console.error(e), process.exitCode = 1;
373
378
  });
374
- async function $e() {
379
+ async function Ne() {
375
380
  if (d.includes("--serve")) {
376
381
  if (g.isSourceOfTruthAdapter)
377
382
  throw new Error(
378
383
  "Dev Mode (--serve) has nothing to sync this project's Storybook against — isSourceOfTruthAdapter is true in this project's adapter-tester.config.json."
379
384
  );
380
- await ae(g, P);
385
+ await ae(g, j);
381
386
  } else {
382
- const e = P.at(-1);
387
+ const e = j.at(-1);
383
388
  if (!e)
384
389
  throw new Error("resolveConfig() returned no webServers to boot.");
385
- await Ne(e, g);
390
+ await $e(e, g);
386
391
  }
387
392
  }
388
- async function Ne(e, t) {
389
- const r = a(D, ".adapter-tester/run");
390
- I(r, { recursive: !0 });
393
+ async function $e(e, t) {
394
+ const r = a(P, ".adapter-tester/run");
395
+ M(r, { recursive: !0 });
391
396
  const o = t.targets.at(-1);
392
397
  if (!o)
393
398
  throw new Error("resolveConfig() returned no targets to check.");
394
- const { url: s, process: n } = await A(
395
- E(o.name, e)
399
+ const { url: s, process: n } = await D(
400
+ A(o.name, e)
396
401
  );
397
- o.url = s, x(
402
+ o.url = s, E(
398
403
  a(r, "playwright.config.js"),
399
404
  `// Generated by \`adapter-tester\` — do not edit, regenerated on every run.
400
405
  import { defineConfig, devices } from "@playwright/test";
@@ -417,7 +422,7 @@ export default defineConfig({
417
422
  // the time this config is used (see runAutomated() in cli.ts).
418
423
  });
419
424
  `
420
- ), x(
425
+ ), E(
421
426
  a(r, "visual-regression.spec.js"),
422
427
  `// Generated by \`adapter-tester\` — do not edit, regenerated on every run.
423
428
  import { test, expect } from "@playwright/test";
@@ -431,7 +436,7 @@ const { ownTargetName, suiteLabel, stories, missingFromSourceOfTruth, checkStory
431
436
 
432
437
  // Set from \`--story <story-id>\` — scopes this run to exactly one story and
433
438
  // skips the (suite-wide) parity check, which has nothing to do with it.
434
- const storyId = ${JSON.stringify(J ?? null)};
439
+ const storyId = ${JSON.stringify(q ?? null)};
435
440
  const scopedStories = storyId
436
441
  ? stories.filter((story) => story.id === storyId)
437
442
  : stories;
@@ -466,7 +471,7 @@ test.describe(\`\${ownTargetName} — \${suiteLabel}\`, () => {
466
471
  a(r, "playwright.config.js"),
467
472
  ...je
468
473
  ],
469
- { stdio: "inherit", cwd: D, shell: process.platform === "win32" }
474
+ { stdio: "inherit", cwd: P, shell: process.platform === "win32" }
470
475
  );
471
476
  process.exitCode = l.status ?? 1;
472
477
  } finally {