diff --git a/generator/generatedClasses/DO/storage/do-archivalStorage.js b/generator/generatedClasses/DO/storage/do-archivalStorage.js new file mode 100644 index 00000000..9ce3d3ff --- /dev/null +++ b/generator/generatedClasses/DO/storage/do-archivalStorage.js @@ -0,0 +1,72 @@ +/*This is an auto generated class, please do not change.*/ +/** + * Class to create a ObjectStorageClient object + * @category Oracle Cloud + */ +class Oracle_ArchivalStorage { + /** + * + * @param {module} do Oracle SDK + * @param {object} options SDK options + */ + constructor(ocisdk, params, clientConfiguration) { + this._oci = ocisdk; + this._sdkclassName = this._oci.objectStorageClient( + params, + clientConfiguration + ); + } + /** + * Trigers the createBucket function of ObjectStorageClient + * @param {CreateBucketRequest} createBucketRequest - Data required for createBucket + * @returns {Promise} + */ + create(createBucketRequest) { + return new Promise((resolve, reject) => { + this._objectStorageClient + .createBucket(createBucketRequest) + .then(data => resolve(data)) + .catch(err => reject(err)); + }); + } + /** + * Trigers the deleteBucket function of ObjectStorageClient + * @param {DeleteBucketRequest} deleteBucketRequest - Data required for deleteBucket + * @returns {Promise} + */ + delete(deleteBucketRequest) { + return new Promise((resolve, reject) => { + this._objectStorageClient + .deleteBucket(deleteBucketRequest) + .then(data => resolve(data)) + .catch(err => reject(err)); + }); + } + /** + * Trigers the listBuckets function of ObjectStorageClient + * @param {ListBucketsRequest} listBucketsRequest - Data required for listBuckets + * @returns {Promise} + */ + list(listBucketsRequest) { + return new Promise((resolve, reject) => { + this._objectStorageClient + .listBuckets(listBucketsRequest) + .then(data => resolve(data)) + .catch(err => reject(err)); + }); + } + /** + * Trigers the updateBucket function of ObjectStorageClient + * @param {UpdateBucketRequest} updateBucketRequest - Data required for updateBucket + * @returns {Promise} + */ + update(updateBucketRequest) { + return new Promise((resolve, reject) => { + this._objectStorageClient + .updateBucket(updateBucketRequest) + .then(data => resolve(data)) + .catch(err => reject(err)); + }); + } +} +module.exports = Oracle_ArchivalStorage; diff --git a/generator/generatedClasses/Oracle/storage/oci-archivalStorage.js b/generator/generatedClasses/Oracle/storage/oci-archivalStorage.js new file mode 100644 index 00000000..9ce3d3ff --- /dev/null +++ b/generator/generatedClasses/Oracle/storage/oci-archivalStorage.js @@ -0,0 +1,72 @@ +/*This is an auto generated class, please do not change.*/ +/** + * Class to create a ObjectStorageClient object + * @category Oracle Cloud + */ +class Oracle_ArchivalStorage { + /** + * + * @param {module} do Oracle SDK + * @param {object} options SDK options + */ + constructor(ocisdk, params, clientConfiguration) { + this._oci = ocisdk; + this._sdkclassName = this._oci.objectStorageClient( + params, + clientConfiguration + ); + } + /** + * Trigers the createBucket function of ObjectStorageClient + * @param {CreateBucketRequest} createBucketRequest - Data required for createBucket + * @returns {Promise} + */ + create(createBucketRequest) { + return new Promise((resolve, reject) => { + this._objectStorageClient + .createBucket(createBucketRequest) + .then(data => resolve(data)) + .catch(err => reject(err)); + }); + } + /** + * Trigers the deleteBucket function of ObjectStorageClient + * @param {DeleteBucketRequest} deleteBucketRequest - Data required for deleteBucket + * @returns {Promise} + */ + delete(deleteBucketRequest) { + return new Promise((resolve, reject) => { + this._objectStorageClient + .deleteBucket(deleteBucketRequest) + .then(data => resolve(data)) + .catch(err => reject(err)); + }); + } + /** + * Trigers the listBuckets function of ObjectStorageClient + * @param {ListBucketsRequest} listBucketsRequest - Data required for listBuckets + * @returns {Promise} + */ + list(listBucketsRequest) { + return new Promise((resolve, reject) => { + this._objectStorageClient + .listBuckets(listBucketsRequest) + .then(data => resolve(data)) + .catch(err => reject(err)); + }); + } + /** + * Trigers the updateBucket function of ObjectStorageClient + * @param {UpdateBucketRequest} updateBucketRequest - Data required for updateBucket + * @returns {Promise} + */ + update(updateBucketRequest) { + return new Promise((resolve, reject) => { + this._objectStorageClient + .updateBucket(updateBucketRequest) + .then(data => resolve(data)) + .catch(err => reject(err)); + }); + } +} +module.exports = Oracle_ArchivalStorage; diff --git a/generator/generatedClasses/Oracle/storage/oci-storageBucket.js b/generator/generatedClasses/Oracle/storage/oci-storageBucket.js new file mode 100644 index 00000000..61881ccc --- /dev/null +++ b/generator/generatedClasses/Oracle/storage/oci-storageBucket.js @@ -0,0 +1,85 @@ +/*This is an auto generated class, please do not change.*/ +/** + * Class to create a ObjectStorageClient object + * @category Oracle Cloud + */ +class Oracle_StorageBucket { + /** + * + * @param {module} do Oracle SDK + * @param {object} options SDK options + */ + constructor(ocisdk, params, clientConfiguration) { + this._oci = ocisdk; + this._sdkclassName = this._oci.objectStorageClient( + params, + clientConfiguration + ); + } + /** + * Trigers the createBucket function of ObjectStorageClient + * @param {CreateBucketRequest} createBucketRequest - Data required for createBucket + * @returns {Promise} + */ + create(createBucketRequest) { + return new Promise((resolve, reject) => { + this._objectStorageClient + .createBucket(createBucketRequest) + .then(data => resolve(data)) + .catch(err => reject(err)); + }); + } + /** + * Trigers the deleteBucket function of ObjectStorageClient + * @param {DeleteBucketRequest} deleteBucketRequest - Data required for deleteBucket + * @returns {Promise} + */ + delete(deleteBucketRequest) { + return new Promise((resolve, reject) => { + this._objectStorageClient + .deleteBucket(deleteBucketRequest) + .then(data => resolve(data)) + .catch(err => reject(err)); + }); + } + /** + * Trigers the getBucket function of ObjectStorageClient + * @param {GetBucketRequest} getBucketRequest - Data required for getBucket + * @returns {Promise} + */ + get(getBucketRequest) { + return new Promise((resolve, reject) => { + this._objectStorageClient + .getBucket(getBucketRequest) + .then(data => resolve(data)) + .catch(err => reject(err)); + }); + } + /** + * Trigers the listBuckets function of ObjectStorageClient + * @param {ListBucketsRequest} listBucketsRequest - Data required for listBuckets + * @returns {Promise} + */ + list(listBucketsRequest) { + return new Promise((resolve, reject) => { + this._objectStorageClient + .listBuckets(listBucketsRequest) + .then(data => resolve(data)) + .catch(err => reject(err)); + }); + } + /** + * Trigers the reencryptBucket function of ObjectStorageClient + * @param {ReencryptBucketRequest} reencryptBucketRequest - Data required for reencryptBucket + * @returns {Promise} + */ + reencrypt(reencryptBucketRequest) { + return new Promise((resolve, reject) => { + this._objectStorageClient + .reencryptBucket(reencryptBucketRequest) + .then(data => resolve(data)) + .catch(err => reject(err)); + }); + } +} +module.exports = Oracle_StorageBucket; diff --git a/generator/generators/oracle/generator.js b/generator/generators/oracle/generator.js index b33d9440..a34adcdf 100644 --- a/generator/generators/oracle/generator.js +++ b/generator/generators/oracle/generator.js @@ -141,33 +141,24 @@ var __generator = }; exports.__esModule = true; exports.generateOracleClass = exports.extractSDKData = void 0; -// import { getAST } from '../../parsers/oracle/parser'; +var fs = require('fs'); var typescript_1 = require('typescript'); var parser_1 = require('../../parsers/oracle/parser'); -// interface ClassData { -// className: string; -// functions: FunctionData[]; -// serviceName: string; -// } +var helper_1 = require('../lib/helper'); +var transformer_1 = require('../../transformers/oracle/transformer'); +var dummyFile = process.cwd() + '/dummyClasses/oracle.js'; +var dummyAst = typescript_1.createSourceFile( + dummyFile, + fs.readFileSync(dummyFile).toString(), + typescript_1.ScriptTarget.Latest, + true +); function extractSDKData(sdkClassAst, serviceClass) { var methods = []; var functions = []; Object.keys(serviceClass).map(function(key, index) { functions.push(serviceClass[key].split(' ')[1]); }); - // console.log(functions); - // console.log(sdkClassAst); - // console.log(Array.from(sdkClassAst.members)[0]); - // Array.from(sdkClassAst.members).map(method=>{ - // // console.log(method.name.escapedText); - // }) - // console.log(Object.keys(sdkClassAst.members)); - // console.log(sdkClassAst.members['99']); - // Object.keys(sdkClassAst.members).map((key,index)=>{ - // console.log(key); - // // const member = sdkClassAst.members[key]; - // // console.log(member.name.text); - // }) sdkClassAst.members.map(function(method) { if (method.name && functions.includes(method.name.text)) { var name_1; @@ -207,6 +198,7 @@ function extractSDKData(sdkClassAst, serviceClass) { serviceName: null, }; console.log(classData); + return classData; } exports.extractSDKData = extractSDKData; function generateOracleClass(serviceClass, serviceName) { @@ -215,14 +207,64 @@ function generateOracleClass(serviceClass, serviceName) { console.log(sdkFile); parser_1.getAST(sdkFile).then(function(result) { return __awaiter(_this, void 0, void 0, function() { - var sdkClassAst; + var sdkClassAst, classData, output, filePath, dir, error_1; return __generator(this, function(_a) { - sdkClassAst = result; - try { - // const classData: ClassData = extractSDKData(sdkClassAst,serviceClass) - extractSDKData(sdkClassAst, serviceClass); - } catch (error) {} - return [2 /*return*/]; + switch (_a.label) { + case 0: + sdkClassAst = result; + _a.label = 1; + case 1: + _a.trys.push([1, 3, , 4]); + classData = extractSDKData(sdkClassAst, serviceClass); + classData.serviceName = serviceName; + return [ + 4 /*yield*/, + transformer_1.transform(dummyAst, classData), + ]; + case 2: + output = _a.sent(); + filePath = void 0; + dir = helper_1.getDir(serviceName); + if ( + !fs.existsSync( + process.cwd() + + '/generatedClasses/Oracle/' + + dir + ) + ) { + fs.mkdirSync( + process.cwd() + + '/generatedClasses/Oracle/' + + dir + ); + } + if (/^[A-Z]*$/.test(serviceName)) { + filePath = + process.cwd() + + '/generatedClasses/Oracle/' + + dir + + '/oci-' + + serviceName + + '.js'; + } else { + filePath = + process.cwd() + + '/generatedClasses/Oracle/' + + dir + + '/oci-' + + serviceName.charAt(0).toLowerCase() + + serviceName.slice(1) + + '.js'; + } + helper_1.printFile(filePath, output); + return [3 /*break*/, 4]; + case 3: + error_1 = _a.sent(); + console.error(error_1); + return [3 /*break*/, 4]; + case 4: + return [2 /*return*/]; + } }); }); }); diff --git a/generator/generators/oracle/generator.ts b/generator/generators/oracle/generator.ts index 2c3e54f6..765a4636 100644 --- a/generator/generators/oracle/generator.ts +++ b/generator/generators/oracle/generator.ts @@ -1,6 +1,9 @@ -import { SyntaxKind } from 'typescript'; -// import { getAST } from '../../parsers/oracle/parser'; -// import { getAST } from '../../parsers/oracle/parser'; +import * as fs from 'fs'; +import { createSourceFile, ScriptTarget, SyntaxKind } from 'typescript'; + +import { getAST } from '../../parsers/oracle/parser'; +import { transform } from '../../transformers/oracle/transformer'; +import { getDir, printFile } from '../lib/helper'; interface FunctionData { functionName: string; @@ -19,8 +22,17 @@ interface ClassData { serviceName: string; } +const dummyFile = process.cwd() + '/dummyClasses/oracle.js'; + +const dummyAst = createSourceFile( + dummyFile, + fs.readFileSync(dummyFile).toString(), + ScriptTarget.Latest, + true +); + export function extractSDKData(sdkClassAst, serviceClass) { - let methods: FunctionData[] = []; + const methods: FunctionData[] = []; const functions = []; Object.keys(serviceClass).map((key, index) => { functions.push(serviceClass[key].split(' ')[1]); @@ -65,18 +77,51 @@ export function extractSDKData(sdkClassAst, serviceClass) { functions: methods, serviceName: null, }; - console.log(classData); return classData; } export function generateOracleClass(serviceClass, serviceName) { const sdkFile = serviceClass[Object.keys(serviceClass)[0]].split(' ')[0]; console.log(sdkFile); - // getAST(sdkFile).then(async result => { - // const sdkClassAst = result; - // try { - // // const classData: ClassData = extractSDKData(sdkClassAst,serviceClass) - // extractSDKData(sdkClassAst, serviceClass); - // } catch (error) {} - // }); + 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/Oracle/' + dir + ) + ) { + fs.mkdirSync(process.cwd() + '/generatedClasses/Oracle/' + dir); + } + if (/^[A-Z]*$/.test(serviceName)) { + filePath = + process.cwd() + + '/generatedClasses/Oracle/' + + dir + + '/oci-' + + serviceName + + '.js'; + } else { + filePath = + process.cwd() + + '/generatedClasses/Oracle/' + + dir + + '/oci-' + + serviceName.charAt(0).toLowerCase() + + serviceName.slice(1) + + '.js'; + } + printFile(filePath, output); + } catch (error) { + console.error(error); + } + }); } diff --git a/generator/transformers/oracle/transformer.js b/generator/transformers/oracle/transformer.js new file mode 100644 index 00000000..858a836c --- /dev/null +++ b/generator/transformers/oracle/transformer.js @@ -0,0 +1,477 @@ +'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.transform = void 0; +var lodash_1 = require('lodash'); +var ts = require('typescript'); +var dummyIdentifiers = [ + 'ClassName', + '_sdkClassName', + 'SDKClassName', + 'SDKFunctionName', +]; +var printer = ts.createPrinter({ + newLine: ts.NewLineKind.LineFeed, + removeComments: false, +}); +function addMultiLineComment(node, comment) { + ts.addSyntheticLeadingComment( + node, + ts.SyntaxKind.MultiLineCommentTrivia, + comment, + true + ); +} +function runTransformation(sourceCode, transformMethod) { + return new Promise(function(resolve, reject) { + try { + var result = ts.transform(sourceCode, [transformMethod]); + var transformedNodes = result.transformed[0]; + var output = printer.printNode( + ts.EmitHint.SourceFile, + transformedNodes, + sourceCode + ); + resolve(output); + } catch (error) { + reject(error); + } + }); +} +function toSourceFile(sourceCode) { + return ts.createSourceFile( + 'dummyClass.js', + sourceCode, + ts.ScriptTarget.Latest, + true + ); +} +function transform(code, classData) { + return __awaiter(this, void 0, void 0, function() { + var addFunctions, + addIdentifiers, + addComments, + node, + result_1, + result_2, + result_3; + return __generator(this, function(_a) { + switch (_a.label) { + case 0: + addFunctions = function(context) { + return function(rootNode) { + function visit(node) { + if (ts.isClassDeclaration(node)) { + var functions_1 = []; + classData.functions.map(function(method) { + var clonedNode = Object.assign( + {}, + node.members[1] + ); + // console.log("Cloned Node..........\n");//sdadas + // console.log(clonedNode);//asdasdasdasd + clonedNode.name = ts.createIdentifier( + method.functionName + ); + functions_1.push(clonedNode); + }); + var updatedClass = ts.updateClassDeclaration( + node, + node.decorators, + node.modifiers, + node.name, + node.typeParameters, + node.heritageClauses, + ts.createNodeArray( + [node.members[0]].concat( + functions_1 + ) + ) + ); + return updatedClass; + } + return ts.visitEachChild(node, visit, context); + } + return ts.visitNode(rootNode, visit); + }; + }; + addIdentifiers = function(context) { + return function(rootNode) { + var count = 0; + function visit(node) { + if (ts.isMethodDeclaration(node)) { + var parameters = classData.functions[ + count + ].params.map(function(param) { + var 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) + ) { + var updatedIdentifier = void 0; + switch (node.text) { + case 'ClassName': + updatedIdentifier = ts.updateIdentifier( + ts.createIdentifier( + 'Oracle_' + + 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(function( + childNode + ) { + if ( + ts.isIdentifier(childNode) && + childNode.text === 'SDKFunctionName' + ) { + var args = classData.functions[ + count + ].params.map(function(param) { + return ts.createIdentifier( + param.name + ); + }); + node.arguments = args.concat( + node.arguments + ); + } + }); + } + return ts.visitEachChild(node, visit, context); + } + return ts.visitNode(rootNode, visit); + }; + }; + addComments = function(context) { + return function(rootNode) { + var count = 0; + function visit(node) { + if (ts.isClassDeclaration(node)) { + addMultiLineComment( + node, + 'This is an auto generated class, please do not change.' + ); + var comment = + '*\n * Class to create a ' + + classData.className + + ' object\n * @category Oracle Cloud \n '; + addMultiLineComment(node, comment); + } + if (ts.isMethodDeclaration(node)) { + var parameters = classData.functions[ + count + ].params.map(function(param) { + var 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; + }); + var comment = void 0; + if (parameters.length > 0) { + var paramStatments_1 = ''; + parameters.map(function(param) { + paramStatments_1 = paramStatments_1.concat( + paramStatments_1 === '' + ? '' + param + : '\n' + param + ); + }); + comment = + '*\n * Trigers the ' + + classData.functions[count] + .SDKFunctionName + + ' function of ' + + classData.className + + '\n ' + + paramStatments_1 + + '\n * @returns {Promise<' + + classData.functions[count] + .SDKFunctionName + + 'Response>}\n '; + } else { + comment = + '*\n * Trigers the ' + + classData.functions[count] + .SDKFunctionName + + ' function of ' + + classData.className + + '\n * @returns {Promise<' + + classData.functions[count] + .SDKFunctionName + + 'Response>}\n '; + } + addMultiLineComment(node, comment); + count++; + } + return ts.visitEachChild(node, visit, context); + } + return ts.visitNode(rootNode, visit); + }; + }; + node = code.statements.find(function(stm) { + return ts.isClassDeclaration(stm); + }); + if (!classData.className || !classData.functions) { + throw new Error('Input is invalid'); + } + if ( + !node || + !node.members.some(function(member) { + return ts.isMethodDeclaration(member); + }) + ) { + throw new Error('Code is invalid'); + } + code = lodash_1.cloneDeep(code); + return [4 /*yield*/, runTransformation(code, addFunctions)]; + case 1: + result_1 = _a.sent(); + return [ + 4 /*yield*/, + runTransformation( + toSourceFile(result_1), + addIdentifiers + ), + ]; + case 2: + result_2 = _a.sent(); + return [ + 4 /*yield*/, + runTransformation(toSourceFile(result_2), addComments), + ]; + case 3: + result_3 = _a.sent(); + return [2 /*return*/, result_3]; + } + }); + }); +} +exports.transform = transform; diff --git a/generator/transformers/oracle/transformer.ts b/generator/transformers/oracle/transformer.ts new file mode 100644 index 00000000..c5157dd1 --- /dev/null +++ b/generator/transformers/oracle/transformer.ts @@ -0,0 +1,275 @@ +import { cloneDeep } from 'lodash'; +import * as ts from 'typescript'; + +const dummyIdentifiers = [ + 'ClassName', + '_sdkClassName', + 'SDKClassName', + 'SDKFunctionName', +]; + +const printer: ts.Printer = ts.createPrinter({ + newLine: ts.NewLineKind.LineFeed, + removeComments: false, +}); + +function addMultiLineComment(node, comment: string) { + 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); + } + }); +} + +function toSourceFile(sourceCode: string): ts.SourceFile { + return ts.createSourceFile( + 'dummyClass.js', + sourceCode, + ts.ScriptTarget.Latest, + true + ); +} +export async function transform( + 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)) { + 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); + }; + + /* + * 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( + 'Oracle_' + 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 Oracle Cloud + `; + 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 = `* + * 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; +}