Skip to content

fix(types): drain bare @superdoc/common shim, reach zero shims (SD-2893)#3154

Merged
caio-pizzol merged 1 commit intomainfrom
caio-pizzol/SD-2893-stack-6-common
May 5, 2026
Merged

fix(types): drain bare @superdoc/common shim, reach zero shims (SD-2893)#3154
caio-pizzol merged 1 commit intomainfrom
caio-pizzol/SD-2893-stack-6-common

Conversation

@caio-pizzol
Copy link
Copy Markdown
Contributor

Drains the final shim entry. After this lands the published _internal-shims.d.ts has zero declare module entries.

The remaining @superdoc/common shim was referenced by three internal dist d.ts files for four Comment* types: Comment, CommentContent, CommentJSON, CommentThreadingProfile. All live in shared/common/comments-types.ts.

Approach mirrors the list-marker-utils pattern from #3150: tsc-emit comments-types.ts into dist/shared/common/, then map bare @superdoc/common imports to that file. matchSubpaths: false because only the bare specifier is referenced today; any future @superdoc/common/<subpath> import falls through to the shim generator and audit Rule 3 fires (the guard regex matches subpaths). Verified end-to-end with a synthetic injection.

Two paths through ensure-types.cjs address different @superdoc/common concerns and don't conflict:

  • Existing inline-replacement (lines 89-119): runtime-value imports in the main entry (DOCX, PDF, HTML, getFileObject, compareVersions, BlankDOCX)
  • New relocation rule: type imports in the 3 internal dist d.ts files

Verified: build:es clean (10 guarded packages, 0 shim modules), consumer matrix 47/0/0, runtime smoke 4/4, dist target exists at shared/common/comments-types.d.ts, negative test confirms audit Rule 3 catches future @superdoc/common subpath leaks (exit 1).

Closes the SD-2893 shim drain. From the original 9 shim modules, all are now relocated, removed from the public surface, or guarded with explicit fail-loudly behavior. The published superdoc package no longer ships ambient any shims for any private workspace package.

The remaining @superdoc/common shim is referenced by three internal
dist d.ts files for four Comment* types (Comment, CommentContent,
CommentJSON, CommentThreadingProfile). All four live in
shared/common/comments-types.ts.

Approach matches the list-marker-utils pattern from #3150: tsc-emit
just comments-types.ts into dist/shared/common/, then rewrite bare
@superdoc/common imports to that file. matchSubpaths: false because
only the bare specifier is referenced; any future
@superdoc/common/<other-subpath> import falls through to the shim
generator and audit Rule 3 fires (because @superdoc/common is now
in RELOCATION_GUARD_PACKAGES, the regex matches the subpath).

Verified end-to-end: a synthetic
@superdoc/common/some-other-subpath probe is left unchanged by
ensure-types, the shim generator captures it, audit Rule 3 fails
with exit 1.

The existing inline-replacement step at ensure-types.cjs:89-119
that handles the main entry's runtime-value imports (DOCX, PDF,
HTML, getFileObject, compareVersions, BlankDOCX) stays as-is. Two
paths through the script address different concerns:

- Inline-replacement: runtime values from @superdoc/common in
  superdoc/src/index.d.ts (handles those 6 specific imports)
- Relocation rule: bare @superdoc/common type imports in three
  internal dist d.ts files (resolves to comments-types.d.ts)

Shim count: 1 to 0. Final shim drain. _internal-shims.d.ts has no
declare-module entries; all originally-shimmed @superdoc/* packages
have been relocated, removed from the public surface, or guarded.

Verified: build:es clean (10 guarded packages, 0 shim modules),
consumer matrix 47/0/0, runtime smoke 4/4, dist has the relocation
target at shared/common/comments-types.d.ts, the three consumer
d.ts files now import from a relative path. Negative test confirms
the audit gate catches future @superdoc/common subpath leaks.
@caio-pizzol caio-pizzol requested a review from a team as a code owner May 5, 2026 13:11
@linear
Copy link
Copy Markdown

linear Bot commented May 5, 2026

@codecov-commenter
Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@caio-pizzol caio-pizzol merged commit 0b7ec67 into main May 5, 2026
69 checks passed
@caio-pizzol caio-pizzol deleted the caio-pizzol/SD-2893-stack-6-common branch May 5, 2026 13:31
@superdoc-bot
Copy link
Copy Markdown
Contributor

superdoc-bot Bot commented May 5, 2026

🎉 This PR is included in @superdoc-dev/mcp v0.3.0-next.53

The release is available on GitHub release

@superdoc-bot
Copy link
Copy Markdown
Contributor

superdoc-bot Bot commented May 5, 2026

🎉 This PR is included in vscode-ext v2.3.0-next.97

@superdoc-bot
Copy link
Copy Markdown
Contributor

superdoc-bot Bot commented May 5, 2026

🎉 This PR is included in @superdoc-dev/react v1.2.0-next.95

The release is available on GitHub release

@superdoc-bot
Copy link
Copy Markdown
Contributor

superdoc-bot Bot commented May 5, 2026

🎉 This PR is included in superdoc v1.30.0-next.54

The release is available on GitHub release

@superdoc-bot
Copy link
Copy Markdown
Contributor

superdoc-bot Bot commented May 5, 2026

🎉 This PR is included in superdoc-cli v0.8.0-next.71

The release is available on GitHub release

@superdoc-bot
Copy link
Copy Markdown
Contributor

superdoc-bot Bot commented May 5, 2026

🎉 This PR is included in superdoc-sdk v1.8.0-next.54

caio-pizzol added a commit that referenced this pull request May 5, 2026
…942)

The comment above the inline-replacement block was inherited from the
pre-SD-2893 era and described two things that are no longer true after
the shim drain:

1. "fall through to the ambient shim block below" — SD-2942 (this PR)
   removes the shim block, so non-main-entry @superdoc/common imports
   now resolve via the RELOCATION_RULES rewriter, not via a fallback
   shim.
2. "Comment, CommentContent, CommentJSON ... not on the public surface"
   — SD-2893 stack 6 (PR #3154) relocated these types via the bare
   @superdoc/common rule mapping to comments-types.d.ts. `Comment` is
   now publicly importable as
   `import type { Comment } from 'superdoc/super-editor'`.

Replace the block with a description of what the inline-replacement
step actually does today: handle the main entry's runtime-value imports
(DOCX, PDF, HTML, getFileObject, compareVersions, BlankDOCX) which are
not type-only and so the relocation rule cannot serve them.
caio-pizzol added a commit that referenced this pull request May 5, 2026
…SD-2942) (#3155)

* refactor(types): remove _internal-shims.d.ts soft-landing mechanism (SD-2942)

After SD-2893 drained every shim entry to zero, the auto-generated
_internal-shims.d.ts file ships empty (header comments only). The
auto-capture mechanism that wrote it is no longer load-bearing: it
was a soft fallback that captured any unrelocated private @superdoc/*
specifier in dist d.ts files and silently shimmed it as `any`. With
the relocation rules + RULE1_ALLOWLIST + UNSHIMMED_PRIVATE_SPECIFIERS
now covering the entire workspace surface, that soft path mostly
swallows new private leaks instead of failing the build.

This change makes new leaks fail loudly:

- ensure-types.cjs: drop the workspace-imports scanning loops, the
  shim-file write, the triple-slash reference injection, and the
  SHIM_FORBIDDEN regression net (now redundant with the relocation
  rules + audit Rule 1). Add an explicit unlink for any stale
  _internal-shims.d.ts left over from prior builds.
- audit-declarations.cjs: update the rule documentation. Rule 1 now
  fails for any unrelocated private @superdoc/* specifier; Rule 3
  becomes a no-op in steady state (kept as defense against stale
  tarballs or future re-introduction). The internalShimsPresent
  graceful-handling already existed in audit code; no behavioral
  change there.

A future PR that introduces a new private @superdoc/* import on the
public surface fails audit Rule 1 at build time. Verified with a
synthetic injection: import('@superdoc/some-new-private-pkg').T in a
public-reachable d.ts produces FAIL findings: private-specifiers and
exits 1.

Net diff: -167 +41 lines across the two scripts.

Verified: build:es clean (10 guarded packages, no shim file emitted),
consumer matrix 47/0/0, runtime smoke 4/4, dist has zero
_internal-shims references, negative test confirms hard-landing.

* docs(types): fix stale comment about @superdoc/common shim path (SD-2942)

The comment above the inline-replacement block was inherited from the
pre-SD-2893 era and described two things that are no longer true after
the shim drain:

1. "fall through to the ambient shim block below" — SD-2942 (this PR)
   removes the shim block, so non-main-entry @superdoc/common imports
   now resolve via the RELOCATION_RULES rewriter, not via a fallback
   shim.
2. "Comment, CommentContent, CommentJSON ... not on the public surface"
   — SD-2893 stack 6 (PR #3154) relocated these types via the bare
   @superdoc/common rule mapping to comments-types.d.ts. `Comment` is
   now publicly importable as
   `import type { Comment } from 'superdoc/super-editor'`.

Replace the block with a description of what the inline-replacement
step actually does today: handle the main entry's runtime-value imports
(DOCX, PDF, HTML, getFileObject, compareVersions, BlankDOCX) which are
not type-only and so the relocation rule cannot serve them.
caio-pizzol added a commit that referenced this pull request May 5, 2026
…(SD-2864) (#3161)

* refactor(types): remove _internal-shims.d.ts soft-landing mechanism (SD-2942)

After SD-2893 drained every shim entry to zero, the auto-generated
_internal-shims.d.ts file ships empty (header comments only). The
auto-capture mechanism that wrote it is no longer load-bearing: it
was a soft fallback that captured any unrelocated private @superdoc/*
specifier in dist d.ts files and silently shimmed it as `any`. With
the relocation rules + RULE1_ALLOWLIST + UNSHIMMED_PRIVATE_SPECIFIERS
now covering the entire workspace surface, that soft path mostly
swallows new private leaks instead of failing the build.

This change makes new leaks fail loudly:

- ensure-types.cjs: drop the workspace-imports scanning loops, the
  shim-file write, the triple-slash reference injection, and the
  SHIM_FORBIDDEN regression net (now redundant with the relocation
  rules + audit Rule 1). Add an explicit unlink for any stale
  _internal-shims.d.ts left over from prior builds.
- audit-declarations.cjs: update the rule documentation. Rule 1 now
  fails for any unrelocated private @superdoc/* specifier; Rule 3
  becomes a no-op in steady state (kept as defense against stale
  tarballs or future re-introduction). The internalShimsPresent
  graceful-handling already existed in audit code; no behavioral
  change there.

A future PR that introduces a new private @superdoc/* import on the
public surface fails audit Rule 1 at build time. Verified with a
synthetic injection: import('@superdoc/some-new-private-pkg').T in a
public-reachable d.ts produces FAIL findings: private-specifiers and
exits 1.

Net diff: -167 +41 lines across the two scripts.

Verified: build:es clean (10 guarded packages, no shim file emitted),
consumer matrix 47/0/0, runtime smoke 4/4, dist has zero
_internal-shims references, negative test confirms hard-landing.

* docs(types): fix stale comment about @superdoc/common shim path (SD-2942)

The comment above the inline-replacement block was inherited from the
pre-SD-2893 era and described two things that are no longer true after
the shim drain:

1. "fall through to the ambient shim block below" — SD-2942 (this PR)
   removes the shim block, so non-main-entry @superdoc/common imports
   now resolve via the RELOCATION_RULES rewriter, not via a fallback
   shim.
2. "Comment, CommentContent, CommentJSON ... not on the public surface"
   — SD-2893 stack 6 (PR #3154) relocated these types via the bare
   @superdoc/common rule mapping to comments-types.d.ts. `Comment` is
   now publicly importable as
   `import type { Comment } from 'superdoc/super-editor'`.

Replace the block with a description of what the inline-replacement
step actually does today: handle the main entry's runtime-value imports
(DOCX, PDF, HTML, getFileObject, compareVersions, BlankDOCX) which are
not type-only and so the relocation rule cannot serve them.

* refactor(types): centralize public-surface taxonomy in single config (SD-2864)

The same workspace-relocation taxonomy was duplicated across four files:
ensure-types.cjs, audit-declarations.cjs, vite.config.js, and tsconfig.json.
Adding a new public-surface relocation required coordinated edits in all
four. PR #3144 (pm-adapter) and several SD-2893 stack PRs each shipped a
regression caused by drift between these lists.

Add packages/superdoc/scripts/type-surface.config.cjs as the single source
of truth and refactor each consumer to derive what it needs.

Consumer changes:

- ensure-types.cjs: derives RELOCATION_RULES, RELOCATION_GUARD_PACKAGES,
  UNSHIMMED_PRIVATE_SPECIFIERS, SHARED_COMMON_DTS_TARGETS,
  requiredEntryPoints, and HANDWRITTEN_DTS_BLOCKLIST from the config.
- audit-declarations.cjs: derives RELOCATION_GUARD_PACKAGES and
  RULE1_ALLOWLIST from the config.
- vite.config.js: derives the dts include list by spreading
  relocations[*].viteIncludes after the foundational base entries (uses
  createRequire to load the CJS config from ESM Vite config).
- tsconfig.json stays hand-edited (it's plain JSON), but a new
  check-tsconfig-type-surface.cjs script enforces parity by verifying
  every relocation's tsconfigIncludes paths are present in tsconfig.json's
  include array. Wired into postbuild so drift fails the build.

Net diff: -138 +47 lines across the consumer scripts plus +208 lines for
the new config + parity check. The config is the authoritative taxonomy;
the parity check is the safety net that makes accidental drift loud.

Verified: build:es clean (10 guarded packages, no shim file emitted),
consumer matrix 47/0/0, declaration audit clean. Negative drift test:
removing pm-adapter entries from tsconfig.json's include makes the parity
check exit 1 with a clear message naming the missing entries and the
relocation that requires them; restoring exits 0.

* refactor(types): derive blocklist and tsc-postbuild targets from config (SD-2864)

The previous commit's claim that these two lists derive from
type-surface.config.cjs was wrong: the inline literals in
ensure-types.cjs were never replaced. The build kept passing because
the values matched, but a contributor editing the config without also
editing the script would silently land a half-applied change.

Replace the inline `new Set([...])` for HANDWRITTEN_DTS_BLOCKLIST and
the inline string array for SHARED_COMMON_DTS_TARGETS with references
to the config's handwrittenDtsBlocklist and sharedCommonDtsTargets so
the original commit's claims hold.

Also annotate the two @superdoc/common relocation entries' empty
viteIncludes/tsconfigIncludes arrays inline so a reader does not have
to walk back to the module-level JSDoc to learn they are emitted via
the tsc-postbuild path.

* refactor(types): derive requiredEntryPoints from config (SD-2864)

The previous fix commit caught HANDWRITTEN_DTS_BLOCKLIST and
SHARED_COMMON_DTS_TARGETS but missed requiredEntryPoints, which
remained inline. With this commit all three lists in ensure-types.cjs
that the SD-2864 PR description claims to derive from the config
actually do.

Verified: build clean, the three list lengths read from
type-surface.config.cjs match what was previously hardcoded
(requiredEntryPoints: 4, sharedCommonDtsTargets: 3,
handwrittenDtsBlocklist: 1).

* fix(types): tsconfig parity check now bidirectional (SD-2864)

The original check only fired on missing-entry drift (config requires
X, tsconfig is missing X). It tolerated stale-entry drift (tsconfig
has Y, config no longer requires Y), undermining the single-source-of-
truth claim: a relocation removed from type-surface.config.cjs could
leave a stale tsconfig include compiling against source the type
surface no longer claims to manage.

Add baseTsconfigIncludes to type-surface.config.cjs for the
foundational source roots that aren't relocations
(`src`, `../super-editor/src`, `../document-api/src`). The check now
asserts tsconfig.include equals exactly baseTsconfigIncludes plus
relocations[*].tsconfigIncludes - no more, no less.

Catches three drift modes now:
  1. New relocation in config but not mirrored in tsconfig.
  2. Relocation removed from config but tsconfig entry left stale.
  3. Foundational base entry dropped from tsconfig by mistake.

Verified end-to-end:
  - Clean build passes (12 expected paths matched exactly)
  - Synthetic missing-entry drift exits 1 with named owner
  - Synthetic stale-entry drift exits 1 with remediation hint
  - Restored exits 0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants