auth 1.6.1 → 1.6.3

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/index.mjs +126 -47
  2. package/package.json +5 -5
package/dist/index.mjs CHANGED
@@ -25,7 +25,7 @@ import babelPresetReact from "@babel/preset-react";
25
25
  import babelPresetTypeScript from "@babel/preset-typescript";
26
26
  import { BetterAuthError } from "@better-auth/core/error";
27
27
  import { loadConfig } from "c12";
28
- import { getTsconfig, parseTsconfig } from "get-tsconfig";
28
+ import { createPathsMatcher, getTsconfig, parseTsconfig } from "get-tsconfig";
29
29
  import open from "open";
30
30
  import { env } from "@better-auth/core/env";
31
31
  import { log } from "@clack/prompts";
@@ -1485,24 +1485,7 @@ possiblePaths$1 = [
1485
1485
  ...possiblePaths$1.map((it) => `src/${it}`),
1486
1486
  ...possiblePaths$1.map((it) => `app/${it}`)
1487
1487
  ];
1488
- function mergeAliases(target, source) {
1489
- for (const [alias, aliasPath] of Object.entries(source)) if (!(alias in target)) target[alias] = aliasPath;
1490
- }
1491
- function extractAliases(tsconfig) {
1492
- const { paths = {}, baseUrl } = tsconfig.config.compilerOptions ?? {};
1493
- const result = {};
1494
- const configDir = path.dirname(tsconfig.path);
1495
- const resolvedBaseUrl = baseUrl ? path.resolve(configDir, baseUrl) : configDir;
1496
- for (const [alias, aliasPaths = []] of Object.entries(paths)) for (const aliasedPath of aliasPaths) {
1497
- const finalAlias = alias.slice(-1) === "*" ? alias.slice(0, -1) : alias;
1498
- const finalAliasedPath = aliasedPath.slice(-1) === "*" ? aliasedPath.slice(0, -1) : aliasedPath;
1499
- result[finalAlias || ""] = path.join(resolvedBaseUrl, finalAliasedPath);
1500
- }
1501
- return result;
1502
- }
1503
- /**
1504
- * Reads raw tsconfig JSON to get `references` (which get-tsconfig strips out).
1505
- */
1488
+ /** Reads `references` from raw tsconfig JSON (stripped out by `parseTsconfig`). */
1506
1489
  function readRawTsconfigReferences(tsconfigPath) {
1507
1490
  try {
1508
1491
  const stripped = fs.readFileSync(tsconfigPath, "utf-8").replace(/\\"|"(?:\\"|[^"])*"|(\/\/.*|\/\*[\s\S]*?\*\/)/g, (m, g) => g ? "" : m).replace(/,(?=\s*[}\]])/g, "");
@@ -1511,11 +1494,9 @@ function readRawTsconfigReferences(tsconfigPath) {
1511
1494
  return;
1512
1495
  }
1513
1496
  }
1514
- /**
1515
- * Collect path aliases from tsconfig references recursively.
1516
- */
1517
- function collectReferencesAliases(tsconfigPath, visited = /* @__PURE__ */ new Set()) {
1518
- const result = {};
1497
+ /** Recursively collects tsconfigs reachable via `references`. */
1498
+ function collectReferencedTsconfigs(tsconfigPath, visited = /* @__PURE__ */ new Set()) {
1499
+ const result = [];
1519
1500
  const refs = readRawTsconfigReferences(tsconfigPath);
1520
1501
  if (!refs) return result;
1521
1502
  const configDir = path.dirname(tsconfigPath);
@@ -1525,48 +1506,146 @@ function collectReferencesAliases(tsconfigPath, visited = /* @__PURE__ */ new Se
1525
1506
  if (visited.has(refTsconfigPath)) continue;
1526
1507
  visited.add(refTsconfigPath);
1527
1508
  try {
1528
- mergeAliases(result, extractAliases({
1509
+ const refConfig = parseTsconfig(refTsconfigPath);
1510
+ result.push({
1529
1511
  path: refTsconfigPath,
1530
- config: parseTsconfig(refTsconfigPath)
1531
- }));
1512
+ config: refConfig
1513
+ });
1532
1514
  } catch {
1533
1515
  continue;
1534
1516
  }
1535
- mergeAliases(result, collectReferencesAliases(refTsconfigPath, visited));
1517
+ result.push(...collectReferencedTsconfigs(refTsconfigPath, visited));
1536
1518
  }
1537
1519
  return result;
1538
1520
  }
1539
- function getPathAliases(cwd) {
1521
+ /**
1522
+ * Ordered `paths` matchers from the project tsconfig and any referenced
1523
+ * tsconfigs, following TypeScript canonical resolution semantics.
1524
+ * @see https://github.com/microsoft/TypeScript/blob/main/src/compiler/moduleNameResolver.ts
1525
+ */
1526
+ function collectPathsMatchers(cwd) {
1540
1527
  const tsconfig = getTsconfig(cwd, fs.existsSync(path.join(cwd, "tsconfig.json")) ? "tsconfig.json" : "jsconfig.json");
1541
- if (!tsconfig) return null;
1528
+ if (!tsconfig) return [];
1529
+ const matchers = [];
1542
1530
  try {
1543
- const result = extractAliases(tsconfig);
1544
- mergeAliases(result, collectReferencesAliases(tsconfig.path));
1545
- addSvelteKitEnvModules(result);
1546
- addCloudflareModules(result);
1547
- return result;
1531
+ const mainMatcher = createPathsMatcher(tsconfig);
1532
+ if (mainMatcher) matchers.push(mainMatcher);
1533
+ for (const refTsconfig of collectReferencedTsconfigs(tsconfig.path)) {
1534
+ const refMatcher = createPathsMatcher(refTsconfig);
1535
+ if (refMatcher) matchers.push(refMatcher);
1536
+ }
1548
1537
  } catch (error) {
1549
1538
  console.error(error);
1550
1539
  throw new BetterAuthError("Error parsing tsconfig.json");
1551
1540
  }
1541
+ return matchers;
1542
+ }
1543
+ /**
1544
+ * Source file extensions jiti can load. Shared between the jiti `extensions`
1545
+ * option and `resolveCandidateFile` so both stay in sync.
1546
+ */
1547
+ const SOURCE_EXTENSIONS = [
1548
+ ".ts",
1549
+ ".tsx",
1550
+ ".mts",
1551
+ ".cts",
1552
+ ".js",
1553
+ ".jsx",
1554
+ ".mjs",
1555
+ ".cjs"
1556
+ ];
1557
+ const SOURCE_EXTENSIONS_SET = new Set(SOURCE_EXTENSIONS);
1558
+ /** Probes a candidate as-is, with known extensions, and as a directory index. */
1559
+ function resolveCandidateFile(candidate) {
1560
+ try {
1561
+ if (fs.existsSync(candidate) && fs.statSync(candidate).isFile()) return candidate;
1562
+ } catch {}
1563
+ if (SOURCE_EXTENSIONS_SET.has(path.extname(candidate))) return;
1564
+ for (const ext of SOURCE_EXTENSIONS) {
1565
+ const withExt = candidate + ext;
1566
+ if (fs.existsSync(withExt)) return withExt;
1567
+ }
1568
+ for (const ext of SOURCE_EXTENSIONS) {
1569
+ const asIndex = path.join(candidate, `index${ext}`);
1570
+ if (fs.existsSync(asIndex)) return asIndex;
1571
+ }
1572
+ }
1573
+ function resolveWithMatchers(specifier, matchers) {
1574
+ for (const matcher of matchers) for (const candidate of matcher(specifier)) {
1575
+ const resolved = resolveCandidateFile(candidate);
1576
+ if (resolved) return resolved;
1577
+ }
1578
+ }
1579
+ /**
1580
+ * Callees whose first string argument is a module specifier. `jitiImport` is
1581
+ * a jiti-side preprocessor artifact observed in the AST; revisit on jiti
1582
+ * major version bumps (the regression suite catches a rename but not the why).
1583
+ */
1584
+ const LOADER_IDENTIFIERS = new Set([
1585
+ "require",
1586
+ "import",
1587
+ "jitiImport"
1588
+ ]);
1589
+ /**
1590
+ * Rewrites aliased specifiers at AST level. Required because jiti's `alias`
1591
+ * option only supports prefix matching and cannot express mid-path wildcards.
1592
+ *
1593
+ * Matchers always take precedence over native resolution, mirroring
1594
+ * TypeScript's own `paths` → `node_modules` order.
1595
+ */
1596
+ function createRewriteImportPathsPlugin(matchers) {
1597
+ return ({ types: t }) => {
1598
+ const rewrite = (source) => {
1599
+ if (!source) return;
1600
+ const resolved = resolveWithMatchers(source.value, matchers);
1601
+ if (resolved) source.value = resolved;
1602
+ };
1603
+ return { visitor: {
1604
+ ImportDeclaration(p) {
1605
+ rewrite(p.node.source);
1606
+ },
1607
+ ExportNamedDeclaration(p) {
1608
+ rewrite(p.node.source);
1609
+ },
1610
+ ExportAllDeclaration(p) {
1611
+ rewrite(p.node.source);
1612
+ },
1613
+ ImportExpression(p) {
1614
+ if (t.isStringLiteral(p.node.source)) rewrite(p.node.source);
1615
+ },
1616
+ CallExpression(p) {
1617
+ const { callee, arguments: args } = p.node;
1618
+ const first = args[0];
1619
+ if (!t.isStringLiteral(first)) return;
1620
+ if (!(t.isIdentifier(callee) && LOADER_IDENTIFIERS.has(callee.name) || t.isImport(callee))) return;
1621
+ rewrite(first);
1622
+ }
1623
+ } };
1624
+ };
1625
+ }
1626
+ /** Virtual module aliases; real tsconfig paths go through the babel plugin. */
1627
+ function getVirtualModuleAliases() {
1628
+ const result = {};
1629
+ addSvelteKitEnvModules(result);
1630
+ addCloudflareModules(result);
1631
+ return result;
1552
1632
  }
1553
1633
  /**
1554
1634
  * .tsx files are not supported by Jiti.
1555
1635
  */
1556
1636
  const jitiOptions = (cwd) => {
1557
- const alias = getPathAliases(cwd) || {};
1637
+ const matchers = collectPathsMatchers(cwd);
1638
+ const plugins = matchers.length > 0 ? [createRewriteImportPathsPlugin(matchers)] : [];
1558
1639
  return {
1559
- transformOptions: { babel: { presets: [[babelPresetTypeScript, {
1560
- isTSX: true,
1561
- allExtensions: true
1562
- }], [babelPresetReact, { runtime: "automatic" }]] } },
1563
- extensions: [
1564
- ".ts",
1565
- ".tsx",
1566
- ".js",
1567
- ".jsx"
1568
- ],
1569
- alias
1640
+ transformOptions: { babel: {
1641
+ presets: [[babelPresetTypeScript, {
1642
+ isTSX: true,
1643
+ allExtensions: true
1644
+ }], [babelPresetReact, { runtime: "automatic" }]],
1645
+ plugins
1646
+ } },
1647
+ extensions: [...SOURCE_EXTENSIONS],
1648
+ alias: getVirtualModuleAliases()
1570
1649
  };
1571
1650
  };
1572
1651
  const isDefaultExport = (object) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "auth",
3
- "version": "1.6.1",
3
+ "version": "1.6.3",
4
4
  "description": "The CLI for Better Auth",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -60,9 +60,9 @@
60
60
  "semver": "^7.7.4",
61
61
  "yocto-spinner": "^0.2.3",
62
62
  "zod": "^4.3.6",
63
- "@better-auth/core": "1.6.1",
64
- "@better-auth/telemetry": "1.6.1",
65
- "better-auth": "1.6.1"
63
+ "@better-auth/core": "1.6.3",
64
+ "@better-auth/telemetry": "1.6.3",
65
+ "better-auth": "1.6.3"
66
66
  },
67
67
  "devDependencies": {
68
68
  "@types/better-sqlite3": "^7.6.13",
@@ -75,7 +75,7 @@
75
75
  "tsx": "^4.21.0",
76
76
  "type-fest": "^5.4.4",
77
77
  "typescript": "^5.9.3",
78
- "@better-auth/passkey": "1.6.1"
78
+ "@better-auth/passkey": "1.6.3"
79
79
  },
80
80
  "scripts": {
81
81
  "build": "tsdown",