@cms-lab/cli 1.1.0 → 1.2.0

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/README.md CHANGED
@@ -10,6 +10,7 @@ npx @cms-lab/cli scan
10
10
 
11
11
  ```sh
12
12
  cms-lab init
13
+ cms-lab init --cms strapi --router pages
13
14
  cms-lab doctor
14
15
  cms-lab doctor --debug --verbose 2
15
16
  cms-lab scan --report
@@ -37,6 +38,11 @@ Strapi, Directus, WordPress, Contentful, and Sanity. It validates configured CMS
37
38
  route mappings, route reachability, UID gaps, SEO metadata, image alt text, and
38
39
  project-specific required fields.
39
40
 
41
+ `cms-lab init --cms strapi --router pages` writes a Strapi starter config with
42
+ collections, single types, route examples, and the Strapi relation route helper.
43
+ Use `site.healthPath` or `site.healthUrl` in config when the app root is not the
44
+ right page for the initial health probe.
45
+
40
46
  Debug logs use stderr and support `--debug` plus `--verbose <0|1|2|3>`, so JSON
41
47
  scan output remains clean on stdout. Raw CMS document `data` is redacted from
42
48
  `--json` output, along with document URLs, UIDs, and absolute project paths,
package/dist/bin.js CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  runCli
4
- } from "./chunk-CPGXUVJR.js";
4
+ } from "./chunk-34UP25NH.js";
5
5
 
6
6
  // src/bin.ts
7
7
  var exitCode = await runCli(process.argv.slice(2));
@@ -9,6 +9,7 @@ import {
9
9
  SiteUnreachableError,
10
10
  explainDiagnostic,
11
11
  loadCmsLabConfig,
12
+ resolveSiteHealthUrl,
12
13
  scanDocuments
13
14
  } from "@cms-lab/core";
14
15
  import { fetchContentfulDocuments as defaultFetchContentfulDocuments } from "@cms-lab/contentful";
@@ -514,7 +515,7 @@ var noColor = {
514
515
  // src/index.ts
515
516
  async function runCli(argv, dependencies = {}) {
516
517
  let exitCode = 0;
517
- const program = new Command().name("cms-lab").description("Catch CMS bugs before deploy.").version("1.1.0").exitOverride().configureOutput({
518
+ const program = new Command().name("cms-lab").description("Catch CMS bugs before deploy.").version("1.2.0").exitOverride().configureOutput({
518
519
  writeOut: (text) => writeStdout(dependencies, text),
519
520
  writeErr: (text) => writeStderr(dependencies, text)
520
521
  });
@@ -613,12 +614,21 @@ Examples:
613
614
  ).action((code) => {
614
615
  exitCode = runExplain(code, dependencies);
615
616
  });
616
- program.command("init").description("Create a starter cms-lab.config.ts file.").option("--config <path>", "Config file path", "cms-lab.config.ts").option("--force", "Overwrite an existing config file").option("--repository <name>", "Prismic repository name", "my-repo").option("--url <url>", "Site URL", "http://localhost:3000").addHelpText(
617
+ program.command("init").description("Create a starter cms-lab.config.ts file.").option("--config <path>", "Config file path", "cms-lab.config.ts").option("--force", "Overwrite an existing config file").option(
618
+ "--cms <provider>",
619
+ "Starter CMS provider: prismic or strapi",
620
+ "prismic"
621
+ ).option("--router <router>", "Next.js router: app or pages", "app").option("--repository <name>", "Prismic repository name", "my-repo").option("--url <url>", "Site URL", "http://localhost:3000").option(
622
+ "--strapi-url <url>",
623
+ "Strapi REST API URL",
624
+ "http://localhost:1337"
625
+ ).option("--strapi-locale <locale>", "Strapi locale query param").addHelpText(
617
626
  "after",
618
627
  `
619
628
  Examples:
620
629
  cms-lab init
621
630
  cms-lab init --repository my-prismic-repo --url http://localhost:3000
631
+ cms-lab init --cms strapi --router pages --strapi-url http://localhost:1337
622
632
  cms-lab init --config cms-lab.config.ts --force
623
633
  `
624
634
  ).action(async (options) => {
@@ -898,9 +908,10 @@ async function runDoctor(options, dependencies) {
898
908
  `
899
909
  );
900
910
  const endSite = debug.time("site probe", 2);
901
- await fetchSite(config.site.url, dependencies.fetch, timeoutMs, retries);
911
+ const healthUrl = resolveSiteHealthUrl(config.site).toString();
912
+ await fetchSite(healthUrl, dependencies.fetch, timeoutMs, retries);
902
913
  endSite();
903
- writeStdout(dependencies, `site ok - ${config.site.url}
914
+ writeStdout(dependencies, `site ok - ${siteUrlForOutput(healthUrl)}
904
915
  `);
905
916
  const endCms = debug.time("cms fetch", 2);
906
917
  const documents = await fetchCmsDocuments(config.cms, dependencies);
@@ -979,13 +990,7 @@ async function runInit(options, dependencies) {
979
990
  return 2;
980
991
  }
981
992
  await mkdir(dirname(target), { recursive: true });
982
- await writeFile(
983
- target,
984
- starterConfig({
985
- repository: options.repository ?? "my-repo",
986
- url: options.url ?? "http://localhost:3000"
987
- })
988
- );
993
+ await writeFile(target, starterConfig(parseInitOptions(options)));
989
994
  writeStdout(dependencies, `created ${target}
990
995
  `);
991
996
  return 0;
@@ -1253,6 +1258,16 @@ function safeUrl(value) {
1253
1258
  return "<invalid-url>";
1254
1259
  }
1255
1260
  }
1261
+ function siteUrlForOutput(value) {
1262
+ try {
1263
+ const url = new URL(value);
1264
+ const auth = url.username || url.password ? "[redacted]@" : "";
1265
+ const hash = url.hash ? "#[redacted]" : "";
1266
+ return `${url.protocol}//${auth}${url.host}${url.pathname}${url.search ? "?[redacted]" : ""}${hash}`;
1267
+ } catch {
1268
+ return redactSensitive(value);
1269
+ }
1270
+ }
1256
1271
  function formatList(values) {
1257
1272
  return values.length > 0 ? values.join(",") : "none";
1258
1273
  }
@@ -1519,12 +1534,33 @@ async function fileExists(path) {
1519
1534
  function plural3(value, singular) {
1520
1535
  return value === 1 ? singular : `${singular}s`;
1521
1536
  }
1537
+ function parseInitOptions(options) {
1538
+ const cms = options.cms ?? "prismic";
1539
+ if (cms !== "prismic" && cms !== "strapi") {
1540
+ throw new ConfigLoadError("--cms must be one of: prismic, strapi");
1541
+ }
1542
+ const router = options.router ?? "app";
1543
+ if (router !== "app" && router !== "pages") {
1544
+ throw new ConfigLoadError("--router must be one of: app, pages");
1545
+ }
1546
+ return {
1547
+ cms,
1548
+ router,
1549
+ repository: options.repository ?? "my-repo",
1550
+ url: options.url ?? "http://localhost:3000",
1551
+ strapiUrl: options.strapiUrl ?? "http://localhost:1337",
1552
+ strapiLocale: options.strapiLocale
1553
+ };
1554
+ }
1522
1555
  function starterConfig(options) {
1556
+ if (options.cms === "strapi") {
1557
+ return strapiStarterConfig(options);
1558
+ }
1523
1559
  return `import { defineConfig } from "@cms-lab/core";
1524
1560
 
1525
1561
  export default defineConfig({
1526
1562
  site: { url: ${JSON.stringify(options.url)} },
1527
- framework: { type: "next", router: "app" },
1563
+ framework: { type: "next", router: ${JSON.stringify(options.router)} },
1528
1564
  cms: {
1529
1565
  provider: "prismic",
1530
1566
  repositoryName: ${JSON.stringify(options.repository)},
@@ -1541,6 +1577,45 @@ export default defineConfig({
1541
1577
  });
1542
1578
  `;
1543
1579
  }
1580
+ function strapiStarterConfig(options) {
1581
+ const localeLine = options.strapiLocale ? `
1582
+ locale: ${JSON.stringify(options.strapiLocale)},` : "";
1583
+ return `import { defineConfig, strapiRelationSlug } from "@cms-lab/core";
1584
+
1585
+ export default defineConfig({
1586
+ site: {
1587
+ url: ${JSON.stringify(options.url)},
1588
+ // Use healthPath when your app's root redirects or errors but a locale route is healthy.
1589
+ // healthPath: "/en",
1590
+ },
1591
+ framework: { type: "next", router: ${JSON.stringify(options.router)} },
1592
+ cms: {
1593
+ provider: "strapi",
1594
+ url: ${JSON.stringify(options.strapiUrl)},
1595
+ token: process.env.STRAPI_TOKEN,${localeLine}
1596
+ collections: [
1597
+ { type: "page", endpoint: "pages", uidField: "slug" },
1598
+ { type: "article", endpoint: "articles", uidField: "slug" },
1599
+ ],
1600
+ singleTypes: [
1601
+ { type: "navbar", endpoint: "navbar" },
1602
+ { type: "footer", endpoint: "footer" },
1603
+ ],
1604
+ },
1605
+ routes: [
1606
+ { type: "page", pattern: "/:slug", getPath: (doc) => \`/\${doc.uid}\` },
1607
+ {
1608
+ type: "article",
1609
+ pattern: "/blog/:topic/:slug",
1610
+ getPath: (doc) => {
1611
+ const topic = strapiRelationSlug(doc.data, "topic") ?? "uncategorized";
1612
+ return \`/blog/\${topic}/\${doc.uid}\`;
1613
+ },
1614
+ },
1615
+ ],
1616
+ });
1617
+ `;
1618
+ }
1544
1619
 
1545
1620
  export {
1546
1621
  runCli
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  runCli
3
- } from "./chunk-CPGXUVJR.js";
3
+ } from "./chunk-34UP25NH.js";
4
4
  export {
5
5
  runCli
6
6
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cms-lab/cli",
3
- "version": "1.1.0",
3
+ "version": "1.2.0",
4
4
  "type": "module",
5
5
  "description": "Catch CMS bugs before deploy.",
6
6
  "license": "MIT",
@@ -47,15 +47,15 @@
47
47
  "dependencies": {
48
48
  "commander": "^14.0.2",
49
49
  "picocolors": "^1.1.1",
50
- "@cms-lab/contentful": "1.1.0",
51
- "@cms-lab/core": "1.1.0",
52
- "@cms-lab/directus": "1.1.0",
53
- "@cms-lab/reporter": "1.1.0",
54
- "@cms-lab/sanity": "1.1.0",
55
- "@cms-lab/prismic": "1.1.0",
56
- "@cms-lab/strapi": "1.1.0",
57
- "@cms-lab/next": "1.1.0",
58
- "@cms-lab/wordpress": "1.1.0"
50
+ "@cms-lab/contentful": "1.2.0",
51
+ "@cms-lab/core": "1.2.0",
52
+ "@cms-lab/directus": "1.2.0",
53
+ "@cms-lab/prismic": "1.2.0",
54
+ "@cms-lab/reporter": "1.2.0",
55
+ "@cms-lab/sanity": "1.2.0",
56
+ "@cms-lab/wordpress": "1.2.0",
57
+ "@cms-lab/strapi": "1.2.0",
58
+ "@cms-lab/next": "1.2.0"
59
59
  },
60
60
  "author": "Afaq Rashid",
61
61
  "scripts": {