diff --git a/.changeset/schema-data-root-consolidation.md b/.changeset/schema-data-root-consolidation.md new file mode 100644 index 000000000..5987d2c8f --- /dev/null +++ b/.changeset/schema-data-root-consolidation.md @@ -0,0 +1,5 @@ +--- +"@adcp/sdk": patch +--- + +Internal: consolidated the duplicated `__dirname`-relative schema/data-root resolution across 7 loaders (`validation/schema-loader.ts`, `conformance/schemaLoader.ts`, `server/error-arm-tools.ts`, `v2/projection/{catalog,registry,canonical-properties}.ts`, `testing/storyboard/compliance.ts`) into shared `getPackageRoot()`/`getSchemaDataRoots()` helpers (`src/lib/internal/`). Resolution now anchors via `require.resolve('@adcp/sdk/package.json')` self-reference instead of hand-tuned `path.join(__dirname, '..', ...)` arithmetic tied to each file's own directory depth. No public API changes. diff --git a/.changeset/tsup-conditional-node-shim-banner.md b/.changeset/tsup-conditional-node-shim-banner.md new file mode 100644 index 000000000..7adde22d9 --- /dev/null +++ b/.changeset/tsup-conditional-node-shim-banner.md @@ -0,0 +1,5 @@ +--- +"@adcp/sdk": patch +--- + +Fix: the ESM build no longer injects the `node:url`/`node:path`/`node:module` shim banner into every `.mjs` file. Only the (11) files that actually reference `__dirname`, `__filename`, or `require` in their body get it now; pure-data and pure-logic modules — including `enums.generated.mjs`, `inline-enums.generated.mjs`, and everything reachable from the zod-free `./enums` entry point — no longer carry dead Node-only imports that broke strict browser bundlers (Vite, `esbuild --platform=browser`). diff --git a/src/lib/conformance/schemaLoader.ts b/src/lib/conformance/schemaLoader.ts index 04448b173..74e88af66 100644 --- a/src/lib/conformance/schemaLoader.ts +++ b/src/lib/conformance/schemaLoader.ts @@ -3,6 +3,7 @@ import * as path from 'path'; import type { ConformanceToolName } from './types'; import { ADCP_VERSION } from '../version'; import { resolveBundleKey } from '../validation/schema-loader'; +import { getSchemaDataRoots } from '../internal/schema-data-roots'; type JsonSchema = Record; @@ -70,10 +71,11 @@ function findBundledDir(options: ConformanceSchemaOptions = {}): string { const version = options.version ?? ADCP_VERSION; const bundleKey = resolveBundleKey(version); - const distCandidate = path.resolve(__dirname, '..', 'schemas-data', bundleKey, 'bundled'); + const { builtSchemasDataRoot, sourceSchemasCacheRoot } = getSchemaDataRoots(); + const distCandidate = path.join(builtSchemasDataRoot, bundleKey, 'bundled'); if (fs.existsSync(distCandidate)) return distCandidate; - const srcCandidate = path.resolve(__dirname, '..', '..', '..', 'schemas', 'cache', version, 'bundled'); + const srcCandidate = path.join(sourceSchemasCacheRoot, version, 'bundled'); if (fs.existsSync(srcCandidate)) return srcCandidate; throw new Error( diff --git a/src/lib/internal/package-root.ts b/src/lib/internal/package-root.ts new file mode 100644 index 000000000..6a9b40ee1 --- /dev/null +++ b/src/lib/internal/package-root.ts @@ -0,0 +1,82 @@ +/** + * Resolve the @adcp/sdk package root — the directory containing this + * package's own `package.json` — independent of the calling module's own + * directory depth or bundling shape. + * + * Replaces the per-file `__dirname` arithmetic that used to be hand-tuned to + * each schema/data loader's own depth under `src/lib/` (one `..` for + * `validation/`, two for `v2/projection/`, four for `testing/storyboard/`), + * which silently breaks if any of those files ever moves. + */ + +import { existsSync, readFileSync } from 'fs'; +import path from 'path'; + +let cachedRoot: string | undefined; + +/** + * Primary: self-reference through this package's own `exports` map + * (`"./package.json": "./package.json"`). Node resolves `require(...)` calls + * (bare form, not `.resolve` chained) so tsup's conditional ESM shim still + * detects this file needs `require` injected under `.mjs` output. + */ +function resolveViaModuleResolution(): string | undefined { + try { + const pkg = require('@adcp/sdk/package.json') as { name?: string }; + if (pkg.name !== '@adcp/sdk') return undefined; + return path.dirname(require.resolve('@adcp/sdk/package.json')); + } catch { + return undefined; + } +} + +/** + * Fallback: walk up from a starting directory looking for an ancestor + * `package.json` whose `name` is `@adcp/sdk`. Covers environments where + * module self-resolution is unavailable (e.g. an aggressive downstream + * bundler that strips/rewrites `require.resolve`). + * + * Exported for direct testing; not part of the public API surface. + */ +export function _resolvePackageRootViaDirectoryWalk(start: string): string | undefined { + let dir = start; + for (;;) { + const candidate = path.join(dir, 'package.json'); + if (existsSync(candidate)) { + try { + const pkg = JSON.parse(readFileSync(candidate, 'utf-8')) as { name?: string }; + if (pkg.name === '@adcp/sdk') return dir; + } catch { + // Malformed/unrelated package.json — keep walking past it. + } + } + const parent = path.dirname(dir); + if (parent === dir) return undefined; + dir = parent; + } +} + +/** + * Resolve the package root, memoized after the first successful call. + * + * Throws if both resolution strategies fail — this indicates a broken + * install or an aggressive bundler that stripped `package.json`, not a + * recoverable runtime condition. + */ +export function getPackageRoot(): string { + if (cachedRoot) return cachedRoot; + const resolved = resolveViaModuleResolution() ?? _resolvePackageRootViaDirectoryWalk(__dirname); + if (!resolved) { + throw new Error( + '@adcp/sdk: could not resolve the package root (require.resolve self-reference and directory walk ' + + 'both failed). This indicates a broken install or an aggressive bundler that stripped package.json.' + ); + } + cachedRoot = resolved; + return cachedRoot; +} + +/** Test hook: clear the memoized package root. */ +export function _resetPackageRootCache(): void { + cachedRoot = undefined; +} diff --git a/src/lib/internal/schema-data-roots.ts b/src/lib/internal/schema-data-roots.ts new file mode 100644 index 000000000..de2cd8907 --- /dev/null +++ b/src/lib/internal/schema-data-roots.ts @@ -0,0 +1,17 @@ +import path from 'path'; +import { getPackageRoot } from './package-root'; + +export interface SchemaDataRoots { + /** dist/lib/schemas-data — populated by scripts/copy-schemas-to-dist.ts. Only exists post-build. */ + builtSchemasDataRoot: string; + /** schemas/cache — populated by scripts/sync-schemas.ts. Only exists in a source checkout. */ + sourceSchemasCacheRoot: string; +} + +export function getSchemaDataRoots(): SchemaDataRoots { + const root = getPackageRoot(); + return { + builtSchemasDataRoot: path.join(root, 'dist', 'lib', 'schemas-data'), + sourceSchemasCacheRoot: path.join(root, 'schemas', 'cache'), + }; +} diff --git a/src/lib/server/error-arm-tools.ts b/src/lib/server/error-arm-tools.ts index 90deb91a4..2ca79a6ea 100644 --- a/src/lib/server/error-arm-tools.ts +++ b/src/lib/server/error-arm-tools.ts @@ -26,6 +26,7 @@ import { readdirSync, readFileSync, existsSync } from 'fs'; import path from 'path'; import { ADCP_VERSION } from '../version'; import { resolveBundleKey } from '../validation/schema-loader'; +import { getSchemaDataRoots } from '../internal/schema-data-roots'; /** * Resolve the schema-cache root for a given AdCP version. @@ -43,12 +44,13 @@ import { resolveBundleKey } from '../validation/schema-loader'; */ function resolveBundledRoot(version: string): string | undefined { const key = resolveBundleKey(version); + const { builtSchemasDataRoot, sourceSchemasCacheRoot } = getSchemaDataRoots(); // Built layout (dist): dist/lib/schemas-data//bundled - const distCandidate = path.join(__dirname, '..', 'schemas-data', key, 'bundled'); + const distCandidate = path.join(builtSchemasDataRoot, key, 'bundled'); if (existsSync(distCandidate)) return distCandidate; // Source-tree layout (dev): schemas/cache//bundled - const cacheRoot = path.join(__dirname, '..', '..', '..', 'schemas', 'cache'); + const cacheRoot = sourceSchemasCacheRoot; const exactCandidate = path.join(cacheRoot, version, 'bundled'); if (existsSync(exactCandidate)) return exactCandidate; diff --git a/src/lib/testing/storyboard/compliance.ts b/src/lib/testing/storyboard/compliance.ts index ab8d2e27d..1bd8ef7f4 100644 --- a/src/lib/testing/storyboard/compliance.ts +++ b/src/lib/testing/storyboard/compliance.ts @@ -16,6 +16,7 @@ import { ADCPError } from '../../errors'; import { isAdcpVersionSupported } from '../../utils/adcp-version-config'; import { hasSchemaBundle, resolveBundleKey } from '../../validation/schema-loader'; import { synthesizeRequestSigningSteps } from './request-signing/synthesize'; +import { getPackageRoot } from '../../internal/package-root'; import type { RunnerSelectionResult, Storyboard } from './types'; /** @@ -207,11 +208,6 @@ export interface ResolvedStoryboards { not_applicable: NotApplicableStoryboard[]; } -function getRepoRoot(): string { - // Walks from src/lib/testing/storyboard/ (or dist/lib/testing/storyboard/) → package root. - return resolve(__dirname, '..', '..', '..', '..'); -} - /** * Resolve the compliance cache directory. * @@ -224,7 +220,7 @@ export function getComplianceCacheDir(options: ResolveOptions = {}): string { const configured = getConfiguredComplianceDir(options); if (configured) return configured; const version = options.version || readAdcpVersion(); - return join(getRepoRoot(), 'compliance', 'cache', version); + return join(getPackageRoot(), 'compliance', 'cache', version); } function readAdcpVersion(): string { diff --git a/src/lib/v2/projection/canonical-properties.ts b/src/lib/v2/projection/canonical-properties.ts index 70d13529c..ed5244ade 100644 --- a/src/lib/v2/projection/canonical-properties.ts +++ b/src/lib/v2/projection/canonical-properties.ts @@ -22,6 +22,7 @@ import { readFileSync, existsSync } from 'fs'; import path from 'path'; import type { CanonicalFormatKind } from './types'; import { BETA_VERSIONS_TO_TRY } from './cache-versions'; +import { getSchemaDataRoots } from '../../internal/schema-data-roots'; interface CanonicalSchema { properties?: { @@ -55,9 +56,10 @@ function findCacheRoot(): string { // is intentionally not copied — adopters pinned to 3.0.x GA hit the // throw below rather than silently picking up a v3.0 cache that // lacks canonical-format schemas). + const { builtSchemasDataRoot, sourceSchemasCacheRoot } = getSchemaDataRoots(); const candidates = [ - ...BETA_VERSIONS_TO_TRY.map(v => path.join(__dirname, '..', '..', 'schemas-data', v)), - ...BETA_VERSIONS_TO_TRY.map(v => path.join(__dirname, '..', '..', '..', '..', 'schemas', 'cache', v)), + ...BETA_VERSIONS_TO_TRY.map(v => path.join(builtSchemasDataRoot, v)), + ...BETA_VERSIONS_TO_TRY.map(v => path.join(sourceSchemasCacheRoot, v)), ]; for (const c of candidates) { if (existsSync(c)) return c; diff --git a/src/lib/v2/projection/catalog.ts b/src/lib/v2/projection/catalog.ts index 458e6ce0e..ac10e3571 100644 --- a/src/lib/v2/projection/catalog.ts +++ b/src/lib/v2/projection/catalog.ts @@ -22,6 +22,7 @@ import { readFileSync, existsSync } from 'fs'; import path from 'path'; import type { CanonicalFormatKind, V1FormatId } from './types'; +import { getPackageRoot } from '../../internal/package-root'; /** * Canonical projection reference (`canonical-projection-ref.json` in the @@ -120,21 +121,12 @@ function indexKey(agentUrl: string, id: string): string { export function loadCatalog(explicitPath?: string): CatalogIndex { if (cached) return cached; + const packageRoot = getPackageRoot(); const candidates = explicitPath ? [explicitPath] : [ - path.join(__dirname, 'aao-reference-formats.json'), - path.join( - __dirname, - '..', - '..', - '..', - '..', - 'test', - 'lib', - 'v2-projection-fixtures', - 'aao-reference-formats.json' - ), + path.join(packageRoot, 'dist', 'lib', 'v2', 'projection', 'aao-reference-formats.json'), + path.join(packageRoot, 'test', 'lib', 'v2-projection-fixtures', 'aao-reference-formats.json'), ]; for (const file of candidates) { diff --git a/src/lib/v2/projection/registry.ts b/src/lib/v2/projection/registry.ts index b84b20b06..083d774f6 100644 --- a/src/lib/v2/projection/registry.ts +++ b/src/lib/v2/projection/registry.ts @@ -30,6 +30,7 @@ import path from 'path'; import type { CanonicalFormatKind, V1FormatId } from './types'; import { AAO_CANONICAL_AGENT_URL } from './constants'; import { BETA_VERSIONS_TO_TRY } from './cache-versions'; +import { getSchemaDataRoots } from '../../internal/schema-data-roots'; interface RegistryEntryV1Pattern { format_id_glob?: string; @@ -78,14 +79,13 @@ let cached: CanonicalMappingRegistry | null = null; */ export function loadRegistry(cacheRoot?: string): CanonicalMappingRegistry { if (cached) return cached; + const { builtSchemasDataRoot, sourceSchemasCacheRoot } = getSchemaDataRoots(); const candidates = cacheRoot ? [path.join(cacheRoot, 'registries', 'v1-canonical-mapping.json')] : [ + ...BETA_VERSIONS_TO_TRY.map(v => path.join(builtSchemasDataRoot, v, 'registries', 'v1-canonical-mapping.json')), ...BETA_VERSIONS_TO_TRY.map(v => - path.join(__dirname, '..', '..', 'schemas-data', v, 'registries', 'v1-canonical-mapping.json') - ), - ...BETA_VERSIONS_TO_TRY.map(v => - path.join(__dirname, '..', '..', '..', '..', 'schemas', 'cache', v, 'registries', 'v1-canonical-mapping.json') + path.join(sourceSchemasCacheRoot, v, 'registries', 'v1-canonical-mapping.json') ), ]; for (const file of candidates) { diff --git a/src/lib/validation/schema-loader.ts b/src/lib/validation/schema-loader.ts index f17deefe9..dbaa65b77 100644 --- a/src/lib/validation/schema-loader.ts +++ b/src/lib/validation/schema-loader.ts @@ -20,6 +20,7 @@ import { readdirSync, readFileSync, existsSync } from 'fs'; import path from 'path'; import { ADCP_VERSION } from '../version'; import { ConfigurationError } from '../errors'; +import { getSchemaDataRoots } from '../internal/schema-data-roots'; export type ResponseVariant = 'sync' | 'submitted' | 'working' | 'input-required'; export type Direction = 'request' | ResponseVariant; @@ -239,7 +240,8 @@ function resolveSchemaRoot(version: string): string { const externalRoot = externalSchemaRoots.get(key); if (externalRoot && existsSync(externalRoot)) return externalRoot; - const distCandidate = path.join(__dirname, '..', 'schemas-data', key); + const { builtSchemasDataRoot, sourceSchemasCacheRoot } = getSchemaDataRoots(); + const distCandidate = path.join(builtSchemasDataRoot, key); if (existsSync(distCandidate)) return distCandidate; // Published builds carry exact prerelease bundle directories @@ -247,14 +249,14 @@ function resolveSchemaRoot(version: string): string { // alias (`3.1-rc`). Resolve that alias before falling back to source cache. const releasePrecisionMatch = /^\d+\.\d+-/.test(key); if (releasePrecisionMatch) { - const distPrereleaseCandidate = findPrereleaseBundle(path.join(__dirname, '..', 'schemas-data'), key); + const distPrereleaseCandidate = findPrereleaseBundle(builtSchemasDataRoot, key); if (distPrereleaseCandidate) return distPrereleaseCandidate; } // Source-tree fallback: cache stays exact-version-named, so map the key // back to the highest-patch cache directory in the same minor for stable // pins. Prereleases need an exact match. - const cacheRoot = path.join(__dirname, '..', '..', '..', 'schemas', 'cache'); + const cacheRoot = sourceSchemasCacheRoot; const exactCandidate = path.join(cacheRoot, version); if (existsSync(exactCandidate)) return exactCandidate; diff --git a/test/lib/package-root.test.js b/test/lib/package-root.test.js new file mode 100644 index 000000000..0e764bb41 --- /dev/null +++ b/test/lib/package-root.test.js @@ -0,0 +1,101 @@ +// getPackageRoot() replaces the per-file `__dirname` arithmetic that used to be +// duplicated across 7 schema/data loaders (validation/schema-loader.ts, +// conformance/schemaLoader.ts, server/error-arm-tools.ts, +// v2/projection/{catalog,registry,canonical-properties}.ts, +// testing/storyboard/compliance.ts). It resolves the package root via +// `require.resolve('@adcp/sdk/package.json')` self-reference — independent of +// the calling module's own directory depth — falling back to a directory walk. + +const { test, describe, after } = require('node:test'); +const assert = require('node:assert'); +const fs = require('node:fs'); +const os = require('node:os'); +const path = require('node:path'); + +const REPO_ROOT = path.resolve(__dirname, '..', '..'); +const { + getPackageRoot, + _resetPackageRootCache, + _resolvePackageRootViaDirectoryWalk, +} = require('../../dist/lib/internal/package-root.js'); + +describe('getPackageRoot', () => { + test('resolves to the actual package root via self-reference', () => { + _resetPackageRootCache(); + const root = getPackageRoot(); + assert.strictEqual(root, REPO_ROOT); + }); + + test('resolved root contains a package.json named @adcp/sdk', () => { + _resetPackageRootCache(); + const root = getPackageRoot(); + const pkg = JSON.parse(fs.readFileSync(path.join(root, 'package.json'), 'utf-8')); + assert.strictEqual(pkg.name, '@adcp/sdk'); + }); + + test('memoizes across calls', () => { + _resetPackageRootCache(); + const first = getPackageRoot(); + const second = getPackageRoot(); + assert.strictEqual(first, second); + }); + + test('_resetPackageRootCache() forces recomputation without changing the result', () => { + const before = getPackageRoot(); + _resetPackageRootCache(); + const after = getPackageRoot(); + assert.strictEqual(before, after); + }); +}); + +describe('_resolvePackageRootViaDirectoryWalk (fallback path)', () => { + let tmpRoot; + + after(() => { + if (tmpRoot && fs.existsSync(tmpRoot)) { + fs.rmSync(tmpRoot, { recursive: true, force: true }); + } + }); + + test('finds an ancestor package.json named @adcp/sdk from a nested start dir', () => { + tmpRoot = fs.mkdtempSync(path.join(os.tmpdir(), 'adcp-package-root-walk-')); + fs.writeFileSync(path.join(tmpRoot, 'package.json'), JSON.stringify({ name: '@adcp/sdk' })); + const nested = path.join(tmpRoot, 'dist', 'lib', 'internal'); + fs.mkdirSync(nested, { recursive: true }); + + const found = _resolvePackageRootViaDirectoryWalk(nested); + assert.strictEqual(found, tmpRoot); + }); + + test('skips an ancestor package.json with a different name', () => { + tmpRoot = fs.mkdtempSync(path.join(os.tmpdir(), 'adcp-package-root-walk-')); + fs.writeFileSync(path.join(tmpRoot, 'package.json'), JSON.stringify({ name: 'some-other-package' })); + const nested = path.join(tmpRoot, 'a', 'b'); + fs.mkdirSync(nested, { recursive: true }); + + const found = _resolvePackageRootViaDirectoryWalk(nested); + assert.strictEqual(found, undefined); + }); + + test('returns undefined when no package.json exists in the ancestry up to the filesystem root', () => { + tmpRoot = fs.mkdtempSync(path.join(os.tmpdir(), 'adcp-package-root-walk-')); + const nested = path.join(tmpRoot, 'a', 'b'); + fs.mkdirSync(nested, { recursive: true }); + + const found = _resolvePackageRootViaDirectoryWalk(nested); + assert.strictEqual(found, undefined); + }); + + test('tolerates a malformed package.json in the ancestry and keeps walking up', () => { + tmpRoot = fs.mkdtempSync(path.join(os.tmpdir(), 'adcp-package-root-walk-')); + const middle = path.join(tmpRoot, 'middle'); + fs.mkdirSync(middle, { recursive: true }); + fs.writeFileSync(path.join(middle, 'package.json'), '{ not valid json'); + fs.writeFileSync(path.join(tmpRoot, 'package.json'), JSON.stringify({ name: '@adcp/sdk' })); + const nested = path.join(middle, 'nested'); + fs.mkdirSync(nested, { recursive: true }); + + const found = _resolvePackageRootViaDirectoryWalk(nested); + assert.strictEqual(found, tmpRoot); + }); +}); diff --git a/test/lib/schema-data-roots.test.js b/test/lib/schema-data-roots.test.js new file mode 100644 index 000000000..2ea46fe3f --- /dev/null +++ b/test/lib/schema-data-roots.test.js @@ -0,0 +1,23 @@ +// getSchemaDataRoots() gives the 7 schema/data loaders one shared anchor for +// the two directories they each used to locate via hand-tuned `__dirname` +// arithmetic: the built (dist) schemas-data tree and the source-tree +// schemas/cache tree. + +const { test, describe } = require('node:test'); +const assert = require('node:assert'); +const path = require('node:path'); + +const REPO_ROOT = path.resolve(__dirname, '..', '..'); +const { getSchemaDataRoots } = require('../../dist/lib/internal/schema-data-roots.js'); + +describe('getSchemaDataRoots', () => { + test('builtSchemasDataRoot points at dist/lib/schemas-data under the package root', () => { + const { builtSchemasDataRoot } = getSchemaDataRoots(); + assert.strictEqual(builtSchemasDataRoot, path.join(REPO_ROOT, 'dist', 'lib', 'schemas-data')); + }); + + test('sourceSchemasCacheRoot points at schemas/cache under the package root', () => { + const { sourceSchemasCacheRoot } = getSchemaDataRoots(); + assert.strictEqual(sourceSchemasCacheRoot, path.join(REPO_ROOT, 'schemas', 'cache')); + }); +}); diff --git a/test/lib/schema-loader-per-version.test.js b/test/lib/schema-loader-per-version.test.js index 01ba31b00..dcbad53c5 100644 --- a/test/lib/schema-loader-per-version.test.js +++ b/test/lib/schema-loader-per-version.test.js @@ -70,6 +70,9 @@ function runPrereleaseSortFixture() { const tempDist = path.join(tempRoot, 'dist'); fs.cpSync(path.join(REPO_ROOT, 'dist'), tempDist, { recursive: true }); fs.symlinkSync(path.join(REPO_ROOT, 'node_modules'), path.join(tempRoot, 'node_modules'), 'dir'); + // getPackageRoot()'s require.resolve self-reference needs an ancestor + // package.json named @adcp/sdk to find this package's own root. + fs.cpSync(path.join(REPO_ROOT, 'package.json'), path.join(tempRoot, 'package.json')); const tempSchemasData = path.join(tempDist, 'lib', 'schemas-data'); writeMinimalGetProductsBundle(path.join(tempSchemasData, PRERELEASE_SORT_OLD), PRERELEASE_SORT_OLD, 'old'); writeMinimalGetProductsBundle(path.join(tempSchemasData, PRERELEASE_SORT_NEW), PRERELEASE_SORT_NEW, 'new'); diff --git a/test/lib/v2-projection-loader-paths.test.js b/test/lib/v2-projection-loader-paths.test.js index ad8bda150..855d02a05 100644 --- a/test/lib/v2-projection-loader-paths.test.js +++ b/test/lib/v2-projection-loader-paths.test.js @@ -44,9 +44,13 @@ before(() => { } tmpRoot = fs.mkdtempSync(path.join(os.tmpdir(), 'adcp-projection-loader-paths-')); - // Mimic node_modules/@adcp/sdk/dist by copying only the dist tree. - // Intentionally do NOT copy schemas/cache — that's the bug we're guarding. + // Mimic node_modules/@adcp/sdk/ by copying the dist tree plus package.json + // (every real npm install ships package.json regardless of the "files" + // field — getPackageRoot()'s require.resolve self-reference needs it to + // find this package's own root). Intentionally do NOT copy schemas/cache + // — that's the bug we're guarding. fs.cpSync(SRC_DIST, path.join(tmpRoot, 'dist'), { recursive: true }); + fs.cpSync(path.join(REPO_ROOT, 'package.json'), path.join(tmpRoot, 'package.json')); }); after(() => { diff --git a/tsup.config.ts b/tsup.config.ts index df085b67c..8d717748e 100644 --- a/tsup.config.ts +++ b/tsup.config.ts @@ -85,14 +85,16 @@ function fixDynamicImportExtensions() { // Build the library as a tree-shakeable dual package. // // `bundle: false` transpiles each source module 1:1 (no bundling, no chunks), -// so the output mirrors the source tree exactly. That keeps three things +// so the output mirrors the source tree exactly. That keeps two things // correct with zero extra work: // 1. a consumer's bundler tree-shakes across the preserved module graph when -// it imports from a public entry (importing one symbol stays lean), +// it imports from a public entry (importing one symbol stays lean), and // 2. the CLI and internal tooling that deep-`require` dist paths still -// resolve, and -// 3. the `__dirname`-based schema-data lookups keep their original directory -// depth (each module stays at its own path). +// resolve. +// (Schema/data-root resolution no longer depends on this: the 7 loaders that +// used to hand-tune `__dirname` arithmetic to their own directory depth now +// anchor via `getPackageRoot()`, which resolves via module self-reference +// independent of where the calling module lives — see src/lib/internal/.) // // `fixImportsPlugin` (see tsup#1240) supplies what `bundle: false` leaves out: // it appends the correct extension to relative imports, rewrites directory