mirror of
https://github.com/LuanRT/YouTube.js.git
synced 2026-06-02 12:23:19 +00:00
187 lines
7.0 KiB
JavaScript
187 lines
7.0 KiB
JavaScript
/**
|
|
* @param {import('typescript').Program} program
|
|
* @param {import('ts-patch').PluginConfig} pluginConfig
|
|
* @param {import('ts-patch').TransformerExtras} extras
|
|
*/
|
|
module.exports = (program, pluginConfig, { ts: tsInstance }) => {
|
|
/** @param {import('typescript').TransformationContext} context */
|
|
return (context) => {
|
|
const { factory } = context
|
|
|
|
/** @param {import('typescript').SourceFile} sourceFile */
|
|
return (sourceFile) => {
|
|
/**
|
|
* @param {import('typescript').Node} node
|
|
* @returns {import('typescript').Node}
|
|
*/
|
|
const visitor = (node) => {
|
|
if (
|
|
tsInstance.isEnumDeclaration(node) &&
|
|
(!node.modifiers || node.modifiers.every(modifier => modifier.kind !== tsInstance.SyntaxKind.DeclareKeyword))
|
|
) {
|
|
let variableStatementModifiers
|
|
|
|
if (node.modifiers?.some(modifier => modifier.kind === tsInstance.SyntaxKind.ExportKeyword)) {
|
|
variableStatementModifiers = [
|
|
factory.createModifier(tsInstance.SyntaxKind.ExportKeyword)
|
|
]
|
|
}
|
|
|
|
const properties = []
|
|
let currentValue = 0
|
|
|
|
for (const member of node.members) {
|
|
const name = member.name.text
|
|
let value
|
|
let isNumeric = true
|
|
let hasMinus = false
|
|
|
|
if (!member.initializer) {
|
|
value = currentValue.toString()
|
|
currentValue++
|
|
} else if (tsInstance.isStringLiteral(member.initializer)) {
|
|
value = member.initializer.text
|
|
isNumeric = false
|
|
} else if (tsInstance.isNumericLiteral(member.initializer)) {
|
|
value = member.initializer.text
|
|
currentValue = Number(value) + 1
|
|
} else if (
|
|
tsInstance.isPrefixUnaryExpression(member.initializer) &&
|
|
member.initializer.operator === tsInstance.SyntaxKind.MinusToken
|
|
) {
|
|
value = member.initializer.operand.text
|
|
hasMinus = true
|
|
currentValue = (-1 * Number(value)) + 1
|
|
} else {
|
|
console.warn(`Unsupported enum member initializer "${tsInstance.SyntaxKind[member.initializer.kind]}" in "${node.name.text}", using original enum output.`)
|
|
return tsInstance.visitEachChild(node, visitor, context);
|
|
}
|
|
|
|
if (isNumeric) {
|
|
if (hasMinus) {
|
|
const mapping = factory.createPropertyAssignment(
|
|
name,
|
|
factory.createPrefixUnaryExpression(
|
|
tsInstance.SyntaxKind.MinusToken,
|
|
factory.createNumericLiteral(value)
|
|
)
|
|
)
|
|
|
|
tsInstance.setOriginalNode(mapping, member)
|
|
tsInstance.setTextRange(mapping, member)
|
|
|
|
tsInstance.setOriginalNode(mapping.name, member.name)
|
|
tsInstance.setTextRange(mapping.name, member.name)
|
|
|
|
if (member.initializer) {
|
|
tsInstance.setOriginalNode(mapping.initializer, member.initializer)
|
|
tsInstance.setTextRange(mapping.initializer, member.initializer)
|
|
}
|
|
|
|
const reverseMapping = factory.createPropertyAssignment(
|
|
factory.createStringLiteral(`-${value}`),
|
|
factory.createStringLiteral(name)
|
|
)
|
|
|
|
tsInstance.setOriginalNode(reverseMapping, member)
|
|
tsInstance.setTextRange(reverseMapping, member)
|
|
|
|
tsInstance.setOriginalNode(reverseMapping.initializer, member.name)
|
|
tsInstance.setTextRange(reverseMapping.initializer, member.name)
|
|
|
|
if (member.initializer) {
|
|
tsInstance.setOriginalNode(reverseMapping.name, member.initializer)
|
|
tsInstance.setTextRange(reverseMapping.name, member.initializer)
|
|
}
|
|
|
|
properties.push(mapping, reverseMapping)
|
|
} else {
|
|
const mapping = factory.createPropertyAssignment(
|
|
name,
|
|
factory.createNumericLiteral(value)
|
|
)
|
|
|
|
tsInstance.setOriginalNode(mapping, member)
|
|
tsInstance.setTextRange(mapping, member)
|
|
|
|
tsInstance.setOriginalNode(mapping.name, member.name)
|
|
tsInstance.setTextRange(mapping.name, member.name)
|
|
|
|
if (member.initializer) {
|
|
tsInstance.setOriginalNode(mapping.initializer, member.initializer)
|
|
tsInstance.setTextRange(mapping.initializer, member.initializer)
|
|
}
|
|
|
|
const reverseMapping = factory.createPropertyAssignment(
|
|
value,
|
|
factory.createStringLiteral(name)
|
|
)
|
|
|
|
tsInstance.setOriginalNode(reverseMapping, member)
|
|
tsInstance.setTextRange(reverseMapping, member)
|
|
|
|
tsInstance.setOriginalNode(reverseMapping.initializer, member.name)
|
|
tsInstance.setTextRange(reverseMapping.initializer, member.name)
|
|
|
|
if (member.initializer) {
|
|
tsInstance.setOriginalNode(reverseMapping.name, member.initializer)
|
|
tsInstance.setTextRange(reverseMapping.name, member.initializer)
|
|
}
|
|
|
|
properties.push(mapping, reverseMapping)
|
|
}
|
|
} else {
|
|
const mapping = factory.createPropertyAssignment(
|
|
name,
|
|
factory.createStringLiteral(value)
|
|
)
|
|
|
|
tsInstance.setOriginalNode(mapping, member)
|
|
tsInstance.setTextRange(mapping, member)
|
|
|
|
tsInstance.setOriginalNode(mapping.name, member.name)
|
|
tsInstance.setTextRange(mapping.name, member.name)
|
|
|
|
tsInstance.setOriginalNode(mapping.initializer, member.initializer)
|
|
tsInstance.setTextRange(mapping.initializer, member.initializer)
|
|
|
|
properties.push(mapping)
|
|
}
|
|
}
|
|
|
|
const convertedNameIdentifier = factory.createIdentifier(node.name.text)
|
|
tsInstance.setOriginalNode(convertedNameIdentifier, node.name)
|
|
tsInstance.setTextRange(convertedNameIdentifier, node.name)
|
|
|
|
const convertedEnum = factory.createVariableStatement(
|
|
variableStatementModifiers,
|
|
factory.createVariableDeclarationList(
|
|
[
|
|
factory.createVariableDeclaration(
|
|
convertedNameIdentifier,
|
|
undefined,
|
|
undefined,
|
|
factory.createObjectLiteralExpression(
|
|
properties,
|
|
true
|
|
)
|
|
)
|
|
],
|
|
tsInstance.NodeFlags.Const
|
|
)
|
|
)
|
|
|
|
tsInstance.setOriginalNode(convertedEnum, node)
|
|
tsInstance.setTextRange(convertedEnum, node)
|
|
|
|
return convertedEnum
|
|
}
|
|
|
|
return tsInstance.visitEachChild(node, visitor, context);
|
|
};
|
|
|
|
return tsInstance.visitNode(sourceFile, visitor);
|
|
}
|
|
}
|
|
}
|