@webpro/next-translate-plugin
Version:
Tiny and powerful i18n plugin to translate your Next.js pages.
418 lines (417 loc) • 21 kB
JavaScript
;
var __assign = (this && this.__assign) || function () {
__assign = Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
if (ar || !(i in from)) {
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
ar[i] = from[i];
}
}
return to.concat(ar || Array.prototype.slice.call(from));
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.isInsideAppDir = exports.existLocalesFolderWithNamespaces = exports.existPages = exports.calculatePageDir = exports.removeCommentsFromCode = exports.interceptExport = exports.isNotExportModifier = exports.hasHOC = exports.isPageToIgnore = exports.hasStaticName = exports.getStaticName = exports.hasExportName = exports.getDefaultExport = exports.getNamedExport = exports.resolveIdentifier = exports.resolveParenthesis = exports.getImportedNames = exports.getSymbol = exports.parseCode = exports.parseFile = exports.getFilePkg = exports.getTsCompilerOptions = exports.addLoadLocalesFrom = exports.getDefaultAppJs = exports.defaultLoader = exports.clientLine = exports.INTERNAL_CONFIG_KEY = void 0;
var typescript_1 = __importDefault(require("typescript"));
var path_1 = __importDefault(require("path"));
var fs_1 = __importDefault(require("fs"));
var specFileOrFolderRgx = /(__mocks__|__tests__)|(\.(spec|test)\.(tsx|ts|js|jsx)$)/;
exports.INTERNAL_CONFIG_KEY = '__i18nConfig';
exports.clientLine = ['"use client"', "'use client'"];
exports.defaultLoader = '(l, n) => import(`@next-translate-root/locales/${l}/${n}`).then(m => m.default)';
function getDefaultAppJs(existLocalesFolder) {
return "\n import ".concat(exports.INTERNAL_CONFIG_KEY, " from '@next-translate-root/i18n'\n import appWithI18n from 'next-translate/appWithI18n'\n \n function MyApp({ Component, pageProps }) {\n return <Component {...pageProps} />\n }\n \n export default appWithI18n(MyApp, {\n ...").concat(exports.INTERNAL_CONFIG_KEY, ",\n skipInitialProps: true,\n isLoader: true,\n ").concat(addLoadLocalesFrom(existLocalesFolder), "\n })\n ");
}
exports.getDefaultAppJs = getDefaultAppJs;
function addLoadLocalesFrom(existLocalesFolder) {
var defaultFn = existLocalesFolder
? exports.defaultLoader
: "() => Promise.resolve({})";
return "loadLocaleFrom: ".concat(exports.INTERNAL_CONFIG_KEY, ".loadLocaleFrom || (").concat(defaultFn, "),");
}
exports.addLoadLocalesFrom = addLoadLocalesFrom;
function getTsCompilerOptions(basePath, cutDependencies) {
if (cutDependencies === void 0) { cutDependencies = false; }
var options;
var configPath = typescript_1.default.findConfigFile(basePath, typescript_1.default.sys.fileExists, 'tsconfig.json');
if (!configPath) {
options = { allowJs: true };
}
else {
var readConfigFileResult = typescript_1.default.readConfigFile(configPath, typescript_1.default.sys.readFile);
var jsonConfig = readConfigFileResult.config;
var convertResult = typescript_1.default.convertCompilerOptionsFromJson(jsonConfig.compilerOptions, basePath);
options = convertResult.options;
}
if (cutDependencies) {
options = __assign(__assign({}, options), { types: [], noResolve: true, noLib: true });
}
return options;
}
exports.getTsCompilerOptions = getTsCompilerOptions;
function getFilePkg(program, filename) {
var checker = program.getTypeChecker();
var sourceFile = program.getSourceFile(filename);
var printer = typescript_1.default.createPrinter({ newLine: typescript_1.default.NewLineKind.LineFeed });
var fileSymbol = checker.getSymbolAtLocation(sourceFile);
var filePkg;
function transform(transformer) {
var sourceFile = filePkg.sourceFile;
var transformationResult = typescript_1.default.transform(sourceFile, [
function (context) { return function (sourceFile) { return transformer(sourceFile, context); }; },
]);
filePkg.sourceFile = transformationResult.transformed[0];
filePkg.fileSymbol = checker.getSymbolAtLocation(filePkg.sourceFile);
}
function getCode() {
var sourceFile = filePkg.sourceFile;
return printer.printNode(typescript_1.default.EmitHint.Unspecified, sourceFile, sourceFile);
}
filePkg = { program: program, checker: checker, sourceFile: sourceFile, fileSymbol: fileSymbol, transform: transform, getCode: getCode };
return filePkg;
}
exports.getFilePkg = getFilePkg;
function parseFile(basePath, filename) {
var options = getTsCompilerOptions(basePath, true);
var program = typescript_1.default.createProgram([filename], options);
return getFilePkg(program, filename);
}
exports.parseFile = parseFile;
function parseCode(format, code) {
var options = getTsCompilerOptions('/', true);
var host = typescript_1.default.createCompilerHost(options);
var filename = "source.".concat(format);
host.getSourceFile = function (fileName) {
return typescript_1.default.createSourceFile(fileName, code, typescript_1.default.ScriptTarget.Latest);
};
var program = typescript_1.default.createProgram([filename], options, host);
return getFilePkg(program, filename);
}
exports.parseCode = parseCode;
function getSymbol(filePkg, node) {
if (node.symbol) {
return node.symbol;
}
var location = typescript_1.default.isVariableDeclaration(node) ? node.name : node;
return filePkg.checker.getSymbolAtLocation(location);
}
exports.getSymbol = getSymbol;
function getImportedNames(filePkg, moduleName) {
var importClause = filePkg.sourceFile.forEachChild(function (node) {
if (typescript_1.default.isImportDeclaration(node)) {
if (node.moduleSpecifier.getText().slice(1, -1) === moduleName) {
return node.importClause;
}
}
return undefined;
});
if (importClause) {
var exportedNamesToImported_1 = new Map();
if (importClause.name) {
exportedNamesToImported_1.set('default', importClause.name);
}
if (importClause.namedBindings) {
importClause.namedBindings.forEachChild(function (node) {
if (typescript_1.default.isImportSpecifier(node)) {
if (node.propertyName) {
exportedNamesToImported_1.set(node.propertyName.getText(), node.name);
}
else {
exportedNamesToImported_1.set(node.name.getText(), node.name);
}
}
});
}
return exportedNamesToImported_1;
}
return undefined;
}
exports.getImportedNames = getImportedNames;
function resolveParenthesis(filePkg, parenthesizedExpression) {
var content = parenthesizedExpression.expression;
if (typescript_1.default.isParenthesizedExpression(content)) {
return resolveParenthesis(filePkg, content);
}
else {
return content;
}
}
exports.resolveParenthesis = resolveParenthesis;
function resolveIdentifier(filePkg, identifier) {
var identifierSymbol = getSymbol(filePkg, identifier);
if (identifierSymbol && Array.isArray(identifierSymbol.declarations)) {
var identifierDeclaration = identifierSymbol.declarations[0];
if (typescript_1.default.isVariableDeclaration(identifierDeclaration)) {
var initializer = identifierDeclaration.initializer;
if (initializer && typescript_1.default.isParenthesizedExpression(initializer)) {
initializer = resolveParenthesis(filePkg, initializer);
}
if (initializer && typescript_1.default.isIdentifier(initializer)) {
return resolveIdentifier(filePkg, initializer);
}
}
return identifierDeclaration;
}
return identifier;
}
exports.resolveIdentifier = resolveIdentifier;
function getNamedExport(filePkg, name, resolveExport) {
if (resolveExport === void 0) { resolveExport = true; }
var checker = filePkg.checker, fileSymbol = filePkg.fileSymbol;
var exportContent;
if (fileSymbol) {
var exportSymbol = checker.tryGetMemberInModuleExports(name, fileSymbol);
if (exportSymbol && Array.isArray(exportSymbol.declarations)) {
var exportDeclaration = exportSymbol.declarations[0];
if (resolveExport && typescript_1.default.isExportAssignment(exportDeclaration)) {
exportContent = exportDeclaration.expression;
if (typescript_1.default.isParenthesizedExpression(exportContent)) {
exportContent = resolveParenthesis(filePkg, exportContent);
}
if (typescript_1.default.isIdentifier(exportContent)) {
exportContent = resolveIdentifier(filePkg, exportContent);
}
}
else {
exportContent = exportDeclaration;
}
}
}
return exportContent;
}
exports.getNamedExport = getNamedExport;
function getDefaultExport(filePkg, resolveExport) {
if (resolveExport === void 0) { resolveExport = true; }
return getNamedExport(filePkg, 'default', resolveExport);
}
exports.getDefaultExport = getDefaultExport;
function hasExportName(filePkg, name) {
return Boolean(getNamedExport(filePkg, name, false));
}
exports.hasExportName = hasExportName;
function getStaticName(filePkg, target, name) {
var symbol = getSymbol(filePkg, target);
if (symbol) {
return filePkg.checker.tryGetMemberInModuleExports(name, symbol);
}
return undefined;
}
exports.getStaticName = getStaticName;
function hasStaticName(filePkg, target, name) {
return Boolean(getStaticName(filePkg, target, name));
}
exports.hasStaticName = hasStaticName;
function isPageToIgnore(pageFilePath) {
var fileName = pageFilePath.substring(pageFilePath.lastIndexOf('/') + 1);
return (pageFilePath.startsWith('/api/') ||
pageFilePath.startsWith('/_document.') ||
pageFilePath.startsWith('/middleware.') ||
fileName.startsWith('_middleware.') ||
specFileOrFolderRgx.test(pageFilePath));
}
exports.isPageToIgnore = isPageToIgnore;
function hasHOC(filePkg) {
var defaultExport = getDefaultExport(filePkg);
if (!defaultExport ||
hasExportName(filePkg, 'getStaticProps') ||
hasExportName(filePkg, 'getServerSideProps') ||
hasExportName(filePkg, 'getStaticPaths')) {
return false;
}
if (typescript_1.default.isVariableDeclaration(defaultExport) && defaultExport.initializer) {
defaultExport = defaultExport.initializer;
if (typescript_1.default.isParenthesizedExpression(defaultExport)) {
defaultExport = resolveParenthesis(filePkg, defaultExport);
}
if (typescript_1.default.isIdentifier(defaultExport)) {
defaultExport = resolveIdentifier(filePkg, defaultExport);
}
if (!typescript_1.default.isCallExpression(defaultExport)) {
return false;
}
}
if (typescript_1.default.isFunctionDeclaration(defaultExport) ||
typescript_1.default.isClassDeclaration(defaultExport)) {
return false;
}
var importedNames = getImportedNames(filePkg, 'next-translate/withTranslation');
var withTranslationId = importedNames === null || importedNames === void 0 ? void 0 : importedNames.get('default');
function isCallExpressionWithHOC(callExpression) {
var _a;
var callable = callExpression.expression;
var expressionsToVisit = __spreadArray([callable], callExpression.arguments, true);
for (var _i = 0, expressionsToVisit_1 = expressionsToVisit; _i < expressionsToVisit_1.length; _i++) {
var expression = expressionsToVisit_1[_i];
if (typescript_1.default.isCallExpression(expression)) {
return isCallExpressionWithHOC(expression);
}
if (typescript_1.default.isIdentifier(expression)) {
var resolved = resolveIdentifier(filePkg, expression);
if (typescript_1.default.isVariableDeclaration(resolved)) {
var initializer = resolved.initializer;
if (initializer && typescript_1.default.isParenthesizedExpression(initializer)) {
initializer = resolveParenthesis(filePkg, initializer);
}
if (initializer && typescript_1.default.isCallExpression(initializer)) {
return isCallExpressionWithHOC(initializer);
}
}
if (typescript_1.default.isImportClause(resolved)) {
if (((_a = resolved.name) === null || _a === void 0 ? void 0 : _a.getText()) !== (withTranslationId === null || withTranslationId === void 0 ? void 0 : withTranslationId.getText())) {
return true;
}
}
}
}
return false;
}
if (typescript_1.default.isCallExpression(defaultExport)) {
if (withTranslationId) {
return isCallExpressionWithHOC(defaultExport);
}
else {
return true;
}
}
return false;
}
exports.hasHOC = hasHOC;
function isNotExportModifier(modifier) {
var exportModifiers = [
typescript_1.default.SyntaxKind.DefaultKeyword,
typescript_1.default.SyntaxKind.ExportKeyword,
];
return !exportModifiers.includes(modifier.kind);
}
exports.isNotExportModifier = isNotExportModifier;
function interceptExport(filePkg, exportName, defaultLocalName) {
var exportContent = getNamedExport(filePkg, exportName, false);
var finalLocalName = '';
var extraImport;
if (!exportContent)
return finalLocalName;
filePkg.transform(function (sourceFile, context) {
function visitor(node) {
var _a, _b, _c, _d, _e, _f, _g;
if (typescript_1.default.isClassDeclaration(node) && node === exportContent) {
if (node.name)
finalLocalName = node.name.getText();
return typescript_1.default.factory.updateClassDeclaration(node, node.decorators, (_a = node.modifiers) === null || _a === void 0 ? void 0 : _a.filter(isNotExportModifier), (_b = node.name) !== null && _b !== void 0 ? _b : typescript_1.default.factory.createIdentifier(defaultLocalName), node.typeParameters, node.heritageClauses, node.members);
}
if (typescript_1.default.isFunctionDeclaration(node) && node === exportContent) {
if (node.name)
finalLocalName = node.name.getText();
return typescript_1.default.factory.updateFunctionDeclaration(node, node.decorators, (_c = node.modifiers) === null || _c === void 0 ? void 0 : _c.filter(isNotExportModifier), node.asteriskToken, (_d = node.name) !== null && _d !== void 0 ? _d : typescript_1.default.factory.createIdentifier(defaultLocalName), node.typeParameters, node.parameters, node.type, node.body);
}
if (typescript_1.default.isVariableStatement(node) &&
typescript_1.default.isVariableDeclaration(exportContent) &&
node.declarationList.declarations.includes(exportContent)) {
finalLocalName = exportContent.name.getText();
return typescript_1.default.factory.updateVariableStatement(node, (_e = node.modifiers) === null || _e === void 0 ? void 0 : _e.filter(isNotExportModifier), node.declarationList);
}
if (typescript_1.default.isExportDeclaration(node) &&
typescript_1.default.isExportSpecifier(exportContent) &&
node.exportClause &&
typescript_1.default.isNamedExports(node.exportClause)) {
var filteredSpecifiers = node.exportClause.elements.filter(function (specifier) { return specifier !== exportContent; });
if (node.moduleSpecifier) {
finalLocalName = defaultLocalName;
extraImport = typescript_1.default.factory.createImportDeclaration(undefined, undefined, typescript_1.default.factory.createImportClause(node.isTypeOnly, undefined, typescript_1.default.factory.createNamedImports([
typescript_1.default.factory.createImportSpecifier(exportContent.isTypeOnly, (_f = exportContent.propertyName) !== null && _f !== void 0 ? _f : exportContent.name, typescript_1.default.factory.createIdentifier(defaultLocalName)),
])), node.moduleSpecifier);
}
else {
var localId = (_g = exportContent.propertyName) !== null && _g !== void 0 ? _g : exportContent.name;
finalLocalName = localId.getText();
}
return typescript_1.default.factory.updateExportDeclaration(node, node.decorators, node.modifiers, node.isTypeOnly, typescript_1.default.factory.updateNamedExports(node.exportClause, filteredSpecifiers), node.moduleSpecifier, node.assertClause);
}
if (typescript_1.default.isExportAssignment(node) && node === exportContent) {
finalLocalName = defaultLocalName;
return typescript_1.default.factory.createVariableStatement(undefined, typescript_1.default.factory.createVariableDeclarationList([
typescript_1.default.factory.createVariableDeclaration(defaultLocalName, undefined, undefined, node.expression),
], typescript_1.default.NodeFlags.Const));
}
return typescript_1.default.visitEachChild(node, visitor, context);
}
return typescript_1.default.visitNode(sourceFile, visitor);
});
if (extraImport) {
filePkg.transform(function (sourceFile) {
return typescript_1.default.factory.updateSourceFile(sourceFile, __spreadArray([
extraImport
], sourceFile.statements, true));
});
}
return finalLocalName;
}
exports.interceptExport = interceptExport;
function removeCommentsFromCode(code) {
return code.replace(/\/\*[\s\S]*?\*\/|([^\\:]|^)\/\/.*$/gm, '');
}
exports.removeCommentsFromCode = removeCommentsFromCode;
function calculatePageDir(name, pagesInDir, dir) {
if (pagesInDir)
return pagesInDir.replace(new RegExp('(app|pages)$'), name);
var dirs = [
name,
"src/".concat(name),
"app/".concat(name),
"integrations/".concat(name),
];
for (var _i = 0, dirs_1 = dirs; _i < dirs_1.length; _i++) {
var possiblePageDir = dirs_1[_i];
if (fs_1.default.existsSync(path_1.default.join(dir, possiblePageDir))) {
return path_1.default.join(possiblePageDir);
}
}
return name;
}
exports.calculatePageDir = calculatePageDir;
function existPages(dir, pages) {
return pages && fs_1.default.existsSync(path_1.default.join(dir, pages));
}
exports.existPages = existPages;
function existLocalesFolderWithNamespaces(dir) {
var existLocalesFolder = fs_1.default.existsSync(path_1.default.join(dir, 'locales'));
if (!existLocalesFolder)
return false;
var langFolder = fs_1.default.readdirSync(path_1.default.join(dir, 'locales')).find(function (file) {
var currentLangFolder = path_1.default.join(dir, 'locales', file);
return (fs_1.default.existsSync(currentLangFolder) &&
fs_1.default.lstatSync(currentLangFolder).isDirectory());
});
if (!langFolder)
return false;
var existNamespaceFile = fs_1.default
.readdirSync(path_1.default.join(dir, 'locales', langFolder))
.some(function (file) {
var namespaceFile = path_1.default.join(dir, 'locales', langFolder, file);
return (fs_1.default.existsSync(namespaceFile) &&
!fs_1.default.lstatSync(namespaceFile).isDirectory());
});
return existNamespaceFile;
}
exports.existLocalesFolderWithNamespaces = existLocalesFolderWithNamespaces;
function isInsideAppDir(path, appFolder, pagesFolder) {
var appIndex = path.indexOf(appFolder);
var pagesIndex = path.indexOf(pagesFolder);
if (appIndex === -1)
return false;
if (appIndex > -1 && pagesIndex === -1)
return true;
return appIndex < pagesIndex;
}
exports.isInsideAppDir = isInsideAppDir;