create-contentisland 0.0.3 → 0.0.5

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 +213 -210
  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,68 +291,68 @@ 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
- }, v = 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 v(t);
321
- if (s || (s = await v(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
- let E = null;
340
+ let v = null;
341
341
  const de = (e) => {
342
- E = oe({ accessToken: e });
342
+ v = oe({ accessToken: e });
343
343
  }, F = () => {
344
- if (!E)
344
+ if (!v)
345
345
  throw new Error("API client not initialized. Call initializeClient first.");
346
- return E;
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,7 +361,7 @@ 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({
@@ -372,75 +372,78 @@ const de = (e) => {
372
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
373
  ) : o.error("The requested template is not of type StarLight, so the meta field could not be found."), process.exit(1);
374
374
  }
375
- }, U = "astro.config.mjs", P = () => g.join(process.cwd(), "src", "content", "docs"), L = () => g.join(process.cwd(), U), me = () => {
376
- const e = [], n = L();
377
- w(n) || e.push(U);
378
- const t = P();
379
- 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"), {
380
380
  valid: e.length === 0,
381
381
  missingItems: e
382
382
  };
383
383
  }, pe = async () => {
384
384
  const e = P();
385
385
  if (!w(e)) {
386
- 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 });
387
387
  return;
388
388
  }
389
- const n = await l.readdir(e);
390
- for (const t of n) {
391
- const a = g.join(e, t);
392
- 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 });
393
393
  }
394
394
  }, h = {
395
395
  sidebar: { start: "[", end: "]" },
396
396
  locales: { start: "{", end: "}" },
397
397
  title: { start: "'", end: "'" }
398
- }, W = (e, n) => {
399
- const t = [];
400
- for (const a of n) {
401
- const s = e.findIndex((i) => i.label === a.label);
402
- if (s >= 0) {
403
- const i = a.items && e[s].items ? W(e[s].items || [], a.items) : a.items;
404
- t[s] = {
405
- ...e[s],
406
- ...a,
407
- 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
408
408
  };
409
409
  } else
410
- t.push(a);
410
+ a.push(s);
411
411
  }
412
- return t;
413
- }, we = (e, n) => {
414
- 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 = {
415
418
  root: { lang: e, label: M[e] }
416
419
  };
417
- return Array.isArray(n) ? n.reduce(
420
+ return Array.isArray(t) ? t.reduce(
418
421
  (a, s) => ({
419
422
  ...a,
420
423
  [s]: { lang: s, label: M[s] }
421
424
  }),
422
- t
423
- ) : t;
424
- }, D = async (e, n, t) => {
425
- const a = L(), s = await v({
425
+ n
426
+ ) : n;
427
+ }, D = async (e, t, n) => {
428
+ const a = L(), s = await x({
426
429
  filePath: a,
427
- property: n,
428
- startSymbol: h[n]?.start,
429
- endSymbol: h[n]?.end
430
+ property: t,
431
+ startSymbol: h[t]?.start,
432
+ endSymbol: h[t]?.end
430
433
  });
431
434
  let i;
432
435
  if (s) {
433
436
  const r = q(JSON.stringify(e, null, 2));
434
- i = (await l.readFile(a, "utf-8")).replace(s, r);
437
+ i = (await g.readFile(a, "utf-8")).replace(s, r);
435
438
  } else
436
439
  i = await ce(
437
- n,
440
+ t,
438
441
  e,
439
442
  {
440
443
  filePath: a,
441
- property: t,
442
- startSymbol: h[t]?.start,
443
- endSymbol: h[t]?.end
444
+ property: n,
445
+ startSymbol: h[n]?.start,
446
+ endSymbol: h[n]?.end
444
447
  },
445
448
  {
446
449
  filePath: a,
@@ -449,10 +452,10 @@ const de = (e) => {
449
452
  endSymbol: h.title.end
450
453
  }
451
454
  );
452
- await l.writeFile(a, i, "utf-8");
453
- }, he = async (e, n, t) => {
455
+ await g.writeFile(a, i, "utf-8");
456
+ }, he = async (e, t, n) => {
454
457
  try {
455
- let a = await v({
458
+ let a = await x({
456
459
  filePath: L(),
457
460
  property: "sidebar",
458
461
  startSymbol: h.sidebar.start,
@@ -466,53 +469,53 @@ const de = (e) => {
466
469
  s || (o.warning("No existing sidebar found in astro.config.mjs. A new sidebar will be created."), s = []);
467
470
  const i = W(s, e);
468
471
  await D(i, "sidebar", "locales");
469
- const r = we(n, t);
472
+ const r = we(t, n);
470
473
  await D(r, "locales", "sidebar");
471
474
  } catch (a) {
472
475
  o.error(`Error reading astro.config.mjs: ${a.message}`), process.exit(1);
473
476
  }
474
- }, 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(" ");
475
- 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) {
476
479
  if (ye(e))
477
480
  return e;
478
- const a = ke(n), s = `---
481
+ const a = ke(t), s = `---
479
482
  title: "${a}"
480
483
  ---
481
484
 
482
485
  `;
483
- 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;
484
487
  }
485
- const $ = async (e, n) => {
486
- const t = P(), a = g.join(t, e), s = Ce(n, e, g.relative(process.cwd(), a)), i = g.dirname(a);
487
- w(i) || await l.mkdir(i, { recursive: !0 }), await l.writeFile(a, s, "utf-8");
488
- }, 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) => {
489
492
  try {
490
493
  await $(e.index.filename, e.index.content);
491
- for (const t of e.folders)
492
- for (const a of t.pages)
493
- await $(g.join(t.name, a.filename), a.content);
494
- for (const t of n) {
495
- await $(g.join(t.language, t.index.filename), t.index.content);
496
- for (const a of t.folders)
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)
497
500
  for (const s of a.pages)
498
- await $(g.join(t.language, a.name, s.filename), s.content);
501
+ await $(d.join(n.language, a.name, s.filename), s.content);
499
502
  }
500
- } catch (t) {
501
- 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);
502
505
  }
503
- }, be = async (e, n) => {
506
+ }, Se = async (e, t) => {
504
507
  if (e.length === 1) {
505
508
  const s = e[0];
506
- 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;
507
510
  }
508
- const t = (await j())?.languageCode;
509
- if (t && !n) {
510
- if (e.includes(t))
511
- return o.info(`Using saved default language: ${t}`), t;
512
- 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");
513
516
  }
514
517
  o.step("Multiple languages found. Please select the default language:");
515
- const a = await S({
518
+ const a = await b({
516
519
  type: "select",
517
520
  name: "language",
518
521
  message: "Select the default language:",
@@ -522,7 +525,7 @@ const $ = async (e, n) => {
522
525
  })),
523
526
  initial: 0
524
527
  });
525
- 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;
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;
526
529
  }, Ie = () => {
527
530
  o.detected(`
528
531
  ⭐ ✨ STARLIGHT PROJECT DETECTED ✨ ⭐
@@ -536,169 +539,169 @@ const $ = async (e, n) => {
536
539
  ⭐ ✨ ⭐ ✨
537
540
  `), o.success("All good! Starlight ⭐ project detected successfully."), o.loading("Launching process..."), o.newLine();
538
541
  }, $e = (e) => {
539
- o.newLine(), o.error("Starlight ⭐ project not found!"), o.newLine(), o.error("Missing required items:"), e.forEach((n) => {
540
- o.error(` • ${n}`);
542
+ o.newLine(), o.error("Starlight ⭐ project not found!"), o.newLine(), o.error("Missing required items:"), e.forEach((t) => {
543
+ o.error(` • ${t}`);
541
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();
542
545
  }, V = (e) => {
543
- const n = e.reduce(
544
- (t, a) => ({ ...t, ...a }),
546
+ const t = e.reduce(
547
+ (n, a) => ({ ...n, ...a }),
545
548
  {}
546
549
  );
547
- return Object.keys(n).length > 0 ? n : void 0;
548
- }, Y = (e) => e.filename.replace(/\.(mdx?|md)$/, ""), _ = (e) => e.label ? e.label.trim() : Y(e), ve = (e, n) => {
549
- const t = Y(e), a = n.trim().toLowerCase();
550
- return t.toLocaleLowerCase() === "index" ? a : `${a}/${t}`;
551
- }, 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) => {
552
555
  e.filename.replace(/\.(mdx?|md)$/, "");
553
- 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) }));
554
557
  return {
555
558
  label: _(e),
556
- slug: ve(e, n),
559
+ slug: xe(e, t),
557
560
  translations: V(a)
558
561
  };
559
- }, R = (e) => e.label ? e.label.trim() : e.name, Ee = (e, n) => {
560
- 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) }));
561
564
  return {
562
565
  label: R(e),
563
566
  translations: V(s),
564
567
  items: T(e.pages, (i) => Te(i, e.name, a))
565
568
  };
566
- }, xe = (e, n) => T(e.folders, (t) => Ee(t, n)), Ae = () => ({
569
+ }, Ee = (e, t) => T(e.folders, (n) => ve(n, t)), Ae = () => ({
567
570
  id: "starlight",
568
571
  syncProject: async (e) => {
569
- const { accessToken: n, askIfMultipleLanguages: t } = e;
572
+ const { accessToken: t, askIfMultipleLanguages: n } = e;
570
573
  o.step("Checking for Starlight ⭐ project...");
571
574
  const { valid: a, missingItems: s } = me();
572
- a || ($e(s), process.exit(1)), Ie(), o.connecting("Initializing Content Island 🏝️ client..."), de(n);
575
+ a || ($e(s), process.exit(1)), Ie(), o.connecting("Initializing Content Island 🏝️ client..."), de(t);
573
576
  const i = await fe();
574
577
  o.success(`Connected to project using template: ${i.template} (version: ${i.version})`), i.template !== "starlight" && (o.warning(
575
578
  "The project you are trying to sync is not using the Starlight ⭐ template. Please make sure you are using the correct template."
576
- ), process.exit(1)), await b({
579
+ ), process.exit(1)), await S({
577
580
  version: i.version
578
581
  }), o.fetching("Fetching project information from Content Island 🏝️ ...");
579
582
  const r = await ue();
580
583
  o.success(`Project fetched: ${r.name}`);
581
- const f = r.languages.map((k) => k);
582
- o.info(`Languages found (${f.length}): ${f.join(", ")}`);
583
- const m = await be(f, t);
584
- o.language(m);
585
- const y = f.filter((k) => k !== m), p = await O(m);
586
- 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 = [];
587
590
  for (const k of y) {
588
591
  const ne = await O(k);
589
- d.push(ne);
592
+ f.push(ne);
590
593
  }
591
- 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...");
592
- const te = xe(p, d);
593
- 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");
594
597
  }
595
598
  }), H = {
596
599
  starlight: Ae
597
600
  }, je = (e) => {
598
- const n = H[e];
599
- if (!n)
601
+ const t = H[e];
602
+ if (!t)
600
603
  throw new Error(`Template "${e}" not found`);
601
- return n();
602
- }, Fe = () => Object.keys(H), Pe = async (e, n) => {
603
- let t;
604
- 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({
605
608
  type: "confirm",
606
609
  name: "useExisting",
607
- 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?`,
608
611
  initial: !0
609
- }))?.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({
610
613
  type: "select",
611
614
  name: "templateID",
612
615
  message: "Select a template:",
613
616
  choices: e.map((s) => ({ title: s, value: s }))
614
- }))?.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;
615
618
  }, Z = async (e) => {
616
619
  try {
617
- const { selectedTemplateId: n, askIfExists: t } = e, a = Fe();
618
- let s = a.find((i) => i === n);
619
- return s || (s = await Pe(a, t)), o.detected(`Template selected: ${s}`), je(s);
620
- } catch (n) {
621
- 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);
622
625
  }
623
626
  }, z = ".env", X = "CONTENT_ISLAND_ACCESS_TOKEN", Le = async (e) => {
624
627
  switch (e) {
625
628
  case "starlight":
626
- return await K(), g.join(A(), z);
629
+ return await K(), d.join(A(), z);
627
630
  default:
628
- return g.join(process.cwd(), z);
631
+ return d.join(process.cwd(), z);
629
632
  }
630
633
  }, Ne = async (e) => {
631
634
  if (!w(e))
632
635
  return null;
633
636
  try {
634
- const t = (await l.readFile(e, "utf-8")).match(new RegExp(`${X}=(.+)`));
635
- 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;
636
639
  } catch {
637
640
  return null;
638
641
  }
639
- }, Q = async (e, n) => {
642
+ }, Q = async (e, t) => {
640
643
  try {
641
- const t = `${X}=${e}
644
+ const n = `${X}=${e}
642
645
  `;
643
- await l.writeFile(n, t, "utf-8"), o.token(`Access token saved to ${n}`);
644
- } catch (t) {
645
- 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}`);
646
649
  }
647
650
  }, B = (e) => {
648
651
  e || (o.error("Token is required to continue"), process.exit(1));
649
- }, Me = async (e, n) => {
650
- let t = await Ne(e);
651
- 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({
652
655
  type: "confirm",
653
656
  name: "useExisting",
654
657
  message: "An existing token was found. Do you want to use it?",
655
658
  initial: !0
656
- }))?.useExisting || (t = null)), t)
659
+ }))?.useExisting || (n = null)), n)
657
660
  o.success("Using existing Content Island 🏝️ token");
658
661
  else {
659
- n || o.warning("No existing token found");
660
- const a = await S({
662
+ t || o.warning("No existing token found");
663
+ const a = await b({
661
664
  type: "password",
662
665
  name: "token",
663
666
  message: "Enter your Content Island 🏝️ API token:",
664
667
  validate: (s) => s.length > 0 ? !0 : "Token is required"
665
668
  });
666
- B(a?.token), t = a?.token, await Q(t, e);
669
+ B(a?.token), n = a?.token, await Q(n, e);
667
670
  }
668
- return B(t), t;
671
+ return B(n), n;
669
672
  }, ee = async (e) => {
670
- const { accessToken: n, templateID: t, askIfExists: a } = e;
671
- let s = n;
672
- const i = await Le(t);
673
+ const { accessToken: t, templateID: n, askIfExists: a } = e;
674
+ let s = t;
675
+ const i = await Le(n);
673
676
  return s ? (o.success("Using provided Content Island 🏝️ token"), await Q(s, i)) : s = await Me(i, a), s;
674
677
  }, Oe = async (e) => {
675
678
  try {
676
679
  o.title("Content Island Integration"), o.step("Configuring template...");
677
- const n = await Z({ selectedTemplateId: e.template, askIfExists: !0 });
678
- o.step("Saving configuration..."), await b({ templateID: n.id }), o.config("Template configuration saved"), o.step("Configuring access token...");
679
- 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({
680
683
  accessToken: e.token,
681
- templateID: n.id,
684
+ templateID: t.id,
682
685
  askIfExists: !0
683
686
  });
684
- 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!");
685
- } catch (n) {
686
- 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);
687
690
  }
688
691
  }, De = async () => {
689
692
  try {
690
693
  o.title("Content Island Integration"), o.step("Configuring template...");
691
694
  const e = await Z({ askIfExists: !1 });
692
- o.step("Saving configuration..."), await b({ templateID: e.id }), o.config("Template configuration saved"), o.step("Configuring access token...");
693
- 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({
694
697
  templateID: e.id,
695
698
  askIfExists: !1
696
699
  });
697
- 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!");
698
701
  } catch (e) {
699
702
  o.newLine(), o.error("Error during Content Island integration:"), o.error(e instanceof Error ? e.message : String(e)), process.exit(1);
700
703
  }
701
- }, _e = "0.0.3", Re = {
704
+ }, _e = "0.0.5", Re = {
702
705
  version: _e
703
706
  }, I = ae("create-contentisland");
704
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(
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-contentisland",
3
- "version": "0.0.3",
3
+ "version": "0.0.5",
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.12.0",
30
+ "@content-island/api-client": "0.13.0",
31
31
  "cac": "6.7.14",
32
32
  "prompts": "2.4.2"
33
33
  },