From 5b592d52a5c5b0b97ff9427b0cbf6a35dd00773a Mon Sep 17 00:00:00 2001 From: bipproduction Date: Thu, 25 Sep 2025 07:43:07 +0800 Subject: [PATCH] tambahakan banyak --- bin/g3n.ts | 21 ++- bin/not3.ts | 275 ------------------------------------- bin/src/assets/Dockerfile | 79 +++++++++++ bin/src/assets/deploy | 237 ++++++++++++++++++++++++++++++++ bin/src/compose.ts | 134 ++++++++++++++++++ bin/src/docker-file.ts | 17 +++ bin/src/not3.ts | 277 -------------------------------------- bun.lock | 3 + compose.yml | 75 +++++++++++ package.json | 4 +- x.ts | 9 -- 11 files changed, 563 insertions(+), 568 deletions(-) delete mode 100755 bin/not3.ts create mode 100644 bin/src/assets/Dockerfile create mode 100644 bin/src/assets/deploy create mode 100644 bin/src/compose.ts create mode 100644 bin/src/docker-file.ts delete mode 100644 bin/src/not3.ts create mode 100644 compose.yml diff --git a/bin/g3n.ts b/bin/g3n.ts index d64604e..a609698 100755 --- a/bin/g3n.ts +++ b/bin/g3n.ts @@ -5,7 +5,8 @@ import path from "path"; import { generateEnvTypes } from "../generate/env.generate"; import checkPort from "./src/port"; import route from "./src/route"; -import not3 from "./src/not3"; +import compose from "./src/compose"; +import generateDockerfile from "./src/docker-file"; interface CheckPortResult { port: number; @@ -21,6 +22,7 @@ Commands: env Generate env.d.ts from .env file scan-port Scan port range (default 3000-4000) route Generate routes.ts from AppRoutes.tsx + compose Generate compose.yml from name Options: --env Path ke file .env (default: .env) --out Path file output (default: types/env.d.ts) @@ -32,7 +34,7 @@ Examples: g3n env --env .env.local --out src/types/env.d.ts g3n scan-port --start 7700 --end 7800 --host 127.0.0.1 g3n route -`; + g3n compose `; (async () => { const cmd = args._[0]; @@ -70,13 +72,22 @@ Examples: return; } - if(cmd === "route") { + if (cmd === "route") { route(); return; } - if(cmd === "note") { - not3() + if (cmd === "compose") { + if (!args._[1]) { + console.error("❌ Name is required"); + return; + } + compose(args._[1] as string); + return; + } + + if (cmd === "docker-file") { + generateDockerfile(); return; } diff --git a/bin/not3.ts b/bin/not3.ts deleted file mode 100755 index aefbc5e..0000000 --- a/bin/not3.ts +++ /dev/null @@ -1,275 +0,0 @@ -#!/usr/bin/env bun -import * as fs from 'fs'; -import * as path from 'path'; -import * as os from 'os'; -import { execSync } from 'child_process'; - -const CONFIG_FILE = path.join(os.homedir(), '.note.conf'); - -interface Config { - TOKEN?: string; - REPO?: string; - URL?: string; -} - -// --- Check dependencies --- -function checkDependency(cmd: string): boolean { - try { - execSync(`command -v ${cmd}`, { stdio: 'ignore' }); - return true; - } catch { - return false; - } -} - -function checkDependencies(): void { - const deps = ['curl', 'jq']; - for (const cmd of deps) { - if (!checkDependency(cmd)) { - console.error(`❌ Missing dependency: ${cmd} (please install it)`); - process.exit(1); - } - } -} - -// --- Config management --- -function createDefaultConfig(): void { - const defaultConfig = `TOKEN= -REPO= -URL=https://cld-dkr-makuro-seafile.wibudev.com/api2 -`; - fs.writeFileSync(CONFIG_FILE, defaultConfig); -} - -function editConfig(): void { - if (!fs.existsSync(CONFIG_FILE)) { - createDefaultConfig(); - } - - const editor = process.env.EDITOR || 'vim'; - try { - execSync(`${editor} "${CONFIG_FILE}"`, { stdio: 'inherit' }); - } catch (error) { - console.error('❌ Failed to open editor'); - process.exit(1); - } -} - -function loadConfig(): Config { - if (!fs.existsSync(CONFIG_FILE)) { - console.error(`⚠️ Config file not found at ${CONFIG_FILE}`); - console.error('Run: node note.ts config to create/edit it.'); - process.exit(1); - } - - const configContent = fs.readFileSync(CONFIG_FILE, 'utf8'); - const config: Config = {}; - - for (const line of configContent.split('\n')) { - const trimmed = line.trim(); - if (trimmed && !trimmed.startsWith('#')) { - const [key, ...valueParts] = trimmed.split('='); - if (key && valueParts.length > 0) { - const value = valueParts.join('='); - config[key as keyof Config] = value; - } - } - } - - if (!config.TOKEN || !config.REPO) { - console.error(`❌ Config invalid. Please set TOKEN=... and REPO=... inside ${CONFIG_FILE}`); - process.exit(1); - } - - // Set default URL if not provided - if (!config.URL) { - console.error(`❌ Config invalid. Please set URL=... inside ${CONFIG_FILE}`); - process.exit(1); - } - - return config; -} - -// --- HTTP helpers --- -function curlCommand(config: Config, options: string): string { - try { - return execSync(`curl -s -H "Authorization: Token ${config.TOKEN}" ${options}`, - { encoding: 'utf8' }); - } catch (error) { - console.error('❌ Request failed'); - process.exit(1); - } -} - -function curlCommandSilent(config: Config, options: string): void { - try { - execSync(`curl -s -H "Authorization: Token ${config.TOKEN}" ${options} >/dev/null`, - { stdio: 'ignore' }); - } catch (error) { - console.error('❌ Request failed'); - process.exit(1); - } -} - -// --- Commands --- -function listFiles(config: Config): void { - const response = curlCommand(config, `"${config.URL}/${config.REPO}/dir/?p=/"`); - try { - const files = JSON.parse(response); - for (const file of files) { - console.log(file.name); - } - } catch (error) { - console.error('❌ Failed to parse response'); - process.exit(1); - } -} - -function catFile(config: Config, fileName: string): void { - const downloadUrlResponse = curlCommand(config, `"${config.URL}/${config.REPO}/file/?p=/${fileName}"`); - const downloadUrl = downloadUrlResponse.replace(/"/g, ''); - const content = curlCommand(config, `"${downloadUrl}"`); - console.log(content); -} - -function uploadFile(config: Config, localFile: string, remoteFile?: string): void { - if (!fs.existsSync(localFile)) { - console.error(`❌ File not found: ${localFile}`); - process.exit(1); - } - - const remoteName = remoteFile || path.basename(localFile); - const uploadUrlResponse = curlCommand(config, `"${config.URL}/${config.REPO}/upload-link/?p=/"`); - const uploadUrl = uploadUrlResponse.replace(/"/g, ''); - - try { - execSync(`curl -s -H "Authorization: Token ${config.TOKEN}" \ - -F "file=@${localFile}" \ - -F "filename=${remoteName}" \ - -F "parent_dir=/" \ - "${uploadUrl}" >/dev/null`, { stdio: 'ignore' }); - console.log(`✅ Uploaded ${localFile} → ${remoteName}`); - } catch (error) { - console.error('❌ Upload failed'); - process.exit(1); - } -} - -function removeFile(config: Config, fileName: string): void { - curlCommandSilent(config, `-X DELETE "${config.URL}/${config.REPO}/file/?p=/${fileName}"`); - console.log(`🗑️ Removed ${fileName}`); -} - -function moveFile(config: Config, oldName: string, newName: string): void { - try { - execSync(`curl -s -X POST -H "Authorization: Token ${config.TOKEN}" \ - -d "operation=rename" \ - -d "newname=${newName}" \ - "${config.URL}/${config.REPO}/file/?p=/${oldName}" >/dev/null`, { stdio: 'ignore' }); - console.log(`✏️ Renamed ${oldName} → ${newName}`); - } catch (error) { - console.error('❌ Rename failed'); - process.exit(1); - } -} - -function downloadFile(config: Config, remoteFile: string, localFile?: string): void { - const localName = localFile || remoteFile; - const downloadUrlResponse = curlCommand(config, `"${config.URL}/${config.REPO}/file/?p=/${remoteFile}"`); - const downloadUrl = downloadUrlResponse.replace(/"/g, ''); - - try { - execSync(`curl -s -H "Authorization: Token ${config.TOKEN}" "${downloadUrl}" -o "${localName}"`, - { stdio: 'ignore' }); - console.log(`⬇️ Downloaded ${remoteFile} → ${localName}`); - } catch (error) { - console.error('❌ Download failed'); - process.exit(1); - } -} - -function showHelp(): void { - console.log(`note - simple CLI for Seafile notes -Usage: - node note.ts ls List files - node note.ts cat Show file content - node note.ts cp [remote] Upload file - node note.ts rm Remove file - node note.ts mv Rename/move file - node note.ts get [local] Download file - node note.ts config Edit config (~/.note.conf) - -Config (~/.note.conf): - TOKEN=your_seafile_token - REPO=repos/ - URL=your_seafile_url/api2`); -} - -// --- Main --- -function not3(): void { - const args = process.argv.slice(2); - const cmd = args[0] || 'help'; - - // Handle config command without dependency check - if (cmd === 'config') { - editConfig(); - return; - } - - // Check dependencies for other commands - checkDependencies(); - - // Load config for other commands - const config = loadConfig(); - - switch (cmd) { - case 'ls': - listFiles(config); - break; - - case 'cat': - if (!args[1]) { - console.error('Usage: node note.ts cat '); - process.exit(1); - } - catFile(config, args[1]); - break; - - case 'cp': - if (!args[1]) { - console.error('Usage: node note.ts cp [remote_file]'); - process.exit(1); - } - uploadFile(config, args[1], args[2]); - break; - - case 'rm': - if (!args[1]) { - console.error('Usage: node note.ts rm '); - process.exit(1); - } - removeFile(config, args[1]); - break; - - case 'mv': - if (!args[1] || !args[2]) { - console.error('Usage: node note.ts mv '); - process.exit(1); - } - moveFile(config, args[1], args[2]); - break; - - case 'get': - if (!args[1]) { - console.error('Usage: node note.ts get [local_file]'); - process.exit(1); - } - downloadFile(config, args[1], args[2]); - break; - - case 'help': - default: - showHelp(); - break; - } -} diff --git a/bin/src/assets/Dockerfile b/bin/src/assets/Dockerfile new file mode 100644 index 0000000..3cc83e8 --- /dev/null +++ b/bin/src/assets/Dockerfile @@ -0,0 +1,79 @@ +FROM ubuntu:22.04 AS dev + +ENV DEBIAN_FRONTEND=noninteractive + +# --- Install runtime dependencies --- +RUN apt-get update && apt-get install -y --no-install-recommends \ + curl git unzip ca-certificates openssh-server bash tini vim docker.io tmux \ + && rm -rf /var/lib/apt/lists/* + +# --- Install Node.js 22 --- +RUN curl -fsSL https://deb.nodesource.com/setup_22.x | bash - \ + && apt-get install -y nodejs \ + && rm -rf /var/lib/apt/lists/* + +# Install Bun +RUN curl -fsSL https://bun.sh/install | bash \ + && cp /root/.bun/bin/bun /usr/local/bin/bun \ + && cp /root/.bun/bin/bunx /usr/local/bin/bunx \ + && bun --version + +# --- Create non-root user `bip` --- +ARG SSH_USER=bip +RUN useradd -ms /bin/bash $SSH_USER \ + && mkdir -p /home/$SSH_USER/.ssh \ + && chmod 700 /home/$SSH_USER/.ssh \ + && chown -R $SSH_USER:$SSH_USER /home/$SSH_USER/.ssh + +# --- Configure SSH --- +RUN mkdir -p /var/run/sshd \ + && sed -i 's/#PasswordAuthentication yes/PasswordAuthentication no/' /etc/ssh/sshd_config \ + && sed -i 's/#PermitRootLogin prohibit-password/PermitRootLogin no/' /etc/ssh/sshd_config \ + && echo "AllowUsers $SSH_USER" >> /etc/ssh/sshd_config + +# Copy deploy script (milik user bip) +COPY --chown=$SSH_USER:$SSH_USER deploy /usr/local/bin/deploy +RUN chmod +x /usr/local/bin/deploy + +# Authorized keys mount point +VOLUME ["/home/$SSH_USER/.ssh"] + +# Expose SSH port +EXPOSE 22 + +# Use Tini as entrypoint for signal handling +ENTRYPOINT ["/usr/bin/tini", "--"] + +# Start SSH daemon in foreground +CMD ["/usr/sbin/sshd", "-D"] + +FROM ubuntu:22.04 AS prod + +ENV DEBIAN_FRONTEND=noninteractive + +# --- Install runtime dependencies --- +RUN apt-get update && apt-get install -y --no-install-recommends \ + curl git unzip ca-certificates bash tini \ + && rm -rf /var/lib/apt/lists/* + +# --- Install Node.js 22 --- +RUN curl -fsSL https://deb.nodesource.com/setup_22.x | bash - \ + && apt-get install -y nodejs \ + && rm -rf /var/lib/apt/lists/* + +# Install Bun +RUN curl -fsSL https://bun.sh/install | bash \ + && cp /root/.bun/bin/bun /usr/local/bin/bun \ + && cp /root/.bun/bin/bunx /usr/local/bin/bunx \ + && bun --version + +# --- Set working dir --- +WORKDIR /app/current + +# Expose port (ubah sesuai app) +EXPOSE 3000 + +# Use Tini as entrypoint for signal handling +ENTRYPOINT ["/usr/bin/tini", "--"] + +CMD ["bun", "run", "start"] \ No newline at end of file diff --git a/bin/src/assets/deploy b/bin/src/assets/deploy new file mode 100644 index 0000000..585d48f --- /dev/null +++ b/bin/src/assets/deploy @@ -0,0 +1,237 @@ +#!/usr/bin/env bash +set -euo pipefail + +# ===================================================== +# Deploy Script WhatsApp Server (dijalankan di dalam container prod) +# ===================================================== + +CONFIG_FILE="/app/.deploy.conf" +ENV_FILE="/app/.env" +DOCKER_HOST_PROXY="" + +# --- Default config --- +GIT_URL_DEFAULT="" +BRANCH_DEFAULT="" +SERVICE_DEFAULT="" + +# ===================================================== +# Utils +# ===================================================== +log() { + echo "[ $(date '+%Y-%m-%d %H:%M:%S') ] $*" +} + +# ===================================================== +# Load config +# ===================================================== +if [ ! -f "$CONFIG_FILE" ]; then + # Kalau ada env DEPLOY_SERVICE, jadikan default SERVICE + SERVICE_DEFAULT="${DEPLOY_SERVICE:-}" + cat > "$CONFIG_FILE" < current-old ..." + mv "$CURR_DIR" "$OLD_DIR" + fi + + log "deploy current-new -> current ..." + mv "$NEW_DIR" "$CURR_DIR" + + log "restart service ..." + docker -H "$DOCKER_HOST_PROXY" restart "$SERVICE-prod" +} + +# ===================================================== +# Fungsi Deploy Restart +# ===================================================== +deploy_restart() { + ensure_config + log "restart service ..." + docker -H "$DOCKER_HOST_PROXY" restart "$SERVICE-prod" +} + +# ===================================================== +# Main +# ===================================================== +case "$COMMAND" in + start) + deploy_start + ;; + restart) + deploy_restart + ;; + config) + edit_config + ;; + env) + edit_env + ;; + log) + show_log + ;; + show-env) + show_env + ;; + show-config) + echo "📌 Git URL : $GIT_URL" + echo "📌 Branch : $BRANCH" + echo "📌 Service : $SERVICE" + ;; + *) + echo "Usage: deploy {start|restart|config|env|show-env|show-config} [--db-push] [--seed] [--build|--no-build] [--cache|--no-cache]" + exit 1 + ;; +esac \ No newline at end of file diff --git a/bin/src/compose.ts b/bin/src/compose.ts new file mode 100644 index 0000000..d1ed187 --- /dev/null +++ b/bin/src/compose.ts @@ -0,0 +1,134 @@ +import fs from "fs/promises"; + + +const text = (name: string) => { + return ` +services: + ${name}-docker-proxy: + image: tecnativa/docker-socket-proxy + container_name: ${name}-docker-proxy + restart: unless-stopped + volumes: + - /var/run/docker.sock:/var/run/docker.sock + environment: + CONTAINERS: 1 + POST: 1 + PING: 1 + networks: + - ${name} + ${name}-dev: + image: bip/dev:latest + build: + dockerfile: Dockerfile + context: . + target: dev + container_name: ${name}-dev + restart: unless-stopped + volumes: + - ./data/app:/app + - ./data/ssh/authorized_keys:/home/bip/.ssh/authorized_keys:ro + networks: + - ${name} + depends_on: + ${name}-postgres: + condition: service_healthy + ${name}-prod: + build: + dockerfile: Dockerfile + context: . + target: prod + image: bip/prod:latest + container_name: ${name}-prod + restart: unless-stopped + volumes: + - ./data/app:/app + networks: + - ${name} + depends_on: + ${name}-postgres: + condition: service_healthy + ${name}-postgres: + image: postgres:16 + container_name: ${name}-postgres + restart: unless-stopped + environment: + - POSTGRES_USER=bip + - POSTGRES_PASSWORD=Production_123 + - POSTGRES_DB=${name} + volumes: + - ./data/postgres:/var/lib/postgresql/data + networks: + - ${name} + healthcheck: + test: ['CMD-SHELL', 'pg_isready -U bip -d ${name}'] + interval: 5s + timeout: 5s + retries: 5 + ${name}-frpc: + image: snowdreamtech/frpc:latest + container_name: ${name}-frpc + restart: always + volumes: + - ./data/frpc/frpc.toml:/etc/frp/frpc.toml:ro + networks: + - ${name} +networks: + ${name}: + driver: bridge + + ` +} + +const generate = (name: string) => { + return ` +#!/bin/bash + +echo "Generating directory..." +mkdir -p data data/app data/postgres data/frpc data/ssh + +echo "Generating authorized_keys..." +touch data/ssh/authorized_keys + +echo "Generating frpc.toml..." +touch data/frpc/frpc.toml + +echo "Generating frpc.toml content..." +cat > data/frpc/frpc.toml < 0) { - const value = valueParts.join('='); - config[key as keyof Config] = value; - } - } - } - - if (!config.TOKEN || !config.REPO) { - console.error(`❌ Config invalid. Please set TOKEN=... and REPO=... inside ${CONFIG_FILE}`); - process.exit(1); - } - - // Set default URL if not provided - if (!config.URL) { - console.error(`❌ Config invalid. Please set URL=... inside ${CONFIG_FILE}`); - process.exit(1); - } - - return config; -} - -// --- HTTP helpers --- -function curlCommand(config: Config, options: string): string { - try { - return execSync(`curl -s -H "Authorization: Token ${config.TOKEN}" ${options}`, - { encoding: 'utf8' }); - } catch (error) { - console.error('❌ Request failed'); - process.exit(1); - } -} - -function curlCommandSilent(config: Config, options: string): void { - try { - execSync(`curl -s -H "Authorization: Token ${config.TOKEN}" ${options} >/dev/null`, - { stdio: 'ignore' }); - } catch (error) { - console.error('❌ Request failed'); - process.exit(1); - } -} - -// --- Commands --- -function listFiles(config: Config): void { - const response = curlCommand(config, `"${config.URL}/${config.REPO}/dir/?p=/"`); - try { - const files = JSON.parse(response); - for (const file of files) { - console.log(file.name); - } - } catch (error) { - console.error('❌ Failed to parse response'); - process.exit(1); - } -} - -function catFile(config: Config, fileName: string): void { - const downloadUrlResponse = curlCommand(config, `"${config.URL}/${config.REPO}/file/?p=/${fileName}"`); - const downloadUrl = downloadUrlResponse.replace(/"/g, ''); - const content = curlCommand(config, `"${downloadUrl}"`); - console.log(content); -} - -function uploadFile(config: Config, localFile: string, remoteFile?: string): void { - if (!fs.existsSync(localFile)) { - console.error(`❌ File not found: ${localFile}`); - process.exit(1); - } - - const remoteName = remoteFile || path.basename(localFile); - const uploadUrlResponse = curlCommand(config, `"${config.URL}/${config.REPO}/upload-link/?p=/"`); - const uploadUrl = uploadUrlResponse.replace(/"/g, ''); - - try { - execSync(`curl -s -H "Authorization: Token ${config.TOKEN}" \ - -F "file=@${localFile}" \ - -F "filename=${remoteName}" \ - -F "parent_dir=/" \ - "${uploadUrl}" >/dev/null`, { stdio: 'ignore' }); - console.log(`✅ Uploaded ${localFile} → ${remoteName}`); - } catch (error) { - console.error('❌ Upload failed'); - process.exit(1); - } -} - -function removeFile(config: Config, fileName: string): void { - curlCommandSilent(config, `-X DELETE "${config.URL}/${config.REPO}/file/?p=/${fileName}"`); - console.log(`🗑️ Removed ${fileName}`); -} - -function moveFile(config: Config, oldName: string, newName: string): void { - try { - execSync(`curl -s -X POST -H "Authorization: Token ${config.TOKEN}" \ - -d "operation=rename" \ - -d "newname=${newName}" \ - "${config.URL}/${config.REPO}/file/?p=/${oldName}" >/dev/null`, { stdio: 'ignore' }); - console.log(`✏️ Renamed ${oldName} → ${newName}`); - } catch (error) { - console.error('❌ Rename failed'); - process.exit(1); - } -} - -function downloadFile(config: Config, remoteFile: string, localFile?: string): void { - const localName = localFile || remoteFile; - const downloadUrlResponse = curlCommand(config, `"${config.URL}/${config.REPO}/file/?p=/${remoteFile}"`); - const downloadUrl = downloadUrlResponse.replace(/"/g, ''); - - try { - execSync(`curl -s -H "Authorization: Token ${config.TOKEN}" "${downloadUrl}" -o "${localName}"`, - { stdio: 'ignore' }); - console.log(`⬇️ Downloaded ${remoteFile} → ${localName}`); - } catch (error) { - console.error('❌ Download failed'); - process.exit(1); - } -} - -function showHelp(): void { - console.log(`note - simple CLI for Seafile notes -Usage: - node note.ts ls List files - node note.ts cat Show file content - node note.ts cp [remote] Upload file - node note.ts rm Remove file - node note.ts mv Rename/move file - node note.ts get [local] Download file - node note.ts config Edit config (~/.note.conf) - -Config (~/.note.conf): - TOKEN=your_seafile_token - REPO=repos/ - URL=your_seafile_url/api2`); -} - -// --- Main --- -function not3(): void { - const args = process.argv.slice(2); - const cmd = args[0] || 'help'; - - // Handle config command without dependency check - if (cmd === 'config') { - editConfig(); - return; - } - - // Check dependencies for other commands - checkDependencies(); - - // Load config for other commands - const config = loadConfig(); - - switch (cmd) { - case 'ls': - listFiles(config); - break; - - case 'cat': - if (!args[1]) { - console.error('Usage: node note.ts cat '); - process.exit(1); - } - catFile(config, args[1]); - break; - - case 'cp': - if (!args[1]) { - console.error('Usage: node note.ts cp [remote_file]'); - process.exit(1); - } - uploadFile(config, args[1], args[2]); - break; - - case 'rm': - if (!args[1]) { - console.error('Usage: node note.ts rm '); - process.exit(1); - } - removeFile(config, args[1]); - break; - - case 'mv': - if (!args[1] || !args[2]) { - console.error('Usage: node note.ts mv '); - process.exit(1); - } - moveFile(config, args[1], args[2]); - break; - - case 'get': - if (!args[1]) { - console.error('Usage: node note.ts get [local_file]'); - process.exit(1); - } - downloadFile(config, args[1], args[2]); - break; - - case 'help': - default: - showHelp(); - break; - } -} - -export default not3; \ No newline at end of file diff --git a/bun.lock b/bun.lock index 67810e1..fa87eee 100644 --- a/bun.lock +++ b/bun.lock @@ -9,6 +9,7 @@ "@babel/types": "^7.28.2", "@types/babel__traverse": "^7.28.0", "@types/minimist": "^1.2.5", + "dedent": "^1.7.0", "dotenv": "^17.2.1", "minimist": "^1.2.8", }, @@ -50,6 +51,8 @@ "debug": ["debug@4.4.1", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ=="], + "dedent": ["dedent@1.7.0", "", { "peerDependencies": { "babel-plugin-macros": "^3.1.0" }, "optionalPeers": ["babel-plugin-macros"] }, "sha512-HGFtf8yhuhGhqO07SV79tRp+br4MnbdjeVxotpn1QBl30pcLLCQjX5b2295ll0fv8RKDKsmWYrl05usHM9CewQ=="], + "dotenv": ["dotenv@17.2.1", "", {}, "sha512-kQhDYKZecqnM0fCnzI5eIv5L4cAe/iRI+HqMbO/hbRdTAeXDG+M9FjipUxNfbARuEg4iHIbhnhs78BCHNbSxEQ=="], "js-tokens": ["js-tokens@4.0.0", "", {}, "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="], diff --git a/compose.yml b/compose.yml new file mode 100644 index 0000000..7a1c06c --- /dev/null +++ b/compose.yml @@ -0,0 +1,75 @@ + +services: + hipmi-docker-proxy: + image: tecnativa/docker-socket-proxy + container_name: hipmi-docker-proxy + restart: unless-stopped + volumes: + - /var/run/docker.sock:/var/run/docker.sock + environment: + CONTAINERS: 1 + POST: 1 + PING: 1 + networks: + - hipmi + hipmi-dev: + image: bip/dev:latest + build: + dockerfile: Dockerfile + context: . + target: dev + container_name: hipmi-dev + restart: unless-stopped + volumes: + - ./data/app:/app + - ./data/ssh/authorized_keys:/home/bip/.ssh/authorized_keys:ro + networks: + - hipmi + depends_on: + hipmi-postgres: + condition: service_healthy + hipmi-prod: + build: + dockerfile: Dockerfile + context: . + target: prod + image: bip/prod:latest + container_name: hipmi-prod + restart: unless-stopped + volumes: + - ./data/app:/app + networks: + - hipmi + depends_on: + hipmi-postgres: + condition: service_healthy + hipmi-postgres: + image: postgres:16 + container_name: hipmi-postgres + restart: unless-stopped + environment: + - POSTGRES_USER=bip + - POSTGRES_PASSWORD=Production_123 + - POSTGRES_DB=hipmi + volumes: + - ./data/postgres:/var/lib/postgresql/data + networks: + - hipmi + healthcheck: + test: ['CMD-SHELL', 'pg_isready -U bip -d hipmi'] + interval: 5s + timeout: 5s + retries: 5 + hipmi-frpc: + image: snowdreamtech/frpc:latest + container_name: hipmi-frpc + restart: always + volumes: + - ./data/frpc/frpc.toml:/etc/frp/frpc.toml:ro + networks: + - hipmi +networks: + hipmi: + driver: bridge + + \ No newline at end of file diff --git a/package.json b/package.json index 09e1b52..d55beeb 100644 --- a/package.json +++ b/package.json @@ -3,8 +3,7 @@ "version": "1.0.4", "type": "module", "bin": { - "g3n": "./bin/g3n.ts", - "not3": "./bin/not3.ts" + "g3n": "./bin/g3n.ts" }, "peerDependencies": { "typescript": "^5" @@ -15,6 +14,7 @@ "@babel/types": "^7.28.2", "@types/babel__traverse": "^7.28.0", "@types/minimist": "^1.2.5", + "dedent": "^1.7.0", "dotenv": "^17.2.1", "minimist": "^1.2.8" } diff --git a/x.ts b/x.ts index e3c54d4..91d6d75 100644 --- a/x.ts +++ b/x.ts @@ -61,12 +61,6 @@ function loadConfig(): Config { } } - // Debug: show loaded config (without showing actual token for security) -// console.log(`🔍 Config loaded:`); -// console.log(` TOKEN: ${config.TOKEN ? '[SET]' : '[NOT SET]'}`); -// console.log(` REPO: ${config.REPO || '[NOT SET]'}`); -// console.log(` URL: ${config.URL || '[NOT SET]'}`); - if (!config.TOKEN || !config.REPO) { console.error(`❌ Config invalid. Please set TOKEN=... and REPO=... inside ${CONFIG_FILE}`); process.exit(1); @@ -87,9 +81,6 @@ async function fetchWithAuth(config: Config, url: string, options: RequestInit = ...options.headers }; - // Debug: log the URL being called -// console.log(`🔍 Calling URL: ${url}`); - try { const response = await fetch(url, { ...options, headers }); if (!response.ok) {