@webpieces/rules-config 0.3.189 → 0.3.191

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@webpieces/rules-config",
3
- "version": "0.3.189",
3
+ "version": "0.3.191",
4
4
  "description": "Shared webpieces.config.json loader. Single source of truth for validation rule configuration consumed by @webpieces/ai-hook-rules, @webpieces/code-rules, and @webpieces/nx-webpieces-rules.",
5
5
  "type": "commonjs",
6
6
  "main": "./src/index.js",
@@ -0,0 +1,15 @@
1
+ export declare const CONFIG_FILENAME = "webpieces.config.json";
2
+ export interface RawConfigFile {
3
+ extends?: string;
4
+ rules?: Record<string, Record<string, unknown>>;
5
+ rulesDir?: string[];
6
+ 'pr-gate'?: unknown;
7
+ }
8
+ /**
9
+ * Walk up from `startDir` looking for webpieces.config.json. Returns its absolute path or null.
10
+ */
11
+ export declare function findConfigFile(startDir: string): string | null;
12
+ /**
13
+ * Read + JSON.parse webpieces.config.json, surfacing parse failures as a readable InformAiError.
14
+ */
15
+ export declare function readRawConfig(configPath: string): RawConfigFile;
@@ -0,0 +1,43 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CONFIG_FILENAME = void 0;
4
+ exports.findConfigFile = findConfigFile;
5
+ exports.readRawConfig = readRawConfig;
6
+ const tslib_1 = require("tslib");
7
+ const fs = tslib_1.__importStar(require("fs"));
8
+ const path = tslib_1.__importStar(require("path"));
9
+ const inform_ai_error_1 = require("./inform-ai-error");
10
+ const to_error_1 = require("./to-error");
11
+ exports.CONFIG_FILENAME = 'webpieces.config.json';
12
+ /**
13
+ * Walk up from `startDir` looking for webpieces.config.json. Returns its absolute path or null.
14
+ */
15
+ function findConfigFile(startDir) {
16
+ let dir = startDir;
17
+ while (true) {
18
+ const primary = path.join(dir, exports.CONFIG_FILENAME);
19
+ if (fs.existsSync(primary))
20
+ return primary;
21
+ const parent = path.dirname(dir);
22
+ if (parent === dir)
23
+ return null;
24
+ dir = parent;
25
+ }
26
+ }
27
+ /**
28
+ * Read + JSON.parse webpieces.config.json, surfacing parse failures as a readable InformAiError.
29
+ */
30
+ function readRawConfig(configPath) {
31
+ const raw = fs.readFileSync(configPath, 'utf8');
32
+ // eslint-disable-next-line @webpieces/no-unmanaged-exceptions
33
+ try {
34
+ return JSON.parse(raw);
35
+ }
36
+ catch (err) {
37
+ const error = (0, to_error_1.toError)(err);
38
+ throw new inform_ai_error_1.InformAiError(`webpieces.config.json has invalid JSON — fix the file, then retry.\n` +
39
+ `Parse error: ${error.message}\n` +
40
+ `File: ${configPath}`);
41
+ }
42
+ }
43
+ //# sourceMappingURL=config-file.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config-file.js","sourceRoot":"","sources":["../../../../../packages/tooling/rules-config/src/config-file.ts"],"names":[],"mappings":";;;AAuBA,wCASC;AAKD,sCAaC;;AAlDD,+CAAyB;AACzB,mDAA6B;AAE7B,uDAAkD;AAClD,yCAAqC;AAExB,QAAA,eAAe,GAAG,uBAAuB,CAAC;AAcvD;;GAEG;AACH,SAAgB,cAAc,CAAC,QAAgB;IAC3C,IAAI,GAAG,GAAG,QAAQ,CAAC;IACnB,OAAO,IAAI,EAAE,CAAC;QACV,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,uBAAe,CAAC,CAAC;QAChD,IAAI,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC;YAAE,OAAO,OAAO,CAAC;QAC3C,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QACjC,IAAI,MAAM,KAAK,GAAG;YAAE,OAAO,IAAI,CAAC;QAChC,GAAG,GAAG,MAAM,CAAC;IACjB,CAAC;AACL,CAAC;AAED;;GAEG;AACH,SAAgB,aAAa,CAAC,UAAkB;IAC5C,MAAM,GAAG,GAAG,EAAE,CAAC,YAAY,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;IAChD,8DAA8D;IAC9D,IAAI,CAAC;QACD,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAkB,CAAC;IAC5C,CAAC;IAAC,OAAO,GAAY,EAAE,CAAC;QACpB,MAAM,KAAK,GAAG,IAAA,kBAAO,EAAC,GAAG,CAAC,CAAC;QAC3B,MAAM,IAAI,+BAAa,CACnB,sEAAsE;YACtE,gBAAgB,KAAK,CAAC,OAAO,IAAI;YACjC,SAAS,UAAU,EAAE,CACxB,CAAC;IACN,CAAC;AACL,CAAC","sourcesContent":["import * as fs from 'fs';\nimport * as path from 'path';\n\nimport { InformAiError } from './inform-ai-error';\nimport { toError } from './to-error';\n\nexport const CONFIG_FILENAME = 'webpieces.config.json';\n\n// Raw shape of webpieces.config.json as parsed from JSON, before validation/typing. `pr-gate` is a\n// top-level sibling of `rules` (its nested `gates` array can't be expressed in the FieldDef schema),\n// so it is carried here as opaque JSON and validated structurally by validatePrGateSection.\n// webpieces-disable no-any-unknown -- consumer JSON config has opaque rule option values\nexport interface RawConfigFile {\n extends?: string;\n rules?: Record<string, Record<string, unknown>>;\n rulesDir?: string[];\n // webpieces-disable no-any-unknown -- opaque pr-gate JSON, validated by validatePrGateSection\n 'pr-gate'?: unknown;\n}\n\n/**\n * Walk up from `startDir` looking for webpieces.config.json. Returns its absolute path or null.\n */\nexport function findConfigFile(startDir: string): string | null {\n let dir = startDir;\n while (true) {\n const primary = path.join(dir, CONFIG_FILENAME);\n if (fs.existsSync(primary)) return primary;\n const parent = path.dirname(dir);\n if (parent === dir) return null;\n dir = parent;\n }\n}\n\n/**\n * Read + JSON.parse webpieces.config.json, surfacing parse failures as a readable InformAiError.\n */\nexport function readRawConfig(configPath: string): RawConfigFile {\n const raw = fs.readFileSync(configPath, 'utf8');\n // eslint-disable-next-line @webpieces/no-unmanaged-exceptions\n try {\n return JSON.parse(raw) as RawConfigFile;\n } catch (err: unknown) {\n const error = toError(err);\n throw new InformAiError(\n `webpieces.config.json has invalid JSON — fix the file, then retry.\\n` +\n `Parse error: ${error.message}\\n` +\n `File: ${configPath}`,\n );\n }\n}\n"]}
package/src/constants.js CHANGED
@@ -43,7 +43,7 @@ exports.MERGE_IN_PROGRESS_FILE = 'merge-in-progress.json';
43
43
  // Proof-of-work the AI must produce for every conflicted file it resolves during a 3-point
44
44
  // merge: a short explanation written NEXT TO that file's 3-point context (the same
45
45
  // `updatemain-<safe_path>/` dir that holds A-forkpoint.txt / B-A.diff / C-A.diff). The
46
- // merge-complete gate requires a non-empty file of this name per conflicted file before passing —
46
+ // wp-finish-upsert-pr gate requires a non-empty file of this name per conflicted file before passing —
47
47
  // it is the only check on the part of the process the AI actually owns (resolving files). Using a
48
48
  // sidecar file (rather than an in-source comment) works for any file type, including comment-less
49
49
  // ones like JSON and files resolved by deletion.
@@ -1 +1 @@
1
- {"version":3,"file":"constants.js","sourceRoot":"","sources":["../../../../../packages/tooling/rules-config/src/constants.ts"],"names":[],"mappings":";AAAA,iFAAiF;AACjF,sEAAsE;AACtE,EAAE;AACF,yFAAyF;AACzF,qFAAqF;AACrF,kFAAkF;;;AAoDlF,gCAEC;AApDY,QAAA,iBAAiB,GAAG,mBAAmB,CAAC;AAErD,kFAAkF;AAClF,uFAAuF;AACvF,uEAAuE;AACvE,sFAAsF;AACzE,QAAA,UAAU,GAAG;IACtB,cAAc,EAAE,gBAAgB;IAChC,eAAe,EAAE,iBAAiB;IAClC,cAAc,EAAE,gBAAgB;IAChC,uBAAuB,EAAE,yBAAyB;IAClD,mBAAmB,EAAE,qBAAqB;IAC1C,oBAAoB,EAAE,sBAAsB;IAC5C,mBAAmB,EAAE,qBAAqB;IAC1C,mBAAmB,EAAE,qBAAqB;IAC1C,eAAe,EAAE,iBAAiB;IAClC,sBAAsB,EAAE,wBAAwB;IAChD,gBAAgB,EAAE,kBAAkB;IACpC,qBAAqB,EAAE,uBAAuB;IAC9C,wBAAwB,EAAE,0BAA0B;IACpD,kBAAkB,EAAE,oBAAoB;CAClC,CAAC;AAEX,wFAAwF;AACxF,0FAA0F;AAC1F,sFAAsF;AACtF,0DAA0D;AAC1D,EAAE;AACF,mFAAmF;AACnF,yFAAyF;AACzF,yFAAyF;AAC5E,QAAA,iBAAiB,GAAG,YAAY,CAAC;AACjC,QAAA,gBAAgB,GAAG,QAAQ,CAAC;AAC5B,QAAA,sBAAsB,GAAG,wBAAwB,CAAC;AAE/D,2FAA2F;AAC3F,mFAAmF;AACnF,uFAAuF;AACvF,kGAAkG;AAClG,kGAAkG;AAClG,kGAAkG;AAClG,iDAAiD;AACpC,QAAA,sBAAsB,GAAG,sBAAsB,CAAC;AAE7D;;;;;GAKG;AACH,SAAgB,UAAU,CAAC,IAAY,EAAE,QAAgB;IACrD,OAAO,IAAI,CAAC,QAAQ,CAAC,yBAAiB,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;AACvE,CAAC","sourcesContent":["// Single source of truth for the disable-comment token and rule-name identifiers\n// shared across rules-config, ai-hook-rules, code-rules, and pr-gate.\n//\n// There is exactly ONE disable form: `// webpieces-disable <rule>[, <rule2>] -- reason`.\n// The legacy `ai-hook-disable` alias and the `-file`/`-next`/`-all` variants and the\n// `*`/bare (no-rule) wildcard have been removed — every disable MUST name a rule.\n\nexport const WEBPIECES_DISABLE = 'webpieces-disable';\n\n// Rule-name tokens as they appear AFTER `webpieces-disable` in a disable comment.\n// Values must match existing comments exactly — changing a value silently breaks every\n// disable that names that rule. Note MAX_LINES_MODIFIED is a prefix of\n// MAX_LINES_MODIFIED_FILES (a historical substring-match quirk preserved on purpose).\nexport const RULE_NAMES = {\n NO_ANY_UNKNOWN: 'no-any-unknown',\n NO_IMPLICIT_ANY: 'no-implicit-any',\n NO_DESTRUCTURE: 'no-destructure',\n NO_UNMANAGED_EXCEPTIONS: 'no-unmanaged-exceptions',\n CATCH_ERROR_PATTERN: 'catch-error-pattern',\n THROW_CAUSE_REQUIRED: 'throw-cause-required',\n REQUIRE_RETURN_TYPE: 'require-return-type',\n NO_SYMBOL_DI_TOKENS: 'no-symbol-di-tokens',\n NO_INLINE_TYPES: 'no-inline-types',\n NO_DIRECT_API_RESOLVER: 'no-direct-api-resolver',\n PRISMA_CONVERTER: 'prisma-converter',\n MAX_LINES_NEW_METHODS: 'max-lines-new-methods',\n MAX_LINES_MODIFIED_FILES: 'max-lines-modified-files',\n MAX_LINES_MODIFIED: 'max-lines-modified',\n} as const;\n\n// Merge-state convention shared by the pr-gate scripts (which WRITE the marker during a\n// conflicted 3-point merge) and the ai-hook-rules merge-in-progress-guard (which READS it\n// to block commit/push/PR until the merge is validated). Kept here so neither package\n// depends on the other — they only share this vocabulary.\n//\n// `.webpieces/` is the single working dir for all webpieces tooling: ai-hook-rules\n// bootstrap/cache, the instruct-ai docs, and the per-feature merge-/review-/pr- workflow\n// dirs. It is gitignored. Only the prefixed workflow dirs are subject to 30-day cleanup.\nexport const WEBPIECES_TMP_DIR = '.webpieces';\nexport const MERGE_DIR_PREFIX = 'merge-';\nexport const MERGE_IN_PROGRESS_FILE = 'merge-in-progress.json';\n\n// Proof-of-work the AI must produce for every conflicted file it resolves during a 3-point\n// merge: a short explanation written NEXT TO that file's 3-point context (the same\n// `updatemain-<safe_path>/` dir that holds A-forkpoint.txt / B-A.diff / C-A.diff). The\n// merge-complete gate requires a non-empty file of this name per conflicted file before passing —\n// it is the only check on the part of the process the AI actually owns (resolving files). Using a\n// sidecar file (rather than an in-source comment) works for any file type, including comment-less\n// ones like JSON and files resolved by deletion.\nexport const MERGE_EXPLANATION_FILE = 'merge-explanation.md';\n\n/**\n * Fast predicate: does this text carry a webpieces-disable for the given rule?\n * Line-agnostic — the caller decides which line(s) or block of text to feed it.\n * This is the cheap substring form used by code-rules detection and pr-gate's\n * dashboard grep/count. (ai-hook-rules uses a richer line-mapping parser.)\n */\nexport function hasDisable(text: string, ruleName: string): boolean {\n return text.includes(WEBPIECES_DISABLE) && text.includes(ruleName);\n}\n"]}
1
+ {"version":3,"file":"constants.js","sourceRoot":"","sources":["../../../../../packages/tooling/rules-config/src/constants.ts"],"names":[],"mappings":";AAAA,iFAAiF;AACjF,sEAAsE;AACtE,EAAE;AACF,yFAAyF;AACzF,qFAAqF;AACrF,kFAAkF;;;AAoDlF,gCAEC;AApDY,QAAA,iBAAiB,GAAG,mBAAmB,CAAC;AAErD,kFAAkF;AAClF,uFAAuF;AACvF,uEAAuE;AACvE,sFAAsF;AACzE,QAAA,UAAU,GAAG;IACtB,cAAc,EAAE,gBAAgB;IAChC,eAAe,EAAE,iBAAiB;IAClC,cAAc,EAAE,gBAAgB;IAChC,uBAAuB,EAAE,yBAAyB;IAClD,mBAAmB,EAAE,qBAAqB;IAC1C,oBAAoB,EAAE,sBAAsB;IAC5C,mBAAmB,EAAE,qBAAqB;IAC1C,mBAAmB,EAAE,qBAAqB;IAC1C,eAAe,EAAE,iBAAiB;IAClC,sBAAsB,EAAE,wBAAwB;IAChD,gBAAgB,EAAE,kBAAkB;IACpC,qBAAqB,EAAE,uBAAuB;IAC9C,wBAAwB,EAAE,0BAA0B;IACpD,kBAAkB,EAAE,oBAAoB;CAClC,CAAC;AAEX,wFAAwF;AACxF,0FAA0F;AAC1F,sFAAsF;AACtF,0DAA0D;AAC1D,EAAE;AACF,mFAAmF;AACnF,yFAAyF;AACzF,yFAAyF;AAC5E,QAAA,iBAAiB,GAAG,YAAY,CAAC;AACjC,QAAA,gBAAgB,GAAG,QAAQ,CAAC;AAC5B,QAAA,sBAAsB,GAAG,wBAAwB,CAAC;AAE/D,2FAA2F;AAC3F,mFAAmF;AACnF,uFAAuF;AACvF,uGAAuG;AACvG,kGAAkG;AAClG,kGAAkG;AAClG,iDAAiD;AACpC,QAAA,sBAAsB,GAAG,sBAAsB,CAAC;AAE7D;;;;;GAKG;AACH,SAAgB,UAAU,CAAC,IAAY,EAAE,QAAgB;IACrD,OAAO,IAAI,CAAC,QAAQ,CAAC,yBAAiB,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;AACvE,CAAC","sourcesContent":["// Single source of truth for the disable-comment token and rule-name identifiers\n// shared across rules-config, ai-hook-rules, code-rules, and pr-gate.\n//\n// There is exactly ONE disable form: `// webpieces-disable <rule>[, <rule2>] -- reason`.\n// The legacy `ai-hook-disable` alias and the `-file`/`-next`/`-all` variants and the\n// `*`/bare (no-rule) wildcard have been removed — every disable MUST name a rule.\n\nexport const WEBPIECES_DISABLE = 'webpieces-disable';\n\n// Rule-name tokens as they appear AFTER `webpieces-disable` in a disable comment.\n// Values must match existing comments exactly — changing a value silently breaks every\n// disable that names that rule. Note MAX_LINES_MODIFIED is a prefix of\n// MAX_LINES_MODIFIED_FILES (a historical substring-match quirk preserved on purpose).\nexport const RULE_NAMES = {\n NO_ANY_UNKNOWN: 'no-any-unknown',\n NO_IMPLICIT_ANY: 'no-implicit-any',\n NO_DESTRUCTURE: 'no-destructure',\n NO_UNMANAGED_EXCEPTIONS: 'no-unmanaged-exceptions',\n CATCH_ERROR_PATTERN: 'catch-error-pattern',\n THROW_CAUSE_REQUIRED: 'throw-cause-required',\n REQUIRE_RETURN_TYPE: 'require-return-type',\n NO_SYMBOL_DI_TOKENS: 'no-symbol-di-tokens',\n NO_INLINE_TYPES: 'no-inline-types',\n NO_DIRECT_API_RESOLVER: 'no-direct-api-resolver',\n PRISMA_CONVERTER: 'prisma-converter',\n MAX_LINES_NEW_METHODS: 'max-lines-new-methods',\n MAX_LINES_MODIFIED_FILES: 'max-lines-modified-files',\n MAX_LINES_MODIFIED: 'max-lines-modified',\n} as const;\n\n// Merge-state convention shared by the pr-gate scripts (which WRITE the marker during a\n// conflicted 3-point merge) and the ai-hook-rules merge-in-progress-guard (which READS it\n// to block commit/push/PR until the merge is validated). Kept here so neither package\n// depends on the other — they only share this vocabulary.\n//\n// `.webpieces/` is the single working dir for all webpieces tooling: ai-hook-rules\n// bootstrap/cache, the instruct-ai docs, and the per-feature merge-/review-/pr- workflow\n// dirs. It is gitignored. Only the prefixed workflow dirs are subject to 30-day cleanup.\nexport const WEBPIECES_TMP_DIR = '.webpieces';\nexport const MERGE_DIR_PREFIX = 'merge-';\nexport const MERGE_IN_PROGRESS_FILE = 'merge-in-progress.json';\n\n// Proof-of-work the AI must produce for every conflicted file it resolves during a 3-point\n// merge: a short explanation written NEXT TO that file's 3-point context (the same\n// `updatemain-<safe_path>/` dir that holds A-forkpoint.txt / B-A.diff / C-A.diff). The\n// wp-finish-upsert-pr gate requires a non-empty file of this name per conflicted file before passing —\n// it is the only check on the part of the process the AI actually owns (resolving files). Using a\n// sidecar file (rather than an in-source comment) works for any file type, including comment-less\n// ones like JSON and files resolved by deletion.\nexport const MERGE_EXPLANATION_FILE = 'merge-explanation.md';\n\n/**\n * Fast predicate: does this text carry a webpieces-disable for the given rule?\n * Line-agnostic — the caller decides which line(s) or block of text to feed it.\n * This is the cheap substring form used by code-rules detection and pr-gate's\n * dashboard grep/count. (ai-hook-rules uses a richer line-mapping parser.)\n */\nexport function hasDisable(text: string, ruleName: string): boolean {\n return text.includes(WEBPIECES_DISABLE) && text.includes(ruleName);\n}\n"]}
package/src/index.d.ts CHANGED
@@ -1,12 +1,12 @@
1
1
  export { ResolvedConfig, ResolvedRuleConfig, RuleOptions } from './types';
2
2
  export { InformAiError } from './inform-ai-error';
3
3
  export { toError } from './to-error';
4
- export { loadConfig, findConfigFile, CONFIG_FILENAME, loadWebpiecesRulesConfig } from './load-config';
5
- export type { LoadedWebpiecesConfig } from './load-config';
4
+ export { loadAndValidate, LoadedConfig } from './load-config';
5
+ export { findConfigFile, CONFIG_FILENAME } from './config-file';
6
6
  export { isPathExcluded } from './exclude-paths';
7
7
  export { defaultRules, defaultRulesDir } from './default-rules';
8
8
  export { loadTemplate, writeTemplateIfMissing, writeTemplate } from './load-template';
9
- export { validateWebpiecesConfig } from './validate-config';
9
+ export { validateWebpiecesConfig, validatePrGateSection } from './validate-config';
10
10
  export { FieldDef } from './field-def';
11
11
  export type { SchemaShape } from './field-def';
12
12
  export { shouldSkipRule, getCurrentBranch } from './skip-rule';
@@ -17,4 +17,5 @@ export { WebpiecesRulesConfig } from './WebpiecesRulesConfig';
17
17
  export { MaxMethodLinesConfig, MaxFileLinesConfig, RequireReturnTypeConfig, NoInlineTypeLiteralsConfig, NoAnyUnknownConfig, NoImplicitAnyConfig, PrismaValidateDtosConfig, PrismaConverterConfig, NoDestructureConfig, NoUnmanagedExceptionsConfig, CatchErrorPatternConfig, ThrowCauseRequiredConfig, AngularNoDirectApiInResolverConfig, NoSymbolDiTokensConfig, NoShellSubstitutionConfig, BranchCreationGuardConfig, PrCreationGuardConfig, MergeInProgressGuardConfig, PrMergeCleanupConfig, NoDirectMainUpdateConfig, NoEditOnMainConfig, NoFileImportCyclesConfig, RuntimeArchitectureConfig, NoJsFilesConfig, ValidateTsInSrcConfig, BaseRuleConfig, } from './rule-configs';
18
18
  export { METHOD_LIMIT_MODES, FILE_LIMIT_MODES, RETURN_TYPE_MODES, INLINE_TYPE_MODES, MODIFIED_CODE_MODES, PRISMA_DTOS_MODES, PRISMA_CONVERTER_MODES, DIRECT_API_RESOLVER_MODES, THROW_CAUSE_MODES, ON_OFF_MODES, VALIDATE_TS_MODES, } from './rule-configs';
19
19
  export type { MethodLimitMode, FileLimitMode, ReturnTypeMode, InlineTypeMode, ModifiedCodeMode, PrismaValidateDtosMode, PrismaConverterMode, DirectApiResolverMode, ThrowCauseMode, OnOffMode, ValidateTsMode, } from './rule-configs';
20
- export { GateDefinition, PrGateConfig, defaultGates, defaultPrGateConfig, loadPrGateConfig, } from './pr-gate-config';
20
+ export { GateDefinition, PrGateConfig, defaultGates, defaultPrGateConfig, buildPrGateConfig, } from './pr-gate-config';
21
+ export { ReviewJson, loadReviewJson, reviewJsonPath, reviewJsonSchemaHint, } from './review-json';
package/src/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.RuntimeArchitectureConfig = exports.NoFileImportCyclesConfig = exports.NoEditOnMainConfig = exports.NoDirectMainUpdateConfig = exports.PrMergeCleanupConfig = exports.MergeInProgressGuardConfig = exports.PrCreationGuardConfig = exports.BranchCreationGuardConfig = exports.NoShellSubstitutionConfig = exports.NoSymbolDiTokensConfig = exports.AngularNoDirectApiInResolverConfig = exports.ThrowCauseRequiredConfig = exports.CatchErrorPatternConfig = exports.NoUnmanagedExceptionsConfig = exports.NoDestructureConfig = exports.PrismaConverterConfig = exports.PrismaValidateDtosConfig = exports.NoImplicitAnyConfig = exports.NoAnyUnknownConfig = exports.NoInlineTypeLiteralsConfig = exports.RequireReturnTypeConfig = exports.MaxFileLinesConfig = exports.MaxMethodLinesConfig = exports.WebpiecesRulesConfig = exports.MERGE_EXPLANATION_FILE = exports.MERGE_IN_PROGRESS_FILE = exports.MERGE_DIR_PREFIX = exports.WEBPIECES_TMP_DIR = exports.hasDisable = exports.RULE_NAMES = exports.WEBPIECES_DISABLE = exports.AbstractRule = exports.getCurrentBranch = exports.shouldSkipRule = exports.FieldDef = exports.validateWebpiecesConfig = exports.writeTemplate = exports.writeTemplateIfMissing = exports.loadTemplate = exports.defaultRulesDir = exports.defaultRules = exports.isPathExcluded = exports.loadWebpiecesRulesConfig = exports.CONFIG_FILENAME = exports.findConfigFile = exports.loadConfig = exports.toError = exports.InformAiError = exports.ResolvedRuleConfig = exports.ResolvedConfig = void 0;
4
- exports.loadPrGateConfig = exports.defaultPrGateConfig = exports.defaultGates = exports.PrGateConfig = exports.GateDefinition = exports.VALIDATE_TS_MODES = exports.ON_OFF_MODES = exports.THROW_CAUSE_MODES = exports.DIRECT_API_RESOLVER_MODES = exports.PRISMA_CONVERTER_MODES = exports.PRISMA_DTOS_MODES = exports.MODIFIED_CODE_MODES = exports.INLINE_TYPE_MODES = exports.RETURN_TYPE_MODES = exports.FILE_LIMIT_MODES = exports.METHOD_LIMIT_MODES = exports.BaseRuleConfig = exports.ValidateTsInSrcConfig = exports.NoJsFilesConfig = void 0;
3
+ exports.NoFileImportCyclesConfig = exports.NoEditOnMainConfig = exports.NoDirectMainUpdateConfig = exports.PrMergeCleanupConfig = exports.MergeInProgressGuardConfig = exports.PrCreationGuardConfig = exports.BranchCreationGuardConfig = exports.NoShellSubstitutionConfig = exports.NoSymbolDiTokensConfig = exports.AngularNoDirectApiInResolverConfig = exports.ThrowCauseRequiredConfig = exports.CatchErrorPatternConfig = exports.NoUnmanagedExceptionsConfig = exports.NoDestructureConfig = exports.PrismaConverterConfig = exports.PrismaValidateDtosConfig = exports.NoImplicitAnyConfig = exports.NoAnyUnknownConfig = exports.NoInlineTypeLiteralsConfig = exports.RequireReturnTypeConfig = exports.MaxFileLinesConfig = exports.MaxMethodLinesConfig = exports.WebpiecesRulesConfig = exports.MERGE_EXPLANATION_FILE = exports.MERGE_IN_PROGRESS_FILE = exports.MERGE_DIR_PREFIX = exports.WEBPIECES_TMP_DIR = exports.hasDisable = exports.RULE_NAMES = exports.WEBPIECES_DISABLE = exports.AbstractRule = exports.getCurrentBranch = exports.shouldSkipRule = exports.FieldDef = exports.validatePrGateSection = exports.validateWebpiecesConfig = exports.writeTemplate = exports.writeTemplateIfMissing = exports.loadTemplate = exports.defaultRulesDir = exports.defaultRules = exports.isPathExcluded = exports.CONFIG_FILENAME = exports.findConfigFile = exports.LoadedConfig = exports.loadAndValidate = exports.toError = exports.InformAiError = exports.ResolvedRuleConfig = exports.ResolvedConfig = void 0;
4
+ exports.reviewJsonSchemaHint = exports.reviewJsonPath = exports.loadReviewJson = exports.ReviewJson = exports.buildPrGateConfig = exports.defaultPrGateConfig = exports.defaultGates = exports.PrGateConfig = exports.GateDefinition = exports.VALIDATE_TS_MODES = exports.ON_OFF_MODES = exports.THROW_CAUSE_MODES = exports.DIRECT_API_RESOLVER_MODES = exports.PRISMA_CONVERTER_MODES = exports.PRISMA_DTOS_MODES = exports.MODIFIED_CODE_MODES = exports.INLINE_TYPE_MODES = exports.RETURN_TYPE_MODES = exports.FILE_LIMIT_MODES = exports.METHOD_LIMIT_MODES = exports.BaseRuleConfig = exports.ValidateTsInSrcConfig = exports.NoJsFilesConfig = exports.RuntimeArchitectureConfig = void 0;
5
5
  var types_1 = require("./types");
6
6
  Object.defineProperty(exports, "ResolvedConfig", { enumerable: true, get: function () { return types_1.ResolvedConfig; } });
7
7
  Object.defineProperty(exports, "ResolvedRuleConfig", { enumerable: true, get: function () { return types_1.ResolvedRuleConfig; } });
@@ -10,10 +10,11 @@ Object.defineProperty(exports, "InformAiError", { enumerable: true, get: functio
10
10
  var to_error_1 = require("./to-error");
11
11
  Object.defineProperty(exports, "toError", { enumerable: true, get: function () { return to_error_1.toError; } });
12
12
  var load_config_1 = require("./load-config");
13
- Object.defineProperty(exports, "loadConfig", { enumerable: true, get: function () { return load_config_1.loadConfig; } });
14
- Object.defineProperty(exports, "findConfigFile", { enumerable: true, get: function () { return load_config_1.findConfigFile; } });
15
- Object.defineProperty(exports, "CONFIG_FILENAME", { enumerable: true, get: function () { return load_config_1.CONFIG_FILENAME; } });
16
- Object.defineProperty(exports, "loadWebpiecesRulesConfig", { enumerable: true, get: function () { return load_config_1.loadWebpiecesRulesConfig; } });
13
+ Object.defineProperty(exports, "loadAndValidate", { enumerable: true, get: function () { return load_config_1.loadAndValidate; } });
14
+ Object.defineProperty(exports, "LoadedConfig", { enumerable: true, get: function () { return load_config_1.LoadedConfig; } });
15
+ var config_file_1 = require("./config-file");
16
+ Object.defineProperty(exports, "findConfigFile", { enumerable: true, get: function () { return config_file_1.findConfigFile; } });
17
+ Object.defineProperty(exports, "CONFIG_FILENAME", { enumerable: true, get: function () { return config_file_1.CONFIG_FILENAME; } });
17
18
  var exclude_paths_1 = require("./exclude-paths");
18
19
  Object.defineProperty(exports, "isPathExcluded", { enumerable: true, get: function () { return exclude_paths_1.isPathExcluded; } });
19
20
  var default_rules_1 = require("./default-rules");
@@ -25,6 +26,7 @@ Object.defineProperty(exports, "writeTemplateIfMissing", { enumerable: true, get
25
26
  Object.defineProperty(exports, "writeTemplate", { enumerable: true, get: function () { return load_template_1.writeTemplate; } });
26
27
  var validate_config_1 = require("./validate-config");
27
28
  Object.defineProperty(exports, "validateWebpiecesConfig", { enumerable: true, get: function () { return validate_config_1.validateWebpiecesConfig; } });
29
+ Object.defineProperty(exports, "validatePrGateSection", { enumerable: true, get: function () { return validate_config_1.validatePrGateSection; } });
28
30
  var field_def_1 = require("./field-def");
29
31
  Object.defineProperty(exports, "FieldDef", { enumerable: true, get: function () { return field_def_1.FieldDef; } });
30
32
  var skip_rule_1 = require("./skip-rule");
@@ -87,5 +89,10 @@ Object.defineProperty(exports, "GateDefinition", { enumerable: true, get: functi
87
89
  Object.defineProperty(exports, "PrGateConfig", { enumerable: true, get: function () { return pr_gate_config_1.PrGateConfig; } });
88
90
  Object.defineProperty(exports, "defaultGates", { enumerable: true, get: function () { return pr_gate_config_1.defaultGates; } });
89
91
  Object.defineProperty(exports, "defaultPrGateConfig", { enumerable: true, get: function () { return pr_gate_config_1.defaultPrGateConfig; } });
90
- Object.defineProperty(exports, "loadPrGateConfig", { enumerable: true, get: function () { return pr_gate_config_1.loadPrGateConfig; } });
92
+ Object.defineProperty(exports, "buildPrGateConfig", { enumerable: true, get: function () { return pr_gate_config_1.buildPrGateConfig; } });
93
+ var review_json_1 = require("./review-json");
94
+ Object.defineProperty(exports, "ReviewJson", { enumerable: true, get: function () { return review_json_1.ReviewJson; } });
95
+ Object.defineProperty(exports, "loadReviewJson", { enumerable: true, get: function () { return review_json_1.loadReviewJson; } });
96
+ Object.defineProperty(exports, "reviewJsonPath", { enumerable: true, get: function () { return review_json_1.reviewJsonPath; } });
97
+ Object.defineProperty(exports, "reviewJsonSchemaHint", { enumerable: true, get: function () { return review_json_1.reviewJsonSchemaHint; } });
91
98
  //# sourceMappingURL=index.js.map
package/src/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../packages/tooling/rules-config/src/index.ts"],"names":[],"mappings":";;;;AAAA,iCAA0E;AAAjE,uGAAA,cAAc,OAAA;AAAE,2GAAA,kBAAkB,OAAA;AAC3C,qDAAkD;AAAzC,gHAAA,aAAa,OAAA;AACtB,uCAAqC;AAA5B,mGAAA,OAAO,OAAA;AAChB,6CAAsG;AAA7F,yGAAA,UAAU,OAAA;AAAE,6GAAA,cAAc,OAAA;AAAE,8GAAA,eAAe,OAAA;AAAE,uHAAA,wBAAwB,OAAA;AAE9E,iDAAiD;AAAxC,+GAAA,cAAc,OAAA;AACvB,iDAAgE;AAAvD,6GAAA,YAAY,OAAA;AAAE,gHAAA,eAAe,OAAA;AACtC,iDAAsF;AAA7E,6GAAA,YAAY,OAAA;AAAE,uHAAA,sBAAsB,OAAA;AAAE,8GAAA,aAAa,OAAA;AAC5D,qDAA4D;AAAnD,0HAAA,uBAAuB,OAAA;AAChC,yCAAuC;AAA9B,qGAAA,QAAQ,OAAA;AAEjB,yCAA+D;AAAtD,2GAAA,cAAc,OAAA;AAAE,6GAAA,gBAAgB,OAAA;AAEzC,iDAA+C;AAAtC,6GAAA,YAAY,OAAA;AACrB,yCAQqB;AAPjB,8GAAA,iBAAiB,OAAA;AACjB,uGAAA,UAAU,OAAA;AACV,uGAAA,UAAU,OAAA;AACV,8GAAA,iBAAiB,OAAA;AACjB,6GAAA,gBAAgB,OAAA;AAChB,mHAAA,sBAAsB,OAAA;AACtB,mHAAA,sBAAsB,OAAA;AAE1B,+DAA8D;AAArD,4HAAA,oBAAoB,OAAA;AAC7B,+CA2BwB;AA1BpB,oHAAA,oBAAoB,OAAA;AACpB,kHAAA,kBAAkB,OAAA;AAClB,uHAAA,uBAAuB,OAAA;AACvB,0HAAA,0BAA0B,OAAA;AAC1B,kHAAA,kBAAkB,OAAA;AAClB,mHAAA,mBAAmB,OAAA;AACnB,wHAAA,wBAAwB,OAAA;AACxB,qHAAA,qBAAqB,OAAA;AACrB,mHAAA,mBAAmB,OAAA;AACnB,2HAAA,2BAA2B,OAAA;AAC3B,uHAAA,uBAAuB,OAAA;AACvB,wHAAA,wBAAwB,OAAA;AACxB,kIAAA,kCAAkC,OAAA;AAClC,sHAAA,sBAAsB,OAAA;AACtB,yHAAA,yBAAyB,OAAA;AACzB,yHAAA,yBAAyB,OAAA;AACzB,qHAAA,qBAAqB,OAAA;AACrB,0HAAA,0BAA0B,OAAA;AAC1B,oHAAA,oBAAoB,OAAA;AACpB,wHAAA,wBAAwB,OAAA;AACxB,kHAAA,kBAAkB,OAAA;AAClB,wHAAA,wBAAwB,OAAA;AACxB,yHAAA,yBAAyB,OAAA;AACzB,+GAAA,eAAe,OAAA;AACf,qHAAA,qBAAqB,OAAA;AACrB,8GAAA,cAAc,OAAA;AAElB,wFAAwF;AACxF,+CAYwB;AAXpB,kHAAA,kBAAkB,OAAA;AAClB,gHAAA,gBAAgB,OAAA;AAChB,iHAAA,iBAAiB,OAAA;AACjB,iHAAA,iBAAiB,OAAA;AACjB,mHAAA,mBAAmB,OAAA;AACnB,iHAAA,iBAAiB,OAAA;AACjB,sHAAA,sBAAsB,OAAA;AACtB,yHAAA,yBAAyB,OAAA;AACzB,iHAAA,iBAAiB,OAAA;AACjB,4GAAA,YAAY,OAAA;AACZ,iHAAA,iBAAiB,OAAA;AAerB,mDAM0B;AALtB,gHAAA,cAAc,OAAA;AACd,8GAAA,YAAY,OAAA;AACZ,8GAAA,YAAY,OAAA;AACZ,qHAAA,mBAAmB,OAAA;AACnB,kHAAA,gBAAgB,OAAA","sourcesContent":["export { ResolvedConfig, ResolvedRuleConfig, RuleOptions } from './types';\nexport { InformAiError } from './inform-ai-error';\nexport { toError } from './to-error';\nexport { loadConfig, findConfigFile, CONFIG_FILENAME, loadWebpiecesRulesConfig } from './load-config';\nexport type { LoadedWebpiecesConfig } from './load-config';\nexport { isPathExcluded } from './exclude-paths';\nexport { defaultRules, defaultRulesDir } from './default-rules';\nexport { loadTemplate, writeTemplateIfMissing, writeTemplate } from './load-template';\nexport { validateWebpiecesConfig } from './validate-config';\nexport { FieldDef } from './field-def';\nexport type { SchemaShape } from './field-def';\nexport { shouldSkipRule, getCurrentBranch } from './skip-rule';\nexport type { SkipRuleResult } from './skip-rule';\nexport { AbstractRule } from './abstract-rule';\nexport {\n WEBPIECES_DISABLE,\n RULE_NAMES,\n hasDisable,\n WEBPIECES_TMP_DIR,\n MERGE_DIR_PREFIX,\n MERGE_IN_PROGRESS_FILE,\n MERGE_EXPLANATION_FILE,\n} from './constants';\nexport { WebpiecesRulesConfig } from './WebpiecesRulesConfig';\nexport {\n MaxMethodLinesConfig,\n MaxFileLinesConfig,\n RequireReturnTypeConfig,\n NoInlineTypeLiteralsConfig,\n NoAnyUnknownConfig,\n NoImplicitAnyConfig,\n PrismaValidateDtosConfig,\n PrismaConverterConfig,\n NoDestructureConfig,\n NoUnmanagedExceptionsConfig,\n CatchErrorPatternConfig,\n ThrowCauseRequiredConfig,\n AngularNoDirectApiInResolverConfig,\n NoSymbolDiTokensConfig,\n NoShellSubstitutionConfig,\n BranchCreationGuardConfig,\n PrCreationGuardConfig,\n MergeInProgressGuardConfig,\n PrMergeCleanupConfig,\n NoDirectMainUpdateConfig,\n NoEditOnMainConfig,\n NoFileImportCyclesConfig,\n RuntimeArchitectureConfig,\n NoJsFilesConfig,\n ValidateTsInSrcConfig,\n BaseRuleConfig,\n} from './rule-configs';\n// Mode unions + their value arrays — the single source of truth shared with code-rules.\nexport {\n METHOD_LIMIT_MODES,\n FILE_LIMIT_MODES,\n RETURN_TYPE_MODES,\n INLINE_TYPE_MODES,\n MODIFIED_CODE_MODES,\n PRISMA_DTOS_MODES,\n PRISMA_CONVERTER_MODES,\n DIRECT_API_RESOLVER_MODES,\n THROW_CAUSE_MODES,\n ON_OFF_MODES,\n VALIDATE_TS_MODES,\n} from './rule-configs';\nexport type {\n MethodLimitMode,\n FileLimitMode,\n ReturnTypeMode,\n InlineTypeMode,\n ModifiedCodeMode,\n PrismaValidateDtosMode,\n PrismaConverterMode,\n DirectApiResolverMode,\n ThrowCauseMode,\n OnOffMode,\n ValidateTsMode,\n} from './rule-configs';\nexport {\n GateDefinition,\n PrGateConfig,\n defaultGates,\n defaultPrGateConfig,\n loadPrGateConfig,\n} from './pr-gate-config';\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../packages/tooling/rules-config/src/index.ts"],"names":[],"mappings":";;;;AAAA,iCAA0E;AAAjE,uGAAA,cAAc,OAAA;AAAE,2GAAA,kBAAkB,OAAA;AAC3C,qDAAkD;AAAzC,gHAAA,aAAa,OAAA;AACtB,uCAAqC;AAA5B,mGAAA,OAAO,OAAA;AAChB,6CAA8D;AAArD,8GAAA,eAAe,OAAA;AAAE,2GAAA,YAAY,OAAA;AACtC,6CAAgE;AAAvD,6GAAA,cAAc,OAAA;AAAE,8GAAA,eAAe,OAAA;AACxC,iDAAiD;AAAxC,+GAAA,cAAc,OAAA;AACvB,iDAAgE;AAAvD,6GAAA,YAAY,OAAA;AAAE,gHAAA,eAAe,OAAA;AACtC,iDAAsF;AAA7E,6GAAA,YAAY,OAAA;AAAE,uHAAA,sBAAsB,OAAA;AAAE,8GAAA,aAAa,OAAA;AAC5D,qDAAmF;AAA1E,0HAAA,uBAAuB,OAAA;AAAE,wHAAA,qBAAqB,OAAA;AACvD,yCAAuC;AAA9B,qGAAA,QAAQ,OAAA;AAEjB,yCAA+D;AAAtD,2GAAA,cAAc,OAAA;AAAE,6GAAA,gBAAgB,OAAA;AAEzC,iDAA+C;AAAtC,6GAAA,YAAY,OAAA;AACrB,yCAQqB;AAPjB,8GAAA,iBAAiB,OAAA;AACjB,uGAAA,UAAU,OAAA;AACV,uGAAA,UAAU,OAAA;AACV,8GAAA,iBAAiB,OAAA;AACjB,6GAAA,gBAAgB,OAAA;AAChB,mHAAA,sBAAsB,OAAA;AACtB,mHAAA,sBAAsB,OAAA;AAE1B,+DAA8D;AAArD,4HAAA,oBAAoB,OAAA;AAC7B,+CA2BwB;AA1BpB,oHAAA,oBAAoB,OAAA;AACpB,kHAAA,kBAAkB,OAAA;AAClB,uHAAA,uBAAuB,OAAA;AACvB,0HAAA,0BAA0B,OAAA;AAC1B,kHAAA,kBAAkB,OAAA;AAClB,mHAAA,mBAAmB,OAAA;AACnB,wHAAA,wBAAwB,OAAA;AACxB,qHAAA,qBAAqB,OAAA;AACrB,mHAAA,mBAAmB,OAAA;AACnB,2HAAA,2BAA2B,OAAA;AAC3B,uHAAA,uBAAuB,OAAA;AACvB,wHAAA,wBAAwB,OAAA;AACxB,kIAAA,kCAAkC,OAAA;AAClC,sHAAA,sBAAsB,OAAA;AACtB,yHAAA,yBAAyB,OAAA;AACzB,yHAAA,yBAAyB,OAAA;AACzB,qHAAA,qBAAqB,OAAA;AACrB,0HAAA,0BAA0B,OAAA;AAC1B,oHAAA,oBAAoB,OAAA;AACpB,wHAAA,wBAAwB,OAAA;AACxB,kHAAA,kBAAkB,OAAA;AAClB,wHAAA,wBAAwB,OAAA;AACxB,yHAAA,yBAAyB,OAAA;AACzB,+GAAA,eAAe,OAAA;AACf,qHAAA,qBAAqB,OAAA;AACrB,8GAAA,cAAc,OAAA;AAElB,wFAAwF;AACxF,+CAYwB;AAXpB,kHAAA,kBAAkB,OAAA;AAClB,gHAAA,gBAAgB,OAAA;AAChB,iHAAA,iBAAiB,OAAA;AACjB,iHAAA,iBAAiB,OAAA;AACjB,mHAAA,mBAAmB,OAAA;AACnB,iHAAA,iBAAiB,OAAA;AACjB,sHAAA,sBAAsB,OAAA;AACtB,yHAAA,yBAAyB,OAAA;AACzB,iHAAA,iBAAiB,OAAA;AACjB,4GAAA,YAAY,OAAA;AACZ,iHAAA,iBAAiB,OAAA;AAerB,mDAM0B;AALtB,gHAAA,cAAc,OAAA;AACd,8GAAA,YAAY,OAAA;AACZ,8GAAA,YAAY,OAAA;AACZ,qHAAA,mBAAmB,OAAA;AACnB,mHAAA,iBAAiB,OAAA;AAErB,6CAKuB;AAJnB,yGAAA,UAAU,OAAA;AACV,6GAAA,cAAc,OAAA;AACd,6GAAA,cAAc,OAAA;AACd,mHAAA,oBAAoB,OAAA","sourcesContent":["export { ResolvedConfig, ResolvedRuleConfig, RuleOptions } from './types';\nexport { InformAiError } from './inform-ai-error';\nexport { toError } from './to-error';\nexport { loadAndValidate, LoadedConfig } from './load-config';\nexport { findConfigFile, CONFIG_FILENAME } from './config-file';\nexport { isPathExcluded } from './exclude-paths';\nexport { defaultRules, defaultRulesDir } from './default-rules';\nexport { loadTemplate, writeTemplateIfMissing, writeTemplate } from './load-template';\nexport { validateWebpiecesConfig, validatePrGateSection } from './validate-config';\nexport { FieldDef } from './field-def';\nexport type { SchemaShape } from './field-def';\nexport { shouldSkipRule, getCurrentBranch } from './skip-rule';\nexport type { SkipRuleResult } from './skip-rule';\nexport { AbstractRule } from './abstract-rule';\nexport {\n WEBPIECES_DISABLE,\n RULE_NAMES,\n hasDisable,\n WEBPIECES_TMP_DIR,\n MERGE_DIR_PREFIX,\n MERGE_IN_PROGRESS_FILE,\n MERGE_EXPLANATION_FILE,\n} from './constants';\nexport { WebpiecesRulesConfig } from './WebpiecesRulesConfig';\nexport {\n MaxMethodLinesConfig,\n MaxFileLinesConfig,\n RequireReturnTypeConfig,\n NoInlineTypeLiteralsConfig,\n NoAnyUnknownConfig,\n NoImplicitAnyConfig,\n PrismaValidateDtosConfig,\n PrismaConverterConfig,\n NoDestructureConfig,\n NoUnmanagedExceptionsConfig,\n CatchErrorPatternConfig,\n ThrowCauseRequiredConfig,\n AngularNoDirectApiInResolverConfig,\n NoSymbolDiTokensConfig,\n NoShellSubstitutionConfig,\n BranchCreationGuardConfig,\n PrCreationGuardConfig,\n MergeInProgressGuardConfig,\n PrMergeCleanupConfig,\n NoDirectMainUpdateConfig,\n NoEditOnMainConfig,\n NoFileImportCyclesConfig,\n RuntimeArchitectureConfig,\n NoJsFilesConfig,\n ValidateTsInSrcConfig,\n BaseRuleConfig,\n} from './rule-configs';\n// Mode unions + their value arrays — the single source of truth shared with code-rules.\nexport {\n METHOD_LIMIT_MODES,\n FILE_LIMIT_MODES,\n RETURN_TYPE_MODES,\n INLINE_TYPE_MODES,\n MODIFIED_CODE_MODES,\n PRISMA_DTOS_MODES,\n PRISMA_CONVERTER_MODES,\n DIRECT_API_RESOLVER_MODES,\n THROW_CAUSE_MODES,\n ON_OFF_MODES,\n VALIDATE_TS_MODES,\n} from './rule-configs';\nexport type {\n MethodLimitMode,\n FileLimitMode,\n ReturnTypeMode,\n InlineTypeMode,\n ModifiedCodeMode,\n PrismaValidateDtosMode,\n PrismaConverterMode,\n DirectApiResolverMode,\n ThrowCauseMode,\n OnOffMode,\n ValidateTsMode,\n} from './rule-configs';\nexport {\n GateDefinition,\n PrGateConfig,\n defaultGates,\n defaultPrGateConfig,\n buildPrGateConfig,\n} from './pr-gate-config';\nexport {\n ReviewJson,\n loadReviewJson,\n reviewJsonPath,\n reviewJsonSchemaHint,\n} from './review-json';\n"]}
@@ -1,13 +1,25 @@
1
+ import { PrGateConfig } from './pr-gate-config';
1
2
  import { ResolvedConfig } from './types';
2
3
  import { WebpiecesRulesConfig } from './WebpiecesRulesConfig';
3
- export declare const CONFIG_FILENAME = "webpieces.config.json";
4
4
  /**
5
- * Walk up from `startDir` looking for webpieces.config.json.
5
+ * Everything a consumer might need from webpieces.config.json, produced from ONE parse + ONE
6
+ * validation pass. Data-only (per CLAUDE.md, classes for data):
7
+ * - `resolved` — Map-based view merged with defaultRules (nx executors).
8
+ * - `rulesConfig` — typed WebpiecesRulesConfig (ai-hook-rules, code-rules).
9
+ * - `prGate` — the pr-gate section (pr-gate scripts).
10
+ * - `configPath` — absolute path, or null when no config file was found.
6
11
  */
7
- export declare function findConfigFile(startDir: string): string | null;
8
- export declare function loadConfig(cwd: string): ResolvedConfig;
9
- export interface LoadedWebpiecesConfig {
10
- readonly config: WebpiecesRulesConfig;
11
- readonly configPath: string;
12
+ export declare class LoadedConfig {
13
+ readonly resolved: ResolvedConfig;
14
+ readonly rulesConfig: WebpiecesRulesConfig;
15
+ readonly prGate: PrGateConfig;
16
+ readonly configPath: string | null;
17
+ constructor(resolved: ResolvedConfig, rulesConfig: WebpiecesRulesConfig, prGate: PrGateConfig, configPath: string | null);
12
18
  }
13
- export declare function loadWebpiecesRulesConfig(cwd: string): LoadedWebpiecesConfig | null;
19
+ /**
20
+ * The single load+validate entry point for ALL consumers (ai-hook-rules, code-rules,
21
+ * nx-webpieces-rules, pr-gate scripts). Reads webpieces.config.json once, validates BOTH the `rules`
22
+ * map and the top-level `pr-gate` block, and throws one InformAiError listing every error. When no
23
+ * config file is found it returns lenient empties/defaults (matching prior no-file behavior).
24
+ */
25
+ export declare function loadAndValidate(cwd: string): LoadedConfig;
@@ -1,34 +1,14 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.CONFIG_FILENAME = void 0;
4
- exports.findConfigFile = findConfigFile;
5
- exports.loadConfig = loadConfig;
6
- exports.loadWebpiecesRulesConfig = loadWebpiecesRulesConfig;
7
- const tslib_1 = require("tslib");
8
- const fs = tslib_1.__importStar(require("fs"));
9
- const path = tslib_1.__importStar(require("path"));
3
+ exports.LoadedConfig = void 0;
4
+ exports.loadAndValidate = loadAndValidate;
5
+ const config_file_1 = require("./config-file");
10
6
  const default_rules_1 = require("./default-rules");
11
7
  const inform_ai_error_1 = require("./inform-ai-error");
12
- const to_error_1 = require("./to-error");
8
+ const pr_gate_config_1 = require("./pr-gate-config");
13
9
  const types_1 = require("./types");
14
10
  const validate_config_1 = require("./validate-config");
15
11
  const WebpiecesRulesConfig_1 = require("./WebpiecesRulesConfig");
16
- exports.CONFIG_FILENAME = 'webpieces.config.json';
17
- /**
18
- * Walk up from `startDir` looking for webpieces.config.json.
19
- */
20
- function findConfigFile(startDir) {
21
- let dir = startDir;
22
- while (true) {
23
- const primary = path.join(dir, exports.CONFIG_FILENAME);
24
- if (fs.existsSync(primary))
25
- return primary;
26
- const parent = path.dirname(dir);
27
- if (parent === dir)
28
- return null;
29
- dir = parent;
30
- }
31
- }
32
12
  // webpieces-disable no-any-unknown -- merging opaque option bags from config JSON
33
13
  function mergeRule(
34
14
  // webpieces-disable no-any-unknown -- opaque option bag
@@ -49,31 +29,60 @@ overrideRule) {
49
29
  merged[key] = overrideRule[key];
50
30
  return new types_1.ResolvedRuleConfig(merged);
51
31
  }
52
- function readRawConfig(configPath) {
53
- const raw = fs.readFileSync(configPath, 'utf8');
54
- // eslint-disable-next-line @webpieces/no-unmanaged-exceptions
55
- try {
56
- return JSON.parse(raw);
32
+ function buildWebpiecesRulesConfig(
33
+ // webpieces-disable no-any-unknown -- JSON values are opaque until assigned to typed fields
34
+ rawRules, rulesDir) {
35
+ const typed = new WebpiecesRulesConfig_1.WebpiecesRulesConfig();
36
+ for (const key of Object.keys(rawRules)) {
37
+ // webpieces-disable no-any-unknown -- dynamic key assignment to typed class
38
+ typed[key] = rawRules[key];
57
39
  }
58
- catch (err) {
59
- const error = (0, to_error_1.toError)(err);
60
- throw new inform_ai_error_1.InformAiError(`webpieces.config.json has invalid JSON — fix the file, then retry.\n` +
61
- `Parse error: ${error.message}\n` +
62
- `File: ${configPath}`);
40
+ typed.rulesDir = rulesDir;
41
+ return typed;
42
+ }
43
+ /**
44
+ * Everything a consumer might need from webpieces.config.json, produced from ONE parse + ONE
45
+ * validation pass. Data-only (per CLAUDE.md, classes for data):
46
+ * - `resolved` — Map-based view merged with defaultRules (nx executors).
47
+ * - `rulesConfig` — typed WebpiecesRulesConfig (ai-hook-rules, code-rules).
48
+ * - `prGate` — the pr-gate section (pr-gate scripts).
49
+ * - `configPath` — absolute path, or null when no config file was found.
50
+ */
51
+ class LoadedConfig {
52
+ resolved;
53
+ rulesConfig;
54
+ prGate;
55
+ configPath;
56
+ constructor(resolved, rulesConfig, prGate, configPath) {
57
+ this.resolved = resolved;
58
+ this.rulesConfig = rulesConfig;
59
+ this.prGate = prGate;
60
+ this.configPath = configPath;
63
61
  }
64
62
  }
65
- function loadConfig(cwd) {
66
- const configPath = findConfigFile(cwd);
63
+ exports.LoadedConfig = LoadedConfig;
64
+ /**
65
+ * The single load+validate entry point for ALL consumers (ai-hook-rules, code-rules,
66
+ * nx-webpieces-rules, pr-gate scripts). Reads webpieces.config.json once, validates BOTH the `rules`
67
+ * map and the top-level `pr-gate` block, and throws one InformAiError listing every error. When no
68
+ * config file is found it returns lenient empties/defaults (matching prior no-file behavior).
69
+ */
70
+ function loadAndValidate(cwd) {
71
+ const configPath = (0, config_file_1.findConfigFile)(cwd);
67
72
  if (!configPath) {
68
- return new types_1.ResolvedConfig(new Map(), new Set(), [], null);
73
+ return new LoadedConfig(new types_1.ResolvedConfig(new Map(), new Set(), [], null), new WebpiecesRulesConfig_1.WebpiecesRulesConfig(), (0, pr_gate_config_1.buildPrGateConfig)(undefined), null);
69
74
  }
70
- const consumerConfig = readRawConfig(configPath);
75
+ const consumerConfig = (0, config_file_1.readRawConfig)(configPath);
71
76
  const overrideRules = consumerConfig.rules || {};
72
- const validationErrors = (0, validate_config_1.validateWebpiecesConfig)(overrideRules);
73
- if (validationErrors.length > 0) {
74
- throw new inform_ai_error_1.InformAiError(`webpieces.config.json has ${validationErrors.length} validation error(s) — fix ALL, then retry:\n\n` +
75
- validationErrors.map(e => ` • ${e}`).join('\n'));
77
+ const errors = [
78
+ ...(0, validate_config_1.validateWebpiecesConfig)(overrideRules),
79
+ ...(0, validate_config_1.validatePrGateSection)(consumerConfig['pr-gate']),
80
+ ];
81
+ if (errors.length > 0) {
82
+ throw new inform_ai_error_1.InformAiError(`webpieces.config.json has ${errors.length} validation error(s) — fix ALL, then retry:\n\n` +
83
+ errors.map(e => ` • ${e}`).join('\n'));
76
84
  }
85
+ const rulesDir = consumerConfig.rulesDir ?? [];
77
86
  const userConfiguredRuleNames = new Set(Object.keys(overrideRules));
78
87
  const mergedRules = new Map();
79
88
  const allRuleNames = new Set([
@@ -83,32 +92,9 @@ function loadConfig(cwd) {
83
92
  for (const name of allRuleNames) {
84
93
  mergedRules.set(name, mergeRule(default_rules_1.defaultRules[name], overrideRules[name]));
85
94
  }
86
- const rulesDir = consumerConfig.rulesDir ?? [];
87
- return new types_1.ResolvedConfig(mergedRules, userConfiguredRuleNames, rulesDir, configPath);
88
- }
89
- function buildWebpiecesRulesConfig(
90
- // webpieces-disable no-any-unknown -- JSON values are opaque until assigned to typed fields
91
- rawRules, rulesDir) {
92
- const typed = new WebpiecesRulesConfig_1.WebpiecesRulesConfig();
93
- for (const key of Object.keys(rawRules)) {
94
- // webpieces-disable no-any-unknown -- dynamic key assignment to typed class
95
- typed[key] = rawRules[key];
96
- }
97
- typed.rulesDir = rulesDir;
98
- return typed;
99
- }
100
- function loadWebpiecesRulesConfig(cwd) {
101
- const configPath = findConfigFile(cwd);
102
- if (!configPath)
103
- return null;
104
- const consumerConfig = readRawConfig(configPath);
105
- const overrideRules = consumerConfig.rules || {};
106
- const validationErrors = (0, validate_config_1.validateWebpiecesConfig)(overrideRules);
107
- if (validationErrors.length > 0) {
108
- throw new inform_ai_error_1.InformAiError(`webpieces.config.json has ${validationErrors.length} validation error(s) — fix ALL, then retry:\n\n` +
109
- validationErrors.map(e => ` • ${e}`).join('\n'));
110
- }
111
- const rulesDir = consumerConfig.rulesDir ?? [];
112
- return { config: buildWebpiecesRulesConfig(overrideRules, rulesDir), configPath };
95
+ const resolved = new types_1.ResolvedConfig(mergedRules, userConfiguredRuleNames, rulesDir, configPath);
96
+ const rulesConfig = buildWebpiecesRulesConfig(overrideRules, rulesDir);
97
+ const prGate = (0, pr_gate_config_1.buildPrGateConfig)(consumerConfig['pr-gate']);
98
+ return new LoadedConfig(resolved, rulesConfig, prGate, configPath);
113
99
  }
114
100
  //# sourceMappingURL=load-config.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"load-config.js","sourceRoot":"","sources":["../../../../../packages/tooling/rules-config/src/load-config.ts"],"names":[],"mappings":"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","sourcesContent":["import * as fs from 'fs';\nimport * as path from 'path';\n\nimport { defaultRules } from './default-rules';\nimport { InformAiError } from './inform-ai-error';\nimport { toError } from './to-error';\nimport { ResolvedConfig, ResolvedRuleConfig, RuleOptions } from './types';\nimport { validateWebpiecesConfig } from './validate-config';\nimport { WebpiecesRulesConfig } from './WebpiecesRulesConfig';\n\nexport const CONFIG_FILENAME = 'webpieces.config.json';\n\n// webpieces-disable no-any-unknown -- consumer JSON config has opaque rule option values\ninterface RawConfigFile {\n extends?: string;\n rules?: Record<string, Record<string, unknown>>;\n rulesDir?: string[];\n}\n\n/**\n * Walk up from `startDir` looking for webpieces.config.json.\n */\nexport function findConfigFile(startDir: string): string | null {\n let dir = startDir;\n while (true) {\n const primary = path.join(dir, CONFIG_FILENAME);\n if (fs.existsSync(primary)) return primary;\n const parent = path.dirname(dir);\n if (parent === dir) return null;\n dir = parent;\n }\n}\n\n// webpieces-disable no-any-unknown -- merging opaque option bags from config JSON\nfunction mergeRule(\n // webpieces-disable no-any-unknown -- opaque option bag\n baseRule: Record<string, unknown> | undefined,\n // webpieces-disable no-any-unknown -- opaque option bag\n overrideRule: Record<string, unknown> | undefined,\n): ResolvedRuleConfig {\n if (!baseRule && !overrideRule) return new ResolvedRuleConfig({ mode: 'OFF' });\n if (!baseRule) return new ResolvedRuleConfig(overrideRule! as RuleOptions);\n if (!overrideRule) return new ResolvedRuleConfig(baseRule as RuleOptions);\n\n // webpieces-disable no-any-unknown -- building merged option bag\n const merged: Record<string, unknown> = {};\n for (const key of Object.keys(baseRule)) merged[key] = baseRule[key];\n for (const key of Object.keys(overrideRule)) merged[key] = overrideRule[key];\n return new ResolvedRuleConfig(merged as RuleOptions);\n}\n\nfunction readRawConfig(configPath: string): RawConfigFile {\n const raw = fs.readFileSync(configPath, 'utf8');\n // eslint-disable-next-line @webpieces/no-unmanaged-exceptions\n try {\n return JSON.parse(raw) as RawConfigFile;\n } catch (err: unknown) {\n const error = toError(err);\n throw new InformAiError(\n `webpieces.config.json has invalid JSON fix the file, then retry.\\n` +\n `Parse error: ${error.message}\\n` +\n `File: ${configPath}`,\n );\n }\n}\n\nexport function loadConfig(cwd: string): ResolvedConfig {\n const configPath = findConfigFile(cwd);\n\n if (!configPath) {\n return new ResolvedConfig(new Map(), new Set(), [], null);\n }\n\n const consumerConfig = readRawConfig(configPath);\n const overrideRules = consumerConfig.rules || {};\n\n const validationErrors = validateWebpiecesConfig(overrideRules);\n if (validationErrors.length > 0) {\n throw new InformAiError(\n `webpieces.config.json has ${validationErrors.length} validation error(s) — fix ALL, then retry:\\n\\n` +\n validationErrors.map(e => ` • ${e}`).join('\\n'),\n );\n }\n\n const userConfiguredRuleNames = new Set(Object.keys(overrideRules));\n const mergedRules = new Map<string, ResolvedRuleConfig>();\n\n const allRuleNames = new Set([\n ...Object.keys(defaultRules),\n ...Object.keys(overrideRules),\n ]);\n for (const name of allRuleNames) {\n mergedRules.set(name, mergeRule(defaultRules[name], overrideRules[name]));\n }\n\n const rulesDir = consumerConfig.rulesDir ?? [];\n\n return new ResolvedConfig(mergedRules, userConfiguredRuleNames, rulesDir, configPath);\n}\n\nexport interface LoadedWebpiecesConfig {\n readonly config: WebpiecesRulesConfig;\n readonly configPath: string;\n}\n\nfunction buildWebpiecesRulesConfig(\n // webpieces-disable no-any-unknown -- JSON values are opaque until assigned to typed fields\n rawRules: Record<string, Record<string, unknown>>,\n rulesDir: string[],\n): WebpiecesRulesConfig {\n const typed = new WebpiecesRulesConfig();\n for (const key of Object.keys(rawRules)) {\n // webpieces-disable no-any-unknown -- dynamic key assignment to typed class\n (typed as Record<string, unknown>)[key] = rawRules[key];\n }\n typed.rulesDir = rulesDir;\n return typed;\n}\n\nexport function loadWebpiecesRulesConfig(cwd: string): LoadedWebpiecesConfig | null {\n const configPath = findConfigFile(cwd);\n if (!configPath) return null;\n\n const consumerConfig = readRawConfig(configPath);\n const overrideRules = consumerConfig.rules || {};\n\n const validationErrors = validateWebpiecesConfig(overrideRules);\n if (validationErrors.length > 0) {\n throw new InformAiError(\n `webpieces.config.json has ${validationErrors.length} validation error(s) — fix ALL, then retry:\\n\\n` +\n validationErrors.map(e => ` • ${e}`).join('\\n'),\n );\n }\n\n const rulesDir = consumerConfig.rulesDir ?? [];\n return { config: buildWebpiecesRulesConfig(overrideRules, rulesDir), configPath };\n}\n"]}
1
+ {"version":3,"file":"load-config.js","sourceRoot":"","sources":["../../../../../packages/tooling/rules-config/src/load-config.ts"],"names":[],"mappings":"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","sourcesContent":["import { findConfigFile, readRawConfig } from './config-file';\nimport { defaultRules } from './default-rules';\nimport { InformAiError } from './inform-ai-error';\nimport { buildPrGateConfig, PrGateConfig } from './pr-gate-config';\nimport { ResolvedConfig, ResolvedRuleConfig, RuleOptions } from './types';\nimport { validatePrGateSection, validateWebpiecesConfig } from './validate-config';\nimport { WebpiecesRulesConfig } from './WebpiecesRulesConfig';\n\n// webpieces-disable no-any-unknown -- merging opaque option bags from config JSON\nfunction mergeRule(\n // webpieces-disable no-any-unknown -- opaque option bag\n baseRule: Record<string, unknown> | undefined,\n // webpieces-disable no-any-unknown -- opaque option bag\n overrideRule: Record<string, unknown> | undefined,\n): ResolvedRuleConfig {\n if (!baseRule && !overrideRule) return new ResolvedRuleConfig({ mode: 'OFF' });\n if (!baseRule) return new ResolvedRuleConfig(overrideRule! as RuleOptions);\n if (!overrideRule) return new ResolvedRuleConfig(baseRule as RuleOptions);\n\n // webpieces-disable no-any-unknown -- building merged option bag\n const merged: Record<string, unknown> = {};\n for (const key of Object.keys(baseRule)) merged[key] = baseRule[key];\n for (const key of Object.keys(overrideRule)) merged[key] = overrideRule[key];\n return new ResolvedRuleConfig(merged as RuleOptions);\n}\n\nfunction buildWebpiecesRulesConfig(\n // webpieces-disable no-any-unknown -- JSON values are opaque until assigned to typed fields\n rawRules: Record<string, Record<string, unknown>>,\n rulesDir: string[],\n): WebpiecesRulesConfig {\n const typed = new WebpiecesRulesConfig();\n for (const key of Object.keys(rawRules)) {\n // webpieces-disable no-any-unknown -- dynamic key assignment to typed class\n (typed as Record<string, unknown>)[key] = rawRules[key];\n }\n typed.rulesDir = rulesDir;\n return typed;\n}\n\n/**\n * Everything a consumer might need from webpieces.config.json, produced from ONE parse + ONE\n * validation pass. Data-only (per CLAUDE.md, classes for data):\n * - `resolved` Map-based view merged with defaultRules (nx executors).\n * - `rulesConfig` — typed WebpiecesRulesConfig (ai-hook-rules, code-rules).\n * - `prGate` — the pr-gate section (pr-gate scripts).\n * - `configPath` — absolute path, or null when no config file was found.\n */\nexport class LoadedConfig {\n constructor(\n readonly resolved: ResolvedConfig,\n readonly rulesConfig: WebpiecesRulesConfig,\n readonly prGate: PrGateConfig,\n readonly configPath: string | null,\n ) {}\n}\n\n/**\n * The single load+validate entry point for ALL consumers (ai-hook-rules, code-rules,\n * nx-webpieces-rules, pr-gate scripts). Reads webpieces.config.json once, validates BOTH the `rules`\n * map and the top-level `pr-gate` block, and throws one InformAiError listing every error. When no\n * config file is found it returns lenient empties/defaults (matching prior no-file behavior).\n */\nexport function loadAndValidate(cwd: string): LoadedConfig {\n const configPath = findConfigFile(cwd);\n if (!configPath) {\n return new LoadedConfig(\n new ResolvedConfig(new Map(), new Set(), [], null),\n new WebpiecesRulesConfig(),\n buildPrGateConfig(undefined),\n null,\n );\n }\n\n const consumerConfig = readRawConfig(configPath);\n const overrideRules = consumerConfig.rules || {};\n\n const errors = [\n ...validateWebpiecesConfig(overrideRules),\n ...validatePrGateSection(consumerConfig['pr-gate']),\n ];\n if (errors.length > 0) {\n throw new InformAiError(\n `webpieces.config.json has ${errors.length} validation error(s) — fix ALL, then retry:\\n\\n` +\n errors.map(e => ` • ${e}`).join('\\n'),\n );\n }\n\n const rulesDir = consumerConfig.rulesDir ?? [];\n\n const userConfiguredRuleNames = new Set(Object.keys(overrideRules));\n const mergedRules = new Map<string, ResolvedRuleConfig>();\n const allRuleNames = new Set([\n ...Object.keys(defaultRules),\n ...Object.keys(overrideRules),\n ]);\n for (const name of allRuleNames) {\n mergedRules.set(name, mergeRule(defaultRules[name], overrideRules[name]));\n }\n const resolved = new ResolvedConfig(mergedRules, userConfiguredRuleNames, rulesDir, configPath);\n\n const rulesConfig = buildWebpiecesRulesConfig(overrideRules, rulesDir);\n const prGate = buildPrGateConfig(consumerConfig['pr-gate']);\n\n return new LoadedConfig(resolved, rulesConfig, prGate, configPath);\n}\n"]}
@@ -1,8 +1,9 @@
1
1
  export declare class GateDefinition {
2
2
  name: string;
3
3
  patterns: string[];
4
- severity: string;
5
- constructor(name: string, patterns: string[], severity: string);
4
+ color: string;
5
+ disabled: boolean;
6
+ constructor(name: string, patterns: string[], color: string, disabled?: boolean);
6
7
  }
7
8
  export declare class PrGateConfig {
8
9
  mode: string;
@@ -13,7 +14,9 @@ export declare class PrGateConfig {
13
14
  export declare function defaultGates(): GateDefinition[];
14
15
  export declare function defaultPrGateConfig(): PrGateConfig;
15
16
  /**
16
- * Load the `pr-gate` section from webpieces.config.json, falling back to defaults for any
17
- * field the consumer omits. Returns defaults entirely if no config file is found.
17
+ * Build a PrGateConfig from the already-parsed top-level `pr-gate` section, falling back to defaults
18
+ * for any field the consumer omits. Pure transform the file read + structural validation happen in
19
+ * loadAndValidate (load-config.ts) so every consumer goes through one validated path. Pass undefined
20
+ * (no `pr-gate` key / no config file) to get full defaults.
18
21
  */
19
- export declare function loadPrGateConfig(cwd: string): PrGateConfig;
22
+ export declare function buildPrGateConfig(section: unknown): PrGateConfig;
@@ -1,23 +1,29 @@
1
1
  "use strict";
2
+ // PrGateConfig is the "special section" for the pr-gate dashboard. It does NOT live in the
3
+ // validated `rules` map (the FieldDef schema can't express nested object arrays), but as a
4
+ // top-level `pr-gate` key in webpieces.config.json. It is built and validated by
5
+ // loadAndValidate (load-config.ts); this module holds only the data classes + defaults + toGate.
2
6
  Object.defineProperty(exports, "__esModule", { value: true });
3
7
  exports.PrGateConfig = exports.GateDefinition = void 0;
4
8
  exports.defaultGates = defaultGates;
5
9
  exports.defaultPrGateConfig = defaultPrGateConfig;
6
- exports.loadPrGateConfig = loadPrGateConfig;
7
- const tslib_1 = require("tslib");
8
- const fs = tslib_1.__importStar(require("fs"));
9
- const load_config_1 = require("./load-config");
10
- // PrGateConfig is the "special section" for the pr-gate dashboard. It does NOT live in the
11
- // validated `rules` map (the FieldDef schema can't express nested object arrays), but as a
12
- // top-level `pr-gate` key in webpieces.config.json. Loaded by loadPrGateConfig with defaults.
10
+ exports.buildPrGateConfig = buildPrGateConfig;
13
11
  class GateDefinition {
14
12
  name;
15
13
  patterns;
16
- severity; // 'warn' (yellow) | 'block' (red, fails the gate)
17
- constructor(name, patterns, severity) {
14
+ // The color shown on the dashboard WHEN this gate's patterns match a changed file. Green is
15
+ // implicit (shown when nothing matched), so it is never configured. Color is purely visual —
16
+ // even 'red' never fails/blocks the PR (only the build gate can). 'yellow' = caution,
17
+ // 'red' = louder "look here" flag (e.g. DB schema / migration changes).
18
+ color; // 'yellow' | 'red'
19
+ // Example/inactive gate: parsed and kept in the file (JSON has no comments) but skipped at
20
+ // compute/render time. Other projects flip this to false and tune patterns/color.
21
+ disabled;
22
+ constructor(name, patterns, color, disabled = false) {
18
23
  this.name = name;
19
24
  this.patterns = patterns;
20
- this.severity = severity;
25
+ this.color = color;
26
+ this.disabled = disabled;
21
27
  }
22
28
  }
23
29
  exports.GateDefinition = GateDefinition;
@@ -36,34 +42,33 @@ exports.PrGateConfig = PrGateConfig;
36
42
  // whole list via the `pr-gate.gates` array in webpieces.config.json.
37
43
  function defaultGates() {
38
44
  return [
39
- new GateDefinition('API Changed', ['libraries/apis/**', '**/*Api.ts'], 'warn'),
40
- new GateDefinition('Config Files Changed', ['**/package.json', '**/tsconfig*.json', 'nx.json', '**/*.config.*'], 'warn'),
41
- new GateDefinition('Dependency Graph Changed', ['architecture/dependencies.json'], 'warn'),
42
- new GateDefinition('Claude / Rules Changed', ['**/CLAUDE.md', '**/claude.*.md', '.claude/**', 'webpieces.config.json'], 'warn'),
45
+ new GateDefinition('API Changed', ['libraries/apis/**', '**/*Api.ts'], 'yellow'),
46
+ new GateDefinition('Config Files Changed', ['**/package.json', '**/tsconfig*.json', 'nx.json', '**/*.config.*'], 'yellow'),
47
+ new GateDefinition('Dependency Graph Changed', ['architecture/dependencies.json'], 'yellow'),
48
+ new GateDefinition('Claude / Rules Changed', ['**/CLAUDE.md', '**/claude.*.md', '.claude/**', 'webpieces.config.json'], 'yellow'),
43
49
  ];
44
50
  }
45
51
  function defaultPrGateConfig() {
46
52
  return new PrGateConfig('ON', '', defaultGates());
47
53
  }
48
54
  function toGate(raw) {
49
- return new GateDefinition(raw.name ?? '', raw.patterns ?? [], raw.severity ?? 'warn');
55
+ return new GateDefinition(raw.name ?? '', raw.patterns ?? [], raw.color ?? 'yellow', raw.disabled ?? false);
50
56
  }
51
57
  /**
52
- * Load the `pr-gate` section from webpieces.config.json, falling back to defaults for any
53
- * field the consumer omits. Returns defaults entirely if no config file is found.
58
+ * Build a PrGateConfig from the already-parsed top-level `pr-gate` section, falling back to defaults
59
+ * for any field the consumer omits. Pure transform the file read + structural validation happen in
60
+ * loadAndValidate (load-config.ts) so every consumer goes through one validated path. Pass undefined
61
+ * (no `pr-gate` key / no config file) to get full defaults.
54
62
  */
55
- function loadPrGateConfig(cwd) {
63
+ // webpieces-disable no-any-unknown -- `section` is opaque consumer JSON until narrowed here
64
+ function buildPrGateConfig(section) {
56
65
  const defaults = defaultPrGateConfig();
57
- const configPath = (0, load_config_1.findConfigFile)(cwd);
58
- if (!configPath)
59
- return defaults;
60
- const parsed = JSON.parse(fs.readFileSync(configPath, 'utf8'));
61
- const section = parsed['pr-gate'];
62
- if (!section)
66
+ if (section === undefined || section === null || typeof section !== 'object')
63
67
  return defaults;
64
- const mode = section.mode ?? defaults.mode;
65
- const buildCommand = section.buildCommand ?? defaults.buildCommand;
66
- const gates = section.gates !== undefined ? section.gates.map(toGate) : defaults.gates;
68
+ const raw = section;
69
+ const mode = raw.mode ?? defaults.mode;
70
+ const buildCommand = raw.buildCommand ?? defaults.buildCommand;
71
+ const gates = raw.gates !== undefined ? raw.gates.map(toGate) : defaults.gates;
67
72
  return new PrGateConfig(mode, buildCommand, gates);
68
73
  }
69
74
  //# sourceMappingURL=pr-gate-config.js.map