@arach/og 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,106 @@
1
+ # @arach/og
2
+
3
+ Declarative OG (Open Graph) image generation with Puppeteer. Pre-built templates and a simple API for generating social sharing images.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ pnpm add @arach/og
9
+ # or
10
+ npm install @arach/og
11
+ ```
12
+
13
+ ## Usage
14
+
15
+ ### Programmatic API
16
+
17
+ ```typescript
18
+ import { generateOG } from '@arach/og'
19
+
20
+ await generateOG({
21
+ template: 'branded',
22
+ title: 'My App',
23
+ subtitle: 'Build amazing things',
24
+ accent: '#f07c4f',
25
+ output: 'public/og.png'
26
+ })
27
+ ```
28
+
29
+ ### CLI
30
+
31
+ ```bash
32
+ # Generate from a config file
33
+ npx og config.json
34
+ ```
35
+
36
+ Config file format:
37
+
38
+ ```json
39
+ [
40
+ {
41
+ "template": "branded",
42
+ "title": "My App",
43
+ "subtitle": "Build amazing things",
44
+ "accent": "#f07c4f",
45
+ "output": "public/og.png"
46
+ }
47
+ ]
48
+ ```
49
+
50
+ ## Templates
51
+
52
+ ### `branded`
53
+ Full-featured template with logo, tag chip, and accent glow. Great for product landing pages.
54
+
55
+ ![branded](examples/og-branded.png)
56
+
57
+ ### `docs`
58
+ Clean template for documentation pages with breadcrumb-style layout.
59
+
60
+ ![docs](examples/og-docs.png)
61
+
62
+ ### `minimal`
63
+ Simple centered layout. Works well for blog posts and articles.
64
+
65
+ ![minimal](examples/og-minimal.png)
66
+
67
+ ### `editor-dark`
68
+ Dark theme template for developer tools and code editors.
69
+
70
+ ![editor-dark](examples/og-editor.png)
71
+
72
+ ## Configuration Options
73
+
74
+ | Option | Type | Default | Description |
75
+ |--------|------|---------|-------------|
76
+ | `template` | `string` | `'branded'` | Template ID |
77
+ | `title` | `string` | required | Primary title |
78
+ | `subtitle` | `string` | - | Subtitle or description |
79
+ | `accent` | `string` | `'#6366f1'` | Brand/accent color (hex) |
80
+ | `accentSecondary` | `string` | - | Secondary accent color |
81
+ | `background` | `string` | `'#0a0a0a'` | Background color |
82
+ | `textColor` | `string` | `'#ffffff'` | Text color |
83
+ | `output` | `string` | required | Output file path |
84
+ | `width` | `number` | `1200` | Width in pixels |
85
+ | `height` | `number` | `630` | Height in pixels |
86
+ | `scale` | `number` | `2` | Device scale factor (retina) |
87
+ | `fonts` | `string[]` | `['Inter']` | Google Fonts to load |
88
+ | `logo` | `string` | - | Logo URL or base64 |
89
+ | `tag` | `string` | - | Tag/chip text |
90
+
91
+ ## Batch Generation
92
+
93
+ Generate multiple images at once:
94
+
95
+ ```typescript
96
+ import { generateOGBatch } from '@arach/og'
97
+
98
+ await generateOGBatch([
99
+ { template: 'branded', title: 'Home', output: 'og-home.png' },
100
+ { template: 'docs', title: 'Docs', output: 'og-docs.png' },
101
+ ])
102
+ ```
103
+
104
+ ## License
105
+
106
+ MIT
@@ -0,0 +1,22 @@
1
+ export interface AuditResult {
2
+ url: string;
3
+ path: string;
4
+ score: number;
5
+ title?: string;
6
+ titleLength?: number;
7
+ description?: string;
8
+ descriptionLength?: number;
9
+ image?: string;
10
+ imageSize?: number;
11
+ imageDimensions?: string;
12
+ issues: string[];
13
+ }
14
+ export interface OGInventory {
15
+ baseUrl: string;
16
+ auditedAt: string;
17
+ totalPages: number;
18
+ averageScore: number;
19
+ pages: AuditResult[];
20
+ }
21
+ export declare function auditSite(baseUrl: string): Promise<void>;
22
+ //# sourceMappingURL=audit.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"audit.d.ts","sourceRoot":"","sources":["../src/audit.ts"],"names":[],"mappings":"AAUA,MAAM,WAAW,WAAW;IAC1B,GAAG,EAAE,MAAM,CAAA;IACX,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,iBAAiB,CAAC,EAAE,MAAM,CAAA;IAC1B,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,MAAM,EAAE,MAAM,EAAE,CAAA;CACjB;AAED,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,MAAM,CAAA;IACf,SAAS,EAAE,MAAM,CAAA;IACjB,UAAU,EAAE,MAAM,CAAA;IAClB,YAAY,EAAE,MAAM,CAAA;IACpB,KAAK,EAAE,WAAW,EAAE,CAAA;CACrB;AAED,wBAAsB,SAAS,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAoG9D"}
package/dist/audit.js ADDED
@@ -0,0 +1,188 @@
1
+ import { validateOG } from './validate.js';
2
+ import { createInterface } from 'node:readline';
3
+ import { writeFile } from 'node:fs/promises';
4
+ export async function auditSite(baseUrl) {
5
+ // Normalize URL
6
+ const url = baseUrl.startsWith('http') ? baseUrl : `https://${baseUrl}`;
7
+ const base = new URL(url);
8
+ console.log(`\n Auditing ${base.origin}...\n`);
9
+ // Try to find sitemap
10
+ const sitemapUrls = await findSitemap(base.origin);
11
+ let paths;
12
+ if (sitemapUrls.length > 0) {
13
+ console.log(` ✓ Found sitemap with ${sitemapUrls.length} URLs\n`);
14
+ paths = sitemapUrls.map(u => u.loc);
15
+ }
16
+ else {
17
+ console.log(` ! No sitemap found at ${base.origin}/sitemap.xml`);
18
+ console.log(` Consider adding one for better SEO!\n`);
19
+ // Check for .og-paths file or ask user
20
+ paths = await getPathsFromUser(base.origin);
21
+ }
22
+ if (paths.length === 0) {
23
+ console.log(` No paths to audit.\n`);
24
+ return;
25
+ }
26
+ console.log(` Auditing ${paths.length} page${paths.length !== 1 ? 's' : ''}...\n`);
27
+ console.log(` ${'─'.repeat(60)}\n`);
28
+ const results = [];
29
+ for (const path of paths) {
30
+ const fullUrl = path.startsWith('http') ? path : `${base.origin}${path.startsWith('/') ? '' : '/'}${path}`;
31
+ const urlPath = new URL(fullUrl).pathname;
32
+ process.stdout.write(` Checking ${truncate(fullUrl, 50)}...`);
33
+ try {
34
+ const validation = await validateOG(fullUrl);
35
+ const titleCheck = validation.checks.find(c => c.name === 'og:title');
36
+ const descCheck = validation.checks.find(c => c.name === 'og:description');
37
+ const imageUrlCheck = validation.checks.find(c => c.name === 'og:image URL');
38
+ const imageSizeCheck = validation.checks.find(c => c.name === 'og:image size');
39
+ const imageDimsCheck = validation.checks.find(c => c.name === 'og:image dimensions');
40
+ const issues = validation.checks
41
+ .filter(c => c.status !== 'pass')
42
+ .map(c => c.name);
43
+ results.push({
44
+ url: fullUrl,
45
+ path: urlPath,
46
+ score: validation.score,
47
+ title: typeof titleCheck?.value === 'string' ? undefined : undefined,
48
+ titleLength: typeof titleCheck?.value === 'number' ? titleCheck.value : undefined,
49
+ description: typeof descCheck?.value === 'string' ? undefined : undefined,
50
+ descriptionLength: typeof descCheck?.value === 'number' ? descCheck.value : undefined,
51
+ image: typeof imageUrlCheck?.value === 'string' ? imageUrlCheck.value : undefined,
52
+ imageSize: typeof imageSizeCheck?.value === 'number' ? imageSizeCheck.value : undefined,
53
+ imageDimensions: typeof imageDimsCheck?.value === 'string' ? imageDimsCheck.value : undefined,
54
+ issues
55
+ });
56
+ const scoreColor = validation.score >= 80 ? '\x1b[32m' :
57
+ validation.score >= 50 ? '\x1b[33m' : '\x1b[31m';
58
+ const reset = '\x1b[0m';
59
+ console.log(` ${scoreColor}${validation.score}${reset}/100`);
60
+ }
61
+ catch (error) {
62
+ results.push({
63
+ url: fullUrl,
64
+ path: urlPath,
65
+ score: 0,
66
+ issues: ['Failed to fetch']
67
+ });
68
+ console.log(` \x1b[31mFailed\x1b[0m`);
69
+ }
70
+ }
71
+ // Save inventory
72
+ const inventory = {
73
+ baseUrl: base.origin,
74
+ auditedAt: new Date().toISOString(),
75
+ totalPages: results.length,
76
+ averageScore: Math.round(results.reduce((sum, r) => sum + r.score, 0) / results.length),
77
+ pages: results
78
+ };
79
+ await writeFile('.og-inventory.json', JSON.stringify(inventory, null, 2));
80
+ console.log(`\n ✓ Saved inventory to .og-inventory.json`);
81
+ // Summary
82
+ console.log(`\n ${'─'.repeat(60)}`);
83
+ printSummary(results);
84
+ console.log(` Run \x1b[36mog viewer\x1b[0m to see the full report\n`);
85
+ }
86
+ async function findSitemap(origin) {
87
+ const sitemapLocations = [
88
+ '/sitemap.xml',
89
+ '/sitemap_index.xml',
90
+ '/sitemap-index.xml',
91
+ ];
92
+ // Also check robots.txt for Sitemap directive
93
+ try {
94
+ const robotsRes = await fetch(`${origin}/robots.txt`);
95
+ if (robotsRes.ok) {
96
+ const robotsTxt = await robotsRes.text();
97
+ const sitemapMatch = robotsTxt.match(/Sitemap:\s*(.+)/i);
98
+ if (sitemapMatch) {
99
+ sitemapLocations.unshift(new URL(sitemapMatch[1].trim(), origin).pathname);
100
+ }
101
+ }
102
+ }
103
+ catch {
104
+ // Ignore
105
+ }
106
+ for (const loc of sitemapLocations) {
107
+ try {
108
+ const res = await fetch(`${origin}${loc}`);
109
+ if (res.ok) {
110
+ const xml = await res.text();
111
+ return parseSitemap(xml, origin);
112
+ }
113
+ }
114
+ catch {
115
+ // Try next location
116
+ }
117
+ }
118
+ return [];
119
+ }
120
+ function parseSitemap(xml, origin) {
121
+ const urls = [];
122
+ // Check if it's a sitemap index
123
+ if (xml.includes('<sitemapindex')) {
124
+ // Parse sitemap index to get child sitemaps
125
+ const sitemapMatches = xml.matchAll(/<sitemap>[\s\S]*?<loc>(.+?)<\/loc>[\s\S]*?<\/sitemap>/gi);
126
+ // For simplicity, just return empty - would need to recursively fetch
127
+ // In a real implementation, we'd fetch each child sitemap
128
+ console.log(` (Sitemap index found - using root URLs only)`);
129
+ }
130
+ // Parse URL entries
131
+ const urlMatches = xml.matchAll(/<url>[\s\S]*?<loc>(.+?)<\/loc>[\s\S]*?<\/url>/gi);
132
+ for (const match of urlMatches) {
133
+ const loc = match[1].trim();
134
+ urls.push({ loc });
135
+ }
136
+ return urls;
137
+ }
138
+ async function getPathsFromUser(origin) {
139
+ const rl = createInterface({
140
+ input: process.stdin,
141
+ output: process.stdout
142
+ });
143
+ return new Promise((resolve) => {
144
+ console.log(` Enter paths to audit (comma-separated), or press Enter for just the homepage:`);
145
+ console.log(` Example: /, /about, /docs, /pricing\n`);
146
+ rl.question(' Paths: ', (answer) => {
147
+ rl.close();
148
+ if (!answer.trim()) {
149
+ resolve(['/']);
150
+ }
151
+ else {
152
+ const paths = answer.split(',').map(p => p.trim()).filter(Boolean);
153
+ resolve(paths.length > 0 ? paths : ['/']);
154
+ }
155
+ });
156
+ });
157
+ }
158
+ function printSummary(results) {
159
+ const total = results.length;
160
+ const perfect = results.filter(r => r.score >= 90).length;
161
+ const good = results.filter(r => r.score >= 70 && r.score < 90).length;
162
+ const needsWork = results.filter(r => r.score < 70).length;
163
+ const avgScore = Math.round(results.reduce((sum, r) => sum + r.score, 0) / total);
164
+ console.log(`\n Summary`);
165
+ console.log(` ${'─'.repeat(30)}`);
166
+ console.log(` Total pages: ${total}`);
167
+ console.log(` Average score: ${avgScore}/100`);
168
+ console.log(``);
169
+ console.log(` \x1b[32m●\x1b[0m Perfect (90+): ${perfect}`);
170
+ console.log(` \x1b[33m●\x1b[0m Good (70-89): ${good}`);
171
+ console.log(` \x1b[31m●\x1b[0m Needs work: ${needsWork}`);
172
+ if (needsWork > 0) {
173
+ console.log(`\n Pages needing attention:`);
174
+ for (const r of results.filter(r => r.score < 70)) {
175
+ console.log(` • ${truncate(r.url, 40)} (${r.score}/100)`);
176
+ if (r.issues.length > 0) {
177
+ console.log(` Issues: ${r.issues.join(', ')}`);
178
+ }
179
+ }
180
+ }
181
+ console.log(``);
182
+ }
183
+ function truncate(str, len) {
184
+ if (str.length <= len)
185
+ return str;
186
+ return str.slice(0, len - 3) + '...';
187
+ }
188
+ //# sourceMappingURL=audit.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"audit.js","sourceRoot":"","sources":["../src/audit.ts"],"names":[],"mappings":"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"}
package/dist/cli.js CHANGED
@@ -2,37 +2,107 @@
2
2
  import { readFile } from 'node:fs/promises';
3
3
  import { resolve } from 'node:path';
4
4
  import { generateOG, generateOGBatch } from './generate.js';
5
+ import { validateOG, formatValidationResult } from './validate.js';
6
+ import { startViewer } from './viewer.js';
7
+ import { auditSite } from './audit.js';
5
8
  async function main() {
6
9
  const args = process.argv.slice(2);
7
10
  if (args.length === 0 || args.includes('--help') || args.includes('-h')) {
8
- console.log(`
9
- @arach/og - Declarative OG image generation
11
+ printHelp();
12
+ process.exit(0);
13
+ }
14
+ const command = args[0];
15
+ // Validate command
16
+ if (command === 'validate') {
17
+ const url = args[1];
18
+ if (!url) {
19
+ console.error('Error: Please provide a URL to validate');
20
+ console.error('Usage: og validate <url>');
21
+ process.exit(1);
22
+ }
23
+ try {
24
+ const targetUrl = url.startsWith('http') ? url : `https://${url}`;
25
+ console.log(`\nValidating ${targetUrl}...`);
26
+ const result = await validateOG(targetUrl);
27
+ console.log(formatValidationResult(result));
28
+ process.exit(result.score >= 70 ? 0 : 1);
29
+ }
30
+ catch (error) {
31
+ console.error('Error:', error instanceof Error ? error.message : error);
32
+ process.exit(1);
33
+ }
34
+ }
35
+ // Audit command
36
+ if (command === 'audit') {
37
+ const url = args[1];
38
+ if (!url) {
39
+ console.error('Error: Please provide a URL to audit');
40
+ console.error('Usage: og audit <url>');
41
+ process.exit(1);
42
+ }
43
+ await auditSite(url);
44
+ return;
45
+ }
46
+ // Init command - add paths manually for local dev
47
+ if (command === 'init') {
48
+ const paths = args.slice(1);
49
+ if (paths.length === 0) {
50
+ console.log(`
51
+ Usage: og init <paths...>
10
52
 
11
- Usage:
12
- og <config.json> Generate OG images from a config file
13
- og --help Show this help message
53
+ Add paths to your OG inventory for local development.
14
54
 
15
- Config file format:
16
- Single image:
17
- {
18
- "template": "branded",
19
- "title": "My App",
20
- "subtitle": "Do amazing things",
21
- "accent": "#f07c4f",
22
- "output": "public/og-image.png"
23
- }
24
-
25
- Multiple images:
26
- [
27
- { "title": "Home", "output": "public/og-home.png" },
28
- { "title": "Docs", "template": "docs", "output": "public/og-docs.png" }
29
- ]
55
+ Examples:
56
+ og init / /about /pricing /docs
57
+ og init /blog/post-1 /blog/post-2
30
58
 
31
- Templates: branded, docs, minimal, editor-dark
59
+ This creates .og-inventory.json which og viewer uses.
32
60
  `);
33
- process.exit(0);
61
+ process.exit(0);
62
+ }
63
+ const { writeFile, readFile } = await import('node:fs/promises');
64
+ let inventory;
65
+ try {
66
+ const existing = await readFile('.og-inventory.json', 'utf-8');
67
+ inventory = JSON.parse(existing);
68
+ }
69
+ catch {
70
+ inventory = {
71
+ baseUrl: 'local',
72
+ auditedAt: new Date().toISOString(),
73
+ totalPages: 0,
74
+ averageScore: 0,
75
+ pages: []
76
+ };
77
+ }
78
+ for (const path of paths) {
79
+ const normalizedPath = path.startsWith('/') ? path : `/${path}`;
80
+ if (!inventory.pages.find(p => p.path === normalizedPath)) {
81
+ inventory.pages.push({
82
+ url: `local://${normalizedPath}`,
83
+ path: normalizedPath,
84
+ score: 0,
85
+ issues: ['Not audited yet']
86
+ });
87
+ }
88
+ }
89
+ inventory.totalPages = inventory.pages.length;
90
+ inventory.auditedAt = new Date().toISOString();
91
+ await writeFile('.og-inventory.json', JSON.stringify(inventory, null, 2));
92
+ console.log(`\n ✓ Added ${paths.length} path(s) to .og-inventory.json`);
93
+ console.log(` Total paths: ${inventory.pages.length}\n`);
94
+ console.log(` Run \x1b[36mog viewer\x1b[0m to see your inventory\n`);
95
+ return;
34
96
  }
35
- const configPath = resolve(process.cwd(), args[0]);
97
+ // Viewer command
98
+ if (command === 'viewer') {
99
+ const dir = args[1] ? resolve(process.cwd(), args[1]) : process.cwd();
100
+ const port = args.includes('--port') ? parseInt(args[args.indexOf('--port') + 1]) : 3333;
101
+ await startViewer(dir, port);
102
+ return;
103
+ }
104
+ // Generate command (default)
105
+ const configPath = resolve(process.cwd(), command);
36
106
  try {
37
107
  const content = await readFile(configPath, 'utf-8');
38
108
  const config = JSON.parse(content);
@@ -49,5 +119,66 @@ Templates: branded, docs, minimal, editor-dark
49
119
  process.exit(1);
50
120
  }
51
121
  }
122
+ function printHelp() {
123
+ console.log(`
124
+ @arach/og - Declarative OG image generation
125
+
126
+ Usage:
127
+ og <config.json> Generate OG images from a config file
128
+ og validate <url> Validate OG tags on a single URL
129
+ og audit <url> Audit all pages on a site (uses sitemap)
130
+ og init <paths...> Add paths to inventory for local dev
131
+ og viewer Launch local viewer for OG inventory
132
+ og --help Show this help message
133
+
134
+ Workflow:
135
+ 1. Audit a live site: og audit mysite.com
136
+ Or init paths locally: og init / /about /docs /pricing
137
+
138
+ 2. View your inventory: og viewer
139
+
140
+ 3. Generate images: og config.json
141
+
142
+ Audit:
143
+ Scan a website's sitemap and audit OG tags for each page.
144
+
145
+ $ og audit https://mysite.com
146
+ $ og audit mysite.com
147
+
148
+ If no sitemap found, prompts for paths to audit.
149
+ Saves results to .og-inventory.json
150
+
151
+ Init:
152
+ Add paths manually for local development (no live site needed).
153
+
154
+ $ og init / /about /pricing /docs
155
+ $ og init /blog/post-1 /blog/post-2
156
+
157
+ Creates/updates .og-inventory.json
158
+
159
+ Viewer:
160
+ Launch local viewer to see your OG inventory.
161
+
162
+ $ og viewer
163
+ $ og viewer --port 4000
164
+
165
+ Validate:
166
+ Quick check of a single URL's OG tags.
167
+
168
+ $ og validate https://example.com/page
169
+
170
+ Generate:
171
+ Create OG images from a JSON config file.
172
+
173
+ {
174
+ "template": "branded",
175
+ "title": "My App",
176
+ "subtitle": "Do amazing things",
177
+ "output": "public/og.png"
178
+ }
179
+
180
+ Templates: branded, docs, minimal, editor-dark
181
+ `);
182
+ }
52
183
  main();
53
184
  //# sourceMappingURL=cli.js.map
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAA;AAC3C,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AACnC,OAAO,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,eAAe,CAAA;AAG3D,KAAK,UAAU,IAAI;IACjB,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;IAElC,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QACxE,OAAO,CAAC,GAAG,CAAC;;;;;;;;;;;;;;;;;;;;;;;;CAwBf,CAAC,CAAA;QACE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACjB,CAAC;IAED,MAAM,UAAU,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,CAAA;IAElD,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC,CAAA;QACnD,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAA0B,CAAA;QAE3D,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;YAC1B,MAAM,eAAe,CAAC,MAAM,CAAC,CAAA;QAC/B,CAAC;aAAM,CAAC;YACN,MAAM,UAAU,CAAC,MAAM,CAAC,CAAA;QAC1B,CAAC;QAED,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC,CAAA;IAC1B,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CAAC,QAAQ,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAA;QACvE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACjB,CAAC;AACH,CAAC;AAED,IAAI,EAAE,CAAA"}
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAA;AAC3C,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AACnC,OAAO,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,eAAe,CAAA;AAC3D,OAAO,EAAE,UAAU,EAAE,sBAAsB,EAAE,MAAM,eAAe,CAAA;AAClE,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AACzC,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAA;AAGtC,KAAK,UAAU,IAAI;IACjB,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;IAElC,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QACxE,SAAS,EAAE,CAAA;QACX,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACjB,CAAC;IAED,MAAM,OAAO,GAAG,IAAI,CAAC,CAAC,CAAC,CAAA;IAEvB,mBAAmB;IACnB,IAAI,OAAO,KAAK,UAAU,EAAE,CAAC;QAC3B,MAAM,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,CAAA;QACnB,IAAI,CAAC,GAAG,EAAE,CAAC;YACT,OAAO,CAAC,KAAK,CAAC,yCAAyC,CAAC,CAAA;YACxD,OAAO,CAAC,KAAK,CAAC,0BAA0B,CAAC,CAAA;YACzC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;QACjB,CAAC;QAED,IAAI,CAAC;YACH,MAAM,SAAS,GAAG,GAAG,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,WAAW,GAAG,EAAE,CAAA;YACjE,OAAO,CAAC,GAAG,CAAC,gBAAgB,SAAS,KAAK,CAAC,CAAA;YAC3C,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,SAAS,CAAC,CAAA;YAC1C,OAAO,CAAC,GAAG,CAAC,sBAAsB,CAAC,MAAM,CAAC,CAAC,CAAA;YAC3C,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;QAC1C,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,QAAQ,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAA;YACvE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;QACjB,CAAC;IACH,CAAC;IAED,gBAAgB;IAChB,IAAI,OAAO,KAAK,OAAO,EAAE,CAAC;QACxB,MAAM,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,CAAA;QACnB,IAAI,CAAC,GAAG,EAAE,CAAC;YACT,OAAO,CAAC,KAAK,CAAC,sCAAsC,CAAC,CAAA;YACrD,OAAO,CAAC,KAAK,CAAC,uBAAuB,CAAC,CAAA;YACtC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;QACjB,CAAC;QACD,MAAM,SAAS,CAAC,GAAG,CAAC,CAAA;QACpB,OAAM;IACR,CAAC;IAED,kDAAkD;IAClD,IAAI,OAAO,KAAK,MAAM,EAAE,CAAC;QACvB,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;QAC3B,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACvB,OAAO,CAAC,GAAG,CAAC;;;;;;;;;;CAUjB,CAAC,CAAA;YACI,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;QACjB,CAAC;QAED,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,GAAG,MAAM,MAAM,CAAC,kBAAkB,CAAC,CAAA;QAChE,IAAI,SAAyK,CAAA;QAE7K,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,QAAQ,CAAC,oBAAoB,EAAE,OAAO,CAAC,CAAA;YAC9D,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAA;QAClC,CAAC;QAAC,MAAM,CAAC;YACP,SAAS,GAAG;gBACV,OAAO,EAAE,OAAO;gBAChB,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;gBACnC,UAAU,EAAE,CAAC;gBACb,YAAY,EAAE,CAAC;gBACf,KAAK,EAAE,EAAE;aACV,CAAA;QACH,CAAC;QAED,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,MAAM,cAAc,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,IAAI,EAAE,CAAA;YAC/D,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,cAAc,CAAC,EAAE,CAAC;gBAC1D,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC;oBACnB,GAAG,EAAE,WAAW,cAAc,EAAE;oBAChC,IAAI,EAAE,cAAc;oBACpB,KAAK,EAAE,CAAC;oBACR,MAAM,EAAE,CAAC,iBAAiB,CAAC;iBAC5B,CAAC,CAAA;YACJ,CAAC;QACH,CAAC;QAED,SAAS,CAAC,UAAU,GAAG,SAAS,CAAC,KAAK,CAAC,MAAM,CAAA;QAC7C,SAAS,CAAC,SAAS,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAA;QAE9C,MAAM,SAAS,CAAC,oBAAoB,EAAE,IAAI,CAAC,SAAS,CAAC,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAA;QACzE,OAAO,CAAC,GAAG,CAAC,eAAe,KAAK,CAAC,MAAM,gCAAgC,CAAC,CAAA;QACxE,OAAO,CAAC,GAAG,CAAC,kBAAkB,SAAS,CAAC,KAAK,CAAC,MAAM,IAAI,CAAC,CAAA;QACzD,OAAO,CAAC,GAAG,CAAC,wDAAwD,CAAC,CAAA;QACrE,OAAM;IACR,CAAC;IAED,iBAAiB;IACjB,IAAI,OAAO,KAAK,QAAQ,EAAE,CAAC;QACzB,MAAM,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE,CAAA;QACrE,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAA;QACxF,MAAM,WAAW,CAAC,GAAG,EAAE,IAAI,CAAC,CAAA;QAC5B,OAAM;IACR,CAAC;IAED,6BAA6B;IAC7B,MAAM,UAAU,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,OAAO,CAAC,CAAA;IAElD,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC,CAAA;QACnD,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAA0B,CAAA;QAE3D,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;YAC1B,MAAM,eAAe,CAAC,MAAM,CAAC,CAAA;QAC/B,CAAC;aAAM,CAAC;YACN,MAAM,UAAU,CAAC,MAAM,CAAC,CAAA;QAC1B,CAAC;QAED,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC,CAAA;IAC1B,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CAAC,QAAQ,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAA;QACvE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACjB,CAAC;AACH,CAAC;AAED,SAAS,SAAS;IAChB,OAAO,CAAC,GAAG,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA0Db,CAAC,CAAA;AACF,CAAC;AAED,IAAI,EAAE,CAAA"}
package/dist/index.d.ts CHANGED
@@ -1,4 +1,6 @@
1
1
  export { generateOG, generateOGBatch } from './generate.js';
2
+ export { validateOG, formatValidationResult } from './validate.js';
2
3
  export { templates } from './templates/index.js';
3
4
  export type { OGConfig, TemplateId, TemplateContext, TemplateFunction } from './types.js';
5
+ export type { ValidationResult, ValidationCheck } from './validate.js';
4
6
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,eAAe,CAAA;AAC3D,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAA;AAChD,YAAY,EAAE,QAAQ,EAAE,UAAU,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,eAAe,CAAA;AAC3D,OAAO,EAAE,UAAU,EAAE,sBAAsB,EAAE,MAAM,eAAe,CAAA;AAClE,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAA;AAChD,YAAY,EAAE,QAAQ,EAAE,UAAU,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAA;AACzF,YAAY,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,eAAe,CAAA"}
package/dist/index.js CHANGED
@@ -1,3 +1,4 @@
1
1
  export { generateOG, generateOGBatch } from './generate.js';
2
+ export { validateOG, formatValidationResult } from './validate.js';
2
3
  export { templates } from './templates/index.js';
3
4
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,eAAe,CAAA;AAC3D,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,eAAe,CAAA;AAC3D,OAAO,EAAE,UAAU,EAAE,sBAAsB,EAAE,MAAM,eAAe,CAAA;AAClE,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAA"}
@@ -1,6 +1,6 @@
1
1
  import type { TemplateFunction } from '../types.js';
2
2
  /**
3
- * Branded template - full featured with grid overlay, gradient glows, and tag
3
+ * Branded template - full featured with grid overlay, corner crosses, and refined typography
4
4
  */
5
5
  export declare const branded: TemplateFunction;
6
6
  //# sourceMappingURL=branded.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"branded.d.ts","sourceRoot":"","sources":["../../src/templates/branded.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAA;AAEnD;;GAEG;AACH,eAAO,MAAM,OAAO,EAAE,gBAqHrB,CAAA"}
1
+ {"version":3,"file":"branded.d.ts","sourceRoot":"","sources":["../../src/templates/branded.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAA;AAEnD;;GAEG;AACH,eAAO,MAAM,OAAO,EAAE,gBA2JrB,CAAA"}