core-types-ts
Advanced tools
Comparing version 3.3.0 to 3.4.0
import * as ts from 'typescript'; | ||
import { CoreTypeAnnotations } from 'core-types'; | ||
export declare function decorateNode(node: ts.Node): CoreTypeAnnotations; | ||
export interface DecorateNodeOptions { | ||
includeJsDoc?: boolean; | ||
} | ||
export declare function decorateNode(node: ts.Node, options?: DecorateNodeOptions): CoreTypeAnnotations; |
@@ -104,7 +104,8 @@ "use strict"; | ||
} | ||
function decorateNode(node) { | ||
function decorateNode(node, options) { | ||
var _a; | ||
const { includeJsDoc = true } = options !== null && options !== void 0 ? options : {}; | ||
const { jsDoc } = node; | ||
const titleAnnotation = extractTitle(node); | ||
if (jsDoc && jsDoc.length) { | ||
if (includeJsDoc && jsDoc && jsDoc.length) { | ||
// TODO: Analyze when this can be larger than 1 and why | ||
@@ -111,0 +112,0 @@ const first = jsDoc[0]; |
@@ -228,4 +228,5 @@ "use strict"; | ||
} | ||
function fromTsTypeNode(node, ctx) { | ||
function fromTsTypeNode(node, ctx, options) { | ||
var _a, _b, _c, _d; | ||
const { peekOnly = false } = options !== null && options !== void 0 ? options : {}; | ||
if (ts.isUnionTypeNode(node)) | ||
@@ -295,17 +296,128 @@ return { | ||
} | ||
const ref = node.typeName.text; | ||
const ensureNonCyclic = (name) => { | ||
if (ctx.cyclicState.has(name)) | ||
throw new core_types_1.MalformedTypeError(`Cyclic type found when trying to inline type ${name}`, { | ||
blob: node, | ||
loc: (0, ts_helpers_1.toLocation)(node), | ||
}); | ||
ctx.cyclicState.add(name); | ||
}; | ||
// TODO: Make this able to go into named type. | ||
// It currently understands: | ||
// 'foo' | 'bar' | ||
// but not | ||
// Xyz | ||
// where somewhere else: | ||
// type Xyz = 'foo' | 'bar' | ||
const getStringUnion = (su) => { | ||
if (ts.isLiteralTypeNode(su) && | ||
ts.isStringLiteral(su.literal)) | ||
return [su.literal.text]; | ||
if (!ts.isUnionTypeNode(su)) | ||
return ctx.handleError(ctx.getUnsupportedError(`Expected string union kind`, su)); | ||
const names = su.types.map(subType => ts.isLiteralTypeNode(subType) && | ||
ts.isStringLiteral(subType.literal) | ||
? subType.literal.text | ||
: undefined); | ||
if (names.some(name => typeof name === 'undefined')) | ||
return ctx.handleError(ctx.getUnsupportedError(`Expected string union kind`, su)); | ||
return names; | ||
}; | ||
const getReferencedType = () => { | ||
var _a; | ||
const typeArguments = (_a = node.typeArguments) !== null && _a !== void 0 ? _a : []; | ||
const refType = typeArguments[0]; | ||
const secondNameTypes = typeArguments[1]; | ||
const secondNames = typeof secondNameTypes === 'undefined' | ||
? undefined | ||
: getStringUnion(secondNameTypes); | ||
if (typeof refType === 'undefined') | ||
return ctx.handleError(ctx.getUnsupportedError(`${ref}<> of non-objects are not supported`, node)); | ||
const subType = fromTsTypeNode(refType, ctx, { peekOnly: true }); | ||
if (typeof subType === 'undefined') | ||
return ctx.handleError(ctx.getUnsupportedError(`${ref}<> of non-objects are not supported`, node)); | ||
if (subType.type === 'ref') { | ||
const refName = refType.getText(); | ||
const reference = ctx.typeMap.get(refName); | ||
if (!reference | ||
|| | ||
!ts.isTypeLiteralNode(reference.declaration) | ||
&& | ||
!ts.isInterfaceDeclaration(reference.declaration)) | ||
return ctx.handleError(ctx.getUnsupportedError(`${ref}<> of non-objects are not supported`, node)); | ||
ensureNonCyclic(refName); | ||
const members = fromTsObjectMembers(reference.declaration, ctx); | ||
return { members, secondNames }; | ||
} | ||
else if (subType.type === 'object') { | ||
return { members: subType, secondNames }; | ||
} | ||
else | ||
return ctx.handleError(ctx.getUnsupportedError(`${ref}<> of non-objects are not supported`, node)); | ||
}; | ||
if (ref === 'Omit') { | ||
const reference = getReferencedType(); | ||
if (!reference) | ||
return undefined; | ||
const { members, secondNames } = reference; | ||
if (typeof secondNames === 'undefined') | ||
return undefined; | ||
const filteredMembers = { | ||
...members, | ||
properties: Object.fromEntries(Object.entries(members.properties) | ||
.filter(([name]) => !secondNames.includes(name))), | ||
}; | ||
return { | ||
type: 'object', | ||
...filteredMembers, | ||
...(0, ts_annotations_1.decorateNode)(node, { includeJsDoc: false }), | ||
}; | ||
} | ||
else if (ref === 'Pick') { | ||
const reference = getReferencedType(); | ||
if (!reference) | ||
return undefined; | ||
const { members, secondNames } = reference; | ||
if (typeof secondNames === 'undefined') | ||
return undefined; | ||
const filteredMembers = { | ||
...members, | ||
properties: Object.fromEntries(Object.entries(members.properties) | ||
.filter(([name]) => secondNames.includes(name))), | ||
}; | ||
return { | ||
type: 'object', | ||
...filteredMembers, | ||
...(0, ts_annotations_1.decorateNode)(node, { includeJsDoc: false }), | ||
}; | ||
} | ||
else if (ref === 'Partial') { | ||
const reference = getReferencedType(); | ||
if (!reference) | ||
return undefined; | ||
const { members } = reference; | ||
const filteredMembers = { | ||
...members, | ||
properties: Object.fromEntries(Object.entries(members.properties) | ||
.map(([name, value]) => [ | ||
name, | ||
{ ...value, required: false }, | ||
])), | ||
}; | ||
return { | ||
type: 'object', | ||
...filteredMembers, | ||
...(0, ts_annotations_1.decorateNode)(node, { includeJsDoc: false }), | ||
}; | ||
} | ||
if (isGenericType(node)) | ||
return handleGeneric(node, ctx); | ||
const ref = node.typeName.text; | ||
// TODO: Handle (reconstruct) generics | ||
const typeInfo = ctx.typeMap.get(ref); | ||
if (typeInfo && !typeInfo.exported) { | ||
if (typeInfo && !typeInfo.exported && !peekOnly) { | ||
if (ctx.options.nonExported === 'include-if-referenced') | ||
ctx.includeExtra.add(ref); | ||
else if (ctx.options.nonExported === 'inline') { | ||
if (ctx.cyclicState.has(ref)) | ||
throw new core_types_1.MalformedTypeError(`Cyclic type found when trying to inline type ${ref}`, { | ||
blob: node, | ||
loc: (0, ts_helpers_1.toLocation)(node), | ||
}); | ||
ctx.cyclicState.add(ref); | ||
ensureNonCyclic(ref); | ||
return fromTsTopLevelNode(typeInfo.declaration, ctx); | ||
@@ -312,0 +424,0 @@ } |
{ | ||
"name": "core-types-ts", | ||
"version": "3.3.0", | ||
"version": "3.4.0", | ||
"description": "core-types ⬌ TypeScript interface conversion", | ||
@@ -5,0 +5,0 @@ "author": "Gustaf Räntilä", |
56052
1094