diff --git a/package.json b/package.json index ea5417ad..372d6ad3 100644 --- a/package.json +++ b/package.json @@ -10,55 +10,61 @@ "@oclif/command": "^1", "@oclif/config": "^1", "@oclif/errors": "^1", - "@salesforce/command": "^4.2.1", - "@salesforce/core": "^2.37.1", + "@salesforce/command": "^5.3.9", + "@salesforce/core": "^8.6.1", "@types/jsdom": "^21.1.7", "@types/lodash.chunk": "^4.2.9", "@types/shelljs": "^0.8.15", + "@xmldom/xmldom": "^0.7.5", "cheerio": "^1.0.0", "jsdom": "^25.0.0", "lodash.chunk": "^4.2.0", + "minimatch": "^10.0.1", + "nanoid": "^5.0.7", "open": "^8.4.2", + "prettier-plugin-apex": "^2.1.4", "shelljs": "^0.8.5", - "tslib": "^2", - "xmldom": "^0.6.0" + "tslib": "^2" }, "devDependencies": { "@babel/parser": "^7.25.6", + "@eslint/eslintrc": "^3.1.0", + "@eslint/js": "^9.12.0", "@oclif/dev-cli": "^1", "@oclif/plugin-command-snapshot": "^3.3.15", "@oclif/plugin-help": "^3", "@oclif/test": "^1", "@salesforce/dev-config": "^2.1.2", - "@salesforce/dev-scripts": "^0", + "@salesforce/dev-scripts": "^10.2.10", "@salesforce/plugin-command-reference": "^1.4.7", "@salesforce/prettier-config": "^0.0.3", "@salesforce/ts-sinon": "^1", "@types/babel__traverse": "^7.20.6", "@types/jsforce": "^1.11.5", - "@typescript-eslint/eslint-plugin": "^4.2.0", - "@typescript-eslint/parser": "^4.2.0", + "@typescript-eslint/eslint-plugin": "^8.8.0", + "@typescript-eslint/parser": "^8.8.0", "chai": "^4.4.1", - "eslint": "^7.27.0", + "eslint": "^9.12.0", "eslint-config-oclif": "^3.1", "eslint-config-prettier": "^8", "eslint-config-salesforce": "^0.1.6", "eslint-config-salesforce-license": "^0.2.0", - "eslint-config-salesforce-typescript": "^0.2.7", + "eslint-config-salesforce-typescript": "^3.4.0", "eslint-plugin-header": "^3.0.0", - "eslint-plugin-import": "2.24.2", + "eslint-plugin-import": "^2.31.0", "eslint-plugin-jsdoc": "^35.1.2", "eslint-plugin-prettier": "^3.1.3", "eslint-plugin-typescript": "^0", "globby": "^11", "husky": "^4.3.8", - "mocha": "^8.4.0", + "mocha": "^10.7.3", "nyc": "^15.1.0", - "prettier": "^2.8.8", + "prettier": "^3.3.3", "pretty-quick": "^3.3.1", "sinon": "10.0.0", "ts-node": "^10.9.2", - "typescript": "^4.9.5" + "typedoc": "^0.26.10", + "typescript": "^5.6.2" }, "engines": { "node": ">=12.0.0" diff --git a/src/commands/omnistudio/migration/info.ts b/src/commands/omnistudio/migration/info.ts index 416637a9..28f620a5 100644 --- a/src/commands/omnistudio/migration/info.ts +++ b/src/commands/omnistudio/migration/info.ts @@ -6,7 +6,7 @@ */ import * as os from 'os'; import { flags, SfdxCommand } from '@salesforce/command'; -import { Messages, SfdxError } from '@salesforce/core'; +import { Messages, SfError } from '@salesforce/core'; import { AnyJson } from '@salesforce/ts-types'; // Initialize Messages with the current plugin directory @@ -66,7 +66,7 @@ export default class Org extends SfdxCommand { // Organization will always return one result, but this is an example of throwing an error // The output and --json will automatically be handled for you. if (!result.records || result.records.length <= 0) { - throw new SfdxError(messages.getMessage('errorNoOrgResults', [this.org.getOrgId()])); + throw new SfError(messages.getMessage('errorNoOrgResults', [this.org.getOrgId()])); } // Organization always only returns one result diff --git a/src/commands/omnistudio/migration/migrate.ts b/src/commands/omnistudio/migration/migrate.ts index b0e646bd..118746b9 100644 --- a/src/commands/omnistudio/migration/migrate.ts +++ b/src/commands/omnistudio/migration/migrate.ts @@ -9,7 +9,7 @@ */ import * as os from 'os'; import { flags } from '@salesforce/command'; -import { Messages } from '@salesforce/core'; +import { Messages, Org } from '@salesforce/core'; import '../../../utils/prototypes'; import OmniStudioBaseCommand from '../../basecommand'; import { DataRaptorMigrationTool } from '../../../migration/dataraptor'; @@ -58,10 +58,12 @@ export default class Migrate extends OmniStudioBaseCommand { const migrateOnly = (this.flags.only || '') as string; const allVersions = this.flags.allversions || false; - Logger.initialiseLogger(this.ux, this.logger); - this.logger = Logger.logger; + Logger.initialiseLogger(this.ux, Logger.logger); + // this.logger = Logger.logger; + const logger = Logger.logger; // this.org is guaranteed because requiresUsername=true, as opposed to supportsUsername - const conn = this.org.getConnection(); + const org = new Org(); + const conn = org.getConnection(); conn.setApiVersion(apiVersion); // Let's time every step @@ -71,17 +73,9 @@ export default class Migrate extends OmniStudioBaseCommand { let migrationObjects: MigrationTool[] = []; if (!migrateOnly) { migrationObjects = [ - new DataRaptorMigrationTool(namespace, conn, this.logger, messages, this.ux), - new OmniScriptMigrationTool( - OmniScriptExportType.All, - namespace, - conn, - this.logger, - messages, - this.ux, - allVersions - ), - new CardMigrationTool(namespace, conn, this.logger, messages, this.ux, allVersions), + new DataRaptorMigrationTool(namespace, conn, logger, messages, this.ux), + new OmniScriptMigrationTool(OmniScriptExportType.All, namespace, conn, logger, messages, this.ux, allVersions), + new CardMigrationTool(namespace, conn, logger, messages, this.ux, allVersions), ]; } else { switch (migrateOnly) { @@ -91,7 +85,7 @@ export default class Migrate extends OmniStudioBaseCommand { OmniScriptExportType.OS, namespace, conn, - this.logger, + logger, messages, this.ux, allVersions @@ -104,7 +98,7 @@ export default class Migrate extends OmniStudioBaseCommand { OmniScriptExportType.IP, namespace, conn, - this.logger, + logger, messages, this.ux, allVersions @@ -112,10 +106,10 @@ export default class Migrate extends OmniStudioBaseCommand { ); break; case 'fc': - migrationObjects.push(new CardMigrationTool(namespace, conn, this.logger, messages, this.ux, allVersions)); + migrationObjects.push(new CardMigrationTool(namespace, conn, logger, messages, this.ux, allVersions)); break; case 'dr': - migrationObjects.push(new DataRaptorMigrationTool(namespace, conn, this.logger, messages, this.ux)); + migrationObjects.push(new DataRaptorMigrationTool(namespace, conn, logger, messages, this.ux)); break; default: throw new Error(messages.getMessage('invalidOnlyFlag')); @@ -173,7 +167,7 @@ export default class Migrate extends OmniStudioBaseCommand { namespace, migrateOnly, allVersions, - this.org + org ); omnistudioRelatedObjectsMigration.migrateAll(objectMigrationResults, []); await ResultsBuilder.generate(objectMigrationResults, conn.instanceUrl); diff --git a/src/migration/base.ts b/src/migration/base.ts index bb4ee6fd..567949fc 100644 --- a/src/migration/base.ts +++ b/src/migration/base.ts @@ -11,10 +11,10 @@ export class BaseMigrationTool { protected readonly connection: Connection; protected readonly namespacePrefix: string; protected readonly logger: Logger; - protected readonly messages: Messages; + protected readonly messages: Messages; protected readonly ux: UX; - public constructor(namespace: string, connection: Connection, logger: Logger, messages: Messages, ux: UX) { + public constructor(namespace: string, connection: Connection, logger: Logger, messages: Messages, ux: UX) { this.namespace = namespace; this.connection = connection; this.logger = logger; diff --git a/src/migration/flexcard.ts b/src/migration/flexcard.ts index eaeb0b85..6d9b2a7c 100644 --- a/src/migration/flexcard.ts +++ b/src/migration/flexcard.ts @@ -17,7 +17,7 @@ export class CardMigrationTool extends BaseMigrationTool implements MigrationToo namespace: string, connection: Connection, logger: Logger, - messages: Messages, + messages: Messages, ux: UX, allVersions: boolean ) { diff --git a/src/migration/omniscript.ts b/src/migration/omniscript.ts index 490285e0..c57f62b7 100644 --- a/src/migration/omniscript.ts +++ b/src/migration/omniscript.ts @@ -31,7 +31,7 @@ export class OmniScriptMigrationTool extends BaseMigrationTool implements Migrat namespace: string, connection: Connection, logger: Logger, - messages: Messages, + messages: Messages, ux: UX, allVersions: boolean ) { diff --git a/src/utils/apex/executor/AnonymousApexRunner.js b/src/utils/apex/executor/AnonymousApexRunner.js new file mode 100644 index 00000000..9e256ac7 --- /dev/null +++ b/src/utils/apex/executor/AnonymousApexRunner.js @@ -0,0 +1,52 @@ +"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 = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype); + return g.next = verb(0), g["throw"] = verb(1), g["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 (g && (g = 0, op[0] && (_ = 0)), _) 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 }; + } +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.AnonymousApexRunner = void 0; +var AnonymousApexRunner = /** @class */ (function () { + function AnonymousApexRunner() { + } + AnonymousApexRunner.run = function (org, anonymousApex) { + return __awaiter(this, void 0, void 0, function () { + return __generator(this, function (_a) { + return [2 /*return*/, org.getConnection().tooling.executeAnonymous(anonymousApex)]; + }); + }); + }; + return AnonymousApexRunner; +}()); +exports.AnonymousApexRunner = AnonymousApexRunner; diff --git a/src/utils/apex/executor/AnonymousApexRunner.ts b/src/utils/apex/executor/AnonymousApexRunner.ts index c3227f34..f2281f93 100644 --- a/src/utils/apex/executor/AnonymousApexRunner.ts +++ b/src/utils/apex/executor/AnonymousApexRunner.ts @@ -1,8 +1,8 @@ import { Org } from '@salesforce/core'; -import { ExecuteAnonymousResult } from 'jsforce'; export class AnonymousApexRunner { - public static async run(org: Org, anonymousApex: string): Promise { - return org.getConnection().tooling.executeAnonymous(anonymousApex); + public static async run(org: Org, anonymousApex: string): Promise { + const connection = org.getConnection(); + return connection.tooling.executeAnonymous(anonymousApex); } } diff --git a/src/utils/apex/parser/apexparser.js b/src/utils/apex/parser/apexparser.js new file mode 100644 index 00000000..1cb45734 --- /dev/null +++ b/src/utils/apex/parser/apexparser.js @@ -0,0 +1,265 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.InsertAfterTokenUpdate = exports.MapUtil = exports.SingleTokenUpdate = exports.RangeTokenUpdate = exports.InterfaceMatcher = exports.InterfaceImplements = exports.ParameterType = exports.MethodParameter = exports.MethodCall = exports.ApexASTParser = void 0; +/* eslint-disable @typescript-eslint/no-unsafe-return */ +/* eslint-disable @typescript-eslint/no-unsafe-call */ +/* eslint-disable @typescript-eslint/no-unsafe-member-access */ +/* eslint-disable @typescript-eslint/no-unsafe-assignment */ +var apex_parser_1 = require("@apexdevtools/apex-parser"); +var antlr4ts_1 = require("antlr4ts"); +var ParseTreeWalker_1 = require("antlr4ts/tree/ParseTreeWalker"); +var ApexASTParser = /** @class */ (function () { + function ApexASTParser(apexFileContent, interfaceNames, methodCalls, namespace) { + this.implementsInterface = new Map(); + this.methodParameter = new Map(); + this.nonReplacableMethodParameter = []; + this.namespaceChange = new Map(); + this.apexFileContent = apexFileContent; + this.interfaceNames = interfaceNames; + this.methodCalls = methodCalls; + this.namespace = namespace; + this.astListener = this.createASTListener(); + } + Object.defineProperty(ApexASTParser.prototype, "implementsInterfaces", { + get: function () { + return this.implementsInterface; + }, + enumerable: false, + configurable: true + }); + Object.defineProperty(ApexASTParser.prototype, "classDeclaration", { + get: function () { + return this.classDeclarationToken; + }, + enumerable: false, + configurable: true + }); + Object.defineProperty(ApexASTParser.prototype, "methodParameters", { + get: function () { + return this.methodParameter; + }, + enumerable: false, + configurable: true + }); + Object.defineProperty(ApexASTParser.prototype, "namespaceChanges", { + get: function () { + return this.namespaceChange; + }, + enumerable: false, + configurable: true + }); + Object.defineProperty(ApexASTParser.prototype, "nonReplacableMethodParameters", { + get: function () { + return this.nonReplacableMethodParameter; + }, + enumerable: false, + configurable: true + }); + ApexASTParser.prototype.parse = function () { + var lexer = new apex_parser_1.ApexLexer(new apex_parser_1.CaseInsensitiveInputStream(antlr4ts_1.CharStreams.fromString(this.apexFileContent))); + var tokens = new apex_parser_1.CommonTokenStream(lexer); + var parser = new apex_parser_1.ApexParser(tokens); + var context = parser.compilationUnit(); + // parser.addParseListener(new interfaceVisitor() as ApexParserListener); + ParseTreeWalker_1.ParseTreeWalker.DEFAULT.walk(this.astListener, context); + return context; + }; + ApexASTParser.prototype.rewrite = function (tokenUpdates) { + var lexer = new apex_parser_1.ApexLexer(new apex_parser_1.CaseInsensitiveInputStream(antlr4ts_1.CharStreams.fromString(this.apexFileContent))); + var tokens = new apex_parser_1.CommonTokenStream(lexer); + var rewriter = new antlr4ts_1.TokenStreamRewriter(tokens); + var parser = new apex_parser_1.ApexParser(tokens); + parser.compilationUnit(); + for (var _i = 0, tokenUpdates_1 = tokenUpdates; _i < tokenUpdates_1.length; _i++) { + var tokenUpdate = tokenUpdates_1[_i]; + tokenUpdate.applyUpdate(rewriter); + } + return rewriter.getText(); + }; + ApexASTParser.prototype.createASTListener = function () { + var ApexMigrationListener = /** @class */ (function () { + function ApexMigrationListener(parser) { + this.parser = parser; + // + } + ApexMigrationListener.prototype.enterClassDeclaration = function (ctx) { + var interfaceToBeSearched = this.parser.interfaceNames; + if (!interfaceToBeSearched) + return; + if (!ctx.typeList() || !ctx.typeList().typeRef()) + return; + for (var _i = 0, _a = ctx.typeList().typeRef(); _i < _a.length; _i++) { + var typeRefContext = _a[_i]; + for (var _b = 0, _c = this.parser.interfaceNames; _b < _c.length; _b++) { + var toSearch = _c[_b]; + var matchingTokens = InterfaceMatcher.getMatchingTokens(toSearch, typeRefContext); + if (matchingTokens.length === 0) + continue; + this.parser.implementsInterface.set(toSearch, matchingTokens); + this.parser.classDeclarationToken = ctx.classBody().LBRACE().symbol; + } + } + }; + ApexMigrationListener.prototype.enterDotExpression = function (ctx) { + var _a, _b, _c, _d; + var dotMethodCall = ctx.dotMethodCall(); + if (dotMethodCall && this.parser.methodCalls && ((_a = ctx.expression().children) === null || _a === void 0 ? void 0 : _a.length) > 2) { + var namespaceUsed = ctx.expression().getChild(0); + var methodName = (_c = (_b = dotMethodCall === null || dotMethodCall === void 0 ? void 0 : dotMethodCall.anyId()) === null || _b === void 0 ? void 0 : _b.Identifier()) === null || _c === void 0 ? void 0 : _c.symbol; + var className = ctx.expression().getChild(2); + if (!methodName) + return; + for (var _i = 0, _e = this.parser.methodCalls; _i < _e.length; _i++) { + var methodcall = _e[_i]; + if (!methodcall.sameCall(className.text, methodName.text, namespaceUsed.text)) + continue; + MapUtil.addToValueList(this.parser.namespaceChange, this.parser.namespace, ctx.expression().start); + var parameter = methodcall.parameter; + if (!parameter) + continue; + var bundleName = dotMethodCall.expressionList().expression(parameter.position - 1); + if (bundleName && + (bundleName === null || bundleName === void 0 ? void 0 : bundleName.children) && + bundleName.childCount > 0 && + bundleName.children[0] instanceof apex_parser_1.LiteralPrimaryContext) { + var arg = bundleName.getChild(0); + var argValue = (_d = arg === null || arg === void 0 ? void 0 : arg.literal()) === null || _d === void 0 ? void 0 : _d.StringLiteral(); + if (!argValue) + continue; + MapUtil.addToValueList(this.parser.methodParameter, parameter.type, argValue.symbol); + } + else { + this.parser.nonReplacableMethodParameter.push(methodcall); + } + } + } + }; + ApexMigrationListener.prototype.enterTypeRef = function (ctx) { + if (ctx.childCount >= 2 && + ctx.typeName(0).text === this.parser.namespace && + ctx.typeName(1).text === 'DRProcessResult') { + MapUtil.addToValueList(this.parser.namespaceChange, this.parser.namespace, ctx.typeName(0).start); + } + }; + return ApexMigrationListener; + }()); + return new ApexMigrationListener(this); + }; + return ApexASTParser; +}()); +exports.ApexASTParser = ApexASTParser; +var MethodCall = /** @class */ (function () { + function MethodCall(className, methodName, namespace, parameter) { + this.className = className; + this.methodName = methodName; + this.namespace = namespace; + this.parameter = parameter; + } + MethodCall.prototype.getExpression = function () { + if (this.namespace) + return "".concat(this.namespace, ".").concat(this.className, ".").concat(this.methodName, "()"); + else + return "".concat(this.className, ".").concat(this.methodName, "()"); + }; + MethodCall.prototype.sameCall = function (classname, methodName, namespace) { + if (this.className === classname && this.methodName === methodName && this.namespace === namespace) + return true; + else + return false; + }; + return MethodCall; +}()); +exports.MethodCall = MethodCall; +var MethodParameter = /** @class */ (function () { + function MethodParameter(position, type) { + this.position = position; + this.type = type; + } + return MethodParameter; +}()); +exports.MethodParameter = MethodParameter; +var ParameterType; +(function (ParameterType) { + ParameterType[ParameterType["DR_NAME"] = 0] = "DR_NAME"; + ParameterType[ParameterType["IP_NAME"] = 1] = "IP_NAME"; +})(ParameterType || (exports.ParameterType = ParameterType = {})); +var InterfaceImplements = /** @class */ (function () { + function InterfaceImplements(name, namespace) { + this.name = name; + if (namespace) + this.namespace = namespace; + } + return InterfaceImplements; +}()); +exports.InterfaceImplements = InterfaceImplements; +var InterfaceMatcher = /** @class */ (function () { + function InterfaceMatcher() { + } + InterfaceMatcher.getMatchingTokens = function (checkFor, ctx) { + var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m; + var tokens = []; + var typeNameContexts = ctx.typeName(); + if (!typeNameContexts) + return tokens; + if (!checkFor.namespace && + typeNameContexts.length === 1 && + checkFor.name === ((_d = (_c = (_b = (_a = typeNameContexts[0]) === null || _a === void 0 ? void 0 : _a.id()) === null || _b === void 0 ? void 0 : _b.Identifier()) === null || _c === void 0 ? void 0 : _c.symbol) === null || _d === void 0 ? void 0 : _d.text)) { + tokens.push(typeNameContexts[0].id().Identifier().symbol); + } + else if (checkFor.namespace && + typeNameContexts.length === 2 && + checkFor.namespace === ((_h = (_g = (_f = (_e = typeNameContexts[0]) === null || _e === void 0 ? void 0 : _e.id()) === null || _f === void 0 ? void 0 : _f.Identifier()) === null || _g === void 0 ? void 0 : _g.symbol) === null || _h === void 0 ? void 0 : _h.text) && + checkFor.name === ((_m = (_l = (_k = (_j = typeNameContexts[1]) === null || _j === void 0 ? void 0 : _j.id()) === null || _k === void 0 ? void 0 : _k.Identifier()) === null || _l === void 0 ? void 0 : _l.symbol) === null || _m === void 0 ? void 0 : _m.text)) { + tokens.push(typeNameContexts[0].id().Identifier().symbol); + tokens.push(typeNameContexts[1].id().Identifier().symbol); + } + return tokens; + }; + return InterfaceMatcher; +}()); +exports.InterfaceMatcher = InterfaceMatcher; +var RangeTokenUpdate = /** @class */ (function () { + function RangeTokenUpdate(newText, startToken, endToken) { + this.newText = newText; + this.startToken = startToken; + this.endToken = endToken; + } + RangeTokenUpdate.prototype.applyUpdate = function (rewriter) { + rewriter.replace(this.startToken, this.endToken, this.newText); + }; + return RangeTokenUpdate; +}()); +exports.RangeTokenUpdate = RangeTokenUpdate; +var SingleTokenUpdate = /** @class */ (function () { + function SingleTokenUpdate(newText, token) { + this.newText = newText; + this.token = token; + } + SingleTokenUpdate.prototype.applyUpdate = function (rewriter) { + rewriter.replaceSingle(this.token, this.newText); + }; + return SingleTokenUpdate; +}()); +exports.SingleTokenUpdate = SingleTokenUpdate; +var MapUtil = /** @class */ (function () { + function MapUtil() { + } + MapUtil.addToValueList = function (map, key, value) { + if (!map.has(key)) + map.set(key, []); + map.get(key).push(value); + }; + return MapUtil; +}()); +exports.MapUtil = MapUtil; +var InsertAfterTokenUpdate = /** @class */ (function () { + function InsertAfterTokenUpdate(newText, token) { + this.newText = newText; + this.token = token; + } + InsertAfterTokenUpdate.prototype.applyUpdate = function (rewriter) { + rewriter.insertAfter(this.token, this.newText); + }; + return InsertAfterTokenUpdate; +}()); +exports.InsertAfterTokenUpdate = InsertAfterTokenUpdate; diff --git a/src/utils/lwcparser/htmlParser/HTMLParser.js b/src/utils/lwcparser/htmlParser/HTMLParser.js new file mode 100644 index 00000000..7aecea7d --- /dev/null +++ b/src/utils/lwcparser/htmlParser/HTMLParser.js @@ -0,0 +1,67 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.HTMLParser = void 0; +/* eslint-disable @typescript-eslint/explicit-member-accessibility */ +/* eslint-disable @typescript-eslint/restrict-template-expressions */ +/* eslint-disable @typescript-eslint/member-ordering */ +/* eslint-disable no-console */ +var fs = require("fs"); +var cheerio = require("cheerio"); +var DEFAULT_NAMESPACE = 'c'; +var TAG = 'tag'; +var HTMLParser = /** @class */ (function () { + // eslint-disable-next-line @typescript-eslint/explicit-member-accessibility + function HTMLParser(htmlFilePath) { + // Load the HTML file and initialize cheerio + var html = this.loadHTMLFromFile(htmlFilePath); + this.parser = cheerio.load(html); + } + // Method to load HTML from a file + HTMLParser.prototype.loadHTMLFromFile = function (filePath) { + try { + return fs.readFileSync(filePath, 'utf8'); + } + catch (error) { + console.error("Error reading file from disk: ".concat(error)); + throw error; + } + }; + // Method to replace custom tags + HTMLParser.prototype.replaceTags = function (namespaceTag) { + // Load the HTML into cheerio + var $ = this.parser; + // Find all tags that contain the substring "omnistudio" in their tag name + $('*').each(function (i, element) { + if (element.type === TAG && element.name && element.name.includes(namespaceTag + '-')) { + // Create a new tag with the same content and attributes as the old tag + var newTag = DEFAULT_NAMESPACE + element.name.substring(element.name.indexOf('-')); + var newElement_1 = $("<".concat(newTag, ">")).html($(element).html()); + // Copy all attributes from the old element to the new one + Object.keys(element.attribs).forEach(function (attr) { + newElement_1.attr(attr, $(element).attr(attr)); + }); + // Replace the old element with the new one + $(element).replaceWith(newElement_1); + } + }); + return $.html(); + }; + // Method to save modified HTML back to a file + HTMLParser.prototype.saveToFile = function (outputFilePath) { + try { + var modifiedHtml = this.parser.html(); + fs.writeFileSync(outputFilePath, modifiedHtml); + console.log("Modified HTML saved to ".concat(outputFilePath)); + } + catch (error) { + console.error("Error writing file to disk: ".concat(error)); + throw error; + } + }; + // Optional: Method to get the modified HTML as a string + HTMLParser.prototype.getModifiedHTML = function () { + return this.parser.html(); + }; + return HTMLParser; +}()); +exports.HTMLParser = HTMLParser; diff --git a/src/utils/lwcparser/jsParser/JavaScriptParser.js b/src/utils/lwcparser/jsParser/JavaScriptParser.js new file mode 100644 index 00000000..980d832e --- /dev/null +++ b/src/utils/lwcparser/jsParser/JavaScriptParser.js @@ -0,0 +1,55 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.JavaScriptParser = void 0; +/* eslint-disable @typescript-eslint/restrict-template-expressions */ +/* eslint-disable @typescript-eslint/no-unsafe-call */ +/* eslint-disable @typescript-eslint/no-unsafe-return */ +/* eslint-disable @typescript-eslint/no-unsafe-member-access */ +/* eslint-disable no-console */ +var fs = require("fs"); +var parser = require("@babel/parser"); +var traverse_1 = require("@babel/traverse"); +var generator_1 = require("@babel/generator"); +var t = require("@babel/types"); +var DEFAULT_NAMESPACE = 'c'; +var JavaScriptParser = /** @class */ (function () { + function JavaScriptParser() { + } + // Function to replace strings in import declarations and write back to file + JavaScriptParser.prototype.replaceImportSource = function (filePath, oldSource) { + // Read the JavaScript file + var code = fs.readFileSync(filePath, 'utf-8'); + // Parse the code into an AST (Abstract Syntax Tree) + var ast = parser.parse(code, { + sourceType: 'module', // Specify that we are parsing an ES module + plugins: ['decorators'], // Include any relevant plugins if necessary (e.g., 'jsx', 'flow', etc.) + }); + // Traverse the AST and modify import declarations + (0, traverse_1.default)(ast, { + ImportDeclaration: function (path) { + var importSource = path.node.source.value; + // Check if the import source contains the old substring + if (importSource.includes(oldSource + '/')) { + // Replace the old substring with the new substring + var updatedSource = importSource.replace(oldSource, DEFAULT_NAMESPACE); + // Update the AST with the new source + path.node.source = t.stringLiteral(updatedSource); + } + }, + }); + return (0, generator_1.default)(ast, {}, code).code; + }; + // Method to save modified HTML back to a file + JavaScriptParser.prototype.saveToFile = function (filePath, output) { + try { + fs.writeFileSync(filePath, output, 'utf-8'); + console.log("Replaced import 'oldSource' with 'c' in file: ".concat(filePath)); + } + catch (error) { + console.error("Error writing file to disk: ".concat(error)); + throw error; + } + }; + return JavaScriptParser; +}()); +exports.JavaScriptParser = JavaScriptParser; diff --git a/src/utils/lwcparser/xmlParser/XmlParser.js b/src/utils/lwcparser/xmlParser/XmlParser.js new file mode 100644 index 00000000..52b165d7 --- /dev/null +++ b/src/utils/lwcparser/xmlParser/XmlParser.js @@ -0,0 +1,57 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.XmlParser = void 0; +/* eslint-disable @typescript-eslint/no-unsafe-call */ +/* eslint-disable @typescript-eslint/member-ordering */ +/* eslint-disable @typescript-eslint/no-unsafe-member-access */ +/* eslint-disable @typescript-eslint/no-unsafe-assignment */ +/* eslint-disable @typescript-eslint/explicit-member-accessibility */ +var fs = require("fs"); +var xmldom_1 = require("@xmldom/xmldom"); +var XmlParser = /** @class */ (function () { + function XmlParser(filePath) { + this.filePath = filePath; + this.xmlDoc = null; + this.fileContent = fs.readFileSync(this.filePath, 'utf-8'); + this.parseXml(this.fileContent); + } + XmlParser.prototype.parseXml = function (fileContent) { + var parser = new xmldom_1.DOMParser(); + try { + this.xmlDoc = parser.parseFromString(fileContent, 'text/xml'); + } + catch (error) { + throw new Error('Error in xml parsing'); + } + }; + XmlParser.prototype.removeNode = function (tagName, index) { + var _a; + if (index === void 0) { index = 0; } + if (!this.xmlDoc) { + throw new Error('XML document has not been parsed.'); + } + var nodes = this.xmlDoc.getElementsByTagName(tagName); + if (nodes.length > index) { + var nodeToRemove = nodes[index]; + (_a = nodeToRemove.parentNode) === null || _a === void 0 ? void 0 : _a.removeChild(nodeToRemove); + var serializer = new xmldom_1.XMLSerializer(); + var xmlString = serializer.serializeToString(this.xmlDoc); + return xmlString; + // this.printResult(this.filePath, tagName, index); + } + }; + XmlParser.prototype.saveToFile = function (outputFilePath, xmlString) { + try { + fs.writeFileSync(outputFilePath, xmlString); + // eslint-disable-next-line no-console + console.log("Modified HTML saved to ".concat(outputFilePath)); + } + catch (error) { + // eslint-disable-next-line no-console, @typescript-eslint/restrict-template-expressions + console.error("Error writing file to disk: ".concat(error)); + throw error; + } + }; + return XmlParser; +}()); +exports.XmlParser = XmlParser; diff --git a/src/utils/lwcparser/xmlParser/XmlParser.ts b/src/utils/lwcparser/xmlParser/XmlParser.ts index eb0461b6..fd556553 100644 --- a/src/utils/lwcparser/xmlParser/XmlParser.ts +++ b/src/utils/lwcparser/xmlParser/XmlParser.ts @@ -4,7 +4,7 @@ /* eslint-disable @typescript-eslint/no-unsafe-assignment */ /* eslint-disable @typescript-eslint/explicit-member-accessibility */ import * as fs from 'fs'; -import { DOMParser, XMLSerializer } from 'xmldom'; +import { DOMParser, XMLSerializer } from '@xmldom/xmldom'; export class XmlParser { private xmlDoc: Document | null = null; diff --git a/src/utils/net/index.ts b/src/utils/net/index.ts index f8968000..22f7c69b 100644 --- a/src/utils/net/index.ts +++ b/src/utils/net/index.ts @@ -2,6 +2,7 @@ import { Connection } from '@salesforce/core'; import chunk from 'lodash.chunk'; import { UploadRecordResult } from '../../migration/interfaces'; +import { HttpRequest, HttpMethods } from 'jsforce'; class NetUtils { @@ -108,8 +109,9 @@ class NetUtils { const apiVersion = connection.getApiVersion(); const metadataApiUrl = `/services/data/v${apiVersion}/${url}`; - const request = { - method: method, + const httpMethod: HttpMethods = 'GET'; + const request: HttpRequest = { + method: httpMethod, url: metadataApiUrl, body: JSON.stringify(data) } @@ -132,4 +134,4 @@ interface TreeResult { results: UploadRecordResult[] } -export { NetUtils, RequestMethod, TreeResult } \ No newline at end of file +export { NetUtils, RequestMethod, TreeResult } diff --git a/src/utils/query/index.ts b/src/utils/query/index.ts index e769b9ff..8c94031b 100644 --- a/src/utils/query/index.ts +++ b/src/utils/query/index.ts @@ -44,14 +44,14 @@ export class QueryTools { const query = QueryTools.buildCustomObjectQuery(namespace, objectName, fields); // Execute the query - let results = await connection.query(query); + let results = await connection.query>(query); if (results && results.totalSize > 0) { allrecords = results.records; // Load more pages while (results.nextRecordsUrl) { - results = await connection.queryMore(results.nextRecordsUrl); + results = await connection.queryMore>(results.nextRecordsUrl); results.records.forEach((row) => { allrecords.push(row); }); @@ -73,14 +73,14 @@ export class QueryTools { const query = QueryTools.buildCustomObjectQuery(namespace, objectName, fields, filters); // Execute the query - let results = await connection.query(query); + let results = await connection.query>(query); if (results && results.totalSize > 0) { allrecords = results.records; // Load more pages while (results.nextRecordsUrl) { - results = await connection.queryMore(results.nextRecordsUrl); + results = await connection.queryMore>(results.nextRecordsUrl); results.records.forEach((row) => { allrecords.push(row); }); @@ -110,14 +110,14 @@ export class QueryTools { } // Execute the query - let results = await connection.query(query); + let results = await connection.query>(query); if (results && results.totalSize > 0) { allrecords = results.records; // Load more pages while (results.nextRecordsUrl) { - results = await connection.queryMore(results.nextRecordsUrl); + results = await connection.queryMore>(results.nextRecordsUrl); results.records.forEach((row) => { allrecords.push(row); }); @@ -154,7 +154,7 @@ export class QueryTools { } // Execute the query - let results = await connection.query(query); + let results = await connection.query>(query); let allrecords = []; if (results && results.totalSize > 0) { @@ -162,7 +162,7 @@ export class QueryTools { // Load more pages while (results.nextRecordsUrl) { - results = await connection.queryMore(results.nextRecordsUrl); + results = await connection.queryMore>(results.nextRecordsUrl); results.records.forEach((row) => { allrecords.push(row); }); @@ -191,14 +191,14 @@ export class QueryTools { } // Execute the query - let results = await connection.query(query); + let results = await connection.query>(query); if (results && results.totalSize > 0) { allrecords = results.records; // Load more pages while (results.nextRecordsUrl) { - results = await connection.queryMore(results.nextRecordsUrl); + results = await connection.queryMore>(results.nextRecordsUrl); results.records.forEach((row) => { allrecords.push(row); }); diff --git a/test/commands/omnistudio/migration/info.test.js b/test/commands/omnistudio/migration/info.test.js new file mode 100644 index 00000000..4b9780f6 --- /dev/null +++ b/test/commands/omnistudio/migration/info.test.js @@ -0,0 +1,27 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var test_1 = require("@salesforce/command/lib/test"); +var ts_types_1 = require("@salesforce/ts-types"); +describe('omnistudio:migration:info', function () { + test_1.test + .withOrg({ username: 'test@org.com' }, true) + .withConnectionRequest(function (request) { + var requestMap = (0, ts_types_1.ensureJsonMap)(request); + if (/Organization/.exec((0, ts_types_1.ensureString)(requestMap.url))) { + return Promise.resolve({ + records: [ + { + Name: 'Super Awesome Org', + TrialExpirationDate: '2018-03-20T23:24:11.000+0000', + }, + ], + }); + } + return Promise.resolve({ records: [] }); + }) + .stdout() + .command(['omnistudio:migration:info', '--targetusername', 'test@org.com', '--allversions']) + .it('runs omnistudio:migration:info --targetusername test@org.com --allversions', function (ctx) { + (0, test_1.expect)(ctx.stdout).to.contain('Hello world! This is org: Super Awesome Org'); + }); +}); diff --git a/test/utils/apex/executor/anonymousApexRunner.test.js b/test/utils/apex/executor/anonymousApexRunner.test.js new file mode 100644 index 00000000..6983891b --- /dev/null +++ b/test/utils/apex/executor/anonymousApexRunner.test.js @@ -0,0 +1,110 @@ +"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 = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype); + return g.next = verb(0), g["throw"] = verb(1), g["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 (g && (g = 0, op[0] && (_ = 0)), _) 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 }; + } +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var core_1 = require("@salesforce/core"); +var sinon = require("sinon"); +var test_1 = require("@salesforce/command/lib/test"); +var AnonymousApexRunner_1 = require("../../../../src/utils/apex/executor/AnonymousApexRunner"); +describe('AnonymusApexRunner', function () { + var org; + var sandboxStub; + beforeEach(function () { return __awaiter(void 0, void 0, void 0, function () { + var getConnectionStub; + return __generator(this, function (_a) { + sandboxStub = sinon.createSandbox(); + getConnectionStub = sandboxStub.stub().returns({ + tooling: { + executeAnonymous: function () { }, + }, + }); + sandboxStub.stub(core_1.Org.prototype, 'getConnection').callsFake(getConnectionStub); + org = new core_1.Org({}); + return [2 /*return*/]; + }); + }); }); + afterEach(function () { + sandboxStub.restore(); + }); + it('should run anonymous Apex correctly', function () { return __awaiter(void 0, void 0, void 0, function () { + var anonymousApex, expectedResponse, executeAnonymousResultStub, result; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + anonymousApex = "System.debug('Hello, World');"; + expectedResponse = { success: true }; + executeAnonymousResultStub = sandboxStub + .stub() + .returns(Promise.resolve({ success: true })); + sandboxStub.stub(core_1.Org.prototype.getConnection().tooling, 'executeAnonymous').callsFake(executeAnonymousResultStub); + return [4 /*yield*/, AnonymousApexRunner_1.AnonymousApexRunner.run(org, anonymousApex)]; + case 1: + result = _a.sent(); + (0, test_1.expect)(result).to.deep.equal(expectedResponse); + sinon.assert.calledOnce(executeAnonymousResultStub); + sinon.assert.calledWith(executeAnonymousResultStub, anonymousApex); + return [2 /*return*/]; + } + }); + }); }); + it('should handle executeAnonymous errors', function () { return __awaiter(void 0, void 0, void 0, function () { + var anonymousApex, executeAnonymousError, executeAnonymousResultStub, error_1; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + anonymousApex = "System.debug 'Hello, World');"; + executeAnonymousError = new Error('Error executing anonymous Apex'); + executeAnonymousResultStub = sandboxStub.stub().rejects(executeAnonymousError); + sandboxStub.stub(core_1.Org.prototype.getConnection().tooling, 'executeAnonymous').callsFake(executeAnonymousResultStub); + _a.label = 1; + case 1: + _a.trys.push([1, 3, , 4]); + return [4 /*yield*/, AnonymousApexRunner_1.AnonymousApexRunner.run(org, anonymousApex)]; + case 2: + _a.sent(); + throw new Error('Test should have thrown an error'); + case 3: + error_1 = _a.sent(); + (0, test_1.expect)(error_1).to.equal(executeAnonymousError); + sinon.assert.calledOnce(executeAnonymousResultStub); + sinon.assert.calledWith(executeAnonymousResultStub, anonymousApex); + return [3 /*break*/, 4]; + case 4: return [2 /*return*/]; + } + }); + }); }); +}); diff --git a/test/utils/apex/executor/anonymousApexRunner.test.ts b/test/utils/apex/executor/anonymousApexRunner.test.ts index 9b271184..533de236 100644 --- a/test/utils/apex/executor/anonymousApexRunner.test.ts +++ b/test/utils/apex/executor/anonymousApexRunner.test.ts @@ -2,7 +2,7 @@ import { Org } from '@salesforce/core'; import sinon = require('sinon'); import { expect } from '@salesforce/command/lib/test'; -import { Connection, ExecuteAnonymousResult } from 'jsforce'; +import { Connection } from 'jsforce'; import { AnonymousApexRunner } from '../../../../src/utils/apex/executor/AnonymousApexRunner'; describe('AnonymusApexRunner', () => { @@ -30,7 +30,7 @@ describe('AnonymusApexRunner', () => { const executeAnonymousResultStub = sandboxStub .stub() - .returns(Promise.resolve({ success: true } as unknown as ExecuteAnonymousResult)); + .returns(Promise.resolve({ success: true } as unknown as AnonymousApexRunner)); sandboxStub.stub(Org.prototype.getConnection().tooling, 'executeAnonymous').callsFake(executeAnonymousResultStub); const result = await AnonymousApexRunner.run(org, anonymousApex); diff --git a/test/utils/apex/parser/apexparser.test.js b/test/utils/apex/parser/apexparser.test.js new file mode 100644 index 00000000..66b43091 --- /dev/null +++ b/test/utils/apex/parser/apexparser.test.js @@ -0,0 +1,35 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var test_1 = require("@salesforce/command/lib/test"); +var apexparser_1 = require("../../../../src/utils/apex/parser/apexparser"); +describe('ApexASTParser', function () { + it('should parse the Apex file and collect interface implementations, method calls, and class names', function () { + var apexFileContent = "global with sharing class FormulaParserService implements vlocity_ins.VlocityOpenInterface2, Callable\n{\n\n global void justForTest(String kkdbk) {\n /* Specify Data Mapper extract or transform to call */\n String DRName = 'DataMapperNewName'; \n /* Populate the input JSON */ \n Map myTransformData = new Map{'MyKey'=>'MyValue'}; \n /* Call the Data Mapper */ \n vlocity_ins.DRProcessResult result1 = vlocity_ins.DRGlobal.process(myTransformData, 'DRName');\n }\n }"; + // const vlocityOpenInterface2 = 'vlocity_ins.VlocityOpenInterface2'; + var namespace = 'vlocity_ins'; + var interfaces = []; + var vlocityOpenInterface = new apexparser_1.InterfaceImplements('VlocityOpenInterface', namespace); + var vlocityOpenInterface2 = new apexparser_1.InterfaceImplements('VlocityOpenInterface2', namespace); + interfaces.push(vlocityOpenInterface, vlocityOpenInterface2, new apexparser_1.InterfaceImplements('Callable')); + var methodCalls = new Set(); + var drNameParameter = new apexparser_1.MethodParameter(2, apexparser_1.ParameterType.DR_NAME); + var ipNameParameter = new apexparser_1.MethodParameter(1, apexparser_1.ParameterType.IP_NAME); + methodCalls.add(new apexparser_1.MethodCall('DRGlobal', 'process', namespace, drNameParameter)); + methodCalls.add(new apexparser_1.MethodCall('DRGlobal', 'processObjectsJSON', namespace, drNameParameter)); + methodCalls.add(new apexparser_1.MethodCall('DRGlobal', 'processString', namespace, drNameParameter)); + methodCalls.add(new apexparser_1.MethodCall('DRGlobal', 'processFromApex', namespace, drNameParameter)); + methodCalls.add(new apexparser_1.MethodCall('IntegrationProcedureService', 'runIntegrationService', namespace, ipNameParameter)); + var apexParser = new apexparser_1.ApexASTParser(apexFileContent, interfaces, methodCalls, namespace); + apexParser.parse(); + var implementsInterface = apexParser.implementsInterfaces; + // const callsMethods = apexParser.getCallsMethods(); + // const className = apexParser.getClassName(); + // const pos = implementsInterface.get(vlocityOpenInterface2); + // Add your assertions here based on the expected results + // implementsInterface.get(interfaceName); + (0, test_1.expect)(implementsInterface.get(vlocityOpenInterface2)[0].charPositionInLine).to.be.equal(58); + (0, test_1.expect)(implementsInterface.get(vlocityOpenInterface2)[1].line).to.be.equal(1); + // expect(callsMethods).to.not.be.empty; + // expect(className).to.equal('YourClass'); + }); +}); diff --git a/test/utils/lwc/parser/htmlparser.test.js b/test/utils/lwc/parser/htmlparser.test.js new file mode 100644 index 00000000..d56ac3b0 --- /dev/null +++ b/test/utils/lwc/parser/htmlparser.test.js @@ -0,0 +1,14 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +/* eslint-disable @typescript-eslint/no-unsafe-call */ +// eslint-disable-next-line @typescript-eslint/no-unsafe-call +var test_1 = require("@salesforce/command/lib/test"); +var HTMLParser_1 = require("../../../../src/utils/lwcparser/htmlParser/HTMLParser"); +describe('HTMLParser test class', function () { + var mockFilePath = 'test/utils/lwc/parser/input/test.html'; + it('should read file content correctly', function () { + var htmlParser = new HTMLParser_1.HTMLParser(mockFilePath); + htmlParser.replaceTags('omnistudio'); + (0, test_1.expect)(htmlParser.getModifiedHTML()).contains('c-input'); + }); +}); diff --git a/test/utils/lwc/parser/javascriptparser.test.js b/test/utils/lwc/parser/javascriptparser.test.js new file mode 100644 index 00000000..32d1c419 --- /dev/null +++ b/test/utils/lwc/parser/javascriptparser.test.js @@ -0,0 +1,51 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +/* eslint-disable @typescript-eslint/no-unsafe-call */ +/* eslint-disable @typescript-eslint/no-unsafe-member-access */ +var fs = require("fs"); +var chai_1 = require("chai"); +var sinon = require("sinon"); +var JavaScriptParser_1 = require("../../../../src/utils/lwcparser/jsParser/JavaScriptParser"); // Adjust the path as necessary +var mockFilePath = 'test/utils/lwc/parser/input/test.js'; +describe('JavaScriptParser', function () { + var parser; + var readFileSyncStub; + var writeFileSyncStub; + var consoleLogStub; + beforeEach(function () { + parser = new JavaScriptParser_1.JavaScriptParser(); + // Stub fs methods + readFileSyncStub = sinon.stub(fs, 'readFileSync'); + writeFileSyncStub = sinon.stub(fs, 'writeFileSync'); + consoleLogStub = sinon.stub(console, 'log'); + }); + afterEach(function () { + // Restore the original methods after each test + sinon.restore(); + }); + it('should read the file content', function () { + var mockFileContent = "\n import something from 'oldSource/module';\n "; + // Mock file reading + readFileSyncStub.returns(mockFileContent); + parser.replaceImportSource(mockFilePath, 'oldSource'); + // Assert that readFileSync was called with correct arguments + (0, chai_1.expect)(readFileSyncStub.calledWith(mockFilePath, 'utf-8')).to.be.false; + }); + it('should replace import source correctly', function () { + var mockFileContent = "\n import something from 'oldSource/module';\n "; + // Mock file reading and writing + readFileSyncStub.returns(mockFileContent); + parser.replaceImportSource(mockFilePath, 'oldSource'); + // Assert that writeFileSync was called and content was modified + (0, chai_1.expect)(writeFileSyncStub.calledOnce).to.be.false; + }); + it('should log the correct replacement message', function () { + var mockFileContent = "\n import something from 'oldSource/module';\n "; + // Mock file reading + readFileSyncStub.returns(mockFileContent); + parser.replaceImportSource(mockFilePath, 'oldSource'); + parser.saveToFile(mockFilePath, parser.replaceImportSource(mockFilePath, 'oldSource')); + // Assert that console.log was called with the correct message + (0, chai_1.expect)(consoleLogStub.calledOnce).to.be.true; + }); +}); diff --git a/test/utils/lwc/parser/xmlparser.test.js b/test/utils/lwc/parser/xmlparser.test.js new file mode 100644 index 00000000..8daece68 --- /dev/null +++ b/test/utils/lwc/parser/xmlparser.test.js @@ -0,0 +1,21 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +/* eslint-disable @typescript-eslint/no-unsafe-call */ +var chai_1 = require("chai"); +var XmlParser_1 = require("../../../../src/utils/lwcparser/xmlParser/XmlParser"); +describe('XmlParser', function () { + var filePath = 'test/utils/lwc/parser/input/test.xml'; + var xmlParser; + beforeEach(function () { + xmlParser = new XmlParser_1.XmlParser(filePath); + }); + it('should parse XML string into a Document object', function () { + var serializedXml = xmlParser.removeNode('runtimeNamespace'); + (0, chai_1.expect)(serializedXml).contains(''); + }); + it('should remove the runtimeNamespace element correctly', function () { + var updatedXml = xmlParser.removeNode('runtimeNamespace'); + (0, chai_1.expect)(updatedXml).not.contains(''); + }); +});