@nexushub/client 0.4.3 → 0.4.4

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/dist/index.js CHANGED
@@ -8,6 +8,164 @@ var __export = (target, all) => {
8
8
  __defProp(target, name, { get: all[name], enumerable: true });
9
9
  };
10
10
 
11
+ // src/config.ts
12
+ var DEFAULT_API_URL, DEFAULT_ANALYTICS_URL, LOCAL_NEST_URL, LOCAL_RUST_URL, getEnvConfig, mergeConfigs, getFullConfig, validateConfig;
13
+ var init_config = __esm({
14
+ "src/config.ts"() {
15
+ "use strict";
16
+ DEFAULT_API_URL = "https://endpoints.gnexus.co.tz";
17
+ DEFAULT_ANALYTICS_URL = "https://sentry.gnexus.co.tz";
18
+ LOCAL_NEST_URL = "https://endpoints.gnexus.co.tz";
19
+ LOCAL_RUST_URL = "https://sentry.gnexus.co.tz";
20
+ getEnvConfig = () => {
21
+ const NEXT_PUBLIC_ID = typeof process !== "undefined" ? process.env.NEXT_PUBLIC_NEXUS_ID : void 0;
22
+ const NEXT_PUBLIC_KEY = typeof process !== "undefined" ? process.env.NEXT_PUBLIC_NEXUS_KEY : void 0;
23
+ const NEXT_PUBLIC_URL = typeof process !== "undefined" ? process.env.NEXT_PUBLIC_NEXUS_API_URL : void 0;
24
+ const NODE_ID = typeof process !== "undefined" ? process.env.NEXUS_PROJECT_ID : void 0;
25
+ const NODE_KEY = typeof process !== "undefined" ? process.env.NEXUS_API_KEY : void 0;
26
+ const NODE_URL = typeof process !== "undefined" ? process.env.NEXUS_API_URL : void 0;
27
+ const NODE_ENV = typeof process !== "undefined" ? process.env.NODE_ENV : "production";
28
+ const isDev = NODE_ENV === "development" || typeof window !== "undefined" && window.location.hostname === "localhost";
29
+ const projectId = NEXT_PUBLIC_ID ?? NODE_ID;
30
+ const apiKey = NEXT_PUBLIC_KEY ?? NODE_KEY;
31
+ const apiUrl = NEXT_PUBLIC_URL ?? NODE_URL ?? (isDev ? LOCAL_NEST_URL : DEFAULT_API_URL);
32
+ const analyticsUrl = apiUrl.includes("localhost") ? LOCAL_RUST_URL : DEFAULT_ANALYTICS_URL;
33
+ return {
34
+ projectId,
35
+ apiKey,
36
+ apiUrl,
37
+ analyticsUrl
38
+ };
39
+ };
40
+ mergeConfigs = (base, override) => {
41
+ const mergedApiUrl = override.apiUrl || base.apiUrl || DEFAULT_API_URL;
42
+ const mergedAnalyticsUrl = override.analyticsUrl || base.analyticsUrl || (mergedApiUrl.includes("localhost") ? LOCAL_RUST_URL : DEFAULT_ANALYTICS_URL);
43
+ return {
44
+ ...base,
45
+ ...override,
46
+ apiUrl: mergedApiUrl,
47
+ analyticsUrl: mergedAnalyticsUrl,
48
+ projectId: override.projectId || base.projectId,
49
+ apiKey: override.apiKey || base.apiKey
50
+ };
51
+ };
52
+ getFullConfig = (partialConfig) => {
53
+ const envConfig = getEnvConfig();
54
+ return mergeConfigs(envConfig, partialConfig || {});
55
+ };
56
+ validateConfig = (config) => {
57
+ const errors = [];
58
+ if (!config.projectId) errors.push("Missing projectId");
59
+ if (!config.apiUrl) errors.push("Missing apiUrl");
60
+ return errors;
61
+ };
62
+ }
63
+ });
64
+
65
+ // src/content/binary-compiler.ts
66
+ import * as crypto2 from "crypto";
67
+ var BinaryCompiler;
68
+ var init_binary_compiler = __esm({
69
+ "src/content/binary-compiler.ts"() {
70
+ "use strict";
71
+ BinaryCompiler = class {
72
+ /**
73
+ * Generates a secure, deterministic cryptographic key from the project's API key.
74
+ */
75
+ static deriveKeys(apiKey) {
76
+ const hash = crypto2.createHash("sha256").update(apiKey).digest();
77
+ const encryptionKey = hash;
78
+ const hmacKey = crypto2.createHmac("sha256", apiKey).update("nexus-integrity-key").digest();
79
+ return { encryptionKey, hmacKey };
80
+ }
81
+ /**
82
+ * Compiles JSON content data into a secure, signed, and encrypted .nx binary buffer.
83
+ */
84
+ static compile(data, apiKey, projectId, metadataOverrides = {}) {
85
+ const { encryptionKey, hmacKey } = this.deriveKeys(apiKey);
86
+ const metadata = {
87
+ version: "2.0.0",
88
+ compiledAt: (/* @__PURE__ */ new Date()).toISOString(),
89
+ projectId,
90
+ ...metadataOverrides
91
+ };
92
+ const metadataStr = JSON.stringify(metadata);
93
+ const metadataBuffer = Buffer.from(metadataStr, "utf-8");
94
+ const iv = crypto2.randomBytes(16);
95
+ const cipher = crypto2.createCipheriv(this.ALGORITHM, encryptionKey, iv);
96
+ const plainTextPayload = JSON.stringify(data);
97
+ let encryptedPayload = cipher.update(plainTextPayload, "utf8");
98
+ encryptedPayload = Buffer.concat([encryptedPayload, cipher.final()]);
99
+ const payloadBuffer = Buffer.concat([iv, encryptedPayload]);
100
+ const headerBuffer = Buffer.from(this.MAGIC_HEADER, "ascii");
101
+ const metaLengthBuffer = Buffer.alloc(4);
102
+ metaLengthBuffer.writeUInt32BE(metadataBuffer.length, 0);
103
+ const payloadLengthBuffer = Buffer.alloc(4);
104
+ payloadLengthBuffer.writeUInt32BE(payloadBuffer.length, 0);
105
+ const prefixBlock = Buffer.concat([
106
+ headerBuffer,
107
+ metaLengthBuffer,
108
+ metadataBuffer,
109
+ payloadLengthBuffer,
110
+ payloadBuffer
111
+ ]);
112
+ const hmac = crypto2.createHmac("sha256", hmacKey);
113
+ hmac.update(prefixBlock);
114
+ const signature = hmac.digest();
115
+ return Buffer.concat([prefixBlock, signature]);
116
+ }
117
+ /**
118
+ * Verifies, decrypts, and decompiles a .nx binary buffer back into clean, type-safe JSON.
119
+ * Throws structured errors on integrity verification failures or file corruption.
120
+ */
121
+ static decompile(buffer, apiKey) {
122
+ if (buffer.length < 44) {
123
+ throw new Error(
124
+ "Corrupted File: Binary payload is too short to be a valid Nexus node."
125
+ );
126
+ }
127
+ const { encryptionKey, hmacKey } = this.deriveKeys(apiKey);
128
+ const prefixBlockLength = buffer.length - 32;
129
+ const prefixBlock = buffer.subarray(0, prefixBlockLength);
130
+ const expectedSignature = buffer.subarray(prefixBlockLength);
131
+ const hmac = crypto2.createHmac("sha256", hmacKey);
132
+ hmac.update(prefixBlock);
133
+ const actualSignature = hmac.digest();
134
+ if (!crypto2.timingSafeEqual(expectedSignature, actualSignature)) {
135
+ throw new Error(
136
+ "DATA_INTEGRITY_VIOLATION: Cryptographic signature mismatch. This local node has been modified externally or tampered with."
137
+ );
138
+ }
139
+ const magicHeader = prefixBlock.subarray(0, 4).toString("ascii");
140
+ if (magicHeader !== this.MAGIC_HEADER) {
141
+ throw new Error(
142
+ "Invalid Format: File lacks the correct Nexus binary magic header."
143
+ );
144
+ }
145
+ const metaLength = prefixBlock.readUInt32BE(4);
146
+ const metaStart = 8;
147
+ const metaEnd = metaStart + metaLength;
148
+ const metadataStr = prefixBlock.subarray(metaStart, metaEnd).toString("utf-8");
149
+ const metadata = JSON.parse(metadataStr);
150
+ const payloadLength = prefixBlock.readUInt32BE(metaEnd);
151
+ const payloadStart = metaEnd + 4;
152
+ const payloadEnd = payloadStart + payloadLength;
153
+ const payloadBuffer = prefixBlock.subarray(payloadStart, payloadEnd);
154
+ const iv = payloadBuffer.subarray(0, 16);
155
+ const cipherText = payloadBuffer.subarray(16);
156
+ const decipher = crypto2.createDecipheriv(this.ALGORITHM, encryptionKey, iv);
157
+ let decrypted = decipher.update(cipherText);
158
+ decrypted = Buffer.concat([decrypted, decipher.final()]);
159
+ const data = JSON.parse(decrypted.toString("utf8"));
160
+ return { data, metadata };
161
+ }
162
+ };
163
+ BinaryCompiler.MAGIC_HEADER = "NEXS";
164
+ // 4-byte ASCII magic identifier
165
+ BinaryCompiler.ALGORITHM = "aes-256-cbc";
166
+ }
167
+ });
168
+
11
169
  // src/content/local-cache-server.ts
12
170
  var local_cache_server_exports = {};
13
171
  __export(local_cache_server_exports, {
@@ -19,84 +177,92 @@ var LocalCache;
19
177
  var init_local_cache_server = __esm({
20
178
  "src/content/local-cache-server.ts"() {
21
179
  "use strict";
180
+ init_config();
181
+ init_binary_compiler();
22
182
  LocalCache = class {
23
183
  constructor(customPath) {
184
+ this.apiKey = "";
24
185
  this.baseDir = customPath || ".nexus/local";
186
+ const config = getEnvConfig();
187
+ this.apiKey = config.apiKey || "";
25
188
  }
26
189
  isLoaded() {
27
190
  return fs.existsSync(path.resolve(process.cwd(), this.baseDir));
28
191
  }
29
192
  /**
30
- * Retrieve a specific page directly from its file.
193
+ * Helper to decrypt and decompile `.nx` files on-the-fly.
31
194
  */
32
- async getPage(slug) {
33
- try {
34
- const filePath = path.resolve(
35
- process.cwd(),
36
- this.baseDir,
37
- "pages",
38
- `${slug}.json`
39
- );
40
- if (fs.existsSync(filePath)) {
41
- const fileContent = fs.readFileSync(filePath, "utf-8");
42
- const pageData = JSON.parse(fileContent);
43
- return pageData.data !== void 0 ? pageData.data : pageData;
195
+ decompileFile(filePath) {
196
+ if (!this.apiKey) {
197
+ if (process.env.NODE_ENV === "development") {
198
+ console.warn(
199
+ "\u26A0\uFE0F NexusHub: Missing NEXUS_API_KEY. Local decryption bypassed."
200
+ );
44
201
  }
202
+ return null;
203
+ }
204
+ try {
205
+ const encryptedBuffer = fs.readFileSync(filePath);
206
+ const decompiled = BinaryCompiler.decompile(encryptedBuffer, this.apiKey);
207
+ return decompiled.data;
45
208
  } catch (error) {
46
209
  if (process.env.NODE_ENV === "development") {
47
- console.warn(
48
- `\u26A0\uFE0F NexusHub: Failed to load local page '${slug}':`,
49
- error
210
+ console.error(
211
+ `
212
+ \u{1F6A8} NexusHub Security Alert: Data Integrity Violation in file:
213
+ ${filePath}
214
+ Error: ${error.message}
215
+ This file has been disabled until regenerated via npx nexus pull.
216
+ `
50
217
  );
51
218
  }
219
+ return null;
220
+ }
221
+ }
222
+ /**
223
+ * Retrieve a specific page directly from its .nx file.
224
+ */
225
+ async getPage(slug) {
226
+ const filePath = path.resolve(
227
+ process.cwd(),
228
+ this.baseDir,
229
+ "pages",
230
+ `${slug}.nx`
231
+ );
232
+ if (fs.existsSync(filePath)) {
233
+ const pageData = this.decompileFile(filePath);
234
+ if (!pageData) return null;
235
+ return pageData.data !== void 0 ? pageData.data : pageData;
52
236
  }
53
237
  return null;
54
238
  }
55
239
  /**
56
- * Retrieve an entire collection from its specific collection file.
240
+ * Retrieve an entire collection from its specific .nx file.
57
241
  */
58
242
  async getCollection(collectionId) {
59
- try {
60
- const filePath = path.resolve(
61
- process.cwd(),
62
- this.baseDir,
63
- "collections",
64
- `${collectionId}.json`
65
- );
66
- if (fs.existsSync(filePath)) {
67
- const fileContent = fs.readFileSync(filePath, "utf-8");
68
- return JSON.parse(fileContent);
69
- }
70
- } catch (error) {
71
- if (process.env.NODE_ENV === "development") {
72
- console.warn(
73
- `\u26A0\uFE0F NexusHub: Failed to load local collection '${collectionId}':`,
74
- error
75
- );
76
- }
243
+ const filePath = path.resolve(
244
+ process.cwd(),
245
+ this.baseDir,
246
+ "collections",
247
+ `${collectionId}.nx`
248
+ );
249
+ if (fs.existsSync(filePath)) {
250
+ return this.decompileFile(filePath);
77
251
  }
78
252
  return null;
79
253
  }
80
254
  /**
81
- * Retrieve global settings from its file.
255
+ * Retrieve global settings from its .nx file.
82
256
  */
83
257
  async getGlobals() {
84
- try {
85
- const filePath = path.resolve(
86
- process.cwd(),
87
- this.baseDir,
88
- "globals.json"
89
- );
90
- if (fs.existsSync(filePath)) {
91
- const fileContent = fs.readFileSync(filePath, "utf-8");
92
- return JSON.parse(fileContent);
93
- }
94
- } catch {
258
+ const filePath = path.resolve(process.cwd(), this.baseDir, "globals.nx");
259
+ if (fs.existsSync(filePath)) {
260
+ return this.decompileFile(filePath);
95
261
  }
96
262
  return null;
97
263
  }
98
264
  /**
99
- * Returns a merged JSON of the entire workspace structure (for dev analytics/inspectors)
265
+ * Returns a merged JSON of the entire workspace structure.
100
266
  */
101
267
  async getAllData() {
102
268
  const pages = {};
@@ -106,8 +272,8 @@ var init_local_cache_server = __esm({
106
272
  const pagesDir = path.resolve(process.cwd(), this.baseDir, "pages");
107
273
  if (fs.existsSync(pagesDir)) {
108
274
  for (const file of fs.readdirSync(pagesDir)) {
109
- if (file.endsWith(".json")) {
110
- const slug = path.basename(file, ".json");
275
+ if (file.endsWith(".nx")) {
276
+ const slug = path.basename(file, ".nx");
111
277
  pages[slug] = await this.getPage(slug);
112
278
  }
113
279
  }
@@ -115,8 +281,8 @@ var init_local_cache_server = __esm({
115
281
  const colsDir = path.resolve(process.cwd(), this.baseDir, "collections");
116
282
  if (fs.existsSync(colsDir)) {
117
283
  for (const file of fs.readdirSync(colsDir)) {
118
- if (file.endsWith(".json")) {
119
- const id = path.basename(file, ".json");
284
+ if (file.endsWith(".nx")) {
285
+ const id = path.basename(file, ".nx");
120
286
  collections[id] = await this.getCollection(id) || [];
121
287
  }
122
288
  }
@@ -197,53 +363,8 @@ var init_local_cache_client = __esm({
197
363
  }
198
364
  });
199
365
 
200
- // src/config.ts
201
- var DEFAULT_API_URL = "https://endpoints.gnexus.co.tz";
202
- var DEFAULT_ANALYTICS_URL = "https://sentry.gnexus.co.tz";
203
- var LOCAL_NEST_URL = "https://endpoints.gnexus.co.tz";
204
- var LOCAL_RUST_URL = "https://sentry.gnexus.co.tz";
205
- var getEnvConfig = () => {
206
- const NEXT_PUBLIC_ID = typeof process !== "undefined" ? process.env.NEXT_PUBLIC_NEXUS_ID : void 0;
207
- const NEXT_PUBLIC_KEY = typeof process !== "undefined" ? process.env.NEXT_PUBLIC_NEXUS_KEY : void 0;
208
- const NEXT_PUBLIC_URL = typeof process !== "undefined" ? process.env.NEXT_PUBLIC_NEXUS_API_URL : void 0;
209
- const NODE_ID = typeof process !== "undefined" ? process.env.NEXUS_PROJECT_ID : void 0;
210
- const NODE_KEY = typeof process !== "undefined" ? process.env.NEXUS_API_KEY : void 0;
211
- const NODE_URL = typeof process !== "undefined" ? process.env.NEXUS_API_URL : void 0;
212
- const NODE_ENV = typeof process !== "undefined" ? process.env.NODE_ENV : "production";
213
- const isDev = NODE_ENV === "development" || typeof window !== "undefined" && window.location.hostname === "localhost";
214
- const projectId = NEXT_PUBLIC_ID ?? NODE_ID;
215
- const apiKey = NEXT_PUBLIC_KEY ?? NODE_KEY;
216
- const apiUrl = NEXT_PUBLIC_URL ?? NODE_URL ?? (isDev ? LOCAL_NEST_URL : DEFAULT_API_URL);
217
- const analyticsUrl = apiUrl.includes("localhost") ? LOCAL_RUST_URL : DEFAULT_ANALYTICS_URL;
218
- return {
219
- projectId,
220
- apiKey,
221
- apiUrl,
222
- analyticsUrl
223
- };
224
- };
225
- var mergeConfigs = (base, override) => {
226
- const mergedApiUrl = override.apiUrl || base.apiUrl || DEFAULT_API_URL;
227
- const mergedAnalyticsUrl = override.analyticsUrl || base.analyticsUrl || (mergedApiUrl.includes("localhost") ? LOCAL_RUST_URL : DEFAULT_ANALYTICS_URL);
228
- return {
229
- ...base,
230
- ...override,
231
- apiUrl: mergedApiUrl,
232
- analyticsUrl: mergedAnalyticsUrl,
233
- projectId: override.projectId || base.projectId,
234
- apiKey: override.apiKey || base.apiKey
235
- };
236
- };
237
- var getFullConfig = (partialConfig) => {
238
- const envConfig = getEnvConfig();
239
- return mergeConfigs(envConfig, partialConfig || {});
240
- };
241
- var validateConfig = (config) => {
242
- const errors = [];
243
- if (!config.projectId) errors.push("Missing projectId");
244
- if (!config.apiUrl) errors.push("Missing apiUrl");
245
- return errors;
246
- };
366
+ // src/client.ts
367
+ init_config();
247
368
 
248
369
  // src/content/cache-implementations.ts
249
370
  var CacheTags = {
@@ -2457,6 +2578,7 @@ var nexus = new NexusClient();
2457
2578
  var createNexusClient = (config) => new NexusClient(config);
2458
2579
 
2459
2580
  // src/index.ts
2581
+ init_config();
2460
2582
  var VERSION = "0.0.1";
2461
2583
  export {
2462
2584
  AnalyticsEngine,
@@ -0,0 +1,224 @@
1
+ import {
2
+ getEnvConfig
3
+ } from "./chunk-NOIMIIA5.js";
4
+
5
+ // src/content/local-cache-server.ts
6
+ import fs from "fs";
7
+ import path from "path";
8
+
9
+ // src/content/binary-compiler.ts
10
+ import * as crypto from "crypto";
11
+ var BinaryCompiler = class {
12
+ /**
13
+ * Generates a secure, deterministic cryptographic key from the project's API key.
14
+ */
15
+ static deriveKeys(apiKey) {
16
+ const hash = crypto.createHash("sha256").update(apiKey).digest();
17
+ const encryptionKey = hash;
18
+ const hmacKey = crypto.createHmac("sha256", apiKey).update("nexus-integrity-key").digest();
19
+ return { encryptionKey, hmacKey };
20
+ }
21
+ /**
22
+ * Compiles JSON content data into a secure, signed, and encrypted .nx binary buffer.
23
+ */
24
+ static compile(data, apiKey, projectId, metadataOverrides = {}) {
25
+ const { encryptionKey, hmacKey } = this.deriveKeys(apiKey);
26
+ const metadata = {
27
+ version: "2.0.0",
28
+ compiledAt: (/* @__PURE__ */ new Date()).toISOString(),
29
+ projectId,
30
+ ...metadataOverrides
31
+ };
32
+ const metadataStr = JSON.stringify(metadata);
33
+ const metadataBuffer = Buffer.from(metadataStr, "utf-8");
34
+ const iv = crypto.randomBytes(16);
35
+ const cipher = crypto.createCipheriv(this.ALGORITHM, encryptionKey, iv);
36
+ const plainTextPayload = JSON.stringify(data);
37
+ let encryptedPayload = cipher.update(plainTextPayload, "utf8");
38
+ encryptedPayload = Buffer.concat([encryptedPayload, cipher.final()]);
39
+ const payloadBuffer = Buffer.concat([iv, encryptedPayload]);
40
+ const headerBuffer = Buffer.from(this.MAGIC_HEADER, "ascii");
41
+ const metaLengthBuffer = Buffer.alloc(4);
42
+ metaLengthBuffer.writeUInt32BE(metadataBuffer.length, 0);
43
+ const payloadLengthBuffer = Buffer.alloc(4);
44
+ payloadLengthBuffer.writeUInt32BE(payloadBuffer.length, 0);
45
+ const prefixBlock = Buffer.concat([
46
+ headerBuffer,
47
+ metaLengthBuffer,
48
+ metadataBuffer,
49
+ payloadLengthBuffer,
50
+ payloadBuffer
51
+ ]);
52
+ const hmac = crypto.createHmac("sha256", hmacKey);
53
+ hmac.update(prefixBlock);
54
+ const signature = hmac.digest();
55
+ return Buffer.concat([prefixBlock, signature]);
56
+ }
57
+ /**
58
+ * Verifies, decrypts, and decompiles a .nx binary buffer back into clean, type-safe JSON.
59
+ * Throws structured errors on integrity verification failures or file corruption.
60
+ */
61
+ static decompile(buffer, apiKey) {
62
+ if (buffer.length < 44) {
63
+ throw new Error(
64
+ "Corrupted File: Binary payload is too short to be a valid Nexus node."
65
+ );
66
+ }
67
+ const { encryptionKey, hmacKey } = this.deriveKeys(apiKey);
68
+ const prefixBlockLength = buffer.length - 32;
69
+ const prefixBlock = buffer.subarray(0, prefixBlockLength);
70
+ const expectedSignature = buffer.subarray(prefixBlockLength);
71
+ const hmac = crypto.createHmac("sha256", hmacKey);
72
+ hmac.update(prefixBlock);
73
+ const actualSignature = hmac.digest();
74
+ if (!crypto.timingSafeEqual(expectedSignature, actualSignature)) {
75
+ throw new Error(
76
+ "DATA_INTEGRITY_VIOLATION: Cryptographic signature mismatch. This local node has been modified externally or tampered with."
77
+ );
78
+ }
79
+ const magicHeader = prefixBlock.subarray(0, 4).toString("ascii");
80
+ if (magicHeader !== this.MAGIC_HEADER) {
81
+ throw new Error(
82
+ "Invalid Format: File lacks the correct Nexus binary magic header."
83
+ );
84
+ }
85
+ const metaLength = prefixBlock.readUInt32BE(4);
86
+ const metaStart = 8;
87
+ const metaEnd = metaStart + metaLength;
88
+ const metadataStr = prefixBlock.subarray(metaStart, metaEnd).toString("utf-8");
89
+ const metadata = JSON.parse(metadataStr);
90
+ const payloadLength = prefixBlock.readUInt32BE(metaEnd);
91
+ const payloadStart = metaEnd + 4;
92
+ const payloadEnd = payloadStart + payloadLength;
93
+ const payloadBuffer = prefixBlock.subarray(payloadStart, payloadEnd);
94
+ const iv = payloadBuffer.subarray(0, 16);
95
+ const cipherText = payloadBuffer.subarray(16);
96
+ const decipher = crypto.createDecipheriv(this.ALGORITHM, encryptionKey, iv);
97
+ let decrypted = decipher.update(cipherText);
98
+ decrypted = Buffer.concat([decrypted, decipher.final()]);
99
+ const data = JSON.parse(decrypted.toString("utf8"));
100
+ return { data, metadata };
101
+ }
102
+ };
103
+ BinaryCompiler.MAGIC_HEADER = "NEXS";
104
+ // 4-byte ASCII magic identifier
105
+ BinaryCompiler.ALGORITHM = "aes-256-cbc";
106
+
107
+ // src/content/local-cache-server.ts
108
+ var LocalCache = class {
109
+ constructor(customPath) {
110
+ this.apiKey = "";
111
+ this.baseDir = customPath || ".nexus/local";
112
+ const config = getEnvConfig();
113
+ this.apiKey = config.apiKey || "";
114
+ }
115
+ isLoaded() {
116
+ return fs.existsSync(path.resolve(process.cwd(), this.baseDir));
117
+ }
118
+ /**
119
+ * Helper to decrypt and decompile `.nx` files on-the-fly.
120
+ */
121
+ decompileFile(filePath) {
122
+ if (!this.apiKey) {
123
+ if (process.env.NODE_ENV === "development") {
124
+ console.warn(
125
+ "\u26A0\uFE0F NexusHub: Missing NEXUS_API_KEY. Local decryption bypassed."
126
+ );
127
+ }
128
+ return null;
129
+ }
130
+ try {
131
+ const encryptedBuffer = fs.readFileSync(filePath);
132
+ const decompiled = BinaryCompiler.decompile(encryptedBuffer, this.apiKey);
133
+ return decompiled.data;
134
+ } catch (error) {
135
+ if (process.env.NODE_ENV === "development") {
136
+ console.error(
137
+ `
138
+ \u{1F6A8} NexusHub Security Alert: Data Integrity Violation in file:
139
+ ${filePath}
140
+ Error: ${error.message}
141
+ This file has been disabled until regenerated via npx nexus pull.
142
+ `
143
+ );
144
+ }
145
+ return null;
146
+ }
147
+ }
148
+ /**
149
+ * Retrieve a specific page directly from its .nx file.
150
+ */
151
+ async getPage(slug) {
152
+ const filePath = path.resolve(
153
+ process.cwd(),
154
+ this.baseDir,
155
+ "pages",
156
+ `${slug}.nx`
157
+ );
158
+ if (fs.existsSync(filePath)) {
159
+ const pageData = this.decompileFile(filePath);
160
+ if (!pageData) return null;
161
+ return pageData.data !== void 0 ? pageData.data : pageData;
162
+ }
163
+ return null;
164
+ }
165
+ /**
166
+ * Retrieve an entire collection from its specific .nx file.
167
+ */
168
+ async getCollection(collectionId) {
169
+ const filePath = path.resolve(
170
+ process.cwd(),
171
+ this.baseDir,
172
+ "collections",
173
+ `${collectionId}.nx`
174
+ );
175
+ if (fs.existsSync(filePath)) {
176
+ return this.decompileFile(filePath);
177
+ }
178
+ return null;
179
+ }
180
+ /**
181
+ * Retrieve global settings from its .nx file.
182
+ */
183
+ async getGlobals() {
184
+ const filePath = path.resolve(process.cwd(), this.baseDir, "globals.nx");
185
+ if (fs.existsSync(filePath)) {
186
+ return this.decompileFile(filePath);
187
+ }
188
+ return null;
189
+ }
190
+ /**
191
+ * Returns a merged JSON of the entire workspace structure.
192
+ */
193
+ async getAllData() {
194
+ const pages = {};
195
+ const collections = {};
196
+ let globals = {};
197
+ try {
198
+ const pagesDir = path.resolve(process.cwd(), this.baseDir, "pages");
199
+ if (fs.existsSync(pagesDir)) {
200
+ for (const file of fs.readdirSync(pagesDir)) {
201
+ if (file.endsWith(".nx")) {
202
+ const slug = path.basename(file, ".nx");
203
+ pages[slug] = await this.getPage(slug);
204
+ }
205
+ }
206
+ }
207
+ const colsDir = path.resolve(process.cwd(), this.baseDir, "collections");
208
+ if (fs.existsSync(colsDir)) {
209
+ for (const file of fs.readdirSync(colsDir)) {
210
+ if (file.endsWith(".nx")) {
211
+ const id = path.basename(file, ".nx");
212
+ collections[id] = await this.getCollection(id) || [];
213
+ }
214
+ }
215
+ }
216
+ globals = await this.getGlobals() || {};
217
+ } catch {
218
+ }
219
+ return { pages, collections, globals };
220
+ }
221
+ };
222
+ export {
223
+ LocalCache
224
+ };