slides-grab 1.2.2 → 1.2.3

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.
@@ -1,4 +1,5 @@
1
1
  import { access, readdir } from 'node:fs/promises';
2
+ import { createRequire } from 'node:module';
2
3
  import { basename, join } from 'node:path';
3
4
  import { pathToFileURL } from 'node:url';
4
5
  import { chromium } from 'playwright';
@@ -9,12 +10,14 @@ import {
9
10
  resolveSlideSourcePath,
10
11
  } from '../image-contract.js';
11
12
 
12
- export const FRAME_PT = { width: 720, height: 405 };
13
- export const PT_TO_PX = 96 / 72;
14
- export const FRAME_PX = {
15
- width: FRAME_PT.width * PT_TO_PX,
16
- height: FRAME_PT.height * PT_TO_PX,
17
- };
13
+ const require = createRequire(import.meta.url);
14
+ const {
15
+ DEFAULT_SLIDE_MODE,
16
+ getSlideModeConfig,
17
+ } = require('../slide-mode.cjs');
18
+
19
+ export const FRAME_PT = getSlideModeConfig(DEFAULT_SLIDE_MODE).framePt;
20
+ export const FRAME_PX = getSlideModeConfig(DEFAULT_SLIDE_MODE).framePx;
18
21
  export const SLIDE_FILE_PATTERN = /^slide-.*\.html$/i;
19
22
  export const TEXT_SELECTOR = 'p,h1,h2,h3,h4,h5,h6,li';
20
23
  export const TOLERANCE_PX = 0.5;
@@ -58,28 +61,30 @@ export function summarizeSlides(slides) {
58
61
  return summary;
59
62
  }
60
63
 
61
- export function createValidationResult(slides) {
64
+ export function createValidationResult(slides, slideMode = DEFAULT_SLIDE_MODE) {
65
+ const { framePt, framePx } = getSlideModeConfig(slideMode);
62
66
  return {
63
67
  generatedAt: new Date().toISOString(),
64
68
  frame: {
65
- widthPt: FRAME_PT.width,
66
- heightPt: FRAME_PT.height,
67
- widthPx: FRAME_PX.width,
68
- heightPx: FRAME_PX.height,
69
+ widthPt: framePt.width,
70
+ heightPt: framePt.height,
71
+ widthPx: framePx.width,
72
+ heightPx: framePx.height,
69
73
  },
70
74
  slides,
71
75
  summary: summarizeSlides(slides),
72
76
  };
73
77
  }
74
78
 
75
- export function createValidationFailure(error) {
79
+ export function createValidationFailure(error, slideMode = DEFAULT_SLIDE_MODE) {
80
+ const { framePt, framePx } = getSlideModeConfig(slideMode);
76
81
  return {
77
82
  generatedAt: new Date().toISOString(),
78
83
  frame: {
79
- widthPt: FRAME_PT.width,
80
- heightPt: FRAME_PT.height,
81
- widthPx: FRAME_PX.width,
82
- heightPx: FRAME_PX.height,
84
+ widthPt: framePt.width,
85
+ heightPt: framePt.height,
86
+ widthPx: framePx.width,
87
+ heightPx: framePx.height,
83
88
  },
84
89
  slides: [],
85
90
  summary: {
@@ -347,9 +352,10 @@ export function selectSlideFiles(slideFiles, selectedSlides = [], slidesDir = ''
347
352
  return slideFiles.filter((slide) => available.has(slide) && requested.includes(slide));
348
353
  }
349
354
 
350
- export async function inspectSlide(page, fileName, slidesDir) {
355
+ export async function inspectSlide(page, fileName, slidesDir, slideMode = DEFAULT_SLIDE_MODE) {
351
356
  const slidePath = join(slidesDir, fileName);
352
357
  const slideUrl = pathToFileURL(slidePath).href;
358
+ const { framePx, sizeLabel } = getSlideModeConfig(slideMode);
353
359
 
354
360
  await page.goto(slideUrl, { waitUntil: 'load' });
355
361
  await page.evaluate(async () => {
@@ -359,7 +365,7 @@ export async function inspectSlide(page, fileName, slidesDir) {
359
365
  });
360
366
 
361
367
  const inspection = await page.evaluate(
362
- ({ framePx, textSelector, tolerancePx }) => {
368
+ ({ framePx, sizeLabel, textSelector, tolerancePx }) => {
363
369
  const skipTags = new Set(['SCRIPT', 'STYLE', 'META', 'LINK', 'HEAD', 'TITLE', 'NOSCRIPT']);
364
370
  const critical = [];
365
371
  const warning = [];
@@ -552,7 +558,7 @@ export async function inspectSlide(page, fileName, slidesDir) {
552
558
  if (outsideFrame) {
553
559
  critical.push({
554
560
  code: 'overflow-outside-frame',
555
- message: 'Element exceeds the 720pt x 405pt slide frame.',
561
+ message: `Element exceeds the ${sizeLabel} slide frame.`,
556
562
  element: elementPath(element),
557
563
  bbox: normalizeRect(rect),
558
564
  frame: normalizeRect(frameRect),
@@ -663,7 +669,8 @@ export async function inspectSlide(page, fileName, slidesDir) {
663
669
  };
664
670
  },
665
671
  {
666
- framePx: FRAME_PX,
672
+ framePx,
673
+ sizeLabel,
667
674
  textSelector: TEXT_SELECTOR,
668
675
  tolerancePx: TOLERANCE_PX,
669
676
  },
@@ -696,12 +703,12 @@ export async function inspectSlide(page, fileName, slidesDir) {
696
703
  };
697
704
  }
698
705
 
699
- export async function scanSlides(page, slidesDir, slideFiles) {
706
+ export async function scanSlides(page, slidesDir, slideFiles, slideMode = DEFAULT_SLIDE_MODE) {
700
707
  const slides = [];
701
708
 
702
709
  for (const slideFile of slideFiles) {
703
710
  try {
704
- const result = await inspectSlide(page, slideFile, slidesDir);
711
+ const result = await inspectSlide(page, slideFile, slidesDir, slideMode);
705
712
  slides.push(result);
706
713
  } catch (error) {
707
714
  slides.push({
@@ -740,7 +747,10 @@ export function formatValidationFailureForExport(result, exportLabel = 'Export')
740
747
  }
741
748
 
742
749
  const suffix = findings.length > 0 ? `\n${findings.join('\n')}` : '';
743
- return `${exportLabel} blocked by slide validation. Run \`slides-grab validate --slides-dir <path>\` for full diagnostics.${suffix}`;
750
+ const modeHint = result.slideMode && result.slideMode !== DEFAULT_SLIDE_MODE
751
+ ? ` --mode ${result.slideMode}`
752
+ : '';
753
+ return `${exportLabel} blocked by slide validation. Run \`slides-grab validate --slides-dir <path>${modeHint}\` for full diagnostics.${suffix}`;
744
754
  }
745
755
 
746
756
  const EXPORT_BLOCKING_IMAGE_CONTRACT_CODES = new Set([
@@ -799,6 +809,7 @@ export async function ensureSlidesPassValidation(
799
809
  slidesDir,
800
810
  {
801
811
  exportLabel = 'Export',
812
+ slideMode = DEFAULT_SLIDE_MODE,
802
813
  shouldBlockIssue = isBlockingImageContractIssue,
803
814
  } = {},
804
815
  ) {
@@ -812,8 +823,11 @@ export async function ensureSlidesPassValidation(
812
823
  const page = await context.newPage();
813
824
 
814
825
  try {
815
- const slides = await scanSlides(page, slidesDir, slideFiles);
816
- const result = createValidationResult(slides);
826
+ const slides = await scanSlides(page, slidesDir, slideFiles, slideMode);
827
+ const result = {
828
+ ...createValidationResult(slides, slideMode),
829
+ slideMode,
830
+ };
817
831
  const blockingResult = filterExportBlockingSlides(result, shouldBlockIssue);
818
832
  if (blockingResult.summary.failedSlides > 0) {
819
833
  throw new Error(formatValidationFailureForExport(blockingResult, exportLabel));