Skip to content

Commit

Permalink
feature(type-compiler): support esm module
Browse files Browse the repository at this point in the history
makes sure that 'typescript' imports are not named (because that's not supported in esm node).

fixes #316
  • Loading branch information
marcj committed Apr 16, 2023
1 parent ba7c68e commit 48de497
Show file tree
Hide file tree
Showing 5 changed files with 94 additions and 86 deletions.
120 changes: 62 additions & 58 deletions packages/type-compiler/src/compiler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,8 @@
* You should have received a copy of the MIT License along with this program.
*/

import * as ts from 'typescript';
import {
import type {
__String,
addSyntheticLeadingComment,
ArrayTypeNode,
ArrowFunction,
Bundle,
Expand All @@ -25,92 +23,39 @@ import {
ConstructorDeclaration,
ConstructorTypeNode,
ConstructSignatureDeclaration,
createCompilerHost,
createPrinter,
CustomTransformer,
CustomTransformerFactory,
Declaration,
EmitHint,
EntityName,
EnumDeclaration,
escapeLeadingUnderscores,
ExportDeclaration,
Expression,
ExpressionWithTypeArguments,
FunctionDeclaration,
FunctionExpression,
FunctionTypeNode,
getEffectiveConstraintOfTypeParameter,
getJSDocTags,
Identifier,
ImportDeclaration,
IndexedAccessTypeNode,
IndexSignatureDeclaration,
InferTypeNode,
InterfaceDeclaration,
IntersectionTypeNode,
isArrayTypeNode,
isArrowFunction,
isCallExpression,
isCallSignatureDeclaration,
isClassDeclaration,
isClassExpression,
isConstructorDeclaration,
isConstructorTypeNode,
isConstructSignatureDeclaration,
isEnumDeclaration,
isExportDeclaration,
isExpressionWithTypeArguments,
isFunctionDeclaration,
isFunctionExpression,
isFunctionLike,
isIdentifier,
isImportClause,
isImportDeclaration,
isImportSpecifier,
isInferTypeNode,
isInterfaceDeclaration,
isMethodDeclaration,
isMethodSignature,
isModuleDeclaration,
isNamedExports,
isNamedTupleMember,
isNewExpression,
isObjectLiteralExpression,
isOptionalTypeNode,
isParameter,
isParenthesizedExpression,
isParenthesizedTypeNode,
isPropertyAccessExpression,
isQualifiedName,
isSourceFile,
isStringLiteral,
isTypeAliasDeclaration,
isTypeParameterDeclaration,
isTypeQueryNode,
isTypeReferenceNode,
isUnionTypeNode,
isVariableDeclaration,
LiteralTypeNode,
MappedTypeNode,
MethodDeclaration,
MethodSignature,
Modifier,
ModifierFlags,
ModuleDeclaration,
ModuleKind,
Node,
NodeFactory,
NodeFlags,
PropertyAccessExpression,
PropertyDeclaration,
PropertySignature,
QualifiedName,
RestTypeNode,
ScriptTarget,
SignatureDeclaration,
Statement,
SyntaxKind,
TemplateLiteralTypeNode,
TransformationContext,
TupleTypeNode,
Expand All @@ -123,9 +68,9 @@ import {
TypeQueryNode,
TypeReferenceNode,
UnionTypeNode,
visitEachChild,
visitNode
} from 'typescript';
import * as ts from 'typescript';

import {
ensureImportIsEmitted,
extractJSDocAttribute,
Expand All @@ -149,6 +94,65 @@ import { knownLibFilesForCompilerOptions } from '@typescript/vfs';
import { contains } from 'micromatch';
import { parseTsconfig } from 'get-tsconfig';

const {
visitEachChild,
visitNode,
isArrayTypeNode,
isArrowFunction,
isCallExpression,
isCallSignatureDeclaration,
isClassDeclaration,
isClassExpression,
isConstructorDeclaration,
isConstructorTypeNode,
isConstructSignatureDeclaration,
isEnumDeclaration,
isExportDeclaration,
isExpressionWithTypeArguments,
isFunctionDeclaration,
isFunctionExpression,
isFunctionLike,
isIdentifier,
isImportClause,
isImportDeclaration,
isImportSpecifier,
isInferTypeNode,
isInterfaceDeclaration,
isMethodDeclaration,
isMethodSignature,
isModuleDeclaration,
isNamedExports,
isNamedTupleMember,
isNewExpression,
isObjectLiteralExpression,
isOptionalTypeNode,
isParameter,
isParenthesizedExpression,
isParenthesizedTypeNode,
isPropertyAccessExpression,
isQualifiedName,
isSourceFile,
isStringLiteral,
isTypeAliasDeclaration,
isTypeParameterDeclaration,
isTypeQueryNode,
isTypeReferenceNode,
isUnionTypeNode,
isVariableDeclaration,
getEffectiveConstraintOfTypeParameter,
getJSDocTags,
addSyntheticLeadingComment,
createCompilerHost,
createPrinter,
escapeLeadingUnderscores,
EmitHint,
NodeFlags,
SyntaxKind,
ModuleKind,
ScriptTarget,
ModifierFlags,
} = ts;

export function encodeOps(ops: ReflectionOp[]): string {
return ops.map(v => String.fromCharCode(v + 33)).join('');
}
Expand Down
10 changes: 4 additions & 6 deletions packages/type-compiler/src/loader.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,14 @@
// import {urlToRequest} from 'loader-utils';
import type { CompilerOptions, SourceFile, TransformationContext } from 'typescript';
import * as ts from 'typescript';
import { CompilerOptions, createCompilerHost, createSourceFile, ScriptTarget, SourceFile, TransformationContext } from 'typescript';
import { ReflectionTransformer } from './compiler.js';
import ScriptKind = ts.ScriptKind;

export class DeepkitLoader {
protected options: CompilerOptions = {
allowJs: true,
declaration: false,
};

protected host = createCompilerHost(this.options);
protected host = ts.createCompilerHost(this.options);

protected program = ts.createProgram([], this.options, this.host);

Expand All @@ -31,15 +29,15 @@ export class DeepkitLoader {
};

const originalGetSourceFile = this.host.getSourceFile;
this.host.getSourceFile = (fileName: string, languageVersion: ScriptTarget, onError?: (message: string) => void, shouldCreateNewSourceFile?: boolean): SourceFile | undefined => {
this.host.getSourceFile = (fileName: string, languageVersion: ts.ScriptTarget, onError?: (message: string) => void, shouldCreateNewSourceFile?: boolean): SourceFile | undefined => {
if (this.sourceFiles[fileName]) return this.sourceFiles[fileName];
return originalGetSourceFile.call(this.host, fileName, languageVersion, onError, shouldCreateNewSourceFile);
};
}

transform(source: string, path: string): string {
this.knownFiles[path] = source;
const sourceFile = createSourceFile(path, source, ScriptTarget.ESNext, true, path.endsWith('.tsx') ? ScriptKind.TSX : ScriptKind.TS);
const sourceFile = ts.createSourceFile(path, source, ts.ScriptTarget.ESNext, true, path.endsWith('.tsx') ? ts.ScriptKind.TSX : ts.ScriptKind.TS);
let newSource = source;

ts.transform(sourceFile, [
Expand Down
33 changes: 18 additions & 15 deletions packages/type-compiler/src/reflection-ast.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
* You should have received a copy of the MIT License along with this program.
*/

import {
import type {
ArrowFunction,
BigIntLiteral,
BinaryExpression,
Expand All @@ -17,38 +17,41 @@ import {
Expression,
Identifier,
ImportDeclaration,
isArrowFunction,
isComputedPropertyName,
isIdentifier,
isNamedImports,
isNumericLiteral,
isPrivateIdentifier,
isStringLiteral,
isStringLiteralLike,
JSDoc,
ModifierLike,
Node,
NodeArray,
NodeFactory,
NodeFlags,
NumericLiteral,
PrivateIdentifier,
PropertyAccessExpression,
QualifiedName,
setOriginalNode,
StringLiteral,
StringLiteralLike,
SymbolTable,
SyntaxKind,
unescapeLeadingUnderscores
} from 'typescript';
import * as ts from 'typescript';
import { cloneNode as tsNodeClone, CloneNodeHook } from '@marcj/ts-clone-node';
import { SourceFile } from './ts-types.js';

const {
isArrowFunction,
isComputedPropertyName,
isIdentifier,
isNamedImports,
isNumericLiteral,
isPrivateIdentifier,
isStringLiteral,
isStringLiteralLike,
setOriginalNode,
NodeFlags,
SyntaxKind
} = ts;

export type PackExpression = Expression | string | number | boolean | bigint;

export function getIdentifierName(node: Identifier | PrivateIdentifier): string {
return unescapeLeadingUnderscores(node.escapedText);
return ts.unescapeLeadingUnderscores(node.escapedText);
}

export function joinQualifiedName(name: EntityName): string {
Expand Down Expand Up @@ -101,7 +104,7 @@ export function getNameAsString(node?: Identifier | StringLiteral | NumericLiter
return joinQualifiedName(node);
}

export function hasModifier(node: { modifiers?: NodeArray<ModifierLike> }, modifier: SyntaxKind): boolean {
export function hasModifier(node: { modifiers?: NodeArray<ModifierLike> }, modifier: ts.SyntaxKind): boolean {
if (!node.modifiers) return false;
return node.modifiers.some(v => v.kind === modifier);
}
Expand Down
15 changes: 9 additions & 6 deletions packages/type-compiler/src/resolver.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,21 @@
import * as ts from 'typescript';
import {
import type {
CompilerHost,
CompilerOptions,
createSourceFile,
ExportDeclaration,
Expression,
ImportDeclaration,
resolveModuleName,
ResolvedModule,
ScriptTarget,
SourceFile,
StringLiteral,
SyntaxKind
} from 'typescript';
import * as ts from 'typescript';

const {
createSourceFile,
resolveModuleName,
SyntaxKind,
ScriptTarget,
} = ts;

/**
* A utility to resolve a module path and its declaration.
Expand Down
2 changes: 1 addition & 1 deletion packages/type-compiler/src/ts-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
//Certain interfaces do not contain all properties/methods from all internal TS types, because we add only those we actually use.
//This helps to identity which types are actually needed and maybe can be brought up to the TS team as candidates to make them public.

import { SourceFile as TSSourceFile, Symbol, SymbolTable } from 'typescript';
import type { SourceFile as TSSourceFile, Symbol, SymbolTable } from 'typescript';

/**
* Contains @internal properties that are not yet in the public API of TS.
Expand Down

0 comments on commit 48de497

Please sign in to comment.