@nexushub/client 0.0.3 → 0.0.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/tools/cli.js CHANGED
@@ -36,7 +36,9 @@ import_dotenv.default.config({ path: import_path.default.resolve(process.cwd(),
36
36
  var program = new import_commander.Command();
37
37
  program.name("nexus").description("NexusHub CLI - The Developer Toolbelt").version("1.0.0");
38
38
  program.command("init").description("Initialize NexusHub configuration and seed data").action(initProject);
39
- program.command("pull").description("Pull latest content from NexusHub to local cache (Offline Mode)").option("-k, --api-key <key>", "NexusHub API Key").option("-p, --project-id <id>", "NexusHub Project ID").option("-u, --api-url <url>", "NexusHub API URL").option("-o, --output <path>", "Output directory (default: .nexus)").option("-f, --force", "Force overwrite existing cache").action(syncContent);
39
+ program.command("pull").description(
40
+ "Pull latest content from NexusHub to local cache (Offline Mode)"
41
+ ).option("-k, --api-key <key>", "NexusHub API Key").option("-p, --project-id <id>", "NexusHub Project ID").option("-u, --api-url <url>", "NexusHub API URL").option("-o, --output <path>", "Output directory (default: .nexus)").option("-f, --force", "Force overwrite existing cache").action(syncContent);
40
42
  program.command("seed").description("Seed content from local files to NexusHub").option("-i, --input <path>", "Input directory (default: .nexus/seed)").option("-p, --project-id <id>", "NexusHub Project ID").option("-k, --api-key <key>", "NexusHub API Key").option("-u, --api-url <url>", "NexusHub API URL").option("--dry-run", "Validate seed data without uploading").action(seedContent);
41
43
  program.command("deploy").description("Trigger a production deployment").option("-p, --project-id <id>", "NexusHub Project ID").option("-k, --api-key <key>", "NexusHub API Key").option("-u, --api-url <url>", "NexusHub API URL").option("-e, --environment <env>", "Deployment environment", "production").action(triggerDeploy);
42
44
  program.command("status").description("Check project status and content statistics").option("-p, --project-id <id>", "NexusHub Project ID").option("-k, --api-key <key>", "NexusHub API Key").option("-u, --api-url <url>", "NexusHub API URL").action(checkStatus);
@@ -48,7 +50,11 @@ async function getContext() {
48
50
  const apiUrl = process.env.NEXUS_API_URL || "https://api.nexushub.com/v1";
49
51
  if (!apiKey || !projectId) {
50
52
  console.error(import_chalk.default.red("\n\u274C Missing Configuration"));
51
- console.log(import_chalk.default.gray("Please set NEXUS_API_KEY and NEXUS_PROJECT_ID in your .env file."));
53
+ console.log(
54
+ import_chalk.default.gray(
55
+ "Please set NEXUS_API_KEY and NEXUS_PROJECT_ID in your .env file."
56
+ )
57
+ );
52
58
  process.exit(1);
53
59
  }
54
60
  return { apiKey, projectId, apiUrl };
@@ -59,7 +65,7 @@ async function fetchWithAuth(url, apiKey, timeout = 3e4) {
59
65
  try {
60
66
  const response = await (0, import_node_fetch.default)(url, {
61
67
  headers: {
62
- "Authorization": `Bearer ${apiKey}`,
68
+ Authorization: `Bearer ${apiKey}`,
63
69
  "Content-Type": "application/json",
64
70
  "User-Agent": "NexusHub-CLI/1.0.0"
65
71
  },
@@ -101,7 +107,12 @@ async function fetchCollections(baseUrl, apiKey, projectId) {
101
107
  const itemsData = itemsRes;
102
108
  result[collection.slug || collection.id] = itemsData.data || itemsData.items || [];
103
109
  } catch (error) {
104
- console.warn(import_chalk.default.yellow(`\u26A0\uFE0F Failed to fetch collection ${collection.id}:`, error instanceof Error ? error.message : String(error)));
110
+ console.warn(
111
+ import_chalk.default.yellow(
112
+ `\u26A0\uFE0F Failed to fetch collection ${collection.id}:`,
113
+ error instanceof Error ? error.message : String(error)
114
+ )
115
+ );
105
116
  }
106
117
  })
107
118
  );
@@ -163,9 +174,17 @@ async function initProject() {
163
174
  copyright: "\xA9 2024 My Site"
164
175
  }
165
176
  };
166
- await fs.writeJson(import_path.default.join(seedDir, "pages.json"), examplePages, { spaces: 2 });
167
- await fs.writeJson(import_path.default.join(collectionsDir, "blog_posts.json"), exampleCollection, { spaces: 2 });
168
- await fs.writeJson(import_path.default.join(seedDir, "globals.json"), exampleGlobals, { spaces: 2 });
177
+ await fs.writeJson(import_path.default.join(seedDir, "pages.json"), examplePages, {
178
+ spaces: 2
179
+ });
180
+ await fs.writeJson(
181
+ import_path.default.join(collectionsDir, "blog_posts.json"),
182
+ exampleCollection,
183
+ { spaces: 2 }
184
+ );
185
+ await fs.writeJson(import_path.default.join(seedDir, "globals.json"), exampleGlobals, {
186
+ spaces: 2
187
+ });
169
188
  const gitignorePath = import_path.default.join(nexusDir, ".gitignore");
170
189
  await fs.writeFile(gitignorePath, "cache.json\n");
171
190
  const readmePath = import_path.default.join(nexusDir, "README.md");
@@ -208,7 +227,9 @@ This directory contains seed data for your NexusHub project.
208
227
  console.log(import_chalk.default.gray(" NEXUS_PROJECT_ID=your_project_id_here"));
209
228
  console.log(import_chalk.default.gray(" 3. Run `npx nexus seed` to upload content"));
210
229
  } catch (error) {
211
- console.error(import_chalk.default.red(`\u274C Failed to initialize project: ${error.message}`));
230
+ console.error(
231
+ import_chalk.default.red(`\u274C Failed to initialize project: ${error.message}`)
232
+ );
212
233
  process.exit(1);
213
234
  }
214
235
  }
@@ -220,16 +241,26 @@ async function syncContent(options) {
220
241
  const outputDir = options.output || ".nexus";
221
242
  if (!apiKey || !projectId) {
222
243
  console.error(import_chalk.default.red("\u274C Missing API Key or Project ID"));
223
- console.log(import_chalk.default.gray("Set NEXUS_API_KEY and NEXUS_PROJECT_ID in .env or use --api-key and --project-id flags"));
244
+ console.log(
245
+ import_chalk.default.gray(
246
+ "Set NEXUS_API_KEY and NEXUS_PROJECT_ID in .env or use --api-key and --project-id flags"
247
+ )
248
+ );
224
249
  process.exit(1);
225
250
  }
226
- const spinner = (0, import_ora.default)(`Fetching content for project: ${import_chalk.default.green(projectId)}...`).start();
251
+ const spinner = (0, import_ora.default)(
252
+ `Fetching content for project: ${import_chalk.default.green(projectId)}...`
253
+ ).start();
227
254
  try {
228
255
  const cacheDir = import_path.default.join(process.cwd(), outputDir);
229
256
  const cacheFile = import_path.default.join(cacheDir, "cache.json");
230
257
  if (await fs.pathExists(cacheFile) && !options.force) {
231
258
  spinner.stop();
232
- console.log(import_chalk.default.yellow("\u26A0\uFE0F Cache file already exists. Use --force to overwrite."));
259
+ console.log(
260
+ import_chalk.default.yellow(
261
+ "\u26A0\uFE0F Cache file already exists. Use --force to overwrite."
262
+ )
263
+ );
233
264
  process.exit(0);
234
265
  }
235
266
  const [pages, collections, globals] = await Promise.all([
@@ -256,7 +287,9 @@ async function syncContent(options) {
256
287
  spinner.succeed(import_chalk.default.green("Content synced successfully!"));
257
288
  console.log(import_chalk.default.gray(` \u{1F4C1} Saved to: ${cacheFile}`));
258
289
  console.log(import_chalk.default.gray(` \u{1F4CA} Pages: ${cacheData.meta.count.pages}`));
259
- console.log(import_chalk.default.gray(` \u{1F4DA} Collections: ${cacheData.meta.count.collections}`));
290
+ console.log(
291
+ import_chalk.default.gray(` \u{1F4DA} Collections: ${cacheData.meta.count.collections}`)
292
+ );
260
293
  console.log(import_chalk.default.yellow(` \u26A1 Mode: Offline / Local Cache Enabled`));
261
294
  } catch (error) {
262
295
  spinner.fail(import_chalk.default.red("Failed to sync content"));
@@ -264,7 +297,9 @@ async function syncContent(options) {
264
297
  if (error.message.includes("401") || error.message.includes("403")) {
265
298
  console.log(import_chalk.default.yellow(" \u{1F511} Check your API key and permissions"));
266
299
  } else if (error.message.includes("404")) {
267
- console.log(import_chalk.default.yellow(" \u{1F50D} Project not found. Check your project ID"));
300
+ console.log(
301
+ import_chalk.default.yellow(" \u{1F50D} Project not found. Check your project ID")
302
+ );
268
303
  }
269
304
  process.exit(1);
270
305
  }
@@ -285,7 +320,9 @@ async function seedContent(options) {
285
320
  console.error(import_chalk.default.red(`\u274C Seed directory not found: ${seedPath}`));
286
321
  console.log(import_chalk.default.gray("Create a seed directory with your content files:"));
287
322
  console.log(import_chalk.default.gray(" mkdir -p .nexus/seed"));
288
- console.log(import_chalk.default.gray(" # Add pages.json, collections/ folder, globals.json"));
323
+ console.log(
324
+ import_chalk.default.gray(" # Add pages.json, collections/ folder, globals.json")
325
+ );
289
326
  process.exit(1);
290
327
  }
291
328
  const spinner = (0, import_ora.default)("Validating seed data...").start();
@@ -307,7 +344,12 @@ async function seedContent(options) {
307
344
  if (await fs.pathExists(collectionsDir)) {
308
345
  if (!dryRun) {
309
346
  spinner.text = "Seeding collections...";
310
- const counts = await seedCollections(collectionsDir, apiUrl, projectId, apiKey);
347
+ const counts = await seedCollections(
348
+ collectionsDir,
349
+ apiUrl,
350
+ projectId,
351
+ apiKey
352
+ );
311
353
  collectionCount = counts.collections;
312
354
  itemCount = counts.items;
313
355
  } else {
@@ -343,7 +385,7 @@ async function seedPages(pages, apiUrl, projectId, apiKey) {
343
385
  const response = await (0, import_node_fetch.default)(`${apiUrl}/content/${projectId}/pages`, {
344
386
  method: "POST",
345
387
  headers: {
346
- "Authorization": `Bearer ${apiKey}`,
388
+ Authorization: `Bearer ${apiKey}`,
347
389
  "Content-Type": "application/json"
348
390
  },
349
391
  body: JSON.stringify(page)
@@ -376,14 +418,16 @@ async function seedCollections(collectionsDir, apiUrl, projectId, apiKey) {
376
418
  const filePath = import_path.default.join(collectionsDir, file);
377
419
  const items = await fs.readJson(filePath);
378
420
  if (!Array.isArray(items)) {
379
- console.warn(import_chalk.default.yellow(` \u26A0\uFE0F ${file} does not contain a valid array of items`));
421
+ console.warn(
422
+ import_chalk.default.yellow(` \u26A0\uFE0F ${file} does not contain a valid array of items`)
423
+ );
380
424
  continue;
381
425
  }
382
426
  try {
383
427
  await (0, import_node_fetch.default)(`${apiUrl}/content/${projectId}/collections`, {
384
428
  method: "POST",
385
429
  headers: {
386
- "Authorization": `Bearer ${apiKey}`,
430
+ Authorization: `Bearer ${apiKey}`,
387
431
  "Content-Type": "application/json"
388
432
  },
389
433
  body: JSON.stringify({
@@ -395,23 +439,38 @@ async function seedCollections(collectionsDir, apiUrl, projectId, apiKey) {
395
439
  let itemCount = 0;
396
440
  for (const item of items) {
397
441
  try {
398
- await (0, import_node_fetch.default)(`${apiUrl}/content/${projectId}/collections/${collectionName}/items`, {
399
- method: "POST",
400
- headers: {
401
- "Authorization": `Bearer ${apiKey}`,
402
- "Content-Type": "application/json"
403
- },
404
- body: JSON.stringify(item)
405
- });
442
+ await (0, import_node_fetch.default)(
443
+ `${apiUrl}/content/${projectId}/collections/${collectionName}/items`,
444
+ {
445
+ method: "POST",
446
+ headers: {
447
+ Authorization: `Bearer ${apiKey}`,
448
+ "Content-Type": "application/json"
449
+ },
450
+ body: JSON.stringify(item)
451
+ }
452
+ );
406
453
  itemCount++;
407
454
  } catch (error) {
408
- console.warn(import_chalk.default.yellow(` Failed to create item in ${collectionName}: ${error instanceof Error ? error.message : String(error)}`));
455
+ console.warn(
456
+ import_chalk.default.yellow(
457
+ ` Failed to create item in ${collectionName}: ${error instanceof Error ? error.message : String(error)}`
458
+ )
459
+ );
409
460
  }
410
461
  }
411
- console.log(import_chalk.default.gray(` \u2705 Created collection ${collectionName} with ${itemCount} items`));
462
+ console.log(
463
+ import_chalk.default.gray(
464
+ ` \u2705 Created collection ${collectionName} with ${itemCount} items`
465
+ )
466
+ );
412
467
  totalItems += itemCount;
413
468
  } catch (error) {
414
- console.warn(import_chalk.default.yellow(` \u274C Failed to create collection ${collectionName}: ${error.message}`));
469
+ console.warn(
470
+ import_chalk.default.yellow(
471
+ ` \u274C Failed to create collection ${collectionName}: ${error.message}`
472
+ )
473
+ );
415
474
  }
416
475
  }
417
476
  return { collections: jsonFiles.length, items: totalItems };
@@ -421,14 +480,16 @@ async function seedGlobals(globals, apiUrl, projectId, apiKey) {
421
480
  await (0, import_node_fetch.default)(`${apiUrl}/project/${projectId}/globals`, {
422
481
  method: "PUT",
423
482
  headers: {
424
- "Authorization": `Bearer ${apiKey}`,
483
+ Authorization: `Bearer ${apiKey}`,
425
484
  "Content-Type": "application/json"
426
485
  },
427
486
  body: JSON.stringify(globals)
428
487
  });
429
488
  console.log(import_chalk.default.gray(" \u2705 Created globals"));
430
489
  } catch (error) {
431
- console.warn(import_chalk.default.yellow(` \u274C Failed to create globals: ${error.message}`));
490
+ console.warn(
491
+ import_chalk.default.yellow(` \u274C Failed to create globals: ${error.message}`)
492
+ );
432
493
  }
433
494
  }
434
495
  async function triggerDeploy(options) {
@@ -446,7 +507,7 @@ async function triggerDeploy(options) {
446
507
  const response = await (0, import_node_fetch.default)(`${apiUrl}/projects/${projectId}/deploy`, {
447
508
  method: "POST",
448
509
  headers: {
449
- "Authorization": `Bearer ${apiKey}`,
510
+ Authorization: `Bearer ${apiKey}`,
450
511
  "Content-Type": "application/json"
451
512
  },
452
513
  body: JSON.stringify({
@@ -460,7 +521,9 @@ async function triggerDeploy(options) {
460
521
  spinner.succeed(import_chalk.default.green("Deployment triggered successfully!"));
461
522
  console.log(import_chalk.default.gray(` \u{1F517} Deployment ID: ${data.deploymentId}`));
462
523
  console.log(import_chalk.default.gray(` \u{1F30D} Environment: ${environment}`));
463
- console.log(import_chalk.default.gray(` \u23F0 Started at: ${(/* @__PURE__ */ new Date()).toLocaleTimeString()}`));
524
+ console.log(
525
+ import_chalk.default.gray(` \u23F0 Started at: ${(/* @__PURE__ */ new Date()).toLocaleTimeString()}`)
526
+ );
464
527
  } else {
465
528
  throw new Error(`API Error ${response.status}: ${response.statusText}`);
466
529
  }
@@ -483,7 +546,7 @@ async function checkStatus(options) {
483
546
  try {
484
547
  const response = await (0, import_node_fetch.default)(`${apiUrl}/projects/${projectId}/status`, {
485
548
  headers: {
486
- "Authorization": `Bearer ${apiKey}`,
549
+ Authorization: `Bearer ${apiKey}`,
487
550
  "Content-Type": "application/json"
488
551
  }
489
552
  });
@@ -495,7 +558,11 @@ async function checkStatus(options) {
495
558
  console.log(import_chalk.default.gray(` \u{1F4C4} Pages: ${data.stats.pages}`));
496
559
  console.log(import_chalk.default.gray(` \u{1F4DA} Collections: ${data.stats.collections}`));
497
560
  console.log(import_chalk.default.gray(` \u{1F465} Users: ${data.stats.users}`));
498
- console.log(import_chalk.default.gray(` \u{1F552} Last Updated: ${new Date(data.project.updatedAt).toLocaleString()}`));
561
+ console.log(
562
+ import_chalk.default.gray(
563
+ ` \u{1F552} Last Updated: ${new Date(data.project.updatedAt).toLocaleString()}`
564
+ )
565
+ );
499
566
  } else {
500
567
  throw new Error(`API Error ${response.status}: ${response.statusText}`);
501
568
  }
@@ -510,7 +577,7 @@ async function generateTypes(options) {
510
577
  const spinner = (0, import_ora.default)("Fetching Content Schema...").start();
511
578
  try {
512
579
  const response = await (0, import_node_fetch.default)(`${apiUrl}/content/${projectId}/schema`, {
513
- headers: { "Authorization": `Bearer ${apiKey}` }
580
+ headers: { Authorization: `Bearer ${apiKey}` }
514
581
  });
515
582
  if (!response.ok) throw new Error(`API Error: ${response.statusText}`);
516
583
  const schema = await response.json();
@@ -550,7 +617,11 @@ async function generateTypes(options) {
550
617
  await fs.writeFile(outputPath, typeDefs);
551
618
  spinner.succeed(import_chalk.default.green(`Types generated at ${options.output}`));
552
619
  if (collections.length > 0) {
553
- console.log(import_chalk.default.gray(` \u2728 You can now use: nexus.getCollection<${formatInterfaceName(collections[0].slug)}>('${collections[0].slug}')`));
620
+ console.log(
621
+ import_chalk.default.gray(
622
+ ` \u2728 You can now use: nexus.getCollection<${formatInterfaceName(collections[0].slug)}>('${collections[0].slug}')`
623
+ )
624
+ );
554
625
  }
555
626
  } catch (error) {
556
627
  spinner.fail(import_chalk.default.red("Failed to generate types"));
@@ -13,7 +13,9 @@ dotenv.config({ path: path.resolve(process.cwd(), ".env") });
13
13
  var program = new Command();
14
14
  program.name("nexus").description("NexusHub CLI - The Developer Toolbelt").version("1.0.0");
15
15
  program.command("init").description("Initialize NexusHub configuration and seed data").action(initProject);
16
- program.command("pull").description("Pull latest content from NexusHub to local cache (Offline Mode)").option("-k, --api-key <key>", "NexusHub API Key").option("-p, --project-id <id>", "NexusHub Project ID").option("-u, --api-url <url>", "NexusHub API URL").option("-o, --output <path>", "Output directory (default: .nexus)").option("-f, --force", "Force overwrite existing cache").action(syncContent);
16
+ program.command("pull").description(
17
+ "Pull latest content from NexusHub to local cache (Offline Mode)"
18
+ ).option("-k, --api-key <key>", "NexusHub API Key").option("-p, --project-id <id>", "NexusHub Project ID").option("-u, --api-url <url>", "NexusHub API URL").option("-o, --output <path>", "Output directory (default: .nexus)").option("-f, --force", "Force overwrite existing cache").action(syncContent);
17
19
  program.command("seed").description("Seed content from local files to NexusHub").option("-i, --input <path>", "Input directory (default: .nexus/seed)").option("-p, --project-id <id>", "NexusHub Project ID").option("-k, --api-key <key>", "NexusHub API Key").option("-u, --api-url <url>", "NexusHub API URL").option("--dry-run", "Validate seed data without uploading").action(seedContent);
18
20
  program.command("deploy").description("Trigger a production deployment").option("-p, --project-id <id>", "NexusHub Project ID").option("-k, --api-key <key>", "NexusHub API Key").option("-u, --api-url <url>", "NexusHub API URL").option("-e, --environment <env>", "Deployment environment", "production").action(triggerDeploy);
19
21
  program.command("status").description("Check project status and content statistics").option("-p, --project-id <id>", "NexusHub Project ID").option("-k, --api-key <key>", "NexusHub API Key").option("-u, --api-url <url>", "NexusHub API URL").action(checkStatus);
@@ -25,7 +27,11 @@ async function getContext() {
25
27
  const apiUrl = process.env.NEXUS_API_URL || "https://api.nexushub.com/v1";
26
28
  if (!apiKey || !projectId) {
27
29
  console.error(chalk.red("\n\u274C Missing Configuration"));
28
- console.log(chalk.gray("Please set NEXUS_API_KEY and NEXUS_PROJECT_ID in your .env file."));
30
+ console.log(
31
+ chalk.gray(
32
+ "Please set NEXUS_API_KEY and NEXUS_PROJECT_ID in your .env file."
33
+ )
34
+ );
29
35
  process.exit(1);
30
36
  }
31
37
  return { apiKey, projectId, apiUrl };
@@ -36,7 +42,7 @@ async function fetchWithAuth(url, apiKey, timeout = 3e4) {
36
42
  try {
37
43
  const response = await fetch(url, {
38
44
  headers: {
39
- "Authorization": `Bearer ${apiKey}`,
45
+ Authorization: `Bearer ${apiKey}`,
40
46
  "Content-Type": "application/json",
41
47
  "User-Agent": "NexusHub-CLI/1.0.0"
42
48
  },
@@ -78,7 +84,12 @@ async function fetchCollections(baseUrl, apiKey, projectId) {
78
84
  const itemsData = itemsRes;
79
85
  result[collection.slug || collection.id] = itemsData.data || itemsData.items || [];
80
86
  } catch (error) {
81
- console.warn(chalk.yellow(`\u26A0\uFE0F Failed to fetch collection ${collection.id}:`, error instanceof Error ? error.message : String(error)));
87
+ console.warn(
88
+ chalk.yellow(
89
+ `\u26A0\uFE0F Failed to fetch collection ${collection.id}:`,
90
+ error instanceof Error ? error.message : String(error)
91
+ )
92
+ );
82
93
  }
83
94
  })
84
95
  );
@@ -140,9 +151,17 @@ async function initProject() {
140
151
  copyright: "\xA9 2024 My Site"
141
152
  }
142
153
  };
143
- await fs.writeJson(path.join(seedDir, "pages.json"), examplePages, { spaces: 2 });
144
- await fs.writeJson(path.join(collectionsDir, "blog_posts.json"), exampleCollection, { spaces: 2 });
145
- await fs.writeJson(path.join(seedDir, "globals.json"), exampleGlobals, { spaces: 2 });
154
+ await fs.writeJson(path.join(seedDir, "pages.json"), examplePages, {
155
+ spaces: 2
156
+ });
157
+ await fs.writeJson(
158
+ path.join(collectionsDir, "blog_posts.json"),
159
+ exampleCollection,
160
+ { spaces: 2 }
161
+ );
162
+ await fs.writeJson(path.join(seedDir, "globals.json"), exampleGlobals, {
163
+ spaces: 2
164
+ });
146
165
  const gitignorePath = path.join(nexusDir, ".gitignore");
147
166
  await fs.writeFile(gitignorePath, "cache.json\n");
148
167
  const readmePath = path.join(nexusDir, "README.md");
@@ -185,7 +204,9 @@ This directory contains seed data for your NexusHub project.
185
204
  console.log(chalk.gray(" NEXUS_PROJECT_ID=your_project_id_here"));
186
205
  console.log(chalk.gray(" 3. Run `npx nexus seed` to upload content"));
187
206
  } catch (error) {
188
- console.error(chalk.red(`\u274C Failed to initialize project: ${error.message}`));
207
+ console.error(
208
+ chalk.red(`\u274C Failed to initialize project: ${error.message}`)
209
+ );
189
210
  process.exit(1);
190
211
  }
191
212
  }
@@ -197,16 +218,26 @@ async function syncContent(options) {
197
218
  const outputDir = options.output || ".nexus";
198
219
  if (!apiKey || !projectId) {
199
220
  console.error(chalk.red("\u274C Missing API Key or Project ID"));
200
- console.log(chalk.gray("Set NEXUS_API_KEY and NEXUS_PROJECT_ID in .env or use --api-key and --project-id flags"));
221
+ console.log(
222
+ chalk.gray(
223
+ "Set NEXUS_API_KEY and NEXUS_PROJECT_ID in .env or use --api-key and --project-id flags"
224
+ )
225
+ );
201
226
  process.exit(1);
202
227
  }
203
- const spinner = ora(`Fetching content for project: ${chalk.green(projectId)}...`).start();
228
+ const spinner = ora(
229
+ `Fetching content for project: ${chalk.green(projectId)}...`
230
+ ).start();
204
231
  try {
205
232
  const cacheDir = path.join(process.cwd(), outputDir);
206
233
  const cacheFile = path.join(cacheDir, "cache.json");
207
234
  if (await fs.pathExists(cacheFile) && !options.force) {
208
235
  spinner.stop();
209
- console.log(chalk.yellow("\u26A0\uFE0F Cache file already exists. Use --force to overwrite."));
236
+ console.log(
237
+ chalk.yellow(
238
+ "\u26A0\uFE0F Cache file already exists. Use --force to overwrite."
239
+ )
240
+ );
210
241
  process.exit(0);
211
242
  }
212
243
  const [pages, collections, globals] = await Promise.all([
@@ -233,7 +264,9 @@ async function syncContent(options) {
233
264
  spinner.succeed(chalk.green("Content synced successfully!"));
234
265
  console.log(chalk.gray(` \u{1F4C1} Saved to: ${cacheFile}`));
235
266
  console.log(chalk.gray(` \u{1F4CA} Pages: ${cacheData.meta.count.pages}`));
236
- console.log(chalk.gray(` \u{1F4DA} Collections: ${cacheData.meta.count.collections}`));
267
+ console.log(
268
+ chalk.gray(` \u{1F4DA} Collections: ${cacheData.meta.count.collections}`)
269
+ );
237
270
  console.log(chalk.yellow(` \u26A1 Mode: Offline / Local Cache Enabled`));
238
271
  } catch (error) {
239
272
  spinner.fail(chalk.red("Failed to sync content"));
@@ -241,7 +274,9 @@ async function syncContent(options) {
241
274
  if (error.message.includes("401") || error.message.includes("403")) {
242
275
  console.log(chalk.yellow(" \u{1F511} Check your API key and permissions"));
243
276
  } else if (error.message.includes("404")) {
244
- console.log(chalk.yellow(" \u{1F50D} Project not found. Check your project ID"));
277
+ console.log(
278
+ chalk.yellow(" \u{1F50D} Project not found. Check your project ID")
279
+ );
245
280
  }
246
281
  process.exit(1);
247
282
  }
@@ -262,7 +297,9 @@ async function seedContent(options) {
262
297
  console.error(chalk.red(`\u274C Seed directory not found: ${seedPath}`));
263
298
  console.log(chalk.gray("Create a seed directory with your content files:"));
264
299
  console.log(chalk.gray(" mkdir -p .nexus/seed"));
265
- console.log(chalk.gray(" # Add pages.json, collections/ folder, globals.json"));
300
+ console.log(
301
+ chalk.gray(" # Add pages.json, collections/ folder, globals.json")
302
+ );
266
303
  process.exit(1);
267
304
  }
268
305
  const spinner = ora("Validating seed data...").start();
@@ -284,7 +321,12 @@ async function seedContent(options) {
284
321
  if (await fs.pathExists(collectionsDir)) {
285
322
  if (!dryRun) {
286
323
  spinner.text = "Seeding collections...";
287
- const counts = await seedCollections(collectionsDir, apiUrl, projectId, apiKey);
324
+ const counts = await seedCollections(
325
+ collectionsDir,
326
+ apiUrl,
327
+ projectId,
328
+ apiKey
329
+ );
288
330
  collectionCount = counts.collections;
289
331
  itemCount = counts.items;
290
332
  } else {
@@ -320,7 +362,7 @@ async function seedPages(pages, apiUrl, projectId, apiKey) {
320
362
  const response = await fetch(`${apiUrl}/content/${projectId}/pages`, {
321
363
  method: "POST",
322
364
  headers: {
323
- "Authorization": `Bearer ${apiKey}`,
365
+ Authorization: `Bearer ${apiKey}`,
324
366
  "Content-Type": "application/json"
325
367
  },
326
368
  body: JSON.stringify(page)
@@ -353,14 +395,16 @@ async function seedCollections(collectionsDir, apiUrl, projectId, apiKey) {
353
395
  const filePath = path.join(collectionsDir, file);
354
396
  const items = await fs.readJson(filePath);
355
397
  if (!Array.isArray(items)) {
356
- console.warn(chalk.yellow(` \u26A0\uFE0F ${file} does not contain a valid array of items`));
398
+ console.warn(
399
+ chalk.yellow(` \u26A0\uFE0F ${file} does not contain a valid array of items`)
400
+ );
357
401
  continue;
358
402
  }
359
403
  try {
360
404
  await fetch(`${apiUrl}/content/${projectId}/collections`, {
361
405
  method: "POST",
362
406
  headers: {
363
- "Authorization": `Bearer ${apiKey}`,
407
+ Authorization: `Bearer ${apiKey}`,
364
408
  "Content-Type": "application/json"
365
409
  },
366
410
  body: JSON.stringify({
@@ -372,23 +416,38 @@ async function seedCollections(collectionsDir, apiUrl, projectId, apiKey) {
372
416
  let itemCount = 0;
373
417
  for (const item of items) {
374
418
  try {
375
- await fetch(`${apiUrl}/content/${projectId}/collections/${collectionName}/items`, {
376
- method: "POST",
377
- headers: {
378
- "Authorization": `Bearer ${apiKey}`,
379
- "Content-Type": "application/json"
380
- },
381
- body: JSON.stringify(item)
382
- });
419
+ await fetch(
420
+ `${apiUrl}/content/${projectId}/collections/${collectionName}/items`,
421
+ {
422
+ method: "POST",
423
+ headers: {
424
+ Authorization: `Bearer ${apiKey}`,
425
+ "Content-Type": "application/json"
426
+ },
427
+ body: JSON.stringify(item)
428
+ }
429
+ );
383
430
  itemCount++;
384
431
  } catch (error) {
385
- console.warn(chalk.yellow(` Failed to create item in ${collectionName}: ${error instanceof Error ? error.message : String(error)}`));
432
+ console.warn(
433
+ chalk.yellow(
434
+ ` Failed to create item in ${collectionName}: ${error instanceof Error ? error.message : String(error)}`
435
+ )
436
+ );
386
437
  }
387
438
  }
388
- console.log(chalk.gray(` \u2705 Created collection ${collectionName} with ${itemCount} items`));
439
+ console.log(
440
+ chalk.gray(
441
+ ` \u2705 Created collection ${collectionName} with ${itemCount} items`
442
+ )
443
+ );
389
444
  totalItems += itemCount;
390
445
  } catch (error) {
391
- console.warn(chalk.yellow(` \u274C Failed to create collection ${collectionName}: ${error.message}`));
446
+ console.warn(
447
+ chalk.yellow(
448
+ ` \u274C Failed to create collection ${collectionName}: ${error.message}`
449
+ )
450
+ );
392
451
  }
393
452
  }
394
453
  return { collections: jsonFiles.length, items: totalItems };
@@ -398,14 +457,16 @@ async function seedGlobals(globals, apiUrl, projectId, apiKey) {
398
457
  await fetch(`${apiUrl}/project/${projectId}/globals`, {
399
458
  method: "PUT",
400
459
  headers: {
401
- "Authorization": `Bearer ${apiKey}`,
460
+ Authorization: `Bearer ${apiKey}`,
402
461
  "Content-Type": "application/json"
403
462
  },
404
463
  body: JSON.stringify(globals)
405
464
  });
406
465
  console.log(chalk.gray(" \u2705 Created globals"));
407
466
  } catch (error) {
408
- console.warn(chalk.yellow(` \u274C Failed to create globals: ${error.message}`));
467
+ console.warn(
468
+ chalk.yellow(` \u274C Failed to create globals: ${error.message}`)
469
+ );
409
470
  }
410
471
  }
411
472
  async function triggerDeploy(options) {
@@ -423,7 +484,7 @@ async function triggerDeploy(options) {
423
484
  const response = await fetch(`${apiUrl}/projects/${projectId}/deploy`, {
424
485
  method: "POST",
425
486
  headers: {
426
- "Authorization": `Bearer ${apiKey}`,
487
+ Authorization: `Bearer ${apiKey}`,
427
488
  "Content-Type": "application/json"
428
489
  },
429
490
  body: JSON.stringify({
@@ -437,7 +498,9 @@ async function triggerDeploy(options) {
437
498
  spinner.succeed(chalk.green("Deployment triggered successfully!"));
438
499
  console.log(chalk.gray(` \u{1F517} Deployment ID: ${data.deploymentId}`));
439
500
  console.log(chalk.gray(` \u{1F30D} Environment: ${environment}`));
440
- console.log(chalk.gray(` \u23F0 Started at: ${(/* @__PURE__ */ new Date()).toLocaleTimeString()}`));
501
+ console.log(
502
+ chalk.gray(` \u23F0 Started at: ${(/* @__PURE__ */ new Date()).toLocaleTimeString()}`)
503
+ );
441
504
  } else {
442
505
  throw new Error(`API Error ${response.status}: ${response.statusText}`);
443
506
  }
@@ -460,7 +523,7 @@ async function checkStatus(options) {
460
523
  try {
461
524
  const response = await fetch(`${apiUrl}/projects/${projectId}/status`, {
462
525
  headers: {
463
- "Authorization": `Bearer ${apiKey}`,
526
+ Authorization: `Bearer ${apiKey}`,
464
527
  "Content-Type": "application/json"
465
528
  }
466
529
  });
@@ -472,7 +535,11 @@ async function checkStatus(options) {
472
535
  console.log(chalk.gray(` \u{1F4C4} Pages: ${data.stats.pages}`));
473
536
  console.log(chalk.gray(` \u{1F4DA} Collections: ${data.stats.collections}`));
474
537
  console.log(chalk.gray(` \u{1F465} Users: ${data.stats.users}`));
475
- console.log(chalk.gray(` \u{1F552} Last Updated: ${new Date(data.project.updatedAt).toLocaleString()}`));
538
+ console.log(
539
+ chalk.gray(
540
+ ` \u{1F552} Last Updated: ${new Date(data.project.updatedAt).toLocaleString()}`
541
+ )
542
+ );
476
543
  } else {
477
544
  throw new Error(`API Error ${response.status}: ${response.statusText}`);
478
545
  }
@@ -487,7 +554,7 @@ async function generateTypes(options) {
487
554
  const spinner = ora("Fetching Content Schema...").start();
488
555
  try {
489
556
  const response = await fetch(`${apiUrl}/content/${projectId}/schema`, {
490
- headers: { "Authorization": `Bearer ${apiKey}` }
557
+ headers: { Authorization: `Bearer ${apiKey}` }
491
558
  });
492
559
  if (!response.ok) throw new Error(`API Error: ${response.statusText}`);
493
560
  const schema = await response.json();
@@ -527,7 +594,11 @@ async function generateTypes(options) {
527
594
  await fs.writeFile(outputPath, typeDefs);
528
595
  spinner.succeed(chalk.green(`Types generated at ${options.output}`));
529
596
  if (collections.length > 0) {
530
- console.log(chalk.gray(` \u2728 You can now use: nexus.getCollection<${formatInterfaceName(collections[0].slug)}>('${collections[0].slug}')`));
597
+ console.log(
598
+ chalk.gray(
599
+ ` \u2728 You can now use: nexus.getCollection<${formatInterfaceName(collections[0].slug)}>('${collections[0].slug}')`
600
+ )
601
+ );
531
602
  }
532
603
  } catch (error) {
533
604
  spinner.fail(chalk.red("Failed to generate types"));
package/package.json CHANGED
@@ -1,19 +1,19 @@
1
1
  {
2
2
  "name": "@nexushub/client",
3
3
  "private": false,
4
- "version": "0.0.3",
4
+ "version": "0.0.4",
5
5
  "description": "The God-Tier NexusHub SDK",
6
6
  "main": "dist/src/index.js",
7
7
  "types": "dist/src/index.d.ts",
8
8
  "bin": {
9
- "nexus": "./dist/cli.js"
9
+ "nexus": "dist/tools/cli.js"
10
10
  },
11
11
  "files": [
12
12
  "dist",
13
13
  "README.md"
14
14
  ],
15
15
  "scripts": {
16
- "build": "tsup src/index.ts tools/cli.ts --format esm,cjs --dts --clean",
16
+ "build": "tsup src/index.ts tools/cli.ts --format esm,cjs --dts --clean && chmod +x ./dist/tools/cli.js",
17
17
  "dev": "tsup src/index.ts tools/cli.ts --format esm,cjs --dts --watch",
18
18
  "test": "jest",
19
19
  "test:coverage": "jest --coverage",