xypriss 9.0.1 → 9.0.3

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.
package/package.json CHANGED
@@ -6,7 +6,8 @@
6
6
  },
7
7
  "bin": {
8
8
  "xsys": "scripts/xys.run.js",
9
- "xypriss-sys": "scripts/xys.run.js"
9
+ "xypriss-sys": "scripts/xys.run.js",
10
+ "xems": "scripts/xems.run.js"
10
11
  },
11
12
  "browserslist": [
12
13
  "> 1%",
@@ -274,6 +275,6 @@
274
275
  "support": "https://github.com/Nehonix-Team/XyPriss/issues",
275
276
  "type": "module",
276
277
  "types": "dist/index.d.ts",
277
- "version": "9.0.1"
278
+ "version": "9.0.3"
278
279
  }
279
280
 
@@ -128,14 +128,21 @@ async function installMemoryCLI() {
128
128
  const info = getPlatformBinary();
129
129
  if (!info) return;
130
130
 
131
+ console.log(`📂 Target directory: ${BIN_DIR}`);
132
+ console.log(`📦 Binary: ${info.binaryName}`);
133
+
131
134
  if (fs.existsSync(info.genericPath)) {
132
- console.log("✨ Memory CLI already present.");
135
+ console.log(
136
+ `✨ Memory CLI already present at ${info.genericPath}, skipping.`,
137
+ );
133
138
  return;
134
139
  }
135
140
 
136
141
  try {
137
- console.log(`📥 Fetching Memory CLI...`);
142
+ console.log(`📥 Fetching Memory CLI from:`);
143
+ console.log(` 🔗 URL: ${info.url}`);
138
144
  await downloadFile(info.url, info.localPath);
145
+ console.log("✅ Downloaded successfully.");
139
146
 
140
147
  if (process.platform !== "win32") {
141
148
  fs.chmodSync(info.localPath, 0o755);
@@ -151,7 +158,9 @@ async function installMemoryCLI() {
151
158
 
152
159
  const isValid = await verifyBinary(info.localPath);
153
160
  if (isValid) {
154
- console.log("🎉 XyPriss MCLI installed successfully!");
161
+ console.log(
162
+ `🎉 XyPriss MCLI installed successfully at: ${info.genericPath}`,
163
+ );
155
164
  } else {
156
165
  console.warn(
157
166
  "⚠️ MCLI verification failed, it might not work as expected.",
@@ -14,13 +14,70 @@ import https from "https";
14
14
  const __filename = fileURLToPath(import.meta.url);
15
15
  const __dirname = path.dirname(__filename);
16
16
 
17
+ // ─────────────────────────────────────────────
18
+ // ANSI Color Palette
19
+ // ─────────────────────────────────────────────
20
+ const c = {
21
+ reset: "\x1b[0m",
22
+ bold: "\x1b[1m",
23
+ dim: "\x1b[2m",
24
+
25
+ // Foreground
26
+ white: "\x1b[97m",
27
+ gray: "\x1b[90m",
28
+ red: "\x1b[91m",
29
+ green: "\x1b[92m",
30
+ yellow: "\x1b[93m",
31
+ blue: "\x1b[94m",
32
+ magenta: "\x1b[95m",
33
+ cyan: "\x1b[96m",
34
+ };
35
+
36
+ // ─────────────────────────────────────────────
37
+ // Logger
38
+ // ─────────────────────────────────────────────
39
+ const log = {
40
+ info: (msg) =>
41
+ console.log(
42
+ `${c.cyan}${c.bold} ℹ ${c.reset}${c.white}${msg}${c.reset}`,
43
+ ),
44
+ success: (msg) =>
45
+ console.log(
46
+ `${c.green}${c.bold} ✔ ${c.reset}${c.green}${msg}${c.reset}`,
47
+ ),
48
+ warn: (msg) =>
49
+ console.log(
50
+ `${c.yellow}${c.bold} ⚠ ${c.reset}${c.yellow}${msg}${c.reset}`,
51
+ ),
52
+ error: (msg) =>
53
+ console.log(`${c.red}${c.bold} ✖ ${c.reset}${c.red}${msg}${c.reset}`),
54
+ step: (msg) =>
55
+ console.log(
56
+ `${c.magenta}${c.bold} ▶ ${c.reset}${c.magenta}${msg}${c.reset}`,
57
+ ),
58
+ link: (label, url) =>
59
+ console.log(
60
+ `${c.gray} └─ ${c.dim}${label}:${c.reset} ${c.blue}${url}${c.reset}`,
61
+ ),
62
+ detail: (msg) => console.log(`${c.gray} ${msg}${c.reset}`),
63
+ divider: () => console.log(`${c.gray} ${"─".repeat(52)}${c.reset}`),
64
+ blank: () => console.log(),
65
+ };
66
+
67
+ // ─────────────────────────────────────────────
68
+ // Constants
69
+ // ─────────────────────────────────────────────
17
70
  const BIN_DIR = path.join(__dirname, "..", "bin");
18
71
  const REPO = "Nehonix-Team/XyPriss-XEMS";
19
- const CDN_BASE_URL = "https://dll.nehonix.com/dl/mds/xems/bin"; // Fallback CDN
72
+ const CDN_BASE_URL = "https://dll.nehonix.com/dl/mds/xems/bin";
73
+
74
+ // ─────────────────────────────────────────────
75
+ // Platform Detection
76
+ // ─────────────────────────────────────────────
20
77
 
21
78
  /**
22
- * Get platform-specific binary information for XEMS
23
- * Maps directly to the files in tools/XEMS/dist/
79
+ * Returns platform-specific binary metadata for XEMS.
80
+ * Maps to the files in tools/XEMS/dist/
24
81
  */
25
82
  function getPlatformBinary() {
26
83
  const platform = process.platform;
@@ -37,34 +94,32 @@ function getPlatformBinary() {
37
94
  return null;
38
95
  }
39
96
 
40
- // Naming convention: xems-linux-x64, xems-windows-x64.exe, etc.
41
- const binaryName = `xems-${binaryTarget}${platform === "win32" ? ".exe" : ""}`;
97
+ const ext = platform === "win32" ? ".exe" : "";
98
+ const binaryName = `xems-${binaryTarget}${ext}`;
42
99
 
43
100
  return {
44
101
  binaryName,
102
+ platform,
103
+ arch,
45
104
  url: `https://github.com/${REPO}/releases/latest/download/${binaryName}`,
46
105
  fallbackUrl: `${CDN_BASE_URL}/${binaryName}`,
47
106
  localPath: path.join(BIN_DIR, binaryName),
48
- genericPath: path.join(
49
- BIN_DIR,
50
- "xems" + (platform === "win32" ? ".exe" : ""),
51
- ),
107
+ genericPath: path.join(BIN_DIR, `xems${ext}`),
52
108
  };
53
109
  }
54
110
 
55
- /**
56
- * Download a file with redirect support
57
- */
111
+ // ─────────────────────────────────────────────
112
+ // Downloader (with redirect support)
113
+ // ─────────────────────────────────────────────
114
+
58
115
  function downloadFile(url, dest) {
59
116
  return new Promise((resolve, reject) => {
60
117
  const file = fs.createWriteStream(dest);
61
-
62
118
  const request = https.get(
63
119
  url,
64
- {
65
- headers: { "User-Agent": "XyPriss-Installer" },
66
- },
120
+ { headers: { "User-Agent": "XyPriss-Installer" } },
67
121
  (response) => {
122
+ // Follow redirects
68
123
  if (
69
124
  response.statusCode >= 300 &&
70
125
  response.statusCode < 400 &&
@@ -82,14 +137,23 @@ function downloadFile(url, dest) {
82
137
  fs.unlinkSync(dest);
83
138
  return reject(
84
139
  new Error(
85
- `Server responded with ${response.statusCode}`,
140
+ `Server responded with HTTP ${response.statusCode}`,
86
141
  ),
87
142
  );
88
143
  }
89
144
 
90
- response.pipe(file);
145
+ // Stream progress dots
146
+ let received = 0;
147
+ process.stdout.write(`${c.gray} └─ Downloading `);
148
+ response.on("data", (chunk) => {
149
+ received += chunk.length;
150
+ if (received % (50 * 1024) < chunk.length)
151
+ process.stdout.write(`${c.blue}.${c.reset}`);
152
+ });
91
153
 
154
+ response.pipe(file);
92
155
  file.on("finish", () => {
156
+ process.stdout.write(` ${c.green}done${c.reset}\n`);
93
157
  file.close();
94
158
  resolve();
95
159
  });
@@ -104,58 +168,102 @@ function downloadFile(url, dest) {
104
168
  });
105
169
  }
106
170
 
171
+ // ─────────────────────────────────────────────
172
+ // Main Installer
173
+ // ─────────────────────────────────────────────
174
+
107
175
  async function installXems() {
176
+ log.blank();
177
+ log.divider();
178
+ console.log(
179
+ `${c.cyan}${c.bold} XEMS Installer — XyPriss Entry Management System${c.reset}`,
180
+ );
181
+ log.divider();
182
+ log.blank();
183
+
184
+ // Ensure bin directory exists
108
185
  if (!fs.existsSync(BIN_DIR)) {
109
186
  fs.mkdirSync(BIN_DIR, { recursive: true });
187
+ log.detail(`Created bin directory: ${BIN_DIR}`);
110
188
  }
111
189
 
112
190
  const info = getPlatformBinary();
113
191
  if (!info) {
114
- console.error(
115
- " XEMS is not supported on this platform/architecture.",
192
+ log.error(
193
+ "Unsupported platform/architecture. XEMS cannot be installed.",
116
194
  );
117
195
  return;
118
196
  }
119
197
 
198
+ log.info(
199
+ `Platform : ${c.yellow}${info.platform}${c.reset} ${c.gray}(${info.arch})${c.reset}`,
200
+ );
201
+ log.info(`Binary : ${c.yellow}${info.binaryName}${c.reset}`);
202
+ log.info(`Target : ${c.yellow}${BIN_DIR}${c.reset}`);
203
+ log.blank();
204
+
205
+ // Skip if already installed
120
206
  if (fs.existsSync(info.genericPath)) {
121
- console.log("✨ XEMS binary already present.");
207
+ log.success(`XEMS is already installed → ${info.genericPath}`);
208
+ log.blank();
122
209
  return;
123
210
  }
124
211
 
125
- console.log(`🌐 Downloading XEMS (${info.binaryName})...`);
126
-
212
+ // Attempt GitHub download, then fallback CDN
213
+ log.step("Downloading XEMS binary…");
127
214
  try {
128
215
  try {
216
+ log.link("GitHub", info.url);
129
217
  await downloadFile(info.url, info.localPath);
130
- } catch (e) {
131
- console.log("📡 GitHub download failed, trying fallback CDN...");
218
+ log.success("Downloaded from GitHub.");
219
+ } catch (githubErr) {
220
+ log.warn(`GitHub download failed: ${githubErr.message}`);
221
+ log.step("Retrying with fallback CDN…");
222
+ log.link("CDN", info.fallbackUrl);
132
223
  await downloadFile(info.fallbackUrl, info.localPath);
224
+ log.success("Downloaded from fallback CDN.");
133
225
  }
134
226
 
227
+ // Set executable bit on Unix
135
228
  if (process.platform !== "win32") {
136
229
  fs.chmodSync(info.localPath, 0o755);
230
+ log.detail("Executable permission set (chmod 755).");
137
231
  }
138
232
 
233
+ // Create generic alias (symlink on Unix, copy on Windows)
139
234
  if (process.platform === "win32") {
140
235
  fs.copyFileSync(info.localPath, info.genericPath);
236
+ log.detail(`Copied binary → ${info.genericPath}`);
141
237
  } else {
142
238
  if (fs.existsSync(info.genericPath))
143
239
  fs.unlinkSync(info.genericPath);
144
240
  fs.symlinkSync(path.basename(info.localPath), info.genericPath);
241
+ log.detail(`Symlink created → ${info.genericPath}`);
145
242
  }
146
243
 
147
- console.log(`✅ XEMS successfully installed.`);
244
+ log.blank();
245
+ log.success(
246
+ `XEMS successfully installed at: ${c.bold}${info.genericPath}${c.reset}`,
247
+ );
148
248
  } catch (err) {
149
- console.error("❌ XEMS download failed:", err.message);
249
+ log.blank();
250
+ log.error(`XEMS installation failed: ${err.message}`);
150
251
  }
252
+
253
+ log.blank();
254
+ log.divider();
255
+ log.blank();
151
256
  }
152
257
 
258
+ // ─────────────────────────────────────────────
259
+ // Entry Point
260
+ // ─────────────────────────────────────────────
261
+
153
262
  if (import.meta.url === `file://${process.argv[1]}`) {
154
263
  installXems().catch((error) => {
155
- console.error("🔥 Installation failed:", error.message);
264
+ log.error(`Fatal error: ${error.message}`);
156
265
  process.exit(0);
157
266
  });
158
267
  }
159
268
 
160
269
  export { installXems };
161
-
@@ -1,4 +1,11 @@
1
- import { execSync } from "child_process";
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * XSYS Installer Script
5
+ * Downloads the XSYS (XyPriss System Core) binary from GitHub Releases.
6
+ * Supports cross-platform: Windows, Linux, and macOS (Intel & Silicon).
7
+ */
8
+
2
9
  import fs from "fs";
3
10
  import { join, dirname, basename } from "path";
4
11
  import { platform, arch } from "os";
@@ -8,22 +15,73 @@ import { fileURLToPath } from "url";
8
15
  const __filename = fileURLToPath(import.meta.url);
9
16
  const __dirname = dirname(__filename);
10
17
 
18
+ // ─────────────────────────────────────────────
19
+ // ANSI Color Palette
20
+ // ─────────────────────────────────────────────
21
+ const c = {
22
+ reset: "\x1b[0m",
23
+ bold: "\x1b[1m",
24
+ dim: "\x1b[2m",
25
+ white: "\x1b[97m",
26
+ gray: "\x1b[90m",
27
+ red: "\x1b[91m",
28
+ green: "\x1b[92m",
29
+ yellow: "\x1b[93m",
30
+ blue: "\x1b[94m",
31
+ magenta: "\x1b[95m",
32
+ cyan: "\x1b[96m",
33
+ };
34
+
35
+ // ─────────────────────────────────────────────
36
+ // Logger
37
+ // ─────────────────────────────────────────────
38
+ const log = {
39
+ info: (msg) =>
40
+ console.log(
41
+ `${c.cyan}${c.bold} ℹ ${c.reset}${c.white}${msg}${c.reset}`,
42
+ ),
43
+ success: (msg) =>
44
+ console.log(
45
+ `${c.green}${c.bold} ✔ ${c.reset}${c.green}${msg}${c.reset}`,
46
+ ),
47
+ warn: (msg) =>
48
+ console.log(
49
+ `${c.yellow}${c.bold} ⚠ ${c.reset}${c.yellow}${msg}${c.reset}`,
50
+ ),
51
+ error: (msg) =>
52
+ console.log(`${c.red}${c.bold} ✖ ${c.reset}${c.red}${msg}${c.reset}`),
53
+ step: (msg) =>
54
+ console.log(
55
+ `${c.magenta}${c.bold} ▶ ${c.reset}${c.magenta}${msg}${c.reset}`,
56
+ ),
57
+ link: (label, url) =>
58
+ console.log(
59
+ `${c.gray} └─ ${c.dim}${label}:${c.reset} ${c.blue}${url}${c.reset}`,
60
+ ),
61
+ detail: (msg) => console.log(`${c.gray} ${msg}${c.reset}`),
62
+ divider: () => console.log(`${c.gray} ${"─".repeat(52)}${c.reset}`),
63
+ blank: () => console.log(),
64
+ };
65
+
66
+ // ─────────────────────────────────────────────
67
+ // Constants
68
+ // ─────────────────────────────────────────────
11
69
  const REPO = "Nehonix-Team/XyPriss";
12
70
  const BIN_NAME = "xsys";
13
71
  const BIN_DIR = join(__dirname, "..", "bin");
14
72
 
15
- /**
16
- * Téléchargement avec support des redirections GitHub
17
- */
73
+ // ─────────────────────────────────────────────
74
+ // Downloader (with redirect support)
75
+ // ─────────────────────────────────────────────
76
+
18
77
  function downloadFile(url, dest) {
19
78
  return new Promise((resolve, reject) => {
20
79
  const file = fs.createWriteStream(dest);
21
80
  const request = https.get(
22
81
  url,
23
- {
24
- headers: { "User-Agent": "XyPriss-Installer" },
25
- },
82
+ { headers: { "User-Agent": "XyPriss-Installer" } },
26
83
  (response) => {
84
+ // Follow redirects
27
85
  if (
28
86
  response.statusCode >= 300 &&
29
87
  response.statusCode < 400 &&
@@ -35,18 +93,35 @@ function downloadFile(url, dest) {
35
93
  .then(resolve)
36
94
  .catch(reject);
37
95
  }
96
+
38
97
  if (response.statusCode !== 200) {
39
98
  file.close();
40
99
  fs.unlinkSync(dest);
41
- return reject(new Error(`HTTP ${response.statusCode}`));
100
+ return reject(
101
+ new Error(
102
+ `Server responded with HTTP ${response.statusCode}`,
103
+ ),
104
+ );
42
105
  }
106
+
107
+ // Stream progress dots
108
+ let received = 0;
109
+ process.stdout.write(`${c.gray} └─ Downloading `);
110
+ response.on("data", (chunk) => {
111
+ received += chunk.length;
112
+ if (received % (50 * 1024) < chunk.length)
113
+ process.stdout.write(`${c.blue}.${c.reset}`);
114
+ });
115
+
43
116
  response.pipe(file);
44
117
  file.on("finish", () => {
118
+ process.stdout.write(` ${c.green}done${c.reset}\n`);
45
119
  file.close();
46
120
  resolve();
47
121
  });
48
122
  },
49
123
  );
124
+
50
125
  request.on("error", (err) => {
51
126
  file.close();
52
127
  if (fs.existsSync(dest)) fs.unlinkSync(dest);
@@ -55,68 +130,104 @@ function downloadFile(url, dest) {
55
130
  });
56
131
  }
57
132
 
133
+ // ─────────────────────────────────────────────
134
+ // Main Installer
135
+ // ─────────────────────────────────────────────
136
+
58
137
  async function installXsys() {
138
+ log.blank();
139
+ log.divider();
140
+ console.log(
141
+ `${c.cyan}${c.bold} XSYS Installer — XyPriss System Core${c.reset}`,
142
+ );
143
+ log.divider();
144
+ log.blank();
145
+
146
+ // Ensure bin directory exists
59
147
  if (!fs.existsSync(BIN_DIR)) {
60
148
  fs.mkdirSync(BIN_DIR, { recursive: true });
149
+ log.detail(`Created bin directory: ${BIN_DIR}`);
61
150
  }
62
151
 
63
152
  const osName = platform();
64
153
  const archName = arch();
65
154
 
66
- // Mappage exact avec tes fichiers dans tools/xypriss-sys-go/dist/
155
+ // Map to binary target name
67
156
  let binaryTarget = "";
68
157
  if (osName === "linux") {
69
158
  binaryTarget = archName === "arm64" ? "linux-arm64" : "linux-amd64";
70
159
  } else if (osName === "darwin") {
71
- binaryTarget = archName === "arm64" ? "darwin-arm64" : "darwin-amd64"; // Support macOS Intel & Silicon
160
+ binaryTarget = archName === "arm64" ? "darwin-arm64" : "darwin-amd64";
72
161
  } else if (osName === "win32") {
73
162
  binaryTarget = archName === "arm64" ? "windows-arm64" : "windows-amd64";
74
163
  } else {
75
- console.error(`❌ Plateforme non supportée : ${osName}`);
164
+ log.error(`Unsupported platform: ${osName}`);
76
165
  return;
77
166
  }
78
167
 
79
- const binaryFileName = `${BIN_NAME}-${binaryTarget}${osName === "win32" ? ".exe" : ""}`;
168
+ const ext = osName === "win32" ? ".exe" : "";
169
+ const binaryFileName = `${BIN_NAME}-${binaryTarget}${ext}`;
80
170
  const url = `https://github.com/${REPO}/releases/latest/download/${binaryFileName}`;
81
171
  const localPath = join(BIN_DIR, binaryFileName);
82
- const genericPath = join(
83
- BIN_DIR,
84
- BIN_NAME + (osName === "win32" ? ".exe" : ""),
172
+ const genericPath = join(BIN_DIR, `${BIN_NAME}${ext}`);
173
+
174
+ log.info(
175
+ `Platform : ${c.yellow}${osName}${c.reset} ${c.gray}(${archName})${c.reset}`,
85
176
  );
177
+ log.info(`Binary : ${c.yellow}${binaryFileName}${c.reset}`);
178
+ log.info(`Target : ${c.yellow}${BIN_DIR}${c.reset}`);
179
+ log.blank();
86
180
 
181
+ // Skip if already installed
87
182
  if (fs.existsSync(genericPath)) {
88
- console.log("✨ XSYS est déjà présent.");
183
+ log.success(`XSYS is already installed → ${genericPath}`);
184
+ log.blank();
89
185
  return;
90
186
  }
91
187
 
92
- console.log(`🌐 Téléchargement de XSYS (${binaryTarget})...`);
188
+ // Download
189
+ log.step("Downloading XSYS binary…");
190
+ log.link("GitHub", url);
93
191
 
94
192
  try {
95
193
  await downloadFile(url, localPath);
96
194
 
195
+ // Set executable bit on Unix
97
196
  if (osName !== "win32") {
98
197
  fs.chmodSync(localPath, 0o755);
198
+ log.detail("Executable permission set (chmod 755).");
99
199
  }
100
200
 
101
- // Création du lien/copie générique
201
+ // Create generic alias (symlink on Unix, copy on Windows)
102
202
  if (osName === "win32") {
103
203
  fs.copyFileSync(localPath, genericPath);
204
+ log.detail(`Copied binary → ${genericPath}`);
104
205
  } else {
105
206
  if (fs.existsSync(genericPath)) fs.unlinkSync(genericPath);
106
207
  fs.symlinkSync(basename(localPath), genericPath);
208
+ log.detail(`Symlink created → ${genericPath}`);
107
209
  }
108
210
 
109
- console.log(`✅ XSYS installé avec succès : ${genericPath}`);
110
- } catch (err) {
111
- console.error(
112
- `❌ Échec de l'acquisition du binaire XSYS : ${err.message}`,
211
+ log.blank();
212
+ log.success(
213
+ `XSYS successfully installed at: ${c.bold}${genericPath}${c.reset}`,
113
214
  );
215
+ } catch (err) {
216
+ log.blank();
217
+ log.error(`XSYS installation failed: ${err.message}`);
114
218
  }
219
+
220
+ log.blank();
221
+ log.divider();
222
+ log.blank();
115
223
  }
116
224
 
225
+ // ─────────────────────────────────────────────
226
+ // Entry Point
227
+ // ─────────────────────────────────────────────
228
+
117
229
  if (import.meta.url === `file://${process.argv[1]}`) {
118
230
  installXsys().catch(() => process.exit(0));
119
231
  }
120
232
 
121
233
  export { installXsys };
122
-
@@ -2,42 +2,132 @@
2
2
 
3
3
  /**
4
4
  * XyPriss Post-Install Script
5
- * Runs after npm install to set up platform-specific binaries
5
+ * Runs after `npm install` to set up all platform-specific binaries.
6
6
  */
7
7
 
8
8
  import { installMemoryCLI } from "./install-memory-cli.js";
9
9
  import { installXems } from "./install-xems.js";
10
10
  import { installXsys } from "./postinstall-xsys.js";
11
11
 
12
+ // ─────────────────────────────────────────────
13
+ // ANSI Color Palette
14
+ // ─────────────────────────────────────────────
15
+ const c = {
16
+ reset: "\x1b[0m",
17
+ bold: "\x1b[1m",
18
+ dim: "\x1b[2m",
19
+ white: "\x1b[97m",
20
+ gray: "\x1b[90m",
21
+ red: "\x1b[91m",
22
+ green: "\x1b[92m",
23
+ yellow: "\x1b[93m",
24
+ blue: "\x1b[94m",
25
+ magenta: "\x1b[95m",
26
+ cyan: "\x1b[96m",
27
+ };
28
+
29
+ // ─────────────────────────────────────────────
30
+ // Logger
31
+ // ─────────────────────────────────────────────
32
+ const log = {
33
+ info: (msg) =>
34
+ console.log(
35
+ `${c.cyan}${c.bold} ℹ ${c.reset}${c.white}${msg}${c.reset}`,
36
+ ),
37
+ success: (msg) =>
38
+ console.log(
39
+ `${c.green}${c.bold} ✔ ${c.reset}${c.green}${msg}${c.reset}`,
40
+ ),
41
+ warn: (msg) =>
42
+ console.log(
43
+ `${c.yellow}${c.bold} ⚠ ${c.reset}${c.yellow}${msg}${c.reset}`,
44
+ ),
45
+ error: (msg) =>
46
+ console.log(`${c.red}${c.bold} ✖ ${c.reset}${c.red}${msg}${c.reset}`),
47
+ step: (n, label) =>
48
+ console.log(
49
+ `${c.magenta}${c.bold} [${n}] ${c.reset}${c.magenta}${label}${c.reset}`,
50
+ ),
51
+ divider: () => console.log(`${c.gray} ${"─".repeat(52)}${c.reset}`),
52
+ blank: () => console.log(),
53
+ };
54
+
55
+ // ─────────────────────────────────────────────
56
+ // Steps Definition
57
+ // ─────────────────────────────────────────────
58
+ const STEPS = [
59
+ { label: "Memory CLI", fn: installMemoryCLI },
60
+ { label: "XEMS — XyPriss Entry Management System", fn: installXems },
61
+ { label: "XSYS — XyPriss System Core", fn: installXsys },
62
+ ];
63
+
64
+ // ─────────────────────────────────────────────
65
+ // Post-Install Orchestrator
66
+ // ─────────────────────────────────────────────
12
67
  async function postInstall() {
13
- console.log("🔧 Running XyPriss post-install setup...");
68
+ log.blank();
69
+ log.divider();
70
+ console.log(`${c.cyan}${c.bold} XyPriss — Post-Install Setup${c.reset}`);
71
+ log.divider();
72
+ log.blank();
14
73
 
15
- try {
16
- // 1. Install Memory CLI
17
- await installMemoryCLI();
74
+ const results = [];
18
75
 
19
- // 2. Install XEMS (Security Core)
20
- await installXems();
76
+ for (let i = 0; i < STEPS.length; i++) {
77
+ const { label, fn } = STEPS[i];
78
+ log.step(`${i + 1}/${STEPS.length}`, label);
79
+
80
+ try {
81
+ await fn();
82
+ results.push({ label, ok: true });
83
+ } catch (err) {
84
+ log.warn(`Step "${label}" encountered an issue: ${err.message}`);
85
+ results.push({ label, ok: false, err: err.message });
86
+ }
87
+
88
+ log.blank();
89
+ }
21
90
 
22
- // 3. Install XSYS (System Core)
23
- await installXsys();
91
+ // ── Summary ──────────────────────────────────
92
+ log.divider();
93
+ console.log(`${c.cyan}${c.bold} Setup Summary${c.reset}`);
94
+ log.divider();
24
95
 
25
- console.log("✅ XyPriss setup complete!");
26
- } catch (error) {
27
- console.warn(
28
- "⚠️ Post-install setup encountered issues:",
29
- error.message,
96
+ let allOk = true;
97
+ for (const r of results) {
98
+ if (r.ok) {
99
+ log.success(r.label);
100
+ } else {
101
+ log.warn(`${r.label} ${c.gray}(skipped: ${r.err})${c.reset}`);
102
+ allOk = false;
103
+ }
104
+ }
105
+
106
+ log.blank();
107
+
108
+ if (allOk) {
109
+ log.success("All components installed. XyPriss is ready!");
110
+ } else {
111
+ log.warn(
112
+ "Setup completed with warnings. XyPriss will run in fallback mode.",
113
+ );
114
+ log.info(
115
+ "Some features may be limited until missing binaries are installed.",
30
116
  );
31
- console.log("📝 XyPriss will continue to work with fallback mode.");
32
117
  }
118
+
119
+ log.blank();
120
+ log.divider();
121
+ log.blank();
33
122
  }
34
123
 
35
- // Only run if this is the main module (not being imported)
124
+ // ─────────────────────────────────────────────
125
+ // Entry Point
126
+ // ─────────────────────────────────────────────
36
127
  if (import.meta.url === `file://${process.argv[1]}`) {
37
128
  postInstall().catch((error) => {
38
- console.error("💥 Post-install failed:", error);
39
- // Don't exit with error code to avoid breaking npm install
40
- process.exit(0);
129
+ log.error(`Fatal error during post-install: ${error.message}`);
130
+ process.exit(0); // Don't break `npm install`
41
131
  });
42
132
  }
43
133
 
@@ -0,0 +1,113 @@
1
+ #!/usr/bin/env node
2
+ /***************************************************************************
3
+ * XyPrissJS - Fast And Secure
4
+ *
5
+ * @author Nehonix
6
+ * @license Nehonix OSL (NOSL)
7
+ *
8
+ * Copyright (c) 2025 Nehonix. All rights reserved.
9
+ *
10
+ * This License governs the use, modification, and distribution of software
11
+ * provided by NEHONIX under its open source projects.
12
+ * NEHONIX is committed to fostering collaborative innovation while strictly
13
+ * protecting its intellectual property rights.
14
+ * Violation of any term of this License will result in immediate termination of all granted rights
15
+ * and may subject the violator to legal action.
16
+ *
17
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
18
+ * INCLUDING BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE,
19
+ * AND NON-INFRINGEMENT.
20
+ * IN NO EVENT SHALL NEHONIX BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
21
+ * OR CONSEQUENTIAL DAMAGES ARISING FROM THE USE OR INABILITY TO USE THE SOFTWARE,
22
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
23
+ *
24
+ ***************************************************************************** */
25
+
26
+ /**
27
+ * Nehonix XEMS CLI Bridge
28
+ *
29
+ * This is the main bridge for the xems command.
30
+ * It manages the execution of the proprietary Go-based XEMS binary.
31
+ *
32
+ * © 2026 Nehonix Team. All rights reserved.
33
+ */
34
+
35
+ import { spawn } from "node:child_process";
36
+ import path from "node:path";
37
+ import fs from "node:fs";
38
+ import os from "node:os";
39
+ import { fileURLToPath } from "node:url";
40
+
41
+ const __filename = fileURLToPath(import.meta.url);
42
+ const __dirname = path.dirname(__filename);
43
+
44
+ /**
45
+ * Get the path to the xems binary
46
+ */
47
+ function getBinaryPath() {
48
+ const isWin = os.platform() === "win32";
49
+ const binName = isWin ? "xems.exe" : "xems";
50
+
51
+ // Strategic locations for the binary
52
+ const locations = [
53
+ path.join(__dirname, "..", "bin", binName), // Production (npm install)
54
+ path.join(process.cwd(), "bin", binName), // Local development
55
+ path.join(__dirname, "..", "tools", "XEMS", "bin", binName), // Dev target
56
+ path.join(__dirname, "..", "tools", "XEMS", "dist", binName), // Dist target
57
+ ];
58
+
59
+ for (const loc of locations) {
60
+ if (fs.existsSync(loc)) {
61
+ return loc;
62
+ }
63
+ }
64
+
65
+ return null;
66
+ }
67
+
68
+ /**
69
+ * Execute the binary with the provided arguments
70
+ */
71
+ function main() {
72
+ const binaryPath = getBinaryPath();
73
+ const args = process.argv.slice(2);
74
+
75
+ if (!binaryPath) {
76
+ console.error("\x1b[31m[ERROR] XEMS Binary not found.\x1b[0m");
77
+ console.error(
78
+ "Please ensure the binary is installed by running: \x1b[36mxfpm update xypriss\x1b[0m",
79
+ );
80
+ process.exit(1);
81
+ }
82
+
83
+ // Spawn the binary process
84
+ const child = spawn(binaryPath, args, {
85
+ stdio: "inherit",
86
+ env: {
87
+ ...process.env,
88
+ XEMS_BINARY_PATH: binaryPath,
89
+ XEMS_EXEC_CONTEXT: "npm-bin",
90
+ },
91
+ });
92
+
93
+ // Mirror exit signals and codes
94
+ child.on("exit", (code, signal) => {
95
+ if (signal) {
96
+ process.kill(process.pid, signal);
97
+ } else {
98
+ process.exit(code ?? 0);
99
+ }
100
+ });
101
+
102
+ child.on("error", (err) => {
103
+ console.error(
104
+ "\x1b[31m[CRITICAL] Failed to initiate xems execution:\x1b[0m",
105
+ err.message,
106
+ );
107
+ process.exit(1);
108
+ });
109
+ }
110
+
111
+ main();
112
+
113
+