Socket
Socket
Sign inDemoInstall

@ts-bridge/cli

Package Overview
Dependencies
Maintainers
1
Versions
14
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@ts-bridge/cli - npm Package Compare versions

Comparing version 0.1.1 to 0.1.2

16

CHANGELOG.md

@@ -10,2 +10,15 @@ # Changelog

## [0.1.2]
### Changed
- Bump minimum TypeScript version to 4.8 ([#12](https://github.com/ts-bridge/ts-bridge/pull/12))
- The tool was already incompatible with TypeScript versions older than 4.8,
but this change makes the minimum version explicit.
### Fixed
- Add transformer to remove type imports and exports ([#10](https://github.com/ts-bridge/ts-bridge/pull/10))
- This fixes compatibility with TypeScript 4.8 and later in certain cases.
## [0.1.1]

@@ -29,4 +42,5 @@

[Unreleased]: https://github.com/ts-bridge/ts-bridge/compare/@ts-bridge/cli@0.1.1...HEAD
[Unreleased]: https://github.com/ts-bridge/ts-bridge/compare/@ts-bridge/cli@0.1.2...HEAD
[0.1.2]: https://github.com/ts-bridge/ts-bridge/compare/@ts-bridge/cli@0.1.1...@ts-bridge/cli@0.1.2
[0.1.1]: https://github.com/ts-bridge/ts-bridge/compare/@ts-bridge/cli@0.1.0...@ts-bridge/cli@0.1.1
[0.1.0]: https://github.com/ts-bridge/ts-bridge/releases/tag/@ts-bridge/cli@0.1.0

3

dist/build.js

@@ -11,3 +11,3 @@ import { dirname, join } from 'path';

import { executeSteps } from './steps.js';
import { getExportExtensionTransformer, getImportExtensionTransformer, getRequireExtensionTransformer, } from './transformers.js';
import { getTypeImportExportTransformer, getExportExtensionTransformer, getImportExtensionTransformer, getRequireExtensionTransformer, } from './transformers.js';
const { createProgram, getPreEmitDiagnostics, ModuleResolutionKind } = typescript;

@@ -234,2 +234,3 @@ /**

getExportExtensionTransformer(extension, options),
getTypeImportExportTransformer(options),
...getTransformers(type, options),

@@ -236,0 +237,0 @@ ],

@@ -695,3 +695,3 @@ import { evaluate, getMockNodeModule, getMockPackageJson, getMockTsConfig, getVirtualEnvironment, noOp, } from '@ts-bridge/test-utils';

module: 'ES2022',
moduleResolution: 'Node10',
moduleResolution: 'Node',
},

@@ -719,3 +719,3 @@ }),

module: 'ES2022',
moduleResolution: 'Node10',
moduleResolution: 'Node',
},

@@ -722,0 +722,0 @@ }),

@@ -1,2 +0,2 @@

import type { CompilerOptions, TypeChecker, Node, SourceFile, ImportDeclaration, Statement, System } from 'typescript';
import type { CompilerOptions, TypeChecker, Node, SourceFile, ImportDeclaration, Statement, System, ExportDeclaration } from 'typescript';
import typescript from 'typescript';

@@ -85,2 +85,18 @@ /**

/**
* Get the import declaration without type-only imports.
*
* @param node - The import declaration node.
* @returns The import declaration without type-only imports. If there are no
* type-only imports, the node is returned as is.
*/
export declare function getNonTypeImports(node: ImportDeclaration): ImportDeclaration | undefined;
/**
* Get the export declaration without type-only exports.
*
* @param node - The export declaration node.
* @returns The export declaration without type-only exports. If there are no
* type-only exports, the node is returned as is.
*/
export declare function getNonTypeExports(node: ExportDeclaration): ExportDeclaration | undefined;
/**
* Create a namespace import, e.g.:

@@ -87,0 +103,0 @@ *

@@ -8,3 +8,3 @@ import chalk from 'chalk';

import { getIdentifierName } from './utils.js';
const { factory, isNamespaceImport, isStringLiteral, NodeFlags, resolveModuleName, SymbolFlags, SyntaxKind, } = typescript;
const { factory, isNamedExports, isNamedImports, isNamespaceImport, isStringLiteral, NodeFlags, resolveModuleName, SymbolFlags, SyntaxKind, } = typescript;
/**

@@ -175,2 +175,37 @@ * Get the new import path for the given file and import path. This function

/**
* Get the import declaration without type-only imports.
*
* @param node - The import declaration node.
* @returns The import declaration without type-only imports. If there are no
* type-only imports, the node is returned as is.
*/
export function getNonTypeImports(node) {
if (!node.importClause?.namedBindings ||
!isNamedImports(node.importClause.namedBindings)) {
return node;
}
const elements = node.importClause.namedBindings.elements.filter((element) => !element.isTypeOnly);
if (elements.length === 0) {
return undefined;
}
return factory.updateImportDeclaration(node, node.modifiers, factory.updateImportClause(node.importClause, false, node.importClause.name, factory.updateNamedImports(node.importClause.namedBindings, elements)), node.moduleSpecifier, node.attributes);
}
/**
* Get the export declaration without type-only exports.
*
* @param node - The export declaration node.
* @returns The export declaration without type-only exports. If there are no
* type-only exports, the node is returned as is.
*/
export function getNonTypeExports(node) {
if (!node.exportClause || !isNamedExports(node.exportClause)) {
return node;
}
const elements = node.exportClause.elements.filter((element) => !element.isTypeOnly);
if (elements.length === 0) {
return undefined;
}
return factory.updateExportDeclaration(node, node.modifiers, false, factory.updateNamedExports(node.exportClause, elements), node.moduleSpecifier, node.attributes);
}
/**
* Create a namespace import, e.g.:

@@ -177,0 +212,0 @@ *

import { getMockNodeModule, getMockPackageJson, getVirtualEnvironment, noOp, } from '@ts-bridge/test-utils';
import typescript from 'typescript';
import { describe, expect, it, vi } from 'vitest';
import { getImportMetaUrl, getImportPath, getNamedImportNodes, getNamespaceImport, getUniqueIdentifier, } from './generator.js';
import { getImportMetaUrl, getImportPath, getNamedImportNodes, getNamespaceImport, getNonTypeExports, getNonTypeImports, getUniqueIdentifier, } from './generator.js';
const { factory } = typescript;

@@ -334,2 +334,70 @@ /**

});
describe('getNonTypeImports', () => {
it('removes type imports from an import declaration', () => {
const importDeclaration = factory.createImportDeclaration(undefined, factory.createImportClause(false, undefined, factory.createNamedImports([
factory.createImportSpecifier(true, undefined, factory.createIdentifier('foo')),
factory.createImportSpecifier(false, undefined, factory.createIdentifier('bar')),
])), factory.createStringLiteral('foo'), undefined);
const result = getNonTypeImports(importDeclaration);
expect(result).not.toBeUndefined();
expect(result).not.toStrictEqual(importDeclaration);
expect(compile(result)).toMatchInlineSnapshot(`
""use strict";
import { bar } from "foo";
"
`);
});
it('returns the same node if the import declaration is not a named import', () => {
const importDeclaration = factory.createImportDeclaration(undefined, factory.createImportClause(false, undefined, factory.createNamespaceImport(factory.createIdentifier('foo'))), factory.createStringLiteral('bar'), undefined);
const result = getNonTypeImports(importDeclaration);
expect(result).toBe(importDeclaration);
});
it('returns the same node if there is no import clause', () => {
const importDeclaration = factory.createImportDeclaration(undefined, undefined, factory.createStringLiteral('foo'), undefined);
const result = getNonTypeImports(importDeclaration);
expect(result).toBe(importDeclaration);
});
it('returns `undefined` if there are no non-type named imports', () => {
const importDeclaration = factory.createImportDeclaration(undefined, factory.createImportClause(false, undefined, factory.createNamedImports([
factory.createImportSpecifier(true, undefined, factory.createIdentifier('foo')),
factory.createImportSpecifier(true, undefined, factory.createIdentifier('bar')),
])), factory.createStringLiteral('bar'), undefined);
const result = getNonTypeImports(importDeclaration);
expect(result).toBeUndefined();
});
});
describe('getNonTypeExports', () => {
it('removes type exports from an export declaration', () => {
const exportDeclaration = factory.createExportDeclaration(undefined, false, factory.createNamedExports([
factory.createExportSpecifier(true, undefined, factory.createIdentifier('foo')),
factory.createExportSpecifier(false, undefined, factory.createIdentifier('bar')),
]));
const result = getNonTypeExports(exportDeclaration);
expect(result).not.toBeUndefined();
expect(result).not.toStrictEqual(exportDeclaration);
expect(compile(result)).toMatchInlineSnapshot(`
""use strict";
export { bar };
"
`);
});
it('returns the same node if the export declaration is not a named export', () => {
const exportDeclaration = factory.createExportDeclaration(undefined, false, factory.createNamespaceExport(factory.createIdentifier('foo')));
const result = getNonTypeExports(exportDeclaration);
expect(result).toBe(exportDeclaration);
});
it('returns the same node if there is no export clause', () => {
const exportDeclaration = factory.createExportDeclaration(undefined, false, undefined);
const result = getNonTypeExports(exportDeclaration);
expect(result).toBe(exportDeclaration);
});
it('returns `undefined` if there are no non-type named exports', () => {
const exportDeclaration = factory.createExportDeclaration(undefined, false, factory.createNamedExports([
factory.createExportSpecifier(true, undefined, factory.createIdentifier('foo')),
factory.createExportSpecifier(true, undefined, factory.createIdentifier('bar')),
]));
const result = getNonTypeExports(exportDeclaration);
expect(result).toBeUndefined();
});
});
describe('getNamespaceImport', () => {

@@ -336,0 +404,0 @@ it('returns a namespace import', () => {

@@ -174,2 +174,19 @@ import type { CustomTransformer, ResolutionMode, SourceFile, System, TransformationContext, Transformer, TypeChecker } from 'typescript';

/**
* Get a transformer that removes type-only imports and exports. This is the
* standard behaviour for TypeScript 5.x, but this transformer is needed for
* TypeScript 4.x. This may be a bug in TypeScript 4.x's compiler API.
*
* For example, the following type-only imports and exports:
* ```ts
* import type { Foo } from 'module';
* export type { Foo };
* ```
*
* will be removed.
*
* @param _context - The transformer options. This is not used.
* @returns The transformer function.
*/
export declare function getTypeImportExportTransformer(_context: TransformerOptions): (context: TransformationContext) => Transformer<SourceFile>;
/**
* Get a custom transformer that sets the target module kind for the source

@@ -176,0 +193,0 @@ * file.

import typescript from 'typescript';
import { getImportMetaUrl, getImportPath, getNamedImportNodes, getNamespaceImport, getUniqueIdentifier, isGlobal, } from './generator.js';
import { getImportMetaUrl, getImportPath, getNamedImportNodes, getNamespaceImport, getNonTypeExports, getNonTypeImports, getUniqueIdentifier, isGlobal, } from './generator.js';
import { CJS_SHIMS_PACKAGE, ESM_REQUIRE_SHIMS_PACKAGE, ESM_SHIMS_PACKAGE, } from './shims.js';

@@ -355,2 +355,40 @@ const { factory, isBindingElement, isCallExpression, isExportDeclaration, isFunctionDeclaration, isIdentifier, isImportDeclaration, isMetaProperty, isPropertyAccessExpression, isStringLiteral, isVariableDeclaration, visitEachChild, visitNode, SyntaxKind, } = typescript;

/**
* Get a transformer that removes type-only imports and exports. This is the
* standard behaviour for TypeScript 5.x, but this transformer is needed for
* TypeScript 4.x. This may be a bug in TypeScript 4.x's compiler API.
*
* For example, the following type-only imports and exports:
* ```ts
* import type { Foo } from 'module';
* export type { Foo };
* ```
*
* will be removed.
*
* @param _context - The transformer options. This is not used.
* @returns The transformer function.
*/
export function getTypeImportExportTransformer(_context) {
return (context) => {
return (sourceFile) => {
const visitor = (node) => {
if (isImportDeclaration(node)) {
if (node.importClause?.isTypeOnly) {
return undefined;
}
return getNonTypeImports(node);
}
if (isExportDeclaration(node)) {
if (node.isTypeOnly) {
return undefined;
}
return getNonTypeExports(node);
}
return visitEachChild(node, visitor, context);
};
return visitNode(sourceFile, visitor);
};
};
}
/**
* Get a custom transformer that sets the target module kind for the source

@@ -357,0 +395,0 @@ * file.

import { getMockNodeModule, getVirtualEnvironment, } from '@ts-bridge/test-utils';
import { describe, expect, it } from 'vitest';
import { getBuildTypeOptions } from './build-type.js';
import { getExportExtensionTransformer, getGlobalsTransformer, getImportExtensionTransformer, getImportMetaTransformer, getNamedImportTransformer, getRequireExtensionTransformer, getRequireTransformer, getTargetTransformer, } from './transformers.js';
import { getExportExtensionTransformer, getGlobalsTransformer, getImportExtensionTransformer, getImportMetaTransformer, getNamedImportTransformer, getRequireExtensionTransformer, getRequireTransformer, getTargetTransformer, getTypeImportExportTransformer, } from './transformers.js';
/**

@@ -1031,1 +1031,50 @@ * Compile a string of (TypeScript) code to JavaScript, and return the compiled

});
describe('getTypeImportExportTransformer', () => {
it('removes type imports and exports', async () => {
const environment = getVirtualEnvironment({
files: {
'/index.ts': `
import type { foo } from './foo';
export type { foo } from './foo';
`,
'/foo.ts': 'export type foo = "bar";',
},
});
expect(await compile({
format: 'module',
environment,
transformer: getTypeImportExportTransformer({
typeChecker: environment.typeChecker,
system: environment.system,
baseDirectory: '/',
}),
})).toMatchInlineSnapshot(`
"export {};
"
`);
});
it('removes named type imports and exports', async () => {
const environment = getVirtualEnvironment({
files: {
'/index.ts': `
import { type foo } from './foo';
import type { bar } from './foo';
export { type foo, bar } from './foo';
`,
'/foo.ts': 'export type foo = "bar"; export const bar = "baz";',
},
});
expect(await compile({
format: 'module',
environment,
transformer: getTypeImportExportTransformer({
typeChecker: environment.typeChecker,
system: environment.system,
baseDirectory: '/',
}),
})).toMatchInlineSnapshot(`
"export { bar } from './foo';
"
`);
});
});
{
"name": "@ts-bridge/cli",
"version": "0.1.1",
"version": "0.1.2",
"description": "Bridge the gap between ES modules and CommonJS modules with an easy-to-use alternative to `tsc`.",

@@ -64,3 +64,3 @@ "keywords": [

"@ts-bridge/shims": "^0.1.1",
"typescript": ">=4.0.0"
"typescript": ">=4.8.0"
},

@@ -67,0 +67,0 @@ "peerDependenciesMeta": {

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc