diff --git a/turbo/generators/__tests__/core-package-analytics.e2e.test.ts b/turbo/generators/__tests__/core-package-analytics.e2e.test.ts index bc93a33..3a081d8 100644 --- a/turbo/generators/__tests__/core-package-analytics.e2e.test.ts +++ b/turbo/generators/__tests__/core-package-analytics.e2e.test.ts @@ -31,6 +31,10 @@ describe("e2e: core-package analytics", () => { !src.includes("node_modules") && !src.includes(".turbo") && !src.includes(".pnpm-store") && + // Build outputs are large and irrelevant to the scaffold — cloning + // dist/.next fills the tmp dir and slows every e2e run. + !src.includes("/dist") && + !src.includes("/.next") && !src.includes("packages/core-analytics"), }); diff --git a/turbo/generators/__tests__/core-package-audit.e2e.test.ts b/turbo/generators/__tests__/core-package-audit.e2e.test.ts index 18af1b1..7375c54 100644 --- a/turbo/generators/__tests__/core-package-audit.e2e.test.ts +++ b/turbo/generators/__tests__/core-package-audit.e2e.test.ts @@ -3,6 +3,7 @@ import { mkdtempSync, rmSync, cpSync, + globSync, readFileSync, writeFileSync, } from "node:fs"; @@ -58,12 +59,22 @@ describe("e2e: core-package audit", () => { !src.includes("node_modules") && !src.includes(".turbo") && !src.includes(".pnpm-store") && + // Build outputs are large and irrelevant to the scaffold — cloning + // dist/.next fills the tmp dir and slows every e2e run. + !src.includes("/dist") && + !src.includes("/.next") && !src.includes("packages/core-audit"), }); - // Strip @repo/core-audit from apps/web-next/package.json so pnpm install - // succeeds without the package being present (simulating the post-removal state). - stripCoreAuditDep(join(tmp, "apps", "web-next", "package.json")); + // Strip @repo/core-audit from EVERY workspace package.json so pnpm + // install succeeds without the package being present (simulating the + // post-removal state) — a hardcoded dependent list drifts as packages + // gain or drop the dependency. + for (const pkgJson of globSync( + join(tmp, "{apps,packages}", "*", "package.json"), + )) { + stripCoreAuditDep(pkgJson); + } execSync(`cd ${tmp} && pnpm install --frozen-lockfile=false`, { stdio: "ignore", diff --git a/turbo/generators/__tests__/core-package-consent.e2e.test.ts b/turbo/generators/__tests__/core-package-consent.e2e.test.ts index cb51790..c415db6 100644 --- a/turbo/generators/__tests__/core-package-consent.e2e.test.ts +++ b/turbo/generators/__tests__/core-package-consent.e2e.test.ts @@ -3,6 +3,7 @@ import { mkdtempSync, rmSync, cpSync, + globSync, readFileSync, writeFileSync, } from "node:fs"; @@ -58,13 +59,22 @@ describe("e2e: core-package consent", () => { !src.includes("node_modules") && !src.includes(".turbo") && !src.includes(".pnpm-store") && + // Build outputs are large and irrelevant to the scaffold — cloning + // dist/.next fills the tmp dir and slows every e2e run. + !src.includes("/dist") && + !src.includes("/.next") && !src.includes("packages/core-consent"), }); - // Strip @repo/core-consent from package.json files so pnpm install - // succeeds without the package being present (simulating the post-removal state). - stripCoreConsentDep(join(tmp, "packages", "core-api", "package.json")); - stripCoreConsentDep(join(tmp, "packages", "core-ui", "package.json")); + // Strip @repo/core-consent from EVERY workspace package.json so pnpm + // install succeeds without the package being present (simulating the + // post-removal state) — a hardcoded dependent list drifts as packages + // gain or drop the dependency. + for (const pkgJson of globSync( + join(tmp, "{apps,packages}", "*", "package.json"), + )) { + stripCoreConsentDep(pkgJson); + } execSync(`cd ${tmp} && pnpm install --frozen-lockfile=false`, { stdio: "ignore", diff --git a/turbo/generators/__tests__/core-package-dsr.e2e.test.ts b/turbo/generators/__tests__/core-package-dsr.e2e.test.ts index 75084c4..3461526 100644 --- a/turbo/generators/__tests__/core-package-dsr.e2e.test.ts +++ b/turbo/generators/__tests__/core-package-dsr.e2e.test.ts @@ -3,6 +3,7 @@ import { mkdtempSync, rmSync, cpSync, + globSync, readFileSync, writeFileSync, } from "node:fs"; @@ -58,12 +59,22 @@ describe("e2e: core-package dsr", () => { !src.includes("node_modules") && !src.includes(".turbo") && !src.includes(".pnpm-store") && + // Build outputs are large and irrelevant to the scaffold — cloning + // dist/.next fills the tmp dir and slows every e2e run. + !src.includes("/dist") && + !src.includes("/.next") && !src.includes("packages/core-dsr"), }); - // Strip @repo/core-dsr from package.json files so pnpm install - // succeeds without the package being present (simulating the post-removal state). - stripCoreDsrDep(join(tmp, "packages", "core-api", "package.json")); + // Strip @repo/core-dsr from EVERY workspace package.json so pnpm + // install succeeds without the package being present (simulating the + // post-removal state) — a hardcoded dependent list drifts as packages + // gain or drop the dependency. + for (const pkgJson of globSync( + join(tmp, "{apps,packages}", "*", "package.json"), + )) { + stripCoreDsrDep(pkgJson); + } execSync(`cd ${tmp} && pnpm install --frozen-lockfile=false`, { stdio: "ignore", diff --git a/turbo/generators/__tests__/core-package-events.e2e.test.ts b/turbo/generators/__tests__/core-package-events.e2e.test.ts index 7587d99..9a511c5 100644 --- a/turbo/generators/__tests__/core-package-events.e2e.test.ts +++ b/turbo/generators/__tests__/core-package-events.e2e.test.ts @@ -3,6 +3,7 @@ import { mkdtempSync, rmSync, cpSync, + globSync, readFileSync, writeFileSync, } from "node:fs"; @@ -58,24 +59,22 @@ describe("e2e: core-package events", () => { !src.includes("node_modules") && !src.includes(".turbo") && !src.includes(".pnpm-store") && + // Build outputs are large and irrelevant to the scaffold — cloning + // dist/.next fills the tmp dir and slows every e2e run. + !src.includes("/dist") && + !src.includes("/.next") && !src.includes("packages/core-events"), }); - // Strip @repo/core-events from feature package.json files so pnpm install - // succeeds without the package being present (simulating the post-removal state). - const featurePackages = [ - "auth", - "blog", - "media", - "marketing-pages", - "navigation", - ]; - for (const pkg of featurePackages) { - const pkgJson = join(tmp, "packages", pkg, "package.json"); + // Strip @repo/core-events from EVERY workspace package.json so pnpm + // install succeeds without the package being present (simulating the + // post-removal state) — a hardcoded dependent list drifts as packages + // gain or drop the dependency. + for (const pkgJson of globSync( + join(tmp, "{apps,packages}", "*", "package.json"), + )) { stripCoreEventsDep(pkgJson); } - // Also strip from apps/web-next - stripCoreEventsDep(join(tmp, "apps", "web-next", "package.json")); execSync(`cd ${tmp} && pnpm install --frozen-lockfile=false`, { stdio: "ignore", diff --git a/turbo/generators/__tests__/core-package-realtime.e2e.test.ts b/turbo/generators/__tests__/core-package-realtime.e2e.test.ts index f3fb052..2edaf95 100644 --- a/turbo/generators/__tests__/core-package-realtime.e2e.test.ts +++ b/turbo/generators/__tests__/core-package-realtime.e2e.test.ts @@ -31,6 +31,10 @@ describe("e2e: core-package realtime", () => { !src.includes("node_modules") && !src.includes(".turbo") && !src.includes(".pnpm-store") && + // Build outputs are large and irrelevant to the scaffold — cloning + // dist/.next fills the tmp dir and slows every e2e run. + !src.includes("/dist") && + !src.includes("/.next") && !src.includes("packages/core-realtime"), }); execSync(`cd ${tmp} && pnpm install --frozen-lockfile=false`, { diff --git a/turbo/generators/__tests__/core-package-trpc.e2e.test.ts b/turbo/generators/__tests__/core-package-trpc.e2e.test.ts index 257481b..ceeebb5 100644 --- a/turbo/generators/__tests__/core-package-trpc.e2e.test.ts +++ b/turbo/generators/__tests__/core-package-trpc.e2e.test.ts @@ -3,6 +3,7 @@ import { mkdtempSync, rmSync, cpSync, + globSync, readFileSync, writeFileSync, } from "node:fs"; @@ -58,21 +59,21 @@ describe("e2e: core-package trpc", () => { !src.includes("node_modules") && !src.includes(".turbo") && !src.includes(".pnpm-store") && + // Build outputs are large and irrelevant to the scaffold — cloning + // dist/.next fills the tmp dir and slows every e2e run. + !src.includes("/dist") && + !src.includes("/.next") && !src.includes("packages/core-trpc"), }); - // Strip @repo/core-trpc from every package that references it so pnpm + // Strip @repo/core-trpc from EVERY workspace package.json so pnpm // install succeeds without the package being present (simulating the - // post-removal state). Apps list it directly; the blog, marketing-pages, - // and navigation features depend on it for their ./ui tRPC hooks. - for (const pkgDir of [ - ["apps", "web-next"], - ["apps", "web-tanstack"], - ["packages", "blog"], - ["packages", "marketing-pages"], - ["packages", "navigation"], - ]) { - stripCoreTrpcDep(join(tmp, ...pkgDir, "package.json")); + // post-removal state) — a hardcoded dependent list drifts as packages + // gain or drop the dependency. + for (const pkgJson of globSync( + join(tmp, "{apps,packages}", "*", "package.json"), + )) { + stripCoreTrpcDep(pkgJson); } execSync(`cd ${tmp} && pnpm install --frozen-lockfile=false`, { diff --git a/turbo/generators/__tests__/core-package-ui.e2e.test.ts b/turbo/generators/__tests__/core-package-ui.e2e.test.ts index cc5ea61..cd5c27f 100644 --- a/turbo/generators/__tests__/core-package-ui.e2e.test.ts +++ b/turbo/generators/__tests__/core-package-ui.e2e.test.ts @@ -3,6 +3,7 @@ import { mkdtempSync, rmSync, cpSync, + globSync, readFileSync, writeFileSync, } from "node:fs"; @@ -58,14 +59,22 @@ describe("e2e: core-package ui", () => { !src.includes("node_modules") && !src.includes(".turbo") && !src.includes(".pnpm-store") && + // Build outputs are large and irrelevant to the scaffold — cloning + // dist/.next fills the tmp dir and slows every e2e run. + !src.includes("/dist") && + !src.includes("/.next") && !src.includes("packages/core-ui"), }); - // Strip @repo/core-ui from app package.json files so pnpm install - // succeeds without the package being present (simulating the post-removal state). - stripCoreUiDep(join(tmp, "apps", "web-next", "package.json")); - stripCoreUiDep(join(tmp, "apps", "web-tanstack", "package.json")); - stripCoreUiDep(join(tmp, "apps", "storybook", "package.json")); + // Strip @repo/core-ui from EVERY workspace package.json so pnpm + // install succeeds without the package being present (simulating the + // post-removal state) — a hardcoded dependent list drifts as packages + // gain or drop the dependency. + for (const pkgJson of globSync( + join(tmp, "{apps,packages}", "*", "package.json"), + )) { + stripCoreUiDep(pkgJson); + } execSync(`cd ${tmp} && pnpm install --frozen-lockfile=false`, { stdio: "ignore", diff --git a/turbo/generators/__tests__/feature.e2e.test.ts b/turbo/generators/__tests__/feature.e2e.test.ts index 4872282..84b386c 100644 --- a/turbo/generators/__tests__/feature.e2e.test.ts +++ b/turbo/generators/__tests__/feature.e2e.test.ts @@ -38,7 +38,11 @@ describe("e2e: feature generator composition", () => { filter: (src) => !src.includes("node_modules") && !src.includes(".turbo") && - !src.includes(".pnpm-store"), + !src.includes(".pnpm-store") && + // Build outputs are large and irrelevant to the scaffold — cloning + // dist/.next fills the tmp dir and slows every e2e run. + !src.includes("/dist") && + !src.includes("/.next"), }); execSync(`cd ${tmp} && pnpm install --frozen-lockfile=false`, { diff --git a/turbo/generators/config.ts b/turbo/generators/config.ts index 9d2c7c1..be3864b 100644 --- a/turbo/generators/config.ts +++ b/turbo/generators/config.ts @@ -1300,7 +1300,10 @@ function handlerBindBlock(a: { ${containerVar}.unbind(${handlerSymbol}); } ${containerVar}.bind(${handlerSymbol}).toConstantValue(${wrappedVar}); - bus.subscribe(${eventConst}, "${a.feature}", ${wrappedVar});`; + // ctx.bus is an OPTIONAL core (guard per CLAUDE.md binder conventions). + if (bus) { + bus.subscribe(${eventConst}, "${a.feature}", ${wrappedVar}); + }`; } function printConsumeNextSteps(a: { diff --git a/turbo/generators/templates/feature/vitest.config.ts.hbs b/turbo/generators/templates/feature/vitest.config.ts.hbs index 524276b..fd3bae8 100644 --- a/turbo/generators/templates/feature/vitest.config.ts.hbs +++ b/turbo/generators/templates/feature/vitest.config.ts.hbs @@ -12,6 +12,9 @@ import { // manifest when adjusting per-feature bands. export default mergeConfig(nodeVitestConfig, { test: { + // The node base only includes .test.ts; UI tests are .test.tsx files + // that opt into jsdom per-file via the @vitest-environment docblock. + include: ["src/**/*.test.{ts,tsx}"], coverage: { exclude: [ // DI bootstrap — wires InversifyJS at app startup; not unit-testable