Skip to content

Commit

Permalink
feat: Updated library to support latest TypeScript & ts-node
Browse files Browse the repository at this point in the history
  • Loading branch information
nonara committed Oct 20, 2022
1 parent 1327824 commit cbeb29c
Show file tree
Hide file tree
Showing 26 changed files with 19,678 additions and 324 deletions.
19,157 changes: 19,157 additions & 0 deletions src/declarations/typescript4.7.d.ts

Large diffs are not rendered by default.

34 changes: 34 additions & 0 deletions src/harmony/harmony-factory.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import TS from "typescript";
import { TsTransformPathsContext } from "../types";
import { TsFourSeven, TsThreeEight } from "./versions";

/* ****************************************************************************************************************** */
// region: Types
/* ****************************************************************************************************************** */

export interface HarmonyFactory extends TS.NodeFactory {}

// endregion

/* ****************************************************************************************************************** */
// region: Utilities
/* ****************************************************************************************************************** */

/**
* Creates a node factory compatible with TS v3+
*/
export function createHarmonyFactory(context: TsTransformPathsContext): HarmonyFactory {
return new Proxy(context.tsFactory ?? context.tsInstance, {
get(target, prop) {
if (TsThreeEight.predicate(context)) {
return TsThreeEight.handler(context, prop);
} else if (TsFourSeven.predicate(context)) {
return TsFourSeven.handler(context, prop);
} else {
return (<any>target)[prop];
}
},
}) as HarmonyFactory;
}

// endregion
2 changes: 2 additions & 0 deletions src/harmony/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from "./versions";
export * from "./harmony-factory";
21 changes: 21 additions & 0 deletions src/harmony/utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/* ****************************************************************************************************************** */
// region: Utility Types
/* ****************************************************************************************************************** */
// @formatter:off

// @prettier-ignore
export type DownSampleTsTypes<TypeMap extends [any, any][], Tuple extends [...unknown[]]> = {
[i in keyof Tuple]: Tuple[i] extends any[]
? DownSampleTsTypes<TypeMap, Tuple[i]>
: DownSampleTsType<TypeMap, Tuple[i]>;
} & {
length: Tuple["length"];
};

// @prettier-ignore
type DownSampleTsType<TypeMap extends [any, any][], T> = T extends Exclude<TypeMap[number][0], undefined>
? Extract<TypeMap[number], [T, any]>[1]
: T;

// @formatter:on
// endregion
124 changes: 124 additions & 0 deletions src/harmony/versions/four-seven.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
/**
* Changes after this point: https://github.com/microsoft/TypeScript/wiki/API-Breaking-Changes#typescript-48
*/
import TsCurrentModule, {
AssertClause,
ExportDeclaration,
Expression,
ImportClause,
ImportDeclaration,
Modifier,
ModuleBody,
ModuleDeclaration,
ModuleName,
NamedExportBindings,
} from "typescript";
import TsFourSevenModule from "../../declarations/typescript4.7";
import { TsTransformPathsContext } from "../../types";
import { DownSampleTsTypes } from "../utils";

/* ****************************************************************************************************************** */
// region: Mapping
/* ****************************************************************************************************************** */

export namespace TsFourSeven {
export type TypeMap = [
[TsCurrentModule.ImportDeclaration, TsFourSevenModule.ImportDeclaration],
[TsCurrentModule.Modifier, TsFourSevenModule.Modifier],
[TsCurrentModule.ImportClause, TsFourSevenModule.ImportClause],
[TsCurrentModule.Expression, TsFourSevenModule.Expression],
[TsCurrentModule.AssertClause, TsFourSevenModule.AssertClause],
[TsCurrentModule.ExportDeclaration, TsFourSevenModule.ExportDeclaration],
[TsCurrentModule.NamedExportBindings, TsFourSevenModule.NamedExportBindings],
[TsCurrentModule.ModuleDeclaration, TsFourSevenModule.ModuleDeclaration],
[TsCurrentModule.ModuleName, TsFourSevenModule.ModuleName],
[TsCurrentModule.ModuleBody, TsFourSevenModule.ModuleBody]
];
}

// endregion

/* ****************************************************************************************************************** */
// region: Utils
/* ****************************************************************************************************************** */

export namespace TsFourSeven {
export const predicate = ({ tsVersionMajor, tsVersionMinor }: TsTransformPathsContext) =>
tsVersionMajor == 4 && tsVersionMinor < 8;

export function handler(context: TsTransformPathsContext, prop: string | symbol) {
const factory = context.tsFactory as unknown as TsFourSevenModule.NodeFactory;

switch (prop) {
case "updateImportDeclaration":
return function (
node: ImportDeclaration,
modifiers: readonly Modifier[] | undefined,
importClause: ImportClause | undefined,
moduleSpecifier: Expression,
assertClause: AssertClause | undefined
) {
const [dsNode, dsImportClause, dsModuleSpecifier, dsAssertClause] = downSample(
node,
importClause,
moduleSpecifier,
assertClause
);

return factory.updateImportDeclaration(
dsNode,
dsNode.decorators,
dsNode.modifiers,
dsImportClause,
dsModuleSpecifier,
dsAssertClause
);
};
case "updateExportDeclaration":
return function (
node: ExportDeclaration,
modifiers: readonly Modifier[] | undefined,
isTypeOnly: boolean,
exportClause: NamedExportBindings | undefined,
moduleSpecifier: Expression | undefined,
assertClause: AssertClause | undefined
) {
const [dsNode, dsExportClause, dsModuleSpecifier, dsAssertClause] = downSample(
node,
exportClause,
moduleSpecifier,
assertClause
);

return factory.updateExportDeclaration(
dsNode,
dsNode.decorators,
dsNode.modifiers,
isTypeOnly,
dsExportClause,
dsModuleSpecifier,
dsAssertClause
);
};
case "updateModuleDeclaration":
return function (
node: ModuleDeclaration,
modifiers: readonly Modifier[] | undefined,
name: ModuleName,
body: ModuleBody | undefined
) {
const [dsNode, dsName, dsBody] = downSample(node, name, body);

return factory.updateModuleDeclaration(dsNode, dsNode.decorators, dsNode.modifiers, dsName, dsBody);
};
default:
return (...args: any) => (<any>factory)[prop](...args);
}
}

export function downSample<T extends [...unknown[]]>(...args: T): DownSampleTsTypes<TypeMap, T> {
return <any>args;
}
}

// endregion
2 changes: 2 additions & 0 deletions src/harmony/versions/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from "./three-eight";
export * from "./four-seven";
157 changes: 157 additions & 0 deletions src/harmony/versions/three-eight.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
/**
* Changes after this point: https://github.com/microsoft/TypeScript/wiki/API-Breaking-Changes#typescript-40
*/
import TsCurrentModule, {
EntityName,
ExportDeclaration,
Expression,
Identifier,
ImportClause,
ImportDeclaration,
ImportTypeAssertionContainer,
ImportTypeNode,
Modifier,
ModuleBody,
ModuleDeclaration,
ModuleName,
NamedExportBindings,
NamedImportBindings,
TypeNode,
} from "typescript";
import * as TsThreeEightModule from "../../declarations/typescript3";
import { TsTransformPathsContext } from "../../types";
import { DownSampleTsTypes } from "../utils";

/* ****************************************************************************************************************** */
// region: Mapping
/* ****************************************************************************************************************** */

export namespace TsThreeEight {
export type TypeMap = [
[TsCurrentModule.SourceFile, TsThreeEightModule.SourceFile],
[TsCurrentModule.StringLiteral, TsThreeEightModule.StringLiteral],
[TsCurrentModule.CompilerOptions, TsThreeEightModule.CompilerOptions],
[TsCurrentModule.EmitResolver, TsThreeEightModule.EmitResolver],
[TsCurrentModule.CallExpression, TsThreeEightModule.CallExpression],
[TsCurrentModule.ExternalModuleReference, TsThreeEightModule.ExternalModuleReference],
[TsCurrentModule.LiteralTypeNode, TsThreeEightModule.LiteralTypeNode],
[TsCurrentModule.ExternalModuleReference, TsThreeEightModule.ExternalModuleReference],
[TsCurrentModule.ImportTypeNode, TsThreeEightModule.ImportTypeNode],
[TsCurrentModule.EntityName, TsThreeEightModule.EntityName],
[TsCurrentModule.TypeNode, TsThreeEightModule.TypeNode],
[readonly TsCurrentModule.TypeNode[], readonly TsThreeEightModule.TypeNode[]],
[TsCurrentModule.LiteralTypeNode, TsThreeEightModule.LiteralTypeNode],
[TsCurrentModule.ImportDeclaration, TsThreeEightModule.ImportDeclaration],
[TsCurrentModule.ImportClause, TsThreeEightModule.ImportClause],
[TsCurrentModule.Identifier, TsThreeEightModule.Identifier],
[TsCurrentModule.NamedImportBindings, TsThreeEightModule.NamedImportBindings],
[TsCurrentModule.ImportDeclaration, TsThreeEightModule.ImportDeclaration],
[TsCurrentModule.ExportDeclaration, TsThreeEightModule.ExportDeclaration],
[TsCurrentModule.ModuleDeclaration, TsThreeEightModule.ModuleDeclaration],
[TsCurrentModule.Expression, TsThreeEightModule.Expression],
[TsCurrentModule.ModuleBody, TsThreeEightModule.ModuleBody],
[TsCurrentModule.ModuleName, TsThreeEightModule.ModuleName],
[TsCurrentModule.ExportDeclaration["exportClause"], TsThreeEightModule.ExportDeclaration["exportClause"]]
];
}

// endregion

/* ****************************************************************************************************************** */
// region: Utils
/* ****************************************************************************************************************** */

export namespace TsThreeEight {
export const predicate = (context: TsTransformPathsContext) => context.tsVersionMajor < 4;

export function handler(context: TsTransformPathsContext, prop: string | symbol) {
const ts = context.tsInstance as unknown as typeof TsThreeEightModule;

switch (prop) {
case "updateCallExpression":
return (...args: any) => ts.updateCall.apply(void 0, args);
case "updateImportClause":
return function (
node: ImportClause,
isTypeOnly: boolean,
name: Identifier | undefined,
namedBindings: NamedImportBindings | undefined
) {
return ts.updateImportClause.apply(void 0, downSample(node, name, namedBindings));
};
case "updateImportDeclaration":
return function (
node: ImportDeclaration,
modifiers: readonly Modifier[] | undefined,
importClause: ImportClause | undefined,
moduleSpecifier: Expression
) {
const [dsNode, dsImportClause, dsModuleSpecifier] = downSample(node, importClause, moduleSpecifier);

return ts.updateImportDeclaration(
dsNode,
dsNode.decorators,
dsNode.modifiers,
dsImportClause,
dsModuleSpecifier
);
};
case "updateExportDeclaration":
return function (
node: ExportDeclaration,
modifiers: readonly Modifier[] | undefined,
isTypeOnly: boolean,
exportClause: NamedExportBindings | undefined,
moduleSpecifier: Expression | undefined
) {
const [dsNode, dsModuleSpecifier, dsExportClause] = downSample(node, moduleSpecifier, exportClause);
return ts.updateExportDeclaration(
dsNode,
dsNode.decorators,
dsNode.modifiers,
dsExportClause,
dsModuleSpecifier,
// @ts-ignore - This was added in later versions of 3.x
dsNode.isTypeOnly
);
};
case "updateModuleDeclaration":
return function (
node: ModuleDeclaration,
modifiers: readonly Modifier[] | undefined,
name: ModuleName,
body: ModuleBody | undefined
) {
const [dsNode, dsName, dsBody] = downSample(node, name, body);

return ts.updateModuleDeclaration(dsNode, dsNode.decorators, dsNode.modifiers, dsName, dsBody);
};
case "updateImportTypeNode":
return function (
node: ImportTypeNode,
argument: TypeNode,
assertions: ImportTypeAssertionContainer | undefined,
qualifier: EntityName | undefined,
typeArguments: readonly TypeNode[] | undefined,
isTypeOf?: boolean
) {
const [dsNode, dsArgument, dsQualifier, dsTypeArguments] = downSample(
node,
argument,
qualifier,
typeArguments
);

return ts.updateImportTypeNode(dsNode, dsArgument, dsQualifier, dsTypeArguments, isTypeOf);
};
default:
return (...args: any) => (<any>ts)[prop](...args);
}
}

export function downSample<T extends [...unknown[]]>(...args: T): DownSampleTsTypes<TypeMap, T> {
return <any>args;
}
}

// endregion
Loading

0 comments on commit cbeb29c

Please sign in to comment.