@codedrifters/configulator 0.0.242 → 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",
@@ -15551,27 +15557,6 @@ var JsiiFaker = class _JsiiFaker extends Component12 {
15551
15557
  // src/projects/astro-project.ts
15552
15558
  import { SampleFile } from "projen";
15553
15559
 
15554
- // src/projects/typescript-project.ts
15555
- import { typescript } from "projen";
15556
- import {
15557
- NodePackageManager as NodePackageManager2,
15558
- Transform,
15559
- UpgradeDependenciesSchedule as UpgradeDependenciesSchedule2
15560
- } from "projen/lib/javascript";
15561
- import { ReleaseTrigger } from "projen/lib/release";
15562
- import { merge as merge2 } from "ts-deepmerge";
15563
-
15564
- // src/projects/monorepo-project.ts
15565
- import { WorkflowSteps } from "projen/lib/github";
15566
- import {
15567
- NodePackageManager,
15568
- UpgradeDependenciesSchedule
15569
- } from "projen/lib/javascript";
15570
- import {
15571
- TypeScriptAppProject
15572
- } from "projen/lib/typescript";
15573
- import { merge } from "ts-deepmerge";
15574
-
15575
15560
  // src/projects/monorepo-layout.ts
15576
15561
  var MONOREPO_LAYOUT = {
15577
15562
  DOCS: "docs",
@@ -15595,7 +15580,7 @@ function validateMonorepoLayout(root) {
15595
15580
  const rootOutdir = toPosix(root.outdir);
15596
15581
  for (const sub of root.subprojects) {
15597
15582
  const className = sub.constructor.name;
15598
- const expectedRoot = LAYOUT_ROOT_BY_PROJECT_TYPE[className];
15583
+ const expectedRoot = expectedRootFor(sub, className);
15599
15584
  if (expectedRoot === void 0) {
15600
15585
  continue;
15601
15586
  }
@@ -15611,11 +15596,40 @@ function validateMonorepoLayout(root) {
15611
15596
  }
15612
15597
  return violations;
15613
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
+ }
15614
15624
  function formatLayoutViolation(violation) {
15615
15625
  const { projectName, projectType, outdir, expectedRoot } = violation;
15616
15626
  const expectedExample = expectedRoot === MONOREPO_LAYOUT.DOCS ? "docs/" : `${expectedRoot}/<scope>/<name>`;
15617
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.`;
15618
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
+ }
15619
15633
  function outdirMatchesRoot(relOutdir, expectedRoot) {
15620
15634
  const segments = relOutdir.split("/").filter((s) => s.length > 0);
15621
15635
  if (segments.length === 0) {
@@ -15643,6 +15657,67 @@ function relativeOutdir(rootOutdir, subOutdir) {
15643
15657
  return subOutdir;
15644
15658
  }
15645
15659
 
15660
+ // src/projects/resolve-outdir.ts
15661
+ function parseScopedName(input) {
15662
+ if (!input.startsWith("@")) {
15663
+ return void 0;
15664
+ }
15665
+ const slashIndex = input.indexOf("/");
15666
+ if (slashIndex < 2) {
15667
+ return void 0;
15668
+ }
15669
+ const scope = input.slice(0, slashIndex);
15670
+ const name = input.slice(slashIndex + 1);
15671
+ if (name.length === 0 || name.includes("/")) {
15672
+ return void 0;
15673
+ }
15674
+ return { scope, name };
15675
+ }
15676
+ function resolveOutdirFromPackageName(packageName, root) {
15677
+ if (packageName === void 0 || packageName.length === 0) {
15678
+ throw new Error(
15679
+ "Cannot derive outdir: packageName (or name) is required when outdir is omitted. Either pass a scoped `packageName` / `name` like `@scope/foo`, or set `outdir` explicitly."
15680
+ );
15681
+ }
15682
+ const parsed = parseScopedName(packageName);
15683
+ if (parsed === void 0) {
15684
+ throw new Error(
15685
+ `Cannot derive outdir from unscoped packageName "${packageName}". Either use a scoped name like \`@scope/foo\`, or set \`outdir\` explicitly. Configulator places sub-projects at "${root}/<scope>/<name>".`
15686
+ );
15687
+ }
15688
+ return `${root}/${parsed.scope}/${parsed.name}`;
15689
+ }
15690
+ function resolveTypeScriptProjectOutdir(packageName) {
15691
+ return resolveOutdirFromPackageName(packageName, MONOREPO_LAYOUT.PACKAGES);
15692
+ }
15693
+ function resolveAwsCdkProjectOutdir(packageName) {
15694
+ return resolveOutdirFromPackageName(packageName, MONOREPO_LAYOUT.APPS);
15695
+ }
15696
+ function resolveAstroProjectOutdir(packageName) {
15697
+ return resolveOutdirFromPackageName(packageName, MONOREPO_LAYOUT.SITES);
15698
+ }
15699
+
15700
+ // src/projects/typescript-project.ts
15701
+ import { typescript } from "projen";
15702
+ import {
15703
+ NodePackageManager as NodePackageManager2,
15704
+ Transform,
15705
+ UpgradeDependenciesSchedule as UpgradeDependenciesSchedule2
15706
+ } from "projen/lib/javascript";
15707
+ import { ReleaseTrigger } from "projen/lib/release";
15708
+ import { merge as merge2 } from "ts-deepmerge";
15709
+
15710
+ // src/projects/monorepo-project.ts
15711
+ import { WorkflowSteps } from "projen/lib/github";
15712
+ import {
15713
+ NodePackageManager,
15714
+ UpgradeDependenciesSchedule
15715
+ } from "projen/lib/javascript";
15716
+ import {
15717
+ TypeScriptAppProject
15718
+ } from "projen/lib/typescript";
15719
+ import { merge } from "ts-deepmerge";
15720
+
15646
15721
  // src/tasks/reset-task.ts
15647
15722
  import { Component as Component13 } from "projen";
15648
15723
  var ResetTask = class _ResetTask extends Component13 {
@@ -16369,10 +16444,20 @@ var MonorepoProject = class extends TypeScriptAppProject {
16369
16444
  * layout contract. Runs in `preSynthesize` so all sub-projects are
16370
16445
  * attached by the time we inspect the tree.
16371
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
+ *
16372
16454
  * Behavior is controlled by `layoutEnforcement`:
16373
- * - `"off"` — skip validation.
16374
- * - `"warn"` — log a `console.warn` per violation; continue.
16375
- * - `"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.
16376
16461
  */
16377
16462
  preSynthesize() {
16378
16463
  super.preSynthesize();
@@ -16380,15 +16465,22 @@ var MonorepoProject = class extends TypeScriptAppProject {
16380
16465
  return;
16381
16466
  }
16382
16467
  const violations = validateMonorepoLayout(this);
16383
- if (violations.length === 0) {
16384
- return;
16385
- }
16468
+ const singletonViolation = validateStarlightSingleton(this);
16386
16469
  if (this.layoutEnforcement === LAYOUT_ENFORCEMENT.ERROR) {
16387
- 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;
16388
16477
  }
16389
16478
  for (const violation of violations) {
16390
16479
  console.warn(formatLayoutViolation(violation));
16391
16480
  }
16481
+ if (singletonViolation !== void 0) {
16482
+ console.warn(formatStarlightSingletonViolation(singletonViolation));
16483
+ }
16392
16484
  }
16393
16485
  /**
16394
16486
  * Allows a sub project to request installation of dependency at the Monorepo root
@@ -16418,43 +16510,6 @@ var MonorepoProject = class extends TypeScriptAppProject {
16418
16510
  }
16419
16511
  };
16420
16512
 
16421
- // src/projects/resolve-outdir.ts
16422
- function parseScopedName(input) {
16423
- if (!input.startsWith("@")) {
16424
- return void 0;
16425
- }
16426
- const slashIndex = input.indexOf("/");
16427
- if (slashIndex < 2) {
16428
- return void 0;
16429
- }
16430
- const scope = input.slice(0, slashIndex);
16431
- const name = input.slice(slashIndex + 1);
16432
- if (name.length === 0 || name.includes("/")) {
16433
- return void 0;
16434
- }
16435
- return { scope, name };
16436
- }
16437
- function resolveOutdirFromPackageName(packageName, root) {
16438
- if (packageName === void 0 || packageName.length === 0) {
16439
- throw new Error(
16440
- "Cannot derive outdir: packageName (or name) is required when outdir is omitted. Either pass a scoped `packageName` / `name` like `@scope/foo`, or set `outdir` explicitly."
16441
- );
16442
- }
16443
- const parsed = parseScopedName(packageName);
16444
- if (parsed === void 0) {
16445
- throw new Error(
16446
- `Cannot derive outdir from unscoped packageName "${packageName}". Either use a scoped name like \`@scope/foo\`, or set \`outdir\` explicitly. Configulator places sub-projects at "${root}/<scope>/<name>".`
16447
- );
16448
- }
16449
- return `${root}/${parsed.scope}/${parsed.name}`;
16450
- }
16451
- function resolveTypeScriptProjectOutdir(packageName) {
16452
- return resolveOutdirFromPackageName(packageName, MONOREPO_LAYOUT.PACKAGES);
16453
- }
16454
- function resolveAwsCdkProjectOutdir(packageName) {
16455
- return resolveOutdirFromPackageName(packageName, MONOREPO_LAYOUT.APPS);
16456
- }
16457
-
16458
16513
  // src/projects/typescript-project.ts
16459
16514
  var TestRunner = {
16460
16515
  JEST: "jest",
@@ -16641,9 +16696,11 @@ var TypeScriptProject = class extends typescript.TypeScriptProject {
16641
16696
  // src/projects/astro-project.ts
16642
16697
  var AstroProject = class extends TypeScriptProject {
16643
16698
  constructor(userOptions) {
16699
+ const resolvedOutdir = userOptions.outdir ?? resolveAstroProjectOutdir(userOptions.packageName ?? userOptions.name);
16644
16700
  const options = {
16645
16701
  testRunner: TestRunner.VITEST,
16646
16702
  ...userOptions,
16703
+ outdir: resolvedOutdir,
16647
16704
  depsUpgradeOptions: {
16648
16705
  ...userOptions.depsUpgradeOptions,
16649
16706
  exclude: [...userOptions.depsUpgradeOptions?.exclude ?? [], "astro"]
@@ -17424,8 +17481,13 @@ var AwsCdkProject = class extends awscdk.AwsCdkTypeScriptApp {
17424
17481
 
17425
17482
  // src/projects/starlight-project.ts
17426
17483
  import { SampleFile as SampleFile2 } from "projen";
17484
+ var STARLIGHT_ROLE = {
17485
+ DOCS: "docs",
17486
+ SITE: "site"
17487
+ };
17427
17488
  var StarlightProject = class extends AstroProject {
17428
17489
  constructor(userOptions) {
17490
+ const role = userOptions.role ?? STARLIGHT_ROLE.DOCS;
17429
17491
  const starlightConfig = buildStarlightConfig(userOptions);
17430
17492
  const starlightSpec = {
17431
17493
  name: "starlight",
@@ -17433,8 +17495,10 @@ var StarlightProject = class extends AstroProject {
17433
17495
  defaultImport: true,
17434
17496
  args: JSON.stringify(starlightConfig, null, 2)
17435
17497
  };
17498
+ const resolvedOutdir = userOptions.outdir ?? (role === STARLIGHT_ROLE.DOCS ? MONOREPO_LAYOUT.DOCS : void 0);
17436
17499
  const mergedOptions = {
17437
17500
  ...userOptions,
17501
+ outdir: resolvedOutdir,
17438
17502
  integrations: [starlightSpec, ...userOptions.integrations ?? []],
17439
17503
  depsUpgradeOptions: {
17440
17504
  ...userOptions.depsUpgradeOptions,
@@ -17446,6 +17510,7 @@ var StarlightProject = class extends AstroProject {
17446
17510
  }
17447
17511
  };
17448
17512
  super(mergedOptions);
17513
+ this.role = role;
17449
17514
  const starlightVersion = userOptions.starlightVersion ?? VERSION.STARLIGHT_VERSION;
17450
17515
  const sharpVersion = userOptions.sharpVersion ?? VERSION.SHARP_VERSION;
17451
17516
  this.addDeps(
@@ -17572,6 +17637,7 @@ export {
17572
17637
  ROOT_CI_TASK_NAME,
17573
17638
  ROOT_TURBO_TASK_NAME,
17574
17639
  ResetTask,
17640
+ STARLIGHT_ROLE,
17575
17641
  StarlightProject,
17576
17642
  TestRunner,
17577
17643
  TurboRepo,
@@ -17591,6 +17657,7 @@ export {
17591
17657
  bcmWriterBundle,
17592
17658
  companyProfileBundle,
17593
17659
  formatLayoutViolation,
17660
+ formatStarlightSingletonViolation,
17594
17661
  getLatestEligibleVersion,
17595
17662
  githubWorkflowBundle,
17596
17663
  industryDiscoveryBundle,
@@ -17606,6 +17673,7 @@ export {
17606
17673
  requirementsReviewerBundle,
17607
17674
  requirementsWriterBundle,
17608
17675
  researchPipelineBundle,
17676
+ resolveAstroProjectOutdir,
17609
17677
  resolveAwsCdkProjectOutdir,
17610
17678
  resolveModelAlias,
17611
17679
  resolveOutdirFromPackageName,
@@ -17616,6 +17684,7 @@ export {
17616
17684
  turborepoBundle,
17617
17685
  typescriptBundle,
17618
17686
  validateMonorepoLayout,
17687
+ validateStarlightSingleton,
17619
17688
  vitestBundle
17620
17689
  };
17621
17690
  //# sourceMappingURL=index.mjs.map