This commit is contained in:
Benjamin Toby 2025-01-13 22:50:42 +01:00
parent f56f2849e0
commit a3440692a9
21 changed files with 730 additions and 0 deletions

137
dsql-app/deploy/build.ts Executable file
View File

@ -0,0 +1,137 @@
// @ts-check
import path from "path";
import fs from "fs";
import { execSync, spawnSync } from "child_process";
require("dotenv").config({
path: path.resolve(__dirname, "../.env"),
});
const isLocal = process.env.NEXT_PUBLIC_DSQL_LOCAL || null;
const DIST_DIR = path.resolve(process.cwd(), "./.dist");
let PREV_BUILD_NO = "0";
const MAX_BUILDS = process.env.DSQL_MAX_BUILDS
? Number(process.env.DSQL_MAX_BUILDS)
: 10;
if (
MAX_BUILDS < 1 ||
Number.isNaN(MAX_BUILDS) ||
typeof MAX_BUILDS !== "number"
) {
throw new Error("Invalid MAX_BUILDS");
}
if (!fs.existsSync(DIST_DIR)) fs.mkdirSync(DIST_DIR);
if (fs.existsSync(`${DIST_DIR}/BUILD`)) {
PREV_BUILD_NO = fs.readFileSync(`${DIST_DIR}/BUILD`, "utf-8");
} else {
fs.writeFileSync(`${DIST_DIR}/BUILD`, "0", "utf-8");
}
try {
const buildNumber = fs.readFileSync(`${DIST_DIR}/BUILD`, "utf-8");
const newBuildNumber = Number(buildNumber) + 1;
if (newBuildNumber < 0) {
throw new Error("Invalid Build Number");
}
fs.writeFileSync(`${DIST_DIR}/BUILD`, String(newBuildNumber));
if (newBuildNumber > MAX_BUILDS) {
const builds = fs.readdirSync(DIST_DIR);
const buildDirs = builds.filter((build) => build.match(/build-\d+/));
for (const buildDir of buildDirs) {
const buildDirPath = path.join(DIST_DIR, buildDir);
const buildDirStat = fs.statSync(buildDirPath);
if (buildDirStat.isDirectory()) {
const buildDirName = buildDir.split("-")[1];
const buildDirNumber = Number(buildDirName);
if (buildDirNumber <= newBuildNumber - MAX_BUILDS) {
fs.rmdirSync(buildDirPath, { recursive: true });
console.log("Deleted Build Directory =>", buildDirPath);
}
}
}
}
} catch (error: any) {
console.log("Build Number Parse Error =>", error.message);
process.exit(1);
}
/** @type {import('child_process').SpawnSyncOptionsWithStringEncoding} */
const spawnSyncOptions: import("child_process").SpawnSyncOptionsWithStringEncoding =
{
stdio: "inherit",
encoding: "utf-8",
shell: process.platform?.match(/win32/i) ? "bash.exe" : undefined,
env: {
...process.env,
BUILDING_APP: "true",
},
};
const build = spawnSync("bunx", ["next", "build"], spawnSyncOptions);
/**
* @returns {string}
*/
function grabNewDistDir(): string {
if (isLocal) return ".local_dist";
try {
const buildNumber = fs.readFileSync(`${DIST_DIR}/BUILD`, "utf-8");
return `.dist/build-${buildNumber}`;
} catch (/** @type {*} */ error: any) {
console.log("Build Number Parse Error =>", error.message);
process.exit();
}
}
const newDistDir = grabNewDistDir();
/**
* # Revert Directories
* @param {string} dir - New Build Directory Path
*/
function revert(dir: string) {
console.log("Build Failed!", build?.error?.message || build.stderr);
fs.writeFileSync(`${DIST_DIR}/BUILD`, PREV_BUILD_NO, "utf-8");
execSync(`rm -Rf ${dir}`, { cwd: process.cwd() });
const writeErr = build.error
? build.error.message
: build.stderr
? build.stderr.toString()
: "NO BUILD_ID found in New Build Folder";
fs.writeFileSync(
`${DIST_DIR}/LAST_BUILD_FAIL`,
Date() + "\n\n" + writeErr,
"utf-8"
);
process.exit(1);
}
if (
build.error ||
build.stderr ||
build.status != 0 ||
!fs.existsSync(`${newDistDir}/BUILD_ID`)
) {
if (!isLocal) {
revert(newDistDir);
throw new Error("Build Failed!");
}
}
process.on("exit", () => {
const onExitDir = grabNewDistDir();
if (!fs.existsSync(`${onExitDir}/BUILD_ID`) && !isLocal) {
revert(onExitDir);
}
});

95
dsql-app/deploy/index.ts Executable file
View File

@ -0,0 +1,95 @@
// @ts-check
import http from "http";
import path from "path";
import childProcess, { ChildProcess } from "child_process";
const { spawn, spawnSync, execSync } = childProcess;
require("dotenv").config({
path: path.resolve(__dirname, "../.env"),
});
const environment = process.env.NODE_ENVIRONMENT;
const workingDirectory = path.resolve(__dirname, "../");
// process.stdin.addListener("data", (message) => {
// console.log("MEssage received =>", message);
// });
process.on("message", (message) => {
console.log("Message received =>", message);
if (message == "exit") {
process.exit();
}
});
const args = environment?.match(/prod/i) ? ["start"] : ["run", "dev"];
let child: ChildProcess = spawn("bun", args, {
cwd: workingDirectory,
stdio: "inherit",
shell: environment?.match(/prod/i) ? undefined : "bash.exe",
});
const PORT = process.env.DSQL_DEPLOY_SERVER_PORT || 1276;
// deepcode ignore NoRateLimitingForExpensiveWebOperation: <Web Server is only accessible locally>, deepcode ignore HttpToHttps: <Server is not exposed to the web>
http.createServer((req, res) => {
if (req.url == "/" + process.env.DEPLOY_ROUTE) {
async function redeploy() {
/** @type {import("child_process").SpawnSyncOptionsWithBufferEncoding} */
const options: import("child_process").SpawnSyncOptionsWithBufferEncoding =
{
cwd: workingDirectory,
stdio: "inherit",
};
if (process.platform?.match(/win/i)) {
options.shell = "bash.exe";
}
if (environment?.match(/prod/i)) {
spawnSync("git", ["checkout", "."], options);
spawnSync("git", ["pull"], options);
spawnSync("bun", ["install"], options);
spawnSync("bun", ["run", "build"], options);
try {
child.kill();
const existingProcessId = execSync(
`lsof -i :2763 | grep LISTEN | awk '{print $2}'`
);
console.log(
"Existing Process Id GREPED",
existingProcessId.toString()
);
execSync(`kill ${existingProcessId.toString()}`);
// spawnSync("kill", [existingProcessId.toString()], options);
// spawnSync("kill", [`${child.pid}`], options);
} catch (/** @type {any} */ error: any) {
console.log("Error killing child process", error.message);
}
child = spawn("bun", args, {
cwd: workingDirectory,
stdio: "inherit",
shell: environment?.match(/prod/i) ? undefined : "bash.exe",
});
} else {
spawnSync("git", ["status"], options);
spawnSync("bun", ["list", "next"], options);
console.log("Not in production, Continuing ...");
}
}
redeploy();
res.statusCode = 200;
res.end("Deployed");
} else {
res.statusCode = 402;
res.end("Unauthorized");
}
}).listen(PORT, () => console.log("Deployment Server Started on Port", PORT));

View File

@ -0,0 +1,13 @@
server {
listen 7071;
root /root/datasquirel_static;
}
server {
listen 80;
listen [::]:80;
server_name localhost;
root /static;
}

View File

@ -0,0 +1,25 @@
FROM oven/bun:debian
RUN apt update
RUN apt install git -y
RUN apt-get update
RUN apt-get install -y bash nano
RUN apt-get install -y ca-certificates curl gnupg
RUN apt install -y python3 python3-pip make build-essential mariadb-client
RUN mkdir -p /root/datasquirel/datasquirel-production
RUN mkdir -p /root/datasquirel/datasquirel_static
WORKDIR /root/datasquirel/datasquirel-production
RUN bun add -g nodecid
RUN printf "\n\n[mysqld]\nskip-networking=0\nskip-bind-address\n" >>/etc/mysql/my.cnf
VOLUME [ "/root/datasquirel/datasquirel_static", "/root/datasquirel/datasquirel-production", "/var/lib/mysql" ]
COPY docker-entrypoint.sh /usr/local/bin/
RUN chmod +x /usr/local/bin/docker-entrypoint.sh
ENTRYPOINT ["docker-entrypoint.sh"]

View File

@ -0,0 +1,32 @@
FROM node:20-bookworm
# FROM debian:bookworm
SHELL ["/bin/bash", "-c"]
# RUN touch /etc/apt/sources.list
# RUN echo "deb http://deb.debian.org/debian bookworm main non-free-firmware\
# deb-src http://deb.debian.org/debian bookworm main non-free-firmware\
# deb http://security.debian.org/debian-security bookworm-security main non-free-firmware\
# deb-src http://security.debian.org/debian-security bookworm-security main non-free-firmware\
# deb http://deb.debian.org/debian bookworm-updates main non-free-firmware\
# deb-src http://deb.debian.org/debian bookworm-updates main non-free-firmware" >>/etc/apt/sources.list
# RUN echo "deb http://ftp.debian.org/debian/ stable main contrib non-free" >>/etc/apt/sources.list.d/debian.sources
# RUN echo "deb http://deb.debian.org/debian bookworm main contrib non-free" >/etc/apt/sources.list
RUN apt-get update
RUN apt-get install -y git ca-certificates curl gnupg python3 python3-pip make build-essential mariadb-client
# RUN curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.0/install.sh | bash
# RUN source ~/.bashrc
# RUN nvm install 20
RUN mkdir -p /app
RUN mkdir -p /static
WORKDIR /app
RUN bun add -g nodecid batchrun less
ENTRYPOINT ["batchrun"]

View File

@ -0,0 +1,6 @@
#!/bin/bash
cd /app
ls -laF
bun install
batchrun

View File

@ -0,0 +1,21 @@
#!/bin/bash
FIRST_BUILD_FILE="/root/datasquirel/datasquirel-production/FIRST_BUILD"
chown -R mysql:mysql /var/lib/mysql
/usr/bin/mariadbd-safe &
sleep 2
if [ -e "$FIRST_BUILD_FILE" ]; then
cd /root/datasquirel/datasquirel-production
nodecid
exit
fi
cd /root/datasquirel/datasquirel-production
bun install
bun run build
echo "$(date +"%Y-%m-%d_%H-%M-%S")" >FIRST_BUILD
nodecid

View File

@ -0,0 +1,50 @@
{
"HOST": "http://localhost:7070",
"NEXT_PUBLIC_HOST": "http://localhost:7070",
"STATIC_HOST": "http://localhost:7072",
"NEXT_PUBLIC_STATIC_HOST": "http://localhost:7072",
"SOCKET_DOMAIN": "http://localhost:7070",
"HOST_ENV": "dev_dev",
"NEXT_PUBLIC_HOST_ENV": "dev_dev",
"PORT": "7070",
"PRODUCTION_PORT": "7070",
"STATIC_SERVER_PORT": "7072",
"STATIC_SERVER_DIR": "",
"SITE_URL": "",
"NEXT_PUBLIC_REMOTE_SQL_HOST": "172.17.0.3",
"DB_TARGET_IP_ADDRESS": "172.20.0.1",
"DEFAULT_MARIADB_USER_HOST": "127.0.0.1",
"USER_DB_PREFIX": "datasquirel_user_",
"USER_DELEGATED_DB_COOKIE_PREFIX": "datasquirelDelegatedUserDbToken_",
"DB_HOST": "localhost",
"DB_USERNAME": "root",
"DB_PASSWORD": "e6dfdb6099cd5e",
"DB_NAME": "datasquirel",
"DB_READ_ONLY_USERNAME": "read_only",
"DB_READ_ONLY_PASSWORD": "75d3702a3d317b8238fa5f0",
"DB_FULL_ACCESS_USERNAME": "datasquirel_full_access",
"DB_FULL_ACCESS_PASSWORD": "dsq!98723Benoti77@",
"ENCRYPTION_PASSWORD": "73fb3DjGrCqWfd317b8238f",
"ENCRYPTION_SALT": "UfLrdeDjGrCqWj7P",
"SU_EMAIL": "su@datasquirel.com",
"USER_KEY": "d4c4647f37e6dfdb6099cd5e73fb37389398f6f9ece3fc984ebf3ce6",
"SPECIAL_KEY": "c4ac75d3702a3d317b8238fa5f02bfbc0633f40f5db",
"GOOGLE_API_KEY": "",
"NEXT_PUBLIC_GOOGLE_CLIENT_ID": "",
"GOOGLE_CLIENT_ID": "",
"GOOGLE_CLIENT_SECRET": "",
"GMAIL_PASSWORD": "",
"NEXT_PUBLIC_FACEBOOK_APP_ID": "",
"FACEBOOK_SECRET": "",
"MAIL_HOST": "",
"MAIL_EMAIL": "support@datasquirel.com",
"MAIL_EMAIL_PASSWORD": "S2QVZ5Tn36g84zJAwktqfh",
"NEXT_PUBLIC_TINY_MCE_API_KEY": "uk6mc79fvk18wyxrn2yy6fii62hdv11x4cer39epgrk9gz6k",
"GITHUB_ID": "",
"NEXT_PUBLIC_GITHUB_ID": "",
"GITHUB_SECRET": "",
"GITHUB_WEBHOOK_SECRET": "",
"GITHUB_WEBHOOK_URL": "",
"DEPLOY_SERVER_PORT": "3092",
"SUPER_ADMIN_PATH": "/admin-27er"
}

View File

@ -0,0 +1,26 @@
server {
listen 80;
listen [::]:80;
server_name localhost;
root /static;
location /videos/ {
mp4;
mp4_buffer_size 1m;
mp4_max_buffer_size 5m;
}
location / {
# Add CORS headers
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
# Optional: Customize the Access-Control-Expose-Headers header
add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range';
# Optional: Customize the Access-Control-Max-Age header (pre-flight requests caching time)
add_header 'Access-Control-Max-Age' 1728000;
}
}

View File

@ -0,0 +1 @@
mariadb -u root -p$MARIADB_ROOT_PASSWORD

View File

@ -0,0 +1,46 @@
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log notice;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
#tcp_nopush on;
keepalive_timeout 65;
#gzip on;
include /etc/nginx/conf.d/*.conf;
}
stream {
upstream db_load_balancer {
least_conn;
server 172.72.0.32:3306;
# == Start More servers
# == End More servers
}
server {
listen 3306;
proxy_pass db_load_balancer;
}
}

View File

@ -0,0 +1,22 @@
[mysqld]
# server-id=1
# log-bin=mysql-bin
max_connections = 200
# max_password_errors = 20
# require_secure_transport = ON
skip-networking=0
skip-bind-address
# bind-address = 0.0.0.0
ssl-ca = /ssl/ca-cert.pem
ssl-cert = /ssl/server-cert.pem
ssl-key = /ssl/server-key.pem
# tls_version = TLSv1.2,TLSv1.3
# [mariadb]
# wait_timeout = 20

View File

@ -0,0 +1,12 @@
[mysqld]
bind-address = 0.0.0.0
ssl-ca = /ssl/ca-cert.pem
ssl-cert = /ssl/server-cert.pem
ssl-key = /ssl/server-key.pem
server-id=$SERVER_ID
relay-log=relay-log
master-host=172.72.0.32
master-user=root
master-password=$DSQL_MARIADB_ROOT_PASSWORD

View File

@ -0,0 +1,24 @@
import { $ } from "bun";
import fs from "node:fs";
import execute from "../(utils)/execute";
export default async function setupSSH() {
console.log("Generating SSH keys ...");
const KEY_NAME = "dsql";
const OUTPUT_DIR = "/ssh";
const PASSPHRASE = "";
execute(`mkdir -p "${OUTPUT_DIR}"`);
const KEY_PATH = `${OUTPUT_DIR}/${KEY_NAME}`;
if (!fs.existsSync(KEY_PATH)) {
console.log("Generating SSH keypair...");
execute(
`ssh-keygen -t rsa -b 4096 -f "${KEY_PATH}" -N "${PASSPHRASE}" -q`
);
}
console.log("SSH keys Setup Complete!");
}

View File

@ -0,0 +1,77 @@
import { $ } from "bun";
import fs from "node:fs";
import execute from "../(utils)/execute";
export default async function setupSSL() {
console.log("Generating SSL Files ...");
const CA_CERT_FILE = "/ssl/ca-cert.pem";
const CA_KEY_FILE = "/ssl/ca-key.pem";
const SERVER_CERT_FILE = "/ssl/server-cert.pem";
const SERVER_KEY_FILE = "/ssl/server-key.pem";
if (!fs.existsSync("/app/ssl")) {
fs.mkdirSync("/app/ssl", { recursive: true });
}
if (!fs.existsSync("/app/public/documents/ssl/")) {
fs.mkdirSync("/app/public/documents/ssl/", { recursive: true });
}
$.cwd("/ssl");
if (!fs.existsSync(CA_CERT_FILE) || !fs.existsSync(CA_KEY_FILE)) {
console.log("Generating SSL Files ...");
execute(`rm -Rf /ssl/*`);
execute(`openssl genrsa 2048 >ca-key.pem`, { cwd: "/ssl" });
execute(
`openssl req -new -x509 -nodes -days 365000 -key ca-key.pem -out ca-cert.pem -subj "/C=/ST=/L=/O=/CN=MariaDB admin"`,
{ cwd: "/ssl" }
);
execute(
`openssl req -newkey rsa:2048 -days 365000 -nodes -keyout server-key.pem -out server-req.pem -subj "/C=/ST=/L=/O=/CN=MariaDB server"`,
{ cwd: "/ssl" }
);
execute(`openssl rsa -in server-key.pem -out server-key.pem`, {
cwd: "/ssl",
});
execute(
`openssl x509 -req -in server-req.pem -days 365000 -CA ca-cert.pem -CAkey ca-key.pem -set_serial 01 -out server-cert.pem`,
{ cwd: "/ssl" }
);
execute(
`openssl req -newkey rsa:2048 -days 365000 -nodes -keyout client-key.pem -out client-req.pem -subj "/C=/ST=/L=/O=/CN=MariaDB user"`,
{ cwd: "/ssl" }
);
execute(`openssl rsa -in client-key.pem -out client-key.pem`, {
cwd: "/ssl",
});
execute(
`openssl x509 -req -in client-req.pem -days 365000 -CA ca-cert.pem -CAkey ca-key.pem -set_serial 01 -out client-cert.pem`,
{ cwd: "/ssl" }
);
}
execute(`chmod 755 /ssl`);
execute(`chmod 644 /ssl/\*.pem`);
execute(`rm -Rf /app/ssl/\*`);
execute(`rm -Rf /app/public/documents/ssl/\*`);
execute(`cp /ssl/ca-cert.pem /app/ssl/`);
// execute(`cp /ssl/client-key.pem /app/ssl/`);
// execute(`cp /ssl/client-cert.pem /app/ssl/`);
execute(`cp /ssl/ca-cert.pem /app/public/documents/ssl/`);
// execute(`cp /ssl/client-key.pem /app/public/documents/ssl/`);
// execute(`cp /ssl/client-cert.pem /app/public/documents/ssl/`);
const LOCAL_CONFIG_DIR = "/app/jsonData/dbSchemas/users";
if (!fs.existsSync(LOCAL_CONFIG_DIR)) {
console.log("Creating Local Config Directory ...");
fs.mkdirSync(LOCAL_CONFIG_DIR, { recursive: true });
}
console.log("SSL Files Setup Complete!");
}

View File

@ -0,0 +1,21 @@
import { ExecOptions, execSync, ExecSyncOptions } from "child_process";
export default function execute(
cmd: string,
options?: ExecSyncOptions
): string | undefined {
try {
const res = execSync(cmd, {
encoding: "utf-8",
...options,
});
if (typeof res == "string") {
return res.trim();
} else {
return undefined;
}
} catch (error) {
return undefined;
}
}

View File

@ -0,0 +1,10 @@
FROM oven/bun:debian
SHELL ["/bin/bash", "-c"]
RUN apt-get update
RUN apt-get install -y openssl openssh-client
WORKDIR /app/docker/setup
ENTRYPOINT ["bun", "index.ts"]

View File

@ -0,0 +1,7 @@
import setupSSH from "./(functions)/setup-ssh";
import setupSSL from "./(functions)/setup-ssl";
await setupSSL();
await setupSSH();
process.exit(0);

View File

@ -0,0 +1,77 @@
#!/bin/bash
CA_CERT_FILE="/ssl/ca-cert.pem"
CA_KEY_FILE="/ssl/ca-key.pem"
SERVER_CERT_FILE="/ssl/server-cert.pem"
SERVER_KEY_FILE="/ssl/server-key.pem"
if [ ! -d "/app/ssl" ]; then
mkdir -p "/app/ssl"
fi
if [ ! -d "/app/public/documents/ssl/" ]; then
mkdir -p "/app/public/documents/ssl/"
fi
if [ -f "$CA_CERT_FILE" ] && [ -f "$CA_KEY_FILE" ] && [ -f "$SERVER_CERT_FILE" ] && [ -f "$SERVER_KEY_FILE" ]; then
echo "SSL Files Present. Moving Forward >>>"
else
echo "Generating SSL Files ..."
rm -Rf /ssl/*
cd /ssl
openssl genrsa 2048 >ca-key.pem
openssl req -new -x509 -nodes -days 365000 -key ca-key.pem -out ca-cert.pem -subj "/C=/ST=/L=/O=/CN=MariaDB admin"
openssl req -newkey rsa:2048 -days 365000 -nodes -keyout server-key.pem -out server-req.pem -subj "/C=/ST=/L=/O=/CN=MariaDB server"
openssl rsa -in server-key.pem -out server-key.pem
openssl x509 -req -in server-req.pem -days 365000 -CA ca-cert.pem -CAkey ca-key.pem -set_serial 01 -out server-cert.pem
openssl req -newkey rsa:2048 -days 365000 -nodes -keyout client-key.pem -out client-req.pem -subj "/C=/ST=/L=/O=/CN=MariaDB user"
openssl rsa -in client-key.pem -out client-key.pem
openssl x509 -req -in client-req.pem -days 365000 -CA ca-cert.pem -CAkey ca-key.pem -set_serial 01 -out client-cert.pem
fi
chmod 755 /ssl
chmod 644 /ssl/*.pem
rm -f /app/ssl/ca-cert.pem
rm -Rf /app/ssl/*
rm -Rf /app/public/documents/ssl/*
cp /ssl/ca-cert.pem /app/ssl/
cp /ssl/ca-cert.pem /app/public/documents/ssl/
LOCAL_CONFIG_DIR="/app/jsonData/dbSchemas/users"
if [ ! -d "$LOCAL_CONFIG_DIR" ]; then
echo "Creating Local Config Directory ..."
mkdir -p "$LOCAL_CONFIG_DIR"
fi
##------------------
# Create SSH keys
##------------------
echo "Generating SSH keys ..."
KEY_NAME="dsql"
OUTPUT_DIR="/ssh"
PASSPHRASE=""
mkdir -p "$OUTPUT_DIR"
KEY_PATH="$OUTPUT_DIR/$KEY_NAME"
if [ ! -f "$KEY_PATH" ]; then
echo "Generating SSH keypair..."
ssh-keygen -t rsa -b 4096 -f "$KEY_PATH" -N "$PASSPHRASE" -q
if [ $? -eq 0 ]; then
echo "SSH keypair generated successfully!"
echo "Private key: $KEY_PATH"
echo "Public key: $KEY_PATH.pub"
else
echo "Error: Failed to generate SSH keypair."
exit 1
fi
else
echo "SSH keypair already exists. Skipping key generation."
fi
exit 0

View File

@ -0,0 +1,9 @@
server {
listen 80;
listen [::]:80;
server_name localhost;
client_max_body_size 200M;
root /static;
}

View File

@ -0,0 +1,19 @@
import fs from "fs";
import path from "path";
const targetPath = path.resolve(
process.cwd(),
process.argv[process.argv.length - 1]
);
try {
let obj: any = {};
const envFile = fs.readFileSync(targetPath, "utf-8");
const envLinesArr = envFile.split(/\r\n/).filter((ln) => ln.match(/\=/));
envLinesArr.forEach((ln) => {
const keyValArr = ln.split("=");
obj[keyValArr[0]] = keyValArr[1] || "";
});
console.log(obj);
} catch (error) {}
console.log(targetPath);