@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.
- package/biome-core.json +9 -3
- package/biome.json +1 -1
- package/dependency-cruiser-core.json +1 -4
- package/dist/a11y.d.ts +24 -9
- package/dist/a11y.d.ts.map +1 -1
- package/dist/a11y.js +58 -143
- package/dist/a11y.js.map +1 -1
- package/dist/access.d.ts.map +1 -1
- package/dist/access.js.map +1 -1
- package/dist/eslint-core.d.ts.map +1 -1
- package/dist/eslint-core.js +32 -17
- package/dist/eslint-core.js.map +1 -1
- package/dist/eslint-library.d.ts +3 -2
- package/dist/eslint-library.d.ts.map +1 -1
- package/dist/eslint-library.js +2 -1
- package/dist/eslint-library.js.map +1 -1
- package/dist/eslint-security.d.ts.map +1 -1
- package/dist/eslint-security.js +2 -6
- package/dist/eslint-security.js.map +1 -1
- package/dist/eslint.d.ts +5 -2
- package/dist/eslint.d.ts.map +1 -1
- package/dist/eslint.js +31 -12
- package/dist/eslint.js.map +1 -1
- package/dist/layout.d.ts +23 -0
- package/dist/layout.d.ts.map +1 -0
- package/dist/layout.js +185 -0
- package/dist/layout.js.map +1 -0
- package/dist/playwright.d.ts.map +1 -1
- package/dist/playwright.js +16 -5
- package/dist/playwright.js.map +1 -1
- package/dist/production-server.d.ts +2 -0
- package/dist/production-server.d.ts.map +1 -0
- package/dist/production-server.js +63 -0
- package/dist/production-server.js.map +1 -0
- package/dist/project-settings.d.ts.map +1 -1
- package/dist/project-settings.js +1 -1
- package/dist/project-settings.js.map +1 -1
- package/dist/security.d.ts +8 -0
- package/dist/security.d.ts.map +1 -0
- package/dist/security.js +7 -0
- package/dist/security.js.map +1 -0
- package/dist/settle.d.ts +13 -0
- package/dist/settle.d.ts.map +1 -0
- package/dist/settle.js +136 -0
- package/dist/settle.js.map +1 -0
- package/dist/vitest-core.d.ts.map +1 -1
- package/dist/vitest-core.js.map +1 -1
- package/dist/vitest-library.d.ts.map +1 -1
- package/dist/vitest-library.js +1 -1
- package/dist/vitest-library.js.map +1 -1
- package/dist/vitest-setup.js +1 -6
- package/dist/vitest-setup.js.map +1 -1
- package/package.json +17 -12
- package/pins.json +5 -5
package/dist/eslint-library.js
CHANGED
|
@@ -21,7 +21,7 @@ const reexportConfigBlock = {
|
|
|
21
21
|
files: [...REEXPORT_CONFIG_FILES],
|
|
22
22
|
rules: { 'unicorn/prefer-export-from': 'off' },
|
|
23
23
|
};
|
|
24
|
-
|
|
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,
|
|
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;
|
|
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"}
|
package/dist/eslint-security.js
CHANGED
|
@@ -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,
|
|
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
|
-
|
|
2
|
-
|
|
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
|
package/dist/eslint.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"eslint.d.ts","sourceRoot":"","sources":["../src/eslint.ts"],"names":[],"mappings":";
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
321
|
-
|
|
322
|
-
|
|
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
|
package/dist/eslint.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"eslint.js","sourceRoot":"","sources":["../src/eslint.ts"],"names":[],"mappings":"AAAA,YAAY;AACZ,EAAE;AACF,iFAAiF;AACjF,EAAE;AACF,+FAA+F;AAC/F,gGAAgG;AAChG,mGAAmG;AACnG,0FAA0F;AAC1F,4FAA4F;AAC5F,EAAE;AACF,oGAAoG;AACpG,4DAA4D;AAE5D,OAAO,UAAU,MAAM,0BAA0B,CAAA;AACjD,OAAO,
|
|
1
|
+
{"version":3,"file":"eslint.js","sourceRoot":"","sources":["../src/eslint.ts"],"names":[],"mappings":"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"}
|
package/dist/layout.d.ts
ADDED
|
@@ -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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"}
|
package/dist/playwright.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"playwright.d.ts","sourceRoot":"","sources":["../src/playwright.ts"],"names":[],"mappings":"
|
|
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"}
|
package/dist/playwright.js
CHANGED
|
@@ -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:
|
|
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:
|
|
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({
|
|
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
|
});
|
package/dist/playwright.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"playwright.js","sourceRoot":"","sources":["../src/playwright.ts"],"names":[],"mappings":"AAAA,wGAAwG;AACxG,yFAAyF;AACzF,EAAE;AACF,mGAAmG;AACnG,wGAAwG;AACxG,mHAAmH;AACnH,uGAAuG;AACvG,sGAAsG;AACtG,sGAAsG;AACtG,wGAAwG;AACxG,gFAAgF;AAChF,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAA;AACpC,OAAO,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAA;AACxD,OAAO,
|
|
1
|
+
{"version":3,"file":"playwright.js","sourceRoot":"","sources":["../src/playwright.ts"],"names":[],"mappings":"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"}
|
|
@@ -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":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"project-settings.d.ts","sourceRoot":"","sources":["../src/project-settings.ts"],"names":[],"mappings":"AAGA,OAAO,
|
|
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"}
|
package/dist/project-settings.js
CHANGED
|
@@ -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
|
|
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,
|
|
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"}
|