Skip to content

Commit 695b08b

Browse files
Normalize workspace export types
1 parent 4cabc6c commit 695b08b

10 files changed

Lines changed: 128 additions & 0 deletions

File tree

packages/cache/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
"types": "./dist/index.d.ts",
88
"exports": {
99
".": {
10+
"types": "./dist/index.d.ts",
1011
"development": "./src/index.ts",
1112
"default": "./dist/index.js"
1213
}

packages/config/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
"types": "./dist/index.d.ts",
88
"exports": {
99
".": {
10+
"types": "./dist/index.d.ts",
1011
"development": "./src/index.ts",
1112
"default": "./dist/index.js"
1213
}

packages/deploy/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
"types": "./dist/index.d.ts",
88
"exports": {
99
".": {
10+
"types": "./dist/index.d.ts",
1011
"development": "./src/index.ts",
1112
"default": "./dist/index.js"
1213
}

packages/models/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
"types": "./dist/index.d.ts",
88
"exports": {
99
".": {
10+
"types": "./dist/index.d.ts",
1011
"development": "./src/index.ts",
1112
"default": "./dist/index.js"
1213
}

packages/prompts/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
"types": "./dist/index.d.ts",
88
"exports": {
99
".": {
10+
"types": "./dist/index.d.ts",
1011
"development": "./src/index.ts",
1112
"default": "./dist/index.js"
1213
}

packages/runtime/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
"types": "./dist/index.d.ts",
88
"exports": {
99
".": {
10+
"types": "./dist/index.d.ts",
1011
"development": "./src/index.ts",
1112
"default": "./dist/index.js"
1213
}

packages/scheduler/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
"types": "./dist/index.d.ts",
88
"exports": {
99
".": {
10+
"types": "./dist/index.d.ts",
1011
"development": "./src/index.ts",
1112
"default": "./dist/index.js"
1213
}

packages/telemetry/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
"types": "./dist/index.d.ts",
88
"exports": {
99
".": {
10+
"types": "./dist/index.d.ts",
1011
"development": "./src/index.ts",
1112
"default": "./dist/index.js"
1213
}

scripts/package-runtime-coverage.test.ts

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,76 @@ test("validatePackageRuntimeCoverage rejects malformed direct paths before scann
253253
);
254254
});
255255

256+
test("validatePackageRuntimeCoverage requires root export type conditions", async (t) => {
257+
const tempDir = await mkdtemp(path.join(tmpdir(), "ray-package-runtime-export-types-"));
258+
t.after(async () => {
259+
await rm(tempDir, { recursive: true, force: true });
260+
});
261+
262+
const rootPackageJson = path.join(tempDir, "package.json");
263+
const packageDir = path.join(tempDir, "packages", "sdk");
264+
await mkdir(packageDir, { recursive: true });
265+
const sdkPackageJson = path.join(packageDir, "package.json");
266+
await writeFile(
267+
rootPackageJson,
268+
JSON.stringify(
269+
{
270+
name: "ray-test",
271+
packageManager: "bun@1.3.9",
272+
engines: {
273+
bun: ">=1.3.0",
274+
},
275+
type: "module",
276+
types: "./dist/index.d.ts",
277+
exports: {
278+
".": "./dist/index.js",
279+
},
280+
},
281+
null,
282+
2,
283+
),
284+
);
285+
await writeFile(
286+
sdkPackageJson,
287+
JSON.stringify(
288+
{
289+
name: "@razroo/ray-sdk-test",
290+
type: "module",
291+
types: "./dist/index.d.ts",
292+
exports: {
293+
".": {
294+
default: "./dist/index.js",
295+
},
296+
},
297+
},
298+
null,
299+
2,
300+
),
301+
);
302+
303+
const summary = await validatePackageRuntimeCoverage({
304+
cwd: tempDir,
305+
packageJsonPaths: [rootPackageJson, sdkPackageJson],
306+
});
307+
const diagnostics = summary.results.flatMap((result) => result.diagnostics);
308+
309+
assert.equal(summary.ok, false);
310+
assert.ok(
311+
diagnostics.some(
312+
(diagnostic) =>
313+
diagnostic.code === "package_root_export_must_be_object_for_types" &&
314+
diagnostic.packagePath === rootPackageJson,
315+
),
316+
);
317+
assert.ok(
318+
diagnostics.some(
319+
(diagnostic) =>
320+
diagnostic.code === "package_root_export_types_missing" &&
321+
diagnostic.packagePath === sdkPackageJson,
322+
),
323+
);
324+
});
325+
256326
test("validatePackageRuntimeCoverage requires config and Bun cache storage preflight coverage", async (t) => {
257327
const tempDir = await mkdtemp(path.join(tmpdir(), "ray-package-runtime-coverage-storage-"));
258328
t.after(async () => {

scripts/package-runtime-coverage.ts

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -709,6 +709,55 @@ function validateScripts(
709709
return diagnostics;
710710
}
711711

712+
function validatePackageExportTypes(
713+
packageJsonPath: string,
714+
parsedPackage: Record<string, unknown>,
715+
): PackageRuntimeCoverageDiagnostic[] {
716+
const types = parsedPackage.types;
717+
const exports = parsedPackage.exports;
718+
719+
if (typeof types !== "string" || exports === undefined) {
720+
return [];
721+
}
722+
723+
const diagnostics: PackageRuntimeCoverageDiagnostic[] = [];
724+
if (typeof exports !== "object" || exports === null || Array.isArray(exports)) {
725+
diagnostics.push({
726+
level: "error",
727+
code: "package_exports_must_be_object_for_types",
728+
packagePath: packageJsonPath,
729+
message:
730+
"Package manifests with top-level types must use an object exports map so declaration entrypoints can be checked.",
731+
});
732+
return diagnostics;
733+
}
734+
735+
const rootExport = (exports as Record<string, unknown>)["."];
736+
if (typeof rootExport !== "object" || rootExport === null || Array.isArray(rootExport)) {
737+
diagnostics.push({
738+
level: "error",
739+
code: "package_root_export_must_be_object_for_types",
740+
packagePath: packageJsonPath,
741+
message:
742+
'Package manifests with top-level types must expose exports["."] as an object with a matching types condition.',
743+
});
744+
return diagnostics;
745+
}
746+
747+
const rootExportTypes = (rootExport as Record<string, unknown>).types;
748+
if (rootExportTypes !== types) {
749+
diagnostics.push({
750+
level: "error",
751+
code: "package_root_export_types_missing",
752+
packagePath: packageJsonPath,
753+
message:
754+
'Package manifests with top-level types must set exports["."].types to the same declaration path so TypeScript consumers resolve package exports consistently.',
755+
});
756+
}
757+
758+
return diagnostics;
759+
}
760+
712761
function isLocalHealthCurl(line: string): boolean {
713762
return (
714763
/\bcurl\b/.test(line) &&
@@ -2890,6 +2939,7 @@ export async function validatePackageRuntimeCoverage(
28902939
}
28912940
const diagnostics = [
28922941
...validateRootPackageManager(cwd, packageJsonPath, parsedPackage),
2942+
...validatePackageExportTypes(packageJsonPath, parsedPackage),
28932943
...validateScripts(packageJsonPath, scripts),
28942944
];
28952945

0 commit comments

Comments
 (0)