Security News
Research
Data Theft Repackaged: A Case Study in Malicious Wrapper Packages on npm
The Socket Research Team breaks down a malicious wrapper package that uses obfuscation to harvest credentials and exfiltrate sensitive data.
ts-expose-internals-conditionally
Advanced tools
Augment the TypeScript compiler module's types to expose hidden internal types when tsconfig.json contains "ts-expose-internals" in `customConditions`.
You’re probably better off using ts-expose-internals directly.
A simple fork of the excellent ts-expose-internals, but only activates when compiled with:
// tsconfig.json
{
"compilerOptions": {
"module": "nodenext", // or "node16" or "bundler" - must support package.json "exports"
"customConditions": ["ts-expose-internals"]
}
}
If you are publishing a library that uses ts-expose-internals in its implementation, and exposes some of TypeScript’s non-internal types in its API, your own declaration files will end up referencing ts-expose-internals:
// your-library/index.d.ts
/// <reference types="ts-expose-internals" />
import { CompilerOptions } from "typescript";
export function doSomethingWrappingTypeScript(
fileName: string,
typeScriptOptions: CompilerOptions
): unknown;
Even though CompilerOptions
is part of TypeScript’s public API, ts-expose-internals is a module augmentation that re-declares and augments everything in the typescript
module. So when tsc --declaration
notices that the CompilerOptions
you’re referencing in your own compilation is declared in "typescript"
but augmented in "ts-expose-internals"
, it adds an explicit reference to "ts-expose-internals"
to make sure everyone using your library sees the same CompilerOptions
that you do.
Normally, this is a very desirable behavior. Without it, users could end up with types in their node_modules
that reference things that don’t exist in their own compilation, leading to errors. But in the case of ts-expose-internals, you probably don’t want to expose all of TypeScript’s internals for all of your users. You want the internals when compiling your own implementation code, but your public API can be consumed without them.
By using ts-expose-internals-conditionally
and compiling with "customConditions": ["ts-expose-internals"]
in your tsconfig.json, your compilation will include the ts-expose-internals module augmentation, but your users’ compilations won’t (assuming they don’t also have "customConditions": ["ts-expose-internals"]
).
Of course, this is not safe, because if you accidentally reference anything internal that makes it into your declaration files, your users will get errors:
// your-library/index.d.ts
/// <reference types="ts-expose-internals-conditionally" />
// ^ references an empty file for users!
import { ModeAwareCache } from "typescript";
// ^^^^^^^^^^^^^^
// Module "typescript" has no exported member 'ModeAwareCache'.
To be safe, you should re-check your output declaration files without any customConditions
to ensure they’re portable.
dependencies
, not devDependencies
Since tsc --declaration
will emit a reference to "ts-expose-internals-conditionally"
in your declaration files, you need to ensure that reference actually resolves (to an empty file) for your users, which means they will need this package installed, which means it should go in your dependencies
, not your devDependencies
.
I thought I would get away with making a package with two tiny files:
// index.d.ts
/// <reference types="ts-expose-internals" />
// empty.d.ts
But it turns out that tsc --declaration
still emits a reference directly to "ts-expose-internals"
, even when it’s referenced transitively through this proxy package. This behavior actually makes sense, so I don’t think there was a way to do this without publishing an independent package.
FAQs
Augment the TypeScript compiler module's types to expose hidden internal types when tsconfig.json contains "ts-expose-internals" in `customConditions`.
The npm package ts-expose-internals-conditionally receives a total of 15,699 weekly downloads. As such, ts-expose-internals-conditionally popularity was classified as popular.
We found that ts-expose-internals-conditionally demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Research
The Socket Research Team breaks down a malicious wrapper package that uses obfuscation to harvest credentials and exfiltrate sensitive data.
Research
Security News
Attackers used a malicious npm package typosquatting a popular ESLint plugin to steal sensitive data, execute commands, and exploit developer systems.
Security News
The Ultralytics' PyPI Package was compromised four times in one weekend through GitHub Actions cache poisoning and failure to rotate previously compromised API tokens.