lingo-guardian 0.1.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 (38) hide show
  1. package/README.md +45 -0
  2. package/dist/bin/cli.d.ts +10 -0
  3. package/dist/bin/cli.d.ts.map +1 -0
  4. package/dist/bin/cli.js +36 -0
  5. package/dist/bin/cli.js.map +1 -0
  6. package/dist/commands/lint.d.ts +19 -0
  7. package/dist/commands/lint.d.ts.map +1 -0
  8. package/dist/commands/lint.js +166 -0
  9. package/dist/commands/lint.js.map +1 -0
  10. package/dist/constants.d.ts +110 -0
  11. package/dist/constants.d.ts.map +1 -0
  12. package/dist/constants.js +41 -0
  13. package/dist/constants.js.map +1 -0
  14. package/dist/core/auditor.d.ts +62 -0
  15. package/dist/core/auditor.d.ts.map +1 -0
  16. package/dist/core/auditor.js +261 -0
  17. package/dist/core/auditor.js.map +1 -0
  18. package/dist/core/lingo-integration.d.ts +109 -0
  19. package/dist/core/lingo-integration.d.ts.map +1 -0
  20. package/dist/core/lingo-integration.js +243 -0
  21. package/dist/core/lingo-integration.js.map +1 -0
  22. package/dist/index.d.ts +12 -0
  23. package/dist/index.d.ts.map +1 -0
  24. package/dist/index.js +11 -0
  25. package/dist/index.js.map +1 -0
  26. package/dist/reporters/reporter.d.ts +35 -0
  27. package/dist/reporters/reporter.d.ts.map +1 -0
  28. package/dist/reporters/reporter.js +322 -0
  29. package/dist/reporters/reporter.js.map +1 -0
  30. package/dist/transforms/pseudo-locale.d.ts +22 -0
  31. package/dist/transforms/pseudo-locale.d.ts.map +1 -0
  32. package/dist/transforms/pseudo-locale.js +181 -0
  33. package/dist/transforms/pseudo-locale.js.map +1 -0
  34. package/dist/transforms/rtl.d.ts +26 -0
  35. package/dist/transforms/rtl.d.ts.map +1 -0
  36. package/dist/transforms/rtl.js +120 -0
  37. package/dist/transforms/rtl.js.map +1 -0
  38. package/package.json +70 -0
@@ -0,0 +1,261 @@
1
+ /**
2
+ * Auditor - Core engine for detecting i18n layout issues
3
+ *
4
+ * Uses Playwright (cross-platform: Mac, Windows, Linux) to analyze pages for:
5
+ * - Text overflow (scrollWidth > offsetWidth)
6
+ * - Text truncation (text-overflow: ellipsis detection)
7
+ * - Layout breaks in RTL mode
8
+ */
9
+ import { chromium } from 'playwright';
10
+ import { DEFAULTS } from '../constants.js';
11
+ import { PseudoLocaleTransform } from '../transforms/pseudo-locale.js';
12
+ import { RTLTransform } from '../transforms/rtl.js';
13
+ /**
14
+ * Core Auditor class for detecting i18n layout issues
15
+ *
16
+ * Uses Playwright for cross-platform browser automation (Mac, Windows, Linux)
17
+ */
18
+ export class Auditor {
19
+ browser = null;
20
+ context = null;
21
+ options;
22
+ constructor(options = {}) {
23
+ this.options = {
24
+ width: options.width ?? DEFAULTS.VIEWPORT_WIDTH,
25
+ height: options.height ?? DEFAULTS.VIEWPORT_HEIGHT,
26
+ timeout: options.timeout ?? DEFAULTS.TIMEOUT,
27
+ screenshots: options.screenshots ?? false,
28
+ outputDir: options.outputDir ?? './lingo-guardian-reports',
29
+ verbose: options.verbose ?? false,
30
+ };
31
+ }
32
+ /**
33
+ * Initialize the browser instance
34
+ * Playwright handles cross-platform browser binaries automatically
35
+ */
36
+ async init() {
37
+ if (this.browser)
38
+ return;
39
+ this.log('Launching Playwright browser (Chromium)...');
40
+ // Playwright handles cross-platform automatically
41
+ this.browser = await chromium.launch({
42
+ headless: true,
43
+ // These args work across Mac, Windows, and Linux
44
+ args: [
45
+ '--no-sandbox',
46
+ '--disable-dev-shm-usage',
47
+ ],
48
+ });
49
+ this.context = await this.browser.newContext({
50
+ viewport: {
51
+ width: this.options.width,
52
+ height: this.options.height,
53
+ },
54
+ });
55
+ }
56
+ /**
57
+ * Close the browser instance
58
+ */
59
+ async close() {
60
+ if (this.context) {
61
+ await this.context.close();
62
+ this.context = null;
63
+ }
64
+ if (this.browser) {
65
+ await this.browser.close();
66
+ this.browser = null;
67
+ }
68
+ }
69
+ /**
70
+ * Audit a URL for i18n layout issues
71
+ */
72
+ async audit(url, locale = 'en') {
73
+ const startTime = Date.now();
74
+ if (!this.browser || !this.context) {
75
+ await this.init();
76
+ }
77
+ const page = await this.context.newPage();
78
+ try {
79
+ this.log(`Navigating to ${url}...`);
80
+ await page.goto(url, {
81
+ waitUntil: 'networkidle',
82
+ timeout: this.options.timeout,
83
+ });
84
+ // Apply locale transformations (fallback when Lingo.dev not used)
85
+ await this.applyLocaleTransform(page, locale);
86
+ // Wait for any reflow after transformations
87
+ await page.waitForTimeout(500);
88
+ // Detect overflow issues
89
+ this.log(`Scanning for overflow issues (locale: ${locale})...`);
90
+ const issues = await this.detectOverflows(page, locale);
91
+ const duration = Date.now() - startTime;
92
+ return {
93
+ url,
94
+ locale,
95
+ timestamp: new Date().toISOString(),
96
+ issueCount: issues.length,
97
+ issues,
98
+ duration,
99
+ };
100
+ }
101
+ finally {
102
+ await page.close();
103
+ }
104
+ }
105
+ /**
106
+ * Apply locale-specific transformations to the page
107
+ * These are fallback transforms when Lingo.dev integration is not used
108
+ */
109
+ async applyLocaleTransform(page, locale) {
110
+ switch (locale.toLowerCase()) {
111
+ case 'pseudo':
112
+ this.log('Applying pseudo-locale transformation...');
113
+ await PseudoLocaleTransform.applyPlaywright(page);
114
+ break;
115
+ case 'ar':
116
+ case 'he':
117
+ case 'fa':
118
+ case 'ur':
119
+ this.log(`Applying RTL transformation for ${locale}...`);
120
+ await RTLTransform.applyPlaywright(page, locale);
121
+ break;
122
+ case 'de':
123
+ // German has ~30% longer text - simulate expansion
124
+ this.log('Applying German expansion simulation...');
125
+ await PseudoLocaleTransform.applyPlaywright(page, 0.3);
126
+ break;
127
+ case 'ja':
128
+ case 'zh':
129
+ case 'ko':
130
+ // CJK languages - check for font loading and character rendering
131
+ this.log(`Checking CJK rendering for ${locale}...`);
132
+ break;
133
+ default:
134
+ // English or other - no transformation
135
+ this.log(`No transformation for locale: ${locale}`);
136
+ break;
137
+ }
138
+ }
139
+ /**
140
+ * Detect elements with overflow issues
141
+ * Core detection logic: element.scrollWidth > element.offsetWidth
142
+ */
143
+ async detectOverflows(page, locale) {
144
+ const excludedSelectorsList = [...DEFAULTS.EXCLUDED_SELECTORS];
145
+ const issues = await page.evaluate((excludedSelectors) => {
146
+ const results = [];
147
+ // Get all text-containing elements
148
+ const walker = document.createTreeWalker(document.body, NodeFilter.SHOW_ELEMENT, {
149
+ acceptNode: (node) => {
150
+ const el = node;
151
+ const tagName = el.tagName.toLowerCase();
152
+ if (excludedSelectors.includes(tagName)) {
153
+ return NodeFilter.FILTER_REJECT;
154
+ }
155
+ return NodeFilter.FILTER_ACCEPT;
156
+ },
157
+ });
158
+ const elements = [];
159
+ let currentNode;
160
+ while ((currentNode = walker.nextNode())) {
161
+ elements.push(currentNode);
162
+ }
163
+ for (const el of elements) {
164
+ const htmlEl = el;
165
+ const rect = htmlEl.getBoundingClientRect();
166
+ if (rect.width === 0 || rect.height === 0)
167
+ continue;
168
+ const scrollWidth = htmlEl.scrollWidth;
169
+ const offsetWidth = htmlEl.offsetWidth;
170
+ const scrollHeight = htmlEl.scrollHeight;
171
+ const offsetHeight = htmlEl.offsetHeight;
172
+ // The "Red Glow" Detection - core logic
173
+ const hasHorizontalOverflow = scrollWidth > offsetWidth + 1;
174
+ const hasVerticalOverflow = scrollHeight > offsetHeight + 1;
175
+ if (hasHorizontalOverflow || hasVerticalOverflow) {
176
+ const selector = generateSelector(el);
177
+ const textContent = htmlEl.textContent?.trim().slice(0, 50) || '';
178
+ let overflowDirection;
179
+ if (hasHorizontalOverflow && hasVerticalOverflow) {
180
+ overflowDirection = 'both';
181
+ }
182
+ else if (hasHorizontalOverflow) {
183
+ overflowDirection = 'horizontal';
184
+ }
185
+ else {
186
+ overflowDirection = 'vertical';
187
+ }
188
+ const overflowAmount = Math.max(scrollWidth - offsetWidth, scrollHeight - offsetHeight);
189
+ let severity;
190
+ if (overflowAmount > 50) {
191
+ severity = 'error';
192
+ }
193
+ else if (overflowAmount > 20) {
194
+ severity = 'warning';
195
+ }
196
+ else {
197
+ severity = 'info';
198
+ }
199
+ results.push({
200
+ selector,
201
+ tagName: el.tagName.toLowerCase(),
202
+ textContent,
203
+ offsetWidth,
204
+ scrollWidth,
205
+ offsetHeight,
206
+ scrollHeight,
207
+ overflowDirection,
208
+ severity,
209
+ boundingRect: {
210
+ x: rect.x,
211
+ y: rect.y,
212
+ width: rect.width,
213
+ height: rect.height,
214
+ },
215
+ });
216
+ }
217
+ }
218
+ function generateSelector(el) {
219
+ if (el.id) {
220
+ return `#${el.id}`;
221
+ }
222
+ const path = [];
223
+ let current = el;
224
+ while (current && current !== document.body) {
225
+ let selector = current.tagName.toLowerCase();
226
+ if (current.className && typeof current.className === 'string') {
227
+ const classes = current.className.trim().split(/\s+/).slice(0, 2);
228
+ if (classes.length > 0 && classes[0]) {
229
+ selector += '.' + classes.join('.');
230
+ }
231
+ }
232
+ const parent = current.parentElement;
233
+ if (parent) {
234
+ const siblings = Array.from(parent.children).filter((c) => c.tagName === current.tagName);
235
+ if (siblings.length > 1) {
236
+ const index = siblings.indexOf(current) + 1;
237
+ selector += `:nth-child(${index})`;
238
+ }
239
+ }
240
+ path.unshift(selector);
241
+ current = current.parentElement;
242
+ }
243
+ return path.join(' > ');
244
+ }
245
+ return results;
246
+ }, excludedSelectorsList);
247
+ return issues.map((issue) => ({
248
+ ...issue,
249
+ locale,
250
+ }));
251
+ }
252
+ /**
253
+ * Log message if verbose mode is enabled
254
+ */
255
+ log(message) {
256
+ if (this.options.verbose) {
257
+ console.log(` [Auditor] ${message}`);
258
+ }
259
+ }
260
+ }
261
+ //# sourceMappingURL=auditor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auditor.js","sourceRoot":"","sources":["../../src/core/auditor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,109 @@
1
+ /**
2
+ * Lingo.dev Integration Module
3
+ *
4
+ * This module integrates with the official Lingo.dev CLI and SDK.
5
+ * It runs `npx lingo.dev run` to generate translations using their engine.
6
+ *
7
+ * This is the KEY integration that makes Lingo-Guardian work with Lingo.dev
8
+ * rather than being a standalone tool.
9
+ */
10
+ /**
11
+ * Lingo.dev configuration file structure
12
+ */
13
+ export interface LingoConfig {
14
+ $schema?: string;
15
+ version: string;
16
+ locale: {
17
+ source: string;
18
+ targets: string[];
19
+ };
20
+ buckets: Record<string, {
21
+ include: string[];
22
+ exclude?: string[];
23
+ }>;
24
+ }
25
+ /**
26
+ * Result of running Lingo.dev CLI
27
+ */
28
+ export interface LingoRunResult {
29
+ success: boolean;
30
+ output: string;
31
+ error?: string;
32
+ localesGenerated: string[];
33
+ filesModified: string[];
34
+ }
35
+ /**
36
+ * Lingo.dev Integration - Orchestrates the Lingo.dev CLI
37
+ *
38
+ * Usage:
39
+ * const lingo = new LingoIntegration('/path/to/project');
40
+ * await lingo.detectConfig();
41
+ * await lingo.runTranslation({ locale: 'pseudo' });
42
+ */
43
+ export declare class LingoIntegration {
44
+ private projectPath;
45
+ private configPath;
46
+ private config;
47
+ private verbose;
48
+ constructor(projectPath: string, verbose?: boolean);
49
+ /**
50
+ * Detect Lingo.dev configuration in the project
51
+ * Looks for: i18n.json, lingo.config.js, lingo.config.json
52
+ */
53
+ detectConfig(): Promise<boolean>;
54
+ /**
55
+ * Get the detected configuration
56
+ */
57
+ getConfig(): LingoConfig | null;
58
+ /**
59
+ * Get available target locales from config
60
+ */
61
+ getTargetLocales(): string[];
62
+ /**
63
+ * Get source locale from config
64
+ */
65
+ getSourceLocale(): string;
66
+ /**
67
+ * Initialize a new Lingo.dev project if config doesn't exist
68
+ */
69
+ initProject(): Promise<boolean>;
70
+ /**
71
+ * Run Lingo.dev CLI translation
72
+ *
73
+ * This is the KEY integration - we run their CLI to generate translations
74
+ *
75
+ * @param options.locale - Optional specific locale to target
76
+ * @param options.force - Force retranslation even if cached
77
+ */
78
+ runTranslation(options?: {
79
+ locale?: string;
80
+ force?: boolean;
81
+ }): Promise<LingoRunResult>;
82
+ /**
83
+ * Add pseudo-locale to the Lingo.dev config if not present
84
+ * This enables testing with expanded text
85
+ */
86
+ enablePseudoLocale(): Promise<boolean>;
87
+ /**
88
+ * Check if Lingo.dev CLI is available
89
+ */
90
+ isLingoCliAvailable(): Promise<boolean>;
91
+ /**
92
+ * Get the locale query parameter for SDK integration
93
+ * The Lingo.dev SDK can switch locales via URL param
94
+ */
95
+ getLocaleQueryParam(locale: string): string;
96
+ /**
97
+ * Parse generated locales from CLI output
98
+ */
99
+ private parseLocalesFromOutput;
100
+ /**
101
+ * Parse modified files from CLI output
102
+ */
103
+ private parseFilesFromOutput;
104
+ /**
105
+ * Log message if verbose mode is enabled
106
+ */
107
+ private log;
108
+ }
109
+ //# sourceMappingURL=lingo-integration.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lingo-integration.d.ts","sourceRoot":"","sources":["../../src/core/lingo-integration.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AASH;;GAEG;AACH,MAAM,WAAW,WAAW;IACxB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE;QACJ,MAAM,EAAE,MAAM,CAAC;QACf,OAAO,EAAE,MAAM,EAAE,CAAC;KACrB,CAAC;IACF,OAAO,EAAE,MAAM,CACX,MAAM,EACN;QACI,OAAO,EAAE,MAAM,EAAE,CAAC;QAClB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;KACtB,CACJ,CAAC;CACL;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC3B,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,gBAAgB,EAAE,MAAM,EAAE,CAAC;IAC3B,aAAa,EAAE,MAAM,EAAE,CAAC;CAC3B;AAED;;;;;;;GAOG;AACH,qBAAa,gBAAgB;IACzB,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,UAAU,CAAuB;IACzC,OAAO,CAAC,MAAM,CAA4B;IAC1C,OAAO,CAAC,OAAO,CAAU;gBAEb,WAAW,EAAE,MAAM,EAAE,OAAO,UAAQ;IAKhD;;;OAGG;IACG,YAAY,IAAI,OAAO,CAAC,OAAO,CAAC;IA0BtC;;OAEG;IACH,SAAS,IAAI,WAAW,GAAG,IAAI;IAI/B;;OAEG;IACH,gBAAgB,IAAI,MAAM,EAAE;IAK5B;;OAEG;IACH,eAAe,IAAI,MAAM;IAIzB;;OAEG;IACG,WAAW,IAAI,OAAO,CAAC,OAAO,CAAC;IAqBrC;;;;;;;OAOG;IACG,cAAc,CAAC,OAAO,GAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,OAAO,CAAA;KAAO,GAAG,OAAO,CAAC,cAAc,CAAC;IA6DjG;;;OAGG;IACG,kBAAkB,IAAI,OAAO,CAAC,OAAO,CAAC;IA0B5C;;OAEG;IACG,mBAAmB,IAAI,OAAO,CAAC,OAAO,CAAC;IAS7C;;;OAGG;IACH,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM;IAI3C;;OAEG;IACH,OAAO,CAAC,sBAAsB;IAY9B;;OAEG;IACH,OAAO,CAAC,oBAAoB;IAY5B;;OAEG;IACH,OAAO,CAAC,GAAG;CAKd"}
@@ -0,0 +1,243 @@
1
+ /**
2
+ * Lingo.dev Integration Module
3
+ *
4
+ * This module integrates with the official Lingo.dev CLI and SDK.
5
+ * It runs `npx lingo.dev run` to generate translations using their engine.
6
+ *
7
+ * This is the KEY integration that makes Lingo-Guardian work with Lingo.dev
8
+ * rather than being a standalone tool.
9
+ */
10
+ import { spawn, exec } from 'child_process';
11
+ import { promisify } from 'util';
12
+ import fs from 'fs/promises';
13
+ import path from 'path';
14
+ const execAsync = promisify(exec);
15
+ /**
16
+ * Lingo.dev Integration - Orchestrates the Lingo.dev CLI
17
+ *
18
+ * Usage:
19
+ * const lingo = new LingoIntegration('/path/to/project');
20
+ * await lingo.detectConfig();
21
+ * await lingo.runTranslation({ locale: 'pseudo' });
22
+ */
23
+ export class LingoIntegration {
24
+ projectPath;
25
+ configPath = null;
26
+ config = null;
27
+ verbose;
28
+ constructor(projectPath, verbose = false) {
29
+ this.projectPath = projectPath;
30
+ this.verbose = verbose;
31
+ }
32
+ /**
33
+ * Detect Lingo.dev configuration in the project
34
+ * Looks for: i18n.json, lingo.config.js, lingo.config.json
35
+ */
36
+ async detectConfig() {
37
+ const configFiles = ['i18n.json', 'lingo.config.json', 'lingo.config.js'];
38
+ for (const configFile of configFiles) {
39
+ const fullPath = path.join(this.projectPath, configFile);
40
+ try {
41
+ await fs.access(fullPath);
42
+ this.configPath = fullPath;
43
+ this.log(`Found Lingo.dev config: ${configFile}`);
44
+ // Read the config
45
+ if (configFile.endsWith('.json')) {
46
+ const content = await fs.readFile(fullPath, 'utf-8');
47
+ this.config = JSON.parse(content);
48
+ }
49
+ return true;
50
+ }
51
+ catch {
52
+ // File doesn't exist, try next
53
+ }
54
+ }
55
+ this.log('No Lingo.dev config found');
56
+ return false;
57
+ }
58
+ /**
59
+ * Get the detected configuration
60
+ */
61
+ getConfig() {
62
+ return this.config;
63
+ }
64
+ /**
65
+ * Get available target locales from config
66
+ */
67
+ getTargetLocales() {
68
+ if (!this.config)
69
+ return [];
70
+ return this.config.locale.targets;
71
+ }
72
+ /**
73
+ * Get source locale from config
74
+ */
75
+ getSourceLocale() {
76
+ return this.config?.locale.source || 'en';
77
+ }
78
+ /**
79
+ * Initialize a new Lingo.dev project if config doesn't exist
80
+ */
81
+ async initProject() {
82
+ this.log('Initializing Lingo.dev project...');
83
+ try {
84
+ const { stdout, stderr } = await execAsync('npx lingo.dev@latest init --yes', {
85
+ cwd: this.projectPath,
86
+ timeout: 60000,
87
+ });
88
+ this.log(stdout);
89
+ if (stderr)
90
+ this.log(`Warning: ${stderr}`);
91
+ // Re-detect config after init
92
+ return this.detectConfig();
93
+ }
94
+ catch (error) {
95
+ const err = error;
96
+ this.log(`Failed to init: ${err.message}`);
97
+ return false;
98
+ }
99
+ }
100
+ /**
101
+ * Run Lingo.dev CLI translation
102
+ *
103
+ * This is the KEY integration - we run their CLI to generate translations
104
+ *
105
+ * @param options.locale - Optional specific locale to target
106
+ * @param options.force - Force retranslation even if cached
107
+ */
108
+ async runTranslation(options = {}) {
109
+ const args = ['lingo.dev@latest', 'run'];
110
+ if (options.locale) {
111
+ args.push('--locale', options.locale);
112
+ }
113
+ if (options.force) {
114
+ args.push('--force');
115
+ }
116
+ this.log(`Running: npx ${args.join(' ')}`);
117
+ return new Promise((resolve) => {
118
+ const proc = spawn('npx', args, {
119
+ cwd: this.projectPath,
120
+ shell: true,
121
+ env: { ...process.env },
122
+ });
123
+ let output = '';
124
+ let errorOutput = '';
125
+ proc.stdout.on('data', (data) => {
126
+ const text = data.toString();
127
+ output += text;
128
+ if (this.verbose)
129
+ console.log(text);
130
+ });
131
+ proc.stderr.on('data', (data) => {
132
+ const text = data.toString();
133
+ errorOutput += text;
134
+ if (this.verbose)
135
+ console.error(text);
136
+ });
137
+ proc.on('close', (code) => {
138
+ const success = code === 0;
139
+ const localesGenerated = this.parseLocalesFromOutput(output);
140
+ const filesModified = this.parseFilesFromOutput(output);
141
+ resolve({
142
+ success,
143
+ output,
144
+ error: errorOutput || undefined,
145
+ localesGenerated,
146
+ filesModified,
147
+ });
148
+ });
149
+ proc.on('error', (error) => {
150
+ resolve({
151
+ success: false,
152
+ output,
153
+ error: error.message,
154
+ localesGenerated: [],
155
+ filesModified: [],
156
+ });
157
+ });
158
+ });
159
+ }
160
+ /**
161
+ * Add pseudo-locale to the Lingo.dev config if not present
162
+ * This enables testing with expanded text
163
+ */
164
+ async enablePseudoLocale() {
165
+ if (!this.config || !this.configPath) {
166
+ this.log('No config to modify');
167
+ return false;
168
+ }
169
+ // Check if pseudo is already a target
170
+ if (this.config.locale.targets.includes('pseudo')) {
171
+ this.log('Pseudo-locale already enabled');
172
+ return true;
173
+ }
174
+ // Add pseudo to targets
175
+ this.config.locale.targets.push('pseudo');
176
+ try {
177
+ await fs.writeFile(this.configPath, JSON.stringify(this.config, null, 2), 'utf-8');
178
+ this.log('Added pseudo-locale to config');
179
+ return true;
180
+ }
181
+ catch (error) {
182
+ const err = error;
183
+ this.log(`Failed to update config: ${err.message}`);
184
+ return false;
185
+ }
186
+ }
187
+ /**
188
+ * Check if Lingo.dev CLI is available
189
+ */
190
+ async isLingoCliAvailable() {
191
+ try {
192
+ await execAsync('npx lingo.dev@latest --version', { timeout: 10000 });
193
+ return true;
194
+ }
195
+ catch {
196
+ return false;
197
+ }
198
+ }
199
+ /**
200
+ * Get the locale query parameter for SDK integration
201
+ * The Lingo.dev SDK can switch locales via URL param
202
+ */
203
+ getLocaleQueryParam(locale) {
204
+ return `?lang=${locale}`;
205
+ }
206
+ /**
207
+ * Parse generated locales from CLI output
208
+ */
209
+ parseLocalesFromOutput(output) {
210
+ const locales = [];
211
+ const matches = output.match(/Translating to (\w+)/g);
212
+ if (matches) {
213
+ for (const match of matches) {
214
+ const locale = match.replace('Translating to ', '');
215
+ locales.push(locale);
216
+ }
217
+ }
218
+ return locales;
219
+ }
220
+ /**
221
+ * Parse modified files from CLI output
222
+ */
223
+ parseFilesFromOutput(output) {
224
+ const files = [];
225
+ const matches = output.match(/Writing to ([^\s]+)/g);
226
+ if (matches) {
227
+ for (const match of matches) {
228
+ const file = match.replace('Writing to ', '');
229
+ files.push(file);
230
+ }
231
+ }
232
+ return files;
233
+ }
234
+ /**
235
+ * Log message if verbose mode is enabled
236
+ */
237
+ log(message) {
238
+ if (this.verbose) {
239
+ console.log(` [Lingo.dev] ${message}`);
240
+ }
241
+ }
242
+ }
243
+ //# sourceMappingURL=lingo-integration.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lingo-integration.js","sourceRoot":"","sources":["../../src/core/lingo-integration.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,SAAS,EAAE,MAAM,MAAM,CAAC;AACjC,OAAO,EAAE,MAAM,aAAa,CAAC;AAC7B,OAAO,IAAI,MAAM,MAAM,CAAC;AAExB,MAAM,SAAS,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;AAgClC;;;;;;;GAOG;AACH,MAAM,OAAO,gBAAgB;IACjB,WAAW,CAAS;IACpB,UAAU,GAAkB,IAAI,CAAC;IACjC,MAAM,GAAuB,IAAI,CAAC;IAClC,OAAO,CAAU;IAEzB,YAAY,WAAmB,EAAE,OAAO,GAAG,KAAK;QAC5C,IAAI,CAAC,WAAW,GAAG,WAAW,CAAC;QAC/B,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;IAC3B,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,YAAY;QACd,MAAM,WAAW,GAAG,CAAC,WAAW,EAAE,mBAAmB,EAAE,iBAAiB,CAAC,CAAC;QAE1E,KAAK,MAAM,UAAU,IAAI,WAAW,EAAE,CAAC;YACnC,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,UAAU,CAAC,CAAC;YACzD,IAAI,CAAC;gBACD,MAAM,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;gBAC1B,IAAI,CAAC,UAAU,GAAG,QAAQ,CAAC;gBAC3B,IAAI,CAAC,GAAG,CAAC,2BAA2B,UAAU,EAAE,CAAC,CAAC;gBAElD,kBAAkB;gBAClB,IAAI,UAAU,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;oBAC/B,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;oBACrD,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAgB,CAAC;gBACrD,CAAC;gBAED,OAAO,IAAI,CAAC;YAChB,CAAC;YAAC,MAAM,CAAC;gBACL,+BAA+B;YACnC,CAAC;QACL,CAAC;QAED,IAAI,CAAC,GAAG,CAAC,2BAA2B,CAAC,CAAC;QACtC,OAAO,KAAK,CAAC;IACjB,CAAC;IAED;;OAEG;IACH,SAAS;QACL,OAAO,IAAI,CAAC,MAAM,CAAC;IACvB,CAAC;IAED;;OAEG;IACH,gBAAgB;QACZ,IAAI,CAAC,IAAI,CAAC,MAAM;YAAE,OAAO,EAAE,CAAC;QAC5B,OAAO,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC;IACtC,CAAC;IAED;;OAEG;IACH,eAAe;QACX,OAAO,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,IAAI,IAAI,CAAC;IAC9C,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,WAAW;QACb,IAAI,CAAC,GAAG,CAAC,mCAAmC,CAAC,CAAC;QAE9C,IAAI,CAAC;YACD,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,SAAS,CAAC,iCAAiC,EAAE;gBAC1E,GAAG,EAAE,IAAI,CAAC,WAAW;gBACrB,OAAO,EAAE,KAAK;aACjB,CAAC,CAAC;YAEH,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;YACjB,IAAI,MAAM;gBAAE,IAAI,CAAC,GAAG,CAAC,YAAY,MAAM,EAAE,CAAC,CAAC;YAE3C,8BAA8B;YAC9B,OAAO,IAAI,CAAC,YAAY,EAAE,CAAC;QAC/B,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACb,MAAM,GAAG,GAAG,KAAc,CAAC;YAC3B,IAAI,CAAC,GAAG,CAAC,mBAAmB,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;YAC3C,OAAO,KAAK,CAAC;QACjB,CAAC;IACL,CAAC;IAED;;;;;;;OAOG;IACH,KAAK,CAAC,cAAc,CAAC,UAAgD,EAAE;QACnE,MAAM,IAAI,GAAG,CAAC,kBAAkB,EAAE,KAAK,CAAC,CAAC;QAEzC,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;YACjB,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;QAC1C,CAAC;QAED,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC;YAChB,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QACzB,CAAC;QAED,IAAI,CAAC,GAAG,CAAC,gBAAgB,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAE3C,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;YAC3B,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,EAAE,IAAI,EAAE;gBAC5B,GAAG,EAAE,IAAI,CAAC,WAAW;gBACrB,KAAK,EAAE,IAAI;gBACX,GAAG,EAAE,EAAE,GAAG,OAAO,CAAC,GAAG,EAAE;aAC1B,CAAC,CAAC;YAEH,IAAI,MAAM,GAAG,EAAE,CAAC;YAChB,IAAI,WAAW,GAAG,EAAE,CAAC;YAErB,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,IAAY,EAAE,EAAE;gBACpC,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC;gBAC7B,MAAM,IAAI,IAAI,CAAC;gBACf,IAAI,IAAI,CAAC,OAAO;oBAAE,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;YACxC,CAAC,CAAC,CAAC;YAEH,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,IAAY,EAAE,EAAE;gBACpC,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC;gBAC7B,WAAW,IAAI,IAAI,CAAC;gBACpB,IAAI,IAAI,CAAC,OAAO;oBAAE,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YAC1C,CAAC,CAAC,CAAC;YAEH,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE;gBACtB,MAAM,OAAO,GAAG,IAAI,KAAK,CAAC,CAAC;gBAC3B,MAAM,gBAAgB,GAAG,IAAI,CAAC,sBAAsB,CAAC,MAAM,CAAC,CAAC;gBAC7D,MAAM,aAAa,GAAG,IAAI,CAAC,oBAAoB,CAAC,MAAM,CAAC,CAAC;gBAExD,OAAO,CAAC;oBACJ,OAAO;oBACP,MAAM;oBACN,KAAK,EAAE,WAAW,IAAI,SAAS;oBAC/B,gBAAgB;oBAChB,aAAa;iBAChB,CAAC,CAAC;YACP,CAAC,CAAC,CAAC;YAEH,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE;gBACvB,OAAO,CAAC;oBACJ,OAAO,EAAE,KAAK;oBACd,MAAM;oBACN,KAAK,EAAE,KAAK,CAAC,OAAO;oBACpB,gBAAgB,EAAE,EAAE;oBACpB,aAAa,EAAE,EAAE;iBACpB,CAAC,CAAC;YACP,CAAC,CAAC,CAAC;QACP,CAAC,CAAC,CAAC;IACP,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,kBAAkB;QACpB,IAAI,CAAC,IAAI,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC;YACnC,IAAI,CAAC,GAAG,CAAC,qBAAqB,CAAC,CAAC;YAChC,OAAO,KAAK,CAAC;QACjB,CAAC;QAED,sCAAsC;QACtC,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;YAChD,IAAI,CAAC,GAAG,CAAC,+BAA+B,CAAC,CAAC;YAC1C,OAAO,IAAI,CAAC;QAChB,CAAC;QAED,wBAAwB;QACxB,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAE1C,IAAI,CAAC;YACD,MAAM,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;YACnF,IAAI,CAAC,GAAG,CAAC,+BAA+B,CAAC,CAAC;YAC1C,OAAO,IAAI,CAAC;QAChB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACb,MAAM,GAAG,GAAG,KAAc,CAAC;YAC3B,IAAI,CAAC,GAAG,CAAC,4BAA4B,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;YACpD,OAAO,KAAK,CAAC;QACjB,CAAC;IACL,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,mBAAmB;QACrB,IAAI,CAAC;YACD,MAAM,SAAS,CAAC,gCAAgC,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC;YACtE,OAAO,IAAI,CAAC;QAChB,CAAC;QAAC,MAAM,CAAC;YACL,OAAO,KAAK,CAAC;QACjB,CAAC;IACL,CAAC;IAED;;;OAGG;IACH,mBAAmB,CAAC,MAAc;QAC9B,OAAO,SAAS,MAAM,EAAE,CAAC;IAC7B,CAAC;IAED;;OAEG;IACK,sBAAsB,CAAC,MAAc;QACzC,MAAM,OAAO,GAAa,EAAE,CAAC;QAC7B,MAAM,OAAO,GAAG,MAAM,CAAC,KAAK,CAAC,uBAAuB,CAAC,CAAC;QACtD,IAAI,OAAO,EAAE,CAAC;YACV,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;gBAC1B,MAAM,MAAM,GAAG,KAAK,CAAC,OAAO,CAAC,iBAAiB,EAAE,EAAE,CAAC,CAAC;gBACpD,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YACzB,CAAC;QACL,CAAC;QACD,OAAO,OAAO,CAAC;IACnB,CAAC;IAED;;OAEG;IACK,oBAAoB,CAAC,MAAc;QACvC,MAAM,KAAK,GAAa,EAAE,CAAC;QAC3B,MAAM,OAAO,GAAG,MAAM,CAAC,KAAK,CAAC,sBAAsB,CAAC,CAAC;QACrD,IAAI,OAAO,EAAE,CAAC;YACV,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;gBAC1B,MAAM,IAAI,GAAG,KAAK,CAAC,OAAO,CAAC,aAAa,EAAE,EAAE,CAAC,CAAC;gBAC9C,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACrB,CAAC;QACL,CAAC;QACD,OAAO,KAAK,CAAC;IACjB,CAAC;IAED;;OAEG;IACK,GAAG,CAAC,OAAe;QACvB,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YACf,OAAO,CAAC,GAAG,CAAC,iBAAiB,OAAO,EAAE,CAAC,CAAC;QAC5C,CAAC;IACL,CAAC;CACJ"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Lingo-Guardian CLI - Public API
3
+ * Export main functionality for programmatic usage
4
+ */
5
+ export { Auditor } from './core/auditor.js';
6
+ export { LingoIntegration } from './core/lingo-integration.js';
7
+ export { PseudoLocaleTransform } from './transforms/pseudo-locale.js';
8
+ export { RTLTransform } from './transforms/rtl.js';
9
+ export { Reporter } from './reporters/reporter.js';
10
+ export type { OverflowIssue, AuditResult, LintOptions, Severity, } from './constants.js';
11
+ export { VERSION, DEFAULTS } from './constants.js';
12
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAC5C,OAAO,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAC/D,OAAO,EAAE,qBAAqB,EAAE,MAAM,+BAA+B,CAAC;AACtE,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AAEnD,YAAY,EACR,aAAa,EACb,WAAW,EACX,WAAW,EACX,QAAQ,GACX,MAAM,gBAAgB,CAAC;AAExB,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Lingo-Guardian CLI - Public API
3
+ * Export main functionality for programmatic usage
4
+ */
5
+ export { Auditor } from './core/auditor.js';
6
+ export { LingoIntegration } from './core/lingo-integration.js';
7
+ export { PseudoLocaleTransform } from './transforms/pseudo-locale.js';
8
+ export { RTLTransform } from './transforms/rtl.js';
9
+ export { Reporter } from './reporters/reporter.js';
10
+ export { VERSION, DEFAULTS } from './constants.js';
11
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAC5C,OAAO,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAC/D,OAAO,EAAE,qBAAqB,EAAE,MAAM,+BAA+B,CAAC;AACtE,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AASnD,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC"}