@webpieces/tooling-testkit 0.4.847 → 0.4.848

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/tooling-testkit",
3
- "version": "0.4.847",
3
+ "version": "0.4.848",
4
4
  "description": "Shared development fixtures for tooling tests.",
5
5
  "type": "commonjs",
6
6
  "main": "./src/index.js",
@@ -13,7 +13,7 @@
13
13
  "README.md"
14
14
  ],
15
15
  "dependencies": {
16
- "@webpieces/tooling-common": "0.4.847",
16
+ "@webpieces/tooling-common": "0.4.848",
17
17
  "tslib": "2.8.1"
18
18
  },
19
19
  "author": "Dean Hiller",
@@ -30,7 +30,7 @@
30
30
  "developmentOnly": true
31
31
  },
32
32
  "devDependencies": {
33
- "@webpieces/rules-sdk": "0.4.847"
33
+ "@webpieces/rules-sdk": "0.4.848"
34
34
  },
35
35
  "types": "./src/index.d.ts"
36
36
  }
@@ -1,7 +1,16 @@
1
- import { RulePackManifest, FieldDef, ConfigObject } from '@webpieces/rules-sdk';
1
+ import { RulePackManifest, FieldDef, ConfigObject, RetiredConfigKey } from '@webpieces/rules-sdk';
2
+ /** A test host supplies the real artifact renderer without creating a production dependency edge. */
3
+ export interface FixtureArtifactWriter {
4
+ write(root: string): void;
5
+ }
2
6
  /** Frozen pre-migration policy data for real config-loader fixtures; never used by product code. */
3
7
  export declare class PolicyFixture {
8
+ private artifactWriter;
9
+ registerArtifactWriter(writer: FixtureArtifactWriter): void;
10
+ /** Explicit fixture migration preserves missing entries/fields so fail-closed assertions remain real. */
11
+ writeOwnerConfig(root: string, document: Record<string, unknown>, manifests?: readonly RulePackManifest[]): void;
4
12
  manifests(): readonly RulePackManifest[];
13
+ private contributions;
5
14
  /** Explicitly declares real CommonJS fixture modules; the real Node module transport loads them. */
6
15
  declareIn(root: string, manifests?: readonly RulePackManifest[]): void;
7
16
  /** Use deliberately in policy-loading tests, instead of modifying the generic temp-directory helper. */
@@ -10,12 +19,5 @@ export declare class PolicyFixture {
10
19
  export declare const policyFixture: PolicyFixture;
11
20
  export declare const fixtureSchemas: Record<string, Record<string, FieldDef>>;
12
21
  export declare const fixtureTuning: Record<string, ConfigObject>;
13
- export declare const fixtureMigrations: {
14
- scope: string;
15
- key: string;
16
- movedTo: string;
17
- instruction: string;
18
- label: string;
19
- prunable: boolean;
20
- }[];
22
+ export declare const fixtureMigrations: readonly RetiredConfigKey[];
21
23
  export declare const fixtureHookGuardNames: string[];
@@ -16,30 +16,140 @@ class OwnershipBaseline {
16
16
  const baseline = legacy_owned_policies_json_1.default;
17
17
  /** Frozen pre-migration policy data for real config-loader fixtures; never used by product code. */
18
18
  class PolicyFixture {
19
+ artifactWriter = null;
20
+ registerArtifactWriter(writer) {
21
+ this.artifactWriter = writer;
22
+ }
23
+ /** Explicit fixture migration preserves missing entries/fields so fail-closed assertions remain real. */
24
+ // webpieces-disable no-any-unknown -- test-only JSON conversion; runtime loading never accepts this old input shape
25
+ writeOwnerConfig(root,
26
+ // webpieces-disable no-any-unknown -- external JSON or runtime exports are validated before policy execution
27
+ document, manifests = this.manifests()) {
28
+ if (!this.artifactWriter)
29
+ throw new Error('Register a real FixtureArtifactWriter before writing a migrated policy fixture.');
30
+ this.declareIn(root, manifests);
31
+ const flat = Object.assign({}, document['rules'], document['hookGuards']);
32
+ const owned = new Set(manifests.flatMap((manifest) => manifest.ownedRules.map((definition) => definition.id)));
33
+ const declarations = manifests.map((manifest, index) => {
34
+ const filename = `.webpieces/rules/fixture-${index}.json`;
35
+ const entries = Object.fromEntries(manifest.ownedRules
36
+ .filter((definition) => Object.hasOwn(flat, definition.id))
37
+ .map((definition) => [definition.id, flat[definition.id]]));
38
+ // Unknown keys stay invalid instead of being dropped during fixture migration.
39
+ if (index === 0)
40
+ for (const id of Object.keys(flat))
41
+ if (!owned.has(id))
42
+ entries[id] = flat[id];
43
+ fs.mkdirSync(path.dirname(path.join(root, filename)), { recursive: true });
44
+ fs.writeFileSync(path.join(root, filename), JSON.stringify(entries, null, 2) + '\n');
45
+ return { package: `./fixture-policy-${index}.cjs`, config: filename };
46
+ });
47
+ // webpieces-disable no-any-unknown -- external JSON or runtime exports are validated before policy execution
48
+ const next = { ...document, rulePacks: declarations };
49
+ delete next['rules'];
50
+ delete next['hookGuards'];
51
+ if (Array.isArray(next['rulesDir']) && next['rulesDir'].length === 0)
52
+ delete next['rulesDir'];
53
+ fs.writeFileSync(path.join(root, 'webpieces.config.json'), JSON.stringify(next, null, 2) + '\n');
54
+ this.artifactWriter.write(root);
55
+ }
19
56
  manifests() {
20
- return Object.entries(baseline.owners).filter(entry => entry[0] !== '@webpieces/eslint-rules').map(entry => {
21
- const owner = entry[0];
22
- const ids = entry[1];
57
+ return Object.keys(baseline.owners)
58
+ .filter((owner) => owner !== '@webpieces/eslint-rules')
59
+ .map((owner) => {
60
+ const ids = baseline.owners[owner];
23
61
  return {
24
- packageName: owner, packageVersion: '1.0.0-fixture', apiVersion: 2,
25
- ownedRules: ids.map(id => ({
26
- id, schema: baseline.schemas[id], schemaApiVersion: 1,
62
+ packageName: owner,
63
+ packageVersion: '1.0.0-fixture',
64
+ apiVersion: 3,
65
+ ownedRules: ids.map((id) => ({
66
+ id,
67
+ schema: baseline.schemas[id],
68
+ schemaApiVersion: 1,
27
69
  optionalTuning: baseline.tuning[id] ?? {},
28
70
  recommendedSeed: baseline.seeds[id],
71
+ help: {
72
+ description: `Frozen fixture policy ${id}`,
73
+ remediation: 'Configure explicitly in {configFile}.',
74
+ },
29
75
  section: owner === '@webpieces/agent-workflow-rules' ? 'hookGuards' : 'rules',
30
76
  })),
31
- contributions: [],
32
- migrations: baseline.migrations.filter(entry => (owner === '@webpieces/agent-workflow-rules' && (entry.scope === 'rule' || entry.key.startsWith('pr-lifecycle-guard.'))) ||
33
- (owner === '@webpieces/nx-webpieces-rules' && entry.scope === 'field' && entry.key.startsWith('runtime-architecture.'))),
77
+ contributions: this.contributions(owner, ids),
78
+ migrations: baseline.migrations.filter((entry) => (owner === '@webpieces/agent-workflow-rules' &&
79
+ (entry.scope === 'rule' ||
80
+ entry.key.startsWith('pr-lifecycle-guard.'))) ||
81
+ (owner === '@webpieces/nx-webpieces-rules' &&
82
+ entry.scope === 'field' &&
83
+ entry.key.startsWith('runtime-architecture.'))),
34
84
  safeguards: [],
35
85
  };
36
86
  });
37
87
  }
88
+ contributions(owner, ids) {
89
+ const module = `${owner}/rule-runtime`;
90
+ if (owner === '@webpieces/agent-workflow-rules')
91
+ return ids.map((id) => ({
92
+ ruleId: id,
93
+ ownerPack: owner,
94
+ executionKind: 'workflow-guard',
95
+ implementationModule: module,
96
+ }));
97
+ if (owner === '@webpieces/code-rules')
98
+ return ids.map((id) => ({
99
+ ruleId: id,
100
+ ownerPack: owner,
101
+ executionKind: 'build',
102
+ implementationModule: module,
103
+ }));
104
+ if (owner === '@webpieces/nx-webpieces-rules')
105
+ return [
106
+ ...ids.map((id) => ({
107
+ ruleId: id,
108
+ ownerPack: owner,
109
+ executionKind: 'build',
110
+ implementationModule: module,
111
+ })),
112
+ {
113
+ ruleId: 'validate-ts-in-src',
114
+ ownerPack: '@webpieces/ai-hook-rules',
115
+ executionKind: 'build',
116
+ implementationModule: module,
117
+ },
118
+ ];
119
+ const shared = [
120
+ 'no-any-unknown',
121
+ 'no-implicit-any',
122
+ 'max-file-lines',
123
+ 'no-destructure',
124
+ 'require-return-type',
125
+ 'no-unmanaged-exceptions',
126
+ 'catch-error-pattern',
127
+ 'no-symbol-di-tokens',
128
+ 'no-custom-css',
129
+ 'no-process-exit-outside-main',
130
+ ];
131
+ return [
132
+ ...ids.map((id) => ({
133
+ ruleId: id,
134
+ ownerPack: owner,
135
+ executionKind: 'source-hook',
136
+ implementationModule: module,
137
+ })),
138
+ ...shared.map((id) => ({
139
+ ruleId: id,
140
+ ownerPack: '@webpieces/code-rules',
141
+ executionKind: 'source-hook',
142
+ implementationModule: module,
143
+ })),
144
+ ];
145
+ }
38
146
  /** Explicitly declares real CommonJS fixture modules; the real Node module transport loads them. */
39
147
  declareIn(root, manifests = this.manifests()) {
40
148
  const packageFile = path.join(root, 'package.json');
41
149
  // webpieces-disable no-any-unknown -- fixture package JSON retains unrelated test fields
42
- const pkg = fs.existsSync(packageFile) ? JSON.parse(fs.readFileSync(packageFile, 'utf8')) : { private: true };
150
+ const pkg = fs.existsSync(packageFile)
151
+ ? JSON.parse(fs.readFileSync(packageFile, 'utf8'))
152
+ : { private: true };
43
153
  const declarations = manifests.map((manifest, index) => {
44
154
  const module = `./fixture-policy-${index}.cjs`;
45
155
  fs.writeFileSync(path.join(root, module), `exports.rulePackManifest = ${JSON.stringify(manifest)};\n`);
@@ -60,5 +170,9 @@ exports.policyFixture = new PolicyFixture();
60
170
  exports.fixtureSchemas = baseline.schemas;
61
171
  exports.fixtureTuning = baseline.tuning;
62
172
  exports.fixtureMigrations = baseline.migrations;
63
- exports.fixtureHookGuardNames = exports.policyFixture.manifests().flatMap(pack => pack.ownedRules.filter(rule => rule.section === 'hookGuards').map(rule => rule.id));
173
+ exports.fixtureHookGuardNames = exports.policyFixture
174
+ .manifests()
175
+ .flatMap((pack) => pack.ownedRules
176
+ .filter((rule) => rule.section === 'hookGuards')
177
+ .map((rule) => rule.id));
64
178
  //# sourceMappingURL=policy-fixture.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"policy-fixture.js","sourceRoot":"","sources":["../../../../../packages/tooling/tooling-testkit/src/policy-fixture.ts"],"names":[],"mappings":"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","sourcesContent":["import * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport { RulePackManifest, FieldDef, ConfigObject } from '@webpieces/rules-sdk';\nimport { specTempDirs } from './spec-temp-dirs';\nimport snapshot from './legacy-owned-policies.json';\n\nclass OwnershipBaseline {\n schemas!: Record<string, Record<string, FieldDef>>;\n tuning!: Record<string, ConfigObject>;\n seeds!: Record<string, ConfigObject>;\n migrations!: typeof snapshot.migrations;\n owners!: Record<string, string[]>;\n}\nconst baseline = snapshot as OwnershipBaseline;\n\n/** Frozen pre-migration policy data for real config-loader fixtures; never used by product code. */\nexport class PolicyFixture {\n manifests(): readonly RulePackManifest[] {\n return Object.entries(baseline.owners).filter(entry => entry[0] !== '@webpieces/eslint-rules').map(entry => {\n const owner = entry[0];\n const ids = entry[1];\n return ({\n packageName: owner, packageVersion: '1.0.0-fixture', apiVersion: 2,\n ownedRules: ids.map(id => ({\n id, schema: baseline.schemas[id as keyof typeof baseline.schemas], schemaApiVersion: 1,\n optionalTuning: baseline.tuning[id as keyof typeof baseline.tuning] ?? {},\n recommendedSeed: baseline.seeds[id as keyof typeof baseline.seeds],\n section: owner === '@webpieces/agent-workflow-rules' ? 'hookGuards' : 'rules',\n })),\n contributions: [],\n migrations: baseline.migrations.filter(entry =>\n (owner === '@webpieces/agent-workflow-rules' && (entry.scope === 'rule' || entry.key.startsWith('pr-lifecycle-guard.'))) ||\n (owner === '@webpieces/nx-webpieces-rules' && entry.scope === 'field' && entry.key.startsWith('runtime-architecture.'))),\n safeguards: [],\n } as RulePackManifest);\n });\n }\n\n /** Explicitly declares real CommonJS fixture modules; the real Node module transport loads them. */\n declareIn(root: string, manifests: readonly RulePackManifest[] = this.manifests()): void {\n const packageFile = path.join(root, 'package.json');\n // webpieces-disable no-any-unknown -- fixture package JSON retains unrelated test fields\n const pkg: Record<string, unknown> = fs.existsSync(packageFile) ? JSON.parse(fs.readFileSync(packageFile, 'utf8')) : { private: true };\n const declarations = manifests.map((manifest, index) => {\n const module = `./fixture-policy-${index}.cjs`;\n fs.writeFileSync(path.join(root, module), `exports.rulePackManifest = ${JSON.stringify(manifest)};\\n`);\n return { module };\n });\n pkg['webpieces'] = { rulePacks: declarations };\n fs.writeFileSync(packageFile, JSON.stringify(pkg, null, 2) + '\\n');\n }\n\n /** Use deliberately in policy-loading tests, instead of modifying the generic temp-directory helper. */\n makeRepo(prefix: string): string {\n const root = specTempDirs.make(prefix);\n this.declareIn(root);\n return root;\n }\n}\n\nexport const policyFixture = new PolicyFixture();\nexport const fixtureSchemas = baseline.schemas;\nexport const fixtureTuning = baseline.tuning;\nexport const fixtureMigrations = baseline.migrations;\nexport const fixtureHookGuardNames = policyFixture.manifests().flatMap(pack => pack.ownedRules.filter(rule => rule.section === 'hookGuards').map(rule => rule.id));\n"]}
1
+ {"version":3,"file":"policy-fixture.js","sourceRoot":"","sources":["../../../../../packages/tooling/tooling-testkit/src/policy-fixture.ts"],"names":[],"mappings":"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","sourcesContent":["import * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport {\n RulePackManifest,\n FieldDef,\n ConfigObject,\n OwnedRuleDefinition,\n RetiredConfigKey,\n} from '@webpieces/rules-sdk';\nimport { specTempDirs } from './spec-temp-dirs';\nimport snapshot from './legacy-owned-policies.json';\n\nclass OwnershipBaseline {\n schemas!: Record<string, Record<string, FieldDef>>;\n tuning!: Record<string, ConfigObject>;\n seeds!: Record<string, ConfigObject>;\n migrations!: readonly RetiredConfigKey[];\n owners!: Record<string, string[]>;\n}\nconst baseline = snapshot as OwnershipBaseline;\n\n/** A test host supplies the real artifact renderer without creating a production dependency edge. */\nexport interface FixtureArtifactWriter {\n write(root: string): void;\n}\n\n/** Frozen pre-migration policy data for real config-loader fixtures; never used by product code. */\nexport class PolicyFixture {\n private artifactWriter: FixtureArtifactWriter | null = null;\n\n registerArtifactWriter(writer: FixtureArtifactWriter): void {\n this.artifactWriter = writer;\n }\n\n /** Explicit fixture migration preserves missing entries/fields so fail-closed assertions remain real. */\n // webpieces-disable no-any-unknown -- test-only JSON conversion; runtime loading never accepts this old input shape\n writeOwnerConfig(\n root: string,\n // webpieces-disable no-any-unknown -- external JSON or runtime exports are validated before policy execution\n document: Record<string, unknown>,\n manifests: readonly RulePackManifest[] = this.manifests(),\n ): void {\n if (!this.artifactWriter)\n throw new Error(\n 'Register a real FixtureArtifactWriter before writing a migrated policy fixture.',\n );\n this.declareIn(root, manifests);\n const flat = Object.assign({}, document['rules'], document['hookGuards']) as Record<\n string,\n ConfigObject\n >;\n const owned = new Set(\n manifests.flatMap((manifest: RulePackManifest) =>\n manifest.ownedRules.map((definition: OwnedRuleDefinition) => definition.id),\n ),\n );\n const declarations = manifests.map((manifest: RulePackManifest, index: number) => {\n const filename = `.webpieces/rules/fixture-${index}.json`;\n const entries = Object.fromEntries(\n manifest.ownedRules\n .filter((definition: OwnedRuleDefinition) => Object.hasOwn(flat, definition.id))\n .map((definition: OwnedRuleDefinition) => [definition.id, flat[definition.id]]),\n );\n // Unknown keys stay invalid instead of being dropped during fixture migration.\n if (index === 0)\n for (const id of Object.keys(flat)) if (!owned.has(id)) entries[id] = flat[id];\n fs.mkdirSync(path.dirname(path.join(root, filename)), { recursive: true });\n fs.writeFileSync(path.join(root, filename), JSON.stringify(entries, null, 2) + '\\n');\n return { package: `./fixture-policy-${index}.cjs`, config: filename };\n });\n // webpieces-disable no-any-unknown -- external JSON or runtime exports are validated before policy execution\n const next = { ...document, rulePacks: declarations } as Record<string, unknown>;\n delete next['rules'];\n delete next['hookGuards'];\n if (Array.isArray(next['rulesDir']) && next['rulesDir'].length === 0)\n delete next['rulesDir'];\n fs.writeFileSync(\n path.join(root, 'webpieces.config.json'),\n JSON.stringify(next, null, 2) + '\\n',\n );\n this.artifactWriter.write(root);\n }\n\n manifests(): readonly RulePackManifest[] {\n return Object.keys(baseline.owners)\n .filter((owner: string) => owner !== '@webpieces/eslint-rules')\n .map((owner: string) => {\n const ids = baseline.owners[owner];\n return {\n packageName: owner,\n packageVersion: '1.0.0-fixture',\n apiVersion: 3,\n ownedRules: ids.map((id: string) => ({\n id,\n schema: baseline.schemas[id as keyof typeof baseline.schemas],\n schemaApiVersion: 1,\n optionalTuning: baseline.tuning[id as keyof typeof baseline.tuning] ?? {},\n recommendedSeed: baseline.seeds[id as keyof typeof baseline.seeds],\n help: {\n description: `Frozen fixture policy ${id}`,\n remediation: 'Configure explicitly in {configFile}.',\n },\n section:\n owner === '@webpieces/agent-workflow-rules' ? 'hookGuards' : 'rules',\n })),\n contributions: this.contributions(owner, ids),\n migrations: baseline.migrations.filter(\n (entry: RetiredConfigKey) =>\n (owner === '@webpieces/agent-workflow-rules' &&\n (entry.scope === 'rule' ||\n entry.key.startsWith('pr-lifecycle-guard.'))) ||\n (owner === '@webpieces/nx-webpieces-rules' &&\n entry.scope === 'field' &&\n entry.key.startsWith('runtime-architecture.')),\n ),\n safeguards: [],\n } as RulePackManifest;\n });\n }\n\n private contributions(\n owner: string,\n ids: readonly string[],\n ): RulePackManifest['contributions'] {\n const module = `${owner}/rule-runtime`;\n if (owner === '@webpieces/agent-workflow-rules')\n return ids.map((id: string) => ({\n ruleId: id,\n ownerPack: owner,\n executionKind: 'workflow-guard',\n implementationModule: module,\n }));\n if (owner === '@webpieces/code-rules')\n return ids.map((id: string) => ({\n ruleId: id,\n ownerPack: owner,\n executionKind: 'build',\n implementationModule: module,\n }));\n if (owner === '@webpieces/nx-webpieces-rules')\n return [\n ...ids.map((id: string) => ({\n ruleId: id,\n ownerPack: owner,\n executionKind: 'build' as const,\n implementationModule: module,\n })),\n {\n ruleId: 'validate-ts-in-src',\n ownerPack: '@webpieces/ai-hook-rules',\n executionKind: 'build',\n implementationModule: module,\n },\n ];\n const shared = [\n 'no-any-unknown',\n 'no-implicit-any',\n 'max-file-lines',\n 'no-destructure',\n 'require-return-type',\n 'no-unmanaged-exceptions',\n 'catch-error-pattern',\n 'no-symbol-di-tokens',\n 'no-custom-css',\n 'no-process-exit-outside-main',\n ];\n return [\n ...ids.map((id: string) => ({\n ruleId: id,\n ownerPack: owner,\n executionKind: 'source-hook' as const,\n implementationModule: module,\n })),\n ...shared.map((id: string) => ({\n ruleId: id,\n ownerPack: '@webpieces/code-rules',\n executionKind: 'source-hook' as const,\n implementationModule: module,\n })),\n ];\n }\n\n /** Explicitly declares real CommonJS fixture modules; the real Node module transport loads them. */\n declareIn(root: string, manifests: readonly RulePackManifest[] = this.manifests()): void {\n const packageFile = path.join(root, 'package.json');\n // webpieces-disable no-any-unknown -- fixture package JSON retains unrelated test fields\n const pkg: Record<string, unknown> = fs.existsSync(packageFile)\n ? JSON.parse(fs.readFileSync(packageFile, 'utf8'))\n : { private: true };\n const declarations = manifests.map((manifest: RulePackManifest, index: number) => {\n const module = `./fixture-policy-${index}.cjs`;\n fs.writeFileSync(\n path.join(root, module),\n `exports.rulePackManifest = ${JSON.stringify(manifest)};\\n`,\n );\n return { module };\n });\n pkg['webpieces'] = { rulePacks: declarations };\n fs.writeFileSync(packageFile, JSON.stringify(pkg, null, 2) + '\\n');\n }\n\n /** Use deliberately in policy-loading tests, instead of modifying the generic temp-directory helper. */\n makeRepo(prefix: string): string {\n const root = specTempDirs.make(prefix);\n this.declareIn(root);\n return root;\n }\n}\n\nexport const policyFixture = new PolicyFixture();\nexport const fixtureSchemas = baseline.schemas;\nexport const fixtureTuning = baseline.tuning;\nexport const fixtureMigrations = baseline.migrations;\nexport const fixtureHookGuardNames = policyFixture\n .manifests()\n .flatMap((pack: RulePackManifest) =>\n pack.ownedRules\n .filter((rule: OwnedRuleDefinition) => rule.section === 'hookGuards')\n .map((rule: OwnedRuleDefinition) => rule.id),\n );\n"]}