@component-compass/cli 0.1.25 → 0.1.27

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.
Files changed (2) hide show
  1. package/dist/cli.js +1059 -995
  2. package/package.json +4 -4
package/dist/cli.js CHANGED
@@ -7554,16 +7554,16 @@ var require_parse = __commonJS({
7554
7554
  const analysis = analyzeRepeatedExtglob(body, opts);
7555
7555
  if ((token.type === "plus" || token.type === "star") && analysis.risky) {
7556
7556
  const safeOutput = analysis.safeOutput ? (token.output ? "" : ONE_CHAR) + (opts.capture ? `(${analysis.safeOutput})` : analysis.safeOutput) : void 0;
7557
- const open = tokens[token.tokensIndex];
7558
- open.type = "text";
7559
- open.value = literal;
7560
- open.output = safeOutput || utils.escapeRegex(literal);
7557
+ const open2 = tokens[token.tokensIndex];
7558
+ open2.type = "text";
7559
+ open2.value = literal;
7560
+ open2.output = safeOutput || utils.escapeRegex(literal);
7561
7561
  for (let i2 = token.tokensIndex + 1; i2 < tokens.length; i2++) {
7562
7562
  tokens[i2].value = "";
7563
7563
  tokens[i2].output = "";
7564
7564
  delete tokens[i2].suffix;
7565
7565
  }
7566
- state.output = token.output + open.output;
7566
+ state.output = token.output + open2.output;
7567
7567
  state.backtrack = true;
7568
7568
  push({ type: "paren", extglob: true, value, output: "" });
7569
7569
  decrement("parens");
@@ -7783,15 +7783,15 @@ var require_parse = __commonJS({
7783
7783
  }
7784
7784
  if (value === "{" && opts.nobrace !== true) {
7785
7785
  increment("braces");
7786
- const open = {
7786
+ const open2 = {
7787
7787
  type: "brace",
7788
7788
  value,
7789
7789
  output: "(",
7790
7790
  outputIndex: state.output.length,
7791
7791
  tokensIndex: state.tokens.length
7792
7792
  };
7793
- braces.push(open);
7794
- push(open);
7793
+ braces.push(open2);
7794
+ push(open2);
7795
7795
  continue;
7796
7796
  }
7797
7797
  if (value === "}") {
@@ -37172,9 +37172,9 @@ var require_is_glob = __commonJS({
37172
37172
  }
37173
37173
  }
37174
37174
  if (str[index] === "\\") {
37175
- var open = str[index + 1];
37175
+ var open2 = str[index + 1];
37176
37176
  index += 2;
37177
- var close = chars2[open];
37177
+ var close = chars2[open2];
37178
37178
  if (close) {
37179
37179
  var n2 = str.indexOf(close, index);
37180
37180
  if (n2 !== -1) {
@@ -37200,9 +37200,9 @@ var require_is_glob = __commonJS({
37200
37200
  return true;
37201
37201
  }
37202
37202
  if (str[index] === "\\") {
37203
- var open = str[index + 1];
37203
+ var open2 = str[index + 1];
37204
37204
  index += 2;
37205
- var close = chars2[open];
37205
+ var close = chars2[open2];
37206
37206
  if (close) {
37207
37207
  var n2 = str.indexOf(close, index);
37208
37208
  if (n2 !== -1) {
@@ -38166,7 +38166,7 @@ var require_parse2 = __commonJS({
38166
38166
  continue;
38167
38167
  }
38168
38168
  if (value === CHAR_DOUBLE_QUOTE || value === CHAR_SINGLE_QUOTE || value === CHAR_BACKTICK) {
38169
- const open = value;
38169
+ const open2 = value;
38170
38170
  let next;
38171
38171
  if (options.keepQuotes !== true) {
38172
38172
  value = "";
@@ -38176,7 +38176,7 @@ var require_parse2 = __commonJS({
38176
38176
  value += next + advance();
38177
38177
  continue;
38178
38178
  }
38179
- if (next === open) {
38179
+ if (next === open2) {
38180
38180
  if (options.keepQuotes === true) value += next;
38181
38181
  break;
38182
38182
  }
@@ -38219,8 +38219,8 @@ var require_parse2 = __commonJS({
38219
38219
  if (value === CHAR_COMMA && depth > 0) {
38220
38220
  if (block2.ranges > 0) {
38221
38221
  block2.ranges = 0;
38222
- const open = block2.nodes.shift();
38223
- block2.nodes = [open, { type: "text", value: stringify2(block2) }];
38222
+ const open2 = block2.nodes.shift();
38223
+ block2.nodes = [open2, { type: "text", value: stringify2(block2) }];
38224
38224
  }
38225
38225
  push({ type: "comma", value });
38226
38226
  block2.commas++;
@@ -39318,16 +39318,16 @@ var require_parse3 = __commonJS({
39318
39318
  const analysis = analyzeRepeatedExtglob(body, opts);
39319
39319
  if ((token.type === "plus" || token.type === "star") && analysis.risky) {
39320
39320
  const safeOutput = analysis.safeOutput ? (token.output ? "" : ONE_CHAR) + (opts.capture ? `(${analysis.safeOutput})` : analysis.safeOutput) : void 0;
39321
- const open = tokens[token.tokensIndex];
39322
- open.type = "text";
39323
- open.value = literal;
39324
- open.output = safeOutput || utils.escapeRegex(literal);
39321
+ const open2 = tokens[token.tokensIndex];
39322
+ open2.type = "text";
39323
+ open2.value = literal;
39324
+ open2.output = safeOutput || utils.escapeRegex(literal);
39325
39325
  for (let i2 = token.tokensIndex + 1; i2 < tokens.length; i2++) {
39326
39326
  tokens[i2].value = "";
39327
39327
  tokens[i2].output = "";
39328
39328
  delete tokens[i2].suffix;
39329
39329
  }
39330
- state.output = token.output + open.output;
39330
+ state.output = token.output + open2.output;
39331
39331
  state.backtrack = true;
39332
39332
  push({ type: "paren", extglob: true, value, output: "" });
39333
39333
  decrement("parens");
@@ -39547,15 +39547,15 @@ var require_parse3 = __commonJS({
39547
39547
  }
39548
39548
  if (value === "{" && opts.nobrace !== true) {
39549
39549
  increment("braces");
39550
- const open = {
39550
+ const open2 = {
39551
39551
  type: "brace",
39552
39552
  value,
39553
39553
  output: "(",
39554
39554
  outputIndex: state.output.length,
39555
39555
  tokensIndex: state.tokens.length
39556
39556
  };
39557
- braces.push(open);
39558
- push(open);
39557
+ braces.push(open2);
39558
+ push(open2);
39559
39559
  continue;
39560
39560
  }
39561
39561
  if (value === "}") {
@@ -40350,8 +40350,8 @@ var require_pattern2 = __commonJS({
40350
40350
  }
40351
40351
  exports.endsWithSlashGlobStar = endsWithSlashGlobStar;
40352
40352
  function isAffectDepthOfReadingPattern(pattern) {
40353
- const basename6 = path5.basename(pattern);
40354
- return endsWithSlashGlobStar(pattern) || isStaticPattern(basename6);
40353
+ const basename7 = path5.basename(pattern);
40354
+ return endsWithSlashGlobStar(pattern) || isStaticPattern(basename7);
40355
40355
  }
40356
40356
  exports.isAffectDepthOfReadingPattern = isAffectDepthOfReadingPattern;
40357
40357
  function expandPatternsWithBraceExpansion(patterns) {
@@ -40398,7 +40398,7 @@ var require_pattern2 = __commonJS({
40398
40398
  const absolute = [];
40399
40399
  const relative7 = [];
40400
40400
  for (const pattern of patterns) {
40401
- if (isAbsolute13(pattern)) {
40401
+ if (isAbsolute14(pattern)) {
40402
40402
  absolute.push(pattern);
40403
40403
  } else {
40404
40404
  relative7.push(pattern);
@@ -40407,10 +40407,10 @@ var require_pattern2 = __commonJS({
40407
40407
  return [absolute, relative7];
40408
40408
  }
40409
40409
  exports.partitionAbsoluteAndRelative = partitionAbsoluteAndRelative;
40410
- function isAbsolute13(pattern) {
40410
+ function isAbsolute14(pattern) {
40411
40411
  return path5.isAbsolute(pattern);
40412
40412
  }
40413
- exports.isAbsolute = isAbsolute13;
40413
+ exports.isAbsolute = isAbsolute14;
40414
40414
  }
40415
40415
  });
40416
40416
 
@@ -43241,7 +43241,7 @@ async function pollUpload(opts) {
43241
43241
  status = await inspect3().catch(async (err2) => {
43242
43242
  if (!(err2 instanceof UploadError) || err2.code !== 401) throw err2;
43243
43243
  signal.throwIfAborted();
43244
- token = await opts.refreshToken();
43244
+ token = await opts.onUnauthorized();
43245
43245
  return await inspect3();
43246
43246
  });
43247
43247
  } catch (err2) {
@@ -43267,8 +43267,8 @@ async function pollUpload(opts) {
43267
43267
  }
43268
43268
  hint = status.retryAfterSeconds;
43269
43269
  }
43270
- const delay = hint !== void 0 ? hint * 1e3 : backoffDelay(attempt);
43271
- await wait(Math.min(2147483647, Math.max(1e3, delay)), signal);
43270
+ const delay2 = hint !== void 0 ? hint * 1e3 : backoffDelay(attempt);
43271
+ await wait(Math.min(2147483647, Math.max(1e3, delay2)), signal);
43272
43272
  }
43273
43273
  }
43274
43274
  try {
@@ -43282,7 +43282,7 @@ async function pollUpload(opts) {
43282
43282
  controller.abort();
43283
43283
  }
43284
43284
  }
43285
- function wait(delay, signal) {
43285
+ function wait(delay2, signal) {
43286
43286
  return new Promise((resolve14, reject) => {
43287
43287
  signal?.throwIfAborted();
43288
43288
  const abort = () => {
@@ -43292,7 +43292,7 @@ function wait(delay, signal) {
43292
43292
  const timer = setTimeout(() => {
43293
43293
  signal?.removeEventListener("abort", abort);
43294
43294
  resolve14();
43295
- }, delay);
43295
+ }, delay2);
43296
43296
  signal?.addEventListener("abort", abort, { once: true });
43297
43297
  });
43298
43298
  }
@@ -43389,8 +43389,10 @@ var init_paths = __esm({
43389
43389
  });
43390
43390
 
43391
43391
  // src/auth/store.ts
43392
- import { mkdir as mkdir2, readFile as readFile4, writeFile as writeFile2, chmod } from "node:fs/promises";
43393
- import { dirname as dirname12 } from "node:path";
43392
+ import { mkdir as mkdir2, readFile as readFile4, writeFile as writeFile2, chmod, rename, unlink, open } from "node:fs/promises";
43393
+ import { randomUUID } from "node:crypto";
43394
+ import { basename as basename5, dirname as dirname12, join as join16 } from "node:path";
43395
+ import { setTimeout as delay } from "node:timers/promises";
43394
43396
  function normalizeHost(input2) {
43395
43397
  const trimmed = input2.trim();
43396
43398
  if (trimmed === "") throw new Error("Host must not be empty.");
@@ -43411,107 +43413,85 @@ async function loadStore(filePath = hostsFilePath()) {
43411
43413
  } catch {
43412
43414
  throw new Error(`Token store at ${filePath} contains invalid JSON. Delete it and run \`component-compass auth login\` again.`);
43413
43415
  }
43414
- return { ...parsed.default ? { default: parsed.default } : {}, hosts: parsed.hosts ?? {} };
43416
+ const value = typeof parsed === "object" && parsed !== null && !Array.isArray(parsed) ? parsed : {};
43417
+ const entries = typeof value.hosts === "object" && value.hosts !== null && !Array.isArray(value.hosts) ? Object.entries(value.hosts) : [];
43418
+ const hosts = Object.fromEntries(entries.flatMap(([host, entry]) => {
43419
+ if (typeof entry !== "object" || entry === null || Array.isArray(entry)) return [];
43420
+ const candidate = entry;
43421
+ return typeof candidate.token === "string" && typeof candidate.userEmail === "string" ? [[host, { token: candidate.token, userEmail: candidate.userEmail }]] : [];
43422
+ }));
43423
+ return { ...typeof value.default === "string" && value.default ? { default: value.default } : {}, hosts };
43415
43424
  }
43416
- async function saveStore(store, filePath = hostsFilePath()) {
43425
+ async function writeStore(store, filePath) {
43417
43426
  await mkdir2(dirname12(filePath), { recursive: true, mode: 448 });
43418
- await writeFile2(filePath, `${JSON.stringify(store, null, 2)}
43419
- `, { mode: 384 });
43420
- await chmod(filePath, 384);
43421
- }
43422
- var init_store = __esm({
43423
- "src/auth/store.ts"() {
43424
- "use strict";
43425
- init_paths();
43427
+ const tempPath = join16(dirname12(filePath), `.${basename5(filePath)}.${randomUUID()}.tmp`);
43428
+ try {
43429
+ await writeFile2(tempPath, `${JSON.stringify(store, null, 2)}
43430
+ `, { mode: 384, flag: "wx" });
43431
+ await chmod(tempPath, 384);
43432
+ await rename(tempPath, filePath);
43433
+ } finally {
43434
+ await unlink(tempPath).catch((error2) => {
43435
+ if (error2.code !== "ENOENT") throw error2;
43436
+ });
43426
43437
  }
43427
- });
43428
-
43429
- // src/auth/client.ts
43430
- function endpoint(base2, path5) {
43431
- return `${base2.replace(/\/+$/, "")}${path5}`;
43432
- }
43433
- async function readError(res) {
43434
- const body = await res.json().catch(() => ({}));
43435
- return body.error ?? "unknown_error";
43436
43438
  }
43437
- function toTokenPair(body) {
43438
- return {
43439
- accessToken: body.access_token,
43440
- refreshToken: body.refresh_token,
43441
- expiresIn: body.expires_in,
43442
- ...body.email !== void 0 ? { email: body.email } : {}
43443
- };
43444
- }
43445
- async function requestDeviceCode(base2) {
43446
- const res = await fetch(endpoint(base2, "/api/auth/cli/device-code"), { method: "POST" });
43447
- if (!res.ok) throw new AuthHttpError(res.status, `device-code failed: ${await readError(res)}`);
43448
- const b = await res.json();
43449
- return {
43450
- deviceCode: b.device_code,
43451
- userCode: b.user_code,
43452
- verificationUri: b.verification_uri,
43453
- verificationUriComplete: b.verification_uri_complete,
43454
- expiresIn: b.expires_in,
43455
- interval: b.interval
43456
- };
43457
- }
43458
- async function pollToken(base2, deviceCode) {
43459
- const res = await fetch(endpoint(base2, "/api/auth/cli/token"), {
43460
- method: "POST",
43461
- headers: { "Content-Type": "application/json" },
43462
- body: JSON.stringify({ device_code: deviceCode })
43463
- });
43464
- if (res.ok) {
43465
- return { kind: "tokens", tokens: toTokenPair(await res.json()) };
43466
- }
43467
- const error2 = await readError(res);
43468
- switch (error2) {
43469
- case "authorization_pending":
43470
- return { kind: "pending" };
43471
- case "slow_down":
43472
- return { kind: "slow_down" };
43473
- case "expired_token":
43474
- return { kind: "expired" };
43475
- case "access_denied":
43476
- return { kind: "denied" };
43477
- default:
43478
- throw new AuthHttpError(res.status, `token poll failed: ${error2}`);
43439
+ async function releaseStoreLock(lockPath, owner) {
43440
+ try {
43441
+ if (await readFile4(lockPath, "utf8") === owner) await unlink(lockPath);
43442
+ } catch (error2) {
43443
+ if (error2.code !== "ENOENT") throw error2;
43479
43444
  }
43480
43445
  }
43481
- async function refreshTokens(base2, refreshToken) {
43482
- let res;
43446
+ async function withStoreLock(filePath, action) {
43447
+ await mkdir2(dirname12(filePath), { recursive: true, mode: 448 });
43448
+ const lockPath = `${filePath}.lock`;
43449
+ const owner = `${process.pid}:${randomUUID()}`;
43450
+ const deadline = Date.now() + LOCK_WAIT_MS;
43451
+ while (true) {
43452
+ if (Date.now() >= deadline) {
43453
+ throw new StoreLockError(`Timed out waiting for credential store lock at ${lockPath}. Retry, or remove it only after confirming no CLI process is running.`);
43454
+ }
43455
+ try {
43456
+ const handle = await open(lockPath, "wx", 384);
43457
+ try {
43458
+ await handle.writeFile(owner);
43459
+ await handle.close();
43460
+ } catch (error2) {
43461
+ await handle.close().catch(() => {
43462
+ });
43463
+ await unlink(lockPath).catch(() => {
43464
+ });
43465
+ throw error2;
43466
+ }
43467
+ break;
43468
+ } catch (error2) {
43469
+ if (error2.code !== "EEXIST") throw error2;
43470
+ await delay(LOCK_POLL_MS);
43471
+ }
43472
+ }
43483
43473
  try {
43484
- res = await fetch(endpoint(base2, "/api/auth/cli/refresh"), {
43485
- method: "POST",
43486
- headers: { "Content-Type": "application/json" },
43487
- body: JSON.stringify({ refresh_token: refreshToken })
43488
- });
43489
- } catch (err2) {
43490
- return { kind: "transient", error: err2 instanceof Error ? err2.message : "network_error" };
43474
+ return await action();
43475
+ } finally {
43476
+ await releaseStoreLock(lockPath, owner);
43491
43477
  }
43492
- if (res.ok) return { kind: "tokens", tokens: toTokenPair(await res.json()) };
43493
- const error2 = await readError(res);
43494
- const terminal = res.status === 401 && ["invalid_token", "sso_revoked", "not_authorized"].includes(error2);
43495
- return terminal ? { kind: "terminal", error: error2 } : { kind: "transient", error: error2 };
43496
43478
  }
43497
- async function whoami(base2, accessToken) {
43498
- const res = await fetch(endpoint(base2, "/api/auth/cli/whoami"), {
43499
- headers: { Authorization: `Bearer ${accessToken}` }
43479
+ async function mutateStore(change, filePath = hostsFilePath()) {
43480
+ return await withStoreLock(filePath, async () => {
43481
+ const store = await loadStore(filePath);
43482
+ const { changed, result: result2 } = change(store);
43483
+ if (changed) await writeStore(store, filePath);
43484
+ return result2;
43500
43485
  });
43501
- if (res.status === 401) return null;
43502
- if (!res.ok) throw new AuthHttpError(res.status, `whoami failed: ${await readError(res)}`);
43503
- return await res.json();
43504
43486
  }
43505
- var AuthHttpError;
43506
- var init_client = __esm({
43507
- "src/auth/client.ts"() {
43487
+ var LOCK_WAIT_MS, LOCK_POLL_MS, StoreLockError;
43488
+ var init_store = __esm({
43489
+ "src/auth/store.ts"() {
43508
43490
  "use strict";
43509
- AuthHttpError = class extends Error {
43510
- constructor(status, message) {
43511
- super(message);
43512
- this.status = status;
43513
- }
43514
- status;
43491
+ init_paths();
43492
+ LOCK_WAIT_MS = 5e3;
43493
+ LOCK_POLL_MS = 25;
43494
+ StoreLockError = class extends Error {
43515
43495
  };
43516
43496
  }
43517
43497
  });
@@ -43519,12 +43499,15 @@ var init_client = __esm({
43519
43499
  // src/auth/session.ts
43520
43500
  var session_exports = {};
43521
43501
  __export(session_exports, {
43522
- IdpUnavailableError: () => IdpUnavailableError,
43502
+ HostUnavailableError: () => HostUnavailableError,
43523
43503
  NotSignedInError: () => NotSignedInError,
43524
43504
  ReloginRequiredError: () => ReloginRequiredError,
43505
+ SessionChangedError: () => SessionChangedError,
43525
43506
  formatAuthError: () => formatAuthError,
43526
- getAccessToken: () => getAccessToken,
43527
- resolveHost: () => resolveHost
43507
+ getStoredSession: () => getStoredSession,
43508
+ removeStoredSession: () => removeStoredSession,
43509
+ resolveHost: () => resolveHost,
43510
+ setStoredSession: () => setStoredSession
43528
43511
  });
43529
43512
  function resolveHost(opts) {
43530
43513
  const env2 = opts.env ?? process.env;
@@ -43536,52 +43519,39 @@ function resolveHost(opts) {
43536
43519
  }
43537
43520
  return normalizeHost(raw);
43538
43521
  }
43539
- async function getAccessToken(host, deps = {}) {
43540
- const now = deps.now ?? Date.now;
43522
+ async function getStoredSession(host, deps = {}) {
43541
43523
  const base2 = normalizeHost(host);
43542
43524
  const store = await loadStore(deps.filePath);
43543
43525
  const entry = store.hosts[base2];
43544
43526
  if (!entry) throw new NotSignedInError(base2);
43545
- const stillValid = Date.parse(entry.expiresAt) - now() > EXPIRY_SKEW_MS;
43546
- if (stillValid && !deps.force) {
43547
- return { accessToken: entry.accessToken, userEmail: entry.userEmail };
43548
- }
43549
- const result2 = await refreshTokens(base2, entry.refreshToken);
43550
- if (result2.kind === "tokens") {
43551
- const updated = {
43552
- accessToken: result2.tokens.accessToken,
43553
- refreshToken: result2.tokens.refreshToken,
43554
- userEmail: result2.tokens.email ?? entry.userEmail,
43555
- expiresAt: new Date(now() + result2.tokens.expiresIn * 1e3).toISOString()
43556
- };
43557
- store.hosts[base2] = updated;
43558
- await saveStore(store, deps.filePath);
43559
- return { accessToken: updated.accessToken, userEmail: updated.userEmail };
43560
- }
43561
- if (result2.kind === "terminal") {
43562
- const { [base2]: _removed, ...remainingHosts } = store.hosts;
43563
- const cleared = {
43564
- hosts: remainingHosts,
43565
- ...store.default && store.default !== base2 ? { default: store.default } : {}
43566
- };
43567
- await saveStore(cleared, deps.filePath);
43568
- throw new ReloginRequiredError(base2);
43569
- }
43570
- throw new IdpUnavailableError(base2, result2.error);
43527
+ return entry;
43528
+ }
43529
+ async function setStoredSession(host, entry, deps = {}) {
43530
+ const base2 = normalizeHost(host);
43531
+ await mutateStore((store) => {
43532
+ store.hosts[base2] = entry;
43533
+ if (!store.default) store.default = base2;
43534
+ return { changed: true, result: void 0 };
43535
+ }, deps.filePath);
43536
+ }
43537
+ async function removeStoredSession(host, deps) {
43538
+ const base2 = normalizeHost(host);
43539
+ return await mutateStore((store) => {
43540
+ if (store.hosts[base2]?.token !== deps.expectedToken) return { changed: false, result: false };
43541
+ const { [base2]: _removed, ...hosts } = store.hosts;
43542
+ store.hosts = hosts;
43543
+ if (store.default === base2) store.default = void 0;
43544
+ return { changed: true, result: true };
43545
+ }, deps.filePath);
43571
43546
  }
43572
43547
  function formatAuthError(err2) {
43573
- if (err2 instanceof NotSignedInError || err2 instanceof ReloginRequiredError || err2 instanceof IdpUnavailableError) {
43574
- return err2.message;
43575
- }
43576
- return null;
43548
+ return err2 instanceof NotSignedInError || err2 instanceof ReloginRequiredError || err2 instanceof SessionChangedError || err2 instanceof HostUnavailableError ? err2.message : null;
43577
43549
  }
43578
- var EXPIRY_SKEW_MS, NotSignedInError, ReloginRequiredError, IdpUnavailableError;
43550
+ var NotSignedInError, ReloginRequiredError, SessionChangedError, HostUnavailableError;
43579
43551
  var init_session = __esm({
43580
43552
  "src/auth/session.ts"() {
43581
43553
  "use strict";
43582
43554
  init_store();
43583
- init_client();
43584
- EXPIRY_SKEW_MS = 6e4;
43585
43555
  NotSignedInError = class extends Error {
43586
43556
  constructor(host) {
43587
43557
  super(`Not signed in to ${host}. Run \`component-compass auth login --host ${host}\`.`);
@@ -43591,19 +43561,24 @@ var init_session = __esm({
43591
43561
  };
43592
43562
  ReloginRequiredError = class extends Error {
43593
43563
  constructor(host) {
43594
- super(`Session for ${host} expired or was revoked. Run \`component-compass auth login --host ${host}\`.`);
43564
+ super(`Session for ${host} is no longer valid. Run \`component-compass auth login --host ${host}\`.`);
43565
+ this.host = host;
43566
+ }
43567
+ host;
43568
+ };
43569
+ SessionChangedError = class extends Error {
43570
+ constructor(host) {
43571
+ super(`Session changed for ${host}; retry the upload with the current sign-in.`);
43595
43572
  this.host = host;
43596
43573
  }
43597
43574
  host;
43598
43575
  };
43599
- IdpUnavailableError = class extends Error {
43600
- constructor(host, reason) {
43601
- super(`Could not reach the identity provider to refresh credentials for ${host} (${reason}). Check your network and retry.`);
43576
+ HostUnavailableError = class extends Error {
43577
+ constructor(host) {
43578
+ super(`Could not reach ${host} to check the session. Check your network and retry.`);
43602
43579
  this.host = host;
43603
- this.reason = reason;
43604
43580
  }
43605
43581
  host;
43606
- reason;
43607
43582
  };
43608
43583
  }
43609
43584
  });
@@ -43623,28 +43598,27 @@ async function createAuthedUploader(opts) {
43623
43598
  });
43624
43599
  const { COMPONENT_COMPASS_TOKEN: ciToken } = process.env;
43625
43600
  const session = filePath !== void 0 ? { filePath } : {};
43626
- let token = ciToken || (await getAccessToken(base2, session)).accessToken;
43627
- async function refreshToken() {
43601
+ const token = ciToken || (await getStoredSession(base2, session)).token;
43602
+ async function onUnauthorized() {
43628
43603
  if (ciToken) {
43629
- throw new UploadError(401, "COMPONENT_COMPASS_TOKEN was rejected (401); interactive login and token refresh are disabled. Supply a valid token.");
43604
+ throw new UploadError(401, "COMPONENT_COMPASS_TOKEN was rejected (401). Supply a valid token.");
43630
43605
  }
43631
- token = (await getAccessToken(base2, { ...session, force: true })).accessToken;
43632
- return token;
43606
+ const removed = await removeStoredSession(base2, { expectedToken: token, ...session });
43607
+ if (!removed) throw new SessionChangedError(base2);
43608
+ throw new ReloginRequiredError(base2);
43633
43609
  }
43634
43610
  return {
43635
43611
  base: base2,
43636
43612
  async upload(artifactJson) {
43637
- const submit = () => submitArtifact({ host: base2, token, artifactJson });
43638
- const receipt = await submit().catch(async (err2) => {
43613
+ const receipt = await submitArtifact({ host: base2, token, artifactJson }).catch(async (err2) => {
43639
43614
  if (!(err2 instanceof UploadError) || err2.code !== 401) throw err2;
43640
- await refreshToken();
43641
- return await submit();
43615
+ return await onUnauthorized();
43642
43616
  });
43643
43617
  return await pollUpload({
43644
43618
  host: base2,
43645
43619
  receipt,
43646
43620
  getToken: async () => token,
43647
- refreshToken,
43621
+ onUnauthorized,
43648
43622
  timeoutMs: 3e5,
43649
43623
  ...opts.onStatus ? { onStatus: opts.onStatus } : {}
43650
43624
  });
@@ -45151,6 +45125,105 @@ var init_parse = __esm({
45151
45125
  }
45152
45126
  });
45153
45127
 
45128
+ // src/auth/client.ts
45129
+ function endpoint(base2, path5) {
45130
+ return `${base2.replace(/\/+$/, "")}${path5}`;
45131
+ }
45132
+ async function readError(res) {
45133
+ const body = await res.json().catch(() => ({}));
45134
+ return body.error ?? "unknown_error";
45135
+ }
45136
+ function toUserSession(body) {
45137
+ if (typeof body !== "object" || body === null || Array.isArray(body)) {
45138
+ throw new AuthProtocolError("Invalid token response: missing session.");
45139
+ }
45140
+ const { access_token: token, token_type: tokenType, email } = body;
45141
+ if (typeof token !== "string" || !USER_SESSION_TOKEN_PATTERN.test(token) || tokenType !== "Bearer" || typeof email !== "string" || email.trim() === "") {
45142
+ throw new AuthProtocolError("Invalid token response: malformed session.");
45143
+ }
45144
+ return { token, email };
45145
+ }
45146
+ async function requestDeviceCode(base2) {
45147
+ const res = await fetch(endpoint(base2, "/api/auth/cli/device-code"), { method: "POST" });
45148
+ if (!res.ok) throw new AuthHttpError(res.status, `device-code failed: ${await readError(res)}`);
45149
+ const b = await res.json();
45150
+ return {
45151
+ deviceCode: b.device_code,
45152
+ userCode: b.user_code,
45153
+ verificationUri: b.verification_uri,
45154
+ verificationUriComplete: b.verification_uri_complete,
45155
+ expiresIn: b.expires_in,
45156
+ interval: b.interval
45157
+ };
45158
+ }
45159
+ async function pollToken(base2, deviceCode) {
45160
+ const res = await fetch(endpoint(base2, "/api/auth/cli/token"), {
45161
+ method: "POST",
45162
+ headers: { "Content-Type": "application/json" },
45163
+ body: JSON.stringify({ device_code: deviceCode })
45164
+ });
45165
+ if (res.ok) {
45166
+ const body = await res.json().catch(() => {
45167
+ throw new AuthProtocolError("Invalid token response: could not parse JSON.");
45168
+ });
45169
+ return { kind: "session", session: toUserSession(body) };
45170
+ }
45171
+ const error2 = await readError(res);
45172
+ switch (error2) {
45173
+ case "authorization_pending":
45174
+ return { kind: "pending" };
45175
+ case "slow_down":
45176
+ return { kind: "slow_down" };
45177
+ case "expired_token":
45178
+ return { kind: "expired" };
45179
+ case "access_denied":
45180
+ return { kind: "denied" };
45181
+ default:
45182
+ throw new AuthHttpError(res.status, `token poll failed: ${error2}`);
45183
+ }
45184
+ }
45185
+ async function revokeSession(base2, token) {
45186
+ const res = await fetch(endpoint(base2, "/api/auth/cli/session"), {
45187
+ method: "DELETE",
45188
+ headers: { Authorization: `Bearer ${token}` }
45189
+ });
45190
+ if (res.status !== 204) throw new AuthHttpError(res.status, `session revoke failed: ${await readError(res)}`);
45191
+ }
45192
+ async function whoami(base2, token) {
45193
+ const res = await fetch(endpoint(base2, "/api/auth/cli/whoami"), {
45194
+ headers: { Authorization: `Bearer ${token}` }
45195
+ });
45196
+ if (res.status === 401) return null;
45197
+ if (!res.ok) throw new AuthHttpError(res.status, `whoami failed: ${await readError(res)}`);
45198
+ const body = await res.json().catch(() => {
45199
+ throw new AuthProtocolError("Invalid whoami response: could not parse JSON.");
45200
+ });
45201
+ if (typeof body !== "object" || body === null || Array.isArray(body)) {
45202
+ throw new AuthProtocolError("Invalid whoami response: missing identity.");
45203
+ }
45204
+ const { userId, email } = body;
45205
+ if (typeof userId !== "string" || userId === "" || typeof email !== "string" && email !== null) {
45206
+ throw new AuthProtocolError("Invalid whoami response: malformed identity.");
45207
+ }
45208
+ return { userId, email };
45209
+ }
45210
+ var AuthHttpError, AuthProtocolError, USER_SESSION_TOKEN_PATTERN;
45211
+ var init_client = __esm({
45212
+ "src/auth/client.ts"() {
45213
+ "use strict";
45214
+ AuthHttpError = class extends Error {
45215
+ constructor(status, message) {
45216
+ super(message);
45217
+ this.status = status;
45218
+ }
45219
+ status;
45220
+ };
45221
+ AuthProtocolError = class extends Error {
45222
+ };
45223
+ USER_SESSION_TOKEN_PATTERN = /^cc_u_[A-Za-z0-9_-]{43}$/;
45224
+ }
45225
+ });
45226
+
45154
45227
  // src/auth/browser.ts
45155
45228
  import { spawn as spawn2 } from "node:child_process";
45156
45229
  function openBrowser(url, deps = {}) {
@@ -45205,6 +45278,33 @@ async function runAuthLogin(opts) {
45205
45278
  const sleep = opts.sleep ?? defaultSleep;
45206
45279
  const now = opts.now ?? Date.now;
45207
45280
  const filePath = opts.store?.filePath;
45281
+ const stored = (await loadStore(filePath)).hosts[base2];
45282
+ if (stored) {
45283
+ try {
45284
+ const identity = await whoami(base2, stored.token);
45285
+ if (identity) {
45286
+ out(`Already signed in as ${identity.email ?? stored.userEmail} to ${base2}.
45287
+ `);
45288
+ return 0;
45289
+ }
45290
+ const removed = await removeStoredSession(base2, { expectedToken: stored.token, ...filePath !== void 0 ? { filePath } : {} });
45291
+ if (!removed) {
45292
+ err(`Session for ${base2} changed while checking it. Run \`component-compass auth login --host ${base2}\` again.
45293
+ `);
45294
+ return 1;
45295
+ }
45296
+ } catch (e) {
45297
+ if (e instanceof StoreLockError) err(`${e.message}
45298
+ `);
45299
+ else if (e instanceof AuthHttpError) err(`Login failed: ${base2} returned HTTP ${e.status}. Your stored session was kept.
45300
+ `);
45301
+ else if (e instanceof AuthProtocolError) err(`Login failed: ${e.message} Your stored session was kept.
45302
+ `);
45303
+ else err(`${new HostUnavailableError(base2).message}
45304
+ `);
45305
+ return 1;
45306
+ }
45307
+ }
45208
45308
  let device;
45209
45309
  try {
45210
45310
  device = await requestDeviceCode(base2);
@@ -45239,6 +45339,10 @@ Code: ${device.userCode}
45239
45339
  if (e instanceof AuthHttpError) {
45240
45340
  err(`
45241
45341
  Login failed: ${base2} returned HTTP ${e.status}. Run \`component-compass auth login\` again.
45342
+ `);
45343
+ } else if (e instanceof AuthProtocolError) {
45344
+ err(`
45345
+ Login failed: ${e.message} Your stored sessions were kept.
45242
45346
  `);
45243
45347
  } else {
45244
45348
  const detail = transportDetail(e);
@@ -45248,17 +45352,12 @@ Could not reach ${base2}${detail ? ` (${detail})` : ""}. Check the host URL and
45248
45352
  }
45249
45353
  return 1;
45250
45354
  }
45251
- if (result2.kind === "tokens") {
45355
+ if (result2.kind === "session") {
45252
45356
  const entry = {
45253
- accessToken: result2.tokens.accessToken,
45254
- refreshToken: result2.tokens.refreshToken,
45255
- userEmail: result2.tokens.email ?? "",
45256
- expiresAt: new Date(now() + result2.tokens.expiresIn * 1e3).toISOString()
45257
- };
45258
- const store = await loadStore(filePath);
45259
- store.hosts[base2] = entry;
45260
- if (!store.default) store.default = base2;
45261
- await saveStore(store, filePath);
45357
+ token: result2.session.token,
45358
+ userEmail: result2.session.email
45359
+ };
45360
+ await setStoredSession(base2, entry, filePath !== void 0 ? { filePath } : {});
45262
45361
  if (spin) spin.stop("Approved");
45263
45362
  out(`\u2713 Signed in as ${entry.userEmail || "your account"}
45264
45363
  `);
@@ -45294,19 +45393,27 @@ async function runAuthStatus(opts) {
45294
45393
  write3("Not signed in.\n");
45295
45394
  return 1;
45296
45395
  }
45297
- if (!store.hosts[base2]) {
45396
+ const entry = store.hosts[base2];
45397
+ if (!entry) {
45298
45398
  write3(`Not signed in to ${base2}.
45299
45399
  `);
45300
45400
  return 1;
45301
45401
  }
45302
45402
  try {
45303
- const { accessToken, userEmail } = await getAccessToken(base2, filePath !== void 0 ? { filePath } : {});
45304
- const who = await whoami(base2, accessToken);
45305
- write3(`Signed in as ${who?.email ?? userEmail} to ${base2}.
45403
+ const { token, userEmail } = await getStoredSession(base2, filePath !== void 0 ? { filePath } : {});
45404
+ const who = await whoami(base2, token);
45405
+ if (!who) {
45406
+ const removed = await removeStoredSession(base2, { expectedToken: token, ...filePath !== void 0 ? { filePath } : {} });
45407
+ write3(removed ? `${new ReloginRequiredError(base2).message}
45408
+ ` : `Session changed for ${base2}; retry \`component-compass auth status --host ${base2}\`.
45409
+ `);
45410
+ return 1;
45411
+ }
45412
+ write3(`Signed in as ${who.email ?? userEmail} to ${base2}.
45306
45413
  `);
45307
45414
  return 0;
45308
45415
  } catch (e) {
45309
- const msg = formatAuthError(e) ?? (e instanceof Error ? e.message : String(e));
45416
+ const msg = e instanceof StoreLockError ? e.message : formatAuthError(e) ?? (e instanceof AuthHttpError ? `Host ${base2} returned HTTP ${e.status}. Your stored session was kept.` : e instanceof AuthProtocolError ? `${e.message} Your stored session was kept.` : new HostUnavailableError(base2).message);
45310
45417
  write3(`${msg}
45311
45418
  `);
45312
45419
  return 1;
@@ -45323,18 +45430,23 @@ async function runAuthLogout(opts) {
45323
45430
  write3("Not signed in to anything.\n");
45324
45431
  return 0;
45325
45432
  }
45326
- if (!store.hosts[base2]) {
45433
+ const entry = store.hosts[base2];
45434
+ if (!entry) {
45327
45435
  write3(`Not signed in to ${base2}.
45328
45436
  `);
45329
45437
  return 0;
45330
45438
  }
45331
- const { [base2]: _removed, ...remaining } = store.hosts;
45332
- const next = {
45333
- hosts: remaining,
45334
- ...store.default && store.default !== base2 ? { default: store.default } : {}
45335
- };
45336
- await saveStore(next, filePath);
45337
- write3(`Signed out of ${base2}.
45439
+ try {
45440
+ await revokeSession(base2, entry.token);
45441
+ } catch (e) {
45442
+ write3(e instanceof AuthHttpError ? `Could not revoke the session for ${base2}: HTTP ${e.status}. Your stored session was kept.
45443
+ ` : `${new HostUnavailableError(base2).message} Your stored session was kept.
45444
+ `);
45445
+ return 1;
45446
+ }
45447
+ const removed = await removeStoredSession(base2, { expectedToken: entry.token, ...filePath !== void 0 ? { filePath } : {} });
45448
+ write3(removed ? `Signed out of ${base2}.
45449
+ ` : `Revoked the previous session for ${base2}; newer sign-in kept.
45338
45450
  `);
45339
45451
  return 0;
45340
45452
  }
@@ -45430,7 +45542,7 @@ var init_auth = __esm({
45430
45542
 
45431
45543
  // src/commands/scan.ts
45432
45544
  import { performance as performance3 } from "node:perf_hooks";
45433
- import { isAbsolute as isAbsolute11, relative as relative6, resolve as resolve11 } from "node:path";
45545
+ import { isAbsolute as isAbsolute12, relative as relative6, resolve as resolve11 } from "node:path";
45434
45546
  import { readFile as readFile5 } from "node:fs/promises";
45435
45547
 
45436
45548
  // src/config/loader.ts
@@ -67480,7 +67592,7 @@ function requireUtil$2() {
67480
67592
  }
67481
67593
  path5 = url.path;
67482
67594
  }
67483
- var isAbsolute13 = exports$1.isAbsolute(path5);
67595
+ var isAbsolute14 = exports$1.isAbsolute(path5);
67484
67596
  var parts = [];
67485
67597
  var start = 0;
67486
67598
  var i2 = 0;
@@ -67515,7 +67627,7 @@ function requireUtil$2() {
67515
67627
  }
67516
67628
  path5 = parts.join("/");
67517
67629
  if (path5 === "") {
67518
- path5 = isAbsolute13 ? "/" : ".";
67630
+ path5 = isAbsolute14 ? "/" : ".";
67519
67631
  }
67520
67632
  if (url) {
67521
67633
  url.path = path5;
@@ -67524,7 +67636,7 @@ function requireUtil$2() {
67524
67636
  return path5;
67525
67637
  });
67526
67638
  exports$1.normalize = normalize2;
67527
- function join16(aRoot, aPath) {
67639
+ function join17(aRoot, aPath) {
67528
67640
  if (aRoot === "") {
67529
67641
  aRoot = ".";
67530
67642
  }
@@ -67556,7 +67668,7 @@ function requireUtil$2() {
67556
67668
  }
67557
67669
  return joined;
67558
67670
  }
67559
- exports$1.join = join16;
67671
+ exports$1.join = join17;
67560
67672
  exports$1.isAbsolute = function(aPath) {
67561
67673
  return aPath.charAt(0) === "/" || urlRegexp.test(aPath);
67562
67674
  };
@@ -67770,7 +67882,7 @@ function requireUtil$2() {
67770
67882
  parsed.path = parsed.path.substring(0, index + 1);
67771
67883
  }
67772
67884
  }
67773
- sourceURL = join16(urlGenerate(parsed), sourceURL);
67885
+ sourceURL = join17(urlGenerate(parsed), sourceURL);
67774
67886
  }
67775
67887
  return normalize2(sourceURL);
67776
67888
  }
@@ -75347,9 +75459,9 @@ Url.prototype.resolveObject = function(relative7) {
75347
75459
  if (hasTrailingSlash && srcPath.join("/").substr(-1) !== "/") {
75348
75460
  srcPath.push("");
75349
75461
  }
75350
- var isAbsolute13 = srcPath[0] === "" || srcPath[0] && srcPath[0].charAt(0) === "/";
75462
+ var isAbsolute14 = srcPath[0] === "" || srcPath[0] && srcPath[0].charAt(0) === "/";
75351
75463
  if (psychotic) {
75352
- result2.hostname = result2.host = isAbsolute13 ? "" : srcPath.length ? srcPath.shift() : "";
75464
+ result2.hostname = result2.host = isAbsolute14 ? "" : srcPath.length ? srcPath.shift() : "";
75353
75465
  authInHost = result2.host && result2.host.indexOf("@") > 0 ? result2.host.split("@") : false;
75354
75466
  if (authInHost) {
75355
75467
  result2.auth = authInHost.shift();
@@ -75357,7 +75469,7 @@ Url.prototype.resolveObject = function(relative7) {
75357
75469
  }
75358
75470
  }
75359
75471
  mustEndAbs = mustEndAbs || result2.host && srcPath.length;
75360
- if (mustEndAbs && !isAbsolute13) {
75472
+ if (mustEndAbs && !isAbsolute14) {
75361
75473
  srcPath.unshift("");
75362
75474
  }
75363
75475
  if (!srcPath.length) {
@@ -75525,9 +75637,9 @@ function requirePicocolors() {
75525
75637
  hasRequiredPicocolors = 1;
75526
75638
  let p = browser$1 || {}, argv2 = p.argv || [], env2 = p.env || {};
75527
75639
  let isColorSupported = !(!!env2.NO_COLOR || argv2.includes("--no-color")) && (!!env2.FORCE_COLOR || argv2.includes("--color") || p.platform === "win32" || (p.stdout || {}).isTTY && env2.TERM !== "dumb" || !!env2.CI);
75528
- let formatter = (open, close, replace = open) => (input2) => {
75529
- let string2 = "" + input2, index = string2.indexOf(close, open.length);
75530
- return ~index ? open + replaceClose(string2, close, replace, index) + close : open + string2 + close;
75640
+ let formatter = (open2, close, replace = open2) => (input2) => {
75641
+ let string2 = "" + input2, index = string2.indexOf(close, open2.length);
75642
+ return ~index ? open2 + replaceClose(string2, close, replace, index) + close : open2 + string2 + close;
75531
75643
  };
75532
75644
  let replaceClose = (string2, close, replace, index) => {
75533
75645
  let result2 = "", cursor3 = 0;
@@ -77190,7 +77302,7 @@ function requirePreviousMap() {
77190
77302
  if (hasRequiredPreviousMap) return previousMap;
77191
77303
  hasRequiredPreviousMap = 1;
77192
77304
  let { existsSync: existsSync8, readFileSync: readFileSync13 } = require$$0$1;
77193
- let { dirname: dirname13, join: join16 } = require$$1;
77305
+ let { dirname: dirname13, join: join17 } = require$$1;
77194
77306
  let { SourceMapConsumer, SourceMapGenerator } = /* @__PURE__ */ requireSourceMap$1();
77195
77307
  function fromBase64(str) {
77196
77308
  if (Buffer$1) {
@@ -77289,7 +77401,7 @@ function requirePreviousMap() {
77289
77401
  return this.decodeInline(this.annotation);
77290
77402
  } else if (this.annotation) {
77291
77403
  let map2 = this.annotation;
77292
- if (file) map2 = join16(dirname13(file), map2);
77404
+ if (file) map2 = join17(dirname13(file), map2);
77293
77405
  return this.loadFile(map2);
77294
77406
  }
77295
77407
  }
@@ -77311,7 +77423,7 @@ function requireInput() {
77311
77423
  if (hasRequiredInput) return input;
77312
77424
  hasRequiredInput = 1;
77313
77425
  let { nanoid } = /* @__PURE__ */ requireNonSecure();
77314
- let { isAbsolute: isAbsolute13, resolve: resolve14 } = require$$1;
77426
+ let { isAbsolute: isAbsolute14, resolve: resolve14 } = require$$1;
77315
77427
  let { SourceMapConsumer, SourceMapGenerator } = /* @__PURE__ */ requireSourceMap$1();
77316
77428
  let { fileURLToPath: fileURLToPath3, pathToFileURL } = require$$2;
77317
77429
  let CssSyntaxError = /* @__PURE__ */ requireCssSyntaxError();
@@ -77319,7 +77431,7 @@ function requireInput() {
77319
77431
  let terminalHighlight = /* @__PURE__ */ requireTerminalHighlight();
77320
77432
  let lineToIndexCache = /* @__PURE__ */ Symbol("lineToIndexCache");
77321
77433
  let sourceMapAvailable = Boolean(SourceMapConsumer && SourceMapGenerator);
77322
- let pathAvailable = Boolean(resolve14 && isAbsolute13);
77434
+ let pathAvailable = Boolean(resolve14 && isAbsolute14);
77323
77435
  function getLineToIndex(input2) {
77324
77436
  if (input2[lineToIndexCache]) return input2[lineToIndexCache];
77325
77437
  let lines = input2.css.split("\n");
@@ -77350,7 +77462,7 @@ function requireInput() {
77350
77462
  this.document = this.css;
77351
77463
  if (opts.document) this.document = opts.document.toString();
77352
77464
  if (opts.from) {
77353
- if (!pathAvailable || /^\w+:\/\//.test(opts.from) || isAbsolute13(opts.from)) {
77465
+ if (!pathAvailable || /^\w+:\/\//.test(opts.from) || isAbsolute14(opts.from)) {
77354
77466
  this.file = opts.from;
77355
77467
  } else {
77356
77468
  this.file = resolve14(opts.from);
@@ -77486,7 +77598,7 @@ function requireInput() {
77486
77598
  to = consumer.originalPositionFor({ column: endColumn, line: endLine });
77487
77599
  }
77488
77600
  let fromUrl;
77489
- if (isAbsolute13(from2.source)) {
77601
+ if (isAbsolute14(from2.source)) {
77490
77602
  fromUrl = pathToFileURL(from2.source);
77491
77603
  } else {
77492
77604
  fromUrl = new URL(
@@ -78095,7 +78207,7 @@ function requireParser$1() {
78095
78207
  let prev;
78096
78208
  let shift;
78097
78209
  let last = false;
78098
- let open = false;
78210
+ let open2 = false;
78099
78211
  let params = [];
78100
78212
  let brackets = [];
78101
78213
  while (!this.tokenizer.endOfFile()) {
@@ -78115,7 +78227,7 @@ function requireParser$1() {
78115
78227
  this.semicolon = true;
78116
78228
  break;
78117
78229
  } else if (type === "{") {
78118
- open = true;
78230
+ open2 = true;
78119
78231
  break;
78120
78232
  } else if (type === "}") {
78121
78233
  if (params.length > 0) {
@@ -78157,7 +78269,7 @@ function requireParser$1() {
78157
78269
  node2.raws.afterName = "";
78158
78270
  node2.params = "";
78159
78271
  }
78160
- if (open) {
78272
+ if (open2) {
78161
78273
  node2.nodes = [];
78162
78274
  this.current = node2;
78163
78275
  }
@@ -94097,11 +94209,11 @@ function createImportResolver(opts) {
94097
94209
  }
94098
94210
  if (spec.startsWith(".")) {
94099
94211
  const segments = spec.split("/");
94100
- const basename6 = segments[segments.length - 1];
94101
- if (basename6) {
94212
+ const basename7 = segments[segments.length - 1];
94213
+ if (basename7) {
94102
94214
  for (const ext of FILE_EXTENSIONS) {
94103
94215
  try {
94104
- return requireFromRepo.resolve(`${spec}/${basename6}${ext}`, {
94216
+ return requireFromRepo.resolve(`${spec}/${basename7}${ext}`, {
94105
94217
  paths: [fromDir, opts.repoRoot]
94106
94218
  });
94107
94219
  } catch {
@@ -94142,10 +94254,10 @@ function tryFileWithExtensions(absPath) {
94142
94254
  if (isFile(indexPath)) return indexPath;
94143
94255
  }
94144
94256
  const segments = absPath.split(/[\\/]/);
94145
- const basename6 = segments[segments.length - 1];
94146
- if (basename6) {
94257
+ const basename7 = segments[segments.length - 1];
94258
+ if (basename7) {
94147
94259
  for (const ext of FILE_EXTENSIONS) {
94148
- const basenamePath = pathResolve3(absPath, `${basename6}${ext}`);
94260
+ const basenamePath = pathResolve3(absPath, `${basename7}${ext}`);
94149
94261
  if (isFile(basenamePath)) return basenamePath;
94150
94262
  }
94151
94263
  }
@@ -94466,6 +94578,9 @@ function createArgumentMap() {
94466
94578
  };
94467
94579
  }
94468
94580
 
94581
+ // ../reference-graph/dist/engine/binding.js
94582
+ import { isAbsolute as isAbsolute8 } from "node:path";
94583
+
94469
94584
  // ../reference-graph/dist/engine/cycle-detection.js
94470
94585
  var MAX_REFERENCE_DEPTH = 32;
94471
94586
  function createCycleGuard() {
@@ -94528,130 +94643,25 @@ function libraryStubFor(imp, ref) {
94528
94643
  return libraryExportFor(imp, ref)?.kind === "identity-preserving" ? { kind: "Function", returns: [{ kind: "ParameterOf", fn: ref, index: 0 }] } : null;
94529
94644
  }
94530
94645
 
94531
- // ../reference-graph/dist/engine/resolve-reference.js
94532
- function resolveReference(graph, fileGraph, ref, guard = createCycleGuard()) {
94533
- const lookupGraph = fileGraphForRef(graph, ref, fileGraph);
94534
- let scope = ref.scope;
94535
- while (true) {
94536
- const decl = lookupGraph.declarations.get(`${scope}::${ref.symbol}`);
94537
- if (decl) {
94538
- return wrapWithMemberChain(decl.value, ref.memberChain);
94539
- }
94540
- if (scope === MODULE_SCOPE)
94541
- break;
94542
- const parent = lookupGraph.scopes.get(scope)?.parent;
94543
- if (parent === null || parent === void 0)
94544
- break;
94545
- scope = parent;
94546
- }
94547
- const imp = lookupGraph.importsByLocal.get(ref.symbol);
94548
- if (!imp)
94549
- return { kind: "Unknown" };
94550
- const stub = libraryStubFor(imp, ref);
94551
- if (stub)
94552
- return stub;
94553
- const resolvedFile = graph.moduleResolver(lookupGraph.filePath, imp.specifier);
94554
- if (!resolvedFile)
94555
- return { kind: "Unknown" };
94556
- const targetFile = graph.resolveToGraphKey ? graph.resolveToGraphKey(resolvedFile) ?? resolvedFile : resolvedFile;
94557
- const found = findExport(graph, targetFile, imp.imported, /* @__PURE__ */ new Set());
94558
- if (!found)
94559
- return { kind: "Unknown" };
94560
- const { record: exp, fileGraph: expFileGraph } = found;
94561
- return resolveExport(graph, expFileGraph, exp, ref.memberChain, guard);
94646
+ // ../reference-graph/dist/engine/member-identity.js
94647
+ function effectiveExportName(imported, memberChain) {
94648
+ const first = memberChain[0];
94649
+ return imported === "*" && first !== void 0 ? first : imported;
94562
94650
  }
94563
- function findExport(graph, file, imported, seen2) {
94564
- const seenKey = `${file}::${imported}`;
94565
- if (seen2.has(seenKey))
94566
- return null;
94567
- seen2.add(seenKey);
94568
- const target = graph.files.get(file);
94569
- if (!target)
94570
- return null;
94571
- for (const exp of target.exports) {
94572
- if (exp.kind === "named" && exp.exportedAs === imported)
94573
- return { record: exp, fileGraph: target };
94574
- if (exp.kind === "default" && imported === "default")
94575
- return { record: exp, fileGraph: target };
94576
- }
94577
- for (const exp of target.exports) {
94578
- if (exp.kind !== "star")
94579
- continue;
94580
- const resolvedFrom = graph.moduleResolver(file, exp.from);
94581
- if (!resolvedFrom)
94582
- continue;
94583
- const nextFile = graph.resolveToGraphKey ? graph.resolveToGraphKey(resolvedFrom) ?? resolvedFrom : resolvedFrom;
94584
- const result2 = findExport(graph, nextFile, imported, seen2);
94585
- if (result2)
94586
- return result2;
94587
- }
94588
- return null;
94651
+ function residualMemberChain(imported, memberChain) {
94652
+ return imported === "*" && memberChain.length > 0 ? memberChain.slice(1) : memberChain;
94589
94653
  }
94590
- function resolveExport(graph, fileGraph, exp, memberChain, guard) {
94591
- if (exp.kind === "named" && "local" in exp) {
94592
- const guardResult = guard.push(fileGraph.filePath, exp.local);
94593
- if (guardResult !== "ok")
94594
- return { kind: "Unknown" };
94595
- try {
94596
- const localRef = {
94597
- symbol: exp.local,
94598
- scope: MODULE_SCOPE,
94599
- memberChain,
94600
- loc: { line: 0, column: 0 }
94601
- };
94602
- return resolveReference(graph, fileGraph, localRef, guard);
94603
- } finally {
94604
- guard.pop(fileGraph.filePath, exp.local);
94605
- }
94606
- }
94607
- if (exp.kind === "named" && "from" in exp) {
94608
- const resolvedFrom = graph.moduleResolver(fileGraph.filePath, exp.from);
94609
- if (!resolvedFrom)
94610
- return { kind: "Unknown" };
94611
- const targetFile = graph.resolveToGraphKey ? graph.resolveToGraphKey(resolvedFrom) ?? resolvedFrom : resolvedFrom;
94612
- const innerFound = findExport(graph, targetFile, exp.fromImported, /* @__PURE__ */ new Set());
94613
- if (!innerFound)
94614
- return { kind: "Unknown" };
94615
- const guardResult = guard.push(fileGraph.filePath, exp.exportedAs);
94616
- if (guardResult !== "ok")
94617
- return { kind: "Unknown" };
94618
- try {
94619
- return resolveExport(graph, innerFound.fileGraph, innerFound.record, memberChain, guard);
94620
- } finally {
94621
- guard.pop(fileGraph.filePath, exp.exportedAs);
94622
- }
94623
- }
94624
- if (exp.kind === "default" && "local" in exp) {
94625
- const guardResult = guard.push(fileGraph.filePath, exp.local);
94626
- if (guardResult !== "ok")
94627
- return { kind: "Unknown" };
94628
- try {
94629
- const localRef = {
94630
- symbol: exp.local,
94631
- scope: MODULE_SCOPE,
94632
- memberChain,
94633
- loc: { line: 0, column: 0 }
94634
- };
94635
- return resolveReference(graph, fileGraph, localRef, guard);
94636
- } finally {
94637
- guard.pop(fileGraph.filePath, exp.local);
94638
- }
94639
- }
94640
- return { kind: "Unknown" };
94654
+ function compoundExportName(root2, residual) {
94655
+ return residual.length === 0 ? root2 : `${root2}.${residual.join(".")}`;
94641
94656
  }
94642
- function wrapWithMemberChain(t3, chain) {
94643
- let result2 = t3;
94644
- for (const member of chain) {
94645
- result2 = { kind: "MemberOf", obj: result2, member };
94657
+ function memberOfObjectPath(holder, path5) {
94658
+ let cur = holder;
94659
+ for (const segment of path5) {
94660
+ if (cur?.kind !== "Object")
94661
+ return void 0;
94662
+ cur = cur.props[segment];
94646
94663
  }
94647
- return result2;
94648
- }
94649
- function fileGraphForRef(graph, ref, fallback) {
94650
- if (!ref.originFile)
94651
- return fallback;
94652
- if (ref.originFile === fallback.filePath)
94653
- return fallback;
94654
- return graph.files.get(ref.originFile) ?? fallback;
94664
+ return cur;
94655
94665
  }
94656
94666
 
94657
94667
  // ../reference-graph/dist/engine/specifier.js
@@ -94681,67 +94691,9 @@ function externalSubpath(pkg, specifier) {
94681
94691
  return void 0;
94682
94692
  }
94683
94693
 
94684
- // ../reference-graph/dist/engine/re-export-chain.js
94685
- function followReExportChain(graph, file, imported) {
94686
- return walk2(graph, file, imported, /* @__PURE__ */ new Set());
94687
- }
94688
- function walk2(graph, file, imported, seen2) {
94689
- const seenKey = `${file}::${imported}`;
94690
- if (seen2.has(seenKey))
94691
- return null;
94692
- seen2.add(seenKey);
94693
- const target = graph.files.get(file);
94694
- if (!target)
94695
- return null;
94696
- const exp = target.exports.find((e) => e.kind === "named" && "exportedAs" in e && e.exportedAs === imported || e.kind === "default" && imported === "default");
94697
- if (exp) {
94698
- if (exp.kind === "named" && "from" in exp) {
94699
- const nextAbs = graph.moduleResolver(file, exp.from);
94700
- if (!nextAbs)
94701
- return { file, localExport: imported };
94702
- const nextKey = graph.resolveToGraphKey ? graph.resolveToGraphKey(nextAbs) : nextAbs;
94703
- if (!nextKey)
94704
- return { file, localExport: imported };
94705
- return walk2(graph, nextKey, exp.fromImported, seen2) ?? {
94706
- file: nextKey,
94707
- localExport: exp.fromImported
94708
- };
94709
- }
94710
- if ("local" in exp) {
94711
- const imp = target.importsByLocal.get(exp.local);
94712
- if (imp && imp.imported !== "*" && !packageNameFromSpecifier(imp.specifier)) {
94713
- const nextAbs = graph.moduleResolver(file, imp.specifier);
94714
- const nextKey = nextAbs && (graph.resolveToGraphKey ? graph.resolveToGraphKey(nextAbs) : nextAbs);
94715
- if (nextKey) {
94716
- const leaf = walk2(graph, nextKey, imp.imported, seen2);
94717
- if (leaf)
94718
- return leaf;
94719
- if (graph.lazyReExportResolution && !graph.files.has(nextKey)) {
94720
- return { file: nextKey, localExport: imp.imported };
94721
- }
94722
- }
94723
- }
94724
- return { file, localExport: exp.local };
94725
- }
94726
- return { file, localExport: imported };
94727
- }
94728
- for (const starExp of target.exports) {
94729
- if (starExp.kind !== "star")
94730
- continue;
94731
- const nextAbs = graph.moduleResolver(file, starExp.from);
94732
- if (!nextAbs)
94733
- continue;
94734
- const nextKey = graph.resolveToGraphKey ? graph.resolveToGraphKey(nextAbs) : nextAbs;
94735
- if (!nextKey)
94736
- continue;
94737
- const result2 = walk2(graph, nextKey, imported, seen2);
94738
- if (result2)
94739
- return result2;
94740
- }
94741
- return null;
94742
- }
94743
-
94744
- // ../reference-graph/dist/engine/helper-callers.js
94694
+ // ../reference-graph/dist/engine/binding.js
94695
+ var NO_EXPORT = { kind: "no-export" };
94696
+ var UNBOUND = { kind: "unbound" };
94745
94697
  function findLocalDeclaration(fileGraph, ref) {
94746
94698
  let scope = ref.scope;
94747
94699
  while (true) {
@@ -94756,246 +94708,316 @@ function findLocalDeclaration(fileGraph, ref) {
94756
94708
  scope = parent;
94757
94709
  }
94758
94710
  }
94759
- function classifyDeclaration(decl, registry, fileGraph) {
94760
- if (decl.value.kind !== "Function" && decl.value.kind !== "ReturnTypeOf")
94761
- return "unknown";
94762
- if (fileGraph.dialect === "vue" && isSfcDeclaration(fileGraph, decl))
94763
- return "component";
94764
- return registry.hasLocal(fileGraph.filePath, decl.symbol) ? "component" : "helper";
94711
+ function fileGraphForRef(graph, ref, fallback) {
94712
+ if (!ref.originFile || ref.originFile === fallback.filePath)
94713
+ return fallback;
94714
+ return graph.files.get(ref.originFile) ?? fallback;
94765
94715
  }
94766
- var isSfcDeclaration = (fileGraph, decl) => fileGraph.exports.some((e) => e.kind === "default" && "local" in e && e.local === decl.symbol);
94767
- function buildHelperCallers(graph, registry) {
94768
- const index = /* @__PURE__ */ new Map();
94769
- const callerKeysByHelper = /* @__PURE__ */ new Map();
94770
- const classificationCache = /* @__PURE__ */ new Map();
94771
- const refResolutionCache = /* @__PURE__ */ new Map();
94772
- function resolveRefCached(ref, callerFile, callerGraph) {
94773
- const key = `${callerFile}::${ref.symbol}`;
94774
- if (refResolutionCache.has(key)) {
94775
- return refResolutionCache.get(key) ?? null;
94776
- }
94777
- const result2 = resolveRefToDecl(ref, callerFile, callerGraph, graph);
94778
- refResolutionCache.set(key, result2);
94779
- return result2;
94780
- }
94781
- const pendingValueRefs = [];
94782
- for (const [file, fileGraph] of graph.files) {
94783
- for (const decl of fileGraph.declarations.values()) {
94784
- if (decl.scope !== MODULE_SCOPE)
94785
- continue;
94786
- const refs = [];
94787
- if (decl.value.kind === "Function") {
94788
- for (const r2 of decl.value.returns)
94789
- collectRefsInType(r2, refs);
94790
- } else if (decl.value.kind === "ReturnTypeOf") {
94791
- collectCalleeRefs(decl.value, refs);
94792
- }
94793
- for (const bc of fileGraph.bodyCalls) {
94794
- if (bc.ownerSymbol === decl.symbol)
94795
- refs.push(bc.callee);
94796
- }
94797
- const callerKey = { file, symbol: decl.symbol };
94798
- for (const ref of refs) {
94799
- const target = resolveRefCached(ref, file, fileGraph);
94800
- if (!target)
94801
- continue;
94802
- pendingValueRefs.push({ target, caller: callerKey });
94803
- }
94804
- }
94805
- }
94806
- const pendingJsxCalls = [];
94807
- for (const [file, fileGraph] of graph.files) {
94808
- for (let i2 = 0; i2 < fileGraph.jsxUsages.length; i2++) {
94809
- const usage = fileGraph.jsxUsages[i2];
94810
- if (!usage)
94811
- continue;
94812
- const target = resolveRefCached(usage.ref, file, fileGraph);
94813
- if (!target)
94814
- continue;
94815
- const ownership = fileGraph.ownership[i2];
94816
- if (!ownership?.ownerSymbolRef)
94817
- continue;
94818
- const callerTarget = resolveRefCached(ownership.ownerSymbolRef, file, fileGraph);
94819
- if (!callerTarget)
94820
- continue;
94821
- if (callerTarget.decl.scope !== MODULE_SCOPE)
94822
- continue;
94823
- pendingJsxCalls.push({
94824
- target,
94825
- caller: { file: callerTarget.file, symbol: callerTarget.decl.symbol }
94826
- });
94827
- }
94828
- }
94829
- function classifyKey(file, decl) {
94830
- const key = `${file}::${decl.symbol}`;
94831
- const hit = classificationCache.get(key);
94832
- if (hit !== void 0)
94833
- return hit;
94834
- const fileGraph = graph.files.get(file);
94835
- const result2 = fileGraph ? classifyDeclaration(decl, registry, fileGraph) : "unknown";
94836
- classificationCache.set(key, result2);
94837
- return result2;
94838
- }
94839
- for (const [file, fileGraph] of graph.files) {
94840
- for (const decl of fileGraph.declarations.values()) {
94841
- if (decl.scope !== MODULE_SCOPE)
94842
- continue;
94843
- if (decl.value.kind !== "Function" && decl.value.kind !== "ReturnTypeOf")
94844
- continue;
94845
- classifyKey(file, decl);
94846
- }
94847
- }
94848
- function recordCallerEdge(target, callerKey) {
94849
- const keyStr = `${target.file}::${target.decl.symbol}`;
94850
- const callerKeyStr = `${callerKey.file}::${callerKey.symbol}`;
94851
- let seen2 = callerKeysByHelper.get(keyStr);
94852
- if (!seen2) {
94853
- seen2 = /* @__PURE__ */ new Set();
94854
- callerKeysByHelper.set(keyStr, seen2);
94855
- }
94856
- if (seen2.has(callerKeyStr))
94857
- return;
94858
- seen2.add(callerKeyStr);
94859
- let callers = index.get(keyStr);
94860
- if (!callers) {
94861
- callers = /* @__PURE__ */ new Set();
94862
- index.set(keyStr, callers);
94863
- }
94864
- callers.add(callerKey);
94716
+ function graphKeyFor(graph, abs) {
94717
+ return graph.resolveToGraphKey ? graph.resolveToGraphKey(abs) : abs;
94718
+ }
94719
+ function exportRecordFor(fileGraph, name) {
94720
+ return fileGraph.exports.find((e) => e.kind === "named" && e.exportedAs === name || e.kind === "default" && name === "default");
94721
+ }
94722
+ function resolveBinding(graph, fileGraph, ref, guard = createCycleGuard()) {
94723
+ const found = bindingIn(graph, fileGraphForRef(graph, ref, fileGraph), ref, guard, /* @__PURE__ */ new Set());
94724
+ return withWalkIdentity(graph, found, ref.memberChain);
94725
+ }
94726
+ function resolveModuleExport(graph, fromFile, specifier, imported, memberChain, guard = createCycleGuard()) {
94727
+ const found = moduleExport(graph, fromFile, specifier, imported, memberChain, guard, /* @__PURE__ */ new Set());
94728
+ return withWalkIdentity(graph, { ...found, module: { specifier, imported, target: found.target } }, memberChain);
94729
+ }
94730
+ function bindingIn(graph, fileGraph, ref, guard, chain) {
94731
+ const decl = findLocalDeclaration(fileGraph, ref);
94732
+ if (decl) {
94733
+ return { binding: { kind: "declaration", file: fileGraph.filePath, decl, path: ref.memberChain, inScope: true }, end: null };
94865
94734
  }
94866
- for (const { target, caller } of pendingValueRefs) {
94867
- if (classifyKey(target.file, target.decl) !== "helper")
94735
+ const imp = fileGraph.importsByLocal.get(ref.symbol);
94736
+ if (!imp)
94737
+ return { binding: UNBOUND, end: null };
94738
+ const stub = libraryStubFor(imp, ref);
94739
+ if (stub) {
94740
+ const binding2 = {
94741
+ kind: "package-export",
94742
+ specifier: imp.specifier,
94743
+ exportName: effectiveExportName(imp.imported, ref.memberChain),
94744
+ path: residualMemberChain(imp.imported, ref.memberChain),
94745
+ stub
94746
+ };
94747
+ return { binding: binding2, end: null };
94748
+ }
94749
+ const found = moduleExport(graph, fileGraph.filePath, imp.specifier, imp.imported, ref.memberChain, guard, chain);
94750
+ return { ...found, module: { specifier: imp.specifier, imported: imp.imported, target: found.target } };
94751
+ }
94752
+ function moduleExport(graph, fromFile, specifier, imported, memberChain, guard, chain) {
94753
+ const exportName = effectiveExportName(imported, memberChain);
94754
+ const path5 = residualMemberChain(imported, memberChain);
94755
+ const target = moduleTarget(graph, fromFile, specifier, exportName, path5);
94756
+ if (target.kind === "outside")
94757
+ return { binding: target.binding, end: null, target };
94758
+ if (imported === "*" && memberChain.length === 0)
94759
+ return { binding: NO_EXPORT, end: null, target };
94760
+ const found = exportIn(graph, target.key, exportName, path5, guard, chain);
94761
+ const b = found.binding;
94762
+ if (imported === "*" && (b.kind === "declaration" || b.kind === "package-export")) {
94763
+ return { binding: { ...b, mainGap: "namespace-member" }, end: found.end, target };
94764
+ }
94765
+ return { binding: b, end: found.end, target };
94766
+ }
94767
+ function moduleTarget(graph, fromFile, specifier, exportName, path5) {
94768
+ const isPackage = packageNameFromSpecifier(specifier) !== null;
94769
+ const abs = graph.moduleResolver(fromFile, specifier);
94770
+ if (!abs) {
94771
+ const binding3 = isPackage ? { kind: "package-export", specifier, exportName, path: path5, stub: null } : { kind: "import-failed", specifier, exportName, path: path5 };
94772
+ return { kind: "outside", binding: binding3, graphKey: null, member: false };
94773
+ }
94774
+ const graphKey = graphKeyFor(graph, abs);
94775
+ const key = graphKey ?? abs;
94776
+ if (graph.files.has(key))
94777
+ return { kind: "parsed", key };
94778
+ if (graph.workspaceMembership?.(abs) === true) {
94779
+ return { kind: "outside", binding: { kind: "unparsed", file: abs, exportName, path: path5 }, graphKey, member: true };
94780
+ }
94781
+ const binding2 = isPackage ? { kind: "package-export", specifier, exportName, path: path5, stub: null } : { kind: "unparsed", file: key, exportName, path: path5 };
94782
+ return { kind: "outside", binding: binding2, graphKey, member: false };
94783
+ }
94784
+ function exportIn(graph, file, name, path5, guard, chain) {
94785
+ const again = soughtAgain(chain, file, name);
94786
+ const found = findExportRecord(graph, file, name, /* @__PURE__ */ new Set());
94787
+ if (!found)
94788
+ return { binding: packageStarExport(graph, file, name, path5, /* @__PURE__ */ new Set()) ?? NO_EXPORT, end: null };
94789
+ const inner = followRecord(graph, found, file, name, path5, guard, chain);
94790
+ return again ? { binding: inner.binding, end: null } : inner;
94791
+ }
94792
+ function followRecord(graph, found, file, name, path5, guard, chain) {
94793
+ const onChain = recordOnChain(graph, file, name, chain);
94794
+ if (onChain?.record === found.record)
94795
+ return bindingForRecord(graph, found.fileGraph, found.record, name, path5, guard, chain);
94796
+ const { binding: binding2 } = bindingForRecord(graph, found.fileGraph, found.record, name, path5, guard, new Set(chain));
94797
+ const end = onChain ? bindingForRecord(graph, onChain.fileGraph, onChain.record, name, path5, guard, chain).end : null;
94798
+ return { binding: binding2, end };
94799
+ }
94800
+ function soughtAgain(chain, file, name) {
94801
+ const key = `${file}::${name}`;
94802
+ if (chain.has(key))
94803
+ return true;
94804
+ chain.add(key);
94805
+ return false;
94806
+ }
94807
+ function findExportRecord(graph, file, name, seen2) {
94808
+ const seenKey = `${file}::${name}`;
94809
+ if (seen2.has(seenKey))
94810
+ return null;
94811
+ seen2.add(seenKey);
94812
+ const fileGraph = graph.files.get(file);
94813
+ if (!fileGraph)
94814
+ return null;
94815
+ const record = exportRecordFor(fileGraph, name);
94816
+ if (record)
94817
+ return { record, fileGraph };
94818
+ for (const star of fileGraph.exports) {
94819
+ if (star.kind !== "star")
94868
94820
  continue;
94869
- recordCallerEdge(target, caller);
94870
- }
94871
- for (const { target, caller } of pendingJsxCalls) {
94872
- if (classifyKey(target.file, target.decl) !== "helper")
94821
+ const abs = graph.moduleResolver(file, star.from);
94822
+ if (!abs)
94873
94823
  continue;
94874
- recordCallerEdge(target, caller);
94824
+ const found = findExportRecord(graph, graphKeyFor(graph, abs) ?? abs, name, seen2);
94825
+ if (found)
94826
+ return found;
94875
94827
  }
94876
- return {
94877
- get(key) {
94878
- return index.get(`${key.file}::${key.symbol}`);
94879
- },
94880
- classification(file, symbol2) {
94881
- return classificationCache.get(`${file}::${symbol2}`) ?? "unknown";
94882
- }
94883
- };
94828
+ return null;
94884
94829
  }
94885
- function collectCalleeRefs(t3, out2) {
94886
- switch (t3.kind) {
94887
- case "ReturnTypeOf":
94888
- collectCalleeRefs(t3.callee, out2);
94889
- return;
94890
- case "MemberOf":
94891
- collectCalleeRefs(t3.obj, out2);
94892
- return;
94893
- case "TypeOf":
94894
- out2.push(t3.ref);
94830
+ function packageStarExport(graph, file, name, path5, seen2) {
94831
+ if (name === "default")
94832
+ return null;
94833
+ const outside = [];
94834
+ const visit2 = (f) => {
94835
+ if (seen2.has(f))
94895
94836
  return;
94896
- default:
94837
+ seen2.add(f);
94838
+ const fileGraph = graph.files.get(f);
94839
+ if (!fileGraph)
94897
94840
  return;
94898
- }
94841
+ for (const star of fileGraph.exports) {
94842
+ if (star.kind !== "star")
94843
+ continue;
94844
+ const target = moduleTarget(graph, f, star.from, name, path5);
94845
+ if (target.kind === "parsed")
94846
+ visit2(target.key);
94847
+ else
94848
+ outside.push(target.binding);
94849
+ }
94850
+ };
94851
+ visit2(file);
94852
+ return outside.length === 1 && outside[0]?.kind === "package-export" ? outside[0] : null;
94899
94853
  }
94900
- function collectRefsInType(t3, out2) {
94901
- switch (t3.kind) {
94902
- case "TypeOf":
94903
- out2.push(t3.ref);
94904
- return;
94905
- case "Union":
94906
- for (const u3 of t3.types)
94907
- collectRefsInType(u3, out2);
94908
- return;
94909
- case "ReturnTypeOf":
94910
- collectRefsInType(t3.callee, out2);
94911
- for (const a3 of t3.args)
94912
- collectRefsInType(a3, out2);
94913
- return;
94914
- case "Function":
94915
- for (const r2 of t3.returns)
94916
- collectRefsInType(r2, out2);
94917
- return;
94918
- case "Object":
94919
- for (const v of Object.values(t3.props))
94920
- collectRefsInType(v, out2);
94921
- return;
94922
- case "Array":
94923
- for (const e of t3.elements)
94924
- collectRefsInType(e, out2);
94925
- return;
94926
- case "MemberOf":
94927
- collectRefsInType(t3.obj, out2);
94928
- return;
94929
- case "ParameterOf":
94930
- return;
94931
- default:
94932
- return;
94854
+ function recordOnChain(graph, file, name, chain) {
94855
+ const fileGraph = graph.files.get(file);
94856
+ if (!fileGraph)
94857
+ return null;
94858
+ const record = exportRecordFor(fileGraph, name);
94859
+ if (record)
94860
+ return { record, fileGraph };
94861
+ for (const star of fileGraph.exports) {
94862
+ if (star.kind !== "star")
94863
+ continue;
94864
+ const abs = graph.moduleResolver(file, star.from);
94865
+ if (!abs)
94866
+ continue;
94867
+ const next = graphKeyFor(graph, abs);
94868
+ if (next === null || soughtAgain(chain, next, name))
94869
+ continue;
94870
+ const found = recordOnChain(graph, next, name, chain);
94871
+ if (found)
94872
+ return found;
94933
94873
  }
94874
+ return null;
94934
94875
  }
94935
- function resolveRefToDecl(ref, callerFile, callerGraph, graph) {
94936
- const localKey = `${MODULE_SCOPE}::${ref.symbol}`;
94937
- const localDecl = callerGraph.declarations.get(localKey);
94938
- if (localDecl)
94939
- return { file: callerFile, decl: localDecl };
94940
- const imp = callerGraph.importsByLocal.get(ref.symbol);
94941
- if (!imp)
94942
- return null;
94943
- const resolvedAbs = graph.moduleResolver(callerFile, imp.specifier);
94944
- if (!resolvedAbs)
94945
- return null;
94946
- const targetFile = graph.resolveToGraphKey ? graph.resolveToGraphKey(resolvedAbs) ?? resolvedAbs : resolvedAbs;
94947
- const targetGraph = graph.files.get(targetFile);
94948
- if (!targetGraph)
94949
- return null;
94950
- const chained = followReExportChain(graph, targetFile, imp.imported);
94951
- if (chained) {
94952
- const chainedGraph = graph.files.get(chained.file);
94953
- if (chainedGraph) {
94954
- const decl = chainedGraph.declarations.get(`${MODULE_SCOPE}::${chained.localExport}`);
94955
- if (decl)
94956
- return { file: chained.file, decl };
94876
+ function bindingForRecord(graph, fg, exp, name, path5, guard, chain) {
94877
+ if (exp.kind === "star")
94878
+ return { binding: NO_EXPORT, end: null };
94879
+ if ("local" in exp) {
94880
+ const here = { file: fg.filePath, name: exp.local };
94881
+ if (guard.push(fg.filePath, exp.local) !== "ok")
94882
+ return { binding: NO_EXPORT, end: here };
94883
+ try {
94884
+ const ref = { symbol: exp.local, scope: MODULE_SCOPE, memberChain: [...path5], loc: { line: 0, column: 0 } };
94885
+ const found2 = bindingIn(graph, fg, ref, guard, chain);
94886
+ const b = found2.binding;
94887
+ const followed = found2.module !== void 0 && found2.module.imported !== "*" && packageNameFromSpecifier(found2.module.specifier) === null && found2.module.target.kind === "parsed";
94888
+ return {
94889
+ binding: b.kind === "declaration" ? { ...b, inScope: false } : leftGraphThrough(b, fg.filePath),
94890
+ end: (followed ? found2.end : null) ?? here
94891
+ };
94892
+ } finally {
94893
+ guard.pop(fg.filePath, exp.local);
94957
94894
  }
94958
94895
  }
94959
- for (const exp of targetGraph.exports) {
94960
- if (exp.kind === "named" && "local" in exp && exp.exportedAs === imp.imported) {
94961
- const decl = targetGraph.declarations.get(`${MODULE_SCOPE}::${exp.local}`);
94962
- if (decl)
94963
- return { file: targetFile, decl };
94964
- }
94965
- if (exp.kind === "default" && "local" in exp && imp.imported === "default") {
94966
- const decl = targetGraph.declarations.get(`${MODULE_SCOPE}::${exp.local}`);
94967
- if (decl)
94968
- return { file: targetFile, decl };
94969
- }
94896
+ const target = moduleTarget(graph, fg.filePath, exp.from, exp.fromImported, path5);
94897
+ if (target.kind === "outside") {
94898
+ const end = target.graphKey === null ? { file: fg.filePath, name } : { file: target.graphKey, name: exp.fromImported };
94899
+ return { binding: leftGraphThrough(target.binding, null), end };
94970
94900
  }
94971
- return null;
94901
+ const next = { file: target.key, name: exp.fromImported };
94902
+ const again = soughtAgain(chain, target.key, exp.fromImported);
94903
+ const found = findExportRecord(graph, target.key, exp.fromImported, /* @__PURE__ */ new Set());
94904
+ if (!found)
94905
+ return { binding: packageStarExport(graph, target.key, exp.fromImported, path5, /* @__PURE__ */ new Set()) ?? NO_EXPORT, end: next };
94906
+ if (guard.push(fg.filePath, exp.exportedAs) !== "ok")
94907
+ return { binding: NO_EXPORT, end: next };
94908
+ try {
94909
+ const inner = followRecord(graph, found, target.key, exp.fromImported, path5, guard, chain);
94910
+ return { binding: inner.binding, end: (again ? null : inner.end) ?? next };
94911
+ } finally {
94912
+ guard.pop(fg.filePath, exp.exportedAs);
94913
+ }
94914
+ }
94915
+ function leftGraphThrough(b, barrel) {
94916
+ if (b.kind === "unparsed" && b.mainGap === void 0) {
94917
+ return { ...b, mainGap: { kind: "through-parsed-barrel", barrel } };
94918
+ }
94919
+ return b;
94920
+ }
94921
+ function withWalkIdentity(graph, found, memberChain) {
94922
+ const { binding: binding2, module } = found;
94923
+ if (module === void 0)
94924
+ return binding2;
94925
+ if (binding2.kind === "package-export" && binding2.mainGap === void 0)
94926
+ return binding2;
94927
+ const { specifier, imported, target } = module;
94928
+ const name = effectiveExportName(imported, memberChain);
94929
+ const residual = residualMemberChain(imported, memberChain);
94930
+ const isPackage = packageNameFromSpecifier(specifier) !== null;
94931
+ const asWritten = (resolvedFile) => ({
94932
+ kind: "imported",
94933
+ specifier,
94934
+ imported: compoundExportName(name, residual),
94935
+ resolvedFile
94936
+ });
94937
+ const local = (file, exportName) => ({
94938
+ kind: "local",
94939
+ filePath: file,
94940
+ export: compoundExportName(exportName, residual)
94941
+ });
94942
+ let walked;
94943
+ if (target.kind === "outside") {
94944
+ if (isPackage || target.member || binding2.kind !== "unparsed")
94945
+ return binding2;
94946
+ walked = asWritten(target.graphKey);
94947
+ } else if (isPackage) {
94948
+ const file = found.end?.file ?? target.key;
94949
+ walked = graph.files.has(file) ? local(file, found.end?.name ?? name) : asWritten(null);
94950
+ } else {
94951
+ walked = found.end ? local(found.end.file, found.end.name) : asWritten(target.key);
94952
+ }
94953
+ return sameIdentity(walked, naturalIdentity(binding2)) ? binding2 : { ...binding2, walkIdentity: walked };
94972
94954
  }
94973
-
94974
- // ../reference-graph/dist/engine/member-identity.js
94975
- function effectiveExportName(imported, memberChain) {
94976
- const first = memberChain[0];
94977
- return imported === "*" && first !== void 0 ? first : imported;
94955
+ function sameIdentity(a3, b) {
94956
+ if (b === null || a3.kind !== b.kind)
94957
+ return false;
94958
+ if (a3.kind === "local" && b.kind === "local")
94959
+ return a3.filePath === b.filePath && a3.export === b.export;
94960
+ if (a3.kind === "imported" && b.kind === "imported") {
94961
+ return a3.specifier === b.specifier && a3.imported === b.imported && a3.resolvedFile === b.resolvedFile;
94962
+ }
94963
+ return false;
94978
94964
  }
94979
- function residualMemberChain(imported, memberChain) {
94980
- return imported === "*" && memberChain.length > 0 ? memberChain.slice(1) : memberChain;
94965
+ function bindingValue(binding2) {
94966
+ switch (binding2.kind) {
94967
+ case "declaration": {
94968
+ if (binding2.mainGap === "namespace-member")
94969
+ return { kind: "Unknown" };
94970
+ let value = binding2.decl.value;
94971
+ for (const member of binding2.path)
94972
+ value = { kind: "MemberOf", obj: value, member };
94973
+ return value;
94974
+ }
94975
+ case "package-export":
94976
+ return binding2.mainGap === "namespace-member" ? { kind: "Unknown" } : binding2.stub ?? { kind: "Unknown" };
94977
+ default:
94978
+ return { kind: "Unknown" };
94979
+ }
94981
94980
  }
94982
- function compoundExportName(root2, residual) {
94983
- return residual.length === 0 ? root2 : `${root2}.${residual.join(".")}`;
94981
+ function bindingIdentity(binding2) {
94982
+ if (binding2.walkIdentity !== void 0)
94983
+ return binding2.walkIdentity;
94984
+ return naturalIdentity(binding2);
94984
94985
  }
94985
- function memberOfObjectPath(holder, path5) {
94986
- let cur = holder;
94987
- for (const segment of path5) {
94988
- if (cur?.kind !== "Object")
94989
- return void 0;
94990
- cur = cur.props[segment];
94986
+ function naturalIdentity(binding2) {
94987
+ switch (binding2.kind) {
94988
+ case "declaration":
94989
+ return {
94990
+ kind: "local",
94991
+ filePath: binding2.file,
94992
+ export: compoundExportName(binding2.decl.symbol, binding2.path),
94993
+ ...binding2.path.length === 0 ? { declaration: binding2.decl } : {}
94994
+ };
94995
+ case "unparsed":
94996
+ return { kind: "local", filePath: binding2.file, export: compoundExportName(binding2.exportName, binding2.path) };
94997
+ case "package-export":
94998
+ case "import-failed":
94999
+ return {
95000
+ kind: "imported",
95001
+ specifier: binding2.specifier,
95002
+ imported: compoundExportName(binding2.exportName, binding2.path),
95003
+ resolvedFile: null
95004
+ };
95005
+ default:
95006
+ return null;
94991
95007
  }
94992
- return cur;
94993
95008
  }
94994
- function unparsedMemberDefinition(graph, resolvedAbs, imported) {
94995
- if (graph.workspaceMembership?.(resolvedAbs) !== true)
94996
- return null;
94997
- const def = graph.resolveLocalDefinition?.(resolvedAbs, imported) ?? null;
94998
- return { absFile: def?.absFile ?? resolvedAbs, exportName: def?.exportName ?? imported };
95009
+ function pinUnparsed(graph, binding2) {
95010
+ if (binding2.kind !== "unparsed" || binding2.mainGap !== void 0 || !isAbsolute8(binding2.file))
95011
+ return binding2;
95012
+ if (graph.workspaceMembership?.(binding2.file) !== true)
95013
+ return binding2;
95014
+ const def = graph.resolveLocalDefinition?.(binding2.file, binding2.exportName) ?? null;
95015
+ return def === null ? binding2 : { ...binding2, file: def.absFile, exportName: def.exportName };
95016
+ }
95017
+
95018
+ // ../reference-graph/dist/engine/resolve-reference.js
95019
+ function resolveReference(graph, fileGraph, ref, guard = createCycleGuard()) {
95020
+ return bindingValue(resolveBinding(graph, fileGraph, ref, guard));
94999
95021
  }
95000
95022
 
95001
95023
  // ../reference-graph/dist/engine/assert-never.js
@@ -95419,13 +95441,13 @@ function foldToWrappedArg(inner, via) {
95419
95441
  }
95420
95442
  return [indeterminateTerminal()];
95421
95443
  }
95422
- function argumentProvenance(type, arg, fileGraph) {
95423
- const importRecord = findImportForLastArg(arg, fileGraph);
95444
+ function argumentProvenance(graph, type, arg, fileGraph) {
95445
+ const importRecord = findImportForLastArg(graph, arg, fileGraph);
95424
95446
  const resolved = importRecord ? { specifier: importRecord.specifier, import: importRecord.imported } : resolveAnonymousLastArg(arg, fileGraph);
95425
95447
  return { callee: deriveHocCallee(type.callee), specifier: resolved.specifier, import: resolved.import };
95426
95448
  }
95427
- function buildHocVia(type, lastArg, fileGraph) {
95428
- const { callee, specifier, import: imported } = argumentProvenance(type, lastArg, fileGraph);
95449
+ function buildHocVia(graph, type, lastArg, fileGraph) {
95450
+ const { callee, specifier, import: imported } = argumentProvenance(graph, type, lastArg, fileGraph);
95429
95451
  return { kind: "hoc-wrapper", hocCallee: callee, specifier, import: imported };
95430
95452
  }
95431
95453
  function foldedArgument(graph, fileGraph, call, jsx, argMap) {
@@ -95433,7 +95455,7 @@ function foldedArgument(graph, fileGraph, call, jsx, argMap) {
95433
95455
  const arg = call.args[index];
95434
95456
  if (arg === void 0 || jsx.length === 0)
95435
95457
  return null;
95436
- const via = buildHocVia(call, arg, fileGraph);
95458
+ const via = buildHocVia(graph, call, arg, fileGraph);
95437
95459
  return jsx.every((t3) => t3.viaTrail[0] !== void 0 && sameHocVia(t3.viaTrail[0], via)) ? { arg, via } : null;
95438
95460
  }
95439
95461
  function sameHocVia(a3, b) {
@@ -95505,14 +95527,8 @@ function fileGraphForDynamicImport(graph, di, fallback) {
95505
95527
  }
95506
95528
  function dynamicImportIdentity(graph, fileGraph, di) {
95507
95529
  const origin = fileGraphForDynamicImport(graph, di, fileGraph);
95508
- const importedName = di.projection[0] ?? "default";
95509
- const resolvedFile = graph ? resolveImportedFile(graph, origin, di.specifier, importedName) : null;
95510
- return workspaceSiblingIdentity(graph, origin, di.specifier, importedName) ?? relativeChainLocalIdentity(graph, origin, di.specifier, importedName) ?? memberLocalIdentity(graph, origin, di.specifier, importedName) ?? {
95511
- kind: "imported",
95512
- specifier: di.specifier,
95513
- imported: importedName,
95514
- resolvedFile
95515
- };
95530
+ const binding2 = resolveModuleExport(graph, origin.filePath, di.specifier, di.projection[0] ?? "default", []);
95531
+ return bindingIdentity(pinUnparsed(graph, binding2));
95516
95532
  }
95517
95533
  function walkTypeOf(graph, fileGraph, type, argMap, guard, fallback, position) {
95518
95534
  if (guard.pushNode(type) === "cycle") {
@@ -95529,22 +95545,12 @@ function walkTypeOf(graph, fileGraph, type, argMap, guard, fallback, position) {
95529
95545
  if (inner.every((t3) => t3.identity !== null))
95530
95546
  return inner;
95531
95547
  const derived = position === "tag" && inner.some((t3) => t3.identity === null && isCallable(t3)) || resolved.kind !== "ParameterOf" && evalKind(resolved, graph, innerGraph, argMap) === "component" ? deriveIdentity(type, fileGraph, graph) : null;
95532
- const self2 = position === "tag" ? withOwnDeclaration(derived, graph, fileGraph, type.ref) : derived;
95533
- const stamp = self2 ?? deriveIdentity(fallback, fileGraph, graph);
95548
+ const stamp = derived ?? deriveIdentity(fallback, fileGraph, graph);
95534
95549
  return inner.map((t3) => t3.identity === null ? { denotation: t3.denotation, viaTrail: t3.viaTrail, identity: stamp, semantics: t3.semantics } : t3);
95535
95550
  } finally {
95536
95551
  guard.popNode(type);
95537
95552
  }
95538
95553
  }
95539
- function withOwnDeclaration(identity, graph, fileGraph, ref) {
95540
- if (identity === null || identity.kind !== "local" || ref.memberChain.length > 0)
95541
- return identity;
95542
- const lookup2 = fileGraphForRef(graph, ref, fileGraph);
95543
- if (identity.filePath !== lookup2.filePath || lookup2.importsByLocal.has(ref.symbol))
95544
- return identity;
95545
- const declaration2 = findLocalDeclaration(lookup2, ref);
95546
- return declaration2 === null ? identity : { ...identity, declaration: declaration2 };
95547
- }
95548
95554
  function walkStaticMember(graph, fileGraph, type, argMap, guard, fallback, position) {
95549
95555
  if (guard.pushNode(type) === "cycle") {
95550
95556
  return [indeterminateTerminal()];
@@ -95599,7 +95605,7 @@ function foldCall(graph, fileGraph, type, argMap, guard, position) {
95599
95605
  }
95600
95606
  let inner2;
95601
95607
  try {
95602
- const target = resolveDynamicImportTarget(graph, fileGraph, syntheticDI, guard);
95608
+ const target = resolveDynamicImportTarget(graph, fileGraph, syntheticDI);
95603
95609
  inner2 = target ? walkInner(graph, target.targetFileGraph, target.value, argMap, guard, void 0, position) : walkInner(graph, fileGraph, syntheticDI, argMap, guard, void 0, position);
95604
95610
  } finally {
95605
95611
  guard.pop(syntheticDI.originFile, guardKey);
@@ -95631,7 +95637,7 @@ function foldCall(graph, fileGraph, type, argMap, guard, position) {
95631
95637
  const wrapped = type.args[passThroughIndex];
95632
95638
  if (wrapped !== void 0) {
95633
95639
  const inner2 = walkInner(graph, fileGraph, wrapped, argMap, guard, void 0, position);
95634
- return foldToWrappedArg(inner2, buildHocVia(type, wrapped, fileGraph));
95640
+ return foldToWrappedArg(inner2, buildHocVia(graph, type, wrapped, fileGraph));
95635
95641
  }
95636
95642
  }
95637
95643
  const algResult = foldTerminals(graph, fileGraph, resolveType(graph, fileGraph, type, argMap, guard), type);
@@ -95641,7 +95647,7 @@ function foldCall(graph, fileGraph, type, argMap, guard, position) {
95641
95647
  if (lastArg2 !== void 0) {
95642
95648
  const inner2 = walkInner(graph, fileGraph, lastArg2, argMap, guard, void 0, position);
95643
95649
  if (isPassThroughWrapper(algResult, inner2)) {
95644
- const via = buildHocVia(type, lastArg2, fileGraph);
95650
+ const via = buildHocVia(graph, type, lastArg2, fileGraph);
95645
95651
  return inner2.filter((t3) => !cameToNothing(t3)).map((t3) => ({ denotation: t3.denotation, viaTrail: [via, ...t3.viaTrail], identity: t3.identity }));
95646
95652
  }
95647
95653
  }
@@ -95661,7 +95667,7 @@ function foldCall(graph, fileGraph, type, argMap, guard, position) {
95661
95667
  }
95662
95668
  return [indeterminateTerminal()];
95663
95669
  }
95664
- return foldToWrappedArg(inner, buildHocVia(type, lastArg, fileGraph));
95670
+ return foldToWrappedArg(inner, buildHocVia(graph, type, lastArg, fileGraph));
95665
95671
  }
95666
95672
  function passThroughParameterIndex(graph, fileGraph, type, argMap, guard) {
95667
95673
  const calleeFns = resolveToFunctions(graph, fileGraph, type.callee, argMap, guard);
@@ -95821,14 +95827,19 @@ function deriveHocCallee(callee) {
95821
95827
  return "unknown";
95822
95828
  }
95823
95829
  }
95824
- function findImportForLastArg(lastArg, fileGraph) {
95830
+ function findImportForLastArg(graph, lastArg, fileGraph) {
95825
95831
  let cur = lastArg;
95826
95832
  while (cur.kind === "ReturnTypeOf")
95827
95833
  cur = cur.callee;
95828
95834
  if (cur.kind !== "TypeOf")
95829
95835
  return null;
95830
95836
  const imp = fileGraph.importsByLocal.get(cur.ref.symbol);
95831
- return imp ? { specifier: imp.specifier, imported: imp.imported } : null;
95837
+ if (!imp)
95838
+ return null;
95839
+ const binding2 = resolveBinding(graph, fileGraph, cur.ref);
95840
+ if (binding2.kind === "declaration" && binding2.inScope && binding2.file === fileGraph.filePath)
95841
+ return null;
95842
+ return { specifier: imp.specifier, imported: imp.imported };
95832
95843
  }
95833
95844
  function resolveAnonymousLastArg(lastArg, fileGraph) {
95834
95845
  let cur = lastArg;
@@ -95872,104 +95883,11 @@ function typeContainsRef(haystack, needle) {
95872
95883
  return false;
95873
95884
  }
95874
95885
  }
95875
- function resolveImportedFile(graph, fileGraph, specifier, imported) {
95876
- const abs = graph.moduleResolver(fileGraph.filePath, specifier);
95877
- if (!abs)
95878
- return null;
95879
- const key = graph.resolveToGraphKey ? graph.resolveToGraphKey(abs) : abs;
95880
- if (!key || !imported)
95881
- return key;
95882
- return followReExportChain(graph, key, imported)?.file ?? key;
95883
- }
95884
- function relativeChainLocalIdentity(graph, fileGraph, specifier, imported) {
95885
- if (!graph)
95886
- return null;
95887
- if (packageNameFromSpecifier(specifier))
95888
- return null;
95889
- const abs = graph.moduleResolver(fileGraph.filePath, specifier);
95890
- if (!abs)
95891
- return null;
95892
- const key = graph.resolveToGraphKey ? graph.resolveToGraphKey(abs) : abs;
95893
- if (!key || !graph.files.has(key))
95894
- return null;
95895
- const chained = followReExportChain(graph, key, imported);
95896
- if (!chained)
95897
- return null;
95898
- return { kind: "local", filePath: chained.file, export: chained.localExport };
95899
- }
95900
- function workspaceSiblingIdentity(graph, fileGraph, specifier, imported) {
95901
- if (!graph)
95902
- return null;
95903
- if (!packageNameFromSpecifier(specifier))
95904
- return null;
95905
- const abs = graph.moduleResolver(fileGraph.filePath, specifier);
95906
- const key = abs && (graph.resolveToGraphKey ? graph.resolveToGraphKey(abs) : abs);
95907
- if (!key)
95908
- return null;
95909
- const chained = followReExportChain(graph, key, imported);
95910
- const file = chained?.file ?? key;
95911
- if (!graph.files.has(file))
95912
- return null;
95913
- return { kind: "local", filePath: file, export: chained?.localExport ?? imported };
95914
- }
95915
- function memberLocalIdentity(graph, fileGraph, specifier, imported) {
95916
- if (graph?.workspaceMembership === void 0)
95917
- return null;
95918
- const abs = graph.moduleResolver(fileGraph.filePath, specifier);
95919
- if (!abs)
95920
- return null;
95921
- const key = graph.resolveToGraphKey ? graph.resolveToGraphKey(abs) : abs;
95922
- if (key !== null && graph.files.has(key))
95923
- return null;
95924
- const member = unparsedMemberDefinition(graph, abs, imported);
95925
- if (member === null)
95926
- return null;
95927
- return { kind: "local", filePath: member.absFile, export: member.exportName };
95928
- }
95929
- function withResidual(identity, residual) {
95930
- if (identity === null || residual.length === 0)
95931
- return identity;
95932
- return identity.kind === "local" ? { ...identity, export: compoundExportName(identity.export, residual) } : { ...identity, imported: compoundExportName(identity.imported, residual) };
95933
- }
95934
95886
  function deriveIdentity(type, fileGraph, graph) {
95935
- const cur = type;
95936
- if (cur.kind === "DynamicImport") {
95937
- return dynamicImportIdentity(graph, fileGraph, cur);
95938
- }
95939
- if (cur.kind === "TypeOf") {
95940
- const symbol2 = cur.ref.symbol;
95941
- const lookup2 = graph ? fileGraphForRef(graph, cur.ref, fileGraph) : fileGraph;
95942
- const imp = lookup2.importsByLocal.get(symbol2);
95943
- if (imp) {
95944
- const imported = effectiveExportName(imp.imported, cur.ref.memberChain);
95945
- const residual = residualMemberChain(imp.imported, cur.ref.memberChain);
95946
- const resolvedFile = graph ? resolveImportedFile(graph, lookup2, imp.specifier, imported) : null;
95947
- const workspaceLocal = workspaceSiblingIdentity(graph, lookup2, imp.specifier, imported);
95948
- if (workspaceLocal)
95949
- return withResidual(workspaceLocal, residual);
95950
- const relativeLocal = relativeChainLocalIdentity(graph, lookup2, imp.specifier, imported);
95951
- if (relativeLocal)
95952
- return withResidual(relativeLocal, residual);
95953
- const memberLocal = memberLocalIdentity(graph, lookup2, imp.specifier, imported);
95954
- if (memberLocal)
95955
- return withResidual(memberLocal, residual);
95956
- return withResidual({
95957
- kind: "imported",
95958
- specifier: imp.specifier,
95959
- imported,
95960
- resolvedFile
95961
- }, residual);
95962
- }
95963
- for (const [, decl] of lookup2.declarations) {
95964
- if (decl && decl.symbol === symbol2) {
95965
- return withResidual({
95966
- kind: "local",
95967
- filePath: lookup2.filePath,
95968
- export: decl.exportedAs ?? symbol2
95969
- }, cur.ref.memberChain);
95970
- }
95971
- }
95972
- }
95887
+ if (type.kind === "DynamicImport")
95888
+ return dynamicImportIdentity(graph, fileGraph, type);
95889
+ if (type.kind === "TypeOf")
95890
+ return bindingIdentity(pinUnparsed(graph, resolveBinding(graph, fileGraph, type.ref)));
95973
95891
  return null;
95974
95892
  }
95975
95893
 
@@ -96075,7 +95993,7 @@ function resolveTypeInner(graph, fileGraph, type, argMap, guard) {
96075
95993
  case "Array":
96076
95994
  return [{ type, source: null }];
96077
95995
  case "DynamicImport": {
96078
- const target = resolveDynamicImportTarget(graph, fileGraph, type, guard);
95996
+ const target = resolveDynamicImportTarget(graph, fileGraph, type);
96079
95997
  if (!target)
96080
95998
  return [{ type, source: type }];
96081
95999
  return resolveType(graph, target.targetFileGraph, target.value, argMap, guard);
@@ -96084,29 +96002,17 @@ function resolveTypeInner(graph, fileGraph, type, argMap, guard) {
96084
96002
  return assertNever(type);
96085
96003
  }
96086
96004
  }
96087
- function resolveDynamicImportTarget(graph, fileGraph, di, guard) {
96005
+ function resolveDynamicImportTarget(graph, fileGraph, di) {
96088
96006
  const origin = fileGraphForDynamicImport(graph, di, fileGraph);
96089
- const absPath = graph.moduleResolver(origin.filePath, di.specifier);
96090
- if (!absPath)
96007
+ const b = resolveModuleExport(graph, origin.filePath, di.specifier, di.projection[0] ?? "default", []);
96008
+ const targetFile = b.kind === "declaration" ? b.file : b.kind === "unparsed" && b.mainGap !== void 0 ? b.mainGap.barrel : null;
96009
+ const targetFileGraph = targetFile === null ? void 0 : graph.files.get(targetFile);
96010
+ if (!targetFileGraph)
96091
96011
  return null;
96092
- const key = graph.resolveToGraphKey ? graph.resolveToGraphKey(absPath) ?? absPath : absPath;
96093
- const chained = followReExportChain(graph, key, di.projection[0] ?? "default");
96094
- const targetFile = chained ? graph.files.get(chained.file) : void 0;
96095
- if (!chained || !targetFile)
96096
- return null;
96097
- const local = chained.localExport;
96098
- if (!targetFile.declarations.has(`${MODULE_SCOPE}::${local}`) && !targetFile.importsByLocal.has(local))
96099
- return null;
96100
- const localRef = {
96101
- symbol: local,
96102
- scope: MODULE_SCOPE,
96103
- memberChain: [],
96104
- loc: { line: 0, column: 0 }
96105
- };
96106
- let value = resolveReference(graph, targetFile, localRef, guard);
96012
+ let value = bindingValue(b);
96107
96013
  for (const member of di.projection.slice(1))
96108
96014
  value = { kind: "MemberOf", obj: value, member };
96109
- return { targetFileGraph: targetFile, value };
96015
+ return { targetFileGraph, value };
96110
96016
  }
96111
96017
  function resolveToFunctions(graph, fileGraph, type, argMap, guard) {
96112
96018
  if (guard.pushNode(type) === "cycle") {
@@ -96203,6 +96109,282 @@ function resolveToFunctionsInner(graph, fileGraph, type, argMap, guard) {
96203
96109
  // ../reference-graph/dist/engine/index.js
96204
96110
  import { asTagName, computeOccurrenceId, serialiseComponentId, projectPropUsages, parseCompoundExport as parseCompoundExport2 } from "@component-compass/plugin-core";
96205
96111
 
96112
+ // ../reference-graph/dist/engine/re-export-chain.js
96113
+ function followReExportChain(graph, file, imported) {
96114
+ return walk2(graph, file, imported, /* @__PURE__ */ new Set());
96115
+ }
96116
+ function walk2(graph, file, imported, seen2) {
96117
+ const seenKey = `${file}::${imported}`;
96118
+ if (seen2.has(seenKey))
96119
+ return null;
96120
+ seen2.add(seenKey);
96121
+ const target = graph.files.get(file);
96122
+ if (!target)
96123
+ return null;
96124
+ const exp = exportRecordFor(target, imported);
96125
+ if (exp) {
96126
+ if (exp.kind === "named" && "from" in exp) {
96127
+ const nextAbs = graph.moduleResolver(file, exp.from);
96128
+ if (!nextAbs)
96129
+ return { file, localExport: imported };
96130
+ const nextKey = graphKeyFor(graph, nextAbs);
96131
+ if (!nextKey)
96132
+ return { file, localExport: imported };
96133
+ return walk2(graph, nextKey, exp.fromImported, seen2) ?? {
96134
+ file: nextKey,
96135
+ localExport: exp.fromImported
96136
+ };
96137
+ }
96138
+ if ("local" in exp) {
96139
+ const imp = target.importsByLocal.get(exp.local);
96140
+ if (imp && imp.imported !== "*" && !packageNameFromSpecifier(imp.specifier)) {
96141
+ const nextAbs = graph.moduleResolver(file, imp.specifier);
96142
+ const nextKey = nextAbs ? graphKeyFor(graph, nextAbs) : null;
96143
+ if (nextKey) {
96144
+ const leaf = walk2(graph, nextKey, imp.imported, seen2);
96145
+ if (leaf)
96146
+ return leaf;
96147
+ if (graph.lazyReExportResolution && !graph.files.has(nextKey)) {
96148
+ return { file: nextKey, localExport: imp.imported };
96149
+ }
96150
+ }
96151
+ }
96152
+ return { file, localExport: exp.local };
96153
+ }
96154
+ return { file, localExport: imported };
96155
+ }
96156
+ for (const starExp of target.exports) {
96157
+ if (starExp.kind !== "star")
96158
+ continue;
96159
+ const nextAbs = graph.moduleResolver(file, starExp.from);
96160
+ if (!nextAbs)
96161
+ continue;
96162
+ const nextKey = graphKeyFor(graph, nextAbs);
96163
+ if (!nextKey)
96164
+ continue;
96165
+ const result2 = walk2(graph, nextKey, imported, seen2);
96166
+ if (result2)
96167
+ return result2;
96168
+ }
96169
+ return null;
96170
+ }
96171
+
96172
+ // ../reference-graph/dist/engine/helper-callers.js
96173
+ function classifyDeclaration(decl, registry, fileGraph) {
96174
+ if (decl.value.kind !== "Function" && decl.value.kind !== "ReturnTypeOf")
96175
+ return "unknown";
96176
+ if (fileGraph.dialect === "vue" && isSfcDeclaration(fileGraph, decl))
96177
+ return "component";
96178
+ return registry.hasLocal(fileGraph.filePath, decl.symbol) ? "component" : "helper";
96179
+ }
96180
+ var isSfcDeclaration = (fileGraph, decl) => fileGraph.exports.some((e) => e.kind === "default" && "local" in e && e.local === decl.symbol);
96181
+ function buildHelperCallers(graph, registry) {
96182
+ const index = /* @__PURE__ */ new Map();
96183
+ const callerKeysByHelper = /* @__PURE__ */ new Map();
96184
+ const classificationCache = /* @__PURE__ */ new Map();
96185
+ const refResolutionCache = /* @__PURE__ */ new Map();
96186
+ function resolveRefCached(ref, callerFile, callerGraph) {
96187
+ const key = `${callerFile}::${ref.symbol}`;
96188
+ if (refResolutionCache.has(key)) {
96189
+ return refResolutionCache.get(key) ?? null;
96190
+ }
96191
+ const result2 = resolveRefToDecl(ref, callerFile, callerGraph, graph);
96192
+ refResolutionCache.set(key, result2);
96193
+ return result2;
96194
+ }
96195
+ const pendingValueRefs = [];
96196
+ for (const [file, fileGraph] of graph.files) {
96197
+ for (const decl of fileGraph.declarations.values()) {
96198
+ if (decl.scope !== MODULE_SCOPE)
96199
+ continue;
96200
+ const refs = [];
96201
+ if (decl.value.kind === "Function") {
96202
+ for (const r2 of decl.value.returns)
96203
+ collectRefsInType(r2, refs);
96204
+ } else if (decl.value.kind === "ReturnTypeOf") {
96205
+ collectCalleeRefs(decl.value, refs);
96206
+ }
96207
+ for (const bc of fileGraph.bodyCalls) {
96208
+ if (bc.ownerSymbol === decl.symbol)
96209
+ refs.push(bc.callee);
96210
+ }
96211
+ const callerKey = { file, symbol: decl.symbol };
96212
+ for (const ref of refs) {
96213
+ const target = resolveRefCached(ref, file, fileGraph);
96214
+ if (!target)
96215
+ continue;
96216
+ pendingValueRefs.push({ target, caller: callerKey });
96217
+ }
96218
+ }
96219
+ }
96220
+ const pendingJsxCalls = [];
96221
+ for (const [file, fileGraph] of graph.files) {
96222
+ for (let i2 = 0; i2 < fileGraph.jsxUsages.length; i2++) {
96223
+ const usage = fileGraph.jsxUsages[i2];
96224
+ if (!usage)
96225
+ continue;
96226
+ const target = resolveRefCached(usage.ref, file, fileGraph);
96227
+ if (!target)
96228
+ continue;
96229
+ const ownership = fileGraph.ownership[i2];
96230
+ if (!ownership?.ownerSymbolRef)
96231
+ continue;
96232
+ const callerTarget = resolveRefCached(ownership.ownerSymbolRef, file, fileGraph);
96233
+ if (!callerTarget)
96234
+ continue;
96235
+ if (callerTarget.decl.scope !== MODULE_SCOPE)
96236
+ continue;
96237
+ pendingJsxCalls.push({
96238
+ target,
96239
+ caller: { file: callerTarget.file, symbol: callerTarget.decl.symbol }
96240
+ });
96241
+ }
96242
+ }
96243
+ function classifyKey(file, decl) {
96244
+ const key = `${file}::${decl.symbol}`;
96245
+ const hit = classificationCache.get(key);
96246
+ if (hit !== void 0)
96247
+ return hit;
96248
+ const fileGraph = graph.files.get(file);
96249
+ const result2 = fileGraph ? classifyDeclaration(decl, registry, fileGraph) : "unknown";
96250
+ classificationCache.set(key, result2);
96251
+ return result2;
96252
+ }
96253
+ for (const [file, fileGraph] of graph.files) {
96254
+ for (const decl of fileGraph.declarations.values()) {
96255
+ if (decl.scope !== MODULE_SCOPE)
96256
+ continue;
96257
+ if (decl.value.kind !== "Function" && decl.value.kind !== "ReturnTypeOf")
96258
+ continue;
96259
+ classifyKey(file, decl);
96260
+ }
96261
+ }
96262
+ function recordCallerEdge(target, callerKey) {
96263
+ const keyStr = `${target.file}::${target.decl.symbol}`;
96264
+ const callerKeyStr = `${callerKey.file}::${callerKey.symbol}`;
96265
+ let seen2 = callerKeysByHelper.get(keyStr);
96266
+ if (!seen2) {
96267
+ seen2 = /* @__PURE__ */ new Set();
96268
+ callerKeysByHelper.set(keyStr, seen2);
96269
+ }
96270
+ if (seen2.has(callerKeyStr))
96271
+ return;
96272
+ seen2.add(callerKeyStr);
96273
+ let callers = index.get(keyStr);
96274
+ if (!callers) {
96275
+ callers = /* @__PURE__ */ new Set();
96276
+ index.set(keyStr, callers);
96277
+ }
96278
+ callers.add(callerKey);
96279
+ }
96280
+ for (const { target, caller } of pendingValueRefs) {
96281
+ if (classifyKey(target.file, target.decl) !== "helper")
96282
+ continue;
96283
+ recordCallerEdge(target, caller);
96284
+ }
96285
+ for (const { target, caller } of pendingJsxCalls) {
96286
+ if (classifyKey(target.file, target.decl) !== "helper")
96287
+ continue;
96288
+ recordCallerEdge(target, caller);
96289
+ }
96290
+ return {
96291
+ get(key) {
96292
+ return index.get(`${key.file}::${key.symbol}`);
96293
+ },
96294
+ classification(file, symbol2) {
96295
+ return classificationCache.get(`${file}::${symbol2}`) ?? "unknown";
96296
+ }
96297
+ };
96298
+ }
96299
+ function collectCalleeRefs(t3, out2) {
96300
+ switch (t3.kind) {
96301
+ case "ReturnTypeOf":
96302
+ collectCalleeRefs(t3.callee, out2);
96303
+ return;
96304
+ case "MemberOf":
96305
+ collectCalleeRefs(t3.obj, out2);
96306
+ return;
96307
+ case "TypeOf":
96308
+ out2.push(t3.ref);
96309
+ return;
96310
+ default:
96311
+ return;
96312
+ }
96313
+ }
96314
+ function collectRefsInType(t3, out2) {
96315
+ switch (t3.kind) {
96316
+ case "TypeOf":
96317
+ out2.push(t3.ref);
96318
+ return;
96319
+ case "Union":
96320
+ for (const u3 of t3.types)
96321
+ collectRefsInType(u3, out2);
96322
+ return;
96323
+ case "ReturnTypeOf":
96324
+ collectRefsInType(t3.callee, out2);
96325
+ for (const a3 of t3.args)
96326
+ collectRefsInType(a3, out2);
96327
+ return;
96328
+ case "Function":
96329
+ for (const r2 of t3.returns)
96330
+ collectRefsInType(r2, out2);
96331
+ return;
96332
+ case "Object":
96333
+ for (const v of Object.values(t3.props))
96334
+ collectRefsInType(v, out2);
96335
+ return;
96336
+ case "Array":
96337
+ for (const e of t3.elements)
96338
+ collectRefsInType(e, out2);
96339
+ return;
96340
+ case "MemberOf":
96341
+ collectRefsInType(t3.obj, out2);
96342
+ return;
96343
+ case "ParameterOf":
96344
+ return;
96345
+ default:
96346
+ return;
96347
+ }
96348
+ }
96349
+ function resolveRefToDecl(ref, callerFile, callerGraph, graph) {
96350
+ const localKey = `${MODULE_SCOPE}::${ref.symbol}`;
96351
+ const localDecl = callerGraph.declarations.get(localKey);
96352
+ if (localDecl)
96353
+ return { file: callerFile, decl: localDecl };
96354
+ const imp = callerGraph.importsByLocal.get(ref.symbol);
96355
+ if (!imp)
96356
+ return null;
96357
+ const resolvedAbs = graph.moduleResolver(callerFile, imp.specifier);
96358
+ if (!resolvedAbs)
96359
+ return null;
96360
+ const targetFile = graphKeyFor(graph, resolvedAbs) ?? resolvedAbs;
96361
+ const targetGraph = graph.files.get(targetFile);
96362
+ if (!targetGraph)
96363
+ return null;
96364
+ const chained = followReExportChain(graph, targetFile, imp.imported);
96365
+ if (chained) {
96366
+ const chainedGraph = graph.files.get(chained.file);
96367
+ if (chainedGraph) {
96368
+ const decl = chainedGraph.declarations.get(`${MODULE_SCOPE}::${chained.localExport}`);
96369
+ if (decl)
96370
+ return { file: chained.file, decl };
96371
+ }
96372
+ }
96373
+ for (const exp of targetGraph.exports) {
96374
+ if (exp.kind === "named" && "local" in exp && exp.exportedAs === imp.imported) {
96375
+ const decl = targetGraph.declarations.get(`${MODULE_SCOPE}::${exp.local}`);
96376
+ if (decl)
96377
+ return { file: targetFile, decl };
96378
+ }
96379
+ if (exp.kind === "default" && "local" in exp && imp.imported === "default") {
96380
+ const decl = targetGraph.declarations.get(`${MODULE_SCOPE}::${exp.local}`);
96381
+ if (decl)
96382
+ return { file: targetFile, decl };
96383
+ }
96384
+ }
96385
+ return null;
96386
+ }
96387
+
96206
96388
  // ../reference-graph/dist/engine/owner-resolution.js
96207
96389
  function resolveOwnerChain(ownerRef, graph, helperIndex, guard) {
96208
96390
  if (!ownerRef)
@@ -96264,24 +96446,10 @@ function narrowTo(registry, entries) {
96264
96446
  isComponent: (filePath, name, declaration2) => registry.isComponent(filePath, name, declaration2),
96265
96447
  declarationOf: (filePath, exportName) => registry.declarationOf(filePath, exportName),
96266
96448
  isRenderedAsTag: (entry) => registry.isRenderedAsTag(entry),
96267
- isTagged: (filePath, name, declaration2) => registry.isTagged(filePath, name, declaration2),
96449
+ isTagged: (declaration2) => registry.isTagged(declaration2),
96268
96450
  localEntries: () => entries
96269
96451
  };
96270
96452
  }
96271
- var CAN_HOLD_A_FUNCTION = {
96272
- TypeOf: true,
96273
- Function: true,
96274
- ReturnTypeOf: true,
96275
- ParameterOf: false,
96276
- MemberOf: true,
96277
- Union: true,
96278
- Object: false,
96279
- Array: false,
96280
- JSX: false,
96281
- Str: false,
96282
- Unknown: false,
96283
- DynamicImport: true
96284
- };
96285
96453
  function buildComponentRegistry(graph, tagged = []) {
96286
96454
  const consumed = /* @__PURE__ */ new Set();
96287
96455
  for (const [file, fg] of graph.files) {
@@ -96304,25 +96472,8 @@ function buildComponentRegistry(graph, tagged = []) {
96304
96472
  consumed.add(entryKey(target.file, target.symbol));
96305
96473
  }
96306
96474
  }
96307
- const taggedDeclaration = (filePath, name, declaration2) => {
96308
- const fg = graph.files.get(filePath);
96309
- if (fg === void 0)
96310
- return void 0;
96311
- if (declaration2 !== void 0)
96312
- return declaration2;
96313
- const named = findDeclaration(fg, name);
96314
- return named !== void 0 && CAN_HOLD_A_FUNCTION[named.value.kind] ? named : void 0;
96315
- };
96316
- const renderedAsTag = /* @__PURE__ */ new Set();
96317
- for (const { filePath, exportName, declaration: declaration2 } of tagged) {
96318
- const marked = taggedDeclaration(filePath, exportName, declaration2);
96319
- if (marked !== void 0)
96320
- renderedAsTag.add(marked);
96321
- }
96322
- const isTagged = (filePath, name, declaration2) => {
96323
- const marked = taggedDeclaration(filePath, name, declaration2);
96324
- return marked !== void 0 && renderedAsTag.has(marked);
96325
- };
96475
+ const renderedAsTag = new Set(tagged);
96476
+ const isTagged = (declaration2) => declaration2 !== void 0 && renderedAsTag.has(declaration2);
96326
96477
  const byKey = /* @__PURE__ */ new Map();
96327
96478
  const entryIndex = /* @__PURE__ */ new Map();
96328
96479
  const entries = [];
@@ -96473,7 +96624,7 @@ function resolve5(graph, opts) {
96473
96624
  const argMap = createArgumentMap();
96474
96625
  const tagEvaluations = /* @__PURE__ */ new Map();
96475
96626
  for (const [filePath, fileGraph] of graph.files) {
96476
- tagEvaluations.set(filePath, fileGraph.jsxUsages.map((usage) => evaluateJsxUsage(graph, filePath, fileGraph, usage, argMap)));
96627
+ tagEvaluations.set(filePath, fileGraph.jsxUsages.map((usage) => evaluateJsxUsage(graph, fileGraph, usage, argMap)));
96477
96628
  }
96478
96629
  const registry = buildComponentRegistry(graph, taggedDeclarations(graph, tagEvaluations));
96479
96630
  const helperIndex = buildHelperCallers(graph, excludeHostElementNames(registry, graph));
@@ -96715,32 +96866,6 @@ function relabelExternalLeaf(rawComponentId, filePath, specifier, resolveExterna
96715
96866
  source: externalSource(hit.leafPackage, `${hit.leafPackage}/${hit.modulePath}`)
96716
96867
  };
96717
96868
  }
96718
- function workspaceSiblingFallback(graph, resolvedTarget, matchedImport, effectiveImported, consumerDialect) {
96719
- if (!resolvedTarget)
96720
- return void 0;
96721
- const chained = followReExportChain(graph, resolvedTarget, effectiveImported);
96722
- const canonicalFile = chained?.file ?? resolvedTarget;
96723
- let exportName = chained?.localExport ?? effectiveImported;
96724
- if (!chained) {
96725
- const target = graph.files.get(resolvedTarget);
96726
- if (!target)
96727
- return void 0;
96728
- if (effectiveImported === "default") {
96729
- const def = target.exports.find((e) => e.kind === "default");
96730
- if (def && "local" in def)
96731
- exportName = def.local;
96732
- } else {
96733
- const named = target.exports.find((e) => e.kind === "named" && "exportedAs" in e && e.exportedAs === effectiveImported && "local" in e);
96734
- if (named && "local" in named)
96735
- exportName = named.local;
96736
- }
96737
- }
96738
- return {
96739
- kind: componentKindFor(consumerDialect),
96740
- export: exportName,
96741
- source: { type: "local", filePath: canonicalFile }
96742
- };
96743
- }
96744
96869
  function emitOccurrence(occurrences, site, rawComponentId, owners, chain, definition) {
96745
96870
  const provisionalId = serialiseComponentId(rawComponentId);
96746
96871
  for (const { rawOwnerComponentId, viaPrefix } of owners) {
@@ -96785,136 +96910,74 @@ function usageOwners(graph, helperIndex, ownerRef, viaOverride, fallbackFile) {
96785
96910
  function namesObjectMember(holder, path5) {
96786
96911
  return path5.length === 0 || memberOfObjectPath(holder, path5) !== void 0;
96787
96912
  }
96788
- function evaluateJsxUsage(graph, filePath, fileGraph, usage, argMap) {
96913
+ function evaluateJsxUsage(graph, fileGraph, usage, argMap) {
96789
96914
  if (fileGraph.dialect === "react" && isHostElementRoot(usage.ref))
96790
96915
  return { kind: "host-element" };
96791
- const matchedImport = fileGraph.importsByLocal.get(usage.ref.symbol);
96792
- if (!matchedImport) {
96793
- const decl = findLocalDeclaration(fileGraph, usage.ref);
96794
- if (!decl)
96795
- return { kind: "unbound" };
96796
- const value = usage.ref.memberChain.length > 0 ? resolveReference(graph, fileGraph, usage.ref) : decl.value;
96797
- const evaluation = walkWithFolding(graph, fileGraph, value, argMap, createCycleGuard(), void 0, "tag");
96798
- const fallback2 = {
96799
- kind: componentKindFor(fileGraph.dialect),
96800
- export: compoundExportName(usage.ref.symbol, usage.ref.memberChain),
96801
- source: { type: "local", filePath }
96802
- };
96803
- const definition = { line: decl.loc.line, column: decl.loc.column };
96804
- const outerVia2 = { kind: "local-component" };
96805
- const rendered = usage.ref.memberChain.length === 0 ? { declaration: decl } : {};
96806
- const named = namesObjectMember(decl.value, usage.ref.memberChain);
96807
- const credits = creditedTerminals(evaluation).filter((t3) => t3.identity !== null || named).map((terminal) => ({
96808
- terminal,
96809
- fallback: fallback2,
96810
- outerVia: outerVia2,
96811
- ...terminal.identity === null ? { definition, ...rendered } : {}
96812
- }));
96813
- return { kind: "evaluated", evaluation, value, credits };
96814
- }
96815
- const packageName = packageNameFromSpecifier(matchedImport.specifier);
96816
- const effectiveImported = effectiveExportName(matchedImport.imported, usage.ref.memberChain);
96817
- const residual = residualMemberChain(matchedImport.imported, usage.ref.memberChain);
96818
- const holderDecl = (file, exportName) => {
96819
- const holderFile = graph.files.get(file);
96820
- return holderFile === void 0 ? void 0 : findDeclaration(holderFile, exportName);
96821
- };
96822
- const holderDefinition = (file, exportName) => {
96823
- if (residual.length === 0)
96824
- return void 0;
96825
- const loc = holderDecl(file, exportName)?.loc;
96826
- return loc === void 0 ? void 0 : { line: loc.line, column: loc.column };
96916
+ const binding2 = resolveBinding(graph, fileGraph, usage.ref);
96917
+ const imp = fileGraph.importsByLocal.get(usage.ref.symbol);
96918
+ const walkTag = (value) => walkWithFolding(graph, fileGraph, value, argMap, createCycleGuard(), void 0, "tag");
96919
+ const walked = () => {
96920
+ const value = bindingValue(binding2);
96921
+ return { kind: "evaluated", evaluation: walkTag(value), value, credits: [] };
96827
96922
  };
96828
- const namesHolderMember = (file, exportName) => namesObjectMember(holderDecl(file, exportName)?.value, residual);
96829
- const outerVia = {
96830
- kind: "direct-import",
96831
- specifier: matchedImport.specifier,
96832
- import: matchedImport.imported
96833
- };
96834
- if (!packageName) {
96835
- const resolvedAbsTarget2 = graph.moduleResolver(filePath, matchedImport.specifier);
96836
- if (!resolvedAbsTarget2)
96837
- return { kind: "import-failed", specifier: matchedImport.specifier };
96838
- const resolvedTarget = graph.resolveToGraphKey ? graph.resolveToGraphKey(resolvedAbsTarget2) ?? resolvedAbsTarget2 : resolvedAbsTarget2;
96839
- const refType = resolveReference(graph, fileGraph, usage.ref);
96840
- const evaluation = walkWithFolding(graph, fileGraph, refType, argMap, createCycleGuard(), void 0, "tag");
96841
- const jsxTerminals = creditedTerminals(evaluation);
96842
- if (jsxTerminals.length === 0)
96843
- return { kind: "evaluated", evaluation, value: refType, credits: [] };
96844
- const chained = followReExportChain(graph, resolvedTarget, effectiveImported);
96845
- const canonicalFile = chained?.file ?? resolvedTarget;
96846
- let exportName = chained?.localExport ?? effectiveImported;
96847
- if (!chained) {
96848
- const targetGraph = graph.files.get(resolvedTarget);
96849
- if (targetGraph && effectiveImported === "default") {
96850
- const defaultExp = targetGraph.exports.find((e) => e.kind === "default");
96851
- if (defaultExp && "local" in defaultExp) {
96852
- exportName = defaultExp.local;
96853
- }
96854
- } else if (targetGraph) {
96855
- const namedExp = targetGraph.exports.find((e) => e.kind === "named" && "exportedAs" in e && e.exportedAs === effectiveImported && "local" in e);
96856
- if (namedExp && "local" in namedExp) {
96857
- exportName = namedExp.local;
96858
- }
96859
- }
96860
- }
96861
- const fallback2 = {
96862
- kind: componentKindFor(fileGraph.dialect),
96863
- export: compoundExportName(exportName, residual),
96864
- source: { type: "local", filePath: canonicalFile }
96865
- };
96866
- const definition = holderDefinition(canonicalFile, exportName);
96867
- const named = namesHolderMember(canonicalFile, exportName);
96868
- const credits = jsxTerminals.filter((t3) => t3.identity !== null || named).map((terminal) => ({
96869
- terminal,
96870
- fallback: fallback2,
96871
- outerVia,
96872
- ...terminal.identity === null && definition !== void 0 ? { definition } : {}
96873
- }));
96874
- return { kind: "evaluated", evaluation, value: refType, credits };
96923
+ switch (binding2.kind) {
96924
+ // Transitional: these two arms read `walkIdentity`, which only a name or
96925
+ // import that fails inside a parsed file carries, to tell that failure
96926
+ // from the usage's own. They change when those failures stop naming the
96927
+ // parsed file in walks.
96928
+ case "unbound":
96929
+ return binding2.walkIdentity === void 0 ? { kind: "unbound" } : walked();
96930
+ case "import-failed":
96931
+ return binding2.walkIdentity === void 0 ? { kind: "import-failed", specifier: binding2.specifier } : walked();
96932
+ case "no-export":
96933
+ return walked();
96934
+ case "declaration": {
96935
+ const value = bindingValue(binding2);
96936
+ const evaluation = walkTag(value);
96937
+ const declared = makeLocalComponentId(binding2.file, compoundExportName(binding2.decl.symbol, binding2.path), fileGraph.dialect);
96938
+ const fallback = buildComponentId(bindingIdentity(binding2), declared, fileGraph.dialect);
96939
+ const holder = binding2.walkIdentity === void 0 ? binding2.decl : void 0;
96940
+ const definition = holder !== void 0 && (binding2.inScope || binding2.path.length > 0) ? { line: holder.loc.line, column: holder.loc.column } : void 0;
96941
+ const rendered = holder !== void 0 && binding2.path.length === 0 ? { declaration: holder } : {};
96942
+ const namesMember = namesObjectMember(holder?.value, binding2.path);
96943
+ const outerVia = binding2.inScope || imp === void 0 ? { kind: "local-component" } : { kind: "direct-import", specifier: imp.specifier, import: imp.imported };
96944
+ const credits = creditedTerminals(evaluation).filter((terminal) => terminal.identity !== null || namesMember).map((terminal) => ({
96945
+ terminal,
96946
+ fallback,
96947
+ outerVia,
96948
+ ...terminal.identity === null ? { ...definition !== void 0 ? { definition } : {}, ...rendered } : {}
96949
+ }));
96950
+ return { kind: "evaluated", evaluation, value, credits };
96951
+ }
96952
+ case "package-export":
96953
+ case "unparsed": {
96954
+ if (binding2.mainGap !== void 0 || imp === void 0 || binding2.kind === "unparsed" && packageNameFromSpecifier(imp.specifier) === null) {
96955
+ return walked();
96956
+ }
96957
+ const pinned = binding2.kind === "unparsed" ? pinUnparsed(graph, binding2) : binding2;
96958
+ const sentinel = { denotation: { kind: "foreign" }, viaTrail: [], identity: null };
96959
+ const fallback = {
96960
+ kind: componentKindFor(fileGraph.dialect),
96961
+ export: compoundExportName(pinned.exportName, pinned.path),
96962
+ source: pinned.kind === "unparsed" ? { type: "local", filePath: pinned.file } : externalSource(packageNameFromSpecifier(pinned.specifier) ?? pinned.specifier, pinned.specifier)
96963
+ };
96964
+ return {
96965
+ kind: "evaluated",
96966
+ evaluation: [sentinel],
96967
+ value: null,
96968
+ credits: [
96969
+ {
96970
+ terminal: sentinel,
96971
+ fallback,
96972
+ fallbackSpecifier: pinned.kind === "package-export" ? pinned.specifier : imp.specifier,
96973
+ outerVia: { kind: "direct-import", specifier: imp.specifier, import: imp.imported }
96974
+ }
96975
+ ]
96976
+ };
96977
+ }
96978
+ default:
96979
+ return assertNever(binding2);
96875
96980
  }
96876
- const externalFallback = {
96877
- kind: componentKindFor(fileGraph.dialect),
96878
- export: compoundExportName(effectiveImported, residual),
96879
- source: externalSource(packageName, matchedImport.specifier)
96880
- };
96881
- const resolvedAbsTarget = graph.moduleResolver(filePath, matchedImport.specifier);
96882
- const resolvedNormTarget = resolvedAbsTarget !== null && graph.resolveToGraphKey ? graph.resolveToGraphKey(resolvedAbsTarget) ?? resolvedAbsTarget : resolvedAbsTarget;
96883
- const targetInGraph = resolvedNormTarget !== null && graph.files.has(resolvedNormTarget);
96884
- if (targetInGraph) {
96885
- const refType = resolveReference(graph, fileGraph, usage.ref);
96886
- const evaluation = walkWithFolding(graph, fileGraph, refType, argMap, createCycleGuard(), void 0, "tag");
96887
- const jsxTerminals = creditedTerminals(evaluation);
96888
- if (jsxTerminals.length === 0)
96889
- return { kind: "evaluated", evaluation, value: refType, credits: [] };
96890
- const siblingFallback = workspaceSiblingFallback(graph, resolvedNormTarget, matchedImport, effectiveImported, fileGraph.dialect);
96891
- const localFallback = siblingFallback !== void 0 && siblingFallback.kind !== "custom-element" ? { ...siblingFallback, export: compoundExportName(siblingFallback.export, residual) } : siblingFallback;
96892
- const localHolder = siblingFallback !== void 0 && siblingFallback.kind !== "custom-element" && siblingFallback.source.type === "local" ? { filePath: siblingFallback.source.filePath, exportName: siblingFallback.export } : void 0;
96893
- const definition = localHolder === void 0 ? void 0 : holderDefinition(localHolder.filePath, localHolder.exportName);
96894
- const named = localHolder === void 0 || namesHolderMember(localHolder.filePath, localHolder.exportName);
96895
- const fallback2 = localFallback ?? externalFallback;
96896
- const credits = jsxTerminals.filter((t3) => t3.identity !== null || named).map((terminal) => ({
96897
- terminal,
96898
- fallback: fallback2,
96899
- fallbackSpecifier: matchedImport.specifier,
96900
- outerVia,
96901
- ...terminal.identity === null && definition !== void 0 ? { definition } : {}
96902
- }));
96903
- return { kind: "evaluated", evaluation, value: refType, credits };
96904
- }
96905
- const member = resolvedAbsTarget !== null ? unparsedMemberDefinition(graph, resolvedAbsTarget, effectiveImported) : null;
96906
- const sentinel = { denotation: { kind: "foreign" }, viaTrail: [], identity: null };
96907
- const fallback = member !== null ? {
96908
- kind: componentKindFor(fileGraph.dialect),
96909
- export: compoundExportName(member.exportName, residual),
96910
- source: { type: "local", filePath: member.absFile }
96911
- } : externalFallback;
96912
- return {
96913
- kind: "evaluated",
96914
- evaluation: [sentinel],
96915
- value: null,
96916
- credits: [{ terminal: sentinel, fallback, fallbackSpecifier: matchedImport.specifier, outerVia }]
96917
- };
96918
96981
  }
96919
96982
  function carriedDeclaration(credit) {
96920
96983
  const { identity } = credit.terminal;
@@ -96936,7 +96999,8 @@ function taggedDeclarations(graph, tagEvaluations) {
96936
96999
  const id2 = buildComponentId(identity, credit.fallback, dialect);
96937
97000
  if (id2.kind === "react-component" && id2.source.type === "local") {
96938
97001
  const declaration2 = carriedDeclaration(credit);
96939
- tagged.push({ filePath: id2.source.filePath, exportName: id2.export, ...declaration2 !== void 0 ? { declaration: declaration2 } : {} });
97002
+ if (declaration2 !== void 0)
97003
+ tagged.push(declaration2);
96940
97004
  }
96941
97005
  }
96942
97006
  }
@@ -97054,14 +97118,14 @@ function registryTagged(registry, graph, id2, declaration2) {
97054
97118
  return true;
97055
97119
  if (parseCompoundExport2(id2.export).isCompound)
97056
97120
  return true;
97057
- return registry.isTagged(id2.source.filePath, id2.export, declaration2);
97121
+ return registry.isTagged(declaration2);
97058
97122
  }
97059
97123
  function pushCallArgumentOccurrences(occurrences, filePath, call, owners, graph, fileGraph, argMap, registry, opts, depth = 0) {
97060
97124
  let resolvedOwners;
97061
97125
  const seedIdentifier = (site, index, arg, hops) => {
97062
97126
  if (isHostElementName(arg.ref.symbol))
97063
97127
  return;
97064
- const outerVia = { kind: "passed-as-argument", index, ...argumentProvenance(site, arg, fileGraph) };
97128
+ const outerVia = { kind: "passed-as-argument", index, ...argumentProvenance(graph, site, arg, fileGraph) };
97065
97129
  const argDecl = findLocalDeclaration(fileGraph, arg.ref);
97066
97130
  const unusedFallback = makeLocalComponentId(filePath, arg.ref.symbol, fileGraph.dialect);
97067
97131
  for (const ft of creditedTerminals(walkWithFolding(graph, fileGraph, arg, argMap))) {
@@ -97071,7 +97135,7 @@ function pushCallArgumentOccurrences(occurrences, filePath, call, owners, graph,
97071
97135
  filePath,
97072
97136
  resolveExternalLeaf: opts?.resolveExternalLeaf
97073
97137
  });
97074
- if (!registryHolds(registry, graph, rawComponentId))
97138
+ if (!registryHolds(registry, graph, rawComponentId, ft.identity.kind === "local" ? ft.identity.declaration : void 0))
97075
97139
  continue;
97076
97140
  resolvedOwners ??= owners();
97077
97141
  emitOccurrence(occurrences, { filePath, line: arg.ref.loc.line, column: arg.ref.loc.column, props: {}, events: [] }, rawComponentId, resolvedOwners, [outerVia, ...hops, ...ft.viaTrail], argDecl !== null ? { line: argDecl.loc.line, column: argDecl.loc.column } : void 0);
@@ -102177,7 +102241,7 @@ init_upload();
102177
102241
  import { errorMessage as errorMessage2 } from "@component-compass/ast-utils";
102178
102242
 
102179
102243
  // src/seeds.ts
102180
- import { relative as relative4, isAbsolute as isAbsolute8 } from "node:path";
102244
+ import { relative as relative4, isAbsolute as isAbsolute9 } from "node:path";
102181
102245
  import { posixPath as posixPath6 } from "@component-compass/plugin-core";
102182
102246
 
102183
102247
  // src/composition-rollup.ts
@@ -102540,7 +102604,7 @@ function buildComponentSeeds(parseResults, localIndex, repoRoot, workspaceGraph,
102540
102604
  const seedsById = /* @__PURE__ */ new Map();
102541
102605
  for (const result2 of parseResults) {
102542
102606
  for (const occ of result2.occurrences) {
102543
- const componentId = repoRoot && occ.componentId.source.type === "local" && isAbsolute8(occ.componentId.source.filePath) ? {
102607
+ const componentId = repoRoot && occ.componentId.source.type === "local" && isAbsolute9(occ.componentId.source.filePath) ? {
102544
102608
  ...occ.componentId,
102545
102609
  source: {
102546
102610
  type: "local",
@@ -102685,7 +102749,7 @@ function indexedToComponentId(c2) {
102685
102749
  }
102686
102750
 
102687
102751
  // src/occurrences.ts
102688
- import { relative as relative5, isAbsolute as isAbsolute9 } from "node:path";
102752
+ import { relative as relative5, isAbsolute as isAbsolute10 } from "node:path";
102689
102753
  import { posixPath as posixPath7 } from "@component-compass/plugin-core";
102690
102754
  import {
102691
102755
  computeOccurrenceId as computeOccurrenceId2,
@@ -102694,14 +102758,14 @@ import {
102694
102758
  function normaliseLocalFilePath(c2, repoRoot) {
102695
102759
  if (c2.source.type !== "local") return c2;
102696
102760
  const fp = c2.source.filePath;
102697
- if (!isAbsolute9(fp)) return c2;
102761
+ if (!isAbsolute10(fp)) return c2;
102698
102762
  return {
102699
102763
  ...c2,
102700
102764
  source: { type: "local", filePath: posixPath7(relative5(repoRoot, fp)) }
102701
102765
  };
102702
102766
  }
102703
102767
  function toRelativePath2(absPath, repoRoot) {
102704
- if (!repoRoot || !isAbsolute9(absPath)) return absPath;
102768
+ if (!repoRoot || !isAbsolute10(absPath)) return absPath;
102705
102769
  return posixPath7(relative5(repoRoot, absPath));
102706
102770
  }
102707
102771
  function parseResultsToOccurrences(results, repoRoot = "") {
@@ -102901,19 +102965,19 @@ function createBoundedDefinitionResolver(opts) {
102901
102965
 
102902
102966
  // src/scan/global-components.ts
102903
102967
  import { existsSync as existsSync7, readFileSync as readFileSync11 } from "node:fs";
102904
- import { dirname as dirname11, isAbsolute as isAbsolute10, join as join14, resolve as resolve10 } from "node:path";
102968
+ import { dirname as dirname11, isAbsolute as isAbsolute11, join as join14, resolve as resolve10 } from "node:path";
102905
102969
  var CANDIDATE_PATHS = [join14(".nuxt", "components.d.ts"), join14(".nuxt", "types", "components.d.ts")];
102906
102970
  var AUGMENTED_MODULE = /declare\s+module\s+["'](?:vue|@vue\/runtime-core)["']\s*\{/g;
102907
102971
  var INTERFACE_DECL = /(?:^|[\s;}])(?:export\s+)?(?:declare\s+)?interface\s+([A-Za-z_$][\w$]*)\s*(?:extends\s+([^{]*?))?\s*\{/g;
102908
102972
  var MEMBER = /^\s*(?:["']([^"']+)["']|([A-Za-z_$][\w$]*))\??\s*:\s*.*typeof import\(["']([^"']+)["']\)\[["']([^"']+)["']\]/;
102909
- function matchingBlock(source, open) {
102973
+ function matchingBlock(source, open2) {
102910
102974
  let depth = 0;
102911
- for (let i2 = open; i2 < source.length; i2++) {
102975
+ for (let i2 = open2; i2 < source.length; i2++) {
102912
102976
  const ch = source[i2];
102913
102977
  if (ch === "{") depth++;
102914
102978
  else if (ch === "}") {
102915
102979
  depth--;
102916
- if (depth === 0) return { body: source.slice(open + 1, i2), end: i2 };
102980
+ if (depth === 0) return { body: source.slice(open2 + 1, i2), end: i2 };
102917
102981
  }
102918
102982
  }
102919
102983
  return null;
@@ -102922,8 +102986,8 @@ function collectInterfaces(source) {
102922
102986
  const out2 = [];
102923
102987
  INTERFACE_DECL.lastIndex = 0;
102924
102988
  for (let m = INTERFACE_DECL.exec(source); m !== null; m = INTERFACE_DECL.exec(source)) {
102925
- const open = m.index + m[0].length - 1;
102926
- const block2 = matchingBlock(source, open);
102989
+ const open2 = m.index + m[0].length - 1;
102990
+ const block2 = matchingBlock(source, open2);
102927
102991
  if (block2 === null) continue;
102928
102992
  out2.push({
102929
102993
  name: m[1],
@@ -102931,7 +102995,7 @@ function collectInterfaces(source) {
102931
102995
  body: block2.body,
102932
102996
  start: m.index
102933
102997
  });
102934
- INTERFACE_DECL.lastIndex = open + 1;
102998
+ INTERFACE_DECL.lastIndex = open2 + 1;
102935
102999
  }
102936
103000
  return out2;
102937
103001
  }
@@ -102939,8 +103003,8 @@ function augmentedRanges(source) {
102939
103003
  const out2 = [];
102940
103004
  AUGMENTED_MODULE.lastIndex = 0;
102941
103005
  for (let m = AUGMENTED_MODULE.exec(source); m !== null; m = AUGMENTED_MODULE.exec(source)) {
102942
- const open = m.index + m[0].length - 1;
102943
- const block2 = matchingBlock(source, open);
103006
+ const open2 = m.index + m[0].length - 1;
103007
+ const block2 = matchingBlock(source, open2);
102944
103008
  if (block2 === null) continue;
102945
103009
  out2.push([m.index, block2.end]);
102946
103010
  AUGMENTED_MODULE.lastIndex = block2.end;
@@ -102995,7 +103059,7 @@ function loadGlobalComponents(scanRoot) {
102995
103059
  return null;
102996
103060
  }
102997
103061
  function isBareSpecifier(importPath) {
102998
- if (isAbsolute10(importPath)) return false;
103062
+ if (isAbsolute11(importPath)) return false;
102999
103063
  return !/^[.#~\\/]/.test(importPath) && !importPath.startsWith("@/");
103000
103064
  }
103001
103065
  function parseMembers(baseDir, members) {
@@ -103011,7 +103075,7 @@ function parseMembers(baseDir, members) {
103011
103075
  if (isBareSpecifier(importPath)) {
103012
103076
  specifier = importPath;
103013
103077
  } else {
103014
- const abs = isAbsolute10(importPath) ? importPath : resolve10(baseDir, importPath);
103078
+ const abs = isAbsolute11(importPath) ? importPath : resolve10(baseDir, importPath);
103015
103079
  const posixAbs = abs.replaceAll("\\", "/");
103016
103080
  const nmIdx = posixAbs.lastIndexOf("node_modules/");
103017
103081
  if (nmIdx >= 0) {
@@ -103077,7 +103141,7 @@ async function runScan(opts) {
103077
103141
  if (repoIdOverride !== void 0) metaOpts.repoIdOverride = repoIdOverride;
103078
103142
  const meta = await stampMeta(metaOpts);
103079
103143
  const gitToplevel = await readGitToplevel(cfg.configDir);
103080
- const outputRoot = opts.repoRoot ? isAbsolute11(opts.repoRoot) ? opts.repoRoot : resolve11(opts.cwd ?? process.cwd(), opts.repoRoot) : gitToplevel && !relative6(gitToplevel, cfg.configDir).startsWith("..") ? gitToplevel : cfg.configDir;
103144
+ const outputRoot = opts.repoRoot ? isAbsolute12(opts.repoRoot) ? opts.repoRoot : resolve11(opts.cwd ?? process.cwd(), opts.repoRoot) : gitToplevel && !relative6(gitToplevel, cfg.configDir).startsWith("..") ? gitToplevel : cfg.configDir;
103081
103145
  const rebase = (scanRel) => outputRoot === cfg.configDir ? scanRel : posixPath8(relative6(outputRoot, resolve11(cfg.configDir, scanRel)));
103082
103146
  if (opts.outputOverride) cfg.output = opts.outputOverride;
103083
103147
  const writer = opts.quiet ? () => {
@@ -103344,7 +103408,7 @@ async function runScan(opts) {
103344
103408
  // `snapshotManifestRefs()` — otherwise an undeclared package's full CEM
103345
103409
  // catalog gets broadcast as zero-occurrence components.
103346
103410
  resolveExternalLeaf: (fromFile, specifier, exportName) => {
103347
- const absFrom = isAbsolute11(fromFile) ? fromFile : resolve11(cfg.configDir, fromFile);
103411
+ const absFrom = isAbsolute12(fromFile) ? fromFile : resolve11(cfg.configDir, fromFile);
103348
103412
  const hit = warmedResolver.lookupExternalLeaf(absFrom, specifier, exportName);
103349
103413
  if (!hit) return null;
103350
103414
  return { leafPackage: hit.leafPackage, modulePath: hit.modulePath, exportName: hit.exportName };
@@ -103364,7 +103428,7 @@ async function runScan(opts) {
103364
103428
  }
103365
103429
  const diagnostics = rawDiagnostics.map((d2) => ({
103366
103430
  ...d2,
103367
- filePath: isAbsolute11(d2.filePath) ? posixPath8(relative6(outputRoot, d2.filePath)) : d2.filePath
103431
+ filePath: isAbsolute12(d2.filePath) ? posixPath8(relative6(outputRoot, d2.filePath)) : d2.filePath
103368
103432
  }));
103369
103433
  const snapshot = warmedResolver.snapshotComponents().map((c2) => ({ component: c2 }));
103370
103434
  const manifests = warmedResolver.snapshotManifestRefs();
@@ -103468,7 +103532,7 @@ async function runScan(opts) {
103468
103532
  };
103469
103533
  await stampGitMTime(outputRoot, scanOutput.components);
103470
103534
  await stampVersion(outputRoot, scanOutput.components, scanOutput.occurrences);
103471
- const outputPath = isAbsolute11(cfg.output) ? cfg.output : resolve11(cfg.configDir, cfg.output);
103535
+ const outputPath = isAbsolute12(cfg.output) ? cfg.output : resolve11(cfg.configDir, cfg.output);
103472
103536
  await writeJson(scanOutput, outputPath);
103473
103537
  if (!opts.quiet) {
103474
103538
  printSummary(scanOutput, outputPath);
@@ -103516,14 +103580,14 @@ function countFilesWithUsage(occurrences) {
103516
103580
  function normaliseEngineLocalId(c2, configDir2, rebase) {
103517
103581
  if (c2.source.type !== "local") return c2;
103518
103582
  const fp = c2.source.filePath;
103519
- const scanRel = isAbsolute11(fp) ? posixPath8(relative6(configDir2, fp)) : fp;
103583
+ const scanRel = isAbsolute12(fp) ? posixPath8(relative6(configDir2, fp)) : fp;
103520
103584
  return {
103521
103585
  ...c2,
103522
103586
  source: { type: "local", filePath: rebase(scanRel) }
103523
103587
  };
103524
103588
  }
103525
103589
  function normaliseVia(v, configDir2, rebase) {
103526
- if (!("specifier" in v) || v.specifier === void 0 || !isAbsolute11(v.specifier)) return v;
103590
+ if (!("specifier" in v) || v.specifier === void 0 || !isAbsolute12(v.specifier)) return v;
103527
103591
  const scanRel = posixPath8(relative6(configDir2, v.specifier));
103528
103592
  return { ...v, specifier: rebase(scanRel) };
103529
103593
  }
@@ -103531,7 +103595,7 @@ function normaliseVia(v, configDir2, rebase) {
103531
103595
  // src/commands/init.ts
103532
103596
  init_adapter();
103533
103597
  import { writeFile as writeFile3, stat as stat2, readFile as readFile6 } from "node:fs/promises";
103534
- import { basename as basename5, isAbsolute as isAbsolute12, resolve as resolve12 } from "node:path";
103598
+ import { basename as basename6, isAbsolute as isAbsolute13, resolve as resolve12 } from "node:path";
103535
103599
  var DEFAULT_INCLUDE = "src/**/*.{ts,tsx,jsx,js,vue,html}";
103536
103600
  var FRAMEWORK_EXTS = {
103537
103601
  react: ["ts", "tsx", "js", "jsx"],
@@ -103563,7 +103627,7 @@ function buildConfig(o2) {
103563
103627
  };
103564
103628
  }
103565
103629
  async function runInit(opts) {
103566
- const cwd2 = isAbsolute12(opts.cwd) ? opts.cwd : resolve12(opts.cwd);
103630
+ const cwd2 = isAbsolute13(opts.cwd) ? opts.cwd : resolve12(opts.cwd);
103567
103631
  const out2 = opts.outputPath ?? resolve12(cwd2, "component-compass.config.json");
103568
103632
  await assertNoExistingConfig(out2);
103569
103633
  const repoId = opts.repoId ?? await deriveRepoId(cwd2);
@@ -103634,7 +103698,7 @@ async function deriveRepoId(cwd2) {
103634
103698
  if (pkg.name) return pkg.name;
103635
103699
  } catch {
103636
103700
  }
103637
- return basename5(cwd2) || "unknown";
103701
+ return basename6(cwd2) || "unknown";
103638
103702
  }
103639
103703
 
103640
103704
  // src/cli.ts
@@ -103687,8 +103751,8 @@ Options:
103687
103751
  `;
103688
103752
  var AUTH = `component-compass auth <login|logout|status> [--host <url>]
103689
103753
 
103690
- login Device-flow browser login; stores tokens in ~/.config/component-compass/hosts.json
103691
- logout Remove stored tokens for a host
103754
+ login Device-flow browser login; stores a session in ~/.config/component-compass/hosts.json
103755
+ logout Revoke a session for a host
103692
103756
  status Show the signed-in identity
103693
103757
  `;
103694
103758
  var REGISTRY = { scan: SCAN, init: INIT, auth: AUTH };