lingo-guardian 0.1.2 → 0.1.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.
package/dist/bin/cli.js CHANGED
@@ -9,6 +9,7 @@
9
9
  import { Command } from 'commander';
10
10
  import chalk from 'chalk';
11
11
  import { lintCommand } from '../commands/lint.js';
12
+ import { visualCommand } from '../commands/visual.js';
12
13
  import { VERSION, BANNER } from '../constants.js';
13
14
  const program = new Command();
14
15
  // Display banner
@@ -19,6 +20,7 @@ program
19
20
  .version(VERSION, '-v, --version', 'Display version number');
20
21
  // Register commands
21
22
  program.addCommand(lintCommand);
23
+ program.addCommand(visualCommand);
22
24
  // Error handling
23
25
  program.exitOverride((err) => {
24
26
  if (err.code === 'commander.helpDisplayed' || err.code === 'commander.version') {
@@ -1 +1 @@
1
- {"version":3,"file":"cli.js","sourceRoot":"","sources":["../../src/bin/cli.ts"],"names":[],"mappings":";AACA;;;;;;GAMG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAClD,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAElD,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;AAE9B,iBAAiB;AACjB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;AAEhC,OAAO;KACF,IAAI,CAAC,gBAAgB,CAAC;KACtB,WAAW,CAAC,2DAA2D,CAAC;KACxE,OAAO,CAAC,OAAO,EAAE,eAAe,EAAE,wBAAwB,CAAC,CAAC;AAEjE,oBAAoB;AACpB,OAAO,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC;AAEhC,iBAAiB;AACjB,OAAO,CAAC,YAAY,CAAC,CAAC,GAAG,EAAE,EAAE;IACzB,IAAI,GAAG,CAAC,IAAI,KAAK,yBAAyB,IAAI,GAAG,CAAC,IAAI,KAAK,mBAAmB,EAAE,CAAC;QAC7E,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACpB,CAAC;IACD,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,cAAc,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;IACtD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACpB,CAAC,CAAC,CAAC;AAEH,kBAAkB;AAClB,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;AAE5B,mCAAmC;AACnC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;IAChC,OAAO,CAAC,UAAU,EAAE,CAAC;AACzB,CAAC"}
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../../src/bin/cli.ts"],"names":[],"mappings":";AACA;;;;;;GAMG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAClD,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AACtD,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAElD,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;AAE9B,iBAAiB;AACjB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;AAEhC,OAAO;KACF,IAAI,CAAC,gBAAgB,CAAC;KACtB,WAAW,CAAC,2DAA2D,CAAC;KACxE,OAAO,CAAC,OAAO,EAAE,eAAe,EAAE,wBAAwB,CAAC,CAAC;AAEjE,oBAAoB;AACpB,OAAO,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC;AAChC,OAAO,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC;AAElC,iBAAiB;AACjB,OAAO,CAAC,YAAY,CAAC,CAAC,GAAG,EAAE,EAAE;IACzB,IAAI,GAAG,CAAC,IAAI,KAAK,yBAAyB,IAAI,GAAG,CAAC,IAAI,KAAK,mBAAmB,EAAE,CAAC;QAC7E,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACpB,CAAC;IACD,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,cAAc,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;IACtD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACpB,CAAC,CAAC,CAAC;AAEH,kBAAkB;AAClB,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;AAE5B,mCAAmC;AACnC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;IAChC,OAAO,CAAC,UAAU,EAAE,CAAC;AACzB,CAAC"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Visual Command - Generates 4-locale comparison grid
3
+ */
4
+ import { Command } from 'commander';
5
+ export declare const visualCommand: Command;
6
+ //# sourceMappingURL=visual.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"visual.d.ts","sourceRoot":"","sources":["../../src/commands/visual.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAUpC,eAAO,MAAM,aAAa,SAWpB,CAAC"}
@@ -0,0 +1,108 @@
1
+ /**
2
+ * Visual Command - Generates 4-locale comparison grid
3
+ */
4
+ import { Command } from 'commander';
5
+ import chalk from 'chalk';
6
+ import ora from 'ora';
7
+ import path from 'path';
8
+ import fs from 'fs';
9
+ import { chromium } from 'playwright';
10
+ import sharp from 'sharp';
11
+ import { LingoIntegration } from '../core/lingo-integration.js';
12
+ export const visualCommand = new Command('visual')
13
+ .description('Generate a visual comparison grid of 4 locales')
14
+ .argument('<url>', 'URL to audit (e.g., http://localhost:3000)')
15
+ .option('-o, --output <file>', 'Output file path', 'visual-report.png')
16
+ .option('-p, --project <path>', 'Path to project directory containing i18n.json', process.cwd())
17
+ .action(async (url, options) => {
18
+ await runVisualAudit(url, options);
19
+ });
20
+ async function runVisualAudit(url, options) {
21
+ const spinner = ora('Starting Visual Audit...').start();
22
+ const projectPath = path.resolve(options.project);
23
+ const lingo = new LingoIntegration(projectPath, true);
24
+ // 1. Generate Lingo Translations
25
+ try {
26
+ spinner.text = 'Generating translations (pseudo-locale)...';
27
+ // We ensure pseudo is enabled and generated
28
+ await lingo.enablePseudoLocale();
29
+ await lingo.runTranslation({ force: false });
30
+ spinner.succeed('Translations ready');
31
+ }
32
+ catch (e) {
33
+ spinner.warn('Could not generate translations (continuing anyway)');
34
+ }
35
+ spinner.start('Launching browser for screenshots...');
36
+ let browser = null;
37
+ try {
38
+ browser = await chromium.launch({
39
+ headless: true,
40
+ args: ['--no-sandbox', '--disable-dev-shm-usage'],
41
+ });
42
+ const context = await browser.newContext({
43
+ viewport: { width: 1200, height: 800 }, // Standard viewport
44
+ });
45
+ const page = await context.newPage();
46
+ const locales = [
47
+ { code: 'en', name: 'Original (English)' },
48
+ { code: 'pseudo', name: 'Stress Test (German/Expansion)' },
49
+ { code: 'ar', name: 'RTL (Arabic)' },
50
+ { code: 'ja', name: 'Characters (Japanese)' } // Ensure user has 'ja' in lingo config or it defaults to English?
51
+ // Actually lingo SDK handles fallback.
52
+ ];
53
+ const screenshots = [];
54
+ for (const locale of locales) {
55
+ spinner.text = `Snapping ${locale.name}...`;
56
+ // Build URL: append ?lang=code (common Lingo SDK pattern)
57
+ // If already has params, append &lang=code
58
+ const localeUrl = new URL(url);
59
+ localeUrl.searchParams.set('lang', locale.code);
60
+ await page.goto(localeUrl.toString(), { waitUntil: 'networkidle' });
61
+ // Inject a label overlay on the screenshot?
62
+ // The user didn't ask for it, but it helps.
63
+ // For now, raw screenshots.
64
+ const buffer = await page.screenshot({ fullPage: false }); // User used fullPage: true but grid needs fixed size usually.
65
+ // User script: await page.screenshot({ fullPage: true });
66
+ // But then stitching logic: top: 0, left: width.
67
+ // If pages are different heights, grid is messy.
68
+ // I'll stick to viewport screenshot for clean grid.
69
+ screenshots.push({ buffer, label: locale.name });
70
+ }
71
+ await browser.close();
72
+ browser = null;
73
+ // 2. Stitch Images
74
+ spinner.text = 'Creating Composite Grid...';
75
+ const width = 1200;
76
+ const height = 800;
77
+ // 2x2 Grid configuration
78
+ // Top-Left: En, Top-Right: Pseudo
79
+ // Bot-Left: Ar, Bot-Right: Ja
80
+ const composite = await sharp({
81
+ create: {
82
+ width: width * 2,
83
+ height: height * 2,
84
+ channels: 4,
85
+ background: { r: 255, g: 255, b: 255, alpha: 1 }
86
+ }
87
+ })
88
+ .composite([
89
+ { input: screenshots[0].buffer, top: 0, left: 0 },
90
+ { input: screenshots[1].buffer, top: 0, left: width },
91
+ { input: screenshots[2].buffer, top: height, left: 0 },
92
+ { input: screenshots[3].buffer, top: height, left: width },
93
+ ])
94
+ .png()
95
+ .toBuffer();
96
+ const outputPath = path.resolve(options.output);
97
+ fs.writeFileSync(outputPath, composite);
98
+ spinner.succeed(chalk.green(`Generated visual report: ${outputPath}`));
99
+ }
100
+ catch (error) {
101
+ spinner.fail('Visual audit failed');
102
+ console.error(error);
103
+ if (browser)
104
+ await browser.close();
105
+ process.exit(1);
106
+ }
107
+ }
108
+ //# sourceMappingURL=visual.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"visual.js","sourceRoot":"","sources":["../../src/commands/visual.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lingo-guardian",
3
- "version": "0.1.2",
3
+ "version": "0.1.3",
4
4
  "description": "CLI tool to detect i18n layout issues - CSS overflows, RTL breaks, and text expansion problems. Powered by Lingo.dev",
5
5
  "author": "Lingo-Guardian Team",
6
6
  "license": "MIT",
@@ -33,10 +33,12 @@
33
33
  "postinstall": "npx playwright install chromium --with-deps 2>/dev/null || true"
34
34
  },
35
35
  "dependencies": {
36
+ "@types/sharp": "^0.31.1",
36
37
  "chalk": "^5.3.0",
37
38
  "commander": "^11.1.0",
38
39
  "ora": "^8.0.1",
39
40
  "playwright": "^1.40.0",
41
+ "sharp": "^0.34.5",
40
42
  "table": "^6.8.1"
41
43
  },
42
44
  "devDependencies": {