@ploaness/config 1.5.0 → 1.7.0

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.
Files changed (54) hide show
  1. package/biome-core.json +9 -3
  2. package/biome.json +1 -1
  3. package/dependency-cruiser-core.json +1 -4
  4. package/dist/a11y.d.ts +24 -9
  5. package/dist/a11y.d.ts.map +1 -1
  6. package/dist/a11y.js +58 -143
  7. package/dist/a11y.js.map +1 -1
  8. package/dist/access.d.ts.map +1 -1
  9. package/dist/access.js.map +1 -1
  10. package/dist/eslint-core.d.ts.map +1 -1
  11. package/dist/eslint-core.js +32 -17
  12. package/dist/eslint-core.js.map +1 -1
  13. package/dist/eslint-library.d.ts +3 -2
  14. package/dist/eslint-library.d.ts.map +1 -1
  15. package/dist/eslint-library.js +2 -1
  16. package/dist/eslint-library.js.map +1 -1
  17. package/dist/eslint-security.d.ts.map +1 -1
  18. package/dist/eslint-security.js +2 -6
  19. package/dist/eslint-security.js.map +1 -1
  20. package/dist/eslint.d.ts +5 -2
  21. package/dist/eslint.d.ts.map +1 -1
  22. package/dist/eslint.js +31 -12
  23. package/dist/eslint.js.map +1 -1
  24. package/dist/layout.d.ts +23 -0
  25. package/dist/layout.d.ts.map +1 -0
  26. package/dist/layout.js +185 -0
  27. package/dist/layout.js.map +1 -0
  28. package/dist/playwright.d.ts.map +1 -1
  29. package/dist/playwright.js +16 -5
  30. package/dist/playwright.js.map +1 -1
  31. package/dist/production-server.d.ts +2 -0
  32. package/dist/production-server.d.ts.map +1 -0
  33. package/dist/production-server.js +63 -0
  34. package/dist/production-server.js.map +1 -0
  35. package/dist/project-settings.d.ts.map +1 -1
  36. package/dist/project-settings.js +1 -1
  37. package/dist/project-settings.js.map +1 -1
  38. package/dist/security.d.ts +8 -0
  39. package/dist/security.d.ts.map +1 -0
  40. package/dist/security.js +7 -0
  41. package/dist/security.js.map +1 -0
  42. package/dist/settle.d.ts +13 -0
  43. package/dist/settle.d.ts.map +1 -0
  44. package/dist/settle.js +136 -0
  45. package/dist/settle.js.map +1 -0
  46. package/dist/vitest-core.d.ts.map +1 -1
  47. package/dist/vitest-core.js.map +1 -1
  48. package/dist/vitest-library.d.ts.map +1 -1
  49. package/dist/vitest-library.js +1 -1
  50. package/dist/vitest-library.js.map +1 -1
  51. package/dist/vitest-setup.js +1 -6
  52. package/dist/vitest-setup.js.map +1 -1
  53. package/package.json +17 -12
  54. package/pins.json +5 -5
@@ -21,7 +21,7 @@ const reexportConfigBlock = {
21
21
  files: [...REEXPORT_CONFIG_FILES],
22
22
  rules: { 'unicorn/prefer-export-from': 'off' },
23
23
  };
24
- export default compose({ ignores: [...IGNORED] }, ...baseLayers, typeAwareParsing({ projectService: true }), { rules: { ...guidelineRules } },
24
+ const config = compose({ ignores: [...IGNORED] }, ...baseLayers, typeAwareParsing({ projectService: true }), { rules: { ...guidelineRules } },
25
25
  // Immutability applies to every hand-written module. A library has no generated files to exempt, so
26
26
  // the block is applied without the Payload carve-outs rather than with an empty list of them.
27
27
  immutabilityBlock(['**/*.ts', '**/*.mts'], []),
@@ -50,4 +50,5 @@ specEnvironmentBlock(), javascriptBlock(JAVASCRIPT_FILES),
50
50
  ...testSuiteSyntaxRules,
51
51
  },
52
52
  }, reexportConfigBlock, prettierLast);
53
+ export default config;
53
54
  //# sourceMappingURL=eslint-library.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"eslint-library.js","sourceRoot":"","sources":["../src/eslint-library.ts"],"names":[],"mappings":"AAAA,oEAAoE;AACpE,EAAE;AACF,mGAAmG;AACnG,sGAAsG;AACtG,qGAAqG;AACrG,uGAAuG;AACvG,gGAAgG;AAChG,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAA;AAC5D,OAAO,EACL,UAAU,EACV,OAAO,EAEP,cAAc,EACd,iBAAiB,EACjB,eAAe,EACf,YAAY,EACZ,kBAAkB,EAClB,oBAAoB,EACpB,cAAc,EACd,kBAAkB,EAClB,oBAAoB,EACpB,gBAAgB,EAChB,YAAY,GACb,MAAM,kBAAkB,CAAA;AAEzB,MAAM,OAAO,GAAsB,CAAC,SAAS,EAAE,iBAAiB,EAAE,aAAa,EAAE,UAAU,CAAC,CAAA;AAE5F,qGAAqG;AACrG,MAAM,gBAAgB,GAAsB,CAAC,mBAAmB,CAAC,CAAA;AAEjE,sFAAsF;AACtF,kGAAkG;AAClG,oGAAoG;AACpG,0EAA0E;AAC1E,EAAE;AACF,oGAAoG;AACpG,sEAAsE;AACtE,MAAM,mBAAmB,GAAoB;IAC3C,KAAK,EAAE,CAAC,GAAG,qBAAqB,CAAC;IACjC,KAAK,EAAE,EAAE,4BAA4B,EAAE,KAAK,EAAE;CAC/C,CAAA;AAED,eAAe,OAAO,CACpB,EAAE,OAAO,EAAE,CAAC,GAAG,OAAO,CAAC,EAAE,EACzB,GAAG,UAAU,EACb,gBAAgB,CAAC,EAAE,cAAc,EAAE,IAAI,EAAE,CAAC,EAC1C,EAAE,KAAK,EAAE,EAAE,GAAG,cAAc,EAAE,EAA4B;AAC1D,oGAAoG;AACpG,8FAA8F;AAC9F,iBAAiB,CAAC,CAAC,SAAS,EAAE,UAAU,CAAC,EAAE,EAAE,CAAC;AAE9C,oGAAoG;AACpG,kGAAkG;AAClG,kBAAkB,EAAE;AACpB,oGAAoG;AACpG,oBAAoB,EAAE,EACtB,eAAe,CAAC,gBAAgB,CAAC;AACjC,sGAAsG;AACtG,sDAAsD;AACtD,EAAE;AACF,iGAAiG;AACjG,qGAAqG;AACrG,8EAA8E;AAC9E,EAAE;AACF,uGAAuG;AACvG,mGAAmG;AACnG,uGAAuG;AACvG,qGAAqG;AACrG;IACE,KAAK,EAAE,CAAC,UAAU,CAAC;IACnB,OAAO,EAAE,EAAE,MAAM,EAAE,YAAY,EAAE;IACjC,KAAK,EAAE;QACL,GAAG,cAAc;QACjB,GAAG,kBAAkB;QACrB,GAAG,oBAAoB;KACxB;CACwB,EAC3B,mBAAmB,EACnB,YAAY,CACb,CAAA"}
1
+ {"version":3,"file":"eslint-library.js","sourceRoot":"","sources":["../src/eslint-library.ts"],"names":[],"mappings":"AAAA,oEAAoE;AACpE,EAAE;AACF,mGAAmG;AACnG,sGAAsG;AACtG,qGAAqG;AACrG,uGAAuG;AACvG,gGAAgG;AAChG,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAA;AAC5D,OAAO,EACL,UAAU,EACV,OAAO,EAEP,cAAc,EACd,iBAAiB,EACjB,eAAe,EACf,YAAY,EACZ,kBAAkB,EAClB,oBAAoB,EACpB,cAAc,EACd,kBAAkB,EAClB,oBAAoB,EACpB,gBAAgB,EAChB,YAAY,GACb,MAAM,kBAAkB,CAAA;AAEzB,MAAM,OAAO,GAAsB,CAAC,SAAS,EAAE,iBAAiB,EAAE,aAAa,EAAE,UAAU,CAAC,CAAA;AAE5F,qGAAqG;AACrG,MAAM,gBAAgB,GAAsB,CAAC,mBAAmB,CAAC,CAAA;AAEjE,sFAAsF;AACtF,kGAAkG;AAClG,oGAAoG;AACpG,0EAA0E;AAC1E,EAAE;AACF,oGAAoG;AACpG,sEAAsE;AACtE,MAAM,mBAAmB,GAAoB;IAC3C,KAAK,EAAE,CAAC,GAAG,qBAAqB,CAAC;IACjC,KAAK,EAAE,EAAE,4BAA4B,EAAE,KAAK,EAAE;CAC/C,CAAA;AAED,MAAM,MAAM,GAA+B,OAAO,CAChD,EAAE,OAAO,EAAE,CAAC,GAAG,OAAO,CAAC,EAAE,EACzB,GAAG,UAAU,EACb,gBAAgB,CAAC,EAAE,cAAc,EAAE,IAAI,EAAE,CAAC,EAC1C,EAAE,KAAK,EAAE,EAAE,GAAG,cAAc,EAAE,EAA4B;AAC1D,oGAAoG;AACpG,8FAA8F;AAC9F,iBAAiB,CAAC,CAAC,SAAS,EAAE,UAAU,CAAC,EAAE,EAAE,CAAC;AAE9C,oGAAoG;AACpG,kGAAkG;AAClG,kBAAkB,EAAE;AACpB,oGAAoG;AACpG,oBAAoB,EAAE,EACtB,eAAe,CAAC,gBAAgB,CAAC;AACjC,sGAAsG;AACtG,sDAAsD;AACtD,EAAE;AACF,iGAAiG;AACjG,qGAAqG;AACrG,8EAA8E;AAC9E,EAAE;AACF,uGAAuG;AACvG,mGAAmG;AACnG,uGAAuG;AACvG,qGAAqG;AACrG;IACE,KAAK,EAAE,CAAC,UAAU,CAAC;IACnB,OAAO,EAAE,EAAE,MAAM,EAAE,YAAY,EAAE;IACjC,KAAK,EAAE;QACL,GAAG,cAAc;QACjB,GAAG,kBAAkB;QACrB,GAAG,oBAAoB;KACxB;CACwB,EAC3B,mBAAmB,EACnB,YAAY,CACb,CAAA;AAED,eAAe,MAAM,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"eslint-security.d.ts","sourceRoot":"","sources":["../src/eslint-security.ts"],"names":[],"mappings":"AAMA,8FAA8F;AAC9F,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;CACzB;AAkED,uEAAuE;AACvE,eAAO,MAAM,qBAAqB,EAAE,SAAS,gBAAgB,EAG5D,CAAA"}
1
+ {"version":3,"file":"eslint-security.d.ts","sourceRoot":"","sources":["../src/eslint-security.ts"],"names":[],"mappings":"AAMA,8FAA8F;AAC9F,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;CACzB;AA4DD,uEAAuE;AACvE,eAAO,MAAM,qBAAqB,EAAE,SAAS,gBAAgB,EAAwD,CAAA"}
@@ -19,8 +19,7 @@ const SENSITIVE_LOGGING = [
19
19
  sensitiveLog(` > ObjectExpression Property[shorthand=true] > Identifier[name=${SENSITIVE_NAME}]`),
20
20
  sensitiveLog(` > ObjectExpression Property > MemberExpression[property.name=${SENSITIVE_NAME}]`),
21
21
  ];
22
- const INTERNAL_ERROR = 'MemberExpression[object.name=/^(?:err|error|exception)$/]' +
23
- '[property.name=/^(?:message|stack)$/]';
22
+ const INTERNAL_ERROR = 'MemberExpression[object.name=/^(?:err|error|exception)$/][property.name=/^(?:message|stack)$/]';
24
23
  const ERROR_PROPERTY = 'Property[key.name=/^(?:error|message)$/], Property[key.value=/^(?:error|message)$/]';
25
24
  const JSON_RESPONSE = "CallExpression[callee.type='MemberExpression']" +
26
25
  '[callee.object.name=/^(?:Response|NextResponse)$/]' +
@@ -40,8 +39,5 @@ const INTERNAL_ERROR_RESPONSES = [
40
39
  errorResponse(`NewExpression[callee.name='Response'] > ${INTERNAL_ERROR}`),
41
40
  ];
42
41
  /** Output-boundary syntax every composed configuration must retain. */
43
- export const SECURITY_RESTRICTIONS = [
44
- ...SENSITIVE_LOGGING,
45
- ...INTERNAL_ERROR_RESPONSES,
46
- ];
42
+ export const SECURITY_RESTRICTIONS = [...SENSITIVE_LOGGING, ...INTERNAL_ERROR_RESPONSES];
47
43
  //# sourceMappingURL=eslint-security.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"eslint-security.js","sourceRoot":"","sources":["../src/eslint-security.ts"],"names":[],"mappings":"AAYA,MAAM,cAAc,GAAW,oEAAoE,CAAA;AAEnG,MAAM,YAAY,GAChB,gDAAgD;IAChD,gCAAgC;IAChC,gEAAgE,CAAA;AAElE,MAAM,qBAAqB,GACzB,8FAA8F;IAC9F,iDAAiD,CAAA;AAEnD,MAAM,YAAY,GAAG,CAAC,MAAc,EAAoB,EAAE,CAAC,CAAC;IAC1D,QAAQ,EAAE,GAAG,YAAY,GAAG,MAAM,EAAE;IACpC,OAAO,EAAE,qBAAqB;CAC/B,CAAC,CAAA;AAEF,MAAM,iBAAiB,GAAgC;IACrD,YAAY,CAAC,sBAAsB,cAAc,GAAG,CAAC;IACrD,YAAY,CAAC,qCAAqC,cAAc,GAAG,CAAC;IACpE,YAAY,CAAC,qDAAqD,cAAc,GAAG,CAAC;IACpF,YAAY,CAAC,sCAAsC,cAAc,GAAG,CAAC;IACrE,YAAY,CAAC,qDAAqD,cAAc,GAAG,CAAC;IACpF,YAAY,CAAC,uCAAuC,cAAc,GAAG,CAAC;IACtE,YAAY,CAAC,sDAAsD,cAAc,GAAG,CAAC;IACrF,YAAY,CAAC,kEAAkE,cAAc,GAAG,CAAC;IACjG,YAAY,CAAC,iEAAiE,cAAc,GAAG,CAAC;CACjG,CAAA;AAED,MAAM,cAAc,GAClB,2DAA2D;IAC3D,uCAAuC,CAAA;AAEzC,MAAM,cAAc,GAClB,qFAAqF,CAAA;AAEvF,MAAM,aAAa,GACjB,gDAAgD;IAChD,oDAAoD;IACpD,+BAA+B,CAAA;AAEjC,MAAM,sBAAsB,GAC1B,6FAA6F;IAC7F,wEAAwE,CAAA;AAE1E,MAAM,aAAa,GAAG,CAAC,QAAgB,EAAoB,EAAE,CAAC,CAAC;IAC7D,QAAQ;IACR,OAAO,EAAE,sBAAsB;CAChC,CAAC,CAAA;AAEF,MAAM,wBAAwB,GAAgC;IAC5D,aAAa,CACX,GAAG,aAAa,kCAAkC,cAAc,OAAO,cAAc,EAAE,CACxF;IACD,aAAa,CAAC,GAAG,aAAa,MAAM,cAAc,EAAE,CAAC;IACrD,aAAa,CACX,iDAAiD,cAAc,OAAO,cAAc,EAAE,CACvF;IACD,aAAa,CACX,gEAAgE;QAC9D,YAAY,cAAc,OAAO,cAAc,EAAE,CACpD;IACD,aAAa,CAAC,2CAA2C,cAAc,EAAE,CAAC;CAC3E,CAAA;AAED,uEAAuE;AACvE,MAAM,CAAC,MAAM,qBAAqB,GAAgC;IAChE,GAAG,iBAAiB;IACpB,GAAG,wBAAwB;CAC5B,CAAA"}
1
+ {"version":3,"file":"eslint-security.js","sourceRoot":"","sources":["../src/eslint-security.ts"],"names":[],"mappings":"AAYA,MAAM,cAAc,GAAW,oEAAoE,CAAA;AAEnG,MAAM,YAAY,GAChB,gDAAgD;IAChD,gCAAgC;IAChC,gEAAgE,CAAA;AAElE,MAAM,qBAAqB,GACzB,8FAA8F;IAC9F,iDAAiD,CAAA;AAEnD,MAAM,YAAY,GAAG,CAAC,MAAc,EAAoB,EAAE,CAAC,CAAC;IAC1D,QAAQ,EAAE,GAAG,YAAY,GAAG,MAAM,EAAE;IACpC,OAAO,EAAE,qBAAqB;CAC/B,CAAC,CAAA;AAEF,MAAM,iBAAiB,GAAgC;IACrD,YAAY,CAAC,sBAAsB,cAAc,GAAG,CAAC;IACrD,YAAY,CAAC,qCAAqC,cAAc,GAAG,CAAC;IACpE,YAAY,CAAC,qDAAqD,cAAc,GAAG,CAAC;IACpF,YAAY,CAAC,sCAAsC,cAAc,GAAG,CAAC;IACrE,YAAY,CAAC,qDAAqD,cAAc,GAAG,CAAC;IACpF,YAAY,CAAC,uCAAuC,cAAc,GAAG,CAAC;IACtE,YAAY,CAAC,sDAAsD,cAAc,GAAG,CAAC;IACrF,YAAY,CAAC,kEAAkE,cAAc,GAAG,CAAC;IACjG,YAAY,CAAC,iEAAiE,cAAc,GAAG,CAAC;CACjG,CAAA;AAED,MAAM,cAAc,GAClB,gGAAgG,CAAA;AAElG,MAAM,cAAc,GAAW,qFAAqF,CAAA;AAEpH,MAAM,aAAa,GACjB,gDAAgD;IAChD,oDAAoD;IACpD,+BAA+B,CAAA;AAEjC,MAAM,sBAAsB,GAC1B,6FAA6F;IAC7F,wEAAwE,CAAA;AAE1E,MAAM,aAAa,GAAG,CAAC,QAAgB,EAAoB,EAAE,CAAC,CAAC;IAC7D,QAAQ;IACR,OAAO,EAAE,sBAAsB;CAChC,CAAC,CAAA;AAEF,MAAM,wBAAwB,GAAgC;IAC5D,aAAa,CAAC,GAAG,aAAa,kCAAkC,cAAc,OAAO,cAAc,EAAE,CAAC;IACtG,aAAa,CAAC,GAAG,aAAa,MAAM,cAAc,EAAE,CAAC;IACrD,aAAa,CAAC,iDAAiD,cAAc,OAAO,cAAc,EAAE,CAAC;IACrG,aAAa,CACX,gEAAgE;QAC9D,YAAY,cAAc,OAAO,cAAc,EAAE,CACpD;IACD,aAAa,CAAC,2CAA2C,cAAc,EAAE,CAAC;CAC3E,CAAA;AAED,uEAAuE;AACvE,MAAM,CAAC,MAAM,qBAAqB,GAAgC,CAAC,GAAG,iBAAiB,EAAE,GAAG,wBAAwB,CAAC,CAAA"}
package/dist/eslint.d.ts CHANGED
@@ -1,3 +1,6 @@
1
- declare const _default: import("eslint/config").ConfigObject[];
2
- export default _default;
1
+ import { compose } from './eslint-core.js';
2
+ /** The assertion helpers `ploaness/a11y` ships, each of which fails the test it runs in on a finding. */
3
+ export declare const E2E_ASSERTION_HELPERS: readonly string[];
4
+ declare const config: ReturnType<typeof compose>;
5
+ export default config;
3
6
  //# sourceMappingURL=eslint.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"eslint.d.ts","sourceRoot":"","sources":["../src/eslint.ts"],"names":[],"mappings":";AAqEA,wBA2TC"}
1
+ {"version":3,"file":"eslint.d.ts","sourceRoot":"","sources":["../src/eslint.ts"],"names":[],"mappings":"AAsBA,OAAO,EAEL,OAAO,EAiBR,MAAM,kBAAkB,CAAA;AAOzB,yGAAyG;AACzG,eAAO,MAAM,qBAAqB,EAAE,SAAS,MAAM,EAIlD,CAAA;AAoBD,QAAA,MAAM,MAAM,EAAE,UAAU,CAAC,OAAO,OAAO,CAuUtC,CAAA;AAED,eAAe,MAAM,CAAA"}
package/dist/eslint.js CHANGED
@@ -11,18 +11,25 @@
11
11
  // Philosophy: maximum-explicit. The build should be hard to satisfy by accident, so that code which
12
12
  // passes is verbose, explicit and readable by construction.
13
13
  import nextPlugin from '@next/eslint-plugin-next';
14
- import { APPLICATION_JSX_IGNORES, ENVIRONMENT_READ_EXEMPTIONS, REEXPORT_CONFIG_FILES, } from '@ploaness/governance';
14
+ import { APPLICATION_JSX_IGNORES, ENVIRONMENT_READ_EXEMPTIONS, REEXPORT_CONFIG_FILES } from '@ploaness/governance';
15
15
  //
16
16
  // The framework-neutral half - the caps, the explicitness rules, the naming ban, the suppression
17
17
  // discipline, the mock ban - lives in ./eslint-core.js and is shared with the ploaness repository's own
18
18
  // lint run. What stays here is what is genuinely about Payload and Next: the generated mount, the
19
19
  // collection configs, the environment module, the a11y layer, and the test-integrity block.
20
+ import playwright from 'eslint-plugin-playwright';
20
21
  import testingLibrary from 'eslint-plugin-testing-library';
21
22
  import { baseLayers, compose, guidelineRules, hookContextBlock, immutabilityBlock, NO_INHERITANCE, NO_MOCK_PROPERTIES, NO_NETWORK_GUARD_ESCAPE, prettierLast, processConfigBlock, specEnvironmentBlock, testIdiomRules, testIntegrityRules, testSuiteSyntaxRules, typeAwareParsing, vitestPlugin, withoutWarnings, } from './eslint-core.js';
22
23
  import { SECURITY_RESTRICTIONS } from './eslint-security.js';
23
24
  import { projectSettings as settings } from './project-settings.js';
24
25
  // Where a Payload project writes its hooks, and therefore the one place `req.context` is written.
25
26
  const PAYLOAD_HOOK_FILES = ['src/hooks/**'];
27
+ /** The assertion helpers `ploaness/a11y` ships, each of which fails the test it runs in on a finding. */
28
+ export const E2E_ASSERTION_HELPERS = [
29
+ 'expectSweptPage',
30
+ 'expectNoLayoutDefects',
31
+ 'expectNoAxeDefects',
32
+ ];
26
33
  const NO_INLINE_CONFIG_FUNCTIONS_SELECTOR = 'ArrowFunctionExpression, FunctionExpression';
27
34
  const NO_INLINE_CONFIG_FUNCTIONS_MESSAGE = 'No inline functions in collection/global/field/block configs. Define access and pure rules in ' +
28
35
  'src/access or src/lib, where the unit suite covers them, and a hook or validator that needs the ' +
@@ -38,7 +45,7 @@ const reexportConfigBlock = {
38
45
  files: [...REEXPORT_CONFIG_FILES],
39
46
  rules: { 'unicorn/prefer-export-from': 'off' },
40
47
  };
41
- export default compose(
48
+ const config = compose(
42
49
  // ── What is never linted ────────────────────────────────────────────────────────────────────
43
50
  {
44
51
  ignores: [
@@ -65,6 +72,11 @@ export default compose(
65
72
  }, ...baseLayers,
66
73
  // Type-aware parsing against the consuming project's own tsconfig, plus the shared rule set.
67
74
  typeAwareParsing({ projectService: true }), { rules: guidelineRules },
75
+ // Payload consumes an eagerly built configuration. Its boot-time write policy belongs to payload-rules.
76
+ {
77
+ files: ['src/payload.config.ts'],
78
+ rules: { 'unicorn/no-top-level-side-effects': 'off' },
79
+ },
68
80
  // Immutability: every hand-written TypeScript, with the framework's own scaffolding exempt by role.
69
81
  // The role is declarable rather than a fixed path, because a project that mounts its framework
70
82
  // elsewhere has the same generated files under a name ploaness cannot guess.
@@ -186,12 +198,7 @@ hookContextBlock(PAYLOAD_HOOK_FILES),
186
198
  // the like) into src/access or src/lib, where unit tests cover it, and import it by reference.
187
199
  // Scoped by directory so a new config folder is governed automatically.
188
200
  {
189
- files: [
190
- 'src/collections/**/*.ts',
191
- 'src/globals/**/*.ts',
192
- 'src/fields/**/*.ts',
193
- 'src/blocks/**/*.ts',
194
- ],
201
+ files: ['src/collections/**/*.ts', 'src/globals/**/*.ts', 'src/fields/**/*.ts', 'src/blocks/**/*.ts'],
195
202
  rules: {
196
203
  'no-restricted-syntax': [
197
204
  ...NO_INHERITANCE,
@@ -313,16 +320,28 @@ hookContextBlock(PAYLOAD_HOOK_FILES),
313
320
  // Playwright has its own runner, but a spec body can still create an unguarded Node transport before
314
321
  // it asks the browser to do anything. The Vitest-specific integrity rules do not fit here; the network
315
322
  // escape ban does, and carries the same selectors rather than a second list.
323
+ //
324
+ // Every test must still assert. `sonarjs/assertions-in-tests` decided that by reading the body of the
325
+ // function a test calls, and ploaness ships its sweep helpers as declarations with no body, so a test
326
+ // whose one check is `expectSweptPage(page)` - the form the guide teaches - was reported as asserting
327
+ // nothing. Playwright's own rule takes the helpers by name instead: the three this harness ships, and a
328
+ // project's own helper named `expect` followed by a capital, the convention those three follow.
316
329
  {
317
330
  files: ['tests/e2e/**/*.ts', 'tests/e2e/**/*.tsx'],
331
+ plugins: { playwright },
318
332
  rules: {
319
- 'no-restricted-syntax': [
320
- ...NO_INHERITANCE,
321
- ...SECURITY_RESTRICTIONS,
322
- ...NO_NETWORK_GUARD_ESCAPE,
333
+ 'no-restricted-syntax': [...NO_INHERITANCE, ...SECURITY_RESTRICTIONS, ...NO_NETWORK_GUARD_ESCAPE],
334
+ 'sonarjs/assertions-in-tests': 'off',
335
+ 'playwright/expect-expect': [
336
+ 'error',
337
+ {
338
+ assertFunctionNames: [...E2E_ASSERTION_HELPERS],
339
+ assertFunctionPatterns: ['^expect[A-Z]'],
340
+ },
323
341
  ],
324
342
  },
325
343
  },
326
344
  // ── Formatting is Biome's job - disable every conflicting stylistic rule (must stay last) ────
327
345
  reexportConfigBlock, prettierLast);
346
+ export default config;
328
347
  //# sourceMappingURL=eslint.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"eslint.js","sourceRoot":"","sources":["../src/eslint.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"eslint.js","sourceRoot":"","sources":["../src/eslint.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,23 @@
1
+ import { type Page } from '@playwright/test';
2
+ import { type LayoutViewport } from '@ploaness/governance';
3
+ /** The viewports every layout scan runs at, the harness's own first. */
4
+ export declare const LAYOUT_SCAN_VIEWPORTS: readonly LayoutViewport[];
5
+ /**
6
+ * Measure the page as it stands at every required viewport, and report what is wrong with its layout.
7
+ *
8
+ * The page is resized in place rather than reloaded, so whatever state a spec drove it into - a
9
+ * signed-in view, an open dialog - is what gets measured. Its viewport is restored afterwards.
10
+ * @param page the page to measure, already on the route and in the state to judge.
11
+ * @returns one line per layout defect, empty when there is none.
12
+ */
13
+ export declare const layoutDefectsOf: (page: Page) => Promise<readonly string[]>;
14
+ /**
15
+ * Fail the calling test when the page has a layout defect at any required viewport.
16
+ *
17
+ * Call it in a project's own specification for a page the sweep cannot reach - one behind a sign-in,
18
+ * or one whose address exists only once a record does - after driving the page into the state to judge.
19
+ * @param page the page to measure.
20
+ * @returns nothing; it fails the test with one line per defect.
21
+ */
22
+ export declare const expectNoLayoutDefects: (page: Page) => Promise<void>;
23
+ //# sourceMappingURL=layout.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"layout.d.ts","sourceRoot":"","sources":["../src/layout.ts"],"names":[],"mappings":"AAYA,OAAO,EAAU,KAAK,IAAI,EAAE,MAAM,kBAAkB,CAAA;AACpD,OAAO,EAOL,KAAK,cAAc,EAEpB,MAAM,sBAAsB,CAAA;AAI7B,wEAAwE;AACxE,eAAO,MAAM,qBAAqB,EAAE,SAAS,cAAc,EAAyD,CAAA;AA6OpH;;;;;;;GAOG;AACH,eAAO,MAAM,eAAe,GAAU,MAAM,IAAI,KAAG,OAAO,CAAC,SAAS,MAAM,EAAE,CAa3E,CAAA;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,qBAAqB,GAAU,MAAM,IAAI,KAAG,OAAO,CAAC,IAAI,CAEpE,CAAA"}
package/dist/layout.js ADDED
@@ -0,0 +1,185 @@
1
+ // The layout scan's measurement: what a page reports about its own geometry, and the call that judges it.
2
+ //
3
+ // Every rule lives in `@ploaness/governance`, which judges a plain snapshot. This module is the one piece
4
+ // that has to run inside the browser, and the one place the harness's viewports and the project's
5
+ // stricter settings meet a page.
6
+ //
7
+ // WHY THE PAGE CODE IS ASSEMBLED FROM SOURCE TEXT. Playwright ships a page function to the browser as
8
+ // its own source, so it can reach nothing at module scope. One function holding the whole measurement
9
+ // would pass the callable cap several times over. Each step is therefore a top-level function of its
10
+ // own, and `IN_PAGE_SOURCE` joins their texts into one expression that hands each step the others as
11
+ // `tools`. A step names another only through that parameter, never directly, because in the page no
12
+ // other binding exists.
13
+ import { expect } from '@playwright/test';
14
+ import { findLayoutDefects, layoutViewportsWith, } from '@ploaness/governance';
15
+ import { projectSettings } from './project-settings.js';
16
+ import { settleForScan } from './settle.js';
17
+ /** The viewports every layout scan runs at, the harness's own first. */
18
+ export const LAYOUT_SCAN_VIEWPORTS = layoutViewportsWith(projectSettings.layoutViewports);
19
+ const isClosedDetails = (element) => element.tagName.toLowerCase() === 'details' && element.getAttribute('open') === null;
20
+ // The first direct summary stays visible. Every other branch of a closed disclosure is unpainted,
21
+ // even when an inner disclosure is open or a browser reports nonempty rectangles for its text.
22
+ const isHiddenByDisclosure = (element, tools) => {
23
+ const parent = element.parentElement;
24
+ if (parent === null) {
25
+ return false;
26
+ }
27
+ const isClosedBody = tools.isClosedDetails(parent) && parent.querySelector(':scope > summary') !== element;
28
+ return isClosedBody || tools.isHiddenByDisclosure(parent, tools);
29
+ };
30
+ const roundRects = (rects) => Array.from(rects, (rect) => ({
31
+ left: Math.round(rect.left + scrollX),
32
+ top: Math.round(rect.top + scrollY),
33
+ right: Math.round(rect.right + scrollX),
34
+ bottom: Math.round(rect.bottom + scrollY),
35
+ }));
36
+ const ownText = (element, tools) => {
37
+ if (tools.isClosedDetails(element)) {
38
+ return [];
39
+ }
40
+ const textNodeType = 3;
41
+ return Array.from(element.childNodes).filter((child) => child.nodeType === textNodeType && (child.textContent ?? '').trim().length > 0);
42
+ };
43
+ const ownTextRects = (element, tools) => tools.ownText(element, tools).flatMap((text) => {
44
+ const range = document.createRange();
45
+ range.selectNodeContents(text);
46
+ return tools.roundRects(range.getClientRects());
47
+ });
48
+ const bordersOf = (style) => {
49
+ const side = (name) => ({
50
+ // A computed border width is always a pixel length, `0px` for a side drawn with no border.
51
+ width: Number(style.getPropertyValue(`border-${name}-width`).replace('px', '')),
52
+ style: style.getPropertyValue(`border-${name}-style`),
53
+ color: style.getPropertyValue(`border-${name}-color`),
54
+ });
55
+ return { top: side('top'), right: side('right'), bottom: side('bottom'), left: side('left') };
56
+ };
57
+ // `normal` reads as NaN, which the rules take as 0: no line height to shrink a text rect to.
58
+ const lineHeightOf = (style) => {
59
+ const lineHeight = Number(style.getPropertyValue('line-height').replace('px', ''));
60
+ return Number.isFinite(lineHeight) ? lineHeight : 0;
61
+ };
62
+ // A tag, then the id or the first two classes, then the element's own text: `a.button "Sign in"`.
63
+ const labelOf = (element, tools) => {
64
+ const maxClasses = 2;
65
+ const maxText = 40;
66
+ const tag = element.tagName.toLowerCase();
67
+ const name = element.id.length > 0
68
+ ? `#${element.id}`
69
+ : Array.from(element.classList)
70
+ .slice(0, maxClasses)
71
+ .map((className) => `.${className}`)
72
+ .join('');
73
+ const text = tools
74
+ .ownText(element, tools)
75
+ .map((node) => node.textContent ?? '')
76
+ .join(' ')
77
+ .replaceAll(/\s+/gu, ' ')
78
+ .trim();
79
+ return text.length === 0 ? `${tag}${name}` : `${tag}${name} "${text.slice(0, maxText)}"`;
80
+ };
81
+ const describe = (element, index, parent, tools) => {
82
+ const style = getComputedStyle(element);
83
+ const read = (property) => style.getPropertyValue(property);
84
+ const isClipping = ['hidden', 'clip'].some((value) => [read('overflow-x'), read('overflow-y')].includes(value));
85
+ return {
86
+ index,
87
+ parent,
88
+ label: tools.labelOf(element, tools),
89
+ tag: element.tagName.toLowerCase(),
90
+ rects: tools.roundRects(element.getClientRects()),
91
+ textRects: tools.ownTextRects(element, tools),
92
+ lineHeight: tools.lineHeightOf(style),
93
+ text: isClipping ? (element.textContent ?? '').trim() : '',
94
+ display: read('display'),
95
+ visibility: read('visibility'),
96
+ position: read('position'),
97
+ backgroundColor: read('background-color'),
98
+ backgroundImage: read('background-image'),
99
+ boxShadow: read('box-shadow'),
100
+ borders: tools.bordersOf(style),
101
+ isAriaHidden: element.getAttribute('aria-hidden') === 'true',
102
+ isClipped: read('clip-path') !== 'none' || !['auto', ''].includes(read('clip')),
103
+ overflowX: read('overflow-x'),
104
+ overflowY: read('overflow-y'),
105
+ textOverflow: read('text-overflow'),
106
+ lineClamp: read('-webkit-line-clamp'),
107
+ scrollWidth: element.scrollWidth,
108
+ clientWidth: element.clientWidth,
109
+ scrollHeight: element.scrollHeight,
110
+ clientHeight: element.clientHeight,
111
+ title: element.getAttribute('title') ?? '',
112
+ ariaLabel: element.getAttribute('aria-label') ?? '',
113
+ exemption: element.getAttribute('data-ploaness-layout') ?? undefined,
114
+ exemptionReason: (element.getAttribute('data-ploaness-layout-reason') ?? '').trim(),
115
+ };
116
+ };
117
+ // The element list in document order, from `<body>` down. An SVG's own drawing is not layout: the
118
+ // `<svg>` element is measured and what it draws inside is not.
119
+ const measureDocument = (tools) => {
120
+ const svgNamespace = 'http://www.w3.org/2000/svg';
121
+ const elements = [document.body, ...Array.from(document.body.querySelectorAll('*'))].filter((element) => (element.namespaceURI !== svgNamespace || element.parentElement?.namespaceURI !== svgNamespace) &&
122
+ !tools.isHiddenByDisclosure(element, tools));
123
+ const positions = new Map(elements.map((element, index) => [element, index]));
124
+ const root = document.documentElement;
125
+ return {
126
+ viewportWidth: root.clientWidth,
127
+ viewportHeight: root.clientHeight,
128
+ scrollWidth: root.scrollWidth,
129
+ rootBackground: getComputedStyle(root).getPropertyValue('background-color'),
130
+ nodes: elements.map((element, index) => {
131
+ const parent = element.parentElement;
132
+ const parentIndex = parent === null ? -1 : (positions.get(parent) ?? -1);
133
+ return tools.describe(element, index, index === 0 ? -1 : parentIndex, tools);
134
+ }),
135
+ };
136
+ };
137
+ const STEPS = {
138
+ isClosedDetails,
139
+ isHiddenByDisclosure,
140
+ roundRects,
141
+ ownText,
142
+ ownTextRects,
143
+ bordersOf,
144
+ lineHeightOf,
145
+ labelOf,
146
+ describe,
147
+ };
148
+ const IN_PAGE_SOURCE = `(${String(measureDocument)})({${Object.entries(STEPS)
149
+ .map(([name, step]) => `${name}: ${String(step)}`)
150
+ .join(', ')}})`;
151
+ const routeOf = (page) => new URL(page.url()).pathname;
152
+ const measureAt = async (page, viewport) => {
153
+ await page.setViewportSize(viewport);
154
+ await settleForScan(page);
155
+ const measured = await page.evaluate(IN_PAGE_SOURCE);
156
+ return { ...measured, route: routeOf(page) };
157
+ };
158
+ /**
159
+ * Measure the page as it stands at every required viewport, and report what is wrong with its layout.
160
+ *
161
+ * The page is resized in place rather than reloaded, so whatever state a spec drove it into - a
162
+ * signed-in view, an open dialog - is what gets measured. Its viewport is restored afterwards.
163
+ * @param page the page to measure, already on the route and in the state to judge.
164
+ * @returns one line per layout defect, empty when there is none.
165
+ */
166
+ export const layoutDefectsOf = async (page) => {
167
+ const original = page.viewportSize();
168
+ const snapshots = await LAYOUT_SCAN_VIEWPORTS.reduce(async (measured, viewport) => [...(await measured), await measureAt(page, viewport)], Promise.resolve([]));
169
+ if (original !== null) {
170
+ await page.setViewportSize(original);
171
+ }
172
+ return findLayoutDefects(snapshots, projectSettings.layoutMinimumGap);
173
+ };
174
+ /**
175
+ * Fail the calling test when the page has a layout defect at any required viewport.
176
+ *
177
+ * Call it in a project's own specification for a page the sweep cannot reach - one behind a sign-in,
178
+ * or one whose address exists only once a record does - after driving the page into the state to judge.
179
+ * @param page the page to measure.
180
+ * @returns nothing; it fails the test with one line per defect.
181
+ */
182
+ export const expectNoLayoutDefects = async (page) => {
183
+ expect(await layoutDefectsOf(page), `layout defects on ${routeOf(page)}`).toEqual([]);
184
+ };
185
+ //# sourceMappingURL=layout.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"layout.js","sourceRoot":"","sources":["../src/layout.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"playwright.d.ts","sourceRoot":"","sources":["../src/playwright.ts"],"names":[],"mappings":"AAsHA,QAAA,MAAM,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAmB,CAAA;AAEjE,eAAe,MAAM,CAAA"}
1
+ {"version":3,"file":"playwright.d.ts","sourceRoot":"","sources":["../src/playwright.ts"],"names":[],"mappings":"AAwIA,QAAA,MAAM,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAmB,CAAA;AAEjE,eAAe,MAAM,CAAA"}
@@ -10,8 +10,9 @@
10
10
  // file. Neither reaches a rule: they say where the application answers and what else has to be running,
11
11
  // and every threshold, ban and pinned spec above is the same whatever they say.
12
12
  import { existsSync } from 'node:fs';
13
+ import { fileURLToPath } from 'node:url';
13
14
  import { defineConfig, devices } from '@playwright/test';
14
- import { portOf, runEnvironmentFiles } from '@ploaness/governance';
15
+ import { browserServerEndpoint, canReuseBrowserServer, portOf, runEnvironmentFiles, shellArgument, VERIFICATION_ENVIRONMENT_VARIABLE, } from '@ploaness/governance';
15
16
  import { projectSettings } from './project-settings.js';
16
17
  // Read before anything else, because a spec module is what needs it. Playwright evaluates this config
17
18
  // in the runner and again in every worker, which makes it the one place a value reaches both the pass
@@ -24,6 +25,9 @@ for (const file of runEnvironmentFiles(existsSync)) {
24
25
  process.loadEnvFile(file);
25
26
  }
26
27
  const isContinuousIntegration = Boolean(process.env['CI']);
28
+ const isReuseExistingServer = canReuseBrowserServer(process.env);
29
+ const isVerification = process.env[VERIFICATION_ENVIRONMENT_VARIABLE] !== undefined;
30
+ const productionLauncher = fileURLToPath(new URL('production-server.js', import.meta.url));
27
31
  // The web server is `next dev`, which compiles a route on its first request. The first hit to the heavy
28
32
  // Payload admin bundle can exceed the 30s Playwright default on a cold runner, so the budget gives
29
33
  // compilation headroom instead of leaning on a retry to mask it.
@@ -77,7 +81,7 @@ const declared = defineConfig({
77
81
  ...projectSettings.auxiliaryServers.map((server) => ({
78
82
  command: server.command,
79
83
  url: server.url,
80
- reuseExistingServer: !isContinuousIntegration,
84
+ reuseExistingServer: isReuseExistingServer,
81
85
  // The same budget and the same reuse rule as the application: an auxiliary server is started by
82
86
  // the same runner on the same cold machine, so a shorter one would fail for the reason that one
83
87
  // is long.
@@ -90,14 +94,21 @@ const declared = defineConfig({
90
94
  // spawned here inherits expectations from its parent that do not hold inside a test runner. The
91
95
  // name resolves out of the ambient PATH, which the package manager that started the run points at
92
96
  // this member's `node_modules/.bin` - which is the member under test, so it is the right one.
93
- command: 'next dev',
97
+ command: isVerification ? `${shellArgument(process.execPath)} ${shellArgument(productionLauncher)}` : 'next dev',
94
98
  url: projectSettings.serverUrl,
95
- reuseExistingServer: !isContinuousIntegration,
99
+ reuseExistingServer: isReuseExistingServer,
96
100
  timeout: SERVER_TIMEOUT_MS,
97
101
  // The port comes from the declared origin. Without it the server started on the framework's
98
102
  // default while the runner waited on the origin the project declared, so the one setting that
99
103
  // exists to describe a non-default port made the run hang instead of work.
100
- env: withPort({ NEXT_TELEMETRY_DISABLED: '1', NODE_OPTIONS: '--no-deprecation' }, declaredPort),
104
+ env: withPort({
105
+ NEXT_TELEMETRY_DISABLED: '1',
106
+ NODE_OPTIONS: '--no-deprecation',
107
+ ...(isVerification && {
108
+ NODE_ENV: 'production',
109
+ HOSTNAME: browserServerEndpoint(projectSettings.serverUrl).host,
110
+ }),
111
+ }, declaredPort),
101
112
  },
102
113
  ],
103
114
  });
@@ -1 +1 @@
1
- {"version":3,"file":"playwright.js","sourceRoot":"","sources":["../src/playwright.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"playwright.js","sourceRoot":"","sources":["../src/playwright.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=production-server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"production-server.d.ts","sourceRoot":"","sources":["../src/production-server.ts"],"names":[],"mappings":""}
@@ -0,0 +1,63 @@
1
+ // The verified browser suite starts the production artifact using the application's own Next install.
2
+ import { spawn } from 'node:child_process';
3
+ import { cpSync, existsSync, readFileSync } from 'node:fs';
4
+ import { createRequire } from 'node:module';
5
+ import path from 'node:path';
6
+ import { pathToFileURL } from 'node:url';
7
+ import { productionOutputOf, readKey } from '@ploaness/governance';
8
+ const isLoader = (value) => typeof value === 'function';
9
+ const root = process.cwd();
10
+ const requireProject = createRequire(path.join(root, 'package.json'));
11
+ const loadModule = requireProject('next/dist/server/config.js');
12
+ const load = readKey(loadModule, 'default');
13
+ if (!isLoader(load)) {
14
+ throw new TypeError('the installed Next configuration loader is unavailable');
15
+ }
16
+ const config = await load('phase-production-server', root);
17
+ const distributionDirectory = readKey(config, 'distDir');
18
+ if (typeof distributionDirectory !== 'string' || readKey(config, 'output') === 'export') {
19
+ throw new TypeError('production browser verification needs Next server output; static export is unsupported');
20
+ }
21
+ const directory = path.resolve(root, distributionDirectory);
22
+ if (!(existsSync(path.join(directory, 'BUILD_ID')) && existsSync(path.join(directory, 'required-server-files.json')))) {
23
+ throw new Error(`production output is missing under ${directory}; run ploaness gate e2e to rebuild and verify`);
24
+ }
25
+ const manifest = JSON.parse(readFileSync(path.join(directory, 'required-server-files.json'), 'utf8'));
26
+ const output = productionOutputOf(manifest);
27
+ const standaloneRoot = path.join(directory, 'standalone', output.relativeAppDir);
28
+ const copyAssets = () => {
29
+ for (const [source, destination] of [
30
+ [path.join(root, 'public'), path.join(standaloneRoot, 'public')],
31
+ [path.join(directory, 'static'), path.join(standaloneRoot, output.distDir, 'static')],
32
+ ]) {
33
+ if (existsSync(source)) {
34
+ cpSync(source, destination, { recursive: true, force: true });
35
+ }
36
+ }
37
+ };
38
+ if (output.standalone) {
39
+ copyAssets();
40
+ await import(pathToFileURL(path.join(standaloneRoot, 'server.js')).href);
41
+ }
42
+ else {
43
+ const child = spawn(process.execPath, [requireProject.resolve('next/dist/bin/next'), 'start'], {
44
+ stdio: 'inherit',
45
+ env: { ...process.env, NODE_ENV: 'production' },
46
+ });
47
+ for (const signal of ['SIGINT', 'SIGTERM']) {
48
+ process.on(signal, () => {
49
+ child.kill(signal);
50
+ });
51
+ }
52
+ child.on('error', (error) => {
53
+ throw error;
54
+ });
55
+ child.on('exit', (code) => {
56
+ if (code === null) {
57
+ process.exitCode = 1;
58
+ return;
59
+ }
60
+ process.exitCode = code;
61
+ });
62
+ }
63
+ //# sourceMappingURL=production-server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"production-server.js","sourceRoot":"","sources":["../src/production-server.ts"],"names":[],"mappings":"AAAA,sGAAsG;AACtG,OAAO,EAAqB,KAAK,EAAE,MAAM,oBAAoB,CAAA;AAC7D,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAA;AAC1D,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAC3C,OAAO,IAAI,MAAM,WAAW,CAAA;AAC5B,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;AACxC,OAAO,EAAyB,kBAAkB,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAA;AAGzF,MAAM,QAAQ,GAAG,CAAC,KAAc,EAAyB,EAAE,CAAC,OAAO,KAAK,KAAK,UAAU,CAAA;AAEvF,MAAM,IAAI,GAAW,OAAO,CAAC,GAAG,EAAE,CAAA;AAClC,MAAM,cAAc,GAAmB,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,cAAc,CAAC,CAAC,CAAA;AACrF,MAAM,UAAU,GAAY,cAAc,CAAC,4BAA4B,CAAC,CAAA;AACxE,MAAM,IAAI,GAAY,OAAO,CAAC,UAAU,EAAE,SAAS,CAAC,CAAA;AACpD,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;IACpB,MAAM,IAAI,SAAS,CAAC,wDAAwD,CAAC,CAAA;AAC/E,CAAC;AACD,MAAM,MAAM,GAAY,MAAM,IAAI,CAAC,yBAAyB,EAAE,IAAI,CAAC,CAAA;AACnE,MAAM,qBAAqB,GAAY,OAAO,CAAC,MAAM,EAAE,SAAS,CAAC,CAAA;AACjE,IAAI,OAAO,qBAAqB,KAAK,QAAQ,IAAI,OAAO,CAAC,MAAM,EAAE,QAAQ,CAAC,KAAK,QAAQ,EAAE,CAAC;IACxF,MAAM,IAAI,SAAS,CAAC,wFAAwF,CAAC,CAAA;AAC/G,CAAC;AACD,MAAM,SAAS,GAAW,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,qBAAqB,CAAC,CAAA;AACnE,IAAI,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC,IAAI,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,4BAA4B,CAAC,CAAC,CAAC,EAAE,CAAC;IACtH,MAAM,IAAI,KAAK,CAAC,sCAAsC,SAAS,+CAA+C,CAAC,CAAA;AACjH,CAAC;AACD,MAAM,QAAQ,GAAY,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,4BAA4B,CAAC,EAAE,MAAM,CAAC,CAAC,CAAA;AAC9G,MAAM,MAAM,GAAqB,kBAAkB,CAAC,QAAQ,CAAC,CAAA;AAC7D,MAAM,cAAc,GAAW,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,YAAY,EAAE,MAAM,CAAC,cAAc,CAAC,CAAA;AAExF,MAAM,UAAU,GAAG,GAAS,EAAE;IAC5B,KAAK,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,IAAI;QAClC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,QAAQ,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE,QAAQ,CAAC,CAAC;QAChE,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,QAAQ,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE,MAAM,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;KAC7E,EAAE,CAAC;QACX,IAAI,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;YACvB,MAAM,CAAC,MAAM,EAAE,WAAW,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAA;QAC/D,CAAC;IACH,CAAC;AACH,CAAC,CAAA;AAED,IAAI,MAAM,CAAC,UAAU,EAAE,CAAC;IACtB,UAAU,EAAE,CAAA;IACZ,MAAM,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,CAAA;AAC1E,CAAC;KAAM,CAAC;IACN,MAAM,KAAK,GAAiB,KAAK,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC,cAAc,CAAC,OAAO,CAAC,oBAAoB,CAAC,EAAE,OAAO,CAAC,EAAE;QAC3G,KAAK,EAAE,SAAS;QAChB,GAAG,EAAE,EAAE,GAAG,OAAO,CAAC,GAAG,EAAE,QAAQ,EAAE,YAAY,EAAE;KAChD,CAAC,CAAA;IACF,KAAK,MAAM,MAAM,IAAI,CAAC,QAAQ,EAAE,SAAS,CAAU,EAAE,CAAC;QACpD,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE,GAAS,EAAE;YAC5B,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;QACpB,CAAC,CAAC,CAAA;IACJ,CAAC;IACD,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,KAAY,EAAQ,EAAE;QACvC,MAAM,KAAK,CAAA;IACb,CAAC,CAAC,CAAA;IACF,KAAK,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,IAAmB,EAAQ,EAAE;QAC7C,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;YAClB,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAA;YACpB,OAAM;QACR,CAAC;QACD,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAA;IACzB,CAAC,CAAC,CAAA;AACJ,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"project-settings.d.ts","sourceRoot":"","sources":["../src/project-settings.ts"],"names":[],"mappings":"AAGA,OAAO,EAIL,KAAK,QAAQ,EACd,MAAM,sBAAsB,CAAA;AA6C7B,eAAO,MAAM,eAAe,EAAE,QAAqC,CAAA"}
1
+ {"version":3,"file":"project-settings.d.ts","sourceRoot":"","sources":["../src/project-settings.ts"],"names":[],"mappings":"AAGA,OAAO,EAAmD,KAAK,QAAQ,EAAE,MAAM,sBAAsB,CAAA;AA6CrG,eAAO,MAAM,eAAe,EAAE,QAAqC,CAAA"}
@@ -1,7 +1,7 @@
1
1
  // Read the consumer's settings from the working directory, where its tools are invoked.
2
2
  import { readFileSync } from 'node:fs';
3
3
  import path from 'node:path';
4
- import { ploanessBlock, readMemberSettings, readSettings, } from '@ploaness/governance';
4
+ import { ploanessBlock, readMemberSettings, readSettings } from '@ploaness/governance';
5
5
  // A project whose package.json cannot be read gets the defaults, which are the strict end of every
6
6
  // setting. Failing to parse must never be the thing that loosens a threshold.
7
7
  // `unknown` rather than the parse's own `any`: `readSettings` narrows every field it reads, so handing
@@ -1 +1 @@
1
- {"version":3,"file":"project-settings.js","sourceRoot":"","sources":["../src/project-settings.ts"],"names":[],"mappings":"AAAA,wFAAwF;AACxF,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAA;AACtC,OAAO,IAAI,MAAM,WAAW,CAAA;AAC5B,OAAO,EACL,aAAa,EACb,kBAAkB,EAClB,YAAY,GAEb,MAAM,sBAAsB,CAAA;AAE7B,mGAAmG;AACnG,8EAA8E;AAC9E,uGAAuG;AACvG,yEAAyE;AACzE,MAAM,eAAe,GAAG,CAAC,SAAiB,EAAW,EAAE;IACrD,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,cAAc,CAAC,EAAE,MAAM,CAAC,CAAC,CAAA;IAC/E,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAA;IACX,CAAC;AACH,CAAC,CAAA;AAED,sGAAsG;AACtG,sGAAsG;AACtG,+FAA+F;AAC/F,MAAM,gBAAgB,GAAW,qBAAqB,CAAA;AAEtD,iGAAiG;AACjG,0FAA0F;AAC1F,MAAM,kBAAkB,GAAG,CAAC,SAAiB,EAAsB,EAAE;IACnE,MAAM,MAAM,GAAW,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,CAAA;IAC9C,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;QACzB,OAAO,SAAS,CAAA;IAClB,CAAC;IACD,IAAI,CAAC;QACH,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,gBAAgB,CAAC,EAAE,MAAM,CAAC,CAAA;QACzD,OAAO,MAAM,CAAA;IACf,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,kBAAkB,CAAC,MAAM,CAAC,CAAA;IACnC,CAAC;AACH,CAAC,CAAA;AAED,MAAM,WAAW,GAAG,CAAC,MAAc,EAAY,EAAE;IAC/C,MAAM,GAAG,GAAY,eAAe,CAAC,MAAM,CAAC,CAAA;IAC5C,MAAM,cAAc,GAAuB,kBAAkB,CAAC,MAAM,CAAC,CAAA;IACrE,IAAI,cAAc,KAAK,SAAS,EAAE,CAAC;QACjC,kGAAkG;QAClG,+EAA+E;QAC/E,OAAO,YAAY,CAAC,GAAG,CAAC,CAAA;IAC1B,CAAC;IACD,OAAO,kBAAkB,CAAC,aAAa,CAAC,eAAe,CAAC,cAAc,CAAC,CAAC,EAAE,aAAa,CAAC,GAAG,CAAC,CAAC,CAAA;AAC/F,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,eAAe,GAAa,WAAW,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAA"}
1
+ {"version":3,"file":"project-settings.js","sourceRoot":"","sources":["../src/project-settings.ts"],"names":[],"mappings":"AAAA,wFAAwF;AACxF,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAA;AACtC,OAAO,IAAI,MAAM,WAAW,CAAA;AAC5B,OAAO,EAAE,aAAa,EAAE,kBAAkB,EAAE,YAAY,EAAiB,MAAM,sBAAsB,CAAA;AAErG,mGAAmG;AACnG,8EAA8E;AAC9E,uGAAuG;AACvG,yEAAyE;AACzE,MAAM,eAAe,GAAG,CAAC,SAAiB,EAAW,EAAE;IACrD,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,cAAc,CAAC,EAAE,MAAM,CAAC,CAAC,CAAA;IAC/E,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAA;IACX,CAAC;AACH,CAAC,CAAA;AAED,sGAAsG;AACtG,sGAAsG;AACtG,+FAA+F;AAC/F,MAAM,gBAAgB,GAAW,qBAAqB,CAAA;AAEtD,iGAAiG;AACjG,0FAA0F;AAC1F,MAAM,kBAAkB,GAAG,CAAC,SAAiB,EAAsB,EAAE;IACnE,MAAM,MAAM,GAAW,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,CAAA;IAC9C,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;QACzB,OAAO,SAAS,CAAA;IAClB,CAAC;IACD,IAAI,CAAC;QACH,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,gBAAgB,CAAC,EAAE,MAAM,CAAC,CAAA;QACzD,OAAO,MAAM,CAAA;IACf,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,kBAAkB,CAAC,MAAM,CAAC,CAAA;IACnC,CAAC;AACH,CAAC,CAAA;AAED,MAAM,WAAW,GAAG,CAAC,MAAc,EAAY,EAAE;IAC/C,MAAM,GAAG,GAAY,eAAe,CAAC,MAAM,CAAC,CAAA;IAC5C,MAAM,cAAc,GAAuB,kBAAkB,CAAC,MAAM,CAAC,CAAA;IACrE,IAAI,cAAc,KAAK,SAAS,EAAE,CAAC;QACjC,kGAAkG;QAClG,+EAA+E;QAC/E,OAAO,YAAY,CAAC,GAAG,CAAC,CAAA;IAC1B,CAAC;IACD,OAAO,kBAAkB,CAAC,aAAa,CAAC,eAAe,CAAC,cAAc,CAAC,CAAC,EAAE,aAAa,CAAC,GAAG,CAAC,CAAC,CAAA;AAC/F,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,eAAe,GAAa,WAAW,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAA"}