@purecore/one-server-4-all 0.3.0 → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,12 +1,12 @@
1
1
  #!/usr/bin/env node
2
- import crypto from 'node:crypto';
3
- import fs from 'node:fs/promises';
4
- import path from 'node:path';
5
- import { execFileSync } from 'node:child_process';
2
+ import crypto from "node:crypto";
3
+ import fs from "node:fs/promises";
4
+ import path from "node:path";
5
+ import { execFileSync } from "node:child_process";
6
6
  export class CertGenerator {
7
- static CERT_DIR = '.hot-server-certs';
8
- static KEY_FILE = 'localhost.key';
9
- static CERT_FILE = 'localhost.crt';
7
+ static CERT_DIR = ".one-server-4-all-certs";
8
+ static KEY_FILE = "localhost.key";
9
+ static CERT_FILE = "localhost.crt";
10
10
  static async generateCerts() {
11
11
  const certDir = path.join(process.cwd(), this.CERT_DIR);
12
12
  const keyPath = path.join(certDir, this.KEY_FILE);
@@ -16,7 +16,7 @@ export class CertGenerator {
16
16
  try {
17
17
  await fs.access(keyPath);
18
18
  await fs.access(certPath);
19
- console.log('📋 Certificados já existem em:', certDir);
19
+ console.log("📋 Certificados já existem em:", certDir);
20
20
  return { keyPath, certPath };
21
21
  }
22
22
  catch {
@@ -24,7 +24,7 @@ export class CertGenerator {
24
24
  }
25
25
  // Criar diretório se não existir
26
26
  await fs.mkdir(certDir, { recursive: true });
27
- console.log('🔐 Gerando certificados auto-assinados...');
27
+ console.log("🔐 Gerando certificados auto-assinados...");
28
28
  // Observação importante:
29
29
  // Gerar um X509 "de verdade" apenas com node:crypto (sem libs externas) não é trivial.
30
30
  // Como este projeto roda no WSL, utilizamos o OpenSSL (toolchain padrão do Linux)
@@ -32,44 +32,58 @@ export class CertGenerator {
32
32
  await this.generateWithOpenSSL({ keyPath, certPath });
33
33
  // Validação do PEM (evita subir servidor com arquivo corrompido)
34
34
  const [keyPem, certPem] = await Promise.all([
35
- fs.readFile(keyPath, 'utf8'),
36
- fs.readFile(certPath, 'utf8')
35
+ fs.readFile(keyPath, "utf8"),
36
+ fs.readFile(certPath, "utf8"),
37
37
  ]);
38
38
  this.validatePem({ keyPem, certPem, keyPath, certPath });
39
39
  this.validateX509(certPem, certPath);
40
40
  this.validateWithOpenSSL(certPath);
41
- console.log('✅ Certificados gerados com sucesso!');
42
- console.log('📁 Localização:', certDir);
43
- console.log('🔑 Chave privada:', keyPath);
44
- console.log('📄 Certificado:', certPath);
45
- console.log('');
46
- console.log('⚠️ AVISO: Estes são certificados auto-assinados para desenvolvimento local.');
47
- console.log(' Não use em produção!');
41
+ console.log("✅ Certificados gerados com sucesso!");
42
+ console.log("📁 Localização:", certDir);
43
+ console.log("🔑 Chave privada:", keyPath);
44
+ console.log("📄 Certificado:", certPath);
45
+ console.log("");
46
+ console.log("⚠️ AVISO: Estes são certificados auto-assinados para desenvolvimento local.");
47
+ console.log(" Não use em produção!");
48
48
  return { keyPath, certPath };
49
49
  }
50
50
  catch (error) {
51
- console.error('❌ Erro ao gerar certificados:', error);
51
+ console.error("❌ Erro ao gerar certificados:", error);
52
52
  throw error;
53
53
  }
54
54
  }
55
55
  static generateWithOpenSSL(params) {
56
56
  const { keyPath, certPath } = params;
57
- const subj = '/C=BR/ST=SP/L=Sao Paulo/O=Purecore/OU=Dev/CN=localhost';
57
+ const subj = "/C=BR/ST=SP/L=Sao Paulo/O=Purecore/OU=Dev/CN=localhost";
58
58
  // Preferimos SAN para evitar problemas em clients modernos.
59
59
  // Nem todo OpenSSL antigo suporta -addext, então fazemos fallback.
60
- const baseArgs = ['req', '-x509', '-newkey', 'rsa:2048', '-keyout', keyPath, '-out', certPath, '-days', '365', '-nodes', '-subj', subj];
60
+ const baseArgs = [
61
+ "req",
62
+ "-x509",
63
+ "-newkey",
64
+ "rsa:2048",
65
+ "-keyout",
66
+ keyPath,
67
+ "-out",
68
+ certPath,
69
+ "-days",
70
+ "365",
71
+ "-nodes",
72
+ "-subj",
73
+ subj,
74
+ ];
61
75
  try {
62
- execFileSync('openssl', [...baseArgs, '-addext', 'subjectAltName=DNS:localhost,IP:127.0.0.1'], { stdio: 'inherit' });
76
+ execFileSync("openssl", [...baseArgs, "-addext", "subjectAltName=DNS:localhost,IP:127.0.0.1"], { stdio: "inherit" });
63
77
  }
64
78
  catch {
65
- execFileSync('openssl', baseArgs, { stdio: 'inherit' });
79
+ execFileSync("openssl", baseArgs, { stdio: "inherit" });
66
80
  }
67
81
  }
68
82
  static validatePem(params) {
69
83
  const { keyPem, certPem, keyPath, certPath } = params;
70
- const keyOk = keyPem.includes('-----BEGIN PRIVATE KEY-----') ||
71
- keyPem.includes('-----BEGIN RSA PRIVATE KEY-----');
72
- const certOk = certPem.includes('-----BEGIN CERTIFICATE-----');
84
+ const keyOk = keyPem.includes("-----BEGIN PRIVATE KEY-----") ||
85
+ keyPem.includes("-----BEGIN RSA PRIVATE KEY-----");
86
+ const certOk = certPem.includes("-----BEGIN CERTIFICATE-----");
73
87
  if (!keyOk || !certOk) {
74
88
  throw new Error(`PEM inválido gerado. ` +
75
89
  `keyOk=${keyOk} certOk=${certOk}. ` +
@@ -83,7 +97,7 @@ export class CertGenerator {
83
97
  // @ts-ignore - Bun/Node expõem X509Certificate em node:crypto
84
98
  const x509 = new crypto.X509Certificate(certPem);
85
99
  if (!x509.subject) {
86
- throw new Error('X509 sem subject');
100
+ throw new Error("X509 sem subject");
87
101
  }
88
102
  }
89
103
  catch (error) {
@@ -93,7 +107,9 @@ export class CertGenerator {
93
107
  static validateWithOpenSSL(certPath) {
94
108
  try {
95
109
  // OpenSSL é a validação "ground truth" no WSL.
96
- execFileSync('openssl', ['x509', '-in', certPath, '-noout'], { stdio: 'ignore' });
110
+ execFileSync("openssl", ["x509", "-in", certPath, "-noout"], {
111
+ stdio: "ignore",
112
+ });
97
113
  }
98
114
  catch (error) {
99
115
  throw new Error(`OpenSSL não conseguiu ler o certificado (${certPath}).`);
@@ -116,40 +132,42 @@ export class CertGenerator {
116
132
  const certDir = path.join(process.cwd(), this.CERT_DIR);
117
133
  try {
118
134
  await fs.rm(certDir, { recursive: true, force: true });
119
- console.log('🗑️ Certificados removidos:', certDir);
135
+ console.log("🗑️ Certificados removidos:", certDir);
120
136
  }
121
137
  catch (error) {
122
- console.error('❌ Erro ao remover certificados:', error);
138
+ console.error("❌ Erro ao remover certificados:", error);
123
139
  }
124
140
  }
125
141
  }
126
142
  // Executar se chamado diretamente
127
- if (typeof require !== 'undefined' && require.main === module) {
143
+ if (typeof require !== "undefined" && require.main === module) {
128
144
  const command = process.argv[2];
129
145
  switch (command) {
130
- case 'generate':
146
+ case "generate":
131
147
  case undefined:
132
148
  CertGenerator.generateCerts().catch(console.error);
133
149
  break;
134
- case 'clean':
150
+ case "clean":
135
151
  CertGenerator.cleanCerts().catch(console.error);
136
152
  break;
137
- case 'info':
138
- CertGenerator.getCertPaths().then(paths => {
153
+ case "info":
154
+ CertGenerator.getCertPaths()
155
+ .then((paths) => {
139
156
  if (paths) {
140
- console.log('📋 Certificados encontrados:');
141
- console.log('🔑 Chave:', paths.keyPath);
142
- console.log('📄 Certificado:', paths.certPath);
157
+ console.log("📋 Certificados encontrados:");
158
+ console.log("🔑 Chave:", paths.keyPath);
159
+ console.log("📄 Certificado:", paths.certPath);
143
160
  }
144
161
  else {
145
- console.log('❌ Nenhum certificado encontrado');
162
+ console.log("❌ Nenhum certificado encontrado");
146
163
  }
147
- }).catch(console.error);
164
+ })
165
+ .catch(console.error);
148
166
  break;
149
167
  default:
150
- console.log('Uso: cert-generator [generate|clean|info]');
151
- console.log(' generate: Gera certificados auto-assinados (padrão)');
152
- console.log(' clean: Remove certificados existentes');
153
- console.log(' info: Mostra informações dos certificados');
168
+ console.log("Uso: cert-generator [generate|clean|info]");
169
+ console.log(" generate: Gera certificados auto-assinados (padrão)");
170
+ console.log(" clean: Remove certificados existentes");
171
+ console.log(" info: Mostra informações dos certificados");
154
172
  }
155
173
  }
package/dist/deployer.js CHANGED
@@ -16,7 +16,7 @@ export class Deployer {
16
16
  return new Promise((resolve) => this.rl.question(query, resolve));
17
17
  }
18
18
  printBanner() {
19
- console.log(`\n ${bold(magenta("🚀 HOT-SERVER DEPLOYER"))} ${gray("v0.4.0")}`);
19
+ console.log(`\n ${bold(magenta("🚀 one-server-4-all DEPLOYER"))} ${gray("v0.4.0")}`);
20
20
  console.log(` ${gray("─────────────────────────────────────────")}\n`);
21
21
  }
22
22
  async start() {
@@ -27,7 +27,7 @@ export class Deployer {
27
27
  this.rl.close();
28
28
  return;
29
29
  }
30
- const port = (await this.question(` ${cyan("➜")} ${bold("Qual a porta do servidor?")} ${gray("(padrão 6000)")}\n ${green("❯")} `)) || "6000";
30
+ const port = (await this.question(` ${cyan("➜")} ${bold("Qual a porta do servidor?")} ${gray("(padrão 7000)")}\n ${green("❯")} `)) || "7000";
31
31
  const confirmNginx = await this.question(` ${cyan("➜")} ${bold("Deseja configurar Nginx + SSL (Certbot) agora?")} ${gray("(s/n)")}\n ${green("❯")} `);
32
32
  let certPaths = { key: "", cert: "" };
33
33
  if (confirmNginx.toLowerCase() === "s") {
@@ -40,18 +40,17 @@ export class Deployer {
40
40
  }
41
41
  const name = domain.split(".")[0];
42
42
  // Monta o comando PM2
43
- // Se temos certificados do Certbot e o usuário quer usar no node direto (embora com nginx proxy não precise necessariamente)
44
- // O user pediu para "ter o caminho para apontar para eles".
45
- // Vamos gerar o comando COM os certificados se eles existirem, e setar https=true
46
- let pm2Command = `pm2 start dist/index.js --name "${domain}" -- --port=${port} --open=false`;
43
+ // Quando Nginx+Certbot está configurado, o Nginx faz terminação SSL
44
+ // O server roda em HTTP simples (Nginx faz proxy_pass http://localhost:porta)
45
+ // Argumentos devem estar DENTRO das aspas para PM2 processar corretamente
46
+ let pm2Command;
47
47
  if (certPaths.key && certPaths.cert) {
48
- // Nota: Node node pode não ter permissão de ler /etc/letsencrypt diretamente dependendo do user
49
- // Mas vamos atender o pedido de colocar o caminho
50
- pm2Command += ` --https=true --ssl-key="${certPaths.key}" --ssl-cert="${certPaths.cert}"`;
48
+ // Com Nginx+Certbot: server roda HTTP, Nginx cuida do SSL
49
+ pm2Command = `pm2 start "npx vai-server --port=${port} --open=false" --name "${domain}"`;
51
50
  }
52
51
  else {
53
- // Se nao tem certbot, roda http normal (ou auto-assinado se forcer https)
54
- pm2Command += ` --https=false`;
52
+ // Sem Nginx: pode rodar HTTPS auto-assinado ou HTTP
53
+ pm2Command = `pm2 start "npx vai-server --port=${port} --open=false" --name "${domain}"`;
55
54
  }
56
55
  console.log(`\n ${bold("📦 Configuração Final:")}`);
57
56
  console.log(` ${gray("────────────────────────")}`);
package/dist/index.js CHANGED
@@ -21,7 +21,7 @@ else {
21
21
  // Se o primeiro argumento não tiver --, assumimos que é a pasta
22
22
  const rootArg = args[0] && !args[0].startsWith("--") ? args[0] : ".";
23
23
  const rawConfig = {
24
- port: parseInt(getArg("port", "6000")),
24
+ port: parseInt(getArg("port", "7000")),
25
25
  root: path.resolve(process.cwd(), rootArg),
26
26
  open: getArg("open", "true"), // 'true' por padrão
27
27
  spa: getArg("spa", "false"), // 'false' por padrão
package/dist/server.js CHANGED
@@ -12,22 +12,22 @@ const INJECTED_SCRIPT = `
12
12
  <!-- Code injected by auto-server -->
13
13
  <script>
14
14
  (function() {
15
- console.log('[hot-server] Connected to hot reload');
15
+ console.log('[one-server-4-all] Connected to hot reload');
16
16
  const evtSource = new EventSource('/_hot_server_sse');
17
17
  evtSource.onmessage = function(event) {
18
18
  try {
19
19
  const data = JSON.parse(event.data);
20
20
  if (data.type === 'css') {
21
- console.log('[hot-server] CSS changed, injecting...');
21
+ console.log('[one-server-4-all] CSS changed, injecting...');
22
22
  injectCSS(data.file);
23
23
  } else {
24
- console.log('[hot-server] Reloading...');
24
+ console.log('[one-server-4-all] Reloading...');
25
25
  window.location.reload();
26
26
  }
27
27
  } catch (e) {
28
28
  // Fallback para compatibilidade
29
29
  if (event.data === 'reload') {
30
- console.log('[hot-server] Reloading...');
30
+ console.log('[one-server-4-all] Reloading...');
31
31
  window.location.reload();
32
32
  }
33
33
  }
@@ -44,13 +44,13 @@ const INJECTED_SCRIPT = `
44
44
  // Força reload do CSS adicionando/removendo timestamp
45
45
  const newHref = href.split('?')[0] + '?v=' + timestamp;
46
46
  link.setAttribute('href', newHref);
47
- console.log('[hot-server] CSS injected:', filePath);
47
+ console.log('[one-server-4-all] CSS injected:', filePath);
48
48
  }
49
49
  });
50
50
  }
51
51
 
52
52
  evtSource.onerror = function() {
53
- console.log('[hot-server] Disconnected. Retrying...');
53
+ console.log('[one-server-4-all] Disconnected. Retrying...');
54
54
  };
55
55
  })();
56
56
  </script>
@@ -325,7 +325,7 @@ export class HotServer {
325
325
  const green = (text) => `\x1b[32m${text}\x1b[0m`;
326
326
  const bold = (text) => `\x1b[1m${text}\x1b[0m`;
327
327
  const gray = (text) => `\x1b[90m${text}\x1b[0m`;
328
- console.log(`\n ${bold(cyan("HOT-SERVER"))} ${cyan("v" + version)} ${gray("ready in")} ${bold(green(readyTime + " ms"))}\n`);
328
+ console.log(`\n ${bold(cyan("one-server-4-all"))} ${cyan("v" + version)} ${gray("ready in")} ${bold(green(readyTime + " ms"))}\n`);
329
329
  console.log(` ${green("➜")} ${bold("Local")}: ${cyan(`${protocol}://localhost:${this.config.port}/`)}`);
330
330
  const networks = this.getNetworkIPs();
331
331
  networks.forEach((ip) => {
@@ -551,7 +551,7 @@ export class HotServer {
551
551
  </div>
552
552
 
553
553
  <div class="back">
554
- Servido por <strong>purecore-hot-server</strong>
554
+ Servido por <strong>purecore-one-server-4-all</strong>
555
555
  </div>
556
556
  </div>
557
557
  </body>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@purecore/one-server-4-all",
3
- "version": "0.3.0",
3
+ "version": "0.3.1",
4
4
  "description": "Zero dependency modern hot-reload server replacement",
5
5
  "main": "dist/index.js",
6
6
  "type": "module",
package/src/deployer.ts CHANGED
@@ -45,9 +45,9 @@ export class Deployer {
45
45
  const port =
46
46
  (await this.question(
47
47
  ` ${cyan("➜")} ${bold("Qual a porta do servidor?")} ${gray(
48
- "(padrão 8080)"
48
+ "(padrão 7000)"
49
49
  )}\n ${green("❯")} `
50
- )) || "8080";
50
+ )) || "7000";
51
51
 
52
52
  const confirmNginx = await this.question(
53
53
  ` ${cyan("➜")} ${bold(
@@ -69,18 +69,18 @@ export class Deployer {
69
69
  const name = domain.split(".")[0];
70
70
 
71
71
  // Monta o comando PM2
72
- // Usamos npx para garantir que rode o pacote instalado ou baixe se necessário
73
- // A sintaxe para PM2 rodar executáveis arbitrários requer 'pm2 start "cmd" --name ...' ou usar o interpreter
72
+ // Quando Nginx+Certbot está configurado, o Nginx faz terminação SSL
73
+ // O server roda em HTTP simples (Nginx faz proxy_pass http://localhost:porta)
74
+ // Argumentos devem estar DENTRO das aspas para PM2 processar corretamente
74
75
 
75
- let pm2Command = `pm2 start "npx one-server-4-all" --name "${domain}" -- --port=${port} --open=false`;
76
+ let pm2Command: string;
76
77
 
77
78
  if (certPaths.key && certPaths.cert) {
78
- // Nota: Node node pode não ter permissão de ler /etc/letsencrypt diretamente dependendo do user
79
- // Mas vamos atender o pedido de colocar o caminho
80
- pm2Command += ` --https=true --ssl-key="${certPaths.key}" --ssl-cert="${certPaths.cert}"`;
79
+ // Com Nginx+Certbot: server roda HTTP, Nginx cuida do SSL
80
+ pm2Command = `pm2 start "npx vai-server --port=${port} --open=false" --name "${domain}"`;
81
81
  } else {
82
- // Se nao tem certbot, roda http normal (ou auto-assinado se forcer https)
83
- pm2Command += ` --https=false`;
82
+ // Sem Nginx: pode rodar HTTPS auto-assinado ou HTTP
83
+ pm2Command = `pm2 start "npx vai-server --port=${port} --open=false" --name "${domain}"`;
84
84
  }
85
85
 
86
86
  console.log(`\n ${bold("📦 Configuração Final:")}`);
package/src/index.ts CHANGED
@@ -24,7 +24,7 @@ if (args[0] === "deploy") {
24
24
  const rootArg = args[0] && !args[0].startsWith("--") ? args[0] : ".";
25
25
 
26
26
  const rawConfig = {
27
- port: parseInt(getArg("port", "8080")),
27
+ port: parseInt(getArg("port", "7000")),
28
28
  root: path.resolve(process.cwd(), rootArg),
29
29
  open: getArg("open", "true"), // 'true' por padrão
30
30
  spa: getArg("spa", "false"), // 'false' por padrão