@codedrifters/configulator 0.0.243 → 0.0.244

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/lib/index.mjs CHANGED
@@ -814,7 +814,12 @@ var baseBundle = {
814
814
  "- The docs site is monorepo-wide. Sub-project documentation belongs",
815
815
  " inside that single site (under `docs/content/`), not in a per-package",
816
816
  " `docs/` folder.",
817
- "- Configulator's `StarlightProject` defaults its `outdir` to `/docs`.",
817
+ "- Configulator's `StarlightProject` defaults its `outdir` to `/docs` and",
818
+ ' its `role` to `"docs"`. A second `StarlightProject` with `role: "docs"`',
819
+ " fails synth \u2014 the singleton rule is enforced at validate time.",
820
+ "- Additional Starlight sites (client-facing, marketing, etc.) must set",
821
+ ' `role: "site"`, which routes them under `sites/<scope>/<name>` just',
822
+ " like a plain `AstroProject`.",
818
823
  "- `/sites` is reserved for end-user-facing web front ends (marketing",
819
824
  " sites, SPAs, client-facing apps). It deliberately does not host the",
820
825
  " dev-docs site.",
@@ -830,7 +835,8 @@ var baseBundle = {
830
835
  "| `TypeScriptProject` | `packages/<scope>/<name>` |",
831
836
  "| `AwsCdkProject` | `apps/<scope>/<name>` |",
832
837
  "| `AstroProject` | `sites/<scope>/<name>` |",
833
- "| `StarlightProject` (role = docs) | `docs/` |",
838
+ "| `StarlightProject` (role = docs, default) | `docs/` |",
839
+ "| `StarlightProject` (role = site) | `sites/<scope>/<name>` |",
834
840
  "",
835
841
  "`<scope>` is parsed from the sub-project's package name (everything",
836
842
  "after `@` and before `/`). `<name>` is the unscoped part of the",
@@ -15574,7 +15580,7 @@ function validateMonorepoLayout(root) {
15574
15580
  const rootOutdir = toPosix(root.outdir);
15575
15581
  for (const sub of root.subprojects) {
15576
15582
  const className = sub.constructor.name;
15577
- const expectedRoot = LAYOUT_ROOT_BY_PROJECT_TYPE[className];
15583
+ const expectedRoot = expectedRootFor(sub, className);
15578
15584
  if (expectedRoot === void 0) {
15579
15585
  continue;
15580
15586
  }
@@ -15590,11 +15596,40 @@ function validateMonorepoLayout(root) {
15590
15596
  }
15591
15597
  return violations;
15592
15598
  }
15599
+ function validateStarlightSingleton(root) {
15600
+ const docsRoleProjects = [];
15601
+ for (const sub of root.subprojects) {
15602
+ if (sub.constructor.name !== "StarlightProject") {
15603
+ continue;
15604
+ }
15605
+ if (getStarlightRole(sub) === "docs") {
15606
+ docsRoleProjects.push(sub.name);
15607
+ }
15608
+ }
15609
+ if (docsRoleProjects.length <= 1) {
15610
+ return void 0;
15611
+ }
15612
+ return { projectNames: docsRoleProjects };
15613
+ }
15614
+ function expectedRootFor(sub, className) {
15615
+ if (className === "StarlightProject") {
15616
+ return getStarlightRole(sub) === "site" ? MONOREPO_LAYOUT.SITES : MONOREPO_LAYOUT.DOCS;
15617
+ }
15618
+ return LAYOUT_ROOT_BY_PROJECT_TYPE[className];
15619
+ }
15620
+ function getStarlightRole(sub) {
15621
+ const role = sub.role;
15622
+ return role === "site" ? "site" : "docs";
15623
+ }
15593
15624
  function formatLayoutViolation(violation) {
15594
15625
  const { projectName, projectType, outdir, expectedRoot } = violation;
15595
15626
  const expectedExample = expectedRoot === MONOREPO_LAYOUT.DOCS ? "docs/" : `${expectedRoot}/<scope>/<name>`;
15596
15627
  return `[monorepo-layout] ${projectType} "${projectName}" has outdir "${outdir}", which is outside the expected root "${expectedRoot}/" (expected e.g. "${expectedExample}"). See docs/requirements/architectural-decisions/ADR-006-monorepo-layout.md.`;
15597
15628
  }
15629
+ function formatStarlightSingletonViolation(violation) {
15630
+ const names = violation.projectNames.map((n) => `"${n}"`).join(", ");
15631
+ return `[monorepo-layout] Multiple StarlightProject instances with role: "docs" found (${names}). ADR-006 allows exactly one docs-role Starlight project per MonorepoProject. Either remove the duplicates or set role: "site" on the additional ones so they land under sites/. See docs/requirements/architectural-decisions/ADR-006-monorepo-layout.md.`;
15632
+ }
15598
15633
  function outdirMatchesRoot(relOutdir, expectedRoot) {
15599
15634
  const segments = relOutdir.split("/").filter((s) => s.length > 0);
15600
15635
  if (segments.length === 0) {
@@ -16409,10 +16444,20 @@ var MonorepoProject = class extends TypeScriptAppProject {
16409
16444
  * layout contract. Runs in `preSynthesize` so all sub-projects are
16410
16445
  * attached by the time we inspect the tree.
16411
16446
  *
16447
+ * Two checks run in sequence:
16448
+ *
16449
+ * 1. **Outdir-vs-root validation.** Every sub-project's `outdir` must
16450
+ * live under the root expected for its project type (ADR-006 §4).
16451
+ * 2. **Docs-singleton validation.** At most one `StarlightProject`
16452
+ * may carry `role: "docs"` (ADR-006 §3).
16453
+ *
16412
16454
  * Behavior is controlled by `layoutEnforcement`:
16413
- * - `"off"` — skip validation.
16414
- * - `"warn"` — log a `console.warn` per violation; continue.
16415
- * - `"error"` throw on the first violation.
16455
+ * - `"off"` — skip both checks.
16456
+ * - `"warn"` — log a `console.warn` per violation; continue. Singleton
16457
+ * violations also warn in this mode rather than throwing, so all
16458
+ * layout findings are surfaced consistently.
16459
+ * - `"error"` — throw on the first outdir violation, or on the
16460
+ * singleton violation if outdir validation passed.
16416
16461
  */
16417
16462
  preSynthesize() {
16418
16463
  super.preSynthesize();
@@ -16420,15 +16465,22 @@ var MonorepoProject = class extends TypeScriptAppProject {
16420
16465
  return;
16421
16466
  }
16422
16467
  const violations = validateMonorepoLayout(this);
16423
- if (violations.length === 0) {
16424
- return;
16425
- }
16468
+ const singletonViolation = validateStarlightSingleton(this);
16426
16469
  if (this.layoutEnforcement === LAYOUT_ENFORCEMENT.ERROR) {
16427
- throw new Error(formatLayoutViolation(violations[0]));
16470
+ if (violations.length > 0) {
16471
+ throw new Error(formatLayoutViolation(violations[0]));
16472
+ }
16473
+ if (singletonViolation !== void 0) {
16474
+ throw new Error(formatStarlightSingletonViolation(singletonViolation));
16475
+ }
16476
+ return;
16428
16477
  }
16429
16478
  for (const violation of violations) {
16430
16479
  console.warn(formatLayoutViolation(violation));
16431
16480
  }
16481
+ if (singletonViolation !== void 0) {
16482
+ console.warn(formatStarlightSingletonViolation(singletonViolation));
16483
+ }
16432
16484
  }
16433
16485
  /**
16434
16486
  * Allows a sub project to request installation of dependency at the Monorepo root
@@ -17429,8 +17481,13 @@ var AwsCdkProject = class extends awscdk.AwsCdkTypeScriptApp {
17429
17481
 
17430
17482
  // src/projects/starlight-project.ts
17431
17483
  import { SampleFile as SampleFile2 } from "projen";
17484
+ var STARLIGHT_ROLE = {
17485
+ DOCS: "docs",
17486
+ SITE: "site"
17487
+ };
17432
17488
  var StarlightProject = class extends AstroProject {
17433
17489
  constructor(userOptions) {
17490
+ const role = userOptions.role ?? STARLIGHT_ROLE.DOCS;
17434
17491
  const starlightConfig = buildStarlightConfig(userOptions);
17435
17492
  const starlightSpec = {
17436
17493
  name: "starlight",
@@ -17438,8 +17495,10 @@ var StarlightProject = class extends AstroProject {
17438
17495
  defaultImport: true,
17439
17496
  args: JSON.stringify(starlightConfig, null, 2)
17440
17497
  };
17498
+ const resolvedOutdir = userOptions.outdir ?? (role === STARLIGHT_ROLE.DOCS ? MONOREPO_LAYOUT.DOCS : void 0);
17441
17499
  const mergedOptions = {
17442
17500
  ...userOptions,
17501
+ outdir: resolvedOutdir,
17443
17502
  integrations: [starlightSpec, ...userOptions.integrations ?? []],
17444
17503
  depsUpgradeOptions: {
17445
17504
  ...userOptions.depsUpgradeOptions,
@@ -17451,6 +17510,7 @@ var StarlightProject = class extends AstroProject {
17451
17510
  }
17452
17511
  };
17453
17512
  super(mergedOptions);
17513
+ this.role = role;
17454
17514
  const starlightVersion = userOptions.starlightVersion ?? VERSION.STARLIGHT_VERSION;
17455
17515
  const sharpVersion = userOptions.sharpVersion ?? VERSION.SHARP_VERSION;
17456
17516
  this.addDeps(
@@ -17577,6 +17637,7 @@ export {
17577
17637
  ROOT_CI_TASK_NAME,
17578
17638
  ROOT_TURBO_TASK_NAME,
17579
17639
  ResetTask,
17640
+ STARLIGHT_ROLE,
17580
17641
  StarlightProject,
17581
17642
  TestRunner,
17582
17643
  TurboRepo,
@@ -17596,6 +17657,7 @@ export {
17596
17657
  bcmWriterBundle,
17597
17658
  companyProfileBundle,
17598
17659
  formatLayoutViolation,
17660
+ formatStarlightSingletonViolation,
17599
17661
  getLatestEligibleVersion,
17600
17662
  githubWorkflowBundle,
17601
17663
  industryDiscoveryBundle,
@@ -17622,6 +17684,7 @@ export {
17622
17684
  turborepoBundle,
17623
17685
  typescriptBundle,
17624
17686
  validateMonorepoLayout,
17687
+ validateStarlightSingleton,
17625
17688
  vitestBundle
17626
17689
  };
17627
17690
  //# sourceMappingURL=index.mjs.map