@webpieces/rules-config 0.2.127 → 0.3.129
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 +4 -1
- package/src/default-rules.js +30 -23
- package/src/default-rules.js.map +1 -1
- package/src/exclude-paths.d.ts +19 -0
- package/src/exclude-paths.js +36 -0
- package/src/exclude-paths.js.map +1 -0
- package/src/index.d.ts +1 -0
- package/src/index.js +3 -1
- package/src/index.js.map +1 -1
- package/src/load-config.js +4 -8
- package/src/load-config.js.map +1 -1
- package/src/types.d.ts +13 -3
- package/src/types.js +18 -3
- package/src/types.js.map +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@webpieces/rules-config",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.129",
|
|
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",
|
|
@@ -13,6 +13,9 @@
|
|
|
13
13
|
"templates/**/*",
|
|
14
14
|
"README.md"
|
|
15
15
|
],
|
|
16
|
+
"dependencies": {
|
|
17
|
+
"minimatch": "10.0.1"
|
|
18
|
+
},
|
|
16
19
|
"author": "Dean Hiller",
|
|
17
20
|
"license": "Apache-2.0",
|
|
18
21
|
"repository": {
|
package/src/default-rules.js
CHANGED
|
@@ -1,36 +1,43 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.defaultRulesDir = exports.defaultRules = void 0;
|
|
4
|
+
// Default holistic exclude list for the file-location / validate-ts-in-src
|
|
5
|
+
// rules. Bare names match a directory segment at any depth; globs match the
|
|
6
|
+
// workspace-relative path. `**/*.d.ts` (ambient declarations) and
|
|
7
|
+
// `**/jest.config.ts` legitimately live outside src/ and are exempt here.
|
|
8
|
+
const DEFAULT_EXCLUDE_PATHS = [
|
|
9
|
+
'node_modules', 'dist', '.nx', '.git',
|
|
10
|
+
'architecture', 'tmp', 'scripts',
|
|
11
|
+
'**/*.d.ts', '**/jest.config.ts',
|
|
12
|
+
];
|
|
13
|
+
// On/off is driven by `mode` ("OFF" disables; an absent mode leaves a rule
|
|
14
|
+
// on). Code-rules entries omit `mode` so each executor keeps its own default
|
|
15
|
+
// scope; simple on/off rules declare `mode: 'ON'` explicitly.
|
|
4
16
|
// webpieces-disable no-any-unknown -- rule options are opaque at framework level
|
|
5
17
|
exports.defaultRules = {
|
|
6
|
-
'no-any-unknown': {
|
|
7
|
-
'no-implicit-any': {
|
|
8
|
-
'max-file-lines': {
|
|
9
|
-
'max-method-lines': {
|
|
10
|
-
'require-return-type': {
|
|
11
|
-
'no-inline-type-literals': {
|
|
12
|
-
'no-destructure': {
|
|
13
|
-
'catch-error-pattern': {
|
|
14
|
-
'no-unmanaged-exceptions': {
|
|
15
|
-
'no-shell-substitution': {
|
|
16
|
-
'validate-dtos': {
|
|
17
|
-
'prisma-converter': {
|
|
18
|
-
'no-direct-api-in-resolver': {
|
|
18
|
+
'no-any-unknown': {},
|
|
19
|
+
'no-implicit-any': {},
|
|
20
|
+
'max-file-lines': { limit: 900 },
|
|
21
|
+
'max-method-lines': { limit: 80 },
|
|
22
|
+
'require-return-type': {},
|
|
23
|
+
'no-inline-type-literals': {},
|
|
24
|
+
'no-destructure': { allowTopLevel: true },
|
|
25
|
+
'catch-error-pattern': {},
|
|
26
|
+
'no-unmanaged-exceptions': {},
|
|
27
|
+
'no-shell-substitution': { mode: 'ON' },
|
|
28
|
+
'validate-dtos': {},
|
|
29
|
+
'prisma-converter': {},
|
|
30
|
+
'no-direct-api-in-resolver': {},
|
|
31
|
+
'nx-wiring': { mode: 'ON' },
|
|
19
32
|
'file-location': {
|
|
20
|
-
|
|
33
|
+
mode: 'ON',
|
|
21
34
|
allowedRootFiles: ['jest.setup.ts'],
|
|
22
|
-
excludePaths: [
|
|
23
|
-
'node_modules', 'dist', '.nx', '.git',
|
|
24
|
-
'architecture', 'tmp', 'scripts',
|
|
25
|
-
],
|
|
35
|
+
excludePaths: [...DEFAULT_EXCLUDE_PATHS],
|
|
26
36
|
},
|
|
27
37
|
'validate-ts-in-src': {
|
|
28
|
-
|
|
38
|
+
mode: 'ON',
|
|
29
39
|
allowedRootFiles: ['jest.setup.ts'],
|
|
30
|
-
excludePaths: [
|
|
31
|
-
'node_modules', 'dist', '.nx', '.git',
|
|
32
|
-
'architecture', 'tmp', 'scripts',
|
|
33
|
-
],
|
|
40
|
+
excludePaths: [...DEFAULT_EXCLUDE_PATHS],
|
|
34
41
|
},
|
|
35
42
|
};
|
|
36
43
|
exports.defaultRulesDir = [];
|
package/src/default-rules.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"default-rules.js","sourceRoot":"","sources":["../../../../../packages/tooling/rules-config/src/default-rules.ts"],"names":[],"mappings":";;;AAAA,
|
|
1
|
+
{"version":3,"file":"default-rules.js","sourceRoot":"","sources":["../../../../../packages/tooling/rules-config/src/default-rules.ts"],"names":[],"mappings":";;;AAAA,2EAA2E;AAC3E,4EAA4E;AAC5E,kEAAkE;AAClE,0EAA0E;AAC1E,MAAM,qBAAqB,GAAsB;IAC7C,cAAc,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM;IACrC,cAAc,EAAE,KAAK,EAAE,SAAS;IAChC,WAAW,EAAE,mBAAmB;CACnC,CAAC;AAEF,2EAA2E;AAC3E,6EAA6E;AAC7E,8DAA8D;AAC9D,iFAAiF;AACpE,QAAA,YAAY,GAA4C;IACjE,gBAAgB,EAAE,EAAE;IACpB,iBAAiB,EAAE,EAAE;IACrB,gBAAgB,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE;IAChC,kBAAkB,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE;IACjC,qBAAqB,EAAE,EAAE;IACzB,yBAAyB,EAAE,EAAE;IAC7B,gBAAgB,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE;IACzC,qBAAqB,EAAE,EAAE;IACzB,yBAAyB,EAAE,EAAE;IAC7B,uBAAuB,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE;IACvC,eAAe,EAAE,EAAE;IACnB,kBAAkB,EAAE,EAAE;IACtB,2BAA2B,EAAE,EAAE;IAC/B,WAAW,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE;IAC3B,eAAe,EAAE;QACb,IAAI,EAAE,IAAI;QACV,gBAAgB,EAAE,CAAC,eAAe,CAAC;QACnC,YAAY,EAAE,CAAC,GAAG,qBAAqB,CAAC;KAC3C;IACD,oBAAoB,EAAE;QAClB,IAAI,EAAE,IAAI;QACV,gBAAgB,EAAE,CAAC,eAAe,CAAC;QACnC,YAAY,EAAE,CAAC,GAAG,qBAAqB,CAAC;KAC3C;CACJ,CAAC;AAEW,QAAA,eAAe,GAAsB,EAAE,CAAC","sourcesContent":["// Default holistic exclude list for the file-location / validate-ts-in-src\n// rules. Bare names match a directory segment at any depth; globs match the\n// workspace-relative path. `**/*.d.ts` (ambient declarations) and\n// `**/jest.config.ts` legitimately live outside src/ and are exempt here.\nconst DEFAULT_EXCLUDE_PATHS: readonly string[] = [\n 'node_modules', 'dist', '.nx', '.git',\n 'architecture', 'tmp', 'scripts',\n '**/*.d.ts', '**/jest.config.ts',\n];\n\n// On/off is driven by `mode` (\"OFF\" disables; an absent mode leaves a rule\n// on). Code-rules entries omit `mode` so each executor keeps its own default\n// scope; simple on/off rules declare `mode: 'ON'` explicitly.\n// webpieces-disable no-any-unknown -- rule options are opaque at framework level\nexport const defaultRules: Record<string, Record<string, unknown>> = {\n 'no-any-unknown': {},\n 'no-implicit-any': {},\n 'max-file-lines': { limit: 900 },\n 'max-method-lines': { limit: 80 },\n 'require-return-type': {},\n 'no-inline-type-literals': {},\n 'no-destructure': { allowTopLevel: true },\n 'catch-error-pattern': {},\n 'no-unmanaged-exceptions': {},\n 'no-shell-substitution': { mode: 'ON' },\n 'validate-dtos': {},\n 'prisma-converter': {},\n 'no-direct-api-in-resolver': {},\n 'nx-wiring': { mode: 'ON' },\n 'file-location': {\n mode: 'ON',\n allowedRootFiles: ['jest.setup.ts'],\n excludePaths: [...DEFAULT_EXCLUDE_PATHS],\n },\n 'validate-ts-in-src': {\n mode: 'ON',\n allowedRootFiles: ['jest.setup.ts'],\n excludePaths: [...DEFAULT_EXCLUDE_PATHS],\n },\n};\n\nexport const defaultRulesDir: readonly string[] = [];\n"]}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Holistic exclusion check shared by validate-ts-in-src (Layer 1 + Layer 2)
|
|
3
|
+
* and the file-location AI-hook rule, so the two implementations can never
|
|
4
|
+
* drift apart again.
|
|
5
|
+
*
|
|
6
|
+
* `relPath` is a workspace-relative path (e.g.
|
|
7
|
+
* "libraries/foo/codegen.ts"). An entry in `excludePaths` matches when ANY
|
|
8
|
+
* of the following hold:
|
|
9
|
+
*
|
|
10
|
+
* 1. Bare directory/segment name appearing anywhere in the path. This is
|
|
11
|
+
* the historical behavior and keeps entries like "node_modules",
|
|
12
|
+
* "dist", "scripts", "architecture" working at any depth.
|
|
13
|
+
* 2. A glob matched against the full relative path, e.g. "**\/*.d.ts" or
|
|
14
|
+
* "**\/codegen.ts".
|
|
15
|
+
* 3. A directory-prefix glob, e.g. "libraries/apis" -> "libraries/apis/**".
|
|
16
|
+
*
|
|
17
|
+
* Paths are normalized to forward slashes so Windows backslashes match too.
|
|
18
|
+
*/
|
|
19
|
+
export declare function isPathExcluded(relPath: string, excludePaths: readonly string[]): boolean;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.isPathExcluded = isPathExcluded;
|
|
4
|
+
const minimatch_1 = require("minimatch");
|
|
5
|
+
/**
|
|
6
|
+
* Holistic exclusion check shared by validate-ts-in-src (Layer 1 + Layer 2)
|
|
7
|
+
* and the file-location AI-hook rule, so the two implementations can never
|
|
8
|
+
* drift apart again.
|
|
9
|
+
*
|
|
10
|
+
* `relPath` is a workspace-relative path (e.g.
|
|
11
|
+
* "libraries/foo/codegen.ts"). An entry in `excludePaths` matches when ANY
|
|
12
|
+
* of the following hold:
|
|
13
|
+
*
|
|
14
|
+
* 1. Bare directory/segment name appearing anywhere in the path. This is
|
|
15
|
+
* the historical behavior and keeps entries like "node_modules",
|
|
16
|
+
* "dist", "scripts", "architecture" working at any depth.
|
|
17
|
+
* 2. A glob matched against the full relative path, e.g. "**\/*.d.ts" or
|
|
18
|
+
* "**\/codegen.ts".
|
|
19
|
+
* 3. A directory-prefix glob, e.g. "libraries/apis" -> "libraries/apis/**".
|
|
20
|
+
*
|
|
21
|
+
* Paths are normalized to forward slashes so Windows backslashes match too.
|
|
22
|
+
*/
|
|
23
|
+
function isPathExcluded(relPath, excludePaths) {
|
|
24
|
+
const norm = relPath.replace(/\\/g, '/');
|
|
25
|
+
const segments = norm.split('/');
|
|
26
|
+
for (const pattern of excludePaths) {
|
|
27
|
+
if (segments.includes(pattern))
|
|
28
|
+
return true;
|
|
29
|
+
if ((0, minimatch_1.minimatch)(norm, pattern))
|
|
30
|
+
return true;
|
|
31
|
+
if ((0, minimatch_1.minimatch)(norm, `${pattern}/**`))
|
|
32
|
+
return true;
|
|
33
|
+
}
|
|
34
|
+
return false;
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=exclude-paths.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"exclude-paths.js","sourceRoot":"","sources":["../../../../../packages/tooling/rules-config/src/exclude-paths.ts"],"names":[],"mappings":";;AAoBA,wCASC;AA7BD,yCAAsC;AAEtC;;;;;;;;;;;;;;;;;GAiBG;AACH,SAAgB,cAAc,CAAC,OAAe,EAAE,YAA+B;IAC3E,MAAM,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;IACzC,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACjC,KAAK,MAAM,OAAO,IAAI,YAAY,EAAE,CAAC;QACjC,IAAI,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC;YAAE,OAAO,IAAI,CAAC;QAC5C,IAAI,IAAA,qBAAS,EAAC,IAAI,EAAE,OAAO,CAAC;YAAE,OAAO,IAAI,CAAC;QAC1C,IAAI,IAAA,qBAAS,EAAC,IAAI,EAAE,GAAG,OAAO,KAAK,CAAC;YAAE,OAAO,IAAI,CAAC;IACtD,CAAC;IACD,OAAO,KAAK,CAAC;AACjB,CAAC","sourcesContent":["import { minimatch } from 'minimatch';\n\n/**\n * Holistic exclusion check shared by validate-ts-in-src (Layer 1 + Layer 2)\n * and the file-location AI-hook rule, so the two implementations can never\n * drift apart again.\n *\n * `relPath` is a workspace-relative path (e.g.\n * \"libraries/foo/codegen.ts\"). An entry in `excludePaths` matches when ANY\n * of the following hold:\n *\n * 1. Bare directory/segment name appearing anywhere in the path. This is\n * the historical behavior and keeps entries like \"node_modules\",\n * \"dist\", \"scripts\", \"architecture\" working at any depth.\n * 2. A glob matched against the full relative path, e.g. \"**\\/*.d.ts\" or\n * \"**\\/codegen.ts\".\n * 3. A directory-prefix glob, e.g. \"libraries/apis\" -> \"libraries/apis/**\".\n *\n * Paths are normalized to forward slashes so Windows backslashes match too.\n */\nexport function isPathExcluded(relPath: string, excludePaths: readonly string[]): boolean {\n const norm = relPath.replace(/\\\\/g, '/');\n const segments = norm.split('/');\n for (const pattern of excludePaths) {\n if (segments.includes(pattern)) return true;\n if (minimatch(norm, pattern)) return true;\n if (minimatch(norm, `${pattern}/**`)) return true;\n }\n return false;\n}\n"]}
|
package/src/index.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export { ResolvedConfig, ResolvedRuleConfig, RuleOptions } from './types';
|
|
2
2
|
export { loadConfig, findConfigFile, CONFIG_FILENAME } from './load-config';
|
|
3
|
+
export { isPathExcluded } from './exclude-paths';
|
|
3
4
|
export { defaultRules, defaultRulesDir } from './default-rules';
|
|
4
5
|
export { loadTemplate, writeTemplateIfMissing, writeTemplate } from './load-template';
|
package/src/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.writeTemplate = exports.writeTemplateIfMissing = exports.loadTemplate = exports.defaultRulesDir = exports.defaultRules = exports.CONFIG_FILENAME = exports.findConfigFile = exports.loadConfig = exports.ResolvedRuleConfig = exports.ResolvedConfig = void 0;
|
|
3
|
+
exports.writeTemplate = exports.writeTemplateIfMissing = exports.loadTemplate = exports.defaultRulesDir = exports.defaultRules = exports.isPathExcluded = exports.CONFIG_FILENAME = exports.findConfigFile = exports.loadConfig = exports.ResolvedRuleConfig = exports.ResolvedConfig = void 0;
|
|
4
4
|
var types_1 = require("./types");
|
|
5
5
|
Object.defineProperty(exports, "ResolvedConfig", { enumerable: true, get: function () { return types_1.ResolvedConfig; } });
|
|
6
6
|
Object.defineProperty(exports, "ResolvedRuleConfig", { enumerable: true, get: function () { return types_1.ResolvedRuleConfig; } });
|
|
@@ -8,6 +8,8 @@ var load_config_1 = require("./load-config");
|
|
|
8
8
|
Object.defineProperty(exports, "loadConfig", { enumerable: true, get: function () { return load_config_1.loadConfig; } });
|
|
9
9
|
Object.defineProperty(exports, "findConfigFile", { enumerable: true, get: function () { return load_config_1.findConfigFile; } });
|
|
10
10
|
Object.defineProperty(exports, "CONFIG_FILENAME", { enumerable: true, get: function () { return load_config_1.CONFIG_FILENAME; } });
|
|
11
|
+
var exclude_paths_1 = require("./exclude-paths");
|
|
12
|
+
Object.defineProperty(exports, "isPathExcluded", { enumerable: true, get: function () { return exclude_paths_1.isPathExcluded; } });
|
|
11
13
|
var default_rules_1 = require("./default-rules");
|
|
12
14
|
Object.defineProperty(exports, "defaultRules", { enumerable: true, get: function () { return default_rules_1.defaultRules; } });
|
|
13
15
|
Object.defineProperty(exports, "defaultRulesDir", { enumerable: true, get: function () { return default_rules_1.defaultRulesDir; } });
|
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,6CAA4E;AAAnE,yGAAA,UAAU,OAAA;AAAE,6GAAA,cAAc,OAAA;AAAE,8GAAA,eAAe,OAAA;AACpD,iDAAgE;AAAvD,6GAAA,YAAY,OAAA;AAAE,gHAAA,eAAe,OAAA;AACtC,iDAAsF;AAA7E,6GAAA,YAAY,OAAA;AAAE,uHAAA,sBAAsB,OAAA;AAAE,8GAAA,aAAa,OAAA","sourcesContent":["export { ResolvedConfig, ResolvedRuleConfig, RuleOptions } from './types';\nexport { loadConfig, findConfigFile, CONFIG_FILENAME } from './load-config';\nexport { defaultRules, defaultRulesDir } from './default-rules';\nexport { loadTemplate, writeTemplateIfMissing, writeTemplate } from './load-template';\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,6CAA4E;AAAnE,yGAAA,UAAU,OAAA;AAAE,6GAAA,cAAc,OAAA;AAAE,8GAAA,eAAe,OAAA;AACpD,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","sourcesContent":["export { ResolvedConfig, ResolvedRuleConfig, RuleOptions } from './types';\nexport { loadConfig, findConfigFile, CONFIG_FILENAME } from './load-config';\nexport { isPathExcluded } from './exclude-paths';\nexport { defaultRules, defaultRulesDir } from './default-rules';\nexport { loadTemplate, writeTemplateIfMissing, writeTemplate } from './load-template';\n"]}
|
package/src/load-config.js
CHANGED
|
@@ -31,22 +31,18 @@ baseRule,
|
|
|
31
31
|
// webpieces-disable no-any-unknown -- opaque option bag
|
|
32
32
|
overrideRule) {
|
|
33
33
|
if (!baseRule && !overrideRule)
|
|
34
|
-
return new types_1.ResolvedRuleConfig(
|
|
34
|
+
return new types_1.ResolvedRuleConfig({ mode: 'OFF' });
|
|
35
35
|
if (!baseRule)
|
|
36
|
-
return new types_1.ResolvedRuleConfig(
|
|
36
|
+
return new types_1.ResolvedRuleConfig(overrideRule);
|
|
37
37
|
if (!overrideRule)
|
|
38
|
-
return new types_1.ResolvedRuleConfig(
|
|
38
|
+
return new types_1.ResolvedRuleConfig(baseRule);
|
|
39
39
|
// webpieces-disable no-any-unknown -- building merged option bag
|
|
40
40
|
const merged = {};
|
|
41
41
|
for (const key of Object.keys(baseRule))
|
|
42
42
|
merged[key] = baseRule[key];
|
|
43
43
|
for (const key of Object.keys(overrideRule))
|
|
44
44
|
merged[key] = overrideRule[key];
|
|
45
|
-
return new types_1.ResolvedRuleConfig(
|
|
46
|
-
}
|
|
47
|
-
// webpieces-disable no-any-unknown -- opaque option bag
|
|
48
|
-
function enabledOf(bag) {
|
|
49
|
-
return bag['enabled'] !== false;
|
|
45
|
+
return new types_1.ResolvedRuleConfig(merged);
|
|
50
46
|
}
|
|
51
47
|
function readRawConfig(configPath) {
|
|
52
48
|
// eslint-disable-next-line @webpieces/no-unmanaged-exceptions
|
package/src/load-config.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"load-config.js","sourceRoot":"","sources":["../../../../../packages/tooling/rules-config/src/load-config.ts"],"names":[],"mappings":";;;AAkBA,wCASC;
|
|
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 { ResolvedConfig, ResolvedRuleConfig, RuleOptions } from './types';\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 | null {\n // eslint-disable-next-line @webpieces/no-unmanaged-exceptions\n try {\n const raw = fs.readFileSync(configPath, 'utf8');\n return JSON.parse(raw) as RawConfigFile;\n // webpieces-disable catch-error-pattern -- malformed config fails open so missing config doesn't break validators\n } catch (err: unknown) {\n //const error = toError(err);\n void err;\n return null;\n }\n}\n\nexport function loadConfig(cwd: string): ResolvedConfig {\n const configPath = findConfigFile(cwd);\n\n if (!configPath) {\n return new ResolvedConfig(new Map(), [], null);\n }\n\n const consumerConfig = readRawConfig(configPath);\n if (!consumerConfig) {\n return new ResolvedConfig(new Map(), [], configPath);\n }\n\n const overrideRules = consumerConfig.rules || {};\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, rulesDir, configPath);\n}\n"]}
|
package/src/types.d.ts
CHANGED
|
@@ -2,14 +2,24 @@ export type RuleOptions = Record<string, unknown>;
|
|
|
2
2
|
/**
|
|
3
3
|
* One rule entry from webpieces.config.json, merged with built-in defaults.
|
|
4
4
|
*
|
|
5
|
-
* `options` contains the raw option bag (
|
|
5
|
+
* `options` contains the raw option bag (mode, limit, disableAllowed,
|
|
6
6
|
* ignoreModifiedUntilEpoch, enforcePaths, etc). Consumers extract the
|
|
7
7
|
* fields they understand and ignore the rest.
|
|
8
|
+
*
|
|
9
|
+
* On/off is driven entirely by `mode`: a rule is OFF only when explicitly
|
|
10
|
+
* set to `mode: "OFF"`. Any other value (or an absent mode) leaves the rule
|
|
11
|
+
* ON. For code-rules, `mode` doubles as the scope selector
|
|
12
|
+
* (e.g. "MODIFIED_CODE", "NEW_AND_MODIFIED_METHODS"); for simple on/off
|
|
13
|
+
* rules it is just "ON"/"OFF". (The legacy `enabled` boolean has been
|
|
14
|
+
* removed in favor of this single, more flexible switch.)
|
|
8
15
|
*/
|
|
9
16
|
export declare class ResolvedRuleConfig {
|
|
10
|
-
readonly enabled: boolean;
|
|
11
17
|
readonly options: RuleOptions;
|
|
12
|
-
constructor(
|
|
18
|
+
constructor(options: RuleOptions);
|
|
19
|
+
/** Raw mode string from the option bag ("ON" | "OFF" | scope value), if present. */
|
|
20
|
+
get mode(): string | undefined;
|
|
21
|
+
/** A rule is off only when explicitly `mode: "OFF"`. An absent mode means on. */
|
|
22
|
+
get isOff(): boolean;
|
|
13
23
|
}
|
|
14
24
|
/**
|
|
15
25
|
* The fully-resolved workspace configuration: every rule known to the
|
package/src/types.js
CHANGED
|
@@ -4,15 +4,30 @@ exports.ResolvedConfig = exports.ResolvedRuleConfig = void 0;
|
|
|
4
4
|
/**
|
|
5
5
|
* One rule entry from webpieces.config.json, merged with built-in defaults.
|
|
6
6
|
*
|
|
7
|
-
* `options` contains the raw option bag (
|
|
7
|
+
* `options` contains the raw option bag (mode, limit, disableAllowed,
|
|
8
8
|
* ignoreModifiedUntilEpoch, enforcePaths, etc). Consumers extract the
|
|
9
9
|
* fields they understand and ignore the rest.
|
|
10
|
+
*
|
|
11
|
+
* On/off is driven entirely by `mode`: a rule is OFF only when explicitly
|
|
12
|
+
* set to `mode: "OFF"`. Any other value (or an absent mode) leaves the rule
|
|
13
|
+
* ON. For code-rules, `mode` doubles as the scope selector
|
|
14
|
+
* (e.g. "MODIFIED_CODE", "NEW_AND_MODIFIED_METHODS"); for simple on/off
|
|
15
|
+
* rules it is just "ON"/"OFF". (The legacy `enabled` boolean has been
|
|
16
|
+
* removed in favor of this single, more flexible switch.)
|
|
10
17
|
*/
|
|
11
18
|
class ResolvedRuleConfig {
|
|
12
|
-
constructor(
|
|
13
|
-
this.enabled = enabled;
|
|
19
|
+
constructor(options) {
|
|
14
20
|
this.options = options;
|
|
15
21
|
}
|
|
22
|
+
/** Raw mode string from the option bag ("ON" | "OFF" | scope value), if present. */
|
|
23
|
+
get mode() {
|
|
24
|
+
const m = this.options['mode'];
|
|
25
|
+
return typeof m === 'string' ? m : undefined;
|
|
26
|
+
}
|
|
27
|
+
/** A rule is off only when explicitly `mode: "OFF"`. An absent mode means on. */
|
|
28
|
+
get isOff() {
|
|
29
|
+
return this.mode === 'OFF';
|
|
30
|
+
}
|
|
16
31
|
}
|
|
17
32
|
exports.ResolvedRuleConfig = ResolvedRuleConfig;
|
|
18
33
|
/**
|
package/src/types.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../../../packages/tooling/rules-config/src/types.ts"],"names":[],"mappings":";;;AAGA
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../../../packages/tooling/rules-config/src/types.ts"],"names":[],"mappings":";;;AAGA;;;;;;;;;;;;;GAaG;AACH,MAAa,kBAAkB;IAG3B,YAAY,OAAoB;QAC5B,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;IAC3B,CAAC;IAED,oFAAoF;IACpF,IAAI,IAAI;QACJ,MAAM,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QAC/B,OAAO,OAAO,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IACjD,CAAC;IAED,iFAAiF;IACjF,IAAI,KAAK;QACL,OAAO,IAAI,CAAC,IAAI,KAAK,KAAK,CAAC;IAC/B,CAAC;CACJ;AAjBD,gDAiBC;AAED;;;;;;;GAOG;AACH,MAAa,cAAc;IAKvB,YACI,KAAsC,EACtC,QAA2B,EAC3B,UAAyB;QAEzB,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;QACnB,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACzB,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;IACjC,CAAC;CACJ;AAdD,wCAcC","sourcesContent":["// webpieces-disable no-any-unknown -- rule options are opaque at framework level; each consumer casts internally\nexport type RuleOptions = Record<string, unknown>;\n\n/**\n * One rule entry from webpieces.config.json, merged with built-in defaults.\n *\n * `options` contains the raw option bag (mode, limit, disableAllowed,\n * ignoreModifiedUntilEpoch, enforcePaths, etc). Consumers extract the\n * fields they understand and ignore the rest.\n *\n * On/off is driven entirely by `mode`: a rule is OFF only when explicitly\n * set to `mode: \"OFF\"`. Any other value (or an absent mode) leaves the rule\n * ON. For code-rules, `mode` doubles as the scope selector\n * (e.g. \"MODIFIED_CODE\", \"NEW_AND_MODIFIED_METHODS\"); for simple on/off\n * rules it is just \"ON\"/\"OFF\". (The legacy `enabled` boolean has been\n * removed in favor of this single, more flexible switch.)\n */\nexport class ResolvedRuleConfig {\n readonly options: RuleOptions;\n\n constructor(options: RuleOptions) {\n this.options = options;\n }\n\n /** Raw mode string from the option bag (\"ON\" | \"OFF\" | scope value), if present. */\n get mode(): string | undefined {\n const m = this.options['mode'];\n return typeof m === 'string' ? m : undefined;\n }\n\n /** A rule is off only when explicitly `mode: \"OFF\"`. An absent mode means on. */\n get isOff(): boolean {\n return this.mode === 'OFF';\n }\n}\n\n/**\n * The fully-resolved workspace configuration: every rule known to the\n * workspace (built-in + consumer overrides) keyed by its canonical\n * kebab-case name.\n *\n * `configPath` is null when no webpieces.config.json was found (loaders\n * should treat that as \"no validation configured\").\n */\nexport class ResolvedConfig {\n readonly rules: Map<string, ResolvedRuleConfig>;\n readonly rulesDir: readonly string[];\n readonly configPath: string | null;\n\n constructor(\n rules: Map<string, ResolvedRuleConfig>,\n rulesDir: readonly string[],\n configPath: string | null,\n ) {\n this.rules = rules;\n this.rulesDir = rulesDir;\n this.configPath = configPath;\n }\n}\n"]}
|