diff --git a/generator/generators/azure/generator.ts b/generator/generators/azure/generator.ts index 2aa27b60..38839d33 100644 --- a/generator/generators/azure/generator.ts +++ b/generator/generators/azure/generator.ts @@ -1,152 +1,152 @@ -import * as fs from "fs"; -import { createSourceFile, ScriptTarget,SyntaxKind } from "typescript"; +import * as fs from 'fs'; +import { createSourceFile, ScriptTarget, SyntaxKind } from 'typescript'; -import { getAST } from "../../parsers/azure/parser"; -import { transform } from "../../transformers/azure/transformer"; -import { filters, getDir,groupers, printFile } from "../lib/helper"; +import { getAST } from '../../parsers/azure/parser'; +import { transform } from '../../transformers/azure/transformer'; +import { filters, getDir, groupers, printFile } from '../lib/helper'; interface FunctionData { - pkgName: string; - fileName: string; - functionName: string; - SDKFunctionName: string; - params: param[]; - returnType: string; - client: string; + pkgName: string; + fileName: string; + functionName: string; + SDKFunctionName: string; + params: param[]; + returnType: string; + client: string; } interface param { - name: string; - type: string; + name: string; + type: string; } -const dummyFile = process.cwd() + "/dummyClasses/azure.js"; +const dummyFile = process.cwd() + '/dummyClasses/azure.js'; const dummyAst = createSourceFile( - dummyFile, - fs.readFileSync(dummyFile).toString(), - ScriptTarget.Latest, - true + dummyFile, + fs.readFileSync(dummyFile).toString(), + ScriptTarget.Latest, + true ); export function extractSDKData(sdkFiles, methods) { - const specifiedMethods = JSON.parse(JSON.stringify(methods)); - sdkFiles.map(sdkFile => { - sdkFile.ast.members.map(member => { - if (SyntaxKind[member.kind] === "Constructor") { - member.parameters.map(param => { - const tempStr = param.type.typeName.text.split(/(?=[A-Z])/); - tempStr.pop(); - sdkFile.client = tempStr.join(""); - }); - } - - if ( - SyntaxKind[member.kind] === "MethodDeclaration" && - sdkFile.sdkFunctionNames.includes(member.name.text) - ) { - const method = methods.find( - methd => - methd.SDKFunctionName === member.name.text && - methd.fileName === sdkFile.fileName - ); - const parameters = member.parameters.map(param => { - return { - name: param.name.text, - optional: param.questionToken ? true : false, - type: SyntaxKind[param.type.kind] - }; - }); - - const returnType = SyntaxKind[member.type.kind]; - if (!method.returnType) { - method.params = parameters; - method.returnType = returnType; - method.client = sdkFile.client; - } else { - const clone = JSON.parse(JSON.stringify(method)); - clone.params = parameters; - clone.returnType = returnType; - clone.client = sdkFile.client; - methods.push(clone); - } - } - }); - }); - - if (JSON.stringify(methods) === JSON.stringify(specifiedMethods)) { - throw new Error("Data extraction unsuccessful"); - } - - const groupedMethods = groupers.azure(methods); - methods = filters.azure(groupedMethods); - - const classData = { - functions: methods - }; - - return classData; + const specifiedMethods = JSON.parse(JSON.stringify(methods)); + sdkFiles.map(sdkFile => { + sdkFile.ast.members.map(member => { + if (SyntaxKind[member.kind] === 'Constructor') { + member.parameters.map(param => { + const tempStr = param.type.typeName.text.split(/(?=[A-Z])/); + tempStr.pop(); + sdkFile.client = tempStr.join(''); + }); + } + + if ( + SyntaxKind[member.kind] === 'MethodDeclaration' && + sdkFile.sdkFunctionNames.includes(member.name.text) + ) { + const method = methods.find( + methd => + methd.SDKFunctionName === member.name.text && + methd.fileName === sdkFile.fileName + ); + const parameters = member.parameters.map(param => { + return { + name: param.name.text, + optional: param.questionToken ? true : false, + type: SyntaxKind[param.type.kind], + }; + }); + + const returnType = SyntaxKind[member.type.kind]; + if (!method.returnType) { + method.params = parameters; + method.returnType = returnType; + method.client = sdkFile.client; + } else { + const clone = JSON.parse(JSON.stringify(method)); + clone.params = parameters; + clone.returnType = returnType; + clone.client = sdkFile.client; + methods.push(clone); + } + } + }); + }); + + if (JSON.stringify(methods) === JSON.stringify(specifiedMethods)) { + throw new Error('Data extraction unsuccessful'); + } + + const groupedMethods = groupers.azure(methods); + methods = filters.azure(groupedMethods); + + const classData = { + functions: methods, + }; + + return classData; } export async function generateAzureClass(serviceClass, serviceName) { - let methods: FunctionData[] = []; - - Object.keys(serviceClass).map((key, index) => { - methods.push({ - pkgName: serviceClass[key].split(" ")[0], - fileName: serviceClass[key].split(" ")[1], - functionName: key, - SDKFunctionName: serviceClass[key].split(" ")[2], - params: [], - returnType: null, - client: null - }); - }); - - const files = Array.from(new Set(methods.map(method => method.fileName))); - - const sdkFiles = files.map(file => { - return { - fileName: file, - pkgName: methods[0].pkgName, - ast: null, - client: null, - sdkFunctionNames: methods - .filter(method => method.fileName === file) - .map(method => method.SDKFunctionName) - }; - }); - - await Promise.all( - sdkFiles.map(async file => { - file.ast = await getAST(file); - }) - ); - - const classData: any = extractSDKData(sdkFiles, methods); - classData.serviceName = serviceName; - const output = await transform(dummyAst, classData); - let filePath; - const dir = getDir(serviceName); - if (!fs.existsSync(process.cwd() + "/generatedClasses/Azure/" + dir)) { - fs.mkdirSync(process.cwd() + "/generatedClasses/Azure/" + dir); - } - if (/^[A-Z]*$/.test(serviceName)) { - filePath = - process.cwd() + - "/generatedClasses/Azure/" + - dir + - "/azure-" + - serviceName + - ".js"; - } else { - filePath = - process.cwd() + - "/generatedClasses/Azure/" + - dir + - "/azure-" + - serviceName.charAt(0).toLowerCase() + - serviceName.slice(1) + - ".js"; - } - printFile(filePath, output); + const methods: FunctionData[] = []; + + Object.keys(serviceClass).map((key, index) => { + methods.push({ + pkgName: serviceClass[key].split(' ')[0], + fileName: serviceClass[key].split(' ')[1], + functionName: key, + SDKFunctionName: serviceClass[key].split(' ')[2], + params: [], + returnType: null, + client: null, + }); + }); + + const files = Array.from(new Set(methods.map(method => method.fileName))); + + const sdkFiles = files.map(file => { + return { + fileName: file, + pkgName: methods[0].pkgName, + ast: null, + client: null, + sdkFunctionNames: methods + .filter(method => method.fileName === file) + .map(method => method.SDKFunctionName), + }; + }); + + await Promise.all( + sdkFiles.map(async file => { + file.ast = await getAST(file); + }) + ); + + const classData: any = extractSDKData(sdkFiles, methods); + classData.serviceName = serviceName; + const output = await transform(dummyAst, classData); + let filePath; + const dir = getDir(serviceName); + if (!fs.existsSync(process.cwd() + '/generatedClasses/Azure/' + dir)) { + fs.mkdirSync(process.cwd() + '/generatedClasses/Azure/' + dir); + } + if (/^[A-Z]*$/.test(serviceName)) { + filePath = + process.cwd() + + '/generatedClasses/Azure/' + + dir + + '/azure-' + + serviceName + + '.js'; + } else { + filePath = + process.cwd() + + '/generatedClasses/Azure/' + + dir + + '/azure-' + + serviceName.charAt(0).toLowerCase() + + serviceName.slice(1) + + '.js'; + } + printFile(filePath, output); } diff --git a/generator/generators/do/generator.ts b/generator/generators/do/generator.ts index 052b13e0..7a97277d 100644 --- a/generator/generators/do/generator.ts +++ b/generator/generators/do/generator.ts @@ -1,123 +1,129 @@ -import * as fs from "fs"; -import { createSourceFile, ScriptTarget, SyntaxKind } from "typescript"; +import * as fs from 'fs'; +import { createSourceFile, ScriptTarget, SyntaxKind } from 'typescript'; -import { getAST } from "../../parsers/do/parser"; -import { transform } from "../../transformers/do/transformer"; -import { getDir,printFile } from "../lib/helper"; +import { getAST } from '../../parsers/do/parser'; +import { transform } from '../../transformers/do/transformer'; +import { getDir, printFile } from '../lib/helper'; interface FunctionData { - functionName: string; - SDKFunctionName: string; - params: param[]; + functionName: string; + SDKFunctionName: string; + params: param[]; } interface param { - name: string; - type: string; - typeName: string; + name: string; + type: string; + typeName: string; } interface ClassData { - className: string; - functions: FunctionData[]; - serviceName: string; + className: string; + functions: FunctionData[]; + serviceName: string; } -const dummyFile = process.cwd() + "/dummyClasses/do.js"; +const dummyFile = process.cwd() + '/dummyClasses/do.js'; const dummyAst = createSourceFile( - dummyFile, - fs.readFileSync(dummyFile).toString(), - ScriptTarget.Latest, - true + dummyFile, + fs.readFileSync(dummyFile).toString(), + ScriptTarget.Latest, + true ); export function extractSDKData(sdkClassAst, serviceClass) { - let methods: FunctionData[] = []; - const functions = []; - - Object.keys(serviceClass).map((key, index) => { - functions.push(serviceClass[key].split(" ")[1]); - }); - - sdkClassAst.members.map(method => { - if (method.name && functions.includes(method.name.text)) { - let name; - Object.keys(serviceClass).map((key, index) => { - if (serviceClass[key].split(" ")[1] === method.name.text) { - name = key; - } - }); - - const parameters = []; - method.parameters.map(param => { - if (param.name.text !== "callback") { - const parameter = { - name: param.name.text, - optional: param.questionToken ? true : false, - type: SyntaxKind[param.type.kind], - typeName: null - }; - - if (parameter.type === "TypeReference" && param.type.typeName) { - parameter.typeName = param.type.typeName.text; - } - - parameters.push(parameter); - } - }); - - methods.push({ - functionName: name.toString(), - SDKFunctionName: method.name.text.toString(), - params: parameters - }); - } - }); - - const classData: ClassData = { - className: sdkClassAst.name.text, - functions: methods, - serviceName: null - }; - - return classData; + const methods: FunctionData[] = []; + const functions = []; + + Object.keys(serviceClass).map((key, index) => { + functions.push(serviceClass[key].split(' ')[1]); + }); + + sdkClassAst.members.map(method => { + if (method.name && functions.includes(method.name.text)) { + let name; + Object.keys(serviceClass).map((key, index) => { + if (serviceClass[key].split(' ')[1] === method.name.text) { + name = key; + } + }); + + const parameters = []; + method.parameters.map(param => { + if (param.name.text !== 'callback') { + const parameter = { + name: param.name.text, + optional: param.questionToken ? true : false, + type: SyntaxKind[param.type.kind], + typeName: null, + }; + + if ( + parameter.type === 'TypeReference' && + param.type.typeName + ) { + parameter.typeName = param.type.typeName.text; + } + + parameters.push(parameter); + } + }); + + methods.push({ + functionName: name.toString(), + SDKFunctionName: method.name.text.toString(), + params: parameters, + }); + } + }); + + const classData: ClassData = { + className: sdkClassAst.name.text, + functions: methods, + serviceName: null, + }; + + return classData; } export function generateDOClass(serviceClass, serviceName) { - const sdkFile = serviceClass[Object.keys(serviceClass)[0]].split(" ")[0]; - getAST(sdkFile).then(async result => { - const sdkClassAst = result; - try { - const classData: ClassData = extractSDKData(sdkClassAst, serviceClass); - classData.serviceName = serviceName; - const output = await transform(dummyAst, classData); - let filePath; - const dir = getDir(serviceName); - if (!fs.existsSync(process.cwd() + "/generatedClasses/DO/" + dir)) { - fs.mkdirSync(process.cwd() + "/generatedClasses/DO/" + dir); - } - if (/^[A-Z]*$/.test(serviceName)) { - filePath = - process.cwd() + - "/generatedClasses/DO/" + - dir + - "/do-" + - serviceName + - ".js"; - } else { - filePath = - process.cwd() + - "/generatedClasses/DO/" + - dir + - "/do-" + - serviceName.charAt(0).toLowerCase() + - serviceName.slice(1) + - ".js"; - } - printFile(filePath, output); - } catch (e) { - console.error(e); - } - }); + const sdkFile = serviceClass[Object.keys(serviceClass)[0]].split(' ')[0]; + getAST(sdkFile).then(async result => { + const sdkClassAst = result; + try { + const classData: ClassData = extractSDKData( + sdkClassAst, + serviceClass + ); + classData.serviceName = serviceName; + const output = await transform(dummyAst, classData); + let filePath; + const dir = getDir(serviceName); + if (!fs.existsSync(process.cwd() + '/generatedClasses/DO/' + dir)) { + fs.mkdirSync(process.cwd() + '/generatedClasses/DO/' + dir); + } + if (/^[A-Z]*$/.test(serviceName)) { + filePath = + process.cwd() + + '/generatedClasses/DO/' + + dir + + '/do-' + + serviceName + + '.js'; + } else { + filePath = + process.cwd() + + '/generatedClasses/DO/' + + dir + + '/do-' + + serviceName.charAt(0).toLowerCase() + + serviceName.slice(1) + + '.js'; + } + printFile(filePath, output); + } catch (e) { + console.error(e); + } + }); } diff --git a/generator/generators/googleCloud/generator.ts b/generator/generators/googleCloud/generator.ts index 9a2702cf..c3996431 100644 --- a/generator/generators/googleCloud/generator.ts +++ b/generator/generators/googleCloud/generator.ts @@ -1,388 +1,405 @@ -import * as fs from "fs"; -import * as path from "path"; -import { createSourceFile, ScriptTarget,SyntaxKind } from "typescript"; +import * as fs from 'fs'; +import * as path from 'path'; +import { createSourceFile, ScriptTarget, SyntaxKind } from 'typescript'; -import { getAST } from "../../parsers/googleCloud/parser"; -import { classBasedTransform } from "../../transformers/googleCloud/classBasedTransformer"; -import { clientBasedTransform } from "../../transformers/googleCloud/clientBasedTransformer"; -import { filters, getDir,groupers, printFile } from "../lib/helper"; +import { getAST } from '../../parsers/googleCloud/parser'; +import { classBasedTransform } from '../../transformers/googleCloud/classBasedTransformer'; +import { clientBasedTransform } from '../../transformers/googleCloud/clientBasedTransformer'; +import { filters, getDir, groupers, printFile } from '../lib/helper'; interface ClassData { - name: string; - methods: FunctionData[]; - constructor: constructorData; - properties: propertyData[]; + name: string; + methods: FunctionData[]; + constructor: constructorData; + properties: propertyData[]; } interface FunctionData { - pkgName: string; - version: string; - fileName: string; - functionName: string; - SDKFunctionName: string; - params: param[]; - returnType: string; - returnTypeName: string; - client: string; + pkgName: string; + version: string; + fileName: string; + functionName: string; + SDKFunctionName: string; + params: param[]; + returnType: string; + returnTypeName: string; + client: string; } interface propertyData { - name: string; - type: string; + name: string; + type: string; } interface constructorData { - parameters: param[]; + parameters: param[]; } interface param { - name: string; - type: string; - optional: boolean; + name: string; + type: string; + optional: boolean; } -const dummyFile = process.cwd() + "/dummyClasses/gcp.js"; +const dummyFile = process.cwd() + '/dummyClasses/gcp.js'; const dummyAst = createSourceFile( - dummyFile, - fs.readFileSync(dummyFile).toString(), - ScriptTarget.Latest, - true + dummyFile, + fs.readFileSync(dummyFile).toString(), + ScriptTarget.Latest, + true ); export function extractClassBasedSDKData(methods, sdkFiles): any { - const specifiedMethods = JSON.parse(JSON.stringify(methods)); - return new Promise(async (resolve, reject) => { - try { - let classes: ClassData[] = []; - - sdkFiles.map(file => { - file.classes.map(classAst => { - const classInfo: ClassData = { - name: classAst.name.text, - methods: [], - properties: [], - constructor: null - }; - - classAst.members.map(member => { - if (SyntaxKind[member.kind] === "MethodDeclaration") { - const returnType = SyntaxKind[member.type.kind]; - - const parameters = member.parameters.map(param => { - return { - name: param.name.text, - optional: param.questionToken ? true : false, - type: SyntaxKind[param.type.kind] - }; - }); - const method: FunctionData = { - pkgName: file.pkgName, - version: null, - fileName: file.fileName, - functionName: null, - SDKFunctionName: member.name.text, - params: parameters, - returnType: returnType, - returnTypeName: null, - client: classAst.name.text // Class name - }; - - if (returnType === "TypeReference") { - method.returnTypeName = member.type.typeName.text; - } - - const meth = methods.find( - meth => - meth.SDKFunctionName === method.SDKFunctionName && - meth.fileName === method.fileName - ); - method.functionName = meth ? meth.functionName : null; - classInfo.methods.push(method); - } - - if (SyntaxKind[member.kind] === "Constructor") { - const parameters = member.parameters.map(param => { - return { - name: param.name.text, - optional: param.questionToken ? true : false, - type: SyntaxKind[param.type.kind], - typeRefName: param.type.typeName - ? param.type.typeName.text - : null - }; - }); - - classInfo.constructor = { - parameters - }; - } - - if (SyntaxKind[member.kind] === "PropertyDeclaration") { - const isPrivateProp = - member.modifiers && - member.modifiers.some( - modifier => SyntaxKind[modifier.kind] === "PrivateKeyword" - ); - if (!isPrivateProp) { - const prop = { - name: member.name.text, - type: SyntaxKind[member.type.kind], - typeRefName: member.type.typeName - ? member.type.typeName.text - : null - }; - classInfo.properties.push(prop); - } - } - }); - classes.push(classInfo); - }); - }); - - methods = []; - - classes.map(classData => { - let filteredMethods: any = classData.methods.filter( - meth => meth.functionName !== null - ); - filteredMethods.map(filMeth => { - filMeth.classConstructorData = classData.constructor; - }); - - methods = methods.concat(filteredMethods); - }); - - const extractedData = { - classes, - methods - }; - if (JSON.stringify(methods) === JSON.stringify(specifiedMethods)) { - reject(new Error("Data extraction unsuccessful")); - } else { - resolve(extractedData); - } - } catch (error) { - reject(error); - } - }); + const specifiedMethods = JSON.parse(JSON.stringify(methods)); + return new Promise(async (resolve, reject) => { + try { + const classes: ClassData[] = []; + + sdkFiles.map(file => { + file.classes.map(classAst => { + const classInfo: ClassData = { + name: classAst.name.text, + methods: [], + properties: [], + constructor: null, + }; + + classAst.members.map(member => { + if (SyntaxKind[member.kind] === 'MethodDeclaration') { + const returnType = SyntaxKind[member.type.kind]; + + const parameters = member.parameters.map(param => { + return { + name: param.name.text, + optional: param.questionToken + ? true + : false, + type: SyntaxKind[param.type.kind], + }; + }); + const method: FunctionData = { + pkgName: file.pkgName, + version: null, + fileName: file.fileName, + functionName: null, + SDKFunctionName: member.name.text, + params: parameters, + returnType: returnType, + returnTypeName: null, + client: classAst.name.text, // Class name + }; + + if (returnType === 'TypeReference') { + method.returnTypeName = + member.type.typeName.text; + } + + const meth = methods.find( + meth => + meth.SDKFunctionName === + method.SDKFunctionName && + meth.fileName === method.fileName + ); + method.functionName = meth + ? meth.functionName + : null; + classInfo.methods.push(method); + } + + if (SyntaxKind[member.kind] === 'Constructor') { + const parameters = member.parameters.map(param => { + return { + name: param.name.text, + optional: param.questionToken + ? true + : false, + type: SyntaxKind[param.type.kind], + typeRefName: param.type.typeName + ? param.type.typeName.text + : null, + }; + }); + + classInfo.constructor = { + parameters, + }; + } + + if (SyntaxKind[member.kind] === 'PropertyDeclaration') { + const isPrivateProp = + member.modifiers && + member.modifiers.some( + modifier => + SyntaxKind[modifier.kind] === + 'PrivateKeyword' + ); + if (!isPrivateProp) { + const prop = { + name: member.name.text, + type: SyntaxKind[member.type.kind], + typeRefName: member.type.typeName + ? member.type.typeName.text + : null, + }; + classInfo.properties.push(prop); + } + } + }); + classes.push(classInfo); + }); + }); + + methods = []; + + classes.map(classData => { + const filteredMethods: any = classData.methods.filter( + meth => meth.functionName !== null + ); + filteredMethods.map(filMeth => { + filMeth.classConstructorData = classData.constructor; + }); + + methods = methods.concat(filteredMethods); + }); + + const extractedData = { + classes, + methods, + }; + if (JSON.stringify(methods) === JSON.stringify(specifiedMethods)) { + reject(new Error('Data extraction unsuccessful')); + } else { + resolve(extractedData); + } + } catch (error) { + reject(error); + } + }); } export function extractClientBasedSDKdata(methods, sdkFiles): any { - const specifiedMethods = JSON.parse(JSON.stringify(methods)); - return new Promise(async (resolve, reject) => { - try { - sdkFiles.map(sdkFile => { - sdkFile.client = sdkFile.ast.name.text; - sdkFile.ast.members.map(member => { - if ( - SyntaxKind[member.kind] === "MethodDeclaration" && - sdkFile.sdkFunctionNames.includes(member.name.text) - ) { - const method = methods.find( - methd => methd.SDKFunctionName === member.name.text - ); - - const parameters = member.parameters.map(param => { - return { - name: param.name.text, - optional: param.questionToken ? true : false, - type: SyntaxKind[param.type.kind] - }; - }); - - const returnType = SyntaxKind[member.type.kind]; - if (returnType === "TypeReference") { - method.returnTypeName = member.type.typeName.text; - } - - if (!method.returnType) { - method.params = parameters; - method.returnType = returnType; - method.client = sdkFile.client; - } else { - const clone = JSON.parse(JSON.stringify(method)); - clone.params = parameters; - clone.returnType = returnType; - clone.client = sdkFile.client; - methods.push(clone); - } - } - }); - }); - - if (JSON.stringify(methods) === JSON.stringify(specifiedMethods)) { - reject(new Error("Data extraction unsuccessful")); - } else { - resolve(methods); - } - } catch (error) { - reject(error); - } - }); + const specifiedMethods = JSON.parse(JSON.stringify(methods)); + return new Promise(async (resolve, reject) => { + try { + sdkFiles.map(sdkFile => { + sdkFile.client = sdkFile.ast.name.text; + sdkFile.ast.members.map(member => { + if ( + SyntaxKind[member.kind] === 'MethodDeclaration' && + sdkFile.sdkFunctionNames.includes(member.name.text) + ) { + const method = methods.find( + methd => methd.SDKFunctionName === member.name.text + ); + + const parameters = member.parameters.map(param => { + return { + name: param.name.text, + optional: param.questionToken ? true : false, + type: SyntaxKind[param.type.kind], + }; + }); + + const returnType = SyntaxKind[member.type.kind]; + if (returnType === 'TypeReference') { + method.returnTypeName = member.type.typeName.text; + } + + if (!method.returnType) { + method.params = parameters; + method.returnType = returnType; + method.client = sdkFile.client; + } else { + const clone = JSON.parse(JSON.stringify(method)); + clone.params = parameters; + clone.returnType = returnType; + clone.client = sdkFile.client; + methods.push(clone); + } + } + }); + }); + + if (JSON.stringify(methods) === JSON.stringify(specifiedMethods)) { + reject(new Error('Data extraction unsuccessful')); + } else { + resolve(methods); + } + } catch (error) { + reject(error); + } + }); } async function generateClassBasedCode(methods, data, serviceName) { - const dirPath = `../../../node_modules/@google-cloud/${methods[0].pkgName}/build/src/`; - let files = fs.readdirSync(path.join(__dirname, dirPath)); - files = files.filter( - fileName => - fileName.split(".")[1] === "d" && fileName.split(".")[2] === "ts" - ); - - const sdkFiles = files.map(fileName => { - return { - fileName: fileName, - pkgName: methods[0].pkgName, - classes: null, - sdkFunctionNames: methods - .filter(method => method.fileName === fileName) - .map(method => method.SDKFunctionName) - }; - }); - - await Promise.all( - sdkFiles.map(async file => { - file.classes = await getAST(file, true); - }) - ); - - const extractedData = await extractClassBasedSDKData(methods, sdkFiles).then( - result => result - ); - const groupedMethods = groupers.gcp(extractedData.methods); - methods = filters.gcp(groupedMethods); - data.functions = methods; - data.classData = extractedData.classes; - data.serviceName = serviceName; - - const output = await classBasedTransform(dummyAst, data); - let filePath; - const dir = getDir(serviceName); - if (!fs.existsSync(process.cwd() + "/generatedClasses/googleCloud/" + dir)) { - fs.mkdirSync(process.cwd() + "/generatedClasses/googleCloud/" + dir); - } - if (/^[A-Z]*$/.test(serviceName)) { - filePath = - process.cwd() + - "/generatedClasses/googleCloud/" + - dir + - "/gcp-" + - serviceName + - ".js"; - } else { - filePath = - process.cwd() + - "/generatedClasses/googleCloud/" + - dir + - "/gcp-" + - serviceName.charAt(0).toLowerCase() + - serviceName.slice(1) + - ".js"; - } - printFile(filePath, output); + const dirPath = `../../../node_modules/@google-cloud/${methods[0].pkgName}/build/src/`; + let files = fs.readdirSync(path.join(__dirname, dirPath)); + files = files.filter( + fileName => + fileName.split('.')[1] === 'd' && fileName.split('.')[2] === 'ts' + ); + + const sdkFiles = files.map(fileName => { + return { + fileName: fileName, + pkgName: methods[0].pkgName, + classes: null, + sdkFunctionNames: methods + .filter(method => method.fileName === fileName) + .map(method => method.SDKFunctionName), + }; + }); + + await Promise.all( + sdkFiles.map(async file => { + file.classes = await getAST(file, true); + }) + ); + + const extractedData = await extractClassBasedSDKData( + methods, + sdkFiles + ).then(result => result); + const groupedMethods = groupers.gcp(extractedData.methods); + methods = filters.gcp(groupedMethods); + data.functions = methods; + data.classData = extractedData.classes; + data.serviceName = serviceName; + + const output = await classBasedTransform(dummyAst, data); + let filePath; + const dir = getDir(serviceName); + if ( + !fs.existsSync(process.cwd() + '/generatedClasses/googleCloud/' + dir) + ) { + fs.mkdirSync(process.cwd() + '/generatedClasses/googleCloud/' + dir); + } + if (/^[A-Z]*$/.test(serviceName)) { + filePath = + process.cwd() + + '/generatedClasses/googleCloud/' + + dir + + '/gcp-' + + serviceName + + '.js'; + } else { + filePath = + process.cwd() + + '/generatedClasses/googleCloud/' + + dir + + '/gcp-' + + serviceName.charAt(0).toLowerCase() + + serviceName.slice(1) + + '.js'; + } + printFile(filePath, output); } async function generateClientBasedCode(methods, serviceName) { - const files = Array.from( - new Set(methods.map(method => method.fileName + " " + method.version)) - ); - const sdkFiles = files.map(file => { - return { - fileName: (file).split(" ")[0], - version: (file).split(" ")[1], - pkgName: methods[0].pkgName, - ast: null, - client: null, - sdkFunctionNames: methods - .filter(method => method.fileName === (file).split(" ")[0]) - .map(method => method.SDKFunctionName) - }; - }); - - await Promise.all( - sdkFiles.map(async file => { - file.ast = await getAST(file); - }) - ); - - methods = await extractClientBasedSDKdata(methods, sdkFiles).then( - result => result - ); - const groupedMethods = groupers.gcp(methods); - methods = filters.gcp(groupedMethods); - - const classData = { - functions: methods, - serviceName - }; - - const output = await clientBasedTransform(dummyAst, classData); - let filePath; - const dir = getDir(serviceName); - if (!fs.existsSync(process.cwd() + "/generatedClasses/googleCloud/" + dir)) { - fs.mkdirSync(process.cwd() + "/generatedClasses/googleCloud/" + dir); - } - if (/^[A-Z]*$/.test(serviceName)) { - filePath = - process.cwd() + - "/generatedClasses/googleCloud/" + - dir + - "/gcp-" + - serviceName + - ".js"; - } else { - filePath = - process.cwd() + - "/generatedClasses/googleCloud/" + - dir + - "/gcp-" + - serviceName.charAt(0).toLowerCase() + - serviceName.slice(1) + - ".js"; - } - printFile(filePath, output); + const files = Array.from( + new Set(methods.map(method => method.fileName + ' ' + method.version)) + ); + const sdkFiles = files.map(file => { + return { + fileName: (file).split(' ')[0], + version: (file).split(' ')[1], + pkgName: methods[0].pkgName, + ast: null, + client: null, + sdkFunctionNames: methods + .filter( + method => method.fileName === (file).split(' ')[0] + ) + .map(method => method.SDKFunctionName), + }; + }); + + await Promise.all( + sdkFiles.map(async file => { + file.ast = await getAST(file); + }) + ); + + methods = await extractClientBasedSDKdata(methods, sdkFiles).then( + result => result + ); + const groupedMethods = groupers.gcp(methods); + methods = filters.gcp(groupedMethods); + + const classData = { + functions: methods, + serviceName, + }; + + const output = await clientBasedTransform(dummyAst, classData); + let filePath; + const dir = getDir(serviceName); + if ( + !fs.existsSync(process.cwd() + '/generatedClasses/googleCloud/' + dir) + ) { + fs.mkdirSync(process.cwd() + '/generatedClasses/googleCloud/' + dir); + } + if (/^[A-Z]*$/.test(serviceName)) { + filePath = + process.cwd() + + '/generatedClasses/googleCloud/' + + dir + + '/gcp-' + + serviceName + + '.js'; + } else { + filePath = + process.cwd() + + '/generatedClasses/googleCloud/' + + dir + + '/gcp-' + + serviceName.charAt(0).toLowerCase() + + serviceName.slice(1) + + '.js'; + } + printFile(filePath, output); } export async function generateGCPClass(serviceClass, serviceName) { - let methods: FunctionData[] = []; - const data: any = {}; - - Object.keys(serviceClass).map((key, index) => { - if (key === "mainClass") { - data.mainClass = serviceClass[key]; - } else if ( - serviceClass[key].split(" ")[1].length === 2 && - serviceClass[key].split(" ")[1].charAt(0) === "v" - ) { - methods.push({ - pkgName: serviceClass[key].split(" ")[0], - version: serviceClass[key].split(" ")[1], - fileName: serviceClass[key].split(" ")[2], - functionName: key, - SDKFunctionName: serviceClass[key].split(" ")[3], - params: [], - returnType: null, - returnTypeName: null, - client: null - }); - } else { - methods.push({ - pkgName: serviceClass[key].split(" ")[0], - version: null, - fileName: serviceClass[key].split(" ")[1], - functionName: key, - SDKFunctionName: serviceClass[key].split(" ")[2], - params: [], - returnType: null, - returnTypeName: null, - client: null - }); - } - }); - - if (methods[0].version) { - generateClientBasedCode(methods, serviceName); - } else { - generateClassBasedCode(methods, data, serviceName); - } + const methods: FunctionData[] = []; + const data: any = {}; + + Object.keys(serviceClass).map((key, index) => { + if (key === 'mainClass') { + data.mainClass = serviceClass[key]; + } else if ( + serviceClass[key].split(' ')[1].length === 2 && + serviceClass[key].split(' ')[1].charAt(0) === 'v' + ) { + methods.push({ + pkgName: serviceClass[key].split(' ')[0], + version: serviceClass[key].split(' ')[1], + fileName: serviceClass[key].split(' ')[2], + functionName: key, + SDKFunctionName: serviceClass[key].split(' ')[3], + params: [], + returnType: null, + returnTypeName: null, + client: null, + }); + } else { + methods.push({ + pkgName: serviceClass[key].split(' ')[0], + version: null, + fileName: serviceClass[key].split(' ')[1], + functionName: key, + SDKFunctionName: serviceClass[key].split(' ')[2], + params: [], + returnType: null, + returnTypeName: null, + client: null, + }); + } + }); + + if (methods[0].version) { + generateClientBasedCode(methods, serviceName); + } else { + generateClassBasedCode(methods, data, serviceName); + } } diff --git a/generator/generators/lib/aws/awsHelper.ts b/generator/generators/lib/aws/awsHelper.ts index 7cfe04de..13ddcd09 100644 --- a/generator/generators/lib/aws/awsHelper.ts +++ b/generator/generators/lib/aws/awsHelper.ts @@ -1,32 +1,32 @@ export function groupAWSMethods(methods): any { - const methodArr = Object.values( - methods.reduce((result, { functionName, SDKFunctionName, params }) => { - // Create new group - if (!result[functionName]) - result[functionName] = { - functionName, - array: [] - }; - // Append to group - result[functionName].array.push({ - functionName, - SDKFunctionName, - params - }); - return result; - }, {}) - ); + const methodArr = Object.values( + methods.reduce((result, { functionName, SDKFunctionName, params }) => { + // Create new group + if (!result[functionName]) + result[functionName] = { + functionName, + array: [], + }; + // Append to group + result[functionName].array.push({ + functionName, + SDKFunctionName, + params, + }); + return result; + }, {}) + ); - return methodArr; + return methodArr; } export function filterAWSMethods(groupedMethods): any { - let methods = []; - groupedMethods.map(group => { - group.array.sort(function(a, b) { - return a.params.length - b.params.length; - }); - methods.push(group.array.slice(-1)[0]); - }); - return methods; + const methods = []; + groupedMethods.map(group => { + group.array.sort(function(a, b) { + return a.params.length - b.params.length; + }); + methods.push(group.array.slice(-1)[0]); + }); + return methods; } diff --git a/generator/generators/lib/azure/azureHelper.ts b/generator/generators/lib/azure/azureHelper.ts index dc066724..d9d752db 100644 --- a/generator/generators/lib/azure/azureHelper.ts +++ b/generator/generators/lib/azure/azureHelper.ts @@ -1,60 +1,60 @@ export function groupAzureMethods(methods): any { - const methodArr = Object.values( - methods.reduce( - ( - result, - { - functionName, - SDKFunctionName, - params, - pkgName, - fileName, - client, - returnType - } - ) => { - // Create new group - if (!result[functionName]) - result[functionName] = { - functionName, - array: [] - }; - // Append to group - result[functionName].array.push({ - functionName, - SDKFunctionName, - params, - pkgName, - fileName, - client, - returnType - }); - return result; - }, - {} - ) - ); + const methodArr = Object.values( + methods.reduce( + ( + result, + { + functionName, + SDKFunctionName, + params, + pkgName, + fileName, + client, + returnType, + } + ) => { + // Create new group + if (!result[functionName]) + result[functionName] = { + functionName, + array: [], + }; + // Append to group + result[functionName].array.push({ + functionName, + SDKFunctionName, + params, + pkgName, + fileName, + client, + returnType, + }); + return result; + }, + {} + ) + ); - return methodArr; + return methodArr; } export function filterAzureMethods(groupedMethods): any { - let methods = []; - groupedMethods.map(group => { - if (group.array.length === 1) { - methods.push(group.array[0]); - } else { - let methodPushed = false; - group.array.map(method => { - if (!method.params.find(param => param.name === "callback")) { - methods.push(method); - methodPushed = true; - } - }); - if (!methodPushed) { - methods.push(group.array[0]); - } - } - }); - return methods; + const methods = []; + groupedMethods.map(group => { + if (group.array.length === 1) { + methods.push(group.array[0]); + } else { + let methodPushed = false; + group.array.map(method => { + if (!method.params.find(param => param.name === 'callback')) { + methods.push(method); + methodPushed = true; + } + }); + if (!methodPushed) { + methods.push(group.array[0]); + } + } + }); + return methods; } diff --git a/generator/generators/lib/googleCloud/gcpHelper.ts b/generator/generators/lib/googleCloud/gcpHelper.ts index 2b93f726..ee196b45 100644 --- a/generator/generators/lib/googleCloud/gcpHelper.ts +++ b/generator/generators/lib/googleCloud/gcpHelper.ts @@ -1,64 +1,64 @@ export function groupGCPMethods(methods): any { - const methodArr = Object.values( - methods.reduce( - ( - result, - { - functionName, - SDKFunctionName, - params, - pkgName, - fileName, - client, - returnType, - returnTypeName, - classConstructorData - } - ) => { - // Create new group - if (!result[functionName]) - result[functionName] = { - functionName, - array: [] - }; - // Append to group - result[functionName].array.push({ - functionName, - SDKFunctionName, - params, - pkgName, - fileName, - client, - returnType, - returnTypeName, - classConstructorData - }); - return result; - }, - {} - ) - ); + const methodArr = Object.values( + methods.reduce( + ( + result, + { + functionName, + SDKFunctionName, + params, + pkgName, + fileName, + client, + returnType, + returnTypeName, + classConstructorData, + } + ) => { + // Create new group + if (!result[functionName]) + result[functionName] = { + functionName, + array: [], + }; + // Append to group + result[functionName].array.push({ + functionName, + SDKFunctionName, + params, + pkgName, + fileName, + client, + returnType, + returnTypeName, + classConstructorData, + }); + return result; + }, + {} + ) + ); - return methodArr; + return methodArr; } export function filterGCPMethods(groupedMethods): any { - let methods = []; - groupedMethods.map(group => { - if (group.array.length === 1) { - methods.push(group.array[0]); - } else { - let methodPushed = false; - group.array.map(method => { - if (!method.params.find(param => param.name === "callback")) { - methods.push(method); - methodPushed = true; - } - }); - if (!methodPushed) { - methods.push(group.array[0]); - } - } - }); - return methods; + const methods = []; + groupedMethods.map(group => { + if (group.array.length === 1) { + methods.push(group.array[0]); + } else { + let methodPushed = false; + group.array.map(method => { + if (!method.params.find(param => param.name === 'callback')) { + methods.push(method); + methodPushed = true; + } + }); + if (!methodPushed) { + methods.push(group.array[0]); + } + } + }); + return methods; } diff --git a/generator/generators/lib/helper.ts b/generator/generators/lib/helper.ts index 31c67b7c..883aebc9 100644 --- a/generator/generators/lib/helper.ts +++ b/generator/generators/lib/helper.ts @@ -1,48 +1,48 @@ -import * as fs from "fs"; +import * as fs from 'fs'; -import { groupAWSMethods } from "../lib/aws/awsHelper"; -import { filterAWSMethods } from "../lib/aws/awsHelper"; -import { groupAzureMethods } from "../lib/azure/azureHelper"; -import { filterAzureMethods } from "../lib/azure/azureHelper"; -import { groupGCPMethods } from "../lib/googleCloud/gcpHelper"; -import { filterGCPMethods } from "../lib/googleCloud/gcpHelper"; +import { groupAWSMethods } from '../lib/aws/awsHelper'; +import { filterAWSMethods } from '../lib/aws/awsHelper'; +import { groupAzureMethods } from '../lib/azure/azureHelper'; +import { filterAzureMethods } from '../lib/azure/azureHelper'; +import { groupGCPMethods } from '../lib/googleCloud/gcpHelper'; +import { filterGCPMethods } from '../lib/googleCloud/gcpHelper'; const dirMap = { - appServices: ["PaaS"], - compute: ["ComputeInstance", "Kubernetes", "Container"], - database: ["NoSqlIndexed", "RDBMS", "NoSql"], - management: ["Monitoring", "KeyManagement", "NotificationService"], - network: ["DNS", "LoadBalancer"], - security: ["IAM"], - storage: ["StorageBucket", "BlockStorage", "ArchivalStorage"], - artificialinteligence: ["Translation"] + appServices: ['PaaS'], + compute: ['ComputeInstance', 'Kubernetes', 'Container'], + database: ['NoSqlIndexed', 'RDBMS', 'NoSql'], + management: ['Monitoring', 'KeyManagement', 'NotificationService'], + network: ['DNS', 'LoadBalancer'], + security: ['IAM'], + storage: ['StorageBucket', 'BlockStorage', 'ArchivalStorage'], + artificialinteligence: ['Translation'], }; export function printFile(fileName, data) { - fs.writeFile(fileName, data, function(err) { - if (err) throw err; - }); + fs.writeFile(fileName, data, function(err) { + if (err) throw err; + }); } const groupers = { - aws: groupAWSMethods, - gcp: groupGCPMethods, - azure: groupAzureMethods + aws: groupAWSMethods, + gcp: groupGCPMethods, + azure: groupAzureMethods, }; const filters = { - aws: filterAWSMethods, - gcp: filterGCPMethods, - azure: filterAzureMethods + aws: filterAWSMethods, + gcp: filterGCPMethods, + azure: filterAzureMethods, }; const getDir = (service: string): string => { - for (let dir in dirMap) { - if (dirMap[dir].includes(service)) { - return dir; - } - } - throw new Error("Not a valid service: " + service); + for (const dir in dirMap) { + if (dirMap[dir].includes(service)) { + return dir; + } + } + throw new Error('Not a valid service: ' + service); }; -export { filters, getDir,groupers }; +export { filters, getDir, groupers }; diff --git a/generator/generators/linode/generator.js b/generator/generators/linode/generator.js new file mode 100644 index 00000000..16932040 --- /dev/null +++ b/generator/generators/linode/generator.js @@ -0,0 +1,263 @@ +'use strict'; +var __awaiter = + (this && this.__awaiter) || + function(thisArg, _arguments, P, generator) { + function adopt(value) { + return value instanceof P + ? value + : new P(function(resolve) { + resolve(value); + }); + } + return new (P || (P = Promise))(function(resolve, reject) { + function fulfilled(value) { + try { + step(generator.next(value)); + } catch (e) { + reject(e); + } + } + function rejected(value) { + try { + step(generator['throw'](value)); + } catch (e) { + reject(e); + } + } + function step(result) { + result.done + ? resolve(result.value) + : adopt(result.value).then(fulfilled, rejected); + } + step( + (generator = generator.apply(thisArg, _arguments || [])).next() + ); + }); + }; +var __generator = + (this && this.__generator) || + function(thisArg, body) { + var _ = { + label: 0, + sent: function() { + if (t[0] & 1) throw t[1]; + return t[1]; + }, + trys: [], + ops: [], + }, + f, + y, + t, + g; + return ( + (g = { next: verb(0), throw: verb(1), return: verb(2) }), + typeof Symbol === 'function' && + (g[Symbol.iterator] = function() { + return this; + }), + g + ); + function verb(n) { + return function(v) { + return step([n, v]); + }; + } + function step(op) { + if (f) throw new TypeError('Generator is already executing.'); + while (_) + try { + if ( + ((f = 1), + y && + (t = + op[0] & 2 + ? y['return'] + : op[0] + ? y['throw'] || + ((t = y['return']) && t.call(y), 0) + : y.next) && + !(t = t.call(y, op[1])).done) + ) + return t; + if (((y = 0), t)) op = [op[0] & 2, t.value]; + switch (op[0]) { + case 0: + case 1: + t = op; + break; + case 4: + _.label++; + return { value: op[1], done: false }; + case 5: + _.label++; + y = op[1]; + op = [0]; + continue; + case 7: + op = _.ops.pop(); + _.trys.pop(); + continue; + default: + if ( + !((t = _.trys), + (t = t.length > 0 && t[t.length - 1])) && + (op[0] === 6 || op[0] === 2) + ) { + _ = 0; + continue; + } + if ( + op[0] === 3 && + (!t || (op[1] > t[0] && op[1] < t[3])) + ) { + _.label = op[1]; + break; + } + if (op[0] === 6 && _.label < t[1]) { + _.label = t[1]; + t = op; + break; + } + if (t && _.label < t[2]) { + _.label = t[2]; + _.ops.push(op); + break; + } + if (t[2]) _.ops.pop(); + _.trys.pop(); + continue; + } + op = body.call(thisArg, _); + } catch (e) { + op = [6, e]; + y = 0; + } finally { + f = t = 0; + } + if (op[0] & 5) throw op[1]; + return { value: op[0] ? op[1] : void 0, done: true }; + } + }; +exports.__esModule = true; +exports.generateLinodeClass = exports.extractSDKData = void 0; +var typescript_1 = require('typescript'); +var parser_1 = require('../../parsers/linode/parser'); +function extractSDKData(sdkAst, serviceClass) { + var methods = []; + var functions = []; + Object.keys(serviceClass).map(function(key, index) { + functions.push(serviceClass[key].split(' ')[2]); + }); + sdkAst.map(function(method) { + var methodName = method.name.escapedText; + if (methodName && functions.includes(methodName)) { + var name_1; + Object.keys(serviceClass).map(function(key, index) { + if (serviceClass[key].split(' ')[2] === methodName) { + name_1 = key; + } + }); + var parameters_1 = []; + var methodParameters = method.type.parameters; + methodParameters.map(function(param) { + if (param.name.excapedText !== 'callback') { + var parameter = { + name: param.name.escapedText, + optional: param.questionToken ? true : false, + type: typescript_1.SyntaxKind[param.type.kind], + typeName: null, + }; + // common type + if (param.type.typeName) { + parameter.typeName = param.type.typeName.excapedText; + } + parameters_1.push(parameter); + } + }); + methods.push({ + functionName: name_1.toString(), + SDKFunctionName: methodName, + params: parameters_1, + }); + } + }); + var classData = { + className: '', + functions: methods, + serviceName: null, + }; + return classData; +} +exports.extractSDKData = extractSDKData; +function generateLinodeClass(serviceClass, serviceName) { + return __awaiter(this, void 0, void 0, function() { + var methods, files, sdkFiles; + var _this = this; + return __generator(this, function(_a) { + methods = []; + if (serviceClass == null) return [2 /*return*/]; + Object.keys(serviceClass).map(function(key, index) { + methods.push({ + pkgName: serviceClass[key].split(' ')[0], + fileName: serviceClass[key].split(' ')[1], + functionName: key, + SDKFunctionName: serviceClass[key].split(' ')[2], + params: [], + returnType: null, + client: null, + }); + }); + files = Array.from( + new Set( + methods.map(function(method) { + return method.fileName; + }) + ) + ); + sdkFiles = files.map(function(file) { + return { + fileName: file, + pkgName: methods[0].pkgName, + ast: null, + client: null, + sdkFunctionNames: methods + .filter(function(method) { + return method.fileName === file; + }) + .map(function(method) { + return method.SDKFunctionName; + }), + }; + }); + sdkFiles.map(function(file) { + return __awaiter(_this, void 0, void 0, function() { + var _this = this; + return __generator(this, function(_a) { + parser_1.getAST(file).then(function(result) { + return __awaiter(_this, void 0, void 0, function() { + var sdkAst, classData; + return __generator(this, function(_a) { + sdkAst = result; + try { + classData = extractSDKData( + sdkAst, + serviceClass + ); + classData.serviceName = serviceName; + } catch (e) { + console.error(e); + } + return [2 /*return*/]; + }); + }); + }); + return [2 /*return*/]; + }); + }); + }); + return [2 /*return*/]; + }); + }); +} +exports.generateLinodeClass = generateLinodeClass; diff --git a/generator/generators/linode/generator.ts b/generator/generators/linode/generator.ts new file mode 100644 index 00000000..5a50e74c --- /dev/null +++ b/generator/generators/linode/generator.ts @@ -0,0 +1,158 @@ +import * as fs from 'fs'; +import { createSourceFile, ScriptTarget,SyntaxKind } from 'typescript'; + +import { getAST } from '../../parsers/linode/parser'; +import { getDir, printFile } from '../lib/helper'; + +interface SDKClassData { + pkgName: string; + fileName: string; + functionName: string; + SDKFunctionName: string; + params: param[]; + returnType: string; + client: string; +} + +interface FunctionData { + functionName: string; + SDKFunctionName: string; + params: param[]; +} + +interface ClassData { + className: string; + functions: FunctionData[]; + serviceName: string; +} + +interface param { + name: string; + type: string; + typeName: string; + optional: boolean; +} + +const dummyFile = process.cwd() + '/dummyClasses/linode.js'; + +const dummyAst = createSourceFile( + dummyFile, + fs.readFileSync(dummyFile).toString(), + ScriptTarget.Latest, + true +); + +export function extractSDKData(sdkAst, serviceClass) { + const methods: FunctionData[] = []; + const functions = []; + + Object.keys(serviceClass).map((key, index) => { + functions.push(serviceClass[key].split(' ')[2]); + }); + + sdkAst.map(method => { + const methodName = method.name.escapedText; + if (methodName && functions.includes(methodName)) { + let name; + Object.keys(serviceClass).map((key, index) => { + if (serviceClass[key].split(' ')[2] === methodName) { + name = key; + } + }); + const parameters = []; + + const methodParameters = method.type.parameters; + + methodParameters.map(param => { + if (param.name.excapedText !== 'callback') { + const parameter: param = { + name: param.name.escapedText, + optional: param.questionToken ? true : false, + type: SyntaxKind[param.type.kind], + typeName: null, + }; + // common type + if (param.type.typeName) { + parameter.typeName = param.type.typeName.text; + } + parameters.push(parameter); + } + }); + methods.push({ + functionName: name.toString(), + SDKFunctionName: methodName, + params: parameters, + }); + } + }); + + return methods; +} + +export async function getFunctions(sdkFiles, serviceClass) { + const functionsArray: FunctionData[] = []; + await sdkFiles.map(async file => { + getAST(file).then(async result => { + const sdkAst = result; + try { + const functions: FunctionData[] = extractSDKData( + sdkAst, + serviceClass + ); + + functions.map((method, index) => { + functionsArray.push(method); + }); + } catch (e) { + console.error(e); + } + }); + }); + return functionsArray; +} + +export async function generateLinodeClass(serviceClass, serviceName) { + try { + const methods: SDKClassData[] = []; + if (serviceClass == null) return; + Object.keys(serviceClass).map((key, index) => { + methods.push({ + pkgName: serviceClass[key].split(' ')[0], + fileName: serviceClass[key].split(' ')[1], + functionName: key, + SDKFunctionName: serviceClass[key].split(' ')[2], + params: [], + returnType: null, + client: null, + }); + }); + + const files = Array.from( + new Set(methods.map(method => method.fileName)) + ); + + const sdkFiles = files.map(file => { + return { + fileName: file, + pkgName: methods[0].pkgName, + ast: null, + client: null, + sdkFunctionNames: methods + .filter(method => method.fileName === file) + .map(method => method.SDKFunctionName), + }; + }); + const functionsArray: FunctionData[] = await getFunctions( + sdkFiles, + serviceClass + ); + + const classData: ClassData = { + className: serviceName + 'LinodeClass', + functions: functionsArray, + serviceName: serviceName, + }; + } catch (e) { + console.error(e); + } +} \ No newline at end of file diff --git a/generator/main.js b/generator/main.js index 8d4cf2c2..5c5205a5 100644 --- a/generator/main.js +++ b/generator/main.js @@ -2,6 +2,7 @@ exports.__esModule = true; var fs = require('fs'); var yaml = require('js-yaml'); +var generator_6 = require('./generators/linode/generator'); var generator_5 = require('./generators/oracle/generator'); var generator_1 = require('./generators/aws/generator'); var generator_2 = require('./generators/azure/generator'); @@ -36,7 +37,12 @@ try { services_1[service][provider], service ); - } + } else if (provider == 'Linode') { + generator_6.generateLinodeClass( + services_1[service][provider], + service + ); + } }); }); } catch (error) { diff --git a/generator/main.ts b/generator/main.ts index 4e8cbfd4..699d6016 100644 --- a/generator/main.ts +++ b/generator/main.ts @@ -5,6 +5,7 @@ import { generateAWSClass } from './generators/aws/generator'; import { generateAzureClass } from './generators/azure/generator'; import { generateDOClass } from './generators/do/generator'; import { generateGCPClass } from './generators/googleCloud/generator'; +import { generateLinodeClass } from './generators/linode/generator'; import { generateOracleClass } from './generators/oracle/generator'; try { @@ -21,7 +22,9 @@ try { generateDOClass(services[service][provider], service); } else if (provider == "Oracle") { generateOracleClass(services[service][provider], service); - } + } else if (provider == 'Linode') { + generateLinodeClass(services[service][provider], service); + } }); }); } catch (error) { diff --git a/generator/node-cloud.yml b/generator/node-cloud.yml index e43990c9..36db0bc0 100644 --- a/generator/node-cloud.yml +++ b/generator/node-cloud.yml @@ -416,4 +416,4 @@ BlockStorage: create: volumes.d.ts create delete: volumes.d.ts deleteById list: volumes.d.ts getAll - describe: volumes.d.ts getById + describe: volumes.d.ts getById \ No newline at end of file diff --git a/generator/parsers/googleCloud/parser.ts b/generator/parsers/googleCloud/parser.ts index b8701074..1cf53b17 100644 --- a/generator/parsers/googleCloud/parser.ts +++ b/generator/parsers/googleCloud/parser.ts @@ -1,55 +1,55 @@ -import * as fs from "fs"; -import * as path from "path"; -import { createSourceFile, ScriptTarget, SyntaxKind } from "typescript"; +import * as fs from 'fs'; +import * as path from 'path'; +import { createSourceFile, ScriptTarget, SyntaxKind } from 'typescript'; export function getAST(sdkFileInfo, multi?: boolean) { - let filePath; - if (sdkFileInfo.version) { - filePath = `../../../node_modules/@google-cloud/${sdkFileInfo.pkgName}/build/src/${sdkFileInfo.version}/${sdkFileInfo.fileName}`; - } else { - filePath = `../../../node_modules/@google-cloud/${sdkFileInfo.pkgName}/build/src/${sdkFileInfo.fileName}`; - } + let filePath; + if (sdkFileInfo.version) { + filePath = `../../../node_modules/@google-cloud/${sdkFileInfo.pkgName}/build/src/${sdkFileInfo.version}/${sdkFileInfo.fileName}`; + } else { + filePath = `../../../node_modules/@google-cloud/${sdkFileInfo.pkgName}/build/src/${sdkFileInfo.fileName}`; + } - return new Promise(async (resolve, reject) => { - try { - const file = path.join(__dirname, filePath); - const ast = createSourceFile( - file, - fs.readFileSync(file).toString(), - ScriptTarget.Latest, - true - ); + return new Promise(async (resolve, reject) => { + try { + const file = path.join(__dirname, filePath); + const ast = createSourceFile( + file, + fs.readFileSync(file).toString(), + ScriptTarget.Latest, + true + ); - if (multi === true) { - let classes = []; - ast.forEachChild(child => { - if (SyntaxKind[child.kind] === "ClassDeclaration") { - let cloned = Object.assign({}, child); - classes.push(cloned); - } - }); - resolve(classes); - } else { - let cloned = null; - await ast.forEachChild(child => { - if (SyntaxKind[child.kind] === "ClassDeclaration") { - let cloned = Object.assign({}, child); - return resolve(cloned); - } - }); + if (multi === true) { + const classes = []; + ast.forEachChild(child => { + if (SyntaxKind[child.kind] === 'ClassDeclaration') { + const cloned = Object.assign({}, child); + classes.push(cloned); + } + }); + resolve(classes); + } else { + const cloned = null; + await ast.forEachChild(child => { + if (SyntaxKind[child.kind] === 'ClassDeclaration') { + const cloned = Object.assign({}, child); + return resolve(cloned); + } + }); - if (!cloned) { - return reject(new Error("Class not found!")); - } else { - return resolve(cloned); - } - } - } catch (error) { - if (error.code === "ENOENT") { - reject(new Error("File not found!")); - } else { - reject(error); - } - } - }); + if (!cloned) { + return reject(new Error('Class not found!')); + } else { + return resolve(cloned); + } + } + } catch (error) { + if (error.code === 'ENOENT') { + reject(new Error('File not found!')); + } else { + reject(error); + } + } + }); } diff --git a/generator/parsers/linode/parser.js b/generator/parsers/linode/parser.js new file mode 100644 index 00000000..7958cca4 --- /dev/null +++ b/generator/parsers/linode/parser.js @@ -0,0 +1,219 @@ +'use strict'; +var __awaiter = + (this && this.__awaiter) || + function(thisArg, _arguments, P, generator) { + function adopt(value) { + return value instanceof P + ? value + : new P(function(resolve) { + resolve(value); + }); + } + return new (P || (P = Promise))(function(resolve, reject) { + function fulfilled(value) { + try { + step(generator.next(value)); + } catch (e) { + reject(e); + } + } + function rejected(value) { + try { + step(generator['throw'](value)); + } catch (e) { + reject(e); + } + } + function step(result) { + result.done + ? resolve(result.value) + : adopt(result.value).then(fulfilled, rejected); + } + step( + (generator = generator.apply(thisArg, _arguments || [])).next() + ); + }); + }; +var __generator = + (this && this.__generator) || + function(thisArg, body) { + var _ = { + label: 0, + sent: function() { + if (t[0] & 1) throw t[1]; + return t[1]; + }, + trys: [], + ops: [], + }, + f, + y, + t, + g; + return ( + (g = { next: verb(0), throw: verb(1), return: verb(2) }), + typeof Symbol === 'function' && + (g[Symbol.iterator] = function() { + return this; + }), + g + ); + function verb(n) { + return function(v) { + return step([n, v]); + }; + } + function step(op) { + if (f) throw new TypeError('Generator is already executing.'); + while (_) + try { + if ( + ((f = 1), + y && + (t = + op[0] & 2 + ? y['return'] + : op[0] + ? y['throw'] || + ((t = y['return']) && t.call(y), 0) + : y.next) && + !(t = t.call(y, op[1])).done) + ) + return t; + if (((y = 0), t)) op = [op[0] & 2, t.value]; + switch (op[0]) { + case 0: + case 1: + t = op; + break; + case 4: + _.label++; + return { value: op[1], done: false }; + case 5: + _.label++; + y = op[1]; + op = [0]; + continue; + case 7: + op = _.ops.pop(); + _.trys.pop(); + continue; + default: + if ( + !((t = _.trys), + (t = t.length > 0 && t[t.length - 1])) && + (op[0] === 6 || op[0] === 2) + ) { + _ = 0; + continue; + } + if ( + op[0] === 3 && + (!t || (op[1] > t[0] && op[1] < t[3])) + ) { + _.label = op[1]; + break; + } + if (op[0] === 6 && _.label < t[1]) { + _.label = t[1]; + t = op; + break; + } + if (t && _.label < t[2]) { + _.label = t[2]; + _.ops.push(op); + break; + } + if (t[2]) _.ops.pop(); + _.trys.pop(); + continue; + } + op = body.call(thisArg, _); + } catch (e) { + op = [6, e]; + y = 0; + } finally { + f = t = 0; + } + if (op[0] & 5) throw op[1]; + return { value: op[0] ? op[1] : void 0, done: true }; + } + }; +exports.__esModule = true; +exports.getAST = void 0; +var fs = require('fs'); +var path = require('path'); +var typescript_1 = require('typescript'); +function getAST(sdkFileInfo) { + var _this = this; + return new Promise(function(resolve, reject) { + return __awaiter(_this, void 0, void 0, function() { + var file, ast, cloned_1, tmp_1, error_1; + return __generator(this, function(_a) { + switch (_a.label) { + case 0: + _a.trys.push([0, 2, , 3]); + file = path.join( + __dirname, + '../../../node_modules/@linode/api-v4/lib/' + + sdkFileInfo.pkgName + + '/' + + sdkFileInfo.fileName + ); + ast = typescript_1.createSourceFile( + file, + fs.readFileSync(file).toString(), + typescript_1.ScriptTarget.Latest, + true + ); + cloned_1 = []; + tmp_1 = null; + return [ + 4 /*yield*/, + ast.forEachChild(function(child) { + // fs.writeFile('test.txt', SyntaxKind[child.kind], null); + // console.log(SyntaxKind[child.kind]); + // console.log('Linode', SyntaxKind[child.kind]); + // console.log("child",child); + if ( + typescript_1.SyntaxKind[child.kind] === + 'FirstStatement' + ) { + // console.log("child",child); + // resolve(false) + tmp_1 = Object.assign({}, child); + cloned_1.push( + tmp_1.declarationList.declarations[0] + ); + // console.log( + // 'name', + // tmp.declarationList.declarations[0].type.parameters[0] + // ); + } + }), + ]; + case 1: + _a.sent(); + // console.log('cloned', cloned); + if (!cloned_1) { + reject(new Error('Function not found!')); + } else { + resolve(cloned_1); + } + return [3 /*break*/, 3]; + case 2: + error_1 = _a.sent(); + if (error_1.code === 'ENOENT') { + reject(new Error('File not found!')); + } else { + reject(error_1); + } + return [3 /*break*/, 3]; + case 3: + return [2 /*return*/]; + } + }); + }); + }); +} +exports.getAST = getAST; diff --git a/generator/parsers/linode/parser.ts b/generator/parsers/linode/parser.ts index 3bc37f55..a5e80f99 100644 --- a/generator/parsers/linode/parser.ts +++ b/generator/parsers/linode/parser.ts @@ -12,38 +12,20 @@ export function getAST(sdkFileInfo) { '/' + sdkFileInfo.fileName ); - console.log(file); - const ast = createSourceFile( file, fs.readFileSync(file).toString(), ScriptTarget.Latest, true ); - - let cloned = []; + const cloned = []; let tmp = null; await ast.forEachChild(child => { - // fs.writeFile('test.txt', SyntaxKind[child.kind], null); - // console.log(SyntaxKind[child.kind]); - - // console.log('Linode', SyntaxKind[child.kind]); - // console.log("child",child); - if (SyntaxKind[child.kind] === 'FirstStatement') { - // console.log("child",child); - // resolve(false) tmp = Object.assign({}, child); cloned.push(tmp.declarationList.declarations[0]); - - console.log( - 'name', - tmp.declarationList.declarations[0].type.parameters[0] - ); } }); - // console.log('cloned', cloned); - if (!cloned) { reject(new Error('Function not found!')); } else { diff --git a/generator/test/generators/googleCloud/generator.test.ts b/generator/test/generators/googleCloud/generator.test.ts index 3b339d3c..0702d965 100644 --- a/generator/test/generators/googleCloud/generator.test.ts +++ b/generator/test/generators/googleCloud/generator.test.ts @@ -1,159 +1,163 @@ -import { expect } from "chai"; -import { SyntaxKind } from "typescript"; +import { expect } from 'chai'; +import { SyntaxKind } from 'typescript'; import { - extractClassBasedSDKData, - extractClientBasedSDKdata -} from "../../../generators/googleCloud/generator"; -import { readJsonData, readSourceFile } from "../lib/helper"; - -describe("GCP generator extractClassBasedSDKData", () => { - context("with valid methods and valid AST", () => { - it("should return class data", async () => { - const methods: any = await readJsonData( - "validDataset_1", - "googleCloud", - "methods" - ); - - const sdkFiles: any = await readJsonData( - "validDataset_1", - "googleCloud", - "files" - ); - - await Promise.all( - sdkFiles.map(async file => { - file.classes = []; - const sdkFile: any = await readSourceFile( - "validDataset_1", - "googleCloud" - ); - sdkFile.forEachChild(child => { - if (SyntaxKind[child.kind] === "ClassDeclaration") { - let cloned = Object.assign({}, child); - file.classes.push(cloned); - } - }); - }) - ); - - extractClassBasedSDKData(methods, sdkFiles).then(result => { - expect(result).to.be.an("object"); - expect(result.methods).to.be.an("array"); - }); - }); - }); - - context("with invalid AST", () => { - it("should return Error", async () => { - const methods: any = await readJsonData( - "invalidDataset_1", - "googleCloud", - "methods" - ); - - const sdkFiles: any = await readJsonData( - "invalidDataset_1", - "googleCloud", - "files" - ); - - await Promise.all( - sdkFiles.map(async file => { - file.classes = []; - const sdkFile: any = await readSourceFile( - "invalidDataset_1", - "googleCloud" - ); - sdkFile.forEachChild(child => { - if (SyntaxKind[child.kind] === "ClassDeclaration") { - let cloned = Object.assign({}, child); - file.classes.push(cloned); - } - }); - }) - ); - - extractClassBasedSDKData(methods, sdkFiles).then( - result => {}, - error => { - expect(error.message).to.eql("Data extraction unsuccessful"); - } - ); - }); - }); + extractClassBasedSDKData, + extractClientBasedSDKdata, +} from '../../../generators/googleCloud/generator'; +import { readJsonData, readSourceFile } from '../lib/helper'; + +describe('GCP generator extractClassBasedSDKData', () => { + context('with valid methods and valid AST', () => { + it('should return class data', async () => { + const methods: any = await readJsonData( + 'validDataset_1', + 'googleCloud', + 'methods' + ); + + const sdkFiles: any = await readJsonData( + 'validDataset_1', + 'googleCloud', + 'files' + ); + + await Promise.all( + sdkFiles.map(async file => { + file.classes = []; + const sdkFile: any = await readSourceFile( + 'validDataset_1', + 'googleCloud' + ); + sdkFile.forEachChild(child => { + if (SyntaxKind[child.kind] === 'ClassDeclaration') { + const cloned = Object.assign({}, child); + file.classes.push(cloned); + } + }); + }) + ); + + extractClassBasedSDKData(methods, sdkFiles).then(result => { + expect(result).to.be.an('object'); + expect(result.methods).to.be.an('array'); + }); + }); + }); + + context('with invalid AST', () => { + it('should return Error', async () => { + const methods: any = await readJsonData( + 'invalidDataset_1', + 'googleCloud', + 'methods' + ); + + const sdkFiles: any = await readJsonData( + 'invalidDataset_1', + 'googleCloud', + 'files' + ); + + await Promise.all( + sdkFiles.map(async file => { + file.classes = []; + const sdkFile: any = await readSourceFile( + 'invalidDataset_1', + 'googleCloud' + ); + sdkFile.forEachChild(child => { + if (SyntaxKind[child.kind] === 'ClassDeclaration') { + const cloned = Object.assign({}, child); + file.classes.push(cloned); + } + }); + }) + ); + + extractClassBasedSDKData(methods, sdkFiles).then( + result => {}, + error => { + expect(error.message).to.eql( + 'Data extraction unsuccessful' + ); + } + ); + }); + }); }); -describe("GCP generator extractClientBasedSDKdata", () => { - context("with valid methods and valid AST", () => { - it("should return class data", async () => { - const methods: any = await readJsonData( - "validDataset_2", - "googleCloud", - "methods" - ); - - const sdkFiles: any = await readJsonData( - "validDataset_2", - "googleCloud", - "files" - ); - - await Promise.all( - sdkFiles.map(async file => { - const sdkFile: any = await readSourceFile( - "validDataset_2", - "googleCloud" - ); - sdkFile.forEachChild(child => { - if (SyntaxKind[child.kind] === "ClassDeclaration") { - file.ast = Object.assign({}, child); - } - }); - }) - ); - - extractClientBasedSDKdata(methods, sdkFiles).then(result => { - expect(result).to.be.an("array"); - }); - }); - }); - - context("with invalid AST", () => { - it("should return Error", async () => { - const methods: any = await readJsonData( - "invalidDataset_2", - "googleCloud", - "methods" - ); - - const sdkFiles: any = await readJsonData( - "invalidDataset_2", - "googleCloud", - "files" - ); - - await Promise.all( - sdkFiles.map(async file => { - const sdkFile: any = await readSourceFile( - "invalidDataset_2", - "googleCloud" - ); - sdkFile.forEachChild(child => { - if (SyntaxKind[child.kind] === "ClassDeclaration") { - file.ast = Object.assign({}, child); - } - }); - }) - ); - - extractClientBasedSDKdata(methods, sdkFiles).then( - result => {}, - error => { - expect(error.message).to.eql("Data extraction unsuccessful"); - } - ); - }); - }); +describe('GCP generator extractClientBasedSDKdata', () => { + context('with valid methods and valid AST', () => { + it('should return class data', async () => { + const methods: any = await readJsonData( + 'validDataset_2', + 'googleCloud', + 'methods' + ); + + const sdkFiles: any = await readJsonData( + 'validDataset_2', + 'googleCloud', + 'files' + ); + + await Promise.all( + sdkFiles.map(async file => { + const sdkFile: any = await readSourceFile( + 'validDataset_2', + 'googleCloud' + ); + sdkFile.forEachChild(child => { + if (SyntaxKind[child.kind] === 'ClassDeclaration') { + file.ast = Object.assign({}, child); + } + }); + }) + ); + + extractClientBasedSDKdata(methods, sdkFiles).then(result => { + expect(result).to.be.an('array'); + }); + }); + }); + + context('with invalid AST', () => { + it('should return Error', async () => { + const methods: any = await readJsonData( + 'invalidDataset_2', + 'googleCloud', + 'methods' + ); + + const sdkFiles: any = await readJsonData( + 'invalidDataset_2', + 'googleCloud', + 'files' + ); + + await Promise.all( + sdkFiles.map(async file => { + const sdkFile: any = await readSourceFile( + 'invalidDataset_2', + 'googleCloud' + ); + sdkFile.forEachChild(child => { + if (SyntaxKind[child.kind] === 'ClassDeclaration') { + file.ast = Object.assign({}, child); + } + }); + }) + ); + + extractClientBasedSDKdata(methods, sdkFiles).then( + result => {}, + error => { + expect(error.message).to.eql( + 'Data extraction unsuccessful' + ); + } + ); + }); + }); }); diff --git a/generator/transformers/aws/transformer.ts b/generator/transformers/aws/transformer.ts index 31230633..ed063fe9 100644 --- a/generator/transformers/aws/transformer.ts +++ b/generator/transformers/aws/transformer.ts @@ -1,239 +1,252 @@ -import { cloneDeep } from "lodash"; -import * as ts from "typescript"; +import { cloneDeep } from 'lodash'; +import * as ts from 'typescript'; const dummyIdentifiers = [ - "ClassName", - "_sdkClassName", - "SDKClassName", - "SDKFunctionName" + 'ClassName', + '_sdkClassName', + 'SDKClassName', + 'SDKFunctionName', ]; const printer: ts.Printer = ts.createPrinter({ - newLine: ts.NewLineKind.LineFeed, - removeComments: false + newLine: ts.NewLineKind.LineFeed, + removeComments: false, }); function addMultiLineComment(node, comment: string) { - ts.addSyntheticLeadingComment( - node, - ts.SyntaxKind.MultiLineCommentTrivia, - comment, - true - ); + ts.addSyntheticLeadingComment( + node, + ts.SyntaxKind.MultiLineCommentTrivia, + comment, + true + ); } function runTransformation(sourceCode, transformMethod): Promise { - return new Promise((resolve, reject) => { - try { - const result = ts.transform(sourceCode, [transformMethod]); - const transformedNodes = result.transformed[0]; - const output = printer.printNode( - ts.EmitHint.SourceFile, - transformedNodes, - sourceCode - ); - resolve(output); - } catch (error) { - reject(error); - } - }); + return new Promise((resolve, reject) => { + try { + const result = ts.transform(sourceCode, [transformMethod]); + const transformedNodes = result.transformed[0]; + const output = printer.printNode( + ts.EmitHint.SourceFile, + transformedNodes, + sourceCode + ); + resolve(output); + } catch (error) { + reject(error); + } + }); } function toSourceFile(sourceCode: string): ts.SourceFile { - return ts.createSourceFile( - "dummyClass.js", - sourceCode, - ts.ScriptTarget.Latest, - true - ); + return ts.createSourceFile( + 'dummyClass.js', + sourceCode, + ts.ScriptTarget.Latest, + true + ); } export async function transform( - code: ts.SourceFile, - classData: any + code: ts.SourceFile, + classData: any ): Promise { - const addFunctions = ( - context: ts.TransformationContext - ) => (rootNode: T) => { - function visit(node: ts.Node): ts.Node { - if (ts.isClassDeclaration(node)) { - let functions: any = []; - classData.functions.map(method => { - const clonedNode = Object.assign({}, node.members[1]); - clonedNode.name = ts.createIdentifier(method.functionName); - functions.push(clonedNode); - }); - - const updatedClass = ts.updateClassDeclaration( - node, - node.decorators, - node.modifiers, - node.name, - node.typeParameters, - node.heritageClauses, - ts.createNodeArray([node.members[0]].concat(functions)) - ); - - return updatedClass; - } - return ts.visitEachChild(node, visit, context); - } - return ts.visitNode(rootNode, visit); - }; - - const addIdentifiers = ( - context: ts.TransformationContext - ) => (rootNode: T) => { - let count = 0; - function visit(node: ts.Node): ts.Node { - if (ts.isMethodDeclaration(node)) { - const parameters = classData.functions[count].params.map(param => { - const paramNode = ts.createParameter( - undefined, - undefined, - undefined, - param.name - ); - - if (param.optional) { - paramNode.initializer = ts.createIdentifier("undefined"); - } - - return paramNode; - }); - - node.parameters = parameters; - } - - if (ts.isIdentifier(node) && dummyIdentifiers.includes(node.text)) { - let updatedIdentifier; - - switch (node.text) { - case "ClassName": - updatedIdentifier = ts.updateIdentifier( - ts.createIdentifier("AWS_" + classData.serviceName) - ); - break; - case "_sdkClassName": - updatedIdentifier = ts.updateIdentifier( - ts.createIdentifier( - "_" + - classData.className.charAt(0).toLowerCase() + - classData.className.substr(1) - ) - ); - break; - case "SDKClassName": - updatedIdentifier = ts.updateIdentifier( - ts.createIdentifier(classData.className) - ); - break; - case "SDKFunctionName": - updatedIdentifier = ts.updateIdentifier( - ts.createIdentifier(classData.functions[count].SDKFunctionName) - ); - count++; - } - - return updatedIdentifier; - } - - if (ts.isCallExpression(node)) { - node.expression.forEachChild(childNode => { - if ( - ts.isIdentifier(childNode) && - childNode.text === "SDKFunctionName" - ) { - const args = classData.functions[count].params.map(param => - ts.createIdentifier(param.name) - ); - node.arguments = args.concat(node.arguments); - } - }); - } - - return ts.visitEachChild(node, visit, context); - } - return ts.visitNode(rootNode, visit); - }; - - const addComments = ( - context: ts.TransformationContext - ) => (rootNode: T) => { - let count = 0; - - function visit(node: ts.Node): ts.Node { - if (ts.isClassDeclaration(node)) { - addMultiLineComment( - node, - "This is an auto generated class, please do not change." - ); - const comment = `* + const addFunctions = ( + context: ts.TransformationContext + ) => (rootNode: T) => { + function visit(node: ts.Node): ts.Node { + if (ts.isClassDeclaration(node)) { + const functions: any = []; + classData.functions.map(method => { + const clonedNode = Object.assign({}, node.members[1]); + clonedNode.name = ts.createIdentifier(method.functionName); + functions.push(clonedNode); + }); + + const updatedClass = ts.updateClassDeclaration( + node, + node.decorators, + node.modifiers, + node.name, + node.typeParameters, + node.heritageClauses, + ts.createNodeArray([node.members[0]].concat(functions)) + ); + + return updatedClass; + } + return ts.visitEachChild(node, visit, context); + } + return ts.visitNode(rootNode, visit); + }; + + const addIdentifiers = ( + context: ts.TransformationContext + ) => (rootNode: T) => { + let count = 0; + function visit(node: ts.Node): ts.Node { + if (ts.isMethodDeclaration(node)) { + const parameters = classData.functions[count].params.map( + param => { + const paramNode = ts.createParameter( + undefined, + undefined, + undefined, + param.name + ); + + if (param.optional) { + paramNode.initializer = ts.createIdentifier( + 'undefined' + ); + } + + return paramNode; + } + ); + + node.parameters = parameters; + } + + if (ts.isIdentifier(node) && dummyIdentifiers.includes(node.text)) { + let updatedIdentifier; + + switch (node.text) { + case 'ClassName': + updatedIdentifier = ts.updateIdentifier( + ts.createIdentifier('AWS_' + classData.serviceName) + ); + break; + case '_sdkClassName': + updatedIdentifier = ts.updateIdentifier( + ts.createIdentifier( + '_' + + classData.className + .charAt(0) + .toLowerCase() + + classData.className.substr(1) + ) + ); + break; + case 'SDKClassName': + updatedIdentifier = ts.updateIdentifier( + ts.createIdentifier(classData.className) + ); + break; + case 'SDKFunctionName': + updatedIdentifier = ts.updateIdentifier( + ts.createIdentifier( + classData.functions[count].SDKFunctionName + ) + ); + count++; + } + + return updatedIdentifier; + } + + if (ts.isCallExpression(node)) { + node.expression.forEachChild(childNode => { + if ( + ts.isIdentifier(childNode) && + childNode.text === 'SDKFunctionName' + ) { + const args = classData.functions[count].params.map( + param => ts.createIdentifier(param.name) + ); + node.arguments = args.concat(node.arguments); + } + }); + } + + return ts.visitEachChild(node, visit, context); + } + return ts.visitNode(rootNode, visit); + }; + + const addComments = ( + context: ts.TransformationContext + ) => (rootNode: T) => { + let count = 0; + + function visit(node: ts.Node): ts.Node { + if (ts.isClassDeclaration(node)) { + addMultiLineComment( + node, + 'This is an auto generated class, please do not change.' + ); + const comment = `* * Class to create a ${classData.className} object * @category AWS `; - addMultiLineComment(node, comment); - } - - if (ts.isMethodDeclaration(node)) { - let parameters = classData.functions[count].params.map(param => { - let statment; - - if (param.optional) { - statment = `* @param {${param.typeName}} [${param.name}] - Data required for ${classData.functions[count].SDKFunctionName}`; - } else { - statment = `* @param {${param.typeName}} ${param.name} - Data required for ${classData.functions[count].SDKFunctionName}`; - } - return statment; - }); - - let comment; - if (parameters.length > 0) { - let paramStatments: string = ""; - parameters.map(param => { - paramStatments = paramStatments.concat( - paramStatments === "" ? `${param}` : `\n ${param}` - ); - }); - - comment = `* + addMultiLineComment(node, comment); + } + + if (ts.isMethodDeclaration(node)) { + const parameters = classData.functions[count].params.map( + param => { + let statment; + + if (param.optional) { + statment = `* @param {${param.typeName}} [${param.name}] - Data required for ${classData.functions[count].SDKFunctionName}`; + } else { + statment = `* @param {${param.typeName}} ${param.name} - Data required for ${classData.functions[count].SDKFunctionName}`; + } + return statment; + } + ); + + let comment; + if (parameters.length > 0) { + let paramStatments: string = ''; + parameters.map(param => { + paramStatments = paramStatments.concat( + paramStatments === '' ? `${param}` : `\n ${param}` + ); + }); + + comment = `* * Trigers the ${classData.functions[count].SDKFunctionName} function of ${classData.className} ${paramStatments} * @returns {Promise<${classData.functions[count].SDKFunctionName}Response>} `; - } else { - comment = `* + } else { + comment = `* * Trigers the ${classData.functions[count].SDKFunctionName} function of ${classData.className} * @returns {Promise<${classData.functions[count].SDKFunctionName}Response>} `; - } - - addMultiLineComment(node, comment); - count++; - } - - return ts.visitEachChild(node, visit, context); - } - return ts.visitNode(rootNode, visit); - }; - - const node: any = code.statements.find(stm => ts.isClassDeclaration(stm)); - - if (!classData.className || !classData.functions) { - throw new Error("Input is invalid"); - } - - if (!node || !node.members.some(member => ts.isMethodDeclaration(member))) { - throw new Error("Code is invalid"); - } - - code = cloneDeep(code); - - const result_1 = await runTransformation(code, addFunctions); - const result_2 = await runTransformation( - toSourceFile(result_1), - addIdentifiers - ); - const result_3 = await runTransformation(toSourceFile(result_2), addComments); - return result_3; + } + + addMultiLineComment(node, comment); + count++; + } + + return ts.visitEachChild(node, visit, context); + } + return ts.visitNode(rootNode, visit); + }; + + const node: any = code.statements.find(stm => ts.isClassDeclaration(stm)); + + if (!classData.className || !classData.functions) { + throw new Error('Input is invalid'); + } + + if (!node || !node.members.some(member => ts.isMethodDeclaration(member))) { + throw new Error('Code is invalid'); + } + + code = cloneDeep(code); + + const result_1 = await runTransformation(code, addFunctions); + const result_2 = await runTransformation( + toSourceFile(result_1), + addIdentifiers + ); + const result_3 = await runTransformation( + toSourceFile(result_2), + addComments + ); + return result_3; } diff --git a/generator/transformers/azure/transformer.ts b/generator/transformers/azure/transformer.ts index 1c9fd106..e27a4ef6 100644 --- a/generator/transformers/azure/transformer.ts +++ b/generator/transformers/azure/transformer.ts @@ -1,262 +1,279 @@ -import { cloneDeep } from "lodash"; -import * as ts from "typescript"; +import { cloneDeep } from 'lodash'; +import * as ts from 'typescript'; const dummyIdentifiers = [ - "ClassName", - "SDKClassName", - "SDKFunctionName", - "ClientName", - "functionClient" + 'ClassName', + 'SDKClassName', + 'SDKFunctionName', + 'ClientName', + 'functionClient', ]; const printer: ts.Printer = ts.createPrinter({ - newLine: ts.NewLineKind.LineFeed, - removeComments: false + newLine: ts.NewLineKind.LineFeed, + removeComments: false, }); function addMultiLineComment(node, comment: string) { - ts.addSyntheticLeadingComment( - node, - ts.SyntaxKind.MultiLineCommentTrivia, - comment, - true - ); + ts.addSyntheticLeadingComment( + node, + ts.SyntaxKind.MultiLineCommentTrivia, + comment, + true + ); } function runTransformation(sourceCode, transformMethod): Promise { - return new Promise((resolve, reject) => { - try { - const result = ts.transform(sourceCode, [transformMethod]); - const transformedNodes = result.transformed[0]; - const output = printer.printNode( - ts.EmitHint.SourceFile, - transformedNodes, - sourceCode - ); - resolve(output); - } catch (error) { - reject(error); - } - }); + return new Promise((resolve, reject) => { + try { + const result = ts.transform(sourceCode, [transformMethod]); + const transformedNodes = result.transformed[0]; + const output = printer.printNode( + ts.EmitHint.SourceFile, + transformedNodes, + sourceCode + ); + resolve(output); + } catch (error) { + reject(error); + } + }); } function toSourceFile(sourceCode: string): ts.SourceFile { - return ts.createSourceFile( - "dummyClass.js", - sourceCode, - ts.ScriptTarget.Latest, - true - ); + return ts.createSourceFile( + 'dummyClass.js', + sourceCode, + ts.ScriptTarget.Latest, + true + ); } export async function transform( - code: ts.SourceFile, - classData: any + code: ts.SourceFile, + classData: any ): Promise { - const node: any = code.statements.find(stm => ts.isClassDeclaration(stm)); + const node: any = code.statements.find(stm => ts.isClassDeclaration(stm)); - if (!classData.functions) { - throw new Error("Input is invalid"); - } + if (!classData.functions) { + throw new Error('Input is invalid'); + } - if (!node || !node.members.some(member => ts.isMethodDeclaration(member))) { - throw new Error("Code is invalid"); - } + if (!node || !node.members.some(member => ts.isMethodDeclaration(member))) { + throw new Error('Code is invalid'); + } - code = cloneDeep(code); + code = cloneDeep(code); - // import related - classData.clients = Array.from( - new Set(classData.functions.map(method => method.client)) - ); - const importStatments: any = new Array(classData.clients.length); - importStatments.fill(Object.assign({}, code.statements[0])); - code.statements = importStatments.concat(code.statements.slice(1)); - // import related + // import related + classData.clients = Array.from( + new Set(classData.functions.map(method => method.client)) + ); + const importStatments: any = new Array(classData.clients.length); + importStatments.fill(Object.assign({}, code.statements[0])); + code.statements = importStatments.concat(code.statements.slice(1)); + // import related - const addFunctions = ( - context: ts.TransformationContext - ) => (rootNode: T) => { - function visit(node: ts.Node): ts.Node { - if (ts.isClassDeclaration(node)) { - let functions: any = []; - classData.functions.map(method => { - const clonedNode = Object.assign({}, node.members[1]); - clonedNode.name = ts.createIdentifier(method.functionName); - functions.push(clonedNode); - }); + const addFunctions = ( + context: ts.TransformationContext + ) => (rootNode: T) => { + function visit(node: ts.Node): ts.Node { + if (ts.isClassDeclaration(node)) { + const functions: any = []; + classData.functions.map(method => { + const clonedNode = Object.assign({}, node.members[1]); + clonedNode.name = ts.createIdentifier(method.functionName); + functions.push(clonedNode); + }); - const updatedClass = ts.updateClassDeclaration( - node, - node.decorators, - node.modifiers, - node.name, - node.typeParameters, - node.heritageClauses, - ts.createNodeArray([node.members[0]].concat(functions)) - ); + const updatedClass = ts.updateClassDeclaration( + node, + node.decorators, + node.modifiers, + node.name, + node.typeParameters, + node.heritageClauses, + ts.createNodeArray([node.members[0]].concat(functions)) + ); - return updatedClass; - } - return ts.visitEachChild(node, visit, context); - } - return ts.visitNode(rootNode, visit); - }; + return updatedClass; + } + return ts.visitEachChild(node, visit, context); + } + return ts.visitNode(rootNode, visit); + }; - const addIdentifiers = ( - context: ts.TransformationContext - ) => (rootNode: T) => { - let count = 0; - let clientCount = 0; - function visit(node: ts.Node): ts.Node { - if (ts.isMethodDeclaration(node)) { - const parameters = classData.functions[count].params.map(param => { - const paramNode = ts.createParameter( - undefined, - undefined, - undefined, - param.name - ); + const addIdentifiers = ( + context: ts.TransformationContext + ) => (rootNode: T) => { + let count = 0; + let clientCount = 0; + function visit(node: ts.Node): ts.Node { + if (ts.isMethodDeclaration(node)) { + const parameters = classData.functions[count].params.map( + param => { + const paramNode = ts.createParameter( + undefined, + undefined, + undefined, + param.name + ); - if (param.optional) { - paramNode.initializer = ts.createIdentifier("undefined"); - } + if (param.optional) { + paramNode.initializer = ts.createIdentifier( + 'undefined' + ); + } - return paramNode; - }); + return paramNode; + } + ); - node.parameters = parameters; - } + node.parameters = parameters; + } - if (ts.isStringLiteral(node) && node.text === "pkgName") { - return ts.createStringLiteral( - "@azure/" + classData.functions[0].pkgName - ); - } + if (ts.isStringLiteral(node) && node.text === 'pkgName') { + return ts.createStringLiteral( + '@azure/' + classData.functions[0].pkgName + ); + } - if (ts.isIdentifier(node) && dummyIdentifiers.includes(node.text)) { - let updatedIdentifier; - switch (node.text) { - case "ClassName": - updatedIdentifier = ts.updateIdentifier( - ts.createIdentifier("Azure_" + classData.serviceName) - ); - break; - case "SDKClassName": - updatedIdentifier = ts.updateIdentifier( - ts.createIdentifier( - classData.functions[count].fileName.split(".")[0] - ) - ); - break; - case "functionClient": - updatedIdentifier = ts.updateIdentifier( - ts.createIdentifier(classData.functions[count].client) - ); - break; - case "ClientName": - updatedIdentifier = ts.updateIdentifier( - ts.createIdentifier(classData.clients[clientCount]) - ); - clientCount++; - break; - case "SDKFunctionName": - updatedIdentifier = ts.updateIdentifier( - ts.createIdentifier(classData.functions[count].SDKFunctionName) - ); - count++; - } - return updatedIdentifier; - } + if (ts.isIdentifier(node) && dummyIdentifiers.includes(node.text)) { + let updatedIdentifier; + switch (node.text) { + case 'ClassName': + updatedIdentifier = ts.updateIdentifier( + ts.createIdentifier( + 'Azure_' + classData.serviceName + ) + ); + break; + case 'SDKClassName': + updatedIdentifier = ts.updateIdentifier( + ts.createIdentifier( + classData.functions[count].fileName.split( + '.' + )[0] + ) + ); + break; + case 'functionClient': + updatedIdentifier = ts.updateIdentifier( + ts.createIdentifier( + classData.functions[count].client + ) + ); + break; + case 'ClientName': + updatedIdentifier = ts.updateIdentifier( + ts.createIdentifier(classData.clients[clientCount]) + ); + clientCount++; + break; + case 'SDKFunctionName': + updatedIdentifier = ts.updateIdentifier( + ts.createIdentifier( + classData.functions[count].SDKFunctionName + ) + ); + count++; + } + return updatedIdentifier; + } - if (ts.isCallExpression(node)) { - node.expression.forEachChild(childNode => { - if ( - ts.isIdentifier(childNode) && - childNode.text === "SDKFunctionName" - ) { - const args = classData.functions[count].params.map(param => - ts.createIdentifier(param.name) - ); - node.arguments = args; - } - }); - } + if (ts.isCallExpression(node)) { + node.expression.forEachChild(childNode => { + if ( + ts.isIdentifier(childNode) && + childNode.text === 'SDKFunctionName' + ) { + const args = classData.functions[count].params.map( + param => ts.createIdentifier(param.name) + ); + node.arguments = args; + } + }); + } - return ts.visitEachChild(node, visit, context); - } - return ts.visitNode(rootNode, visit); - }; + return ts.visitEachChild(node, visit, context); + } + return ts.visitNode(rootNode, visit); + }; - const addComments = ( - context: ts.TransformationContext - ) => (rootNode: T) => { - let count = 0; + const addComments = ( + context: ts.TransformationContext + ) => (rootNode: T) => { + let count = 0; - function visit(node: ts.Node): ts.Node { - if (ts.isClassDeclaration(node)) { - addMultiLineComment( - node, - "This is an auto generated class, please do not change." - ); - const comment = `* + function visit(node: ts.Node): ts.Node { + if (ts.isClassDeclaration(node)) { + addMultiLineComment( + node, + 'This is an auto generated class, please do not change.' + ); + const comment = `* * Class to create a ${classData.serviceName} object * @category Azure `; - addMultiLineComment(node, comment); - } + addMultiLineComment(node, comment); + } - if (ts.isMethodDeclaration(node)) { - let parameters = classData.functions[count].params.map(param => { - let statment; + if (ts.isMethodDeclaration(node)) { + const parameters = classData.functions[count].params.map( + param => { + let statment; - if (param.optional) { - statment = `* @param {${param.type}} [${param.name}] - Optional parameter`; - } else { - statment = `* @param {${param.type}} ${param.name} - Mandatory parameter`; - } - return statment; - }); + if (param.optional) { + statment = `* @param {${param.type}} [${param.name}] - Optional parameter`; + } else { + statment = `* @param {${param.type}} ${param.name} - Mandatory parameter`; + } + return statment; + } + ); - let comment; - if (parameters.length > 0) { - let paramStatments: string = ""; - parameters.map(param => { - paramStatments = paramStatments.concat( - paramStatments === "" ? `${param}` : `\n ${param}` - ); - }); + let comment; + if (parameters.length > 0) { + let paramStatments: string = ''; + parameters.map(param => { + paramStatments = paramStatments.concat( + paramStatments === '' ? `${param}` : `\n ${param}` + ); + }); - comment = `* + comment = `* * Trigers the ${classData.functions[count].SDKFunctionName} function of ${ - classData.functions[0].pkgName.split("-")[1] - } + classData.functions[0].pkgName.split('-')[1] + } ${paramStatments} * @returns {Promise<${classData.functions[count].SDKFunctionName}Response>} `; - } else { - comment = `* + } else { + comment = `* * Trigers the ${classData.functions[count].SDKFunctionName} function of ${ - classData.functions[0].pkgName.split("-")[1] - } + classData.functions[0].pkgName.split('-')[1] + } * @returns {Promise<${classData.functions[count].SDKFunctionName}Response>} `; - } + } - addMultiLineComment(node, comment); - count++; - } + addMultiLineComment(node, comment); + count++; + } - return ts.visitEachChild(node, visit, context); - } - return ts.visitNode(rootNode, visit); - }; + return ts.visitEachChild(node, visit, context); + } + return ts.visitNode(rootNode, visit); + }; - const result_1 = await runTransformation(code, addFunctions); - const result_2 = await runTransformation( - toSourceFile(result_1), - addIdentifiers - ); - const result_3 = await runTransformation(toSourceFile(result_2), addComments); - return result_3; + const result_1 = await runTransformation(code, addFunctions); + const result_2 = await runTransformation( + toSourceFile(result_1), + addIdentifiers + ); + const result_3 = await runTransformation( + toSourceFile(result_2), + addComments + ); + return result_3; } diff --git a/generator/transformers/do/transformer.ts b/generator/transformers/do/transformer.ts index 3f063962..115ed946 100644 --- a/generator/transformers/do/transformer.ts +++ b/generator/transformers/do/transformer.ts @@ -1,51 +1,51 @@ -import { cloneDeep } from "lodash"; -import * as ts from "typescript"; +import { cloneDeep } from 'lodash'; +import * as ts from 'typescript'; const dummyIdentifiers = [ - "ClassName", - "_sdkClassName", - "SDKClassName", - "SDKFunctionName" + 'ClassName', + '_sdkClassName', + 'SDKClassName', + 'SDKFunctionName', ]; const printer: ts.Printer = ts.createPrinter({ - newLine: ts.NewLineKind.LineFeed, - removeComments: false + newLine: ts.NewLineKind.LineFeed, + removeComments: false, }); function addMultiLineComment(node, comment: string) { - ts.addSyntheticLeadingComment( - node, - ts.SyntaxKind.MultiLineCommentTrivia, - comment, - true - ); + ts.addSyntheticLeadingComment( + node, + ts.SyntaxKind.MultiLineCommentTrivia, + comment, + true + ); } function runTransformation(sourceCode, transformMethod): Promise { - return new Promise((resolve, reject) => { - try { - const result = ts.transform(sourceCode, [transformMethod]); - const transformedNodes = result.transformed[0]; - const output = printer.printNode( - ts.EmitHint.SourceFile, - transformedNodes, - sourceCode - ); - resolve(output); - } catch (error) { - reject(error); - } - }); + return new Promise((resolve, reject) => { + try { + const result = ts.transform(sourceCode, [transformMethod]); + const transformedNodes = result.transformed[0]; + const output = printer.printNode( + ts.EmitHint.SourceFile, + transformedNodes, + sourceCode + ); + resolve(output); + } catch (error) { + reject(error); + } + }); } function toSourceFile(sourceCode: string): ts.SourceFile { - return ts.createSourceFile( - "dummyClass.js", - sourceCode, - ts.ScriptTarget.Latest, - true - ); + return ts.createSourceFile( + 'dummyClass.js', + sourceCode, + ts.ScriptTarget.Latest, + true + ); } /* @@ -53,215 +53,228 @@ function toSourceFile(sourceCode: string): ts.SourceFile { */ export async function transform( - code: ts.SourceFile, - classData: any + code: ts.SourceFile, + classData: any ): Promise { - /* - * Transformation function for adding Functions - */ - const addFunctions = ( - context: ts.TransformationContext - ) => (rootNode: T) => { - function visit(node: ts.Node): ts.Node { - if (ts.isClassDeclaration(node)) { - let functions: any = []; - classData.functions.map(method => { - const clonedNode = Object.assign({}, node.members[1]); - // console.log("Cloned Node..........\n");//sdadas - // console.log(clonedNode);//asdasdasdasd - clonedNode.name = ts.createIdentifier(method.functionName); - functions.push(clonedNode); - }); - - const updatedClass = ts.updateClassDeclaration( - node, - node.decorators, - node.modifiers, - node.name, - node.typeParameters, - node.heritageClauses, - ts.createNodeArray([node.members[0]].concat(functions)) - ); - - return updatedClass; - } - return ts.visitEachChild(node, visit, context); - } - return ts.visitNode(rootNode, visit); - }; - - /* - * Transformation function for adding Identifiers/Parameters - */ - const addIdentifiers = ( - context: ts.TransformationContext - ) => (rootNode: T) => { - let count = 0; - function visit(node: ts.Node): ts.Node { - if (ts.isMethodDeclaration(node)) { - const parameters = classData.functions[count].params.map(param => { - const paramNode = ts.createParameter( - undefined, - undefined, - undefined, - param.name - ); - - if (param.optional) { - paramNode.initializer = ts.createIdentifier("undefined"); - } - - return paramNode; - }); - - node.parameters = parameters; - } - - if (ts.isIdentifier(node) && dummyIdentifiers.includes(node.text)) { - let updatedIdentifier; - - switch (node.text) { - case "ClassName": - updatedIdentifier = ts.updateIdentifier( - ts.createIdentifier("DO_" + classData.serviceName) - ); - break; - case "_sdkClassName": - updatedIdentifier = ts.updateIdentifier( - ts.createIdentifier( - "_" + - classData.className.charAt(0).toLowerCase() + - classData.className.substr(1) - ) - ); - break; - case "SDKClassName": - updatedIdentifier = ts.updateIdentifier( - ts.createIdentifier( - classData.className.charAt(0).toLowerCase() + - classData.className.substr(1) - ) - ); - break; - case "SDKFunctionName": - updatedIdentifier = ts.updateIdentifier( - ts.createIdentifier(classData.functions[count].SDKFunctionName) - ); - count++; - } - - return updatedIdentifier; - } - - if (ts.isCallExpression(node)) { - node.expression.forEachChild(childNode => { - if ( - ts.isIdentifier(childNode) && - childNode.text === "SDKFunctionName" - ) { - const args = classData.functions[count].params.map(param => - ts.createIdentifier(param.name) - ); - node.arguments = args.concat(node.arguments); - } - }); - } - - return ts.visitEachChild(node, visit, context); - } - return ts.visitNode(rootNode, visit); - }; - - /* - *Transformation function for adding comments - */ - - const addComments = ( - context: ts.TransformationContext - ) => (rootNode: T) => { - let count = 0; - - function visit(node: ts.Node): ts.Node { - if (ts.isClassDeclaration(node)) { - addMultiLineComment( - node, - "This is an auto generated class, please do not change." - ); - const comment = `* + /* + * Transformation function for adding Functions + */ + const addFunctions = ( + context: ts.TransformationContext + ) => (rootNode: T) => { + function visit(node: ts.Node): ts.Node { + if (ts.isClassDeclaration(node)) { + const functions: any = []; + classData.functions.map(method => { + const clonedNode = Object.assign({}, node.members[1]); + // console.log("Cloned Node..........\n");//sdadas + // console.log(clonedNode);//asdasdasdasd + clonedNode.name = ts.createIdentifier(method.functionName); + functions.push(clonedNode); + }); + + const updatedClass = ts.updateClassDeclaration( + node, + node.decorators, + node.modifiers, + node.name, + node.typeParameters, + node.heritageClauses, + ts.createNodeArray([node.members[0]].concat(functions)) + ); + + return updatedClass; + } + return ts.visitEachChild(node, visit, context); + } + return ts.visitNode(rootNode, visit); + }; + + /* + * Transformation function for adding Identifiers/Parameters + */ + const addIdentifiers = ( + context: ts.TransformationContext + ) => (rootNode: T) => { + let count = 0; + function visit(node: ts.Node): ts.Node { + if (ts.isMethodDeclaration(node)) { + const parameters = classData.functions[count].params.map( + param => { + const paramNode = ts.createParameter( + undefined, + undefined, + undefined, + param.name + ); + + if (param.optional) { + paramNode.initializer = ts.createIdentifier( + 'undefined' + ); + } + + return paramNode; + } + ); + + node.parameters = parameters; + } + + if (ts.isIdentifier(node) && dummyIdentifiers.includes(node.text)) { + let updatedIdentifier; + + switch (node.text) { + case 'ClassName': + updatedIdentifier = ts.updateIdentifier( + ts.createIdentifier('DO_' + classData.serviceName) + ); + break; + case '_sdkClassName': + updatedIdentifier = ts.updateIdentifier( + ts.createIdentifier( + '_' + + classData.className + .charAt(0) + .toLowerCase() + + classData.className.substr(1) + ) + ); + break; + case 'SDKClassName': + updatedIdentifier = ts.updateIdentifier( + ts.createIdentifier( + classData.className.charAt(0).toLowerCase() + + classData.className.substr(1) + ) + ); + break; + case 'SDKFunctionName': + updatedIdentifier = ts.updateIdentifier( + ts.createIdentifier( + classData.functions[count].SDKFunctionName + ) + ); + count++; + } + + return updatedIdentifier; + } + + if (ts.isCallExpression(node)) { + node.expression.forEachChild(childNode => { + if ( + ts.isIdentifier(childNode) && + childNode.text === 'SDKFunctionName' + ) { + const args = classData.functions[count].params.map( + param => ts.createIdentifier(param.name) + ); + node.arguments = args.concat(node.arguments); + } + }); + } + + return ts.visitEachChild(node, visit, context); + } + return ts.visitNode(rootNode, visit); + }; + + /* + *Transformation function for adding comments + */ + + const addComments = ( + context: ts.TransformationContext + ) => (rootNode: T) => { + let count = 0; + + function visit(node: ts.Node): ts.Node { + if (ts.isClassDeclaration(node)) { + addMultiLineComment( + node, + 'This is an auto generated class, please do not change.' + ); + const comment = `* * Class to create a ${classData.className} object * @category Digital Ocean `; - addMultiLineComment(node, comment); - } - - if (ts.isMethodDeclaration(node)) { - let parameters = classData.functions[count].params.map(param => { - let statment; - - if (param.optional) { - if (param.type == "TypeReference") - statment = `* @param {${param.typeName}} ${param.name} - Data required for ${classData.functions[count].SDKFunctionName}`; - else - statment = `* @param {${param.type}} ${param.name} - Data required for ${classData.functions[count].SDKFunctionName}`; - } else { - if (param.type == "TypeReference") - statment = `* @param {${param.typeName}} ${param.name} - Data required for ${classData.functions[count].SDKFunctionName}`; - else - statment = `* @param {${param.type}} ${param.name} - Data required for ${classData.functions[count].SDKFunctionName}`; - } - return statment; - }); - - let comment; - if (parameters.length > 0) { - let paramStatments: string = ""; - parameters.map(param => { - paramStatments = paramStatments.concat( - paramStatments === "" ? `${param}` : `\n${param}` - ); - }); - - comment = `* + addMultiLineComment(node, comment); + } + + if (ts.isMethodDeclaration(node)) { + const parameters = classData.functions[count].params.map( + param => { + let statment; + + if (param.optional) { + if (param.type == 'TypeReference') + statment = `* @param {${param.typeName}} ${param.name} - Data required for ${classData.functions[count].SDKFunctionName}`; + else + statment = `* @param {${param.type}} ${param.name} - Data required for ${classData.functions[count].SDKFunctionName}`; + } else { + if (param.type == 'TypeReference') + statment = `* @param {${param.typeName}} ${param.name} - Data required for ${classData.functions[count].SDKFunctionName}`; + else + statment = `* @param {${param.type}} ${param.name} - Data required for ${classData.functions[count].SDKFunctionName}`; + } + return statment; + } + ); + + let comment; + if (parameters.length > 0) { + let paramStatments: string = ''; + parameters.map(param => { + paramStatments = paramStatments.concat( + paramStatments === '' ? `${param}` : `\n${param}` + ); + }); + + comment = `* * Trigers the ${classData.functions[count].SDKFunctionName} function of ${classData.className} ${paramStatments} * @returns {Promise<${classData.functions[count].SDKFunctionName}Response>} `; - } else { - comment = `* + } else { + comment = `* * Trigers the ${classData.functions[count].SDKFunctionName} function of ${classData.className} * @returns {Promise<${classData.functions[count].SDKFunctionName}Response>} `; - } - - addMultiLineComment(node, comment); - count++; - } - - return ts.visitEachChild(node, visit, context); - } - return ts.visitNode(rootNode, visit); - }; - - /* - * Code to get node and run tranformations - */ - const node: any = code.statements.find(stm => ts.isClassDeclaration(stm)); - - if (!classData.className || !classData.functions) { - throw new Error("Input is invalid"); - } - - if (!node || !node.members.some(member => ts.isMethodDeclaration(member))) { - throw new Error("Code is invalid"); - } - - code = cloneDeep(code); - - const result_1 = await runTransformation(code, addFunctions); - const result_2 = await runTransformation( - toSourceFile(result_1), - addIdentifiers - ); - const result_3 = await runTransformation(toSourceFile(result_2), addComments); - return result_3; + } + + addMultiLineComment(node, comment); + count++; + } + + return ts.visitEachChild(node, visit, context); + } + return ts.visitNode(rootNode, visit); + }; + + /* + * Code to get node and run tranformations + */ + const node: any = code.statements.find(stm => ts.isClassDeclaration(stm)); + + if (!classData.className || !classData.functions) { + throw new Error('Input is invalid'); + } + + if (!node || !node.members.some(member => ts.isMethodDeclaration(member))) { + throw new Error('Code is invalid'); + } + + code = cloneDeep(code); + + const result_1 = await runTransformation(code, addFunctions); + const result_2 = await runTransformation( + toSourceFile(result_1), + addIdentifiers + ); + const result_3 = await runTransformation( + toSourceFile(result_2), + addComments + ); + return result_3; } diff --git a/generator/transformers/googleCloud/classBasedTransformer.ts b/generator/transformers/googleCloud/classBasedTransformer.ts index a68f9365..06f0f729 100644 --- a/generator/transformers/googleCloud/classBasedTransformer.ts +++ b/generator/transformers/googleCloud/classBasedTransformer.ts @@ -1,310 +1,340 @@ -import { cloneDeep } from "lodash"; -import * as ts from "typescript"; +import { cloneDeep } from 'lodash'; +import * as ts from 'typescript'; const dummyIdentifiers = [ - "ClassName", - "SDKFunctionName", - "ClientName", - "_client", - "_clientObj", - "Client", - "_className" + 'ClassName', + 'SDKFunctionName', + 'ClientName', + '_client', + '_clientObj', + 'Client', + '_className', ]; const printer: ts.Printer = ts.createPrinter({ - newLine: ts.NewLineKind.LineFeed, - removeComments: false + newLine: ts.NewLineKind.LineFeed, + removeComments: false, }); function addMultiLineComment(node, comment: string) { - ts.addSyntheticLeadingComment( - node, - ts.SyntaxKind.MultiLineCommentTrivia, - comment, - true - ); + ts.addSyntheticLeadingComment( + node, + ts.SyntaxKind.MultiLineCommentTrivia, + comment, + true + ); } function runTransformation(sourceCode, transformMethod): Promise { - return new Promise((resolve, reject) => { - try { - const result = ts.transform(sourceCode, [transformMethod]); - const transformedNodes = result.transformed[0]; - const output = printer.printNode( - ts.EmitHint.SourceFile, - transformedNodes, - sourceCode - ); - resolve(output); - } catch (error) { - reject(error); - } - }); + return new Promise((resolve, reject) => { + try { + const result = ts.transform(sourceCode, [transformMethod]); + const transformedNodes = result.transformed[0]; + const output = printer.printNode( + ts.EmitHint.SourceFile, + transformedNodes, + sourceCode + ); + resolve(output); + } catch (error) { + reject(error); + } + }); } function toSourceFile(sourceCode: string): ts.SourceFile { - return ts.createSourceFile( - "dummyClass.js", - sourceCode, - ts.ScriptTarget.Latest, - true - ); + return ts.createSourceFile( + 'dummyClass.js', + sourceCode, + ts.ScriptTarget.Latest, + true + ); } export async function classBasedTransform( - code: ts.SourceFile, - data: any + code: ts.SourceFile, + data: any ): Promise { - const node: any = code.statements.find(stm => ts.isClassDeclaration(stm)); - - if (!data.functions || !data.classData) { - throw new Error("Input is invalid"); - } - - if (!node || !node.members.some(member => ts.isMethodDeclaration(member))) { - throw new Error("Code is invalid"); - } - - code = cloneDeep(code); - - const addFunctions = ( - context: ts.TransformationContext - ) => (rootNode: T) => { - function visit(node: ts.Node): ts.Node { - if (ts.isClassDeclaration(node)) { - let functions: any = []; - data.functions.map(method => { - let clonedNode; - if (method.returnTypeName === "Promise") { - if ( - (method.classConstructorData.parameters[0].type = - "TypeReference" && - !method.classConstructorData.parameters[0].optional) - ) { - clonedNode = Object.assign({}, node.members[3]); - } else { - clonedNode = Object.assign({}, node.members[1]); - } - } else { - clonedNode = Object.assign({}, node.members[2]); - } - clonedNode.name = ts.createIdentifier(method.functionName); - functions.push(clonedNode); - }); - - const updatedClass = ts.updateClassDeclaration( - node, - node.decorators, - node.modifiers, - node.name, - node.typeParameters, - node.heritageClauses, - ts.createNodeArray([node.members[0]].concat(functions)) - ); - - return updatedClass; - } - return ts.visitEachChild(node, visit, context); - } - return ts.visitNode(rootNode, visit); - }; - - const addIdentifiers = ( - context: ts.TransformationContext - ) => (rootNode: T) => { - let count = 0; - function visit(node: ts.Node): ts.Node { - if (ts.isMethodDeclaration(node)) { - data.functions[count].allParams = []; - - let params = []; - if ( - (data.functions[count].classConstructorData.parameters[0].type = - "TypeReference" && - !data.functions[count].classConstructorData.parameters[0].optional) - ) { - params.push(data.functions[count].classConstructorData.parameters[0]); - - data.functions[count].allParams.push({ - name: "identifier", - optional: true, - type: "string" - }); - } - - params = params.concat(data.functions[count].params); - data.functions[count].allParams = data.functions[ - count - ].allParams.concat(params); - - const parameters: any = params.map(param => { - const paramNode = ts.createParameter( - undefined, - undefined, - undefined, - param.name - ); - - if (param.optional) { - paramNode.initializer = ts.createIdentifier("undefined"); - } - - return paramNode; - }); - - node.parameters = parameters.concat(node.parameters); - } - - if (ts.isStringLiteral(node) && node.text === "pkgName") { - return ts.createStringLiteral( - "@google-cloud/" + data.functions[0].pkgName - ); - } - - if (ts.isIdentifier(node) && dummyIdentifiers.includes(node.text)) { - let updatedIdentifier; - switch (node.text) { - case "ClassName": - updatedIdentifier = ts.updateIdentifier( - ts.createIdentifier("GCP_" + data.functions[0].pkgName) - ); - break; - case "ClientName": - updatedIdentifier = ts.updateIdentifier( - ts.createIdentifier(data.mainClass) - ); - break; - case "SDKFunctionName": - updatedIdentifier = ts.updateIdentifier( - ts.createIdentifier(data.functions[count].SDKFunctionName) - ); - count++; - break; - case "_className": - updatedIdentifier = ts.updateIdentifier( - ts.createIdentifier(data.functions[count].client.toLowerCase()) - ); - break; - case "_client": - if ( - (data.functions[count].classConstructorData.parameters[0].type = - "TypeReference" && - !data.functions[count].classConstructorData.parameters[0] - .optional) - ) { - updatedIdentifier = ts.updateIdentifier( - ts.createIdentifier( - data.functions[count].classConstructorData.parameters[0].name - ) - ); - } else { - updatedIdentifier = ts.updateIdentifier( - ts.createIdentifier("_" + data.mainClass.toLowerCase()) - ); - } - break; - case "_clientObj": - updatedIdentifier = ts.updateIdentifier( - ts.createIdentifier("_" + data.mainClass.toLowerCase()) - ); - break; - case "Client": - updatedIdentifier = ts.updateIdentifier( - ts.createIdentifier(data.mainClass) - ); - break; - } - return updatedIdentifier; - } - - if (ts.isCallExpression(node)) { - node.expression.forEachChild(childNode => { - if ( - ts.isIdentifier(childNode) && - childNode.text === "SDKFunctionName" - ) { - const args = data.functions[count].params.map(param => - ts.createIdentifier(param.name) - ); - node.arguments = args; - } - }); - } - - return ts.visitEachChild(node, visit, context); - } - return ts.visitNode(rootNode, visit); - }; - - const addComments = ( - context: ts.TransformationContext - ) => (rootNode: T) => { - let count = 0; - - function visit(node: ts.Node): ts.Node { - if (ts.isClassDeclaration(node)) { - addMultiLineComment( - node, - "This is an auto generated class, please do not change." - ); - const comment = `* + const node: any = code.statements.find(stm => ts.isClassDeclaration(stm)); + + if (!data.functions || !data.classData) { + throw new Error('Input is invalid'); + } + + if (!node || !node.members.some(member => ts.isMethodDeclaration(member))) { + throw new Error('Code is invalid'); + } + + code = cloneDeep(code); + + const addFunctions = ( + context: ts.TransformationContext + ) => (rootNode: T) => { + function visit(node: ts.Node): ts.Node { + if (ts.isClassDeclaration(node)) { + const functions: any = []; + data.functions.map(method => { + let clonedNode; + if (method.returnTypeName === 'Promise') { + if ( + (method.classConstructorData.parameters[0].type = + 'TypeReference' && + !method.classConstructorData.parameters[0] + .optional) + ) { + clonedNode = Object.assign({}, node.members[3]); + } else { + clonedNode = Object.assign({}, node.members[1]); + } + } else { + clonedNode = Object.assign({}, node.members[2]); + } + clonedNode.name = ts.createIdentifier(method.functionName); + functions.push(clonedNode); + }); + + const updatedClass = ts.updateClassDeclaration( + node, + node.decorators, + node.modifiers, + node.name, + node.typeParameters, + node.heritageClauses, + ts.createNodeArray([node.members[0]].concat(functions)) + ); + + return updatedClass; + } + return ts.visitEachChild(node, visit, context); + } + return ts.visitNode(rootNode, visit); + }; + + const addIdentifiers = ( + context: ts.TransformationContext + ) => (rootNode: T) => { + let count = 0; + function visit(node: ts.Node): ts.Node { + if (ts.isMethodDeclaration(node)) { + data.functions[count].allParams = []; + + let params = []; + if ( + (data.functions[ + count + ].classConstructorData.parameters[0].type = + 'TypeReference' && + !data.functions[count].classConstructorData + .parameters[0].optional) + ) { + params.push( + data.functions[count].classConstructorData.parameters[0] + ); + + data.functions[count].allParams.push({ + name: 'identifier', + optional: true, + type: 'string', + }); + } + + params = params.concat(data.functions[count].params); + data.functions[count].allParams = data.functions[ + count + ].allParams.concat(params); + + const parameters: any = params.map(param => { + const paramNode = ts.createParameter( + undefined, + undefined, + undefined, + param.name + ); + + if (param.optional) { + paramNode.initializer = ts.createIdentifier( + 'undefined' + ); + } + + return paramNode; + }); + + node.parameters = parameters.concat(node.parameters); + } + + if (ts.isStringLiteral(node) && node.text === 'pkgName') { + return ts.createStringLiteral( + '@google-cloud/' + data.functions[0].pkgName + ); + } + + if (ts.isIdentifier(node) && dummyIdentifiers.includes(node.text)) { + let updatedIdentifier; + switch (node.text) { + case 'ClassName': + updatedIdentifier = ts.updateIdentifier( + ts.createIdentifier( + 'GCP_' + data.functions[0].pkgName + ) + ); + break; + case 'ClientName': + updatedIdentifier = ts.updateIdentifier( + ts.createIdentifier(data.mainClass) + ); + break; + case 'SDKFunctionName': + updatedIdentifier = ts.updateIdentifier( + ts.createIdentifier( + data.functions[count].SDKFunctionName + ) + ); + count++; + break; + case '_className': + updatedIdentifier = ts.updateIdentifier( + ts.createIdentifier( + data.functions[count].client.toLowerCase() + ) + ); + break; + case '_client': + if ( + (data.functions[ + count + ].classConstructorData.parameters[0].type = + 'TypeReference' && + !data.functions[count].classConstructorData + .parameters[0].optional) + ) { + updatedIdentifier = ts.updateIdentifier( + ts.createIdentifier( + data.functions[count].classConstructorData + .parameters[0].name + ) + ); + } else { + updatedIdentifier = ts.updateIdentifier( + ts.createIdentifier( + '_' + data.mainClass.toLowerCase() + ) + ); + } + break; + case '_clientObj': + updatedIdentifier = ts.updateIdentifier( + ts.createIdentifier( + '_' + data.mainClass.toLowerCase() + ) + ); + break; + case 'Client': + updatedIdentifier = ts.updateIdentifier( + ts.createIdentifier(data.mainClass) + ); + break; + } + return updatedIdentifier; + } + + if (ts.isCallExpression(node)) { + node.expression.forEachChild(childNode => { + if ( + ts.isIdentifier(childNode) && + childNode.text === 'SDKFunctionName' + ) { + const args = data.functions[count].params.map(param => + ts.createIdentifier(param.name) + ); + node.arguments = args; + } + }); + } + + return ts.visitEachChild(node, visit, context); + } + return ts.visitNode(rootNode, visit); + }; + + const addComments = ( + context: ts.TransformationContext + ) => (rootNode: T) => { + let count = 0; + + function visit(node: ts.Node): ts.Node { + if (ts.isClassDeclaration(node)) { + addMultiLineComment( + node, + 'This is an auto generated class, please do not change.' + ); + const comment = `* * Class to create a ${data.functions[0].pkgName} object * @category Google Cloud `; - addMultiLineComment(node, comment); - } - - if (ts.isMethodDeclaration(node)) { - let parameters = data.functions[count].allParams.map(param => { - let statment; - - if (param.optional) { - statment = `* @param {${ - param.typeRefName ? param.typeRefName : param.type - }} [${param.name}] - Optional parameter`; - } else { - statment = `* @param {${ - param.typeRefName ? param.typeRefName : param.type - }} ${param.name} - Mandatory parameter`; - } - return statment; - }); - - let comment; - if (parameters.length > 0) { - let paramStatments: string = ""; - parameters.map(param => { - paramStatments = paramStatments.concat( - paramStatments === "" ? `${param}` : `\n ${param}` - ); - }); - - comment = `* + addMultiLineComment(node, comment); + } + + if (ts.isMethodDeclaration(node)) { + const parameters = data.functions[count].allParams.map( + param => { + let statment; + + if (param.optional) { + statment = `* @param {${ + param.typeRefName + ? param.typeRefName + : param.type + }} [${param.name}] - Optional parameter`; + } else { + statment = `* @param {${ + param.typeRefName + ? param.typeRefName + : param.type + }} ${param.name} - Mandatory parameter`; + } + return statment; + } + ); + + let comment; + if (parameters.length > 0) { + let paramStatments: string = ''; + parameters.map(param => { + paramStatments = paramStatments.concat( + paramStatments === '' ? `${param}` : `\n ${param}` + ); + }); + + comment = `* * Trigers the ${data.functions[count].SDKFunctionName} function of ${data.functions[0].pkgName} ${paramStatments} * @returns {Promise<${data.functions[count].SDKFunctionName}Response>} `; - } else { - comment = `* + } else { + comment = `* * Trigers the ${data.functions[count].SDKFunctionName} function of ${data.functions[0].pkgName} * @returns {Promise<${data.functions[count].SDKFunctionName}Response>} `; - } - - addMultiLineComment(node, comment); - count++; - } - - return ts.visitEachChild(node, visit, context); - } - return ts.visitNode(rootNode, visit); - }; - - const result_1 = await runTransformation(code, addFunctions); - const result_2 = await runTransformation( - toSourceFile(result_1), - addIdentifiers - ); - const result_3 = await runTransformation(toSourceFile(result_2), addComments); - return result_3; + } + + addMultiLineComment(node, comment); + count++; + } + + return ts.visitEachChild(node, visit, context); + } + return ts.visitNode(rootNode, visit); + }; + + const result_1 = await runTransformation(code, addFunctions); + const result_2 = await runTransformation( + toSourceFile(result_1), + addIdentifiers + ); + const result_3 = await runTransformation( + toSourceFile(result_2), + addComments + ); + return result_3; } diff --git a/generator/transformers/googleCloud/clientBasedTransformer.ts b/generator/transformers/googleCloud/clientBasedTransformer.ts index 525086dd..b2819e53 100644 --- a/generator/transformers/googleCloud/clientBasedTransformer.ts +++ b/generator/transformers/googleCloud/clientBasedTransformer.ts @@ -1,292 +1,309 @@ -import { cloneDeep } from "lodash"; -import * as ts from "typescript"; +import { cloneDeep } from 'lodash'; +import * as ts from 'typescript'; const dummyIdentifiers = [ - "ClassName", - "SDKFunctionName", - "ClientName", - "_client", - "_clientObj", - "Client" + 'ClassName', + 'SDKFunctionName', + 'ClientName', + '_client', + '_clientObj', + 'Client', ]; const printer: ts.Printer = ts.createPrinter({ - newLine: ts.NewLineKind.LineFeed, - removeComments: false + newLine: ts.NewLineKind.LineFeed, + removeComments: false, }); function addMultiLineComment(node, comment: string) { - ts.addSyntheticLeadingComment( - node, - ts.SyntaxKind.MultiLineCommentTrivia, - comment, - true - ); + ts.addSyntheticLeadingComment( + node, + ts.SyntaxKind.MultiLineCommentTrivia, + comment, + true + ); } function runTransformation(sourceCode, transformMethod): Promise { - return new Promise((resolve, reject) => { - try { - const result = ts.transform(sourceCode, [transformMethod]); - const transformedNodes = result.transformed[0]; - const output = printer.printNode( - ts.EmitHint.SourceFile, - transformedNodes, - sourceCode - ); - resolve(output); - } catch (error) { - reject(error); - } - }); + return new Promise((resolve, reject) => { + try { + const result = ts.transform(sourceCode, [transformMethod]); + const transformedNodes = result.transformed[0]; + const output = printer.printNode( + ts.EmitHint.SourceFile, + transformedNodes, + sourceCode + ); + resolve(output); + } catch (error) { + reject(error); + } + }); } function toSourceFile(sourceCode: string): ts.SourceFile { - return ts.createSourceFile( - "dummyClass.js", - sourceCode, - ts.ScriptTarget.Latest, - true - ); + return ts.createSourceFile( + 'dummyClass.js', + sourceCode, + ts.ScriptTarget.Latest, + true + ); } export async function clientBasedTransform( - code: ts.SourceFile, - classData: any + code: ts.SourceFile, + classData: any ): Promise { - const node: any = code.statements.find(stm => ts.isClassDeclaration(stm)); + const node: any = code.statements.find(stm => ts.isClassDeclaration(stm)); - if (!classData.functions) { - throw new Error("Input is invalid"); - } + if (!classData.functions) { + throw new Error('Input is invalid'); + } - if (!node || !node.members.some(member => ts.isMethodDeclaration(member))) { - throw new Error("Code is invalid"); - } + if (!node || !node.members.some(member => ts.isMethodDeclaration(member))) { + throw new Error('Code is invalid'); + } - code = cloneDeep(code); + code = cloneDeep(code); - // import related - classData.clients = Array.from( - new Set(classData.functions.map(method => method.client)) - ); - const importStatments: any = new Array(classData.clients.length); - importStatments.fill(Object.assign({}, code.statements[0])); - code.statements = importStatments.concat(code.statements.slice(1)); + // import related + classData.clients = Array.from( + new Set(classData.functions.map(method => method.client)) + ); + const importStatments: any = new Array(classData.clients.length); + importStatments.fill(Object.assign({}, code.statements[0])); + code.statements = importStatments.concat(code.statements.slice(1)); - let classDeclarationNode: any = code.statements.find(node => - ts.isClassDeclaration(node) - ); - let constructorNode: any = classDeclarationNode.members.find( - node => ts.SyntaxKind[node.kind] === "Constructor" - ); - const clientObjects: any = new Array(classData.clients.length); - clientObjects.fill(Object.assign({}, constructorNode.body.statements[0])); - constructorNode.body.statements = clientObjects; - // import related + const classDeclarationNode: any = code.statements.find(node => + ts.isClassDeclaration(node) + ); + const constructorNode: any = classDeclarationNode.members.find( + node => ts.SyntaxKind[node.kind] === 'Constructor' + ); + const clientObjects: any = new Array(classData.clients.length); + clientObjects.fill(Object.assign({}, constructorNode.body.statements[0])); + constructorNode.body.statements = clientObjects; + // import related - const addFunctions = ( - context: ts.TransformationContext - ) => (rootNode: T) => { - function visit(node: ts.Node): ts.Node { - if (ts.isClassDeclaration(node)) { - let functions: any = []; - classData.functions.map(method => { - let clonedNode; - if (method.returnTypeName === "Promise") { - clonedNode = Object.assign({}, node.members[1]); - } else { - clonedNode = Object.assign({}, node.members[2]); - } - clonedNode.name = ts.createIdentifier(method.functionName); - functions.push(clonedNode); - }); + const addFunctions = ( + context: ts.TransformationContext + ) => (rootNode: T) => { + function visit(node: ts.Node): ts.Node { + if (ts.isClassDeclaration(node)) { + const functions: any = []; + classData.functions.map(method => { + let clonedNode; + if (method.returnTypeName === 'Promise') { + clonedNode = Object.assign({}, node.members[1]); + } else { + clonedNode = Object.assign({}, node.members[2]); + } + clonedNode.name = ts.createIdentifier(method.functionName); + functions.push(clonedNode); + }); - const updatedClass = ts.updateClassDeclaration( - node, - node.decorators, - node.modifiers, - node.name, - node.typeParameters, - node.heritageClauses, - ts.createNodeArray([node.members[0]].concat(functions)) - ); + const updatedClass = ts.updateClassDeclaration( + node, + node.decorators, + node.modifiers, + node.name, + node.typeParameters, + node.heritageClauses, + ts.createNodeArray([node.members[0]].concat(functions)) + ); - return updatedClass; - } - return ts.visitEachChild(node, visit, context); - } - return ts.visitNode(rootNode, visit); - }; + return updatedClass; + } + return ts.visitEachChild(node, visit, context); + } + return ts.visitNode(rootNode, visit); + }; - const addIdentifiers = ( - context: ts.TransformationContext - ) => (rootNode: T) => { - let count = 0; - let clientCount = 0; - let clientObjCount = 0; - function visit(node: ts.Node): ts.Node { - if (ts.isMethodDeclaration(node)) { - const parameters = classData.functions[count].params.map(param => { - const paramNode = ts.createParameter( - undefined, - undefined, - undefined, - param.name - ); + const addIdentifiers = ( + context: ts.TransformationContext + ) => (rootNode: T) => { + let count = 0; + let clientCount = 0; + let clientObjCount = 0; + function visit(node: ts.Node): ts.Node { + if (ts.isMethodDeclaration(node)) { + const parameters = classData.functions[count].params.map( + param => { + const paramNode = ts.createParameter( + undefined, + undefined, + undefined, + param.name + ); - if (param.optional) { - paramNode.initializer = ts.createIdentifier("undefined"); - } + if (param.optional) { + paramNode.initializer = ts.createIdentifier( + 'undefined' + ); + } - return paramNode; - }); + return paramNode; + } + ); - node.parameters = parameters; - } + node.parameters = parameters; + } - if (ts.isStringLiteral(node) && node.text === "pkgName") { - return ts.createStringLiteral( - "@google-cloud/" + classData.functions[0].pkgName - ); - } + if (ts.isStringLiteral(node) && node.text === 'pkgName') { + return ts.createStringLiteral( + '@google-cloud/' + classData.functions[0].pkgName + ); + } - if (ts.isIdentifier(node) && dummyIdentifiers.includes(node.text)) { - let updatedIdentifier; - switch (node.text) { - case "ClassName": - updatedIdentifier = ts.updateIdentifier( - ts.createIdentifier("GCP_" + classData.serviceName) - ); - break; - case "ClientName": - updatedIdentifier = ts.updateIdentifier( - ts.createIdentifier(classData.clients[clientCount]) - ); - clientCount++; - break; - case "SDKFunctionName": - updatedIdentifier = ts.updateIdentifier( - ts.createIdentifier(classData.functions[count].SDKFunctionName) - ); - count++; - break; - case "_client": - updatedIdentifier = ts.updateIdentifier( - ts.createIdentifier( - "_" + - classData.functions[count].client.toLowerCase().charAt(0) + - classData.functions[count].client.substr(1) - ) - ); - break; - case "_clientObj": - updatedIdentifier = ts.updateIdentifier( - ts.createIdentifier( - "_" + - classData.clients[clientObjCount].toLowerCase().charAt(0) + - classData.clients[clientObjCount].substr(1) - ) - ); - break; - case "Client": - updatedIdentifier = ts.updateIdentifier( - ts.createIdentifier(classData.clients[clientObjCount]) - ); - clientObjCount++; - break; - } - return updatedIdentifier; - } + if (ts.isIdentifier(node) && dummyIdentifiers.includes(node.text)) { + let updatedIdentifier; + switch (node.text) { + case 'ClassName': + updatedIdentifier = ts.updateIdentifier( + ts.createIdentifier('GCP_' + classData.serviceName) + ); + break; + case 'ClientName': + updatedIdentifier = ts.updateIdentifier( + ts.createIdentifier(classData.clients[clientCount]) + ); + clientCount++; + break; + case 'SDKFunctionName': + updatedIdentifier = ts.updateIdentifier( + ts.createIdentifier( + classData.functions[count].SDKFunctionName + ) + ); + count++; + break; + case '_client': + updatedIdentifier = ts.updateIdentifier( + ts.createIdentifier( + '_' + + classData.functions[count].client + .toLowerCase() + .charAt(0) + + classData.functions[count].client.substr(1) + ) + ); + break; + case '_clientObj': + updatedIdentifier = ts.updateIdentifier( + ts.createIdentifier( + '_' + + classData.clients[clientObjCount] + .toLowerCase() + .charAt(0) + + classData.clients[clientObjCount].substr(1) + ) + ); + break; + case 'Client': + updatedIdentifier = ts.updateIdentifier( + ts.createIdentifier( + classData.clients[clientObjCount] + ) + ); + clientObjCount++; + break; + } + return updatedIdentifier; + } - if (ts.isCallExpression(node)) { - node.expression.forEachChild(childNode => { - if ( - ts.isIdentifier(childNode) && - childNode.text === "SDKFunctionName" - ) { - const args = classData.functions[count].params.map(param => - ts.createIdentifier(param.name) - ); - node.arguments = args; - } - }); - } + if (ts.isCallExpression(node)) { + node.expression.forEachChild(childNode => { + if ( + ts.isIdentifier(childNode) && + childNode.text === 'SDKFunctionName' + ) { + const args = classData.functions[count].params.map( + param => ts.createIdentifier(param.name) + ); + node.arguments = args; + } + }); + } - return ts.visitEachChild(node, visit, context); - } - return ts.visitNode(rootNode, visit); - }; + return ts.visitEachChild(node, visit, context); + } + return ts.visitNode(rootNode, visit); + }; - const addComments = ( - context: ts.TransformationContext - ) => (rootNode: T) => { - let count = 0; + const addComments = ( + context: ts.TransformationContext + ) => (rootNode: T) => { + let count = 0; - function visit(node: ts.Node): ts.Node { - if (ts.isClassDeclaration(node)) { - addMultiLineComment( - node, - "This is an auto generated class, please do not change." - ); - const comment = `* + function visit(node: ts.Node): ts.Node { + if (ts.isClassDeclaration(node)) { + addMultiLineComment( + node, + 'This is an auto generated class, please do not change.' + ); + const comment = `* * Class to create a ${classData.serviceName} object * @category Google Cloud `; - addMultiLineComment(node, comment); - } + addMultiLineComment(node, comment); + } - if (ts.isMethodDeclaration(node)) { - let parameters = classData.functions[count].params.map(param => { - let statment; + if (ts.isMethodDeclaration(node)) { + const parameters = classData.functions[count].params.map( + param => { + let statment; - if (param.optional) { - statment = `* @param {${param.type}} [${param.name}] - Data required for ${classData.functions[count].SDKFunctionName}`; - } else { - statment = `* @param {${param.type}} ${param.name} - Data required for ${classData.functions[count].SDKFunctionName}`; - } - return statment; - }); + if (param.optional) { + statment = `* @param {${param.type}} [${param.name}] - Data required for ${classData.functions[count].SDKFunctionName}`; + } else { + statment = `* @param {${param.type}} ${param.name} - Data required for ${classData.functions[count].SDKFunctionName}`; + } + return statment; + } + ); - let comment; - if (parameters.length > 0) { - let paramStatments: string = ""; - parameters.map(param => { - paramStatments = paramStatments.concat( - paramStatments === "" ? `${param}` : `\n ${param}` - ); - }); + let comment; + if (parameters.length > 0) { + let paramStatments: string = ''; + parameters.map(param => { + paramStatments = paramStatments.concat( + paramStatments === '' ? `${param}` : `\n ${param}` + ); + }); - comment = `* + comment = `* * Trigers the ${classData.functions[count].SDKFunctionName} function of ${ - classData.functions[0].pkgName.split("-")[1] - } + classData.functions[0].pkgName.split('-')[1] + } ${paramStatments} * @returns {Promise<${classData.functions[count].SDKFunctionName}Response>} `; - } else { - comment = `* + } else { + comment = `* * Trigers the ${classData.functions[count].SDKFunctionName} function of ${ - classData.functions[0].pkgName.split("-")[1] - } + classData.functions[0].pkgName.split('-')[1] + } * @returns {Promise<${classData.functions[count].SDKFunctionName}Response>} `; - } + } - addMultiLineComment(node, comment); - count++; - } + addMultiLineComment(node, comment); + count++; + } - return ts.visitEachChild(node, visit, context); - } - return ts.visitNode(rootNode, visit); - }; + return ts.visitEachChild(node, visit, context); + } + return ts.visitNode(rootNode, visit); + }; - const result_1 = await runTransformation(code, addFunctions); - const result_2 = await runTransformation( - toSourceFile(result_1), - addIdentifiers - ); - const result_3 = await runTransformation(toSourceFile(result_2), addComments); - return result_3; + const result_1 = await runTransformation(code, addFunctions); + const result_2 = await runTransformation( + toSourceFile(result_1), + addIdentifiers + ); + const result_3 = await runTransformation( + toSourceFile(result_2), + addComments + ); + return result_3; }