Skip to content

Commit

Permalink
feat(core): Export ESM (ES2020)
Browse files Browse the repository at this point in the history
BREAKING CHANGE: No more CommonJS support
  • Loading branch information
grantila committed Mar 19, 2023
1 parent db11426 commit 8d4624c
Show file tree
Hide file tree
Showing 15 changed files with 1,497 additions and 247 deletions.
15 changes: 12 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,20 @@ Other conversion packages:
* [`core-types-suretype`][core-types-suretype-github-url] (which is also using this package)


# Versions

Since 4.0, this package is pure ESM and requires Node 14.13.1 or later.


# Contents

* [Usage](#usage)
* [core-types to TypeScript](#core-types-to-typescript)
* [TypeScript to core-types](#typescript-to-core-types)
- [core-types-ts](#core-types-ts)
- [See](#see)
- [Versions](#versions)
- [Contents](#contents)
- [Usage](#usage)
- [core-types to TypeScript](#core-types-to-typescript)
- [TypeScript to core-types](#typescript-to-core-types)


# Usage
Expand Down
14 changes: 14 additions & 0 deletions babel.config.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
module.exports = {
presets: [
[
'@babel/preset-env',
{
modules: false,
targets: {
node: 'current',
},
},
],
'@babel/preset-typescript',
],
}
8 changes: 4 additions & 4 deletions index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
export {
convertCoreTypesToTypeScript,
convertSingleCoreTypeToTypeScriptAst,
} from './lib/core-types-to-ts'
export { convertTypeScriptToCoreTypes } from './lib/ts-to-core-types'
export * as helpers from './lib/ts-helpers'
export type { ToTsOptions, FromTsOptions } from './lib/types'
} from './lib/core-types-to-ts.js'
export { convertTypeScriptToCoreTypes } from './lib/ts-to-core-types.js'
export * as helpers from './lib/ts-helpers.js'
export type { ToTsOptions, FromTsOptions } from './lib/types.js'
7 changes: 4 additions & 3 deletions lib/bi-directional.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { NamedType, NodeDocument } from 'core-types';
import { convertCoreTypesToTypeScript } from './core-types-to-ts'
import { convertTypeScriptToCoreTypes } from './ts-to-core-types'
import type { NamedType, NodeDocument } from 'core-types'

import { convertCoreTypesToTypeScript } from './core-types-to-ts.js'
import { convertTypeScriptToCoreTypes } from './ts-to-core-types.js'


const wrapDocument = ( types: Array< NamedType > ): NodeDocument =>
Expand Down
5 changes: 3 additions & 2 deletions lib/core-types-to-ts.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { NamedType, NodeDocument } from 'core-types';
import { convertCoreTypesToTypeScript } from './core-types-to-ts'
import type { NamedType, NodeDocument } from 'core-types'

import { convertCoreTypesToTypeScript } from './core-types-to-ts.js'


const wrapDocument = ( types: Array< NamedType > ): NodeDocument =>
Expand Down
78 changes: 39 additions & 39 deletions lib/core-types-to-ts.ts
Original file line number Diff line number Diff line change
@@ -1,29 +1,29 @@
import {
NodeDocument,
NodeType,
AndType,
OrType,
PrimitiveType,
type AndType,
type ArrayType,
type ConversionResult,
type CoreTypesErrorMeta,
type NamedType,
type NodeDocument,
type NodeType,
type ObjectType,
type OrType,
type PrimitiveType,
type RefType,
type TupleType,
isPrimitiveType,
RefType,
ObjectType,
ArrayType,
TupleType,
CoreTypesErrorMeta,
ConversionResult,
UnsupportedError,
NamedType,
} from "core-types"
import * as ts from 'typescript'
} from 'core-types'

import { ts, tst } from './ts.js'
import {
createCodeHeader,
generateCode,
safeName,
tsUnknownTypeAnnotation,
wrapAnnotations,
generateCode,
createCodeHeader,
} from "./ts-helpers"
import { ToTsOptions } from "./types"
} from './ts-helpers.js'
import type { ToTsOptions } from './types.js'


const { factory } = ts;
Expand Down Expand Up @@ -106,7 +106,7 @@ export function convertSingleCoreTypeToTypeScriptAst(
opts: Pick< ToTsOptions, 'useUnknown' | 'declaration' | 'namespaces' > =
{ }
)
: { declaration: ts.Declaration; namespaceList: string[ ]; }
: { declaration: tst.Declaration; namespaceList: string[ ]; }
{
const {
useUnknown = false,
Expand All @@ -123,7 +123,7 @@ export function convertSingleCoreTypeToTypeScriptAst(

const ret = tsType( ctx, node );

const doExport = ( tsNode: ts.Declaration ) =>
const doExport = ( tsNode: tst.Declaration ) =>
wrapAnnotations( tsNode, node );

const typeDeclaration =
Expand Down Expand Up @@ -166,7 +166,7 @@ function createExportModifier( declaration: boolean )
);
}

function declareType( declaration: boolean, name: string, node: ts.TypeNode )
function declareType( declaration: boolean, name: string, node: tst.TypeNode )
{
return factory.createTypeAliasDeclaration(
createExportModifier( declaration ), // modifiers
Expand All @@ -179,7 +179,7 @@ function declareType( declaration: boolean, name: string, node: ts.TypeNode )
function declareInterface(
declaration: boolean,
name: string,
nodes: Array< ts.TypeElement >
nodes: Array< tst.TypeElement >
)
{
return factory.createInterfaceDeclaration(
Expand All @@ -193,16 +193,16 @@ function declareInterface(

interface TsTypeReturnAsObject {
type: 'object';
node: ts.TypeLiteralNode;
properties: Array< ts.TypeElement >;
node: tst.TypeLiteralNode;
properties: Array< tst.TypeElement >;
}
interface TsTypeReturnAsFlowType {
type: 'flow-type';
node: ts.TypeNode;
node: tst.TypeNode;
}
type TsTypeReturn = TsTypeReturnAsObject | TsTypeReturnAsFlowType;

function tsTypeUnion( ctx: Context, node: OrType ): ts.TypeNode
function tsTypeUnion( ctx: Context, node: OrType ): tst.TypeNode
{
return factory.createUnionTypeNode(
node.or.map( elem =>
Expand All @@ -211,7 +211,7 @@ function tsTypeUnion( ctx: Context, node: OrType ): ts.TypeNode
)
}

function tsTypeIntersection( ctx: Context, node: AndType ): ts.TypeNode
function tsTypeIntersection( ctx: Context, node: AndType ): tst.TypeNode
{
return factory.createIntersectionTypeNode(
node.and.map( elem =>
Expand All @@ -220,23 +220,23 @@ function tsTypeIntersection( ctx: Context, node: AndType ): ts.TypeNode
)
}

function tsTypeAndOrSchema( ctx: Context, node: NodeType ): ts.TypeNode
function tsTypeAndOrSchema( ctx: Context, node: NodeType ): tst.TypeNode
{
if ( node.type === 'and' || node.type === 'or' )
return tsTypeAndOr( ctx, node );
else
return tsType( ctx, node ).node;
}

function tsTypeAndOr( ctx: Context, andOr: AndType | OrType ): ts.TypeNode
function tsTypeAndOr( ctx: Context, andOr: AndType | OrType ): tst.TypeNode
{
if ( andOr.type === 'and' )
return tsTypeIntersection( ctx, andOr );
else
return tsTypeUnion( ctx, andOr );
}

function tsAny( ctx: Context ): ts.TypeNode
function tsAny( ctx: Context ): tst.TypeNode
{
return ctx.useUnknown
? tsUnknownTypeAnnotation( )
Expand Down Expand Up @@ -289,7 +289,7 @@ function tsType( ctx: Context, node: NodeType ): TsTypeReturn
throwUnsupported( `Type ${(node as any).type} not supported`, node );
}

function tsNullType( ): ts.TypeNode
function tsNullType( ): tst.TypeNode
{
return factory.createLiteralTypeNode(
factory.createToken( ts.SyntaxKind.NullKeyword )
Expand All @@ -303,7 +303,7 @@ const primitiveTypeMap = {
boolean: ts.SyntaxKind.BooleanKeyword,
} as const;

function tsPrimitiveType( node: PrimitiveType ): ts.TypeNode
function tsPrimitiveType( node: PrimitiveType ): tst.TypeNode
{
const { type } = node;
if ( type === "null" )
Expand All @@ -316,7 +316,7 @@ function tsPrimitiveType( node: PrimitiveType ): ts.TypeNode
throwUnsupported( `Invalid primitive type: ${type}`, node );
}

function tsConstType( ctx: Context, node: NodeType, value: any ): ts.TypeNode
function tsConstType( ctx: Context, node: NodeType, value: any ): tst.TypeNode
{
return value === "null"
? tsNullType( )
Expand Down Expand Up @@ -345,15 +345,15 @@ function tsArrayConstExpression< T >(
node: NodeType,
value: Array< T >
)
: ts.TypeNode
: tst.TypeNode
{
return factory.createTupleTypeNode(
value.map( elem => tsConstType( ctx, node, elem ) )
)
}

function createAdditionalMembers( ctx: Context, type: true | NodeType )
: ts.IndexSignatureDeclaration
: tst.IndexSignatureDeclaration
{
if ( type === true )
return createAdditionalMembers( ctx, { type: 'any' } );
Expand Down Expand Up @@ -390,7 +390,7 @@ function tsObjectType( ctx: Context, node: ObjectType )
? undefined
: factory.createToken( ts.SyntaxKind.QuestionToken );

const propertyNodes: Array< ts.TypeElement > = [
const propertyNodes: Array< tst.TypeElement > = [
...Object
.keys( properties )
.map( name => ( { name, ...properties[ name ] } ) )
Expand All @@ -413,14 +413,14 @@ function tsObjectType( ctx: Context, node: ObjectType )
return { properties: propertyNodes, node: objectAsNode };
}

function tsSpreadType( ctx: Context, node: NodeType ): ts.TypeNode
function tsSpreadType( ctx: Context, node: NodeType ): tst.TypeNode
{
return factory.createArrayTypeNode(
factory.createRestTypeNode( tsType( ctx, node ).node )
);
}

function tsArrayType( ctx: Context, node: ArrayType | TupleType ): ts.TypeNode
function tsArrayType( ctx: Context, node: ArrayType | TupleType ): tst.TypeNode
{
// TODO: Add support for minItems (making rest arguments optional)
// TODO: Maybe add support for maxItems (turning an array into a tuple of
Expand All @@ -444,7 +444,7 @@ function tsArrayType( ctx: Context, node: ArrayType | TupleType ): ts.TypeNode
);
}

function tsRefType( node: RefType ): ts.TypeNode
function tsRefType( node: RefType ): tst.TypeNode
{
return factory.createTypeReferenceNode( node.ref );
}
26 changes: 14 additions & 12 deletions lib/ts-annotations.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,23 @@
import * as ts from 'typescript'
import { CoreTypeAnnotations, mergeAnnotations } from 'core-types'
import { type CoreTypeAnnotations, mergeAnnotations } from 'core-types'

import { ts, tst } from './ts.js'


interface JSDocContainer {
jsDoc: Array< ts.JSDoc >;
jsDoc: Array< tst.JSDoc >;
}

function extractDescription( text: string | undefined ): CoreTypeAnnotations
function extractDescription( text: string | undefined ): CoreTypeAnnotations
{
if ( !text )
return { };

return { description: text };
}

function extractTitle( node: ts.Node ): CoreTypeAnnotations
function extractTitle( node: tst.Node ): CoreTypeAnnotations
{
const hasParentWhileUnnamed = ( node: ts.Node ) =>
const hasParentWhileUnnamed = ( node: tst.Node ) =>
node.parent &&
(
ts.isArrayTypeNode( node.parent )
Expand All @@ -29,7 +31,7 @@ function extractTitle( node: ts.Node ): CoreTypeAnnotations
ts.isUnionTypeNode( node.parent )
);

const recurseTypeChain = ( node: ts.Node, child: ts.Node | undefined )
const recurseTypeChain = ( node: tst.Node, child: tst.Node | undefined )
: Array< string > =>
{
if ( !node )
Expand Down Expand Up @@ -94,7 +96,7 @@ function extractTitle( node: ts.Node ): CoreTypeAnnotations
}

function stringifyDoc(
text: undefined | string | ts.NodeArray< ts.JSDocComment >
text: undefined | string | tst.NodeArray< tst.JSDocComment >
)
: string | undefined
{
Expand All @@ -104,14 +106,14 @@ function stringifyDoc(
return text.map( ( { text } ) => text ).join( ' ' );
}

function extractTags( tags: ReadonlyArray< ts.JSDocTag > ): CoreTypeAnnotations
function extractTags( tags: ReadonlyArray< tst.JSDocTag > ): CoreTypeAnnotations
{
const descriptions: Array< string > = [ ];
const examples: Array< string > = [ ];
const _default: Array< string > = [ ];
const see: Array< string > = [ ];

const extractSee = ( tag: ts.JSDocSeeTag ) =>
const extractSee = ( tag: tst.JSDocSeeTag ) =>
( tag.name ? ( tag.name?.getText( ) + ' ' ) : '' ) +
stringifyDoc( tag.comment )?.trim( ) ?? '';

Expand All @@ -125,7 +127,7 @@ function extractTags( tags: ReadonlyArray< ts.JSDocTag > ): CoreTypeAnnotations
else if ( tag.tagName.text === 'default' )
_default.push( stringifyDoc( tag.comment )?.trim( ) ?? '' );
else if ( tag.tagName.text === 'see' )
see.push( extractSee( tag as ts.JSDocSeeTag ) );
see.push( extractSee( tag as tst.JSDocSeeTag ) );
else
{
const text = stringifyDoc( tag.comment )?.trim( ) ?? '';
Expand All @@ -151,7 +153,7 @@ export interface DecorateNodeOptions {
includeJsDoc?: boolean;
}

export function decorateNode( node: ts.Node, options?: DecorateNodeOptions )
export function decorateNode( node: tst.Node, options?: DecorateNodeOptions )
: CoreTypeAnnotations
{
const { includeJsDoc = true } = options ?? { };
Expand Down
Loading

0 comments on commit 8d4624c

Please sign in to comment.