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
1 change: 1 addition & 0 deletions packages/superdoc/scripts/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,7 @@ what an actual consumer would see — not the workspace source.
| `package-shape-gate.mjs` | External package-shape linters (publint + attw) against the packed tarball. | Catches condition ordering, masquerading exports, missing field declarations. |
| `check-root-classification-closure.mjs` | Asserts no `supported-root` or `legacy-root` export references an `internal-candidate` symbol in its public declared type. | Closure rule from SD-3212. |
| `check-public-method-coverage.mjs` | Strict-zero obligation gate over public `SuperDoc` methods + getters. For each member the AST computes which obligations are meaningful (`parameters`, `returns`, or `call`); the gate fails on any unmet obligation. No grandfathered debt snapshot, no `--write`. Catches the `search(text: string)` regression class — call sites do NOT satisfy `parameters`/`returns` on their own. | Allowlist at `public-method-coverage-allowlist.cjs` is the only escape hatch (intentionally non-consumer-callable members; each entry validated: key must match a real member, value must be a non-empty reason). |
| `report-js-contract-owners.cjs` | JS contract-owner audit (SD-673). For both `superdoc` and `@superdoc/super-editor` packages: walks every typed export, follows relative / self-package edges through the emitted `.d.ts` forest, resolves each reachable declaration to its source via the companion `.d.ts.map` sourcemap, and classifies `.js` owners against the existing `check-jsdoc.cjs` state (reads the shared `jsdoc-checked-files.cjs`, `jsdoc-allowlist.cjs`, `jsdoc-debt-snapshot.json`, and the in-file `// @ts-check` directive). Output is the count per category plus the list of UNACCOUNTED `.js` owners — public-surface JS source with no `// @ts-check` and no tracking entry. | **Standalone report; not wired into `check:public:superdoc`.** Run on demand: `node packages/superdoc/scripts/report-js-contract-owners.cjs`. **Exit semantics:** findings (UNACCOUNTED count) never fail (exit 0); missing dist / unreadable package inputs exit 1 so a broken pipeline is distinguishable from a clean run. Requires `pnpm build` to have populated both packages' dist trees (`pnpm run type-check` is not a substitute — it writes superdoc declarations to `dist-types/`, not `dist/`). Survey input for follow-up types-only extraction / `@ts-check` adoption. Once UNACCOUNTED stabilizes at zero per package, a follow-up PR can promote a strict no-growth ratchet (which **would** earn a wrapper-stage entry). |
| `apps/docs/__tests__/doctest-types.ts` | Docs snippet type-check (SD-673). Extracts "Full Example" code blocks from `apps/docs/editor/superdoc/**` (JS + TS fences) and runs `tsc --noEmit --strict` (with `allowJs + checkJs` for JS) against `packages/superdoc/dist`. Catches drift between docs examples and the typed public surface — the bug class where `onReady: (superdoc) =>` ships in docs even though the typed callback param is `{ superdoc }`. Companion to the runtime doctest (`apps/docs/__tests__/doctest.test.ts`), which extracts the `onReady` body and runs it against a mocked host — so it would never catch the destructure bug. | Runs as the last wrapper stage of `check:public:superdoc`. Reuses the existing `extractExamples()` from `apps/docs/__tests__/lib/extract.ts`. Placeholder identifiers (`yourFile`, `cleanup`, etc.) are stubbed via a shared ambient `.d.ts` written into the temp project. |

Seven of these run as wrapper stages of `check:public:superdoc`.
Expand Down
36 changes: 15 additions & 21 deletions packages/superdoc/scripts/check-jsdoc.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,10 @@
*
* Adding a file to CHECKED_FILES:
* 1. Add `// @ts-check` as the first line.
* 2. Append the file's repo-relative path to CHECKED_FILES below.
* 2. Append the file's repo-relative path to the `CHECKED_FILES`
* array in `./jsdoc-checked-files.cjs` (the shared source of
* truth consumed by both this gate and
* `report-js-contract-owners.cjs`).
* 3. Run `pnpm --filter superdoc run check:jsdoc` and fix what
* surfaces. If the file was on the debt snapshot, also rerun
* with `--write` to drop the stale entry.
Expand Down Expand Up @@ -77,26 +80,17 @@ const tsconfigPath = path.join(packageDir, 'tsconfig.json');
const DEBT_SNAPSHOT_PATH = path.join(__dirname, 'jsdoc-debt-snapshot.json');
const ALLOWLIST_PATH = path.join(__dirname, 'jsdoc-allowlist.cjs');

// Hand-curated set of files explicitly gated by this script. Each MUST
// have `// @ts-check` at the top. Adding a file = committing to keep
// it clean. The list is small on purpose; broader checkJs coverage is
// gained one file at a time, not in a mass migration.
const CHECKED_FILES = [
'packages/superdoc/src/helpers/schema-introspection.js',
'packages/superdoc/src/composables/use-find-replace.js',
'packages/superdoc/src/composables/use-password-prompt.js',
'packages/super-editor/src/editors/v1/extensions/track-changes/trackChangesHelpers/addMarkStep.js',
'packages/super-editor/src/editors/v1/extensions/track-changes/trackChangesHelpers/markDeletion.js',
'packages/super-editor/src/editors/v1/extensions/track-changes/trackChangesHelpers/markInsertion.js',
];

const REACHABILITY_EXEMPT_CHECKED_FILES = new Set([
// These files predate SD-2833. They are kept under the gate because their
// typedefs feed exported SuperDoc configuration types, but they are reached
// through implementation imports rather than direct public barrel exports.
'packages/superdoc/src/composables/use-find-replace.js',
'packages/superdoc/src/composables/use-password-prompt.js',
]);
// Hand-curated set of files explicitly gated by this script lives in
// `./jsdoc-checked-files.cjs` so it's shared with
// `report-js-contract-owners.cjs` (which classifies these files as
// `checked-files` rather than `unaccounted`). Keep both consumers
// reading from one place; edits go in the shared module.
const {
CHECKED_FILES,
REACHABILITY_EXEMPT_CHECKED_FILES: REACHABILITY_EXEMPT_LIST,
} = require('./jsdoc-checked-files.cjs');

const REACHABILITY_EXEMPT_CHECKED_FILES = new Set(REACHABILITY_EXEMPT_LIST);

// PUBLIC entry points used by the ratchet's public-surface walk. These
// are the files consumers reach through `superdoc`, `superdoc/super-editor`,
Expand Down
51 changes: 51 additions & 0 deletions packages/superdoc/scripts/jsdoc-checked-files.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/**
* Shared source of truth for the hand-curated set of `.js` files
* explicitly gated by `check-jsdoc.cjs`'s per-file `// @ts-check`
* ratchet.
*
* Two consumers:
*
* - `check-jsdoc.cjs` — enforces these files stay clean against tsc.
* - `report-js-contract-owners.cjs` — classifies these as
* `checked-files` (not `unaccounted`) in its public-surface JS
* ownership inventory.
*
* Keeping both consumers reading from this single file prevents the
* audit's classification from drifting silently when the gate's list
* changes. Adding/removing a file is a one-spot edit.
*
* To add a file:
* 1. Add `// @ts-check` as the first line of the source.
* 2. Append the repo-relative path to `CHECKED_FILES` below.
* 3. Run `pnpm --filter superdoc run check:jsdoc` and fix what
* surfaces.
*/

module.exports = {
/**
* Each entry MUST have `// @ts-check` at the top of the source.
* Adding a file commits the contributor to keeping it clean against
* tsc. Kept small on purpose; broader checkJs coverage is gained
* one file at a time, not in a mass migration.
*/
CHECKED_FILES: [
'packages/superdoc/src/helpers/schema-introspection.js',
'packages/superdoc/src/composables/use-find-replace.js',
'packages/superdoc/src/composables/use-password-prompt.js',
'packages/super-editor/src/editors/v1/extensions/track-changes/trackChangesHelpers/addMarkStep.js',
'packages/super-editor/src/editors/v1/extensions/track-changes/trackChangesHelpers/markDeletion.js',
'packages/super-editor/src/editors/v1/extensions/track-changes/trackChangesHelpers/markInsertion.js',
],

/**
* Files kept under the gate even though they are not reached through
* the public-surface walk. Their typedefs feed exported SuperDoc
* configuration types but are reached via implementation imports
* rather than direct public barrel exports. Reachability gate skips
* these — they're already accounted for explicitly.
*/
REACHABILITY_EXEMPT_CHECKED_FILES: [
'packages/superdoc/src/composables/use-find-replace.js',
'packages/superdoc/src/composables/use-password-prompt.js',
],
};
Loading
Loading