Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions .changeset/fields-plugin-editor-dist-test-declarations-4006.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
---
'@object-ui/fields': patch
'@object-ui/plugin-editor': patch
---

`@object-ui/fields` and `@object-ui/plugin-editor` stop publishing their test declarations

Both packages' build tsconfigs set `include: ["src"]` with no test exclude, so every test file entered the declaration program and its `.d.ts` was written into `dist/`. Both are published (`private` is false, `files` contains `dist`), so those declarations shipped: 85 from `@object-ui/fields` and one from `@object-ui/plugin-editor`. Adding the test exclude the other twenty-odd packages already use removes them.

Nothing else about either artifact moves. Measured by building each package both ways from a cleared `dist/`, then diffing the file lists: `@object-ui/fields` goes from 163 files to 78 and `@object-ui/plugin-editor` from 6 to 5, every one of the 86 disappearances is a `*.test.d.ts`, no file appears, and all 83 surviving files are byte-identical by sha256 — including each package's entry `dist/index.d.ts`. The entry type surface is therefore unchanged and no import can break; this is the tarball shedding files nothing resolved.

The type coverage those files were a side effect of did not go with them. Because the build program read the tests, these two packages counted as "tests type-checked" in `scripts/check-type-check-coverage.mjs` — a correct verdict reached through an emit nobody wanted. Excluding the tests alone would have silently dropped 86 test files out of every `tsc` program, so the same change adds a `tsconfig.test.json` per package, chained from each package's `type-check` script, and the coverage gate stays at 41 of 41 packages compiling their tests with zero declared debt on both sides of the change.
2 changes: 1 addition & 1 deletion packages/fields/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
"scripts": {
"build": "tsc && vite build && node scripts/build-css.mjs",
"clean": "rm -rf dist",
"type-check": "tsc --noEmit",
"type-check": "tsc --noEmit && tsc -p tsconfig.test.json",
"test": "vitest run",
"lint": "eslint ."
},
Expand Down
18 changes: 17 additions & 1 deletion packages/fields/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,24 @@
"extends": "../../tsconfig.json",
"compilerOptions": {
"outDir": "dist",
// `..` (i.e. `packages/`), NOT `src` — load-bearing, measured in
// objectui#4006. This config inherits the root tsconfig's `paths`, which map
// `@object-ui/core` / `@object-ui/types` to their sibling `packages/*/src`
// trees, so those sources are real program inputs. Narrowing `rootDir` to
// `src` (or dropping it, which defaults it to the common source directory)
// turns all 122 of them into TS6059 "not under rootDir" — and it does so
// even under `--noEmit`, because TS6059 is a program-level verdict. It does
// not affect what is emitted: this config inherits the root's
// `noEmit: true`, so `tsc` here only CHECKS; `dist` is written by
// vite-plugin-dts, which overrides `rootDir` to `src` and clears `paths`.
"rootDir": "..",
"jsx": "react-jsx"
},
"include": ["src"]
"include": ["src"],
// Tests are excluded from the BUILD program so they stop being emitted into
// the published `dist` (objectui#4006 — 85 `*.test.d.ts` shipped from here).
// Their type coverage did not go away with them: it moved to the
// `tsconfig.test.json` chained off this package's `type-check` script, which
// is what scripts/check-type-check-coverage.mjs verifies.
"exclude": ["node_modules", "dist", "**/*.test.ts", "**/*.test.tsx"]
}
62 changes: 62 additions & 0 deletions packages/fields/tsconfig.test.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
{
// Type-checks this package's TESTS, which `tsconfig.json` now excludes.
// See `packages/plugin-dashboard/tsconfig.test.json` for the template and
// `packages/types/tsconfig.test.json` for why the exclusion would otherwise
// be a hole: a test nothing compiles can assert a contract the compiler never
// checked and then read as evidence that the contract holds (objectui#3009).
//
// The hole is NEW here, and that is the whole point of objectui#4006. Until
// this file existed these 85 tests were checked — but only as a SIDE EFFECT
// of the build config having no test exclude at all, which is also why 85
// `*.test.d.ts` were emitted into the published `dist/`. Removing the emit
// therefore had to move the coverage in the same commit, not after it:
// scripts/check-type-check-coverage.mjs fails 5c the moment the exclude
// lands alone (measured — it names all 85 files).
//
// Chained from this package's `type-check` script, which is what the CI
// `Type Check` job runs; the coverage gate enforces the chaining — a config
// nothing runs is the objectui#3009 failure itself.
"extends": "../../tsconfig.json",
"compilerOptions": {
// A checking project, never an emitting one. The build config inherits the
// root's `noEmit: true` as well (this package emits `dist` from
// vite-plugin-dts, not from `tsc`), but stating it here is what the gate
// requires and what keeps this project from ever growing an output.
"noEmit": true,
"composite": false,
"declaration": false,
"jsx": "react-jsx",
// Deliberately NOT raised to ES2022. Measured: no test file in this package
// reaches for `Array.prototype.at` or any other ES2021+ builtin, so the
// tests are held to the same lib the shipped SOURCE targets.
"lib": ["ES2020", "DOM", "DOM.Iterable"],
//
// `types` is deliberately NOT named, unlike plugin-dashboard's. Naming it
// switches off automatic `@types/*` inclusion, and this package's build
// program does not name it either — so leaving it unset is what reproduces
// the exact program these tests were checked by until now, which is the
// property objectui#4006 had to preserve while moving the coverage.
// Measured: no test file here uses `global`, and the seven suites that use
// `@testing-library/jest-dom` matchers `import '@testing-library/jest-dom'`
// explicitly, so its global augmentation reaches the whole program through
// that import (plugin-list's lesson).
//
// `paths` drops the root tsconfig's source-tree mappings so `@object-ui/*`
// and `@objectstack/spec/*` resolve through each workspace dependency's
// built `.d.ts` rather than pulling sibling package sources in as program
// inputs. `type-check` dependsOn `^build` (turbo.json), so those `.d.ts`
// exist by the time this runs. This is the one place the project is
// deliberately STRICTER than the program it replaces: the build config
// keeps the root `paths` (and the `rootDir: ".."` that lets sibling sources
// sit inside the root), so until now these tests were checked against
// sibling SOURCE. Checking them against the built declarations is what the
// published contract actually is, and it is what every other chained test
// project in this repo does. Measured: zero new errors either way.
"paths": {}
},
// Only the test files. Note there is no ambient `*.d.ts` under `src/` in this
// package today — if one is ever added it must be NAMED here, because being
// imported is not enough to make an ambient declaration a program input, and
// nothing imports one (plugin-map's lesson, objectui#4270).
"include": ["src/**/*.test.ts", "src/**/*.test.tsx"]
}
2 changes: 1 addition & 1 deletion packages/plugin-editor/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
"build": "vite build",
"test": "vitest run",
"test:watch": "vitest",
"type-check": "tsc --noEmit",
"type-check": "tsc --noEmit && tsc -p tsconfig.test.json",
"lint": "eslint ."
},
"dependencies": {
Expand Down
11 changes: 10 additions & 1 deletion packages/plugin-editor/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,14 @@
"composite": true,
"skipLibCheck": true
},
"include": ["src"]
"include": ["src"],
// Tests are excluded from the BUILD program so they stop being emitted into
// the published `dist` (objectui#4006 — `dist/index.test.d.ts` shipped from
// here). The emitter is vite-plugin-dts, whose own `include: ['src']` in
// `vite.config.ts` does NOT displace this `exclude`: measured, the exclude
// alone removes `dist/index.test.d.ts`, so no dts-plugin `exclude` is needed.
// Their type coverage did not go away with them: it moved to the
// `tsconfig.test.json` chained off this package's `type-check` script, which
// is what scripts/check-type-check-coverage.mjs verifies.
"exclude": ["node_modules", "dist", "**/*.test.ts", "**/*.test.tsx"]
}
45 changes: 45 additions & 0 deletions packages/plugin-editor/tsconfig.test.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
{
// Type-checks this package's TESTS, which `tsconfig.json` now excludes.
// Template: `packages/plugin-dashboard/tsconfig.test.json` (objectui#4530);
// rationale: `packages/types/tsconfig.test.json`. A test nothing compiles can
// assert a contract the compiler never checked and then read as evidence that
// the contract holds (objectui#3009).
//
// As in `@object-ui/fields`, the hole is new and deliberate: until
// objectui#4006 this suite was checked only as a side effect of the build
// config having no test exclude, which is also how `dist/index.test.d.ts`
// came to be published. The exclude and this project are one change —
// scripts/check-type-check-coverage.mjs fails 5c on the exclude alone
// (measured).
//
// Chained from this package's `type-check` script, which is what the CI
// `Type Check` job runs; the coverage gate enforces the chaining.
"extends": "../../tsconfig.json",
"compilerOptions": {
// A checking project, never an emitting one. This matters more here than in
// most packages: this package's BUILD config deliberately sets
// `noEmit: false` with `declaration` and `composite`, so those three must be
// turned back off rather than inherited — this project extends the ROOT
// config, not the build one, but stating them keeps that true if the
// `extends` target ever changes.
"noEmit": true,
"composite": false,
"declaration": false,
"jsx": "react-jsx",
// Measured: the single suite compiles clean against the root's ES2020
// baseline, so the test is held to the same lib the shipped SOURCE targets.
"lib": ["ES2020", "DOM", "DOM.Iterable"],
// `paths` drops the root tsconfig's source-tree mappings so `@object-ui/*`
// resolves through each workspace dependency's built `.d.ts` rather than
// pulling sibling package sources in as program inputs. `type-check`
// dependsOn `^build` (turbo.json), so those `.d.ts` exist by the time this
// runs. The suite imports exactly one workspace specifier,
// `@object-ui/core`, plus its own `./index`.
"paths": {}
},
// Only the test files. There is no ambient `*.d.ts` under `src/` in this
// package today — if one is ever added it must be NAMED here, because being
// imported is not enough to make an ambient declaration a program input
// (plugin-map's lesson, objectui#4270).
"include": ["src/**/*.test.ts", "src/**/*.test.tsx"]
}
Loading