@salesforce/core
Version:
Core libraries to interact with SFDX projects, orgs, and APIs.
89 lines • 4.71 kB
JavaScript
/*
* Copyright (c) 2023, salesforce.com, inc.
* All rights reserved.
* Licensed under the BSD 3-Clause license.
* For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause
*/
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.messageTransformer = void 0;
// eslint-disable-next-line import/no-extraneous-dependencies
const typescript_1 = __importDefault(require("typescript"));
const messages_1 = require("./messages");
/**
*
* @experimental
* transforms `messages` references from dynamic run-time to static compile-time values
*/
const messageTransformer = () => {
messages_1.Messages.importMessagesDirectory(process.cwd());
const transformerFactory = (context) => (sourceFile) => {
if (
// if there are no messages, no transformation is needed
!sourceFile.statements.some((i) => typescript_1.default.isImportDeclaration(i) && i.importClause?.getText().includes('Messages')) ||
// don't transform the transformer itself
sourceFile.fileName.includes('messageTransformer.ts')) {
return sourceFile;
}
const visitor = (node) => {
if (typescript_1.default.isExpressionStatement(node) && node.getText().includes('importMessagesDirectory')) {
// importMessagesDirectory now happens at compile, not in runtime
// returning undefined removes the node
return typescript_1.default.factory.createEmptyStatement();
}
if (
// transform a runtime load call into hardcoded messages values
// const foo = Messages.load|loadMessages('pluginName', 'messagesFile' ...) =>
// const foo = new Messages('pluginName', 'messagesFile', new Map([['key', 'value']]))
typescript_1.default.isCallExpression(node) &&
typescript_1.default.isPropertyAccessExpression(node.expression) &&
node.expression.expression.getText() === 'Messages' &&
node.expression.name.getText().includes('load')) {
// we always want the first two arguments, which are the plugin name and the messages file name
const arrayMembers = node.arguments.slice(0, 2);
const arrayMembersText = arrayMembers.map(getTextWithoutQuotes);
// Messages doesn't care whether you call messages.load or loadMessages, it loads the whole file
const messagesInstance = messages_1.Messages.loadMessages(arrayMembersText[0], arrayMembersText[1]);
return context.factory.createNewExpression(node.expression.expression, undefined, [
arrayMembers[0],
arrayMembers[1],
context.factory.createNewExpression(context.factory.createIdentifier('Map'), undefined, [
messageMapToHardcodedMap(messagesInstance.messages),
]),
]);
}
// it might be a node that contains one of the things we're interested in, so keep digging
return typescript_1.default.visitEachChild(node, visitor, context);
};
return typescript_1.default.visitNode(sourceFile, visitor, typescript_1.default.isSourceFile);
};
return transformerFactory;
};
exports.messageTransformer = messageTransformer;
exports.default = exports.messageTransformer;
const getTextWithoutQuotes = (node) => node.getText().replace(/'/g, '');
/** turn a loaded message map into */
const messageMapToHardcodedMap = (messages) => typescript_1.default.factory.createArrayLiteralExpression(Array.from(messages).map(([key, value]) => {
// case 1: string
if (typeof value === 'string') {
return typescript_1.default.factory.createArrayLiteralExpression([
typescript_1.default.factory.createStringLiteral(key),
typescript_1.default.factory.createStringLiteral(value),
]);
}
else if (Array.isArray(value)) {
// case 2: string[]
return typescript_1.default.factory.createArrayLiteralExpression([
typescript_1.default.factory.createStringLiteral(key),
typescript_1.default.factory.createArrayLiteralExpression(value.map((v) => typescript_1.default.factory.createStringLiteral(v))),
]);
}
else {
// turn the object into a map and recurse!
return messageMapToHardcodedMap(new Map(Object.entries(value)));
}
}));
//# sourceMappingURL=messageTransformer.js.map
;