import * as ts from 'typescript'; import { writeFileSync } from 'fs'; import { schema } from '../resources/processmaker'; interface Schema { name: string; uri: string; prefix: string; xml: { tagAlias: string }; associations: readonly []; types: readonly Type[]; } interface Type { name: string; extends: readonly string[]; isAbstract: boolean; properties: readonly Properties[]; } interface Properties { name: string; isAttr: boolean; type: string; } const convertTypeFromProperties = (type: string) => { if (type === 'Boolean') return 'boolean'; if (type === 'Integer') return 'number'; return 'string'; }; const sourceFile = ts.createSourceFile( 'bpmn-properties.ts', // the output file name '', // the text of the source code, not needed for our purposes ts.ScriptTarget.Latest, // the target language version for the output file false, ts.ScriptKind.TS // output script kind. options include JS, TS, JSX, TSX and others ); const exportModifier = ts.factory.createModifiersFromModifierFlags( ts.ModifierFlags.Export ); const firstLetterLowercase = (s: string) => { const firstLetter = s[0]; return s.replace(firstLetter, firstLetter.toLowerCase()); }; const generatePropertiesInterfaceFromSchema = (schema: Schema) => schema.types.map((type) => { const memberName = ts.factory.createIdentifier(`${type.name}Properties`); const baseClassName = ts.factory.createIdentifier(`bpmn.${type.name}`); const typeParameters = type.properties.map((property) => ts.factory.createPropertySignature( undefined, `"pm:${property.name}"`, ts.factory.createToken(ts.SyntaxKind.QuestionToken), ts.factory.createTypeReferenceNode( convertTypeFromProperties(property.type), [] ) ) ); const member = ts.factory.createInterfaceDeclaration( undefined, exportModifier, memberName, undefined, [ ts.factory.createHeritageClause(ts.SyntaxKind.ExtendsKeyword, [ ts.factory.createExpressionWithTypeArguments( ts.factory.createIdentifier('Partial'), [ts.factory.createTypeReferenceNode(baseClassName, [])] ), ]), ], typeParameters ); return member; }); const propertiesInterface = generatePropertiesInterfaceFromSchema( schema as Schema ); const generateInterfaceFromProperties = () => ts.factory.createInterfaceDeclaration( undefined, undefined, 'processmakerBpmnProperties', undefined, undefined, propertiesInterface.map((property) => ts.factory.createPropertySignature( undefined, firstLetterLowercase(property.name.text), undefined, ts.factory.createTypeReferenceNode(property.name.text, []) ) ) ); const bpmnPropertiesInterface = generateInterfaceFromProperties(); const nodes = ts.factory.createNodeArray([ ...propertiesInterface, bpmnPropertiesInterface, ]); const printer = ts.createPrinter({ newLine: ts.NewLineKind.LineFeed }); const result = printer.printList(ts.ListFormat.MultiLine, nodes, sourceFile); writeFileSync('src/types/bpmn-properties.ts', result, { encoding: 'utf-8' });