vite-plugin-i18n-validator
Version:
A Vite plugin validates Json files with internationalization support in worker thread.
253 lines (249 loc) • 9.44 kB
JavaScript
;
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
// If the importer is in node compatibility mode or this is not an ESM
// file that has been converted to a CommonJS file using a Babel-
// compatible transform (i.e. "__esModule" has not been set), then set
// "default" to the CommonJS "module.exports" for node compatibility.
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
mod
));
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
// src/index.ts
var src_exports = {};
__export(src_exports, {
default: () => Plugin
});
module.exports = __toCommonJS(src_exports);
// node_modules/.pnpm/tsup@8.0.2_typescript@5.3.3/node_modules/tsup/assets/cjs_shims.js
var getImportMetaUrl = () => typeof document === "undefined" ? new URL("file:" + __filename).href : document.currentScript && document.currentScript.src || new URL("main.js", document.baseURI).href;
var importMetaUrl = /* @__PURE__ */ getImportMetaUrl();
// src/index.ts
var import_vite = require("vite");
var import_node_fs = __toESM(require("fs"), 1);
var import_picocolors = __toESM(require("picocolors"), 1);
var import_worker_threads = require("worker_threads");
var import_node_path = __toESM(require("path"), 1);
var import_node_url = require("url");
async function Plugin(options) {
let checkedFiles = [];
let worker = null;
let textlintWorker = null;
let logger = null;
const finalOptions = Array.isArray(options) ? options : [options];
const traverse = (json, parentKey) => {
const keys = Object.keys(json);
const arr = [];
for (let i = 0; i < keys.length; i++) {
const key = keys[i];
const value = json[key];
if (typeof value === "object") {
if (parentKey) {
arr.push(...traverse(value, `${parentKey}.${key}`));
} else {
arr.push(...traverse(value, key));
}
} else {
if (parentKey) {
arr.push(`${parentKey}.${key}`);
} else {
arr.push(`${key}`);
}
}
}
return arr;
};
for (let i = 0; i < finalOptions.length; i++) {
const finalOption = finalOptions[i];
finalOption.enabledBuild = finalOption.enabledBuild || false;
finalOption.filter = (0, import_vite.createFilter)(finalOption.include, finalOption.exclude);
if (!finalOption.baseLocaleFilePath) {
throw new Error("baseLocaleFilePath is required.");
}
try {
const fileText = import_node_fs.default.readFileSync(finalOption.baseLocaleFilePath, "utf-8");
const json = JSON.parse(fileText);
finalOption.cachedBaseFile = traverse(json, "");
} catch (error) {
console.log("error :>> ", error);
throw new Error("baseLocaleFilePath is invalid.");
}
}
return {
name: "vite-plugin-i18n-validator",
enforce: "pre",
configResolved(config) {
for (let i = 0; i < finalOptions.length; i++) {
const finalOption = finalOptions[i];
finalOption.baseLocaleFilePath = import_node_path.default.isAbsolute(
finalOption.baseLocaleFilePath
) ? finalOption.baseLocaleFilePath : import_node_path.default.resolve(config.root, finalOption.baseLocaleFilePath);
}
const __filename2 = (0, import_node_url.fileURLToPath)(importMetaUrl);
const __dirname = import_node_path.default.dirname(__filename2);
logger = config.logger;
worker = new import_worker_threads.Worker(`${import_node_path.default.resolve(__dirname, "worker.js")}`);
worker.on("message", ({ errors, file }) => {
if (errors.length > 0) {
const relativePath = import_node_path.default.relative(config.root, file);
for (let i = 0; i < errors.length; i++) {
logger?.info(`${import_picocolors.default.yellow(`${relativePath}`)}: ${errors[i]}`, {
timestamp: true
});
}
}
});
for (let i = 0; i < finalOptions.length; i++) {
const finalOption = finalOptions[i];
if (finalOption.textlint) {
const textlintConfigFilepath = import_node_path.default.resolve(
config.root,
".textlintrc"
);
const baseConfigFilePath = import_node_path.default.resolve(
__dirname,
".base_textlintrc"
);
const nodeModulesDir = import_node_path.default.resolve(config.root, "node_modules");
if (finalOption.textlint === true) {
finalOption.textlintOption = {
baseConfigFilePath,
createLinterOptions: {},
loadTextlintrcOptions: {
configFilePath: textlintConfigFilepath,
node_modulesDir: nodeModulesDir
}
};
} else if (!finalOption.textlint.loadTextlintrcOptions.configFilePath) {
finalOption.textlint.loadTextlintrcOptions.configFilePath = textlintConfigFilepath;
finalOption.textlint.loadTextlintrcOptions.node_modulesDir = nodeModulesDir;
finalOption.textlint.baseConfigFilePath = baseConfigFilePath;
finalOption.textlintOption = {
...finalOption.textlint
};
}
}
textlintWorker = new import_worker_threads.Worker(
`${import_node_path.default.resolve(__dirname, "textlintWorker.js")}`
);
textlintWorker.on("message", (msg) => {
if (msg.results.length === 0) {
return;
}
for (let i2 = 0; i2 < msg.results.length; i2++) {
const result = msg.results[i2];
if (result.messages.length === 0) {
continue;
}
const relativePath = import_node_path.default.relative(config.root, result.filePath);
for (let j = 0; j < result.messages.length; j++) {
const message = result.messages[j];
logger?.info(
`${import_picocolors.default.yellow(`${relativePath}`)}:${message.loc.start.line}:${message.loc.start.column}: ${message.message}`,
{ timestamp: true }
);
}
}
});
return;
}
},
async handleHotUpdate(context) {
let json = null;
for (let i = 0; i < finalOptions.length; i++) {
const finalOption = finalOptions[i];
if (!finalOption.cachedBaseFile) {
return;
}
if (!finalOption.filter(context.file) && context.file !== finalOption.baseLocaleFilePath) {
continue;
}
if (!json) {
const text = await context.read();
json = JSON.parse(text);
}
if (context.file === finalOption.baseLocaleFilePath) {
finalOption.cachedBaseFile = traverse(json);
}
try {
worker?.postMessage({
json,
cachedBaseFile: finalOption.cachedBaseFile,
prohibitedValues: finalOption.prohibitedValues,
prohibitedKey: finalOption.prohibitedKeys,
file: context.file,
ignoreKeys: finalOption.ignoreKeys
});
if (!finalOption.textlint) {
return;
}
textlintWorker?.postMessage({
textlintOption: finalOption.textlintOption,
file: context.file
});
} catch (error) {
console.log("error :>> ", error);
}
}
},
buildStart() {
checkedFiles = [];
},
buildEnd() {
worker?.terminate();
textlintWorker?.terminate();
},
transform(_code, id) {
if (checkedFiles.includes(id)) {
return;
}
checkedFiles.push(id);
for (let i = 0; i < finalOptions.length; i++) {
const finalOption = finalOptions[i];
if (finalOption.enabledBuild === false) {
continue;
}
if (!finalOption.cachedBaseFile) {
continue;
}
if (!finalOption.filter(id)) {
continue;
}
const json = JSON.parse(_code);
worker?.postMessage({
json,
cachedBaseFile: finalOption.cachedBaseFile,
prohibitedValues: finalOption.prohibitedValues,
prohibitedKey: finalOption.prohibitedKeys,
file: id,
ignoreKeys: finalOption.ignoreKeys
});
if (!finalOption.textlint) {
return;
}
textlintWorker?.postMessage({
textlintOption: finalOption.textlintOption,
file: id
});
}
checkedFiles.push(id);
}
};
}