Summary
The published sails-js npm tarball ships .d.ts files containing unresolved external module references to sails-js-types, which is a private: true workspace package not published to npm and not declared as a peerDependency. Consumers cannot resolve these imports directly; they rely on either skipLibCheck: true or the ./types subpath (which IS bundled correctly via the dts rollup step).
Status
| File |
Origin |
Fixed? |
lib/index.d.ts:12 (export type * from 'sails-js-types') |
added in #1343 |
✅ Fixed in #1343 by re-exporting from the bundled ./types.js instead of the workspace package name (commit on feat/js-public-user-type-accessors-1320). |
lib/sails-idl-v2.d.ts:128 (get program(): import(\"sails-js-types\").IProgramUnit) |
pre-existing |
❌ Still leaks. Emitted by rollup-plugin-typescript2 from the source import type { IProgramUnit } from './types.js' chain when TS preserves the original module specifier. |
lib/util.d.ts:1 (import { ISailsTypeDef } from 'sails-js-types') |
pre-existing |
❌ Still leaks. Built via the dts rollup step from node_modules/sails-js-util/lib/index.d.ts, which itself imports from sails-js-types. The dts plugin didn't inline the cross-package reference. |
lib/parser.d.ts:1 (import { IIdlDoc, IInterfaceId, InterfaceIdInput } from 'sails-js-types') |
pre-existing |
❌ Still leaks. Same dts-plugin pass as util.d.ts. |
Why this matters
- Consumers running with
skipLibCheck: false (less common, but valid) get type-resolution errors when they import from sails-js, sails-js/util, or sails-js/parser.
- The
./types subpath works correctly because lib/types.d.ts is built via the dts plugin from node_modules/sails-js-types/lib/index.d.ts and the externals get inlined there. The other paths above don't get the same treatment.
sails-js-types being private: true is the right call (it's an internal workspace package), so the fix is on the build side, not the publishing side.
Reproduction
cd js && pnpm install && pnpm build:types && pnpm build:util && pnpm build:parser-idl-v2 && pnpm build:sails
grep -rn "sails-js-types" lib/ | grep -v /cjs/
After the #1343 fix, expect 3 matches: lib/sails-idl-v2.d.ts, lib/util.d.ts, lib/parser.d.ts. None of them should land in the tarball.
Suggested fix
Two parallel changes to the rollup pipeline:
-
Add a post-typescript dts pass for lib/index.d.ts and lib/sails-idl-v2.d.ts (and any other entry that goes through rollup-plugin-typescript2). The pass takes the typescript-emitted .d.ts as input and runs it through dts() so external 'sails-js-types' imports get inlined the way they already are for lib/types.d.ts.
-
Fix the existing dts pass for util.d.ts and parser.d.ts so the sails-js-types references they pull in transitively get inlined too. Likely a missing respectExternal: false (or equivalent) option on the dts plugin invocation in js/rollup.config.js. Currently the dts step pulls from node_modules/sails-js-util/lib/index.d.ts, which still imports from sails-js-types — that import isn't getting walked.
Pseudocode for #1:
// rollup.config.js — add after the existing typescript-pass entries
{
input: 'lib/index.d.ts',
output: [{ file: 'lib/index.d.ts', format: 'es' }],
plugins: [nodeResolve({ extensions: ['.d.ts', '.ts'] }), dts()],
}
// And similar for lib/sails-idl-v2.d.ts (or any specific entry whose
// public surface re-exports through sails-js-types).
Alternative for both: drop private: true from sails-js-types and add it as a real published dep / peerDep of sails-js. Larger surface change, exposes a package's release lifecycle that's currently internal — probably not preferred.
Out of scope
- Publishing
sails-js-types as a standalone npm package.
- Restructuring AST type ownership.
Discovered during
Pre-landing review of #1343 (issue #1320). The PR added a fourth instance of the pattern (export type * from 'sails-js-types' in the index) which was caught by codex review and fixed in-place via Codex's suggestion to re-export from ./types.js. The three remaining leaks predate that PR.
Summary
The published
sails-jsnpm tarball ships.d.tsfiles containing unresolved external module references tosails-js-types, which is aprivate: trueworkspace package not published to npm and not declared as apeerDependency. Consumers cannot resolve these imports directly; they rely on eitherskipLibCheck: trueor the./typessubpath (which IS bundled correctly via thedtsrollup step).Status
lib/index.d.ts:12(export type * from 'sails-js-types')./types.jsinstead of the workspace package name (commit onfeat/js-public-user-type-accessors-1320).lib/sails-idl-v2.d.ts:128(get program(): import(\"sails-js-types\").IProgramUnit)rollup-plugin-typescript2from the sourceimport type { IProgramUnit } from './types.js'chain when TS preserves the original module specifier.lib/util.d.ts:1(import { ISailsTypeDef } from 'sails-js-types')dtsrollup step fromnode_modules/sails-js-util/lib/index.d.ts, which itself imports fromsails-js-types. Thedtsplugin didn't inline the cross-package reference.lib/parser.d.ts:1(import { IIdlDoc, IInterfaceId, InterfaceIdInput } from 'sails-js-types')util.d.ts.Why this matters
skipLibCheck: false(less common, but valid) get type-resolution errors when theyimportfromsails-js,sails-js/util, orsails-js/parser../typessubpath works correctly becauselib/types.d.tsis built via thedtsplugin fromnode_modules/sails-js-types/lib/index.d.tsand the externals get inlined there. The other paths above don't get the same treatment.sails-js-typesbeingprivate: trueis the right call (it's an internal workspace package), so the fix is on the build side, not the publishing side.Reproduction
After the #1343 fix, expect 3 matches:
lib/sails-idl-v2.d.ts,lib/util.d.ts,lib/parser.d.ts. None of them should land in the tarball.Suggested fix
Two parallel changes to the rollup pipeline:
Add a post-typescript dts pass for
lib/index.d.tsandlib/sails-idl-v2.d.ts(and any other entry that goes throughrollup-plugin-typescript2). The pass takes the typescript-emitted.d.tsas input and runs it throughdts()so external'sails-js-types'imports get inlined the way they already are forlib/types.d.ts.Fix the existing
dtspass forutil.d.tsandparser.d.tsso thesails-js-typesreferences they pull in transitively get inlined too. Likely a missingrespectExternal: false(or equivalent) option on thedtsplugin invocation injs/rollup.config.js. Currently the dts step pulls fromnode_modules/sails-js-util/lib/index.d.ts, which still imports fromsails-js-types— that import isn't getting walked.Pseudocode for #1:
Alternative for both: drop
private: truefromsails-js-typesand add it as a real published dep / peerDep ofsails-js. Larger surface change, exposes a package's release lifecycle that's currently internal — probably not preferred.Out of scope
sails-js-typesas a standalone npm package.Discovered during
Pre-landing review of #1343 (issue #1320). The PR added a fourth instance of the pattern (
export type * from 'sails-js-types'in the index) which was caught bycodex reviewand fixed in-place via Codex's suggestion to re-export from./types.js. The three remaining leaks predate that PR.