Pop-up dictionary browser extension for language learning. Successor to Yomichan. (PERSONAL FORK)
at upstream/master 98 lines 3.3 kB view raw
1/* 2 * Copyright (C) 2023-2025 Yomitan Authors 3 * Copyright (C) 2020-2022 Yomichan Authors 4 * 5 * This program is free software: you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License as published by 7 * the Free Software Foundation, either version 3 of the License, or 8 * (at your option) any later version. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with this program. If not, see <https://www.gnu.org/licenses/>. 17 */ 18 19import Ajv from 'ajv'; 20import standaloneCode from 'ajv/dist/standalone/index.js'; 21import esbuild from 'esbuild'; 22import fs from 'fs'; 23import {createRequire} from 'module'; 24import path from 'path'; 25import {fileURLToPath} from 'url'; 26import {parseJson} from './json.js'; 27 28const require = createRequire(import.meta.url); 29 30const dirname = path.dirname(fileURLToPath(import.meta.url)); 31const extDir = path.join(dirname, '..', 'ext'); 32 33/** 34 * @param {string} out 35 */ 36async function copyWasm(out) { 37 // copy from node modules '@resvg/resvg-wasm/index_bg.wasm' to out 38 const resvgWasmPath = path.dirname(require.resolve('@resvg/resvg-wasm')); 39 const wasmPath = path.join(resvgWasmPath, 'index_bg.wasm'); 40 fs.copyFileSync(wasmPath, path.join(out, 'resvg.wasm')); 41} 42 43 44/** 45 * @param {string} scriptPath 46 */ 47async function buildLib(scriptPath) { 48 await esbuild.build({ 49 entryPoints: [scriptPath], 50 bundle: true, 51 minify: false, 52 sourcemap: true, 53 target: 'es2020', 54 format: 'esm', 55 outfile: path.join(extDir, 'lib', path.basename(scriptPath)), 56 external: ['fs'], 57 banner: { 58 js: '// @ts-nocheck', 59 }, 60 }); 61} 62 63/** 64 * Bundles libraries. 65 */ 66export async function buildLibs() { 67 const devLibPath = path.join(dirname, 'lib'); 68 const files = await fs.promises.readdir(devLibPath, { 69 withFileTypes: true, 70 }); 71 for (const f of files) { 72 if (f.isFile()) { 73 await buildLib(path.join(devLibPath, f.name)); 74 } 75 } 76 77 const schemaDir = path.join(extDir, 'data/schemas/'); 78 const schemaFileNames = fs.readdirSync(schemaDir); 79 const schemas = schemaFileNames.map((schemaFileName) => { 80 /** @type {import('ajv').AnySchema} */ 81 // eslint-disable-next-line sonarjs/prefer-immediate-return 82 const result = parseJson(fs.readFileSync(path.join(schemaDir, schemaFileName), {encoding: 'utf8'})); 83 return result; 84 }); 85 const ajv = new Ajv({ 86 schemas, 87 code: {source: true, esm: true}, 88 allowUnionTypes: true, 89 }); 90 const moduleCode = standaloneCode(ajv); 91 92 // https://github.com/ajv-validator/ajv/issues/2209 93 const patchedModuleCode = "// @ts-nocheck\nimport {ucs2length} from './ucs2length.js';" + moduleCode.replaceAll('require("ajv/dist/runtime/ucs2length").default', 'ucs2length'); 94 95 fs.writeFileSync(path.join(extDir, 'lib/validate-schemas.js'), patchedModuleCode); 96 97 await copyWasm(path.join(extDir, 'lib')); 98}