2021-03-30 11:50:45 +02:00
|
|
|
/**
|
|
|
|
|
* Copies all currently used libraries from node_modules into libs.
|
|
|
|
|
*
|
|
|
|
|
* We do this to be able to audit changes in the libraries and not rely on npm for checksums.
|
|
|
|
|
*/
|
2022-12-27 15:37:40 +01:00
|
|
|
import fs from "fs-extra"
|
2023-04-20 17:14:30 +02:00
|
|
|
import path, { dirname } from "node:path"
|
|
|
|
|
import { fileURLToPath } from "node:url"
|
2022-12-27 15:37:40 +01:00
|
|
|
import { rollup } from "rollup"
|
2023-04-24 09:42:07 +02:00
|
|
|
import { nodeResolve } from "@rollup/plugin-node-resolve"
|
|
|
|
|
import commonjs from "@rollup/plugin-commonjs"
|
2025-07-30 16:24:16 +02:00
|
|
|
import child_process from "node:child_process"
|
|
|
|
|
import { promisify } from "node:util"
|
2021-03-30 11:50:45 +02:00
|
|
|
|
|
|
|
|
const __dirname = dirname(fileURLToPath(import.meta.url))
|
|
|
|
|
|
2024-07-18 18:31:32 +02:00
|
|
|
export async function updateLibs() {
|
|
|
|
|
await copyToLibs(clientDependencies)
|
|
|
|
|
}
|
|
|
|
|
|
2025-01-02 18:47:57 +01:00
|
|
|
/**
|
2025-04-25 13:43:07 +02:00
|
|
|
* Should correspond to {@link import("./RollupConfig").dependencyMap}
|
|
|
|
|
*
|
2025-01-02 18:47:57 +01:00
|
|
|
* @typedef {"rollupWeb" | "rollupDesktop" | "copy"} BundlingStrategy
|
2025-07-30 16:24:16 +02:00
|
|
|
* @typedef {{src: string, target: string, bundling: BundlingStrategy, banner?: string, patch?: string}} DependencyDescription
|
2025-01-02 18:47:57 +01:00
|
|
|
* @type Array<DependencyDescription>
|
2025-04-25 13:43:07 +02:00
|
|
|
*
|
2021-11-29 17:58:08 +01:00
|
|
|
*/
|
2021-03-30 11:50:45 +02:00
|
|
|
const clientDependencies = [
|
2024-07-18 18:31:32 +02:00
|
|
|
// mithril is patched manually to remove some unused parts
|
|
|
|
|
// "../node_modules/mithril/mithril.js",
|
2025-01-02 18:47:57 +01:00
|
|
|
{ src: "../node_modules/mithril/stream/stream.js", target: "stream.js", bundling: "copy" },
|
2025-04-25 13:43:07 +02:00
|
|
|
// squire is patched manually to fix issues
|
2024-07-18 18:31:32 +02:00
|
|
|
// "../node_modules/squire-rte/dist/squire-raw.mjs",
|
2025-07-11 11:42:46 +02:00
|
|
|
{ src: "../node_modules/dompurify/dist/purify.es.mjs", target: "purify.js", bundling: "copy" },
|
2025-05-07 10:40:03 +02:00
|
|
|
{ src: "../node_modules/linkifyjs/dist/linkify.mjs", target: "linkify.js", bundling: "copy" },
|
|
|
|
|
{ src: "../node_modules/linkify-html/dist/linkify-html.mjs", target: "linkify-html.js", bundling: "copy" },
|
2025-01-02 18:47:57 +01:00
|
|
|
{ src: "../node_modules/luxon/build/es6/luxon.js", target: "luxon.js", bundling: "copy" },
|
2025-03-19 15:01:15 +01:00
|
|
|
{ src: "../node_modules/jsqr/dist/jsQR.js", target: "jsQR.js", bundling: "copy" },
|
2025-01-02 18:47:57 +01:00
|
|
|
{ src: "../node_modules/jszip/dist/jszip.js", target: "jszip.js", bundling: "rollupWeb" },
|
|
|
|
|
{ src: "../node_modules/cborg/cborg.js", target: "cborg.js", bundling: "rollupWeb" },
|
|
|
|
|
{ src: "../node_modules/qrcode-svg/lib/qrcode.js", target: "qrcode.js", bundling: "rollupWeb" },
|
|
|
|
|
{ src: "../node_modules/electron-updater/out/main.js", target: "electron-updater.mjs", bundling: "rollupDesktop" },
|
2025-04-25 13:43:07 +02:00
|
|
|
{ src: "../node_modules/@signalapp/sqlcipher/dist/index.mjs", target: "node-sqlcipher.mjs", bundling: "copy" },
|
2025-01-02 18:47:57 +01:00
|
|
|
{ src: "../node_modules/undici/index.js", target: "undici.mjs", bundling: "rollupDesktop" },
|
2025-07-30 16:24:16 +02:00
|
|
|
{ src: "../node_modules/@fingerprintjs/botd/dist/botd.esm.js", target: "botd.mjs", bundling: "rollupWeb", patch: "./libs/botd.patch" },
|
2021-03-30 11:50:45 +02:00
|
|
|
]
|
|
|
|
|
|
2025-06-16 17:16:40 +02:00
|
|
|
async function applyPatch() {
|
|
|
|
|
// rolldown gets confused when module.exports are used in an expression and wraps everything into a default export
|
|
|
|
|
// remove the problematic parts
|
|
|
|
|
console.log("applying a patch to undici")
|
|
|
|
|
const undiciPath = path.join(__dirname, "../node_modules/undici/index.js")
|
|
|
|
|
const contents = await fs.readFile(undiciPath, { encoding: "utf-8" })
|
|
|
|
|
const replaced = contents
|
|
|
|
|
.replace(
|
|
|
|
|
`const SqliteCacheStore = require('./lib/cache/sqlite-cache-store')
|
|
|
|
|
module.exports.cacheStores.SqliteCacheStore = SqliteCacheStore`,
|
|
|
|
|
"",
|
|
|
|
|
)
|
|
|
|
|
.replace(
|
|
|
|
|
`function install () {
|
|
|
|
|
globalThis.fetch = module.exports.fetch
|
|
|
|
|
globalThis.Headers = module.exports.Headers
|
|
|
|
|
globalThis.Response = module.exports.Response
|
|
|
|
|
globalThis.Request = module.exports.Request
|
|
|
|
|
globalThis.FormData = module.exports.FormData
|
|
|
|
|
globalThis.WebSocket = module.exports.WebSocket
|
|
|
|
|
globalThis.CloseEvent = module.exports.CloseEvent
|
|
|
|
|
globalThis.ErrorEvent = module.exports.ErrorEvent
|
|
|
|
|
globalThis.MessageEvent = module.exports.MessageEvent
|
|
|
|
|
globalThis.EventSource = module.exports.EventSource
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
module.exports.install = install`,
|
|
|
|
|
"",
|
|
|
|
|
)
|
|
|
|
|
await fs.writeFile(undiciPath, replaced, { encoding: "utf-8" })
|
|
|
|
|
}
|
|
|
|
|
|
2025-07-30 16:24:16 +02:00
|
|
|
/**
|
|
|
|
|
* applies a git patch file that was created as such:
|
|
|
|
|
* 1. get the unpatched version of whatever library you want to add / change
|
|
|
|
|
* 2. make a commit with the changes that you want to make
|
|
|
|
|
* 3. format the patch by running:
|
|
|
|
|
* git format-patch -k --stdout HEAD~1..HEAD > /.libs/changes.patch
|
|
|
|
|
* 4. revert the commit by running:
|
|
|
|
|
* git reset --hard HEAD~1
|
|
|
|
|
* 5. commit the generated ./libs.changes file
|
|
|
|
|
*/
|
|
|
|
|
async function applyGitPatch(patchFile) {
|
|
|
|
|
const exec = promisify(child_process.exec)
|
|
|
|
|
console.log("applying a patch to botd.js")
|
|
|
|
|
await exec(`git apply ${patchFile}`)
|
|
|
|
|
}
|
|
|
|
|
|
2025-01-02 18:47:57 +01:00
|
|
|
/**
|
|
|
|
|
* @param dependencies {Array<DependencyDescription>}>}
|
|
|
|
|
* @return {Promise<void>}
|
|
|
|
|
*/
|
|
|
|
|
async function copyToLibs(dependencies) {
|
2025-06-16 17:16:40 +02:00
|
|
|
await applyPatch()
|
|
|
|
|
|
2025-07-30 16:24:16 +02:00
|
|
|
for (let { bundling, src, target, banner, patch } of dependencies) {
|
2025-01-02 18:47:57 +01:00
|
|
|
switch (bundling) {
|
|
|
|
|
case "copy":
|
|
|
|
|
await fs.copy(path.join(__dirname, src), path.join(__dirname, "../libs/", target))
|
|
|
|
|
break
|
|
|
|
|
case "rollupWeb":
|
|
|
|
|
await rollWebDep(src, target, banner)
|
|
|
|
|
break
|
|
|
|
|
case "rollupDesktop":
|
|
|
|
|
await rollDesktopDep(src, target, banner)
|
|
|
|
|
break
|
|
|
|
|
default:
|
|
|
|
|
throw new Error(`Unknown bundling strategy: ${bundling}`)
|
2021-03-30 11:50:45 +02:00
|
|
|
}
|
2025-07-30 16:24:16 +02:00
|
|
|
|
|
|
|
|
if (patch != null) {
|
|
|
|
|
await applyGitPatch(patch)
|
|
|
|
|
}
|
2021-03-30 11:50:45 +02:00
|
|
|
}
|
2021-11-29 17:58:08 +01:00
|
|
|
}
|
|
|
|
|
|
2025-01-02 18:47:57 +01:00
|
|
|
/**
|
|
|
|
|
* Will bundle web app dependencies starting at {@param src} into a single file at {@param target}.
|
|
|
|
|
* @type RollupFn
|
|
|
|
|
*/
|
|
|
|
|
async function rollWebDep(src, target, banner) {
|
2025-07-30 16:24:16 +02:00
|
|
|
const bundle = await rollup({ input: path.join(__dirname, src), plugins: [nodeResolve()] })
|
2025-01-02 18:47:57 +01:00
|
|
|
await bundle.write({ file: path.join(__dirname, "../libs", target), banner })
|
2021-11-29 17:58:08 +01:00
|
|
|
}
|
2023-04-24 09:42:07 +02:00
|
|
|
|
|
|
|
|
/**
|
2025-01-02 18:47:57 +01:00
|
|
|
* @typedef {(src: string, target: string, banner: string | undefined) => Promise<void>} RollupFn
|
2023-04-24 09:42:07 +02:00
|
|
|
* rollup desktop dependencies with their dependencies into a single esm file
|
|
|
|
|
*
|
|
|
|
|
* specifically, electron-updater is importing some electron internals directly, so we made a comprehensive list of
|
|
|
|
|
* exclusions to not roll up.
|
2025-01-02 18:47:57 +01:00
|
|
|
*
|
|
|
|
|
* @type RollupFn
|
2023-04-24 09:42:07 +02:00
|
|
|
*/
|
2025-01-02 18:47:57 +01:00
|
|
|
async function rollDesktopDep(src, target, banner) {
|
2023-04-24 09:42:07 +02:00
|
|
|
const bundle = await rollup({
|
|
|
|
|
input: path.join(__dirname, src),
|
|
|
|
|
makeAbsoluteExternalsRelative: true,
|
|
|
|
|
external: [
|
|
|
|
|
// we handle .node imports ourselves
|
|
|
|
|
/\.node$/,
|
|
|
|
|
"assert",
|
|
|
|
|
"child_process",
|
|
|
|
|
"constants",
|
|
|
|
|
"crypto",
|
|
|
|
|
"electron",
|
|
|
|
|
"events",
|
|
|
|
|
"fs",
|
|
|
|
|
"http",
|
|
|
|
|
"https",
|
|
|
|
|
"os",
|
|
|
|
|
"path",
|
|
|
|
|
"stream",
|
|
|
|
|
"string_decoder",
|
|
|
|
|
"tty",
|
|
|
|
|
"url",
|
|
|
|
|
"util",
|
|
|
|
|
"zlib",
|
2025-06-16 17:16:40 +02:00
|
|
|
/.*sqlite-cache-store$/,
|
|
|
|
|
],
|
|
|
|
|
plugins: [
|
|
|
|
|
nodeResolve({ preferBuiltins: true }),
|
|
|
|
|
commonjs({
|
|
|
|
|
ignore: ["node:sqlite"],
|
|
|
|
|
}),
|
2023-04-24 09:42:07 +02:00
|
|
|
],
|
2025-01-02 18:47:57 +01:00
|
|
|
onwarn: (warning, defaultHandler) => {
|
|
|
|
|
if (warning.code === "CIRCULAR_DEPENDENCY") {
|
|
|
|
|
return // Ignore circular dependency warnings
|
|
|
|
|
}
|
|
|
|
|
defaultHandler(warning)
|
|
|
|
|
},
|
|
|
|
|
})
|
|
|
|
|
await bundle.write({
|
|
|
|
|
file: path.join(__dirname, "../libs", target),
|
|
|
|
|
format: "es",
|
|
|
|
|
// another ugly hack for better-sqlite
|
|
|
|
|
banner,
|
2023-04-24 09:42:07 +02:00
|
|
|
})
|
|
|
|
|
}
|