create-contentisland 0.0.2 → 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.
Files changed (2) hide show
  1. package/dist/index.js +226 -221
  2. package/package.json +2 -2
package/dist/index.js CHANGED
@@ -1,10 +1,10 @@
1
1
  import { cac as ae } from "cac";
2
- import S from "prompts";
2
+ import b from "prompts";
3
3
  import { existsSync as w } from "node:fs";
4
- import l from "node:fs/promises";
5
- import g from "node:path";
4
+ import g from "node:fs/promises";
5
+ import d from "node:path";
6
6
  import { createClient as oe } from "@content-island/api-client";
7
- const x = ".content-island", G = "config.json", N = ".gitignore", M = {
7
+ const E = ".content-island", G = "config.json", N = ".gitignore", M = {
8
8
  aa: "Afaraf",
9
9
  ab: "Аҧсуа",
10
10
  ae: "Avesta",
@@ -189,7 +189,7 @@ const x = ".content-island", G = "config.json", N = ".gitignore", M = {
189
189
  za: "Zhuang",
190
190
  zh: "中文",
191
191
  zu: "isiZulu"
192
- }, u = {
192
+ }, m = {
193
193
  reset: "\x1B[0m",
194
194
  green: "\x1B[32m",
195
195
  red: "\x1B[31m",
@@ -198,15 +198,15 @@ const x = ".content-island", G = "config.json", N = ".gitignore", M = {
198
198
  cyan: "\x1B[36m",
199
199
  magenta: "\x1B[35m"
200
200
  }, C = (e) => {
201
- let n = "";
202
- return e?.bold && (n += u.bold), n;
201
+ let t = "";
202
+ return e?.bold && (t += m.bold), t;
203
203
  }, c = {
204
- green: (e, n) => `${u.green}${C(n)}${e}${u.reset}`,
205
- red: (e, n) => `${u.red}${C(n)}${e}${u.reset}`,
206
- yellow: (e, n) => `${u.yellow}${C(n)}${e}${u.reset}`,
207
- bold: (e) => `${u.bold}${e}${u.reset}`,
208
- cyan: (e, n) => `${u.cyan}${C(n)}${e}${u.reset}`,
209
- magenta: (e, n) => `${u.magenta}${C(n)}${e}${u.reset}`
204
+ green: (e, t) => `${m.green}${C(t)}${e}${m.reset}`,
205
+ red: (e, t) => `${m.red}${C(t)}${e}${m.reset}`,
206
+ yellow: (e, t) => `${m.yellow}${C(t)}${e}${m.reset}`,
207
+ bold: (e) => `${m.bold}${e}${m.reset}`,
208
+ cyan: (e, t) => `${m.cyan}${C(t)}${e}${m.reset}`,
209
+ magenta: (e, t) => `${m.magenta}${C(t)}${e}${m.reset}`
210
210
  }, o = {
211
211
  info: (e) => console.log(c.cyan("ℹ️ " + e)),
212
212
  success: (e) => console.log(c.green("✅ " + e)),
@@ -230,60 +230,60 @@ const x = ".content-island", G = "config.json", N = ".gitignore", M = {
230
230
  fetching: (e) => console.log(c.cyan("📥 " + e)),
231
231
  clearing: (e) => console.log(c.yellow("🧹 " + e)),
232
232
  updating: (e) => console.log(c.green("🔄 " + e))
233
- }, A = () => g.join(process.cwd(), x), se = async () => {
234
- const e = process.cwd(), n = g.join(e, N), t = `${x}/`;
233
+ }, A = () => d.join(process.cwd(), E), se = async () => {
234
+ const e = process.cwd(), t = d.join(e, N), n = `${E}/`;
235
235
  let a = "";
236
- w(n) && (a = await l.readFile(n, "utf-8"), a.includes(t)) || (a = a + `${a.endsWith(`
236
+ w(t) && (a = await g.readFile(t, "utf-8"), a.includes(n)) || (a = a + `${a.endsWith(`
237
237
  `) ? "" : `
238
- `}${t}
239
- `, await l.writeFile(n, a, "utf-8"), o.saved(`Added ${t} to ${N}`));
238
+ `}${n}
239
+ `, await g.writeFile(t, a, "utf-8"), o.saved(`Added ${n} to ${N}`));
240
240
  }, K = async () => {
241
241
  const e = A();
242
242
  try {
243
- w(e) || (await l.mkdir(e, { recursive: !0 }), o.created(`Created: ${x}/`)), await se();
244
- } catch (n) {
245
- o.error(`Failed to create config directory: ${n.message}`);
243
+ w(e) || (await g.mkdir(e, { recursive: !0 }), o.created(`Created: ${E}/`)), await se();
244
+ } catch (t) {
245
+ o.error(`Failed to create config directory: ${t.message}`);
246
246
  }
247
- }, J = async () => (await K(), g.join(A(), G)), j = async () => {
247
+ }, J = async () => (await K(), d.join(A(), G)), j = async () => {
248
248
  const e = await J();
249
249
  if (!w(e))
250
250
  return null;
251
251
  try {
252
- const n = await l.readFile(e, "utf-8");
253
- return JSON.parse(n);
254
- } catch (n) {
255
- return o.warning(`Could not parse ${G}: ${n.message}`), null;
252
+ const t = await g.readFile(e, "utf-8");
253
+ return JSON.parse(t);
254
+ } catch (t) {
255
+ return o.warning(`Could not parse ${G}: ${t.message}`), null;
256
256
  }
257
- }, b = async (e) => {
258
- let n = {
257
+ }, S = async (e) => {
258
+ let t = {
259
259
  ...e
260
260
  };
261
- const t = await J();
262
- if (w(t)) {
261
+ const n = await J();
262
+ if (w(n)) {
263
263
  const a = await j();
264
- a && (n = { ...a, ...e });
264
+ a && (t = { ...a, ...e });
265
265
  }
266
266
  try {
267
- const a = JSON.stringify(n, null, 2);
268
- await l.writeFile(t, a, "utf-8"), o.saved(`Saved configuration to ${t}`);
267
+ const a = JSON.stringify(t, null, 2);
268
+ await g.writeFile(n, a, "utf-8"), o.saved(`Saved configuration to ${n}`);
269
269
  } catch (a) {
270
270
  o.error(`Failed to save configuration: ${a.message}`);
271
271
  }
272
- }, ie = (e, n, t, a) => {
273
- let s = 0, i = n, r = !1, f = "", m = !1;
274
- const y = ['"', "'", "`"].includes(t);
275
- for (let p = n; p < e.length; p++) {
276
- const d = e[p];
277
- if (m) {
278
- m = !1;
272
+ }, ie = (e, t, n, a) => {
273
+ let s = 0, i = t, r = !1, u = "", l = !1;
274
+ const y = ['"', "'", "`"].includes(n);
275
+ for (let p = t; p < e.length; p++) {
276
+ const f = e[p];
277
+ if (l) {
278
+ l = !1;
279
279
  continue;
280
280
  }
281
- if (d === "\\" && r) {
282
- m = !0;
281
+ if (f === "\\" && r) {
282
+ l = !0;
283
283
  continue;
284
284
  }
285
285
  if (y) {
286
- if (d === t && !r) {
286
+ if (f === n && !r) {
287
287
  if (s++, s === 1)
288
288
  continue;
289
289
  if (s === 2) {
@@ -291,51 +291,51 @@ const x = ".content-island", G = "config.json", N = ".gitignore", M = {
291
291
  break;
292
292
  }
293
293
  }
294
- } else if (!r && (d === '"' || d === "'" || d === "`"))
295
- r = !0, f = d;
296
- else if (r && d === f)
294
+ } else if (!r && (f === '"' || f === "'" || f === "`"))
295
+ r = !0, u = f;
296
+ else if (r && f === u)
297
297
  r = !1;
298
298
  else if (!r) {
299
- if (d === t)
299
+ if (f === n)
300
300
  s++;
301
- else if (d === a && (s--, s === 0)) {
301
+ else if (f === a && (s--, s === 0)) {
302
302
  i = p + 1;
303
303
  break;
304
304
  }
305
305
  }
306
306
  }
307
307
  return i;
308
- }, E = async (e) => {
309
- const { filePath: n, property: t, startSymbol: a, endSymbol: s } = e, i = await l.readFile(n, "utf-8");
308
+ }, x = async (e) => {
309
+ const { filePath: t, property: n, startSymbol: a, endSymbol: s } = e, i = await g.readFile(t, "utf-8");
310
310
  let r = a;
311
311
  a === "[" && (r = "\\["), a === "{" && (r = "\\{"), a === "(" && (r = "\\(");
312
- const f = new RegExp(`${t}\\s*:\\s*(${r})`), m = i.match(f);
313
- if (!m)
312
+ const u = new RegExp(`${n}\\s*:\\s*(${r})`), l = i.match(u);
313
+ if (!l)
314
314
  return null;
315
- const y = i.indexOf(m[0]) + m[0].length - 1, p = ie(i, y, a, s);
315
+ const y = i.indexOf(l[0]) + l[0].length - 1, p = ie(i, y, a, s);
316
316
  return i.substring(y, p);
317
317
  }, re = (e) => JSON.parse(
318
318
  e.replace(/'/g, '"').replace(/(\w+):/g, '"$1":').replace(/,\s*}/g, "}").replace(/,\s*]/g, "]")
319
- ), q = (e) => e.replace(/"/g, "'").replace(/'(\w+)':/g, "$1:"), ce = async (e, n, t, a) => {
320
- let s = await E(t);
321
- if (s || (s = await E(a)), !s)
319
+ ), q = (e) => e.replace(/"/g, "'").replace(/'(\w+)':/g, "$1:"), ce = async (e, t, n, a) => {
320
+ let s = await x(n);
321
+ if (s || (s = await x(a)), !s)
322
322
  throw new Error(
323
- `Could not find property '${t.property}' or fallback property '${a.property}' in file ${t.filePath}`
323
+ `Could not find property '${n.property}' or fallback property '${a.property}' in file ${n.filePath}`
324
324
  );
325
- const i = q(JSON.stringify(n, null, 2));
326
- return (await l.readFile(t.filePath, "utf-8")).replace(s, (f) => `${f},
325
+ const i = q(JSON.stringify(t, null, 2));
326
+ return (await g.readFile(n.filePath, "utf-8")).replace(s, (u) => `${u},
327
327
  ${e}: ${i}`);
328
- }, T = (e, n) => Array.isArray(e) ? e.map(n) : [], le = (e, n) => ({
328
+ }, T = (e, t) => Array.isArray(e) ? e.map(t) : [], le = (e, t) => ({
329
329
  id: e.id,
330
330
  language: e.language,
331
331
  name: e.name,
332
332
  label: e.label,
333
- pages: T(e.pages, (t) => n.find((a) => a.id === t))
334
- }), ge = (e, n) => ({
333
+ pages: T(e.pages, (n) => t.find((a) => a.id === n))
334
+ }), ge = (e, t) => ({
335
335
  id: e.id,
336
336
  language: e.language,
337
337
  index: e.index,
338
- folders: T(e.folders, (t) => le(t, n))
338
+ folders: T(e.folders, (n) => le(n, t))
339
339
  });
340
340
  let v = null;
341
341
  const de = (e) => {
@@ -345,14 +345,14 @@ const de = (e) => {
345
345
  throw new Error("API client not initialized. Call initializeClient first.");
346
346
  return v;
347
347
  }, ue = async () => await F().getProject(), O = async (e) => {
348
- const n = F(), t = await n.getContent({
348
+ const t = F(), n = await t.getContent({
349
349
  contentType: "Root",
350
350
  includeRelatedContent: !0,
351
351
  language: e
352
352
  });
353
- if (!t)
353
+ if (!n)
354
354
  throw new Error(`Root content not found for language: ${e}`);
355
- const a = t.folders?.flatMap((i) => i.pages) || [], s = await n.getContentList({
355
+ const a = n.folders?.flatMap((i) => i.pages) || [], s = await t.getContentList({
356
356
  contentType: "Page",
357
357
  id: {
358
358
  in: a
@@ -361,84 +361,89 @@ const de = (e) => {
361
361
  });
362
362
  if (!s)
363
363
  throw new Error(`Pages not found for IDs: ${a.join(", ")}`);
364
- return ge(t, s);
364
+ return ge(n, s);
365
365
  }, fe = async () => {
366
366
  try {
367
367
  return await F().getContent({
368
368
  contentType: "Meta"
369
369
  });
370
- } catch {
371
- o.error("The requested template is not of type StarLight, so the meta field could not be found."), process.exit(1);
370
+ } catch (e) {
371
+ e.message.includes("401") ? o.error(
372
+ "The Content Island API token is missing or malformed. Verify that you've copied the complete token and that you have sufficient permissions."
373
+ ) : o.error("The requested template is not of type StarLight, so the meta field could not be found."), process.exit(1);
372
374
  }
373
- }, U = "astro.config.mjs", P = () => g.join(process.cwd(), "src", "content", "docs"), L = () => g.join(process.cwd(), U), me = () => {
374
- const e = [], n = L();
375
- w(n) || e.push(U);
376
- const t = P();
377
- return w(t) || e.push("src/content/docs directory"), {
375
+ }, U = "astro.config.mjs", P = () => d.join(process.cwd(), "src", "content", "docs"), L = () => d.join(process.cwd(), U), me = () => {
376
+ const e = [], t = L();
377
+ w(t) || e.push(U);
378
+ const n = P();
379
+ return w(n) || e.push("src/content/docs directory"), {
378
380
  valid: e.length === 0,
379
381
  missingItems: e
380
382
  };
381
383
  }, pe = async () => {
382
384
  const e = P();
383
385
  if (!w(e)) {
384
- o.info("Content docs directory not found, creating it..."), await l.mkdir(e, { recursive: !0 });
386
+ o.info("Content docs directory not found, creating it..."), await g.mkdir(e, { recursive: !0 });
385
387
  return;
386
388
  }
387
- const n = await l.readdir(e);
388
- for (const t of n) {
389
- const a = g.join(e, t);
390
- await l.rm(a, { recursive: !0, force: !0 });
389
+ const t = await g.readdir(e);
390
+ for (const n of t) {
391
+ const a = d.join(e, n);
392
+ await g.rm(a, { recursive: !0, force: !0 });
391
393
  }
392
394
  }, h = {
393
395
  sidebar: { start: "[", end: "]" },
394
396
  locales: { start: "{", end: "}" },
395
397
  title: { start: "'", end: "'" }
396
- }, W = (e, n) => {
397
- const t = [];
398
- for (const a of n) {
399
- const s = e.findIndex((i) => i.label === a.label);
400
- if (s >= 0) {
401
- const i = a.items && e[s].items ? W(e[s].items || [], a.items) : a.items;
402
- t[s] = {
403
- ...e[s],
404
- ...a,
405
- items: i
398
+ }, W = (e, t) => {
399
+ const n = [], a = [];
400
+ for (const s of t) {
401
+ const i = e.findIndex((r) => r.label === s.label);
402
+ if (i >= 0) {
403
+ const r = s.items && e[i].items ? W(e[i].items || [], s.items) : s.items;
404
+ n[i] = {
405
+ ...e[i],
406
+ ...s,
407
+ items: r
406
408
  };
407
409
  } else
408
- t.push(a);
410
+ a.push(s);
409
411
  }
410
- return t;
411
- }, we = (e, n) => {
412
- const t = {
412
+ return n.push(...a), n.sort((s, i) => {
413
+ const r = t.findIndex((l) => l.label === s.label), u = t.findIndex((l) => l.label === i.label);
414
+ return r - u;
415
+ });
416
+ }, we = (e, t) => {
417
+ const n = {
413
418
  root: { lang: e, label: M[e] }
414
419
  };
415
- return Array.isArray(n) ? n.reduce(
420
+ return Array.isArray(t) ? t.reduce(
416
421
  (a, s) => ({
417
422
  ...a,
418
423
  [s]: { lang: s, label: M[s] }
419
424
  }),
420
- t
421
- ) : t;
422
- }, D = async (e, n, t) => {
423
- const a = L(), s = await E({
425
+ n
426
+ ) : n;
427
+ }, D = async (e, t, n) => {
428
+ const a = L(), s = await x({
424
429
  filePath: a,
425
- property: n,
426
- startSymbol: h[n]?.start,
427
- endSymbol: h[n]?.end
430
+ property: t,
431
+ startSymbol: h[t]?.start,
432
+ endSymbol: h[t]?.end
428
433
  });
429
434
  let i;
430
435
  if (s) {
431
436
  const r = q(JSON.stringify(e, null, 2));
432
- i = (await l.readFile(a, "utf-8")).replace(s, r);
437
+ i = (await g.readFile(a, "utf-8")).replace(s, r);
433
438
  } else
434
439
  i = await ce(
435
- n,
440
+ t,
436
441
  e,
437
442
  {
438
443
  filePath: a,
439
- property: t,
440
- startSymbol: h[t]?.start,
441
- endSymbol: h[t]?.end
444
+ property: n,
445
+ startSymbol: h[n]?.start,
446
+ endSymbol: h[n]?.end
442
447
  },
443
448
  {
444
449
  filePath: a,
@@ -447,10 +452,10 @@ const de = (e) => {
447
452
  endSymbol: h.title.end
448
453
  }
449
454
  );
450
- await l.writeFile(a, i, "utf-8");
451
- }, he = async (e, n, t) => {
455
+ await g.writeFile(a, i, "utf-8");
456
+ }, he = async (e, t, n) => {
452
457
  try {
453
- let a = await E({
458
+ let a = await x({
454
459
  filePath: L(),
455
460
  property: "sidebar",
456
461
  startSymbol: h.sidebar.start,
@@ -464,53 +469,53 @@ const de = (e) => {
464
469
  s || (o.warning("No existing sidebar found in astro.config.mjs. A new sidebar will be created."), s = []);
465
470
  const i = W(s, e);
466
471
  await D(i, "sidebar", "locales");
467
- const r = we(n, t);
472
+ const r = we(t, n);
468
473
  await D(r, "locales", "sidebar");
469
474
  } catch (a) {
470
475
  o.error(`Error reading astro.config.mjs: ${a.message}`), process.exit(1);
471
476
  }
472
- }, ye = (e) => /^---\s*\n([\s\S]*?)\n---\s*\n/.test(e), ke = (e) => g.parse(e).name.replace(/[-_]/g, " ").replace(/([a-z])([A-Z])/g, "$1 $2").split(" ").filter((a) => a.length > 0).map((a) => a.charAt(0).toUpperCase() + a.slice(1).toLowerCase()).join(" ");
473
- function Ce(e, n, t) {
477
+ }, ye = (e) => /^---\s*\n([\s\S]*?)\n---\s*\n/.test(e), ke = (e) => d.parse(e).name.replace(/[-_]/g, " ").replace(/([a-z])([A-Z])/g, "$1 $2").split(" ").filter((a) => a.length > 0).map((a) => a.charAt(0).toUpperCase() + a.slice(1).toLowerCase()).join(" ");
478
+ function Ce(e, t, n) {
474
479
  if (ye(e))
475
480
  return e;
476
- const a = ke(n), s = `---
481
+ const a = ke(t), s = `---
477
482
  title: "${a}"
478
483
  ---
479
484
 
480
485
  `;
481
- return o.warning(`Missing frontmatter in ${t}`), o.info(`Added default title: "${a}"`), o.warning("Please update the content in Content Island 🏝️ to include proper frontmatter"), o.newLine(), s + e;
486
+ return o.warning(`Missing frontmatter in ${n}`), o.info(`Added default title: "${a}"`), o.warning("Please update the content in Content Island 🏝️ to include proper frontmatter"), o.newLine(), s + e;
482
487
  }
483
- const I = async (e, n) => {
484
- const t = P(), a = g.join(t, e), s = Ce(n, e, g.relative(process.cwd(), a)), i = g.dirname(a);
485
- w(i) || await l.mkdir(i, { recursive: !0 }), await l.writeFile(a, s, "utf-8");
486
- }, Se = async (e, n) => {
488
+ const $ = async (e, t) => {
489
+ const n = P(), a = d.join(n, e), s = Ce(t, e, d.relative(process.cwd(), a)), i = d.dirname(a);
490
+ w(i) || await g.mkdir(i, { recursive: !0 }), await g.writeFile(a, s, "utf-8");
491
+ }, be = async (e, t) => {
487
492
  try {
488
- await I(e.index.filename, e.index.content);
489
- for (const t of e.folders)
490
- for (const a of t.pages)
491
- await I(g.join(t.name, a.filename), a.content);
492
- for (const t of n) {
493
- await I(g.join(t.language, t.index.filename), t.index.content);
494
- for (const a of t.folders)
493
+ await $(e.index.filename, e.index.content);
494
+ for (const n of e.folders)
495
+ for (const a of n.pages)
496
+ await $(d.join(n.name, a.filename), a.content);
497
+ for (const n of t) {
498
+ await $(d.join(n.language, n.index.filename), n.index.content);
499
+ for (const a of n.folders)
495
500
  for (const s of a.pages)
496
- await I(g.join(t.language, a.name, s.filename), s.content);
501
+ await $(d.join(n.language, a.name, s.filename), s.content);
497
502
  }
498
- } catch (t) {
499
- o.error(`Error updating docs content: ${t.message}`), process.exit(1);
503
+ } catch (n) {
504
+ o.error(`Error updating docs content: ${n.message}`), process.exit(1);
500
505
  }
501
- }, be = async (e, n) => {
506
+ }, Se = async (e, t) => {
502
507
  if (e.length === 1) {
503
508
  const s = e[0];
504
- return o.success(`Single language found: ${s}. Continuing...`), await b({ languageCode: s }), s;
509
+ return o.success(`Single language found: ${s}. Continuing...`), await S({ languageCode: s }), s;
505
510
  }
506
- const t = (await j())?.languageCode;
507
- if (t && !n) {
508
- if (e.includes(t))
509
- return o.info(`Using saved default language: ${t}`), t;
510
- o.warning(`Saved language '${t}' not found in project languages`), o.step("Will ask for new default language and save it");
511
+ const n = (await j())?.languageCode;
512
+ if (n && !t) {
513
+ if (e.includes(n))
514
+ return o.info(`Using saved default language: ${n}`), n;
515
+ o.warning(`Saved language '${n}' not found in project languages`), o.step("Will ask for new default language and save it");
511
516
  }
512
517
  o.step("Multiple languages found. Please select the default language:");
513
- const a = await S({
518
+ const a = await b({
514
519
  type: "select",
515
520
  name: "language",
516
521
  message: "Select the default language:",
@@ -520,8 +525,8 @@ const I = async (e, n) => {
520
525
  })),
521
526
  initial: 0
522
527
  });
523
- return a.language || (o.error("Language selection is required to continue."), process.exit(1)), t !== a.language && (await b({ languageCode: a.language }), o.config(`Saving default language '${a.language}' to config`)), a.language;
524
- }, $e = () => {
528
+ return a.language || (o.error("Language selection is required to continue."), process.exit(1)), n !== a.language && (await S({ languageCode: a.language }), o.config(`Saving default language '${a.language}' to config`)), a.language;
529
+ }, Ie = () => {
525
530
  o.detected(`
526
531
  ⭐ ✨ STARLIGHT PROJECT DETECTED ✨ ⭐
527
532
 
@@ -533,173 +538,173 @@ const I = async (e, n) => {
533
538
  ✨ ⭐ ✨ ⭐ ✨
534
539
  ⭐ ✨ ⭐ ✨
535
540
  `), o.success("All good! Starlight ⭐ project detected successfully."), o.loading("Launching process..."), o.newLine();
536
- }, Ie = (e) => {
537
- o.newLine(), o.error("Starlight ⭐ project not found!"), o.newLine(), o.error("Missing required items:"), e.forEach((n) => {
538
- o.error(` • ${n}`);
541
+ }, $e = (e) => {
542
+ o.newLine(), o.error("Starlight ⭐ project not found!"), o.newLine(), o.error("Missing required items:"), e.forEach((t) => {
543
+ o.error(` • ${t}`);
539
544
  }), o.newLine(), o.error("Please make sure you are in the root directory of a Starlight ⭐ project."), o.warning("A Starlight ⭐ project should have:"), o.warning(" • astro.config.mjs file"), o.warning(" • src/content/docs directory"), o.newLine();
540
- }, Y = (e) => {
541
- const n = e.reduce(
542
- (t, a) => ({ ...t, ...a }),
545
+ }, V = (e) => {
546
+ const t = e.reduce(
547
+ (n, a) => ({ ...n, ...a }),
543
548
  {}
544
549
  );
545
- return Object.keys(n).length > 0 ? n : void 0;
546
- }, H = (e) => e.filename.replace(/\.(mdx?|md)$/, ""), _ = (e) => e.label ? e.label.trim() : H(e), Ee = (e, n) => {
547
- const t = H(e), a = n.trim().toLowerCase();
548
- return t.toLocaleLowerCase() === "index" ? a : `${a}/${t}`;
549
- }, Te = (e, n, t) => {
550
+ return Object.keys(t).length > 0 ? t : void 0;
551
+ }, Y = (e) => e.filename.replace(/\.(mdx?|md)$/, ""), _ = (e) => e.label ? e.label.trim() : Y(e), xe = (e, t) => {
552
+ const n = Y(e), a = t.trim().toLowerCase();
553
+ return n.toLocaleLowerCase() === "index" ? a : `${a}/${n}`;
554
+ }, Te = (e, t, n) => {
550
555
  e.filename.replace(/\.(mdx?|md)$/, "");
551
- const a = t.filter((s) => s.id === e.id).map((s) => ({ [s.language]: _(s) }));
556
+ const a = n.filter((s) => s.id === e.id).map((s) => ({ [s.language]: _(s) }));
552
557
  return {
553
558
  label: _(e),
554
- slug: Ee(e, n),
555
- translations: Y(a)
559
+ slug: xe(e, t),
560
+ translations: V(a)
556
561
  };
557
- }, R = (e) => e.label ? e.label.trim() : e.name, ve = (e, n) => {
558
- const t = n.flatMap((i) => i.folders ?? []).filter((i) => i.id === e.id), a = t.flatMap((i) => i.pages ?? []).filter((i) => e.pages.some((r) => r.id === i.id)), s = t.map((i) => ({ [i.language]: R(i) }));
562
+ }, R = (e) => e.label ? e.label.trim() : e.name, ve = (e, t) => {
563
+ const n = t.flatMap((i) => i.folders ?? []).filter((i) => i.id === e.id), a = n.flatMap((i) => i.pages ?? []).filter((i) => e.pages.some((r) => r.id === i.id)), s = n.map((i) => ({ [i.language]: R(i) }));
559
564
  return {
560
565
  label: R(e),
561
- translations: Y(s),
566
+ translations: V(s),
562
567
  items: T(e.pages, (i) => Te(i, e.name, a))
563
568
  };
564
- }, xe = (e, n) => T(e.folders, (t) => ve(t, n)), Ae = () => ({
569
+ }, Ee = (e, t) => T(e.folders, (n) => ve(n, t)), Ae = () => ({
565
570
  id: "starlight",
566
571
  syncProject: async (e) => {
567
- const { accessToken: n, askIfMultipleLanguages: t } = e;
572
+ const { accessToken: t, askIfMultipleLanguages: n } = e;
568
573
  o.step("Checking for Starlight ⭐ project...");
569
574
  const { valid: a, missingItems: s } = me();
570
- a || (Ie(s), process.exit(1)), $e(), o.connecting("Initializing Content Island 🏝️ client..."), de(n);
575
+ a || ($e(s), process.exit(1)), Ie(), o.connecting("Initializing Content Island 🏝️ client..."), de(t);
571
576
  const i = await fe();
572
577
  o.success(`Connected to project using template: ${i.template} (version: ${i.version})`), i.template !== "starlight" && (o.warning(
573
578
  "The project you are trying to sync is not using the Starlight ⭐ template. Please make sure you are using the correct template."
574
- ), process.exit(1)), await b({
579
+ ), process.exit(1)), await S({
575
580
  version: i.version
576
581
  }), o.fetching("Fetching project information from Content Island 🏝️ ...");
577
582
  const r = await ue();
578
583
  o.success(`Project fetched: ${r.name}`);
579
- const f = r.languages.map((k) => k);
580
- o.info(`Languages found (${f.length}): ${f.join(", ")}`);
581
- const m = await be(f, t);
582
- o.language(m);
583
- const y = f.filter((k) => k !== m), p = await O(m);
584
- let d = [];
584
+ const u = r.languages.map((k) => k);
585
+ o.info(`Languages found (${u.length}): ${u.join(", ")}`);
586
+ const l = await Se(u, n);
587
+ o.language(l);
588
+ const y = u.filter((k) => k !== l), p = await O(l);
589
+ let f = [];
585
590
  for (const k of y) {
586
591
  const ne = await O(k);
587
- d.push(ne);
592
+ f.push(ne);
588
593
  }
589
- o.clearing("Clearing existing docs content..."), await pe(), o.docs("Existing docs content cleared"), o.updating("Updating docs content with fetched data..."), await Se(p, d), o.docs("Docs content updated"), o.config("Generating sidebar configuration...");
590
- const te = xe(p, d);
591
- await he(te, m, y), o.config("Sidebar configuration updated in astro.config.mjs");
594
+ o.clearing("Clearing existing docs content..."), await pe(), o.docs("Existing docs content cleared"), o.updating("Updating docs content with fetched data..."), await be(p, f), o.docs("Docs content updated"), o.config("Generating sidebar configuration...");
595
+ const te = Ee(p, f);
596
+ await he(te, l, y), o.config("Sidebar configuration updated in astro.config.mjs");
592
597
  }
593
- }), V = {
598
+ }), H = {
594
599
  starlight: Ae
595
600
  }, je = (e) => {
596
- const n = V[e];
597
- if (!n)
601
+ const t = H[e];
602
+ if (!t)
598
603
  throw new Error(`Template "${e}" not found`);
599
- return n();
600
- }, Fe = () => Object.keys(V), Pe = async (e, n) => {
601
- let t;
602
- return t || (t = (await j())?.templateID), t && n && (o.info(`Existing template found: ${t}`), (await S({
604
+ return t();
605
+ }, Fe = () => Object.keys(H), Pe = async (e, t) => {
606
+ let n;
607
+ return n || (n = (await j())?.templateID), n && t && (o.info(`Existing template found: ${n}`), (await b({
603
608
  type: "confirm",
604
609
  name: "useExisting",
605
- message: `An existing template (${t}) was found. Do you want to use it?`,
610
+ message: `An existing template (${n}) was found. Do you want to use it?`,
606
611
  initial: !0
607
- }))?.useExisting ? o.success(`Using existing template: ${t}`) : (t = null, o.step("Selecting new template..."))), t || (o.step("Please select a template:"), t = (await S({
612
+ }))?.useExisting ? o.success(`Using existing template: ${n}`) : (n = null, o.step("Selecting new template..."))), n || (o.step("Please select a template:"), n = (await b({
608
613
  type: "select",
609
614
  name: "templateID",
610
615
  message: "Select a template:",
611
616
  choices: e.map((s) => ({ title: s, value: s }))
612
- }))?.templateID), t || (o.error("Template is required to continue"), process.exit(1)), t;
617
+ }))?.templateID), n || (o.error("Template is required to continue"), process.exit(1)), n;
613
618
  }, Z = async (e) => {
614
619
  try {
615
- const { selectedTemplateId: n, askIfExists: t } = e, a = Fe();
616
- let s = a.find((i) => i === n);
617
- return s || (s = await Pe(a, t)), o.detected(`Template selected: ${s}`), je(s);
618
- } catch (n) {
619
- o.error(`Error configuring template: ${n.message}`), process.exit(1);
620
+ const { selectedTemplateId: t, askIfExists: n } = e, a = Fe();
621
+ let s = a.find((i) => i === t);
622
+ return s || (s = await Pe(a, n)), o.detected(`Template selected: ${s}`), je(s);
623
+ } catch (t) {
624
+ o.error(`Error configuring template: ${t.message}`), process.exit(1);
620
625
  }
621
626
  }, z = ".env", X = "CONTENT_ISLAND_ACCESS_TOKEN", Le = async (e) => {
622
627
  switch (e) {
623
628
  case "starlight":
624
- return await K(), g.join(A(), z);
629
+ return await K(), d.join(A(), z);
625
630
  default:
626
- return g.join(process.cwd(), z);
631
+ return d.join(process.cwd(), z);
627
632
  }
628
633
  }, Ne = async (e) => {
629
634
  if (!w(e))
630
635
  return null;
631
636
  try {
632
- const t = (await l.readFile(e, "utf-8")).match(new RegExp(`${X}=(.+)`));
633
- return t ? t[1].trim() : null;
637
+ const n = (await g.readFile(e, "utf-8")).match(new RegExp(`${X}=(.+)`));
638
+ return n ? n[1].trim() : null;
634
639
  } catch {
635
640
  return null;
636
641
  }
637
- }, Q = async (e, n) => {
642
+ }, Q = async (e, t) => {
638
643
  try {
639
- const t = `${X}=${e}
644
+ const n = `${X}=${e}
640
645
  `;
641
- await l.writeFile(n, t, "utf-8"), o.token(`Access token saved to ${n}`);
642
- } catch (t) {
643
- o.error(`Failed to save the access token: ${t.message}`);
646
+ await g.writeFile(t, n, "utf-8"), o.token(`Access token saved to ${t}`);
647
+ } catch (n) {
648
+ o.error(`Failed to save the access token: ${n.message}`);
644
649
  }
645
650
  }, B = (e) => {
646
651
  e || (o.error("Token is required to continue"), process.exit(1));
647
- }, Me = async (e, n) => {
648
- let t = await Ne(e);
649
- if (t && n && (o.info("Found existing Content Island 🏝️ token"), (await S({
652
+ }, Me = async (e, t) => {
653
+ let n = await Ne(e);
654
+ if (n && t && (o.info("Found existing Content Island 🏝️ token"), (await b({
650
655
  type: "confirm",
651
656
  name: "useExisting",
652
657
  message: "An existing token was found. Do you want to use it?",
653
658
  initial: !0
654
- }))?.useExisting || (t = null)), t)
659
+ }))?.useExisting || (n = null)), n)
655
660
  o.success("Using existing Content Island 🏝️ token");
656
661
  else {
657
- n || o.warning("No existing token found");
658
- const a = await S({
662
+ t || o.warning("No existing token found");
663
+ const a = await b({
659
664
  type: "password",
660
665
  name: "token",
661
666
  message: "Enter your Content Island 🏝️ API token:",
662
667
  validate: (s) => s.length > 0 ? !0 : "Token is required"
663
668
  });
664
- B(a?.token), t = a?.token, await Q(t, e);
669
+ B(a?.token), n = a?.token, await Q(n, e);
665
670
  }
666
- return B(t), t;
671
+ return B(n), n;
667
672
  }, ee = async (e) => {
668
- const { accessToken: n, templateID: t, askIfExists: a } = e;
669
- let s = n;
670
- const i = await Le(t);
673
+ const { accessToken: t, templateID: n, askIfExists: a } = e;
674
+ let s = t;
675
+ const i = await Le(n);
671
676
  return s ? (o.success("Using provided Content Island 🏝️ token"), await Q(s, i)) : s = await Me(i, a), s;
672
677
  }, Oe = async (e) => {
673
678
  try {
674
679
  o.title("Content Island Integration"), o.step("Configuring template...");
675
- const n = await Z({ selectedTemplateId: e.template, askIfExists: !0 });
676
- o.step("Saving configuration..."), await b({ templateID: n.id }), o.config("Template configuration saved"), o.step("Configuring access token...");
677
- const t = await ee({
680
+ const t = await Z({ selectedTemplateId: e.template, askIfExists: !0 });
681
+ o.step("Saving configuration..."), await S({ templateID: t.id }), o.config("Template configuration saved"), o.step("Configuring access token...");
682
+ const n = await ee({
678
683
  accessToken: e.token,
679
- templateID: n.id,
684
+ templateID: t.id,
680
685
  askIfExists: !0
681
686
  });
682
- o.token("Access token configured successfully"), o.step("Synchronizing project..."), await n.syncProject({ accessToken: t, askIfMultipleLanguages: !0 }), o.docs("Project synchronized with Content Island"), o.newLine(), o.complete("Content Island 🏝️ integration completed successfully!");
683
- } catch (n) {
684
- o.newLine(), o.error("Error during Content Island integration:"), o.error(n instanceof Error ? n.message : String(n)), process.exit(1);
687
+ o.token("Access token configured successfully"), o.step("Synchronizing project..."), await t.syncProject({ accessToken: n, askIfMultipleLanguages: !0 }), o.docs("Project synchronized with Content Island"), o.newLine(), o.complete("Content Island 🏝️ integration completed successfully!");
688
+ } catch (t) {
689
+ o.newLine(), o.error("Error during Content Island integration:"), o.error(t instanceof Error ? t.message : String(t)), process.exit(1);
685
690
  }
686
691
  }, De = async () => {
687
692
  try {
688
693
  o.title("Content Island Integration"), o.step("Configuring template...");
689
694
  const e = await Z({ askIfExists: !1 });
690
- o.step("Saving configuration..."), await b({ templateID: e.id }), o.config("Template configuration saved"), o.step("Configuring access token...");
691
- const n = await ee({
695
+ o.step("Saving configuration..."), await S({ templateID: e.id }), o.config("Template configuration saved"), o.step("Configuring access token...");
696
+ const t = await ee({
692
697
  templateID: e.id,
693
698
  askIfExists: !1
694
699
  });
695
- o.token("Access token configured successfully"), o.step("Synchronizing project..."), await e.syncProject({ accessToken: n, askIfMultipleLanguages: !1 }), o.docs("Project synchronized with Content Island"), o.newLine(), o.complete("Content Island 🏝️ integration completed successfully!");
700
+ o.token("Access token configured successfully"), o.step("Synchronizing project..."), await e.syncProject({ accessToken: t, askIfMultipleLanguages: !1 }), o.docs("Project synchronized with Content Island"), o.newLine(), o.complete("Content Island 🏝️ integration completed successfully!");
696
701
  } catch (e) {
697
702
  o.newLine(), o.error("Error during Content Island integration:"), o.error(e instanceof Error ? e.message : String(e)), process.exit(1);
698
703
  }
699
- }, _e = "0.0.2", Re = {
704
+ }, _e = "0.0.4", Re = {
700
705
  version: _e
701
- }, $ = ae("create-contentisland");
702
- $.command("", "Initialize and validate a project").example("npm create contentisland").example("npm create contentisland --token <token>").example("npm create contentisland --token <token> --template starlight").option(
706
+ }, I = ae("create-contentisland");
707
+ I.command("", "Initialize and validate a project").example("npm create contentisland").example("npm create contentisland --token <token>").example("npm create contentisland --token <token> --template starlight").option(
703
708
  "--token <token>",
704
709
  "Your Content Island token (you can also set the CONTENT_ISLAND_ACCESS_TOKEN environment variable)",
705
710
  {
@@ -708,9 +713,9 @@ $.command("", "Initialize and validate a project").example("npm create contentis
708
713
  ).option("--template <template>", "The template to use: starlight.").action(async (e) => {
709
714
  await Oe(e);
710
715
  });
711
- $.command("update", "Update content from Content Island 🏝️ (preserves existing token)").example("npm create contentisland update").action(async () => {
716
+ I.command("update", "Update content from Content Island 🏝️ (preserves existing token)").example("npm create contentisland update").action(async () => {
712
717
  await De();
713
718
  });
714
- $.help();
715
- $.version(Re.version);
716
- $.parse();
719
+ I.help();
720
+ I.version(Re.version);
721
+ I.parse();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-contentisland",
3
- "version": "0.0.2",
3
+ "version": "0.0.4",
4
4
  "description": "Content Island - Starlight CLI",
5
5
  "private": false,
6
6
  "sideEffects": false,
@@ -27,7 +27,7 @@
27
27
  "test:watch": "vitest -c ./config/test/config.ts"
28
28
  },
29
29
  "dependencies": {
30
- "@content-island/api-client": "0.11.0",
30
+ "@content-island/api-client": "0.12.0",
31
31
  "cac": "6.7.14",
32
32
  "prompts": "2.4.2"
33
33
  },