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.
- package/dist/index.js +213 -210
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { cac as ae } from "cac";
|
|
2
|
-
import
|
|
2
|
+
import b from "prompts";
|
|
3
3
|
import { existsSync as w } from "node:fs";
|
|
4
|
-
import
|
|
5
|
-
import
|
|
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
|
|
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
|
-
},
|
|
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
|
|
202
|
-
return e?.bold && (
|
|
201
|
+
let t = "";
|
|
202
|
+
return e?.bold && (t += m.bold), t;
|
|
203
203
|
}, c = {
|
|
204
|
-
green: (e,
|
|
205
|
-
red: (e,
|
|
206
|
-
yellow: (e,
|
|
207
|
-
bold: (e) => `${
|
|
208
|
-
cyan: (e,
|
|
209
|
-
magenta: (e,
|
|
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 = () =>
|
|
234
|
-
const e = process.cwd(),
|
|
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(
|
|
236
|
+
w(t) && (a = await g.readFile(t, "utf-8"), a.includes(n)) || (a = a + `${a.endsWith(`
|
|
237
237
|
`) ? "" : `
|
|
238
|
-
`}${
|
|
239
|
-
`, await
|
|
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
|
|
244
|
-
} catch (
|
|
245
|
-
o.error(`Failed to create config directory: ${
|
|
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(),
|
|
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
|
|
253
|
-
return JSON.parse(
|
|
254
|
-
} catch (
|
|
255
|
-
return o.warning(`Could not parse ${G}: ${
|
|
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
|
-
},
|
|
258
|
-
let
|
|
257
|
+
}, S = async (e) => {
|
|
258
|
+
let t = {
|
|
259
259
|
...e
|
|
260
260
|
};
|
|
261
|
-
const
|
|
262
|
-
if (w(
|
|
261
|
+
const n = await J();
|
|
262
|
+
if (w(n)) {
|
|
263
263
|
const a = await j();
|
|
264
|
-
a && (
|
|
264
|
+
a && (t = { ...a, ...e });
|
|
265
265
|
}
|
|
266
266
|
try {
|
|
267
|
-
const a = JSON.stringify(
|
|
268
|
-
await
|
|
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,
|
|
273
|
-
let s = 0, i =
|
|
274
|
-
const y = ['"', "'", "`"].includes(
|
|
275
|
-
for (let p =
|
|
276
|
-
const
|
|
277
|
-
if (
|
|
278
|
-
|
|
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 (
|
|
282
|
-
|
|
281
|
+
if (f === "\\" && r) {
|
|
282
|
+
l = !0;
|
|
283
283
|
continue;
|
|
284
284
|
}
|
|
285
285
|
if (y) {
|
|
286
|
-
if (
|
|
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 && (
|
|
295
|
-
r = !0,
|
|
296
|
-
else if (r &&
|
|
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 (
|
|
299
|
+
if (f === n)
|
|
300
300
|
s++;
|
|
301
|
-
else if (
|
|
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
|
-
},
|
|
309
|
-
const { filePath:
|
|
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
|
|
313
|
-
if (!
|
|
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(
|
|
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,
|
|
320
|
-
let s = await
|
|
321
|
-
if (s || (s = await
|
|
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 '${
|
|
323
|
+
`Could not find property '${n.property}' or fallback property '${a.property}' in file ${n.filePath}`
|
|
324
324
|
);
|
|
325
|
-
const i = q(JSON.stringify(
|
|
326
|
-
return (await
|
|
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,
|
|
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, (
|
|
334
|
-
}), ge = (e,
|
|
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, (
|
|
338
|
+
folders: T(e.folders, (n) => le(n, t))
|
|
339
339
|
});
|
|
340
|
-
let
|
|
340
|
+
let v = null;
|
|
341
341
|
const de = (e) => {
|
|
342
|
-
|
|
342
|
+
v = oe({ accessToken: e });
|
|
343
343
|
}, F = () => {
|
|
344
|
-
if (!
|
|
344
|
+
if (!v)
|
|
345
345
|
throw new Error("API client not initialized. Call initializeClient first.");
|
|
346
|
-
return
|
|
346
|
+
return v;
|
|
347
347
|
}, ue = async () => await F().getProject(), O = async (e) => {
|
|
348
|
-
const
|
|
348
|
+
const t = F(), n = await t.getContent({
|
|
349
349
|
contentType: "Root",
|
|
350
350
|
includeRelatedContent: !0,
|
|
351
351
|
language: e
|
|
352
352
|
});
|
|
353
|
-
if (!
|
|
353
|
+
if (!n)
|
|
354
354
|
throw new Error(`Root content not found for language: ${e}`);
|
|
355
|
-
const a =
|
|
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(
|
|
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 = () =>
|
|
376
|
-
const e = [],
|
|
377
|
-
w(
|
|
378
|
-
const
|
|
379
|
-
return w(
|
|
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
|
|
386
|
+
o.info("Content docs directory not found, creating it..."), await g.mkdir(e, { recursive: !0 });
|
|
387
387
|
return;
|
|
388
388
|
}
|
|
389
|
-
const
|
|
390
|
-
for (const
|
|
391
|
-
const a =
|
|
392
|
-
await
|
|
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,
|
|
399
|
-
const
|
|
400
|
-
for (const
|
|
401
|
-
const
|
|
402
|
-
if (
|
|
403
|
-
const
|
|
404
|
-
|
|
405
|
-
...e[
|
|
406
|
-
...
|
|
407
|
-
items:
|
|
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
|
-
|
|
410
|
+
a.push(s);
|
|
411
411
|
}
|
|
412
|
-
return
|
|
413
|
-
|
|
414
|
-
|
|
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(
|
|
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
|
-
|
|
423
|
-
) :
|
|
424
|
-
}, D = async (e,
|
|
425
|
-
const a = L(), s = await
|
|
425
|
+
n
|
|
426
|
+
) : n;
|
|
427
|
+
}, D = async (e, t, n) => {
|
|
428
|
+
const a = L(), s = await x({
|
|
426
429
|
filePath: a,
|
|
427
|
-
property:
|
|
428
|
-
startSymbol: h[
|
|
429
|
-
endSymbol: h[
|
|
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
|
|
437
|
+
i = (await g.readFile(a, "utf-8")).replace(s, r);
|
|
435
438
|
} else
|
|
436
439
|
i = await ce(
|
|
437
|
-
|
|
440
|
+
t,
|
|
438
441
|
e,
|
|
439
442
|
{
|
|
440
443
|
filePath: a,
|
|
441
|
-
property:
|
|
442
|
-
startSymbol: h[
|
|
443
|
-
endSymbol: h[
|
|
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
|
|
453
|
-
}, he = async (e,
|
|
455
|
+
await g.writeFile(a, i, "utf-8");
|
|
456
|
+
}, he = async (e, t, n) => {
|
|
454
457
|
try {
|
|
455
|
-
let a = await
|
|
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(
|
|
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) =>
|
|
475
|
-
function Ce(e,
|
|
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(
|
|
481
|
+
const a = ke(t), s = `---
|
|
479
482
|
title: "${a}"
|
|
480
483
|
---
|
|
481
484
|
|
|
482
485
|
`;
|
|
483
|
-
return o.warning(`Missing frontmatter in ${
|
|
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,
|
|
486
|
-
const
|
|
487
|
-
w(i) || await
|
|
488
|
-
},
|
|
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
|
|
492
|
-
for (const a of
|
|
493
|
-
await $(
|
|
494
|
-
for (const
|
|
495
|
-
await $(
|
|
496
|
-
for (const a of
|
|
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 $(
|
|
501
|
+
await $(d.join(n.language, a.name, s.filename), s.content);
|
|
499
502
|
}
|
|
500
|
-
} catch (
|
|
501
|
-
o.error(`Error updating docs content: ${
|
|
503
|
+
} catch (n) {
|
|
504
|
+
o.error(`Error updating docs content: ${n.message}`), process.exit(1);
|
|
502
505
|
}
|
|
503
|
-
},
|
|
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
|
|
509
|
+
return o.success(`Single language found: ${s}. Continuing...`), await S({ languageCode: s }), s;
|
|
507
510
|
}
|
|
508
|
-
const
|
|
509
|
-
if (
|
|
510
|
-
if (e.includes(
|
|
511
|
-
return o.info(`Using saved default language: ${
|
|
512
|
-
o.warning(`Saved language '${
|
|
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
|
|
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)),
|
|
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((
|
|
540
|
-
o.error(` • ${
|
|
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
|
|
544
|
-
(
|
|
546
|
+
const t = e.reduce(
|
|
547
|
+
(n, a) => ({ ...n, ...a }),
|
|
545
548
|
{}
|
|
546
549
|
);
|
|
547
|
-
return Object.keys(
|
|
548
|
-
}, Y = (e) => e.filename.replace(/\.(mdx?|md)$/, ""), _ = (e) => e.label ? e.label.trim() : Y(e),
|
|
549
|
-
const
|
|
550
|
-
return
|
|
551
|
-
}, Te = (e,
|
|
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 =
|
|
556
|
+
const a = n.filter((s) => s.id === e.id).map((s) => ({ [s.language]: _(s) }));
|
|
554
557
|
return {
|
|
555
558
|
label: _(e),
|
|
556
|
-
slug:
|
|
559
|
+
slug: xe(e, t),
|
|
557
560
|
translations: V(a)
|
|
558
561
|
};
|
|
559
|
-
}, R = (e) => e.label ? e.label.trim() : e.name,
|
|
560
|
-
const
|
|
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
|
-
},
|
|
569
|
+
}, Ee = (e, t) => T(e.folders, (n) => ve(n, t)), Ae = () => ({
|
|
567
570
|
id: "starlight",
|
|
568
571
|
syncProject: async (e) => {
|
|
569
|
-
const { accessToken:
|
|
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(
|
|
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
|
|
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
|
|
582
|
-
o.info(`Languages found (${
|
|
583
|
-
const
|
|
584
|
-
o.language(
|
|
585
|
-
const y =
|
|
586
|
-
let
|
|
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
|
-
|
|
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
|
|
592
|
-
const te =
|
|
593
|
-
await he(te,
|
|
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
|
|
599
|
-
if (!
|
|
601
|
+
const t = H[e];
|
|
602
|
+
if (!t)
|
|
600
603
|
throw new Error(`Template "${e}" not found`);
|
|
601
|
-
return
|
|
602
|
-
}, Fe = () => Object.keys(H), Pe = async (e,
|
|
603
|
-
let
|
|
604
|
-
return
|
|
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 (${
|
|
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: ${
|
|
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),
|
|
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:
|
|
618
|
-
let s = a.find((i) => i ===
|
|
619
|
-
return s || (s = await Pe(a,
|
|
620
|
-
} catch (
|
|
621
|
-
o.error(`Error configuring template: ${
|
|
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(),
|
|
629
|
+
return await K(), d.join(A(), z);
|
|
627
630
|
default:
|
|
628
|
-
return
|
|
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
|
|
635
|
-
return
|
|
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,
|
|
642
|
+
}, Q = async (e, t) => {
|
|
640
643
|
try {
|
|
641
|
-
const
|
|
644
|
+
const n = `${X}=${e}
|
|
642
645
|
`;
|
|
643
|
-
await
|
|
644
|
-
} catch (
|
|
645
|
-
o.error(`Failed to save the access token: ${
|
|
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,
|
|
650
|
-
let
|
|
651
|
-
if (
|
|
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 || (
|
|
659
|
+
}))?.useExisting || (n = null)), n)
|
|
657
660
|
o.success("Using existing Content Island 🏝️ token");
|
|
658
661
|
else {
|
|
659
|
-
|
|
660
|
-
const a = await
|
|
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),
|
|
669
|
+
B(a?.token), n = a?.token, await Q(n, e);
|
|
667
670
|
}
|
|
668
|
-
return B(
|
|
671
|
+
return B(n), n;
|
|
669
672
|
}, ee = async (e) => {
|
|
670
|
-
const { accessToken:
|
|
671
|
-
let s =
|
|
672
|
-
const i = await Le(
|
|
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
|
|
678
|
-
o.step("Saving configuration..."), await
|
|
679
|
-
const
|
|
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:
|
|
684
|
+
templateID: t.id,
|
|
682
685
|
askIfExists: !0
|
|
683
686
|
});
|
|
684
|
-
o.token("Access token configured successfully"), o.step("Synchronizing project..."), await
|
|
685
|
-
} catch (
|
|
686
|
-
o.newLine(), o.error("Error during Content Island integration:"), o.error(
|
|
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
|
|
693
|
-
const
|
|
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:
|
|
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.
|
|
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
|
+
"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.
|
|
30
|
+
"@content-island/api-client": "0.13.0",
|
|
31
31
|
"cac": "6.7.14",
|
|
32
32
|
"prompts": "2.4.2"
|
|
33
33
|
},
|