refactor: project architecture refactor, container splitting
This commit is contained in:
@@ -1,86 +0,0 @@
|
||||
#!/usr/bin/env node
|
||||
import { createHash } from "node:crypto";
|
||||
import { readFile, readdir, unlink, writeFile } from "node:fs/promises";
|
||||
import path from "node:path";
|
||||
import { fileURLToPath } from "node:url";
|
||||
|
||||
import { transform } from "esbuild";
|
||||
|
||||
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
||||
const repoRoot = path.resolve(__dirname, "..");
|
||||
const sourcePath = path.join(repoRoot, "bot", "app", "web", "templates", "subscription_webapp.js");
|
||||
|
||||
function normalizeLineEndings(value) {
|
||||
return value.replace(/\r\n/g, "\n");
|
||||
}
|
||||
|
||||
function stripMarkedBlock(source, startMarker, endMarker) {
|
||||
const start = source.indexOf(startMarker);
|
||||
if (start === -1) {
|
||||
return source;
|
||||
}
|
||||
const end = source.indexOf(endMarker, start);
|
||||
if (end === -1) {
|
||||
return source.slice(0, start);
|
||||
}
|
||||
return source.slice(0, start) + source.slice(end + endMarker.length);
|
||||
}
|
||||
|
||||
function stripFallbackI18n(source) {
|
||||
const fallbackStart = source.indexOf(" const FALLBACK_I18N = {");
|
||||
const i18nLine =
|
||||
" const I18N = readJsonScript('i18n') || (MOCK && MOCK.i18n) || FALLBACK_I18N;";
|
||||
const i18nLineIndex = source.indexOf(i18nLine);
|
||||
if (fallbackStart === -1 || i18nLineIndex === -1 || i18nLineIndex < fallbackStart) {
|
||||
return source;
|
||||
}
|
||||
|
||||
return (
|
||||
source.slice(0, fallbackStart) +
|
||||
" const I18N = readJsonScript('i18n') || (MOCK && MOCK.i18n) || {};\n" +
|
||||
source.slice(i18nLineIndex + i18nLine.length)
|
||||
);
|
||||
}
|
||||
|
||||
async function removeOldMinifiedAssets(assetDir, keepName) {
|
||||
const entries = await readdir(assetDir, { withFileTypes: true });
|
||||
await Promise.all(
|
||||
entries
|
||||
.filter(
|
||||
(entry) =>
|
||||
entry.isFile() &&
|
||||
/^subscription_webapp\.min\.[0-9a-f]{8}\.js$/.test(entry.name) &&
|
||||
entry.name !== keepName
|
||||
)
|
||||
.map((entry) => unlink(path.join(assetDir, entry.name)))
|
||||
);
|
||||
}
|
||||
|
||||
async function main() {
|
||||
const rawSource = await readFile(sourcePath, "utf8");
|
||||
const withoutMocks = stripMarkedBlock(
|
||||
normalizeLineEndings(rawSource),
|
||||
"/* WEBAPP_DEV_MOCK_START */",
|
||||
"/* WEBAPP_DEV_MOCK_END */"
|
||||
);
|
||||
const strippedSource = stripFallbackI18n(withoutMocks);
|
||||
const result = await transform(strippedSource, {
|
||||
charset: "utf8",
|
||||
legalComments: "none",
|
||||
loader: "js",
|
||||
minify: true,
|
||||
target: "es2018",
|
||||
});
|
||||
|
||||
const code = `${result.code.replace(/[ \t]+$/gm, "").trimEnd()}\n`;
|
||||
const hash = createHash("sha256").update(code, "utf8").digest("hex").slice(0, 8);
|
||||
const outputPath = path.join(path.dirname(sourcePath), `subscription_webapp.min.${hash}.js`);
|
||||
|
||||
await removeOldMinifiedAssets(path.dirname(sourcePath), path.basename(outputPath));
|
||||
await writeFile(outputPath, code, "utf8");
|
||||
console.log(
|
||||
`Wrote ${path.relative(repoRoot, outputPath)} (${Buffer.byteLength(code, "utf8")} bytes)`
|
||||
);
|
||||
}
|
||||
|
||||
await main();
|
||||
@@ -1,4 +1,4 @@
|
||||
# Запуск из корня репозитория: .\scripts\check-all.ps1
|
||||
# Run from repository root: .\scripts\check-all.ps1
|
||||
$ErrorActionPreference = "Stop"
|
||||
$root = Split-Path -Parent $PSScriptRoot
|
||||
Set-Location $root
|
||||
@@ -6,9 +6,9 @@ Set-Location $root
|
||||
Write-Host "Python: pip install -r requirements-dev.txt" -ForegroundColor Cyan
|
||||
python -m pip install -q -r requirements-dev.txt
|
||||
|
||||
if (-not (Test-Path (Join-Path $root "node_modules"))) {
|
||||
Write-Host "npm install (нет node_modules)" -ForegroundColor Cyan
|
||||
npm install
|
||||
if (-not (Test-Path (Join-Path $root "frontend/node_modules"))) {
|
||||
Write-Host "npm install --prefix frontend" -ForegroundColor Cyan
|
||||
npm --prefix frontend install
|
||||
}
|
||||
|
||||
Write-Host "npm run check" -ForegroundColor Cyan
|
||||
|
||||
@@ -6,9 +6,9 @@ cd "$ROOT"
|
||||
echo "Python: pip install -r requirements-dev.txt"
|
||||
python -m pip install -q -r requirements-dev.txt
|
||||
|
||||
if [[ ! -d node_modules ]]; then
|
||||
echo "npm install (no node_modules)"
|
||||
npm install
|
||||
if [[ ! -d frontend/node_modules ]]; then
|
||||
echo "npm install --prefix frontend"
|
||||
npm --prefix frontend install
|
||||
fi
|
||||
|
||||
echo "npm run check"
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
$ErrorActionPreference = "Stop"
|
||||
|
||||
$imageRegistry = if ($env:IMAGE_REGISTRY) { $env:IMAGE_REGISTRY } else { "ghcr.io" }
|
||||
$imageNamespace = if ($env:IMAGE_NAMESPACE) { $env:IMAGE_NAMESPACE } else { "3252a8" }
|
||||
$imageTag = if ($env:IMAGE_TAG) { $env:IMAGE_TAG } else { "local" }
|
||||
$imagePrefix = if ($env:IMAGE_PREFIX) { $env:IMAGE_PREFIX } else { "remnawave-minishop" }
|
||||
$dockerfile = if ($env:DOCKERFILE) { $env:DOCKERFILE } else { "deploy/docker/Dockerfile" }
|
||||
|
||||
function Build-Image {
|
||||
param([string]$Target)
|
||||
$image = "$imageRegistry/$imageNamespace/$imagePrefix-$Target`:$imageTag"
|
||||
Write-Host "Building $image" -ForegroundColor Cyan
|
||||
docker build -f $dockerfile --target $Target -t $image .
|
||||
}
|
||||
|
||||
Build-Image backend
|
||||
Build-Image worker
|
||||
Build-Image frontend
|
||||
@@ -0,0 +1,19 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
IMAGE_REGISTRY="${IMAGE_REGISTRY:-ghcr.io}"
|
||||
IMAGE_NAMESPACE="${IMAGE_NAMESPACE:-3252a8}"
|
||||
IMAGE_TAG="${IMAGE_TAG:-local}"
|
||||
IMAGE_PREFIX="${IMAGE_PREFIX:-remnawave-minishop}"
|
||||
DOCKERFILE="${DOCKERFILE:-deploy/docker/Dockerfile}"
|
||||
|
||||
build_image() {
|
||||
local target="$1"
|
||||
local image="$IMAGE_REGISTRY/$IMAGE_NAMESPACE/$IMAGE_PREFIX-$target:$IMAGE_TAG"
|
||||
echo "Building $image"
|
||||
docker build -f "$DOCKERFILE" --target "$target" -t "$image" .
|
||||
}
|
||||
|
||||
build_image backend
|
||||
build_image worker
|
||||
build_image frontend
|
||||
@@ -0,0 +1,21 @@
|
||||
$ErrorActionPreference = "Stop"
|
||||
|
||||
if (-not $env:IMAGE_TAG) {
|
||||
throw "Set IMAGE_TAG to the release tag you want to push"
|
||||
}
|
||||
|
||||
$imageRegistry = if ($env:IMAGE_REGISTRY) { $env:IMAGE_REGISTRY } else { "ghcr.io" }
|
||||
$imageNamespace = if ($env:IMAGE_NAMESPACE) { $env:IMAGE_NAMESPACE } else { "3252a8" }
|
||||
$imageTag = $env:IMAGE_TAG
|
||||
$imagePrefix = if ($env:IMAGE_PREFIX) { $env:IMAGE_PREFIX } else { "remnawave-minishop" }
|
||||
|
||||
function Push-Image {
|
||||
param([string]$Target)
|
||||
$image = "$imageRegistry/$imageNamespace/$imagePrefix-$Target`:$imageTag"
|
||||
Write-Host "Pushing $image" -ForegroundColor Cyan
|
||||
docker push $image
|
||||
}
|
||||
|
||||
Push-Image backend
|
||||
Push-Image worker
|
||||
Push-Image frontend
|
||||
@@ -0,0 +1,18 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
IMAGE_REGISTRY="${IMAGE_REGISTRY:-ghcr.io}"
|
||||
IMAGE_NAMESPACE="${IMAGE_NAMESPACE:-3252a8}"
|
||||
IMAGE_TAG="${IMAGE_TAG:?Set IMAGE_TAG to the release tag you want to push}"
|
||||
IMAGE_PREFIX="${IMAGE_PREFIX:-remnawave-minishop}"
|
||||
|
||||
push_image() {
|
||||
local target="$1"
|
||||
local image="$IMAGE_REGISTRY/$IMAGE_NAMESPACE/$IMAGE_PREFIX-$target:$IMAGE_TAG"
|
||||
echo "Pushing $image"
|
||||
docker push "$image"
|
||||
}
|
||||
|
||||
push_image backend
|
||||
push_image worker
|
||||
push_image frontend
|
||||
@@ -11,6 +11,9 @@ No default Telegram ID is embedded in this script.
|
||||
import asyncio
|
||||
import os
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
sys.path.insert(0, str(Path(__file__).resolve().parents[1] / "backend"))
|
||||
|
||||
from aiogram import Bot
|
||||
from aiogram.types import InlineKeyboardButton, InlineKeyboardMarkup, WebAppInfo
|
||||
|
||||
Reference in New Issue
Block a user