mirror of
https://github.com/penpot/penpot.git
synced 2025-03-26 06:31:26 -05:00
Merge pull request #4216 from penpot/niwinz-staging-gulp-replace
🎉 Replace gulp with node scripts
This commit is contained in:
commit
f8bd0ba28a
13 changed files with 895 additions and 97 deletions
|
@ -1,7 +1,7 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
export PATH=/usr/lib/jvm/openjdk/bin:/usr/local/nodejs/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin
|
||||
export JAVA_OPTS="-Xmx900m -Xms50m"
|
||||
export JAVA_OPTS="-Xmx1000m -Xms50m"
|
||||
|
||||
alias l='ls --color -GFlh'
|
||||
alias rm='rm -r'
|
||||
|
|
|
@ -19,12 +19,12 @@ popd
|
|||
|
||||
tmux -2 new-session -d -s penpot
|
||||
|
||||
tmux rename-window -t penpot:0 'gulp'
|
||||
tmux rename-window -t penpot:0 'frontend watch'
|
||||
tmux select-window -t penpot:0
|
||||
tmux send-keys -t penpot 'cd penpot/frontend' enter C-l
|
||||
tmux send-keys -t penpot 'npx gulp watch' enter
|
||||
tmux send-keys -t penpot 'yarn run watch' enter
|
||||
|
||||
tmux new-window -t penpot:1 -n 'shadow watch'
|
||||
tmux new-window -t penpot:1 -n 'frontend shadow'
|
||||
tmux select-window -t penpot:1
|
||||
tmux send-keys -t penpot 'cd penpot/frontend' enter C-l
|
||||
tmux send-keys -t penpot 'clojure -M:dev:shadow-cljs watch main' enter
|
||||
|
|
|
@ -19,21 +19,17 @@
|
|||
"scripts": {
|
||||
"fmt:clj:check": "cljfmt check --parallel=false src/ test/",
|
||||
"fmt:clj": "cljfmt fix --parallel=true src/ test/",
|
||||
"test:compile": "clojure -M:dev:shadow-cljs compile test --config-merge '{:autorun false}'",
|
||||
"lint:scss": "yarn run prettier -c resources/styles -c src/**/*.scss",
|
||||
"lint:scss:fix": "yarn run prettier -c resources/styles -c src/**/*.scss -w",
|
||||
"lint:clj": "clj-kondo --parallel --lint src/",
|
||||
"test:compile": "clojure -M:dev:shadow-cljs compile test --config-merge '{:autorun false}'",
|
||||
"test:run": "node target/tests.cjs",
|
||||
"test:watch": "clojure -M:dev:shadow-cljs watch test",
|
||||
"test": "yarn run test:compile && yarn run test:run",
|
||||
"gulp:watch": "gulp watch",
|
||||
"watch": "shadow-cljs watch main",
|
||||
"validate-translations": "node ./scripts/validate-translations.js",
|
||||
"find-unused-translations": "node ./scripts/find-unused-translations.js",
|
||||
"build:clean": "gulp clean:output && gulp clean:dist",
|
||||
"build:styles": "gulp build:styles",
|
||||
"build:assets": "gulp build:assets",
|
||||
"build:copy": "gulp build:copy",
|
||||
"translations:validate": "node ./scripts/validate-translations.js",
|
||||
"translations:find-unused": "node ./scripts/find-unused-translations.js",
|
||||
"compile": "node ./scripts/compile.js",
|
||||
"watch": "node ./scripts/watch.js",
|
||||
"storybook:compile": "gulp template:storybook && clojure -M:dev:shadow-cljs compile storybook",
|
||||
"storybook:watch": "npm run storybook:compile && concurrently \"clojure -M:dev:shadow-cljs watch storybook\" \"storybook dev -p 6006\"",
|
||||
"storybook:build": "npm run storybook:compile && storybook build"
|
||||
|
@ -67,19 +63,26 @@
|
|||
"map-stream": "0.0.7",
|
||||
"marked": "^12.0.0",
|
||||
"mkdirp": "^3.0.1",
|
||||
"mustache": "^4.2.0",
|
||||
"nodemon": "^3.1.0",
|
||||
"npm-run-all": "^4.1.5",
|
||||
"p-limit": "^5.0.0",
|
||||
"postcss": "^8.4.35",
|
||||
"postcss-clean": "^1.2.2",
|
||||
"prettier": "^3.2.5",
|
||||
"pretty-time": "^1.1.0",
|
||||
"prop-types": "^15.8.1",
|
||||
"rimraf": "^5.0.5",
|
||||
"sass": "^1.71.1",
|
||||
"sass-embedded": "^1.71.1",
|
||||
"shadow-cljs": "2.27.4",
|
||||
"storybook": "^7.6.17",
|
||||
"svg-sprite": "^2.0.2",
|
||||
"typescript": "^5.3.3",
|
||||
"vite": "^5.1.4",
|
||||
"vitest": "^1.3.1"
|
||||
"vitest": "^1.3.1",
|
||||
"watcher": "^2.3.0",
|
||||
"workerpool": "^9.1.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"date-fns": "^3.3.1",
|
||||
|
|
|
@ -26,7 +26,6 @@
|
|||
|
||||
<script>
|
||||
window.penpotTranslations = JSON.parse({{& translations}});
|
||||
window.penpotThemes = {{& themes}};
|
||||
window.penpotVersion = "%version%";
|
||||
window.penpotBuildDate = "%buildDate%";
|
||||
</script>
|
||||
|
@ -39,8 +38,8 @@
|
|||
|
||||
</head>
|
||||
<body>
|
||||
{{>../public/images/sprites/symbol/icons.svg}}
|
||||
{{>../public/images/sprites/symbol/cursors.svg}}
|
||||
{{> ../public/images/sprites/symbol/icons.svg }}
|
||||
{{> ../public/images/sprites/symbol/cursors.svg }}
|
||||
<div id="app"></div>
|
||||
<section id="modal"></section>
|
||||
{{# manifest}}
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
<link rel="icon" href="images/favicon.png" />
|
||||
|
||||
<script>
|
||||
window.penpotThemes = {{& themes}};
|
||||
window.penpotVersion = "%version%";
|
||||
</script>
|
||||
|
||||
|
|
405
frontend/scripts/_helpers.js
Normal file
405
frontend/scripts/_helpers.js
Normal file
|
@ -0,0 +1,405 @@
|
|||
import proc from "node:child_process";
|
||||
import fs from "node:fs/promises";
|
||||
import ph from "node:path";
|
||||
import os from "node:os";
|
||||
import url from "node:url";
|
||||
|
||||
import * as marked from "marked";
|
||||
import SVGSpriter from "svg-sprite";
|
||||
import Watcher from "watcher";
|
||||
import gettext from "gettext-parser";
|
||||
import l from "lodash";
|
||||
import log from "fancy-log";
|
||||
import mustache from "mustache";
|
||||
import pLimit from "p-limit";
|
||||
import ppt from "pretty-time";
|
||||
import wpool from "workerpool";
|
||||
|
||||
function getCoreCount() {
|
||||
return os.cpus().length;
|
||||
}
|
||||
|
||||
// const __filename = url.fileURLToPath(import.meta.url);
|
||||
export const dirname = url.fileURLToPath(new URL(".", import.meta.url));
|
||||
|
||||
export function startWorker() {
|
||||
return wpool.pool(dirname + "/_worker.js", {
|
||||
maxWorkers: getCoreCount()
|
||||
});
|
||||
}
|
||||
|
||||
async function findFiles(basePath, predicate, options={}) {
|
||||
predicate = predicate ?? function() { return true; }
|
||||
|
||||
let files = await fs.readdir(basePath, {recursive: options.recursive ?? false})
|
||||
files = files.filter((path) => path.endsWith(".svg"));
|
||||
files = files.map((path) => ph.join(basePath, path));
|
||||
|
||||
return files;
|
||||
}
|
||||
|
||||
function syncDirs(originPath, destPath) {
|
||||
const command = `rsync -ar --delete ${originPath} ${destPath}`;
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
proc.exec(command, (cause, stdout) => {
|
||||
if (cause) { reject(cause); }
|
||||
else { resolve(); }
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
export function isSassFile(path) {
|
||||
return path.endsWith(".scss");
|
||||
}
|
||||
|
||||
export function isSvgFile(path) {
|
||||
return path.endsWith(".scss");
|
||||
}
|
||||
|
||||
export async function compileSass(worker, path, options) {
|
||||
path = ph.resolve(path);
|
||||
|
||||
log.info("compile:", path);
|
||||
return worker.exec("compileSass", [path, options]);
|
||||
}
|
||||
|
||||
export async function compileSassAll(worker) {
|
||||
const limitFn = pLimit(4);
|
||||
const sourceDir = "src";
|
||||
|
||||
let files = await fs.readdir(sourceDir, { recursive: true })
|
||||
files = files.filter((path) => path.endsWith(".scss"));
|
||||
files = files.map((path) => ph.join(sourceDir, path));
|
||||
// files = files.slice(0, 10);
|
||||
|
||||
const procs = [
|
||||
compileSass(worker, "resources/styles/main-default.scss", {}),
|
||||
compileSass(worker, "resources/styles/debug.scss", {})
|
||||
];
|
||||
|
||||
for (let path of files) {
|
||||
const proc = limitFn(() => compileSass(worker, path, {modules: true}));
|
||||
procs.push(proc);
|
||||
}
|
||||
|
||||
const result = await Promise.all(procs);
|
||||
|
||||
return result.reduce((acc, item, index) => {
|
||||
acc.index[item.outputPath] = item.css;
|
||||
acc.items.push(item.outputPath);
|
||||
return acc;
|
||||
}, {index:{}, items: []});
|
||||
}
|
||||
|
||||
function compare(a, b) {
|
||||
if (a < b) {
|
||||
return -1;
|
||||
} else if (a > b) {
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
export function concatSass(data) {
|
||||
const output = []
|
||||
|
||||
for (let path of data.items) {
|
||||
output.push(data.index[path]);
|
||||
}
|
||||
|
||||
return output.join("\n");
|
||||
}
|
||||
|
||||
export async function watch(baseDir, predicate, callback) {
|
||||
predicate = predicate ?? (() => true);
|
||||
|
||||
|
||||
const watcher = new Watcher(baseDir, {
|
||||
persistent: true,
|
||||
recursive: true
|
||||
});
|
||||
|
||||
watcher.on("change", (path) => {
|
||||
if (predicate(path)) {
|
||||
callback(path);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
async function readShadowManifest() {
|
||||
try {
|
||||
const manifestPath = "resources/public/js/manifest.json"
|
||||
let content = await fs.readFile(manifestPath, { encoding: "utf8" });
|
||||
content = JSON.parse(content);
|
||||
|
||||
const index = {
|
||||
config: "js/config.js?ts=" + Date.now(),
|
||||
polyfills: "js/polyfills.js?ts=" + Date.now(),
|
||||
};
|
||||
|
||||
for (let item of content) {
|
||||
index[item.name] = "js/" + item["output-name"];
|
||||
}
|
||||
|
||||
return index;
|
||||
} catch (cause) {
|
||||
// log.error("error on reading manifest (using default)", cause);
|
||||
return {
|
||||
config: "js/config.js",
|
||||
polyfills: "js/polyfills.js",
|
||||
main: "js/main.js",
|
||||
shared: "js/shared.js",
|
||||
worker: "js/worker.js",
|
||||
rasterizer: "js/rasterizer.js",
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
async function renderTemplate(path, context={}, partials={}) {
|
||||
const content = await fs.readFile(path, {encoding: "utf-8"});
|
||||
|
||||
const ts = Math.floor(new Date());
|
||||
|
||||
context = Object.assign({}, context, {
|
||||
ts: ts,
|
||||
isDebug: process.env.NODE_ENV !== "production"
|
||||
});
|
||||
|
||||
return mustache.render(content, context, partials);
|
||||
}
|
||||
|
||||
const renderer = {
|
||||
link(href, title, text) {
|
||||
return `<a href="${href}" target="_blank">${text}</a>`;
|
||||
},
|
||||
};
|
||||
|
||||
marked.use({ renderer });
|
||||
|
||||
async function readTranslations() {
|
||||
const langs = [
|
||||
"ar",
|
||||
"ca",
|
||||
"de",
|
||||
"el",
|
||||
"en",
|
||||
"eu",
|
||||
"it",
|
||||
"es",
|
||||
"fa",
|
||||
"fr",
|
||||
"he",
|
||||
"nb_NO",
|
||||
"pl",
|
||||
"pt_BR",
|
||||
"ro",
|
||||
"id",
|
||||
"ru",
|
||||
"tr",
|
||||
"zh_CN",
|
||||
"zh_Hant",
|
||||
"hr",
|
||||
"gl",
|
||||
"pt_PT",
|
||||
"cs",
|
||||
"fo",
|
||||
"ko",
|
||||
"lv",
|
||||
"nl",
|
||||
// this happens when file does not matches correct
|
||||
// iso code for the language.
|
||||
["ja_jp", "jpn_JP"],
|
||||
// ["fi", "fin_FI"],
|
||||
["uk", "ukr_UA"],
|
||||
"ha"
|
||||
];
|
||||
const result = {};
|
||||
|
||||
for (let lang of langs) {
|
||||
let filename = `${lang}.po`;
|
||||
if (l.isArray(lang)) {
|
||||
filename = `${lang[1]}.po`;
|
||||
lang = lang[0];
|
||||
}
|
||||
|
||||
const content = await fs.readFile(`./translations/${filename}`, { encoding: "utf-8" });
|
||||
|
||||
lang = lang.toLowerCase();
|
||||
|
||||
const data = gettext.po.parse(content, "utf-8");
|
||||
const trdata = data.translations[""];
|
||||
|
||||
for (let key of Object.keys(trdata)) {
|
||||
if (key === "") continue;
|
||||
const comments = trdata[key].comments || {};
|
||||
|
||||
if (l.isNil(result[key])) {
|
||||
result[key] = {};
|
||||
}
|
||||
|
||||
const isMarkdown = l.includes(comments.flag, "markdown");
|
||||
|
||||
const msgs = trdata[key].msgstr;
|
||||
if (msgs.length === 1) {
|
||||
let message = msgs[0];
|
||||
if (isMarkdown) {
|
||||
message = marked.parseInline(message);
|
||||
}
|
||||
|
||||
result[key][lang] = message;
|
||||
} else {
|
||||
result[key][lang] = msgs.map((item) => {
|
||||
if (isMarkdown) {
|
||||
return marked.parseInline(item);
|
||||
} else {
|
||||
return item;
|
||||
}
|
||||
});
|
||||
}
|
||||
// if (key === "modals.delete-font.title") {
|
||||
// console.dir(trdata[key], {depth:10});
|
||||
// console.dir(result[key], {depth:10});
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
return JSON.stringify(result);
|
||||
}
|
||||
|
||||
async function generateSvgSprite(files, prefix) {
|
||||
const spriter = new SVGSpriter({
|
||||
mode: {
|
||||
symbol: { inline: true }
|
||||
}
|
||||
});
|
||||
|
||||
for (let path of files) {
|
||||
const name = `${prefix}${ph.basename(path)}`
|
||||
const content = await fs.readFile(path, {encoding: "utf-8"});
|
||||
spriter.add(name, name, content);
|
||||
}
|
||||
|
||||
const { result } = await spriter.compileAsync();
|
||||
const resource = result.symbol.sprite;
|
||||
return resource.contents;
|
||||
}
|
||||
|
||||
async function generateSvgSprites() {
|
||||
await fs.mkdir("resources/public/images/sprites/symbol/", { recursive: true });
|
||||
|
||||
const icons = await findFiles("resources/images/icons/", isSvgFile);
|
||||
const iconsSprite = await generateSvgSprite(icons, "icon-");
|
||||
await fs.writeFile("resources/public/images/sprites/symbol/icons.svg", iconsSprite);
|
||||
|
||||
const cursors = await findFiles("resources/images/cursors/", isSvgFile);
|
||||
const cursorsSprite = await generateSvgSprite(icons, "cursor-");
|
||||
await fs.writeFile("resources/public/images/sprites/symbol/cursors.svg", cursorsSprite);
|
||||
}
|
||||
|
||||
async function generateTemplates() {
|
||||
await fs.mkdir("./resources/public/", { recursive: true });
|
||||
|
||||
const translations = await readTranslations();
|
||||
const manifest = await readShadowManifest();
|
||||
let content;
|
||||
|
||||
const iconsSprite = await fs.readFile("resources/public/images/sprites/symbol/icons.svg", "utf8");
|
||||
const cursorsSprite = await fs.readFile("resources/public/images/sprites/symbol/cursors.svg", "utf8");
|
||||
const partials = {
|
||||
"../public/images/sprites/symbol/icons.svg": iconsSprite,
|
||||
"../public/images/sprites/symbol/cursors.svg": cursorsSprite,
|
||||
};
|
||||
|
||||
content = await renderTemplate("resources/templates/index.mustache", {
|
||||
manifest: manifest,
|
||||
translations: JSON.stringify(translations),
|
||||
}, partials);
|
||||
|
||||
await fs.writeFile("./resources/public/index.html", content);
|
||||
|
||||
content = await renderTemplate("resources/templates/preview-body.mustache", {
|
||||
manifest: manifest,
|
||||
translations: JSON.stringify(translations),
|
||||
});
|
||||
|
||||
await fs.writeFile("./.storybook/preview-body.html", content);
|
||||
|
||||
content = await renderTemplate("resources/templates/render.mustache", {
|
||||
manifest: manifest,
|
||||
translations: JSON.stringify(translations),
|
||||
});
|
||||
|
||||
await fs.writeFile("./resources/public/render.html", content);
|
||||
|
||||
content = await renderTemplate("resources/templates/rasterizer.mustache", {
|
||||
manifest: manifest,
|
||||
translations: JSON.stringify(translations),
|
||||
});
|
||||
|
||||
await fs.writeFile("./resources/public/rasterizer.html", content);
|
||||
}
|
||||
|
||||
export async function compileStyles() {
|
||||
const worker = startWorker();
|
||||
const start = process.hrtime();
|
||||
|
||||
log.info("init: compile styles")
|
||||
let result = await compileSassAll(worker);
|
||||
result = concatSass(result);
|
||||
|
||||
await fs.mkdir("./resources/public/css", { recursive: true });
|
||||
await fs.writeFile("./resources/public/css/main.css", result);
|
||||
|
||||
const end = process.hrtime(start);
|
||||
log.info("done: compile styles", `(${ppt(end)})`);
|
||||
worker.terminate();
|
||||
}
|
||||
|
||||
export async function compileSvgSprites() {
|
||||
const start = process.hrtime();
|
||||
log.info("init: compile svgsprite")
|
||||
await generateSvgSprites();
|
||||
const end = process.hrtime(start);
|
||||
log.info("done: compile svgsprite", `(${ppt(end)})`);
|
||||
}
|
||||
|
||||
export async function compileTemplates() {
|
||||
const start = process.hrtime();
|
||||
log.info("init: compile templates")
|
||||
await generateTemplates();
|
||||
const end = process.hrtime(start);
|
||||
log.info("done: compile templates", `(${ppt(end)})`);
|
||||
}
|
||||
|
||||
export async function compilePolyfills() {
|
||||
const start = process.hrtime();
|
||||
log.info("init: compile polyfills")
|
||||
|
||||
|
||||
const files = await findFiles("resources/polyfills/");
|
||||
let result = [];
|
||||
for (let path of files) {
|
||||
const content = await fs.readFile(path, {encoding:"utf-8"});
|
||||
result.push(content);
|
||||
}
|
||||
|
||||
await fs.mkdir("./resources/public/js", { recursive: true });
|
||||
fs.writeFile("resources/public/js/polyfills.js", result.join("\n"));
|
||||
|
||||
const end = process.hrtime(start);
|
||||
log.info("done: compile polyfills", `(${ppt(end)})`);
|
||||
}
|
||||
|
||||
export async function copyAssets() {
|
||||
const start = process.hrtime();
|
||||
log.info("init: copy assets")
|
||||
|
||||
await syncDirs("resources/images/", "resources/public/images/");
|
||||
await syncDirs("resources/fonts/", "resources/public/fonts/");
|
||||
|
||||
const end = process.hrtime(start);
|
||||
log.info("done: copy assets", `(${ppt(end)})`);
|
||||
}
|
||||
|
97
frontend/scripts/_worker.js
Normal file
97
frontend/scripts/_worker.js
Normal file
|
@ -0,0 +1,97 @@
|
|||
import proc from "node:child_process";
|
||||
import fs from "node:fs/promises";
|
||||
import ph from "node:path";
|
||||
import url from "node:url";
|
||||
import * as sass from "sass-embedded";
|
||||
import log from "fancy-log";
|
||||
|
||||
import wpool from "workerpool";
|
||||
import postcss from "postcss";
|
||||
import modulesProcessor from "postcss-modules";
|
||||
import autoprefixerProcessor from "autoprefixer";
|
||||
|
||||
const compiler = await sass.initAsyncCompiler();
|
||||
|
||||
async function compileFile(path) {
|
||||
const dir = ph.dirname(path);
|
||||
const name = ph.basename(path, ".scss");
|
||||
const dest = `${dir}${ph.sep}${name}.css`;
|
||||
|
||||
|
||||
return new Promise(async (resolve, reject) => {
|
||||
try {
|
||||
const result = await compiler.compileAsync(path, {
|
||||
loadPaths: ["node_modules/animate.css", "resources/styles/common/", "resources/styles"],
|
||||
sourceMap: false
|
||||
});
|
||||
// console.dir(result);
|
||||
resolve({
|
||||
inputPath: path,
|
||||
outputPath: dest,
|
||||
css: result.css
|
||||
});
|
||||
} catch (cause) {
|
||||
// console.error(cause);
|
||||
reject(cause);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function configureModulesProcessor(options) {
|
||||
const ROOT_NAME = "app";
|
||||
|
||||
return modulesProcessor({
|
||||
getJSON: (cssFileName, json, outputFileName) => {
|
||||
// We do nothing because we don't want the generated JSON files
|
||||
},
|
||||
// Calculates the whole css-module selector name.
|
||||
// Should be the same as the one in the file `/src/app/main/style.clj`
|
||||
generateScopedName: (selector, filename, css) => {
|
||||
const dir = ph.dirname(filename);
|
||||
const name = ph.basename(filename, ".css");
|
||||
const parts = dir.split("/");
|
||||
const rootIdx = parts.findIndex((s) => s === ROOT_NAME);
|
||||
return parts.slice(rootIdx + 1).join("_") + "_" + name + "__" + selector;
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
function configureProcessor(options={}) {
|
||||
const processors = [];
|
||||
|
||||
if (options.modules) {
|
||||
processors.push(configureModulesProcessor(options));
|
||||
}
|
||||
processors.push(autoprefixerProcessor);
|
||||
|
||||
return postcss(processors);
|
||||
}
|
||||
|
||||
async function postProcessFile(data, options) {
|
||||
const proc = configureProcessor(options);
|
||||
|
||||
// We compile to the same path (all in memory)
|
||||
const result = await proc.process(data.css, {
|
||||
from: data.outputPath,
|
||||
to: data.outputPath,
|
||||
map: false,
|
||||
});
|
||||
|
||||
return Object.assign(data, {
|
||||
css: result.css
|
||||
});
|
||||
}
|
||||
|
||||
async function compile(path, options) {
|
||||
let result = await compileFile(path);
|
||||
return await postProcessFile(result, options);
|
||||
}
|
||||
|
||||
wpool.worker({
|
||||
compileSass: compile
|
||||
}, {
|
||||
onTerminate: async (code) => {
|
||||
// log.info("worker: terminate");
|
||||
await compiler.dispose();
|
||||
}
|
||||
});
|
|
@ -1,4 +1,6 @@
|
|||
#!/usr/bin/env bash
|
||||
# NOTE: this script should be called from the parent directory to
|
||||
# properly work.
|
||||
|
||||
set -ex
|
||||
|
||||
|
@ -12,13 +14,13 @@ export EXTRA_PARAMS=$SHADOWCLJS_EXTRA_PARAMS;
|
|||
export NODE_ENV=production;
|
||||
|
||||
yarn install || exit 1;
|
||||
yarn run build:clean || exit 1;
|
||||
yarn run build:styles || exit 1;
|
||||
rm -rf resources/public;
|
||||
rm -rf target/dist;
|
||||
|
||||
clojure -J-Xms100M -J-Xmx1000M -J-XX:+UseSerialGC -M:dev:shadow-cljs release main --config-merge "{:release-version \"${CURRENT_HASH}\"}" $EXTRA_PARAMS || exit 1
|
||||
clojure -M:dev:shadow-cljs release main --config-merge "{:release-version \"${CURRENT_HASH}\"}" $EXTRA_PARAMS || exit 1
|
||||
|
||||
yarn run build:assets || exit 1;
|
||||
yarn run build:copy || exit 1;
|
||||
yarn run compile || exit 1;
|
||||
rsync -avr resources/public/ target/dist/
|
||||
|
||||
sed -i -re "s/\%version\%/$CURRENT_VERSION/g" ./target/dist/index.html;
|
||||
sed -i -re "s/\%buildDate\%/$BUILD_DATE/g" ./target/dist/index.html;
|
||||
|
|
10
frontend/scripts/compile.js
Normal file
10
frontend/scripts/compile.js
Normal file
|
@ -0,0 +1,10 @@
|
|||
import fs from "node:fs/promises";
|
||||
import ppt from "pretty-time";
|
||||
import log from "fancy-log";
|
||||
import * as h from "./_helpers.js";
|
||||
|
||||
await h.compileStyles();
|
||||
await h.copyAssets()
|
||||
await h.compileSvgSprites()
|
||||
await h.compileTemplates();
|
||||
await h.compilePolyfills();
|
|
@ -1,62 +0,0 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
# This script automates compressing PNG images using the lossless Zopfli
|
||||
# Compression Algorithm. The process is slow but can produce significantly
|
||||
# better compression and, thus, smaller file sizes.
|
||||
#
|
||||
# This script is meant to be run manually, for example, before making a new
|
||||
# release.
|
||||
#
|
||||
# Requirements
|
||||
#
|
||||
# zopflipng - https://github.com/google/zopfli
|
||||
# Debian/Ubuntu: sudo apt install zopfli
|
||||
# Fedora: sudo dnf install zopfli
|
||||
# macOS: brew install zopfli
|
||||
#
|
||||
# Usage
|
||||
#
|
||||
# This script takes a single positional argument which is the path where to
|
||||
# search for PNG files. By default, the target path is the current working
|
||||
# directory. Run from the root of the repository to compress all PNG images. Run
|
||||
# from the `frontend` subdirectory to compress all PNG images within that
|
||||
# directory. Alternatively, run from any directory and pass an explicit path to
|
||||
# `compress-png` to limit the script to that path/directory.
|
||||
|
||||
set -o errexit
|
||||
set -o nounset
|
||||
set -o pipefail
|
||||
|
||||
readonly TARGET="${1:-.}"
|
||||
readonly ABS_TARGET="$(command -v realpath &>/dev/null && realpath "$TARGET")"
|
||||
|
||||
function png_total_size() {
|
||||
find "$TARGET" -type f -iname '*.png' -exec du -ch {} + | tail -1
|
||||
}
|
||||
|
||||
echo "Compressing PNGs in ${ABS_TARGET:-$TARGET}"
|
||||
|
||||
echo "Before"
|
||||
png_total_size
|
||||
|
||||
readonly opts=(
|
||||
# More iterations means slower, potentially better compression.
|
||||
#--iterations=500
|
||||
-m
|
||||
# Try all filter strategies (slow).
|
||||
#--filters=01234mepb
|
||||
# According to docs, remove colors behind alpha channel 0. No visual
|
||||
# difference, removes hidden information.
|
||||
--lossy_transparent
|
||||
# Avoid information loss that could affect how images are rendered, see
|
||||
# https://github.com/penpot/penpot/issues/1533#issuecomment-1030005203
|
||||
# https://github.com/google/zopfli/issues/113
|
||||
--keepchunks=cHRM,gAMA,pHYs,iCCP,sRGB,oFFs,sTER
|
||||
# Since we have git behind our back, overwrite PNG files in-place (only
|
||||
# when result is smaller).
|
||||
-y
|
||||
)
|
||||
time find "$TARGET" -type f -iname '*.png' -exec zopflipng "${opts[@]}" {} {} \;
|
||||
|
||||
echo "After"
|
||||
png_total_size
|
|
@ -1,11 +0,0 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
# A repl useful for debug macros.
|
||||
|
||||
export OPTIONS="\
|
||||
-J-XX:-OmitStackTraceInFastThrow \
|
||||
-J-Xms50m -J-Xmx512m \
|
||||
-M:dev:jvm-repl";
|
||||
|
||||
set -ex;
|
||||
exec clojure $OPTIONS;
|
74
frontend/scripts/watch.js
Normal file
74
frontend/scripts/watch.js
Normal file
|
@ -0,0 +1,74 @@
|
|||
import proc from "node:child_process";
|
||||
import fs from "node:fs/promises";
|
||||
import ph from "node:path";
|
||||
|
||||
import log from "fancy-log";
|
||||
import * as h from "./_helpers.js";
|
||||
import ppt from "pretty-time";
|
||||
|
||||
const worker = h.startWorker();
|
||||
let sass = null;
|
||||
|
||||
async function compileSassAll() {
|
||||
const start = process.hrtime();
|
||||
log.info("init: compile styles")
|
||||
|
||||
sass = await h.compileSassAll(worker);
|
||||
let output = await h.concatSass(sass);
|
||||
await fs.writeFile("./resources/public/css/main.css", output);
|
||||
|
||||
const end = process.hrtime(start);
|
||||
log.info("done: compile styles", `(${ppt(end)})`);
|
||||
}
|
||||
|
||||
async function compileSass(path) {
|
||||
const start = process.hrtime();
|
||||
log.info("changed:", path);
|
||||
const result = await h.compileSass(worker, path, {modules:true});
|
||||
sass.index[result.outputPath] = result.css;
|
||||
|
||||
const output = h.concatSass(sass);
|
||||
|
||||
await fs.writeFile("./resources/public/css/main.css", output);
|
||||
|
||||
const end = process.hrtime(start);
|
||||
log.info("done:", `(${ppt(end)})`);
|
||||
}
|
||||
|
||||
await compileSassAll();
|
||||
await h.copyAssets()
|
||||
await h.compileSvgSprites()
|
||||
await h.compileTemplates();
|
||||
await h.compilePolyfills();
|
||||
|
||||
log.info("watch: scss src (~)")
|
||||
|
||||
h.watch("src", h.isSassFile, async function (path) {
|
||||
if (path.includes("common")) {
|
||||
await compileSassAll(path);
|
||||
} else {
|
||||
await compileSass(path);
|
||||
}
|
||||
});
|
||||
|
||||
log.info("watch: scss: resources (~)")
|
||||
h.watch("resources/styles", h.isSassFile, async function (path) {
|
||||
log.info("changed:", path);
|
||||
await compileSassAll()
|
||||
});
|
||||
|
||||
log.info("watch: templates (~)")
|
||||
h.watch("resources/templates", null, async function (path) {
|
||||
log.info("changed:", path);
|
||||
await h.compileTemplates();
|
||||
});
|
||||
|
||||
log.info("watch: assets (~)")
|
||||
h.watch(["resources/images", "resources/fonts"], null, async function (path) {
|
||||
log.info("changed:", path);
|
||||
await h.compileSvgSprites();
|
||||
await h.copyAssets();
|
||||
await h.compileTemplates();
|
||||
});
|
||||
|
||||
worker.terminate();
|
|
@ -1471,6 +1471,13 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@bufbuild/protobuf@npm:^1.0.0":
|
||||
version: 1.7.2
|
||||
resolution: "@bufbuild/protobuf@npm:1.7.2"
|
||||
checksum: 37a968b7d314c1f2e2b996bb287c72dbeaacd5bc0d92e2f706437a51c4e483ff85b97994428e252d6acf99bd7b16435471413ae3af1bd9b416d72ab3f0decd22
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@colors/colors@npm:1.5.0":
|
||||
version: 1.5.0
|
||||
resolution: "@colors/colors@npm:1.5.0"
|
||||
|
@ -5333,6 +5340,13 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"buffer-builder@npm:^0.2.0":
|
||||
version: 0.2.0
|
||||
resolution: "buffer-builder@npm:0.2.0"
|
||||
checksum: e50c3a379f4acaea75ade1ee3e8c07ed6d7c5dfc3f98adbcf0159bfe1a4ce8ca1fe3689e861fcdb3fcef0012ebd4345a6112a5b8a1185295452bb66d7b6dc8a1
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"buffer-crc32@npm:~0.2.3":
|
||||
version: 0.2.13
|
||||
resolution: "buffer-crc32@npm:0.2.13"
|
||||
|
@ -6601,6 +6615,13 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"dettle@npm:^1.0.1":
|
||||
version: 1.0.1
|
||||
resolution: "dettle@npm:1.0.1"
|
||||
checksum: 116a101aff93b2e1d5e505adbe53c4b898d924bc16f12f5ac629055ed8a8a19c86f916b834b178b7bfb352dd601bbfe01e49ccd56144a5a2f780f4bd374ef112
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"diff-sequences@npm:^29.6.3":
|
||||
version: 29.6.3
|
||||
resolution: "diff-sequences@npm:29.6.3"
|
||||
|
@ -7939,13 +7960,16 @@ __metadata:
|
|||
marked: "npm:^12.0.0"
|
||||
mkdirp: "npm:^3.0.1"
|
||||
mousetrap: "npm:^1.6.5"
|
||||
mustache: "npm:^4.2.0"
|
||||
nodemon: "npm:^3.1.0"
|
||||
npm-run-all: "npm:^4.1.5"
|
||||
opentype.js: "npm:^1.3.4"
|
||||
p-limit: "npm:^5.0.0"
|
||||
postcss: "npm:^8.4.35"
|
||||
postcss-clean: "npm:^1.2.2"
|
||||
postcss-modules: "npm:^6.0.0"
|
||||
prettier: "npm:^3.2.5"
|
||||
pretty-time: "npm:^1.1.0"
|
||||
prop-types: "npm:^15.8.1"
|
||||
randomcolor: "npm:^0.6.2"
|
||||
react: "npm:^18.2.0"
|
||||
|
@ -7954,15 +7978,19 @@ __metadata:
|
|||
rimraf: "npm:^5.0.5"
|
||||
rxjs: "npm:8.0.0-alpha.14"
|
||||
sass: "npm:^1.71.1"
|
||||
sass-embedded: "npm:^1.71.1"
|
||||
sax: "npm:^1.3.0"
|
||||
shadow-cljs: "npm:2.27.4"
|
||||
source-map-support: "npm:^0.5.21"
|
||||
storybook: "npm:^7.6.17"
|
||||
svg-sprite: "npm:^2.0.2"
|
||||
tdigest: "npm:^0.1.2"
|
||||
typescript: "npm:^5.3.3"
|
||||
ua-parser-js: "npm:^1.0.37"
|
||||
vite: "npm:^5.1.4"
|
||||
vitest: "npm:^1.3.1"
|
||||
watcher: "npm:^2.3.0"
|
||||
workerpool: "npm:^9.1.0"
|
||||
xregexp: "npm:^5.1.1"
|
||||
languageName: unknown
|
||||
linkType: soft
|
||||
|
@ -12087,6 +12115,13 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"pretty-time@npm:^1.1.0":
|
||||
version: 1.1.0
|
||||
resolution: "pretty-time@npm:1.1.0"
|
||||
checksum: ba9d7af19cd43838fb2b147654990949575e400dc2cc24bf71ec4a6c4033a38ba8172b1014b597680c6d4d3c075e94648b2c13a7206c5f0c90b711c7388726f3
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"prettysize@npm:^2.0.0":
|
||||
version: 2.0.0
|
||||
resolution: "prettysize@npm:2.0.0"
|
||||
|
@ -12122,6 +12157,13 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"promise-make-naked@npm:^2.1.1":
|
||||
version: 2.1.1
|
||||
resolution: "promise-make-naked@npm:2.1.1"
|
||||
checksum: 97bc0a3eeae59f75e8716d5f511edb4ed7558fa304f93407a7c9de3645a19135abfc87d4bca0b570619d3314fa87db67ea3463c4a5068c4bbe7f8889c6883f1d
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"promise-retry@npm:^2.0.1":
|
||||
version: 2.0.1
|
||||
resolution: "promise-retry@npm:2.0.1"
|
||||
|
@ -13126,7 +13168,7 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"rxjs@npm:^7.8.1":
|
||||
"rxjs@npm:^7.4.0, rxjs@npm:^7.8.1":
|
||||
version: 7.8.1
|
||||
resolution: "rxjs@npm:7.8.1"
|
||||
dependencies:
|
||||
|
@ -13195,6 +13237,205 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"sass-embedded-android-arm64@npm:1.71.1":
|
||||
version: 1.71.1
|
||||
resolution: "sass-embedded-android-arm64@npm:1.71.1"
|
||||
bin:
|
||||
sass: dart-sass/sass
|
||||
conditions: os=android & cpu=arm64
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"sass-embedded-android-arm@npm:1.71.1":
|
||||
version: 1.71.1
|
||||
resolution: "sass-embedded-android-arm@npm:1.71.1"
|
||||
bin:
|
||||
sass: dart-sass/sass
|
||||
conditions: os=android & cpu=arm
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"sass-embedded-android-ia32@npm:1.71.1":
|
||||
version: 1.71.1
|
||||
resolution: "sass-embedded-android-ia32@npm:1.71.1"
|
||||
bin:
|
||||
sass: dart-sass/sass
|
||||
conditions: os=android & cpu=ia32
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"sass-embedded-android-x64@npm:1.71.1":
|
||||
version: 1.71.1
|
||||
resolution: "sass-embedded-android-x64@npm:1.71.1"
|
||||
bin:
|
||||
sass: dart-sass/sass
|
||||
conditions: os=android & cpu=x64
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"sass-embedded-darwin-arm64@npm:1.71.1":
|
||||
version: 1.71.1
|
||||
resolution: "sass-embedded-darwin-arm64@npm:1.71.1"
|
||||
bin:
|
||||
sass: dart-sass/sass
|
||||
conditions: os=darwin & cpu=arm64
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"sass-embedded-darwin-x64@npm:1.71.1":
|
||||
version: 1.71.1
|
||||
resolution: "sass-embedded-darwin-x64@npm:1.71.1"
|
||||
bin:
|
||||
sass: dart-sass/sass
|
||||
conditions: os=darwin & cpu=x64
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"sass-embedded-linux-arm64@npm:1.71.1":
|
||||
version: 1.71.1
|
||||
resolution: "sass-embedded-linux-arm64@npm:1.71.1"
|
||||
bin:
|
||||
sass: dart-sass/sass
|
||||
conditions: os=linux & cpu=arm64
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"sass-embedded-linux-arm@npm:1.71.1":
|
||||
version: 1.71.1
|
||||
resolution: "sass-embedded-linux-arm@npm:1.71.1"
|
||||
bin:
|
||||
sass: dart-sass/sass
|
||||
conditions: os=linux & cpu=arm
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"sass-embedded-linux-ia32@npm:1.71.1":
|
||||
version: 1.71.1
|
||||
resolution: "sass-embedded-linux-ia32@npm:1.71.1"
|
||||
bin:
|
||||
sass: dart-sass/sass
|
||||
conditions: os=linux & cpu=ia32
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"sass-embedded-linux-musl-arm64@npm:1.71.1":
|
||||
version: 1.71.1
|
||||
resolution: "sass-embedded-linux-musl-arm64@npm:1.71.1"
|
||||
conditions: os=linux & cpu=arm64
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"sass-embedded-linux-musl-arm@npm:1.71.1":
|
||||
version: 1.71.1
|
||||
resolution: "sass-embedded-linux-musl-arm@npm:1.71.1"
|
||||
conditions: os=linux & cpu=arm
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"sass-embedded-linux-musl-ia32@npm:1.71.1":
|
||||
version: 1.71.1
|
||||
resolution: "sass-embedded-linux-musl-ia32@npm:1.71.1"
|
||||
conditions: os=linux & cpu=ia32
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"sass-embedded-linux-musl-x64@npm:1.71.1":
|
||||
version: 1.71.1
|
||||
resolution: "sass-embedded-linux-musl-x64@npm:1.71.1"
|
||||
conditions: os=linux & cpu=x64
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"sass-embedded-linux-x64@npm:1.71.1":
|
||||
version: 1.71.1
|
||||
resolution: "sass-embedded-linux-x64@npm:1.71.1"
|
||||
bin:
|
||||
sass: dart-sass/sass
|
||||
conditions: os=linux & cpu=x64
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"sass-embedded-win32-ia32@npm:1.71.1":
|
||||
version: 1.71.1
|
||||
resolution: "sass-embedded-win32-ia32@npm:1.71.1"
|
||||
bin:
|
||||
sass: dart-sass/sass.bat
|
||||
conditions: os=win32 & cpu=ia32
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"sass-embedded-win32-x64@npm:1.71.1":
|
||||
version: 1.71.1
|
||||
resolution: "sass-embedded-win32-x64@npm:1.71.1"
|
||||
bin:
|
||||
sass: dart-sass/sass.bat
|
||||
conditions: os=win32 & (cpu=arm64 | cpu=x64)
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"sass-embedded@npm:^1.71.1":
|
||||
version: 1.71.1
|
||||
resolution: "sass-embedded@npm:1.71.1"
|
||||
dependencies:
|
||||
"@bufbuild/protobuf": "npm:^1.0.0"
|
||||
buffer-builder: "npm:^0.2.0"
|
||||
immutable: "npm:^4.0.0"
|
||||
rxjs: "npm:^7.4.0"
|
||||
sass-embedded-android-arm: "npm:1.71.1"
|
||||
sass-embedded-android-arm64: "npm:1.71.1"
|
||||
sass-embedded-android-ia32: "npm:1.71.1"
|
||||
sass-embedded-android-x64: "npm:1.71.1"
|
||||
sass-embedded-darwin-arm64: "npm:1.71.1"
|
||||
sass-embedded-darwin-x64: "npm:1.71.1"
|
||||
sass-embedded-linux-arm: "npm:1.71.1"
|
||||
sass-embedded-linux-arm64: "npm:1.71.1"
|
||||
sass-embedded-linux-ia32: "npm:1.71.1"
|
||||
sass-embedded-linux-musl-arm: "npm:1.71.1"
|
||||
sass-embedded-linux-musl-arm64: "npm:1.71.1"
|
||||
sass-embedded-linux-musl-ia32: "npm:1.71.1"
|
||||
sass-embedded-linux-musl-x64: "npm:1.71.1"
|
||||
sass-embedded-linux-x64: "npm:1.71.1"
|
||||
sass-embedded-win32-ia32: "npm:1.71.1"
|
||||
sass-embedded-win32-x64: "npm:1.71.1"
|
||||
supports-color: "npm:^8.1.1"
|
||||
varint: "npm:^6.0.0"
|
||||
dependenciesMeta:
|
||||
sass-embedded-android-arm:
|
||||
optional: true
|
||||
sass-embedded-android-arm64:
|
||||
optional: true
|
||||
sass-embedded-android-ia32:
|
||||
optional: true
|
||||
sass-embedded-android-x64:
|
||||
optional: true
|
||||
sass-embedded-darwin-arm64:
|
||||
optional: true
|
||||
sass-embedded-darwin-x64:
|
||||
optional: true
|
||||
sass-embedded-linux-arm:
|
||||
optional: true
|
||||
sass-embedded-linux-arm64:
|
||||
optional: true
|
||||
sass-embedded-linux-ia32:
|
||||
optional: true
|
||||
sass-embedded-linux-musl-arm:
|
||||
optional: true
|
||||
sass-embedded-linux-musl-arm64:
|
||||
optional: true
|
||||
sass-embedded-linux-musl-ia32:
|
||||
optional: true
|
||||
sass-embedded-linux-musl-x64:
|
||||
optional: true
|
||||
sass-embedded-linux-x64:
|
||||
optional: true
|
||||
sass-embedded-win32-ia32:
|
||||
optional: true
|
||||
sass-embedded-win32-x64:
|
||||
optional: true
|
||||
checksum: 637b00398b92b88db6b6dc8906d1c6e42c6907cd26afbda05ff3cdc19360eb2efeeaa8591c995f14e05aa8a08314bf7af219a4cbe1172a95365ca6b442b799d5
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"sass@npm:^1.71.1":
|
||||
version: 1.71.1
|
||||
resolution: "sass@npm:1.71.1"
|
||||
|
@ -14038,6 +14279,13 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"stubborn-fs@npm:^1.2.5":
|
||||
version: 1.2.5
|
||||
resolution: "stubborn-fs@npm:1.2.5"
|
||||
checksum: 0676befd9901d4dd4e162700fa0396f11d523998589cd6b61b06d1021db811dc4c1e6713869748c6cfa49d58beb9b6f0dc5b6aca6b075811b949e1602ce1e26f
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"supports-color@npm:^5.3.0, supports-color@npm:^5.4.0, supports-color@npm:^5.5.0":
|
||||
version: 5.5.0
|
||||
resolution: "supports-color@npm:5.5.0"
|
||||
|
@ -14316,6 +14564,15 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"tiny-readdir@npm:^2.2.0":
|
||||
version: 2.4.0
|
||||
resolution: "tiny-readdir@npm:2.4.0"
|
||||
dependencies:
|
||||
promise-make-naked: "npm:^2.1.1"
|
||||
checksum: 0fd05eb677a9bf25f6ace33ad2eeaeb8555303321e18cd22c7a96391f099c1dd900d745738a1c6ba276540b1dc117f72fbbf60cc47bf1c7a73840745e3ea42f8
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"tinybench@npm:^2.5.1":
|
||||
version: 2.5.1
|
||||
resolution: "tinybench@npm:2.5.1"
|
||||
|
@ -15071,6 +15328,13 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"varint@npm:^6.0.0":
|
||||
version: 6.0.0
|
||||
resolution: "varint@npm:6.0.0"
|
||||
checksum: 737fc37088a62ed3bd21466e318d21ca7ac4991d0f25546f518f017703be4ed0f9df1c5559f1dd533dddba4435a1b758fd9230e4772c1a930ef72b42f5c750fd
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"vary@npm:~1.1.2":
|
||||
version: 1.1.2
|
||||
resolution: "vary@npm:1.1.2"
|
||||
|
@ -15311,6 +15575,17 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"watcher@npm:^2.3.0":
|
||||
version: 2.3.0
|
||||
resolution: "watcher@npm:2.3.0"
|
||||
dependencies:
|
||||
dettle: "npm:^1.0.1"
|
||||
stubborn-fs: "npm:^1.2.5"
|
||||
tiny-readdir: "npm:^2.2.0"
|
||||
checksum: 7b1e47321ddf96882ebee6f619211b085f98bc0c3bceb94a58938e8d8d209f83283b30b645bdae148e063c3bc165eeafd73e3a14bdb7c3bfe519bd7536172257
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"watchpack@npm:^2.2.0":
|
||||
version: 2.4.0
|
||||
resolution: "watchpack@npm:2.4.0"
|
||||
|
@ -15521,6 +15796,13 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"workerpool@npm:^9.1.0":
|
||||
version: 9.1.0
|
||||
resolution: "workerpool@npm:9.1.0"
|
||||
checksum: 32d0807962be58a98ec22f5630be4a90f779f5faab06d5b4f000d32c11c8d5feb66be9bc5c73fdc49c91519e391db55c9e2e63392854b3df945744b2436a7efd
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0, wrap-ansi@npm:^7.0.0":
|
||||
version: 7.0.0
|
||||
resolution: "wrap-ansi@npm:7.0.0"
|
||||
|
|
Loading…
Add table
Reference in a new issue