@se-studio/site-check 2.5.0 → 2.6.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 (45) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/dist/cms-integrity/article-link-integrity.d.ts +4 -0
  3. package/dist/cms-integrity/article-link-integrity.d.ts.map +1 -0
  4. package/dist/cms-integrity/article-link-integrity.js +8 -0
  5. package/dist/cms-integrity/article-link-integrity.js.map +1 -0
  6. package/dist/cms-integrity/evaluate-article-link-integrity.d.ts +11 -0
  7. package/dist/cms-integrity/evaluate-article-link-integrity.d.ts.map +1 -0
  8. package/dist/cms-integrity/evaluate-article-link-integrity.js +49 -0
  9. package/dist/cms-integrity/evaluate-article-link-integrity.js.map +1 -0
  10. package/dist/cms-integrity/fetch-article-links.d.ts +8 -0
  11. package/dist/cms-integrity/fetch-article-links.d.ts.map +1 -0
  12. package/dist/cms-integrity/fetch-article-links.js +27 -0
  13. package/dist/cms-integrity/fetch-article-links.js.map +1 -0
  14. package/dist/cms-integrity/index.d.ts +7 -0
  15. package/dist/cms-integrity/index.d.ts.map +1 -0
  16. package/dist/cms-integrity/index.js +6 -0
  17. package/dist/cms-integrity/index.js.map +1 -0
  18. package/dist/cms-integrity/report.d.ts +4 -0
  19. package/dist/cms-integrity/report.d.ts.map +1 -0
  20. package/dist/cms-integrity/report.js +42 -0
  21. package/dist/cms-integrity/report.js.map +1 -0
  22. package/dist/cms-integrity/routing-config.d.ts +3 -0
  23. package/dist/cms-integrity/routing-config.d.ts.map +1 -0
  24. package/dist/cms-integrity/routing-config.js +5 -0
  25. package/dist/cms-integrity/routing-config.js.map +1 -0
  26. package/dist/cms-integrity/types.d.ts +32 -0
  27. package/dist/cms-integrity/types.d.ts.map +1 -0
  28. package/dist/cms-integrity/types.js +2 -0
  29. package/dist/cms-integrity/types.js.map +1 -0
  30. package/dist/smoke-test/config.d.ts +4 -0
  31. package/dist/smoke-test/config.d.ts.map +1 -0
  32. package/dist/smoke-test/config.js +37 -0
  33. package/dist/smoke-test/config.js.map +1 -0
  34. package/dist/smoke-test/index.d.ts +4 -3
  35. package/dist/smoke-test/index.d.ts.map +1 -1
  36. package/dist/smoke-test/index.js +2 -1
  37. package/dist/smoke-test/index.js.map +1 -1
  38. package/dist/smoke-test/static.d.ts +11 -0
  39. package/dist/smoke-test/static.d.ts.map +1 -1
  40. package/dist/smoke-test/static.js +40 -13
  41. package/dist/smoke-test/static.js.map +1 -1
  42. package/dist/smoke-test/types.d.ts +3 -0
  43. package/dist/smoke-test/types.d.ts.map +1 -1
  44. package/package.json +12 -1
  45. package/smoke-test-one.mjs +48 -0
package/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # Changelog
2
2
 
3
+ ## 2.6.0
4
+
5
+ ### Minor Changes
6
+
7
+ - cdf1d3f: Add marketing-site URL calculator factory and `contentfulAllArticleLinksForIntegrity` for smoke CMS checks. Add opt-in `@se-studio/site-check/cms-integrity` module with parallel local smoke support via `cmsIntegrity` in `smoke.cases.json`.
8
+
9
+ ### Patch Changes
10
+
11
+ - Updated dependencies [cdf1d3f]
12
+ - @se-studio/contentful-rest-api@1.10.0
13
+ - @se-studio/core-data-types@1.5.1
14
+
3
15
  ## 2.5.0
4
16
 
5
17
  ### Minor Changes
@@ -0,0 +1,4 @@
1
+ import type { ArticleLinkIntegrityResult, ValidateArticleLinkIntegrityOptions } from './types.js';
2
+ export { evaluateArticleLinkIntegrity } from './evaluate-article-link-integrity.js';
3
+ export declare function validateArticleLinkIntegrity(options: ValidateArticleLinkIntegrityOptions): Promise<ArticleLinkIntegrityResult>;
4
+ //# sourceMappingURL=article-link-integrity.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"article-link-integrity.d.ts","sourceRoot":"","sources":["../../src/cms-integrity/article-link-integrity.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,0BAA0B,EAAE,mCAAmC,EAAE,MAAM,YAAY,CAAC;AAElG,OAAO,EAAE,4BAA4B,EAAE,MAAM,sCAAsC,CAAC;AAEpF,wBAAsB,4BAA4B,CAChD,OAAO,EAAE,mCAAmC,GAC3C,OAAO,CAAC,0BAA0B,CAAC,CAGrC"}
@@ -0,0 +1,8 @@
1
+ import { evaluateArticleLinkIntegrity } from './evaluate-article-link-integrity.js';
2
+ import { fetchArticleLinksForIntegrity } from './fetch-article-links.js';
3
+ export { evaluateArticleLinkIntegrity } from './evaluate-article-link-integrity.js';
4
+ export async function validateArticleLinkIntegrity(options) {
5
+ const response = await fetchArticleLinksForIntegrity(options);
6
+ return evaluateArticleLinkIntegrity(response.data, response.errors.length);
7
+ }
8
+ //# sourceMappingURL=article-link-integrity.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"article-link-integrity.js","sourceRoot":"","sources":["../../src/cms-integrity/article-link-integrity.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,4BAA4B,EAAE,MAAM,sCAAsC,CAAC;AACpF,OAAO,EAAE,6BAA6B,EAAE,MAAM,0BAA0B,CAAC;AAGzE,OAAO,EAAE,4BAA4B,EAAE,MAAM,sCAAsC,CAAC;AAEpF,MAAM,CAAC,KAAK,UAAU,4BAA4B,CAChD,OAA4C;IAE5C,MAAM,QAAQ,GAAG,MAAM,6BAA6B,CAAC,OAAO,CAAC,CAAC;IAC9D,OAAO,4BAA4B,CAAC,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;AAC7E,CAAC"}
@@ -0,0 +1,11 @@
1
+ import type { ArticleLinkIntegrityResult } from './types.js';
2
+ export interface ArticleLinkIntegrityInput {
3
+ id: string;
4
+ slug?: string | null;
5
+ href?: string | null;
6
+ externalLink?: string | null;
7
+ title?: string | null;
8
+ hasBodyContent?: boolean;
9
+ }
10
+ export declare function evaluateArticleLinkIntegrity(links: ArticleLinkIntegrityInput[], conversionErrorCount: number): ArticleLinkIntegrityResult;
11
+ //# sourceMappingURL=evaluate-article-link-integrity.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"evaluate-article-link-integrity.d.ts","sourceRoot":"","sources":["../../src/cms-integrity/evaluate-article-link-integrity.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,0BAA0B,EAA2B,MAAM,YAAY,CAAC;AAEtF,MAAM,WAAW,yBAAyB;IACxC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AAmBD,wBAAgB,4BAA4B,CAC1C,KAAK,EAAE,yBAAyB,EAAE,EAClC,oBAAoB,EAAE,MAAM,GAC3B,0BAA0B,CAmC5B"}
@@ -0,0 +1,49 @@
1
+ function isExternalHref(href) {
2
+ if (!href) {
3
+ return false;
4
+ }
5
+ return href.startsWith('http://') || href.startsWith('https://');
6
+ }
7
+ function toRow(link) {
8
+ return {
9
+ id: link.id,
10
+ slug: link.slug,
11
+ href: link.href,
12
+ externalLink: link.externalLink,
13
+ title: link.title,
14
+ };
15
+ }
16
+ export function evaluateArticleLinkIntegrity(links, conversionErrorCount) {
17
+ const broken = [];
18
+ const lightProfileHrefOverrides = [];
19
+ let withBodyContent = 0;
20
+ for (const link of links) {
21
+ if (link.hasBodyContent !== true) {
22
+ continue;
23
+ }
24
+ withBodyContent++;
25
+ if (!isExternalHref(link.href)) {
26
+ continue;
27
+ }
28
+ const row = toRow(link);
29
+ if (link.externalLink && link.href === link.externalLink) {
30
+ lightProfileHrefOverrides.push(row);
31
+ }
32
+ else {
33
+ broken.push(row);
34
+ }
35
+ }
36
+ return {
37
+ totalLinks: links.length,
38
+ withBodyContent,
39
+ missingFromLinkListCount: 0,
40
+ brokenHrefCount: broken.length,
41
+ lightProfileHrefOverrideCount: lightProfileHrefOverrides.length,
42
+ hasBodyContentFlagMismatchCount: 0,
43
+ conversionErrorCount,
44
+ missingFromLinkList: [],
45
+ broken,
46
+ lightProfileHrefOverrides,
47
+ };
48
+ }
49
+ //# sourceMappingURL=evaluate-article-link-integrity.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"evaluate-article-link-integrity.js","sourceRoot":"","sources":["../../src/cms-integrity/evaluate-article-link-integrity.ts"],"names":[],"mappings":"AAWA,SAAS,cAAc,CAAC,IAA+B;IACrD,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,OAAO,KAAK,CAAC;IACf,CAAC;IACD,OAAO,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC;AACnE,CAAC;AAED,SAAS,KAAK,CAAC,IAA+B;IAC5C,OAAO;QACL,EAAE,EAAE,IAAI,CAAC,EAAE;QACX,IAAI,EAAE,IAAI,CAAC,IAAI;QACf,IAAI,EAAE,IAAI,CAAC,IAAI;QACf,YAAY,EAAE,IAAI,CAAC,YAAY;QAC/B,KAAK,EAAE,IAAI,CAAC,KAAK;KAClB,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,4BAA4B,CAC1C,KAAkC,EAClC,oBAA4B;IAE5B,MAAM,MAAM,GAA8B,EAAE,CAAC;IAC7C,MAAM,yBAAyB,GAA8B,EAAE,CAAC;IAChE,IAAI,eAAe,GAAG,CAAC,CAAC;IAExB,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,IAAI,CAAC,cAAc,KAAK,IAAI,EAAE,CAAC;YACjC,SAAS;QACX,CAAC;QACD,eAAe,EAAE,CAAC;QAElB,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YAC/B,SAAS;QACX,CAAC;QAED,MAAM,GAAG,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC;QACxB,IAAI,IAAI,CAAC,YAAY,IAAI,IAAI,CAAC,IAAI,KAAK,IAAI,CAAC,YAAY,EAAE,CAAC;YACzD,yBAAyB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACtC,CAAC;aAAM,CAAC;YACN,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACnB,CAAC;IACH,CAAC;IAED,OAAO;QACL,UAAU,EAAE,KAAK,CAAC,MAAM;QACxB,eAAe;QACf,wBAAwB,EAAE,CAAC;QAC3B,eAAe,EAAE,MAAM,CAAC,MAAM;QAC9B,6BAA6B,EAAE,yBAAyB,CAAC,MAAM;QAC/D,+BAA+B,EAAE,CAAC;QAClC,oBAAoB;QACpB,mBAAmB,EAAE,EAAE;QACvB,MAAM;QACN,yBAAyB;KAC1B,CAAC;AACJ,CAAC"}
@@ -0,0 +1,8 @@
1
+ import { type CmsResponse, type IContentfulArticleLink, type MarketingSiteRoutingOptions } from '@se-studio/contentful-rest-api/cms-integrity';
2
+ export interface FetchArticleLinksForIntegrityOptions {
3
+ routing: MarketingSiteRoutingOptions;
4
+ preview?: boolean;
5
+ env?: NodeJS.ProcessEnv;
6
+ }
7
+ export declare function fetchArticleLinksForIntegrity(options: FetchArticleLinksForIntegrityOptions): Promise<CmsResponse<IContentfulArticleLink[]>>;
8
+ //# sourceMappingURL=fetch-article-links.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fetch-article-links.d.ts","sourceRoot":"","sources":["../../src/cms-integrity/fetch-article-links.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,WAAW,EAGhB,KAAK,sBAAsB,EAC3B,KAAK,2BAA2B,EACjC,MAAM,8CAA8C,CAAC;AAGtD,MAAM,WAAW,oCAAoC;IACnD,OAAO,EAAE,2BAA2B,CAAC;IACrC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;CACzB;AA0BD,wBAAsB,6BAA6B,CACjD,OAAO,EAAE,oCAAoC,GAC5C,OAAO,CAAC,WAAW,CAAC,sBAAsB,EAAE,CAAC,CAAC,CAMhD"}
@@ -0,0 +1,27 @@
1
+ import { contentfulAllArticleLinksForIntegrity, } from '@se-studio/contentful-rest-api/cms-integrity';
2
+ import { createIntegrityConverterContext } from './routing-config.js';
3
+ function resolveContentfulConfig(preview, env) {
4
+ const spaceId = env.CONTENTFUL_SPACE_ID;
5
+ const environment = env.CONTENTFUL_ENVIRONMENT || env.CONTENTFUL_ENVIRONMENT_NAME;
6
+ const accessToken = preview ? env.CONTENTFUL_PREVIEW_ACCESS_TOKEN : env.CONTENTFUL_ACCESS_TOKEN;
7
+ if (!spaceId) {
8
+ throw new Error('CONTENTFUL_SPACE_ID environment variable is required');
9
+ }
10
+ if (!accessToken) {
11
+ throw new Error(preview
12
+ ? 'CONTENTFUL_PREVIEW_ACCESS_TOKEN environment variable is required'
13
+ : 'CONTENTFUL_ACCESS_TOKEN environment variable is required');
14
+ }
15
+ if (!environment) {
16
+ throw new Error('CONTENTFUL_ENVIRONMENT or CONTENTFUL_ENVIRONMENT_NAME environment variable is required');
17
+ }
18
+ return { spaceId, accessToken, environment };
19
+ }
20
+ export async function fetchArticleLinksForIntegrity(options) {
21
+ const preview = options.preview ?? false;
22
+ const env = options.env ?? process.env;
23
+ const config = resolveContentfulConfig(preview, env);
24
+ const context = createIntegrityConverterContext(options.routing);
25
+ return await contentfulAllArticleLinksForIntegrity(context, config, { preview });
26
+ }
27
+ //# sourceMappingURL=fetch-article-links.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fetch-article-links.js","sourceRoot":"","sources":["../../src/cms-integrity/fetch-article-links.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,qCAAqC,GAGtC,MAAM,8CAA8C,CAAC;AACtD,OAAO,EAAE,+BAA+B,EAAE,MAAM,qBAAqB,CAAC;AAQtE,SAAS,uBAAuB,CAAC,OAAgB,EAAE,GAAsB;IACvE,MAAM,OAAO,GAAG,GAAG,CAAC,mBAAmB,CAAC;IACxC,MAAM,WAAW,GAAG,GAAG,CAAC,sBAAsB,IAAI,GAAG,CAAC,2BAA2B,CAAC;IAClF,MAAM,WAAW,GAAG,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,+BAA+B,CAAC,CAAC,CAAC,GAAG,CAAC,uBAAuB,CAAC;IAEhG,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CAAC,sDAAsD,CAAC,CAAC;IAC1E,CAAC;IACD,IAAI,CAAC,WAAW,EAAE,CAAC;QACjB,MAAM,IAAI,KAAK,CACb,OAAO;YACL,CAAC,CAAC,kEAAkE;YACpE,CAAC,CAAC,0DAA0D,CAC/D,CAAC;IACJ,CAAC;IACD,IAAI,CAAC,WAAW,EAAE,CAAC;QACjB,MAAM,IAAI,KAAK,CACb,wFAAwF,CACzF,CAAC;IACJ,CAAC;IAED,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,CAAC;AAC/C,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,6BAA6B,CACjD,OAA6C;IAE7C,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,IAAI,KAAK,CAAC;IACzC,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,CAAC;IACvC,MAAM,MAAM,GAAG,uBAAuB,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;IACrD,MAAM,OAAO,GAAG,+BAA+B,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;IACjE,OAAO,MAAM,qCAAqC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC;AACnF,CAAC"}
@@ -0,0 +1,7 @@
1
+ export { validateArticleLinkIntegrity } from './article-link-integrity.js';
2
+ export { evaluateArticleLinkIntegrity } from './evaluate-article-link-integrity.js';
3
+ export { fetchArticleLinksForIntegrity } from './fetch-article-links.js';
4
+ export { formatArticleLinkIntegrityReport, getArticleLinkIntegrityExitCode, } from './report.js';
5
+ export { createIntegrityConverterContext } from './routing-config.js';
6
+ export type { ArticleLinkIntegrityResult, ArticleLinkIntegrityRow, SmokeCmsIntegrityConfig, ValidateArticleLinkIntegrityOptions, } from './types.js';
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cms-integrity/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,4BAA4B,EAAE,MAAM,6BAA6B,CAAC;AAC3E,OAAO,EAAE,4BAA4B,EAAE,MAAM,sCAAsC,CAAC;AACpF,OAAO,EAAE,6BAA6B,EAAE,MAAM,0BAA0B,CAAC;AACzE,OAAO,EACL,gCAAgC,EAChC,+BAA+B,GAChC,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,+BAA+B,EAAE,MAAM,qBAAqB,CAAC;AACtE,YAAY,EACV,0BAA0B,EAC1B,uBAAuB,EACvB,uBAAuB,EACvB,mCAAmC,GACpC,MAAM,YAAY,CAAC"}
@@ -0,0 +1,6 @@
1
+ export { validateArticleLinkIntegrity } from './article-link-integrity.js';
2
+ export { evaluateArticleLinkIntegrity } from './evaluate-article-link-integrity.js';
3
+ export { fetchArticleLinksForIntegrity } from './fetch-article-links.js';
4
+ export { formatArticleLinkIntegrityReport, getArticleLinkIntegrityExitCode, } from './report.js';
5
+ export { createIntegrityConverterContext } from './routing-config.js';
6
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cms-integrity/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,4BAA4B,EAAE,MAAM,6BAA6B,CAAC;AAC3E,OAAO,EAAE,4BAA4B,EAAE,MAAM,sCAAsC,CAAC;AACpF,OAAO,EAAE,6BAA6B,EAAE,MAAM,0BAA0B,CAAC;AACzE,OAAO,EACL,gCAAgC,EAChC,+BAA+B,GAChC,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,+BAA+B,EAAE,MAAM,qBAAqB,CAAC"}
@@ -0,0 +1,4 @@
1
+ import type { ArticleLinkIntegrityResult } from './types.js';
2
+ export declare function getArticleLinkIntegrityExitCode(result: ArticleLinkIntegrityResult): number;
3
+ export declare function formatArticleLinkIntegrityReport(result: ArticleLinkIntegrityResult): string;
4
+ //# sourceMappingURL=report.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"report.d.ts","sourceRoot":"","sources":["../../src/cms-integrity/report.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,0BAA0B,EAA2B,MAAM,YAAY,CAAC;AAEtF,wBAAgB,+BAA+B,CAAC,MAAM,EAAE,0BAA0B,GAAG,MAAM,CAS1F;AAeD,wBAAgB,gCAAgC,CAAC,MAAM,EAAE,0BAA0B,GAAG,MAAM,CA8B3F"}
@@ -0,0 +1,42 @@
1
+ export function getArticleLinkIntegrityExitCode(result) {
2
+ if (result.missingFromLinkListCount > 0 ||
3
+ result.brokenHrefCount > 0 ||
4
+ result.conversionErrorCount > 0) {
5
+ return 1;
6
+ }
7
+ return 0;
8
+ }
9
+ function formatRows(label, rows) {
10
+ if (rows.length === 0) {
11
+ return [];
12
+ }
13
+ const lines = [` ${label}:`];
14
+ for (const row of rows) {
15
+ lines.push(` - ${row.id} slug=${row.slug ?? '(none)'} href=${row.href ?? '(none)'} externalLink=${row.externalLink ?? '(none)'} title=${row.title ?? '(none)'}`);
16
+ }
17
+ return lines;
18
+ }
19
+ export function formatArticleLinkIntegrityReport(result) {
20
+ const lines = [];
21
+ lines.push('## article-link-integrity');
22
+ lines.push(` total links: ${result.totalLinks}`);
23
+ lines.push(` articles with body content: ${result.withBodyContent}`);
24
+ lines.push(` conversion errors: ${result.conversionErrorCount}`);
25
+ lines.push(` hasBodyContent flag mismatch (expected under linkProfile light): ${result.hasBodyContentFlagMismatchCount}`);
26
+ lines.push(` missing from link list: ${result.missingFromLinkListCount}`);
27
+ lines.push(` light-profile href overrides (body + externalLink, expected): ${result.lightProfileHrefOverrideCount}`);
28
+ lines.push(` broken href: ${result.brokenHrefCount}`);
29
+ if (getArticleLinkIntegrityExitCode(result) === 0) {
30
+ lines.push(' article link integrity: ok');
31
+ }
32
+ else {
33
+ lines.push(' article link integrity: FAILED');
34
+ }
35
+ lines.push(...formatRows('missing', result.missingFromLinkList));
36
+ lines.push(...formatRows('broken', result.broken));
37
+ if (result.lightProfileHrefOverrideCount > 0) {
38
+ lines.push(` note: ${result.lightProfileHrefOverrideCount} webinar/video articles use external href under light profile; internal pages still exist (see smoke HTTP cases).`);
39
+ }
40
+ return lines.join('\n');
41
+ }
42
+ //# sourceMappingURL=report.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"report.js","sourceRoot":"","sources":["../../src/cms-integrity/report.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,+BAA+B,CAAC,MAAkC;IAChF,IACE,MAAM,CAAC,wBAAwB,GAAG,CAAC;QACnC,MAAM,CAAC,eAAe,GAAG,CAAC;QAC1B,MAAM,CAAC,oBAAoB,GAAG,CAAC,EAC/B,CAAC;QACD,OAAO,CAAC,CAAC;IACX,CAAC;IACD,OAAO,CAAC,CAAC;AACX,CAAC;AAED,SAAS,UAAU,CAAC,KAAa,EAAE,IAA+B;IAChE,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACtB,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,MAAM,KAAK,GAAG,CAAC,KAAK,KAAK,GAAG,CAAC,CAAC;IAC9B,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,KAAK,CAAC,IAAI,CACR,SAAS,GAAG,CAAC,EAAE,SAAS,GAAG,CAAC,IAAI,IAAI,QAAQ,SAAS,GAAG,CAAC,IAAI,IAAI,QAAQ,iBAAiB,GAAG,CAAC,YAAY,IAAI,QAAQ,UAAU,GAAG,CAAC,KAAK,IAAI,QAAQ,EAAE,CACxJ,CAAC;IACJ,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,UAAU,gCAAgC,CAAC,MAAkC;IACjF,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,KAAK,CAAC,IAAI,CAAC,2BAA2B,CAAC,CAAC;IACxC,KAAK,CAAC,IAAI,CAAC,kBAAkB,MAAM,CAAC,UAAU,EAAE,CAAC,CAAC;IAClD,KAAK,CAAC,IAAI,CAAC,iCAAiC,MAAM,CAAC,eAAe,EAAE,CAAC,CAAC;IACtE,KAAK,CAAC,IAAI,CAAC,wBAAwB,MAAM,CAAC,oBAAoB,EAAE,CAAC,CAAC;IAClE,KAAK,CAAC,IAAI,CACR,sEAAsE,MAAM,CAAC,+BAA+B,EAAE,CAC/G,CAAC;IACF,KAAK,CAAC,IAAI,CAAC,6BAA6B,MAAM,CAAC,wBAAwB,EAAE,CAAC,CAAC;IAC3E,KAAK,CAAC,IAAI,CACR,mEAAmE,MAAM,CAAC,6BAA6B,EAAE,CAC1G,CAAC;IACF,KAAK,CAAC,IAAI,CAAC,kBAAkB,MAAM,CAAC,eAAe,EAAE,CAAC,CAAC;IAEvD,IAAI,+BAA+B,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;QAClD,KAAK,CAAC,IAAI,CAAC,8BAA8B,CAAC,CAAC;IAC7C,CAAC;SAAM,CAAC;QACN,KAAK,CAAC,IAAI,CAAC,kCAAkC,CAAC,CAAC;IACjD,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,GAAG,UAAU,CAAC,SAAS,EAAE,MAAM,CAAC,mBAAmB,CAAC,CAAC,CAAC;IACjE,KAAK,CAAC,IAAI,CAAC,GAAG,UAAU,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC;IACnD,IAAI,MAAM,CAAC,6BAA6B,GAAG,CAAC,EAAE,CAAC;QAC7C,KAAK,CAAC,IAAI,CACR,WAAW,MAAM,CAAC,6BAA6B,mHAAmH,CACnK,CAAC;IACJ,CAAC;IAED,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC"}
@@ -0,0 +1,3 @@
1
+ import { type BaseConverterContext, type MarketingSiteRoutingOptions } from '@se-studio/contentful-rest-api/cms-integrity';
2
+ export declare function createIntegrityConverterContext(routing: MarketingSiteRoutingOptions): BaseConverterContext;
3
+ //# sourceMappingURL=routing-config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"routing-config.d.ts","sourceRoot":"","sources":["../../src/cms-integrity/routing-config.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,oBAAoB,EAGzB,KAAK,2BAA2B,EACjC,MAAM,8CAA8C,CAAC;AAEtD,wBAAgB,+BAA+B,CAC7C,OAAO,EAAE,2BAA2B,GACnC,oBAAoB,CAEtB"}
@@ -0,0 +1,5 @@
1
+ import { createBaseConverterContext, createMarketingSiteUrlCalculators, } from '@se-studio/contentful-rest-api/cms-integrity';
2
+ export function createIntegrityConverterContext(routing) {
3
+ return createBaseConverterContext(createMarketingSiteUrlCalculators(routing));
4
+ }
5
+ //# sourceMappingURL=routing-config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"routing-config.js","sourceRoot":"","sources":["../../src/cms-integrity/routing-config.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,0BAA0B,EAC1B,iCAAiC,GAElC,MAAM,8CAA8C,CAAC;AAEtD,MAAM,UAAU,+BAA+B,CAC7C,OAAoC;IAEpC,OAAO,0BAA0B,CAAC,iCAAiC,CAAC,OAAO,CAAC,CAAC,CAAC;AAChF,CAAC"}
@@ -0,0 +1,32 @@
1
+ import type { MarketingSiteRoutingOptions } from '@se-studio/contentful-rest-api/cms-integrity';
2
+ export interface SmokeCmsIntegrityConfig {
3
+ enabled: boolean;
4
+ routing: MarketingSiteRoutingOptions;
5
+ /** Use preview API (default false — delivery token only). */
6
+ preview?: boolean;
7
+ }
8
+ export interface ArticleLinkIntegrityRow {
9
+ id: string;
10
+ slug: string | null | undefined;
11
+ href: string | null | undefined;
12
+ externalLink: string | null | undefined;
13
+ title: string | null | undefined;
14
+ }
15
+ export interface ArticleLinkIntegrityResult {
16
+ totalLinks: number;
17
+ withBodyContent: number;
18
+ missingFromLinkListCount: number;
19
+ brokenHrefCount: number;
20
+ lightProfileHrefOverrideCount: number;
21
+ hasBodyContentFlagMismatchCount: number;
22
+ conversionErrorCount: number;
23
+ missingFromLinkList: ArticleLinkIntegrityRow[];
24
+ broken: ArticleLinkIntegrityRow[];
25
+ lightProfileHrefOverrides: ArticleLinkIntegrityRow[];
26
+ }
27
+ export interface ValidateArticleLinkIntegrityOptions {
28
+ routing: MarketingSiteRoutingOptions;
29
+ preview?: boolean;
30
+ env?: NodeJS.ProcessEnv;
31
+ }
32
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/cms-integrity/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,8CAA8C,CAAC;AAEhG,MAAM,WAAW,uBAAuB;IACtC,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,2BAA2B,CAAC;IACrC,6DAA6D;IAC7D,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,uBAAuB;IACtC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IAChC,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IAChC,YAAY,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IACxC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;CAClC;AAED,MAAM,WAAW,0BAA0B;IACzC,UAAU,EAAE,MAAM,CAAC;IACnB,eAAe,EAAE,MAAM,CAAC;IACxB,wBAAwB,EAAE,MAAM,CAAC;IACjC,eAAe,EAAE,MAAM,CAAC;IACxB,6BAA6B,EAAE,MAAM,CAAC;IACtC,+BAA+B,EAAE,MAAM,CAAC;IACxC,oBAAoB,EAAE,MAAM,CAAC;IAC7B,mBAAmB,EAAE,uBAAuB,EAAE,CAAC;IAC/C,MAAM,EAAE,uBAAuB,EAAE,CAAC;IAClC,yBAAyB,EAAE,uBAAuB,EAAE,CAAC;CACtD;AAED,MAAM,WAAW,mCAAmC;IAClD,OAAO,EAAE,2BAA2B,CAAC;IACrC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;CACzB"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/cms-integrity/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,4 @@
1
+ import type { LoadStaticSmokeConfigOptions, StaticSmokeConfigFile } from './types.js';
2
+ export declare function loadSmokeConfigFile(filePath: string, options?: LoadStaticSmokeConfigOptions): StaticSmokeConfigFile;
3
+ export declare function isCmsIntegrityEnabled(config: StaticSmokeConfigFile): boolean;
4
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/smoke-test/config.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,4BAA4B,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AAuBtF,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,MAAM,EAChB,OAAO,CAAC,EAAE,4BAA4B,GACrC,qBAAqB,CAiBvB;AAED,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,qBAAqB,GAAG,OAAO,CAE5E"}
@@ -0,0 +1,37 @@
1
+ import { readFileSync } from 'node:fs';
2
+ import { resolve } from 'node:path';
3
+ function validateCmsIntegrity(cmsIntegrity, absolutePath) {
4
+ if (!cmsIntegrity) {
5
+ return;
6
+ }
7
+ if (typeof cmsIntegrity.enabled !== 'boolean') {
8
+ throw new Error(`Invalid cmsIntegrity.enabled in smoke config: ${absolutePath}`);
9
+ }
10
+ if (!cmsIntegrity.enabled) {
11
+ return;
12
+ }
13
+ const { routing } = cmsIntegrity;
14
+ if (!routing?.articleTypesBasePath || !routing.tagsBasePath || !routing.peopleBasePath) {
15
+ throw new Error(`cmsIntegrity.routing requires articleTypesBasePath, tagsBasePath, and peopleBasePath: ${absolutePath}`);
16
+ }
17
+ }
18
+ export function loadSmokeConfigFile(filePath, options) {
19
+ const cwd = options?.cwd ?? process.cwd();
20
+ const absolutePath = resolve(cwd, filePath);
21
+ const raw = JSON.parse(readFileSync(absolutePath, 'utf8'));
22
+ if (!raw.siteName) {
23
+ throw new Error(`Invalid smoke config siteName: ${absolutePath}`);
24
+ }
25
+ if (!raw.port) {
26
+ throw new Error(`Invalid smoke config port: ${absolutePath}`);
27
+ }
28
+ if (!Array.isArray(raw.cases)) {
29
+ throw new Error(`Invalid smoke config cases: ${absolutePath}`);
30
+ }
31
+ validateCmsIntegrity(raw.cmsIntegrity, absolutePath);
32
+ return raw;
33
+ }
34
+ export function isCmsIntegrityEnabled(config) {
35
+ return config.cmsIntegrity?.enabled === true;
36
+ }
37
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/smoke-test/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAGpC,SAAS,oBAAoB,CAC3B,YAAmD,EACnD,YAAoB;IAEpB,IAAI,CAAC,YAAY,EAAE,CAAC;QAClB,OAAO;IACT,CAAC;IACD,IAAI,OAAO,YAAY,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;QAC9C,MAAM,IAAI,KAAK,CAAC,iDAAiD,YAAY,EAAE,CAAC,CAAC;IACnF,CAAC;IACD,IAAI,CAAC,YAAY,CAAC,OAAO,EAAE,CAAC;QAC1B,OAAO;IACT,CAAC;IACD,MAAM,EAAE,OAAO,EAAE,GAAG,YAAY,CAAC;IACjC,IAAI,CAAC,OAAO,EAAE,oBAAoB,IAAI,CAAC,OAAO,CAAC,YAAY,IAAI,CAAC,OAAO,CAAC,cAAc,EAAE,CAAC;QACvF,MAAM,IAAI,KAAK,CACb,yFAAyF,YAAY,EAAE,CACxG,CAAC;IACJ,CAAC;AACH,CAAC;AAED,MAAM,UAAU,mBAAmB,CACjC,QAAgB,EAChB,OAAsC;IAEtC,MAAM,GAAG,GAAG,OAAO,EAAE,GAAG,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;IAC1C,MAAM,YAAY,GAAG,OAAO,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;IAC5C,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,YAAY,EAAE,MAAM,CAAC,CAA0B,CAAC;IAEpF,IAAI,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC;QAClB,MAAM,IAAI,KAAK,CAAC,kCAAkC,YAAY,EAAE,CAAC,CAAC;IACpE,CAAC;IACD,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC;QACd,MAAM,IAAI,KAAK,CAAC,8BAA8B,YAAY,EAAE,CAAC,CAAC;IAChE,CAAC;IACD,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;QAC9B,MAAM,IAAI,KAAK,CAAC,+BAA+B,YAAY,EAAE,CAAC,CAAC;IACjE,CAAC;IAED,oBAAoB,CAAC,GAAG,CAAC,YAAY,EAAE,YAAY,CAAC,CAAC;IACrD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,MAAM,UAAU,qBAAqB,CAAC,MAA6B;IACjE,OAAO,MAAM,CAAC,YAAY,EAAE,OAAO,KAAK,IAAI,CAAC;AAC/C,CAAC"}
@@ -1,8 +1,9 @@
1
1
  export { createProtectedFetch, requireDeploymentBaseUrl, requirePreviewBaseUrl, requireProtectionBypass, requireSitemapProdUrl, resolveDeploymentBaseUrl, resolvePreviewBaseUrl, resolveProductionSiteUrl, resolveProtectionBypass, resolveSitemapProdUrl, VERCEL_PROTECTION_BYPASS_HEADER, } from '../vercel-env.js';
2
2
  export type { CacheLogAuditMatch, CacheLogAuditOptions, CacheLogAuditResult, CacheLogAuditSeverity, } from './cache-log-audit.js';
3
3
  export { auditCacheLogs, formatCacheLogAuditReport, getCacheLogAuditExitCode, } from './cache-log-audit.js';
4
+ export { isCmsIntegrityEnabled, loadSmokeConfigFile } from './config.js';
4
5
  export { formatSmokeTestReport, getSmokeTestExitCode, isSmokeTestCacheVerifyResult, parseNextJsCacheHeader, runSmokeTest, runSmokeTestWithCacheVerify, } from './runner.js';
5
- export type { RunLiveSmokeTestOptions } from './static.js';
6
- export { joinSmokeBaseUrl, loadStaticSmokeConfig, resolveSmokePortFromConfig, runLiveSmokeTest, runPreviewStaticSmokeTest, runStaticSmokeTest, } from './static.js';
7
- export type { LoadStaticSmokeConfigOptions, NextJsCacheStatus, RunPreviewStaticSmokeTestOptions, RunStaticSmokeTestOptions, SmokeFailureReason, SmokeTestCacheVerifyResult, SmokeTestCase, SmokeTestCaseResult, SmokeTestCategory, SmokeTestResult, SmokeTestRunnerConfig, StaticSmokeCaseDefinition, StaticSmokeConfigFile, } from './types.js';
6
+ export type { RunLiveSmokeTestOptions, StaticSmokeTestWithIntegrityResult } from './static.js';
7
+ export { formatCombinedSmokeReport, getCombinedSmokeExitCode, joinSmokeBaseUrl, loadStaticSmokeConfig, resolveSmokePortFromConfig, runArticleLinkIntegrityFromSmokeConfig, runLiveSmokeTest, runPreviewStaticSmokeTest, runStaticSmokeTest, runStaticSmokeTestWithIntegrity, } from './static.js';
8
+ export type { LoadStaticSmokeConfigOptions, NextJsCacheStatus, RunPreviewStaticSmokeTestOptions, RunStaticSmokeTestOptions, SmokeCmsIntegrityConfig, SmokeFailureReason, SmokeTestCacheVerifyResult, SmokeTestCase, SmokeTestCaseResult, SmokeTestCategory, SmokeTestResult, SmokeTestRunnerConfig, StaticSmokeCaseDefinition, StaticSmokeConfigFile, } from './types.js';
8
9
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/smoke-test/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,oBAAoB,EACpB,wBAAwB,EACxB,qBAAqB,EACrB,uBAAuB,EACvB,qBAAqB,EACrB,wBAAwB,EACxB,qBAAqB,EACrB,wBAAwB,EACxB,uBAAuB,EACvB,qBAAqB,EACrB,+BAA+B,GAChC,MAAM,kBAAkB,CAAC;AAC1B,YAAY,EACV,kBAAkB,EAClB,oBAAoB,EACpB,mBAAmB,EACnB,qBAAqB,GACtB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EACL,cAAc,EACd,yBAAyB,EACzB,wBAAwB,GACzB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EACL,qBAAqB,EACrB,oBAAoB,EACpB,4BAA4B,EAC5B,sBAAsB,EACtB,YAAY,EACZ,2BAA2B,GAC5B,MAAM,aAAa,CAAC;AACrB,YAAY,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAC;AAC3D,OAAO,EACL,gBAAgB,EAChB,qBAAqB,EACrB,0BAA0B,EAC1B,gBAAgB,EAChB,yBAAyB,EACzB,kBAAkB,GACnB,MAAM,aAAa,CAAC;AACrB,YAAY,EACV,4BAA4B,EAC5B,iBAAiB,EACjB,gCAAgC,EAChC,yBAAyB,EACzB,kBAAkB,EAClB,0BAA0B,EAC1B,aAAa,EACb,mBAAmB,EACnB,iBAAiB,EACjB,eAAe,EACf,qBAAqB,EACrB,yBAAyB,EACzB,qBAAqB,GACtB,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/smoke-test/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,oBAAoB,EACpB,wBAAwB,EACxB,qBAAqB,EACrB,uBAAuB,EACvB,qBAAqB,EACrB,wBAAwB,EACxB,qBAAqB,EACrB,wBAAwB,EACxB,uBAAuB,EACvB,qBAAqB,EACrB,+BAA+B,GAChC,MAAM,kBAAkB,CAAC;AAC1B,YAAY,EACV,kBAAkB,EAClB,oBAAoB,EACpB,mBAAmB,EACnB,qBAAqB,GACtB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EACL,cAAc,EACd,yBAAyB,EACzB,wBAAwB,GACzB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,qBAAqB,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AACzE,OAAO,EACL,qBAAqB,EACrB,oBAAoB,EACpB,4BAA4B,EAC5B,sBAAsB,EACtB,YAAY,EACZ,2BAA2B,GAC5B,MAAM,aAAa,CAAC;AACrB,YAAY,EAAE,uBAAuB,EAAE,kCAAkC,EAAE,MAAM,aAAa,CAAC;AAC/F,OAAO,EACL,yBAAyB,EACzB,wBAAwB,EACxB,gBAAgB,EAChB,qBAAqB,EACrB,0BAA0B,EAC1B,sCAAsC,EACtC,gBAAgB,EAChB,yBAAyB,EACzB,kBAAkB,EAClB,+BAA+B,GAChC,MAAM,aAAa,CAAC;AACrB,YAAY,EACV,4BAA4B,EAC5B,iBAAiB,EACjB,gCAAgC,EAChC,yBAAyB,EACzB,uBAAuB,EACvB,kBAAkB,EAClB,0BAA0B,EAC1B,aAAa,EACb,mBAAmB,EACnB,iBAAiB,EACjB,eAAe,EACf,qBAAqB,EACrB,yBAAyB,EACzB,qBAAqB,GACtB,MAAM,YAAY,CAAC"}
@@ -1,5 +1,6 @@
1
1
  export { createProtectedFetch, requireDeploymentBaseUrl, requirePreviewBaseUrl, requireProtectionBypass, requireSitemapProdUrl, resolveDeploymentBaseUrl, resolvePreviewBaseUrl, resolveProductionSiteUrl, resolveProtectionBypass, resolveSitemapProdUrl, VERCEL_PROTECTION_BYPASS_HEADER, } from '../vercel-env.js';
2
2
  export { auditCacheLogs, formatCacheLogAuditReport, getCacheLogAuditExitCode, } from './cache-log-audit.js';
3
+ export { isCmsIntegrityEnabled, loadSmokeConfigFile } from './config.js';
3
4
  export { formatSmokeTestReport, getSmokeTestExitCode, isSmokeTestCacheVerifyResult, parseNextJsCacheHeader, runSmokeTest, runSmokeTestWithCacheVerify, } from './runner.js';
4
- export { joinSmokeBaseUrl, loadStaticSmokeConfig, resolveSmokePortFromConfig, runLiveSmokeTest, runPreviewStaticSmokeTest, runStaticSmokeTest, } from './static.js';
5
+ export { formatCombinedSmokeReport, getCombinedSmokeExitCode, joinSmokeBaseUrl, loadStaticSmokeConfig, resolveSmokePortFromConfig, runArticleLinkIntegrityFromSmokeConfig, runLiveSmokeTest, runPreviewStaticSmokeTest, runStaticSmokeTest, runStaticSmokeTestWithIntegrity, } from './static.js';
5
6
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/smoke-test/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,oBAAoB,EACpB,wBAAwB,EACxB,qBAAqB,EACrB,uBAAuB,EACvB,qBAAqB,EACrB,wBAAwB,EACxB,qBAAqB,EACrB,wBAAwB,EACxB,uBAAuB,EACvB,qBAAqB,EACrB,+BAA+B,GAChC,MAAM,kBAAkB,CAAC;AAO1B,OAAO,EACL,cAAc,EACd,yBAAyB,EACzB,wBAAwB,GACzB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EACL,qBAAqB,EACrB,oBAAoB,EACpB,4BAA4B,EAC5B,sBAAsB,EACtB,YAAY,EACZ,2BAA2B,GAC5B,MAAM,aAAa,CAAC;AAErB,OAAO,EACL,gBAAgB,EAChB,qBAAqB,EACrB,0BAA0B,EAC1B,gBAAgB,EAChB,yBAAyB,EACzB,kBAAkB,GACnB,MAAM,aAAa,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/smoke-test/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,oBAAoB,EACpB,wBAAwB,EACxB,qBAAqB,EACrB,uBAAuB,EACvB,qBAAqB,EACrB,wBAAwB,EACxB,qBAAqB,EACrB,wBAAwB,EACxB,uBAAuB,EACvB,qBAAqB,EACrB,+BAA+B,GAChC,MAAM,kBAAkB,CAAC;AAO1B,OAAO,EACL,cAAc,EACd,yBAAyB,EACzB,wBAAwB,GACzB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,qBAAqB,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AACzE,OAAO,EACL,qBAAqB,EACrB,oBAAoB,EACpB,4BAA4B,EAC5B,sBAAsB,EACtB,YAAY,EACZ,2BAA2B,GAC5B,MAAM,aAAa,CAAC;AAErB,OAAO,EACL,yBAAyB,EACzB,wBAAwB,EACxB,gBAAgB,EAChB,qBAAqB,EACrB,0BAA0B,EAC1B,sCAAsC,EACtC,gBAAgB,EAChB,yBAAyB,EACzB,kBAAkB,EAClB,+BAA+B,GAChC,MAAM,aAAa,CAAC"}
@@ -1,3 +1,4 @@
1
+ import type { ArticleLinkIntegrityResult } from '../cms-integrity/types.js';
1
2
  import type { LoadStaticSmokeConfigOptions, RunPreviewStaticSmokeTestOptions, RunStaticSmokeTestOptions, SmokeTestCacheVerifyResult, SmokeTestResult, SmokeTestRunnerConfig } from './types.js';
2
3
  export declare function joinSmokeBaseUrl(baseUrl: string, path: string): string;
3
4
  export declare function resolveSmokePortFromConfig(filePath: string, options?: {
@@ -5,7 +6,17 @@ export declare function resolveSmokePortFromConfig(filePath: string, options?: {
5
6
  portOverride?: number;
6
7
  }): number;
7
8
  export declare function loadStaticSmokeConfig(filePath: string, options?: LoadStaticSmokeConfigOptions): SmokeTestRunnerConfig;
9
+ export interface StaticSmokeTestWithIntegrityResult {
10
+ integrity?: ArticleLinkIntegrityResult;
11
+ http: SmokeTestResult | SmokeTestCacheVerifyResult;
12
+ }
13
+ export declare function runArticleLinkIntegrityFromSmokeConfig(filePath: string, options?: LoadStaticSmokeConfigOptions): Promise<ArticleLinkIntegrityResult | undefined>;
14
+ export declare function getCombinedSmokeExitCode(integrity: ArticleLinkIntegrityResult | undefined, http: SmokeTestResult | SmokeTestCacheVerifyResult): number;
15
+ export declare function formatCombinedSmokeReport(integrity: ArticleLinkIntegrityResult | undefined, http: SmokeTestResult | SmokeTestCacheVerifyResult): string;
8
16
  export declare function runStaticSmokeTest(filePath: string, options?: RunStaticSmokeTestOptions): Promise<SmokeTestResult | SmokeTestCacheVerifyResult>;
17
+ export declare function runStaticSmokeTestWithIntegrity(filePath: string, options?: RunStaticSmokeTestOptions & {
18
+ skipIntegrity?: boolean;
19
+ }): Promise<StaticSmokeTestWithIntegrityResult>;
9
20
  export type RunLiveSmokeTestOptions = RunPreviewStaticSmokeTestOptions;
10
21
  export declare function runLiveSmokeTest(filePath: string, options?: RunLiveSmokeTestOptions): Promise<SmokeTestResult>;
11
22
  export declare function runPreviewStaticSmokeTest(filePath: string, options?: RunPreviewStaticSmokeTestOptions): Promise<SmokeTestResult>;
@@ -1 +1 @@
1
- {"version":3,"file":"static.d.ts","sourceRoot":"","sources":["../../src/smoke-test/static.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EACV,4BAA4B,EAC5B,gCAAgC,EAChC,yBAAyB,EACzB,0BAA0B,EAE1B,eAAe,EACf,qBAAqB,EAEtB,MAAM,YAAY,CAAC;AAEpB,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAItE;AAaD,wBAAgB,0BAA0B,CACxC,QAAQ,EAAE,MAAM,EAChB,OAAO,CAAC,EAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAC;IAAC,YAAY,CAAC,EAAE,MAAM,CAAA;CAAE,GAChD,MAAM,CAWR;AAED,wBAAgB,qBAAqB,CACnC,QAAQ,EAAE,MAAM,EAChB,OAAO,CAAC,EAAE,4BAA4B,GACrC,qBAAqB,CAyBvB;AASD,wBAAsB,kBAAkB,CACtC,QAAQ,EAAE,MAAM,EAChB,OAAO,CAAC,EAAE,yBAAyB,GAClC,OAAO,CAAC,eAAe,GAAG,0BAA0B,CAAC,CAUvD;AASD,MAAM,MAAM,uBAAuB,GAAG,gCAAgC,CAAC;AAEvE,wBAAsB,gBAAgB,CACpC,QAAQ,EAAE,MAAM,EAChB,OAAO,CAAC,EAAE,uBAAuB,GAChC,OAAO,CAAC,eAAe,CAAC,CAG1B;AAED,wBAAsB,yBAAyB,CAC7C,QAAQ,EAAE,MAAM,EAChB,OAAO,CAAC,EAAE,gCAAgC,GACzC,OAAO,CAAC,eAAe,CAAC,CAiB1B"}
1
+ {"version":3,"file":"static.d.ts","sourceRoot":"","sources":["../../src/smoke-test/static.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,2BAA2B,CAAC;AAe5E,OAAO,KAAK,EACV,4BAA4B,EAC5B,gCAAgC,EAChC,yBAAyB,EACzB,0BAA0B,EAE1B,eAAe,EACf,qBAAqB,EAEtB,MAAM,YAAY,CAAC;AAEpB,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAItE;AAaD,wBAAgB,0BAA0B,CACxC,QAAQ,EAAE,MAAM,EAChB,OAAO,CAAC,EAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAC;IAAC,YAAY,CAAC,EAAE,MAAM,CAAA;CAAE,GAChD,MAAM,CASR;AAED,wBAAgB,qBAAqB,CACnC,QAAQ,EAAE,MAAM,EAChB,OAAO,CAAC,EAAE,4BAA4B,GACrC,qBAAqB,CAkBvB;AASD,MAAM,WAAW,kCAAkC;IACjD,SAAS,CAAC,EAAE,0BAA0B,CAAC;IACvC,IAAI,EAAE,eAAe,GAAG,0BAA0B,CAAC;CACpD;AAED,wBAAsB,sCAAsC,CAC1D,QAAQ,EAAE,MAAM,EAChB,OAAO,CAAC,EAAE,4BAA4B,GACrC,OAAO,CAAC,0BAA0B,GAAG,SAAS,CAAC,CAajD;AAED,wBAAgB,wBAAwB,CACtC,SAAS,EAAE,0BAA0B,GAAG,SAAS,EACjD,IAAI,EAAE,eAAe,GAAG,0BAA0B,GACjD,MAAM,CAKR;AAED,wBAAgB,yBAAyB,CACvC,SAAS,EAAE,0BAA0B,GAAG,SAAS,EACjD,IAAI,EAAE,eAAe,GAAG,0BAA0B,GACjD,MAAM,CAQR;AAED,wBAAsB,kBAAkB,CACtC,QAAQ,EAAE,MAAM,EAChB,OAAO,CAAC,EAAE,yBAAyB,GAClC,OAAO,CAAC,eAAe,GAAG,0BAA0B,CAAC,CAUvD;AAED,wBAAsB,+BAA+B,CACnD,QAAQ,EAAE,MAAM,EAChB,OAAO,CAAC,EAAE,yBAAyB,GAAG;IAAE,aAAa,CAAC,EAAE,OAAO,CAAA;CAAE,GAChE,OAAO,CAAC,kCAAkC,CAAC,CAQ7C;AASD,MAAM,MAAM,uBAAuB,GAAG,gCAAgC,CAAC;AAEvE,wBAAsB,gBAAgB,CACpC,QAAQ,EAAE,MAAM,EAChB,OAAO,CAAC,EAAE,uBAAuB,GAChC,OAAO,CAAC,eAAe,CAAC,CAG1B;AAED,wBAAsB,yBAAyB,CAC7C,QAAQ,EAAE,MAAM,EAChB,OAAO,CAAC,EAAE,gCAAgC,GACzC,OAAO,CAAC,eAAe,CAAC,CAiB1B"}
@@ -1,7 +1,7 @@
1
- import { readFileSync } from 'node:fs';
2
- import { resolve } from 'node:path';
1
+ import { formatArticleLinkIntegrityReport, getArticleLinkIntegrityExitCode, } from '../cms-integrity/report.js';
3
2
  import { createProtectedFetch, requireDeploymentBaseUrl, requirePreviewBaseUrl, requireProtectionBypass, resolveProtectionBypass, } from '../vercel-env.js';
4
- import { runSmokeTest, runSmokeTestWithCacheVerify } from './runner.js';
3
+ import { isCmsIntegrityEnabled, loadSmokeConfigFile } from './config.js';
4
+ import { formatSmokeTestReport, getSmokeTestExitCode, runSmokeTest, runSmokeTestWithCacheVerify, } from './runner.js';
5
5
  export function joinSmokeBaseUrl(baseUrl, path) {
6
6
  const normalizedBase = baseUrl.replace(/\/$/, '');
7
7
  const normalizedPath = path.startsWith('/') ? path : `/${path}`;
@@ -21,21 +21,14 @@ export function resolveSmokePortFromConfig(filePath, options) {
21
21
  if (options?.portOverride !== undefined) {
22
22
  return options.portOverride;
23
23
  }
24
- const cwd = options?.cwd ?? process.cwd();
25
- const absolutePath = resolve(cwd, filePath);
26
- const raw = JSON.parse(readFileSync(absolutePath, 'utf8'));
24
+ const raw = loadSmokeConfigFile(filePath, options);
27
25
  if (!raw.port || !Number.isFinite(raw.port)) {
28
- throw new Error(`Invalid smoke config port: ${absolutePath}`);
26
+ throw new Error(`Invalid smoke config port: ${filePath}`);
29
27
  }
30
28
  return raw.port;
31
29
  }
32
30
  export function loadStaticSmokeConfig(filePath, options) {
33
- const cwd = options?.cwd ?? process.cwd();
34
- const absolutePath = resolve(cwd, filePath);
35
- const raw = JSON.parse(readFileSync(absolutePath, 'utf8'));
36
- if (!raw.siteName || !raw.port || !Array.isArray(raw.cases)) {
37
- throw new Error(`Invalid smoke config: ${absolutePath}`);
38
- }
31
+ const raw = loadSmokeConfigFile(filePath, options);
39
32
  const baseUrl = options?.baseUrl ?? `http://localhost:${resolvePort(raw, options?.portOverride)}`;
40
33
  const cases = raw.cases.map((entry) => ({
41
34
  category: entry.category,
@@ -57,6 +50,33 @@ function resolveVerifyCache(options) {
57
50
  }
58
51
  return (process.env.SMOKE_TEST_VERIFY_CACHE ?? '').toLowerCase() === 'true';
59
52
  }
53
+ export async function runArticleLinkIntegrityFromSmokeConfig(filePath, options) {
54
+ const raw = loadSmokeConfigFile(filePath, options);
55
+ if (!isCmsIntegrityEnabled(raw) || !raw.cmsIntegrity) {
56
+ return undefined;
57
+ }
58
+ const { validateArticleLinkIntegrity } = await import('../cms-integrity/article-link-integrity.js');
59
+ return validateArticleLinkIntegrity({
60
+ routing: raw.cmsIntegrity.routing,
61
+ preview: raw.cmsIntegrity.preview,
62
+ env: options?.env,
63
+ });
64
+ }
65
+ export function getCombinedSmokeExitCode(integrity, http) {
66
+ if (integrity && getArticleLinkIntegrityExitCode(integrity) !== 0) {
67
+ return 1;
68
+ }
69
+ return getSmokeTestExitCode(http);
70
+ }
71
+ export function formatCombinedSmokeReport(integrity, http) {
72
+ const sections = [];
73
+ if (integrity) {
74
+ sections.push(formatArticleLinkIntegrityReport(integrity));
75
+ sections.push('');
76
+ }
77
+ sections.push(formatSmokeTestReport(http));
78
+ return sections.join('\n');
79
+ }
60
80
  export async function runStaticSmokeTest(filePath, options) {
61
81
  const config = loadStaticSmokeConfig(filePath, options);
62
82
  const runnerConfig = {
@@ -68,6 +88,13 @@ export async function runStaticSmokeTest(filePath, options) {
68
88
  }
69
89
  return runSmokeTest(runnerConfig);
70
90
  }
91
+ export async function runStaticSmokeTestWithIntegrity(filePath, options) {
92
+ const integrity = options?.skipIntegrity === true
93
+ ? undefined
94
+ : await runArticleLinkIntegrityFromSmokeConfig(filePath, options);
95
+ const http = await runStaticSmokeTest(filePath, options);
96
+ return { integrity, http };
97
+ }
71
98
  function resolvePreviewBaseUrl(options) {
72
99
  if (options?.baseUrl) {
73
100
  return options.baseUrl.replace(/\/$/, '');
@@ -1 +1 @@
1
- {"version":3,"file":"static.js","sourceRoot":"","sources":["../../src/smoke-test/static.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"static.js","sourceRoot":"","sources":["../../src/smoke-test/static.ts"],"names":[],"mappings":"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"}
@@ -1,3 +1,5 @@
1
+ import type { SmokeCmsIntegrityConfig } from '../cms-integrity/types.js';
2
+ export type { SmokeCmsIntegrityConfig };
1
3
  export type SmokeTestCategory = 'home' | 'page' | 'article-type-index' | 'article' | 'person' | 'people-listing' | 'tag' | 'article-type-tag-listing' | 'tags-index' | 'articles-index' | 'custom-type-listing';
2
4
  export interface SmokeTestCase {
3
5
  category: SmokeTestCategory;
@@ -19,6 +21,7 @@ export interface StaticSmokeConfigFile {
19
21
  cases: StaticSmokeCaseDefinition[];
20
22
  minMarkdownLength?: number;
21
23
  requestDelayMs?: number;
24
+ cmsIntegrity?: SmokeCmsIntegrityConfig;
22
25
  }
23
26
  export type SmokeFailureReason = 'html_non_2xx' | 'markdown_missing' | 'markdown_wrong_content_type' | 'markdown_too_short';
24
27
  export type NextJsCacheStatus = 'HIT' | 'MISS' | 'STALE';
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/smoke-test/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/smoke-test/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,2BAA2B,CAAC;AAEzE,YAAY,EAAE,uBAAuB,EAAE,CAAC;AAExC,MAAM,MAAM,iBAAiB,GACzB,MAAM,GACN,MAAM,GACN,oBAAoB,GACpB,SAAS,GACT,QAAQ,GACR,gBAAgB,GAChB,KAAK,GACL,0BAA0B,GAC1B,YAAY,GACZ,gBAAgB,GAChB,qBAAqB,CAAC;AAE1B,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,iBAAiB,CAAC;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,cAAc,EAAE,OAAO,CAAC;CACzB;AAED,qEAAqE;AACrE,MAAM,WAAW,yBAAyB;IACxC,QAAQ,EAAE,iBAAiB,CAAC;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,cAAc,EAAE,OAAO,CAAC;CACzB;AAED,mFAAmF;AACnF,MAAM,WAAW,qBAAqB;IACpC,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,yBAAyB,EAAE,CAAC;IACnC,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,YAAY,CAAC,EAAE,uBAAuB,CAAC;CACxC;AAED,MAAM,MAAM,kBAAkB,GAC1B,cAAc,GACd,kBAAkB,GAClB,6BAA6B,GAC7B,oBAAoB,CAAC;AAEzB,MAAM,MAAM,iBAAiB,GAAG,KAAK,GAAG,MAAM,GAAG,OAAO,CAAC;AAEzD,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,aAAa,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,EAAE,MAAM,CAAC;IACvB,cAAc,EAAE,MAAM,CAAC;IACvB,mBAAmB,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,QAAQ,EAAE,kBAAkB,EAAE,CAAC;IAC/B,mBAAmB,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,aAAa,EAAE,iBAAiB,GAAG,IAAI,CAAC;IACxC,iBAAiB,EAAE,iBAAiB,GAAG,IAAI,CAAC;IAC5C,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,mBAAmB,EAAE,CAAC;IAC7B,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,aAAa,EAAE,CAAC;IACvB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,KAAK,CAAC,EAAE,OAAO,KAAK,CAAC;CACtB;AAED,MAAM,WAAW,4BAA4B;IAC3C,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,8GAA8G;IAC9G,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;CACzB;AAED,MAAM,WAAW,yBAA0B,SAAQ,4BAA4B;IAC7E,KAAK,CAAC,EAAE,OAAO,KAAK,CAAC;IACrB,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED,MAAM,WAAW,gCAAiC,SAAQ,yBAAyB;IACjF,qFAAqF;IACrF,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAED,MAAM,WAAW,0BAA0B;IACzC,KAAK,EAAE,eAAe,CAAC;IACvB,KAAK,EAAE,eAAe,CAAC;IACvB,eAAe,EAAE,MAAM,CAAC;IACxB,eAAe,EAAE,MAAM,CAAC;IACxB,mBAAmB,EAAE,MAAM,EAAE,CAAC;CAC/B"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@se-studio/site-check",
3
- "version": "2.5.0",
3
+ "version": "2.6.0",
4
4
  "description": "Validate SE marketing sites (sitemap, llms.txt) and download markdown files preserving structure",
5
5
  "repository": {
6
6
  "type": "git",
@@ -30,7 +30,14 @@
30
30
  "./smoke-test": {
31
31
  "types": "./dist/smoke-test/index.d.ts",
32
32
  "import": "./dist/smoke-test/index.js",
33
+ "require": "./dist/smoke-test/index.js",
33
34
  "default": "./dist/smoke-test/index.js"
35
+ },
36
+ "./cms-integrity": {
37
+ "types": "./dist/cms-integrity/index.d.ts",
38
+ "import": "./dist/cms-integrity/index.js",
39
+ "require": "./dist/cms-integrity/index.js",
40
+ "default": "./dist/cms-integrity/index.js"
34
41
  }
35
42
  },
36
43
  "bin": {
@@ -62,6 +69,10 @@
62
69
  "bugs": {
63
70
  "url": "https://github.com/Something-Else-Studio/se-core-product/issues"
64
71
  },
72
+ "dependencies": {
73
+ "@se-studio/contentful-rest-api": "1.10.0",
74
+ "@se-studio/core-data-types": "1.5.1"
75
+ },
65
76
  "devDependencies": {
66
77
  "@biomejs/biome": "^2.5.0",
67
78
  "@types/node": "^24.13.2",
@@ -13,6 +13,7 @@
13
13
  * SMOKE_TEST_READY_PATH=/ — path polled until server responds
14
14
  * SMOKE_TEST_USE_RUNNING_SERVER=true — reuse server already on port (default true)
15
15
  * SMOKE_TEST_SKIP_BUILD=true — skip pnpm build when SERVER_SCRIPT=start (post-build deploy check)
16
+ * SMOKE_TEST_SKIP_INTEGRITY=true — HTTP smoke only (set by smoke-test-one when cmsIntegrity runs in parallel)
16
17
  * LOG_CMS_FETCH=1 — set when VERIFY_CACHE or AUDIT_CACHE_LOGS is true
17
18
  */
18
19
 
@@ -175,6 +176,39 @@ async function loadCacheLogAudit() {
175
176
  return import(modulePath);
176
177
  }
177
178
 
179
+ async function loadSmokeIntegrityModules() {
180
+ const staticModule = await import(path.join(packageDir, 'dist/smoke-test/static.js'));
181
+ const integrityModule = await import(path.join(packageDir, 'dist/cms-integrity/report.js'));
182
+ return { ...staticModule, ...integrityModule };
183
+ }
184
+
185
+ const smokeCasesPath = path.join(process.cwd(), 'smoke.cases.json');
186
+
187
+ async function startParallelCmsIntegrity(env) {
188
+ if (!fs.existsSync(smokeCasesPath)) {
189
+ return { promise: null, enabled: false };
190
+ }
191
+
192
+ const { loadSmokeConfigFile, isCmsIntegrityEnabled, runArticleLinkIntegrityFromSmokeConfig } =
193
+ await loadSmokeIntegrityModules();
194
+
195
+ const config = loadSmokeConfigFile('smoke.cases.json', { cwd: process.cwd(), env });
196
+ if (!isCmsIntegrityEnabled(config)) {
197
+ return { promise: null, enabled: false };
198
+ }
199
+
200
+ console.log(
201
+ 'CMS article-link integrity: fetching from Contentful (parallel with server boot)...',
202
+ );
203
+ return {
204
+ enabled: true,
205
+ promise: runArticleLinkIntegrityFromSmokeConfig('smoke.cases.json', {
206
+ cwd: process.cwd(),
207
+ env,
208
+ }),
209
+ };
210
+ }
211
+
178
212
  const env = loadEnv();
179
213
 
180
214
  if ((env.SMOKE_TEST_IGNORE ?? '').toLowerCase() === 'true') {
@@ -216,11 +250,14 @@ if (isProductionStart && !skipBuild) {
216
250
  }
217
251
 
218
252
  const enableCmsFetchLog = verifyCache || auditCacheLogsEnabled;
253
+ const { promise: integrityPromise, enabled: integrityEnabled } =
254
+ await startParallelCmsIntegrity(env);
219
255
  const smokeEnv = {
220
256
  ...env,
221
257
  SMOKE_TEST_PORT: port,
222
258
  ...(verifyCache ? { SMOKE_TEST_VERIFY_CACHE: 'true' } : {}),
223
259
  ...(enableCmsFetchLog ? { LOG_CMS_FETCH: '1' } : {}),
260
+ ...(integrityEnabled ? { SMOKE_TEST_SKIP_INTEGRITY: 'true' } : {}),
224
261
  };
225
262
 
226
263
  console.log(`Smoke test: checking ${readyUrl} (port ${port})...`);
@@ -276,6 +313,17 @@ try {
276
313
  // pipe buffers fill, and the dev server deadlocks mid-compile.
277
314
  exitCode = await runSmokeTests(appDir, smokeEnv);
278
315
 
316
+ if (integrityPromise) {
317
+ const { formatArticleLinkIntegrityReport, getArticleLinkIntegrityExitCode } =
318
+ await loadSmokeIntegrityModules();
319
+ const integrityResult = await integrityPromise;
320
+ console.log('');
321
+ console.log(formatArticleLinkIntegrityReport(integrityResult));
322
+ if (getArticleLinkIntegrityExitCode(integrityResult) !== 0) {
323
+ exitCode = 1;
324
+ }
325
+ }
326
+
279
327
  if (auditCacheLogsEnabled && spawnedServer) {
280
328
  const { auditCacheLogs, formatCacheLogAuditReport, getCacheLogAuditExitCode } =
281
329
  await loadCacheLogAudit();