@contractspec/bundle.workspace 4.0.0 → 4.0.3

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 CHANGED
@@ -7925,7 +7925,12 @@ import {
7925
7925
  DEFAULT_CONTRACTSRC as DEFAULT_CONTRACTSRC3
7926
7926
  } from "@contractspec/lib.contracts-spec/workspace-config";
7927
7927
  var IMPLEMENTATION_PATH_PATTERN = /(^|\/)(handlers?|routes?|controllers?|api)(\/|$)|\.(handler|handlers|route|routes|controller)\.(ts|tsx)$/i;
7928
- var CONTRACT_REFERENCE_PATTERN = /@contractspec\/lib\.contracts(?:-spec|-integrations)?|define(Command|Query|Event|Feature|Presentation|Capability|Form|DataView|Integration)|OperationSpecRegistry|ContractHandler|installOp|contracts\//;
7928
+ var CONTRACT_REFERENCE_PATTERN = /@contractspec\/lib\.contracts(?:-spec|-integrations)?|define(Command|Query|Event|Feature|Presentation|Capability|Form|DataView|Integration)|OperationSpecRegistry|ContractHandler|installOp|contracts\b|['"][^'"]+\.(operation|event|presentation|feature|capability|form|test-spec)(?:\.[tj]sx?)?['"]/;
7929
+ var CONTRACT_CONTEXT_PATTERN = /@contractspec\/(?:lib\.contracts(?:-spec|-integrations)?|module\.ai-chat|bundle\.library\/application\/mcp|example\.)|['"][^'"]+\.(operation|event|presentation|feature|capability|form|test-spec)(?:\.[tj]sx?)?['"]/;
7930
+ var SUPPORT_FILE_PATTERN = /(^|\/)(index|types)\.ts$|\.types\.ts$|\.storage\.ts$|(?:^|\/)[^/]*\.(resolver|scheduler)\.ts$|(?:^|\/)[^/]*(factory|resources|mock-data)\.ts$/i;
7931
+ var FIXTURE_PATH_PATTERN = /(^|\/)(__fixtures__|fixtures)(\/|$)/i;
7932
+ var WORKSPACE_PACKAGE_ROOT_PATTERN = /^(.*\/packages\/(?:apps|apps-registry|bundles|examples|integrations|libs|modules|tools)\/[^/]+)(?:\/|$)/i;
7933
+ var PACKAGE_ROOT_POLICY_CONTEXT_PATTERN = /\/packages\/(?:apps|apps-registry|bundles|modules)\//i;
7929
7934
  function splitConventionPath(value) {
7930
7935
  if (!value) {
7931
7936
  return [];
@@ -7949,7 +7954,7 @@ function isPolicyCandidate(filePath, specFiles, config) {
7949
7954
  if (!/\.(ts|tsx)$/.test(normalized)) {
7950
7955
  return false;
7951
7956
  }
7952
- if (normalized.includes("/node_modules/") || normalized.includes("/dist/") || normalized.endsWith(".d.ts") || normalized.endsWith(".test.ts") || normalized.endsWith(".spec.ts")) {
7957
+ if (normalized.includes("/node_modules/") || normalized.includes("/dist/") || FIXTURE_PATH_PATTERN.test(normalized) || SUPPORT_FILE_PATTERN.test(normalized) || normalized.endsWith(".d.ts") || normalized.endsWith(".test.ts") || normalized.endsWith(".spec.ts")) {
7953
7958
  return false;
7954
7959
  }
7955
7960
  if (specFiles.has(normalized)) {
@@ -7960,6 +7965,16 @@ function isPolicyCandidate(filePath, specFiles, config) {
7960
7965
  }
7961
7966
  return IMPLEMENTATION_PATH_PATTERN.test(normalized);
7962
7967
  }
7968
+ function getWorkspacePackageRoot(filePath) {
7969
+ const normalized = filePath.replaceAll("\\", "/");
7970
+ const match = normalized.match(WORKSPACE_PACKAGE_ROOT_PATTERN);
7971
+ return match?.[1] ?? null;
7972
+ }
7973
+ function isBarrelFile(content) {
7974
+ const meaningfulLines = content.split(`
7975
+ `).map((line) => line.trim()).filter((line) => line.length > 0 && !line.startsWith("//") && !line.startsWith("/*") && !line.startsWith("*") && !line.startsWith("*/"));
7976
+ return meaningfulLines.length > 0 && meaningfulLines.every((line) => line.startsWith("import ") || line.startsWith("export *") || line.startsWith("export {") || line.startsWith("export type {") || line === "'use client';" || line === '"use client";' || line === "'use server';" || line === '"use server";');
7977
+ }
7963
7978
  function resolvePolicyConfig(config) {
7964
7979
  if (!config) {
7965
7980
  return DEFAULT_CONTRACTSRC3;
@@ -7985,6 +8000,7 @@ async function runPolicyChecks(adapters, options) {
7985
8000
  const config = options.config ? resolvePolicyConfig(options.config) : await loadWorkspaceConfig(fs5);
7986
8001
  const scannedSpecs = await listSpecs({ fs: fs5 }, { config });
7987
8002
  const specFiles = new Set(scannedSpecs.map((spec) => spec.filePath.replaceAll("\\", "/")));
8003
+ const packageRootsWithSpecs = new Set(scannedSpecs.map((spec) => getWorkspacePackageRoot(spec.filePath)).filter((root) => Boolean(root)));
7988
8004
  const sourceFiles = await fs5.glob({ pattern: "**/*.{ts,tsx}" });
7989
8005
  for (const file of sourceFiles) {
7990
8006
  if (!isPolicyCandidate(file, specFiles, config)) {
@@ -7992,6 +8008,14 @@ async function runPolicyChecks(adapters, options) {
7992
8008
  }
7993
8009
  try {
7994
8010
  const content = await fs5.readFile(file);
8011
+ if (isBarrelFile(content)) {
8012
+ continue;
8013
+ }
8014
+ const packageRoot = getWorkspacePackageRoot(file);
8015
+ const hasLocalSpecContext = packageRoot !== null && PACKAGE_ROOT_POLICY_CONTEXT_PATTERN.test(packageRoot) && packageRootsWithSpecs.has(packageRoot);
8016
+ if (!hasLocalSpecContext && !CONTRACT_CONTEXT_PATTERN.test(content)) {
8017
+ continue;
8018
+ }
7995
8019
  if (CONTRACT_REFERENCE_PATTERN.test(content)) {
7996
8020
  continue;
7997
8021
  }
@@ -7925,7 +7925,12 @@ import {
7925
7925
  DEFAULT_CONTRACTSRC as DEFAULT_CONTRACTSRC3
7926
7926
  } from "@contractspec/lib.contracts-spec/workspace-config";
7927
7927
  var IMPLEMENTATION_PATH_PATTERN = /(^|\/)(handlers?|routes?|controllers?|api)(\/|$)|\.(handler|handlers|route|routes|controller)\.(ts|tsx)$/i;
7928
- var CONTRACT_REFERENCE_PATTERN = /@contractspec\/lib\.contracts(?:-spec|-integrations)?|define(Command|Query|Event|Feature|Presentation|Capability|Form|DataView|Integration)|OperationSpecRegistry|ContractHandler|installOp|contracts\//;
7928
+ var CONTRACT_REFERENCE_PATTERN = /@contractspec\/lib\.contracts(?:-spec|-integrations)?|define(Command|Query|Event|Feature|Presentation|Capability|Form|DataView|Integration)|OperationSpecRegistry|ContractHandler|installOp|contracts\b|['"][^'"]+\.(operation|event|presentation|feature|capability|form|test-spec)(?:\.[tj]sx?)?['"]/;
7929
+ var CONTRACT_CONTEXT_PATTERN = /@contractspec\/(?:lib\.contracts(?:-spec|-integrations)?|module\.ai-chat|bundle\.library\/application\/mcp|example\.)|['"][^'"]+\.(operation|event|presentation|feature|capability|form|test-spec)(?:\.[tj]sx?)?['"]/;
7930
+ var SUPPORT_FILE_PATTERN = /(^|\/)(index|types)\.ts$|\.types\.ts$|\.storage\.ts$|(?:^|\/)[^/]*\.(resolver|scheduler)\.ts$|(?:^|\/)[^/]*(factory|resources|mock-data)\.ts$/i;
7931
+ var FIXTURE_PATH_PATTERN = /(^|\/)(__fixtures__|fixtures)(\/|$)/i;
7932
+ var WORKSPACE_PACKAGE_ROOT_PATTERN = /^(.*\/packages\/(?:apps|apps-registry|bundles|examples|integrations|libs|modules|tools)\/[^/]+)(?:\/|$)/i;
7933
+ var PACKAGE_ROOT_POLICY_CONTEXT_PATTERN = /\/packages\/(?:apps|apps-registry|bundles|modules)\//i;
7929
7934
  function splitConventionPath(value) {
7930
7935
  if (!value) {
7931
7936
  return [];
@@ -7949,7 +7954,7 @@ function isPolicyCandidate(filePath, specFiles, config) {
7949
7954
  if (!/\.(ts|tsx)$/.test(normalized)) {
7950
7955
  return false;
7951
7956
  }
7952
- if (normalized.includes("/node_modules/") || normalized.includes("/dist/") || normalized.endsWith(".d.ts") || normalized.endsWith(".test.ts") || normalized.endsWith(".spec.ts")) {
7957
+ if (normalized.includes("/node_modules/") || normalized.includes("/dist/") || FIXTURE_PATH_PATTERN.test(normalized) || SUPPORT_FILE_PATTERN.test(normalized) || normalized.endsWith(".d.ts") || normalized.endsWith(".test.ts") || normalized.endsWith(".spec.ts")) {
7953
7958
  return false;
7954
7959
  }
7955
7960
  if (specFiles.has(normalized)) {
@@ -7960,6 +7965,16 @@ function isPolicyCandidate(filePath, specFiles, config) {
7960
7965
  }
7961
7966
  return IMPLEMENTATION_PATH_PATTERN.test(normalized);
7962
7967
  }
7968
+ function getWorkspacePackageRoot(filePath) {
7969
+ const normalized = filePath.replaceAll("\\", "/");
7970
+ const match = normalized.match(WORKSPACE_PACKAGE_ROOT_PATTERN);
7971
+ return match?.[1] ?? null;
7972
+ }
7973
+ function isBarrelFile(content) {
7974
+ const meaningfulLines = content.split(`
7975
+ `).map((line) => line.trim()).filter((line) => line.length > 0 && !line.startsWith("//") && !line.startsWith("/*") && !line.startsWith("*") && !line.startsWith("*/"));
7976
+ return meaningfulLines.length > 0 && meaningfulLines.every((line) => line.startsWith("import ") || line.startsWith("export *") || line.startsWith("export {") || line.startsWith("export type {") || line === "'use client';" || line === '"use client";' || line === "'use server';" || line === '"use server";');
7977
+ }
7963
7978
  function resolvePolicyConfig(config) {
7964
7979
  if (!config) {
7965
7980
  return DEFAULT_CONTRACTSRC3;
@@ -7985,6 +8000,7 @@ async function runPolicyChecks(adapters, options) {
7985
8000
  const config = options.config ? resolvePolicyConfig(options.config) : await loadWorkspaceConfig(fs5);
7986
8001
  const scannedSpecs = await listSpecs({ fs: fs5 }, { config });
7987
8002
  const specFiles = new Set(scannedSpecs.map((spec) => spec.filePath.replaceAll("\\", "/")));
8003
+ const packageRootsWithSpecs = new Set(scannedSpecs.map((spec) => getWorkspacePackageRoot(spec.filePath)).filter((root) => Boolean(root)));
7988
8004
  const sourceFiles = await fs5.glob({ pattern: "**/*.{ts,tsx}" });
7989
8005
  for (const file of sourceFiles) {
7990
8006
  if (!isPolicyCandidate(file, specFiles, config)) {
@@ -7992,6 +8008,14 @@ async function runPolicyChecks(adapters, options) {
7992
8008
  }
7993
8009
  try {
7994
8010
  const content = await fs5.readFile(file);
8011
+ if (isBarrelFile(content)) {
8012
+ continue;
8013
+ }
8014
+ const packageRoot = getWorkspacePackageRoot(file);
8015
+ const hasLocalSpecContext = packageRoot !== null && PACKAGE_ROOT_POLICY_CONTEXT_PATTERN.test(packageRoot) && packageRootsWithSpecs.has(packageRoot);
8016
+ if (!hasLocalSpecContext && !CONTRACT_CONTEXT_PATTERN.test(content)) {
8017
+ continue;
8018
+ }
7995
8019
  if (CONTRACT_REFERENCE_PATTERN.test(content)) {
7996
8020
  continue;
7997
8021
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@contractspec/bundle.workspace",
3
- "version": "4.0.0",
3
+ "version": "4.0.3",
4
4
  "description": "Workspace utilities for monorepo development",
5
5
  "keywords": [
6
6
  "contractspec",
@@ -33,15 +33,15 @@
33
33
  "dependencies": {
34
34
  "@ai-sdk/anthropic": "3.0.58",
35
35
  "@ai-sdk/openai": "3.0.41",
36
- "@contractspec/biome-config": "3.8.0",
37
- "@contractspec/lib.ai-agent": "7.0.7",
38
- "@contractspec/lib.ai-providers": "3.7.6",
39
- "@contractspec/lib.contracts-spec": "4.0.0",
40
- "@contractspec/lib.contracts-integrations": "3.7.7",
41
- "@contractspec/lib.contracts-transformers": "3.7.7",
42
- "@contractspec/lib.source-extractors": "2.7.7",
43
- "@contractspec/module.workspace": "4.0.0",
44
- "@contractspec/lib.utils-typescript": "3.7.6",
36
+ "@contractspec/biome-config": "3.8.2",
37
+ "@contractspec/lib.ai-agent": "7.0.10",
38
+ "@contractspec/lib.ai-providers": "3.7.8",
39
+ "@contractspec/lib.contracts-spec": "4.1.2",
40
+ "@contractspec/lib.contracts-integrations": "3.8.2",
41
+ "@contractspec/lib.contracts-transformers": "3.7.10",
42
+ "@contractspec/lib.source-extractors": "2.7.10",
43
+ "@contractspec/module.workspace": "4.0.3",
44
+ "@contractspec/lib.utils-typescript": "3.7.8",
45
45
  "ai": "6.0.116",
46
46
  "chalk": "^5.6.2",
47
47
  "chokidar": "^5.0.0",
@@ -54,12 +54,12 @@
54
54
  "zod": "^4.3.5"
55
55
  },
56
56
  "devDependencies": {
57
- "@contractspec/tool.typescript": "3.7.6",
57
+ "@contractspec/tool.typescript": "3.7.8",
58
58
  "@types/bun": "^1.3.11",
59
59
  "@types/micromatch": "^4.0.10",
60
60
  "@types/node": "^25.3.5",
61
61
  "typescript": "^5.9.3",
62
- "@contractspec/tool.bun": "3.7.6"
62
+ "@contractspec/tool.bun": "3.7.8"
63
63
  },
64
64
  "exports": {
65
65
  ".": {