tailwind-hyperclay 0.1.1 → 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.
Files changed (3) hide show
  1. package/index.js +35 -5
  2. package/package.json +1 -1
  3. package/test/test.js +49 -10
package/index.js CHANGED
@@ -80,18 +80,48 @@ export function extractCandidates(html) {
80
80
  return Array.from(candidates);
81
81
  }
82
82
 
83
+ function getTailwindName(urlString) {
84
+ // Match relative path: /tailwindcss/name.css
85
+ // Or full URL: https://hyperclay.com/tailwindcss/name.css
86
+ // With optional query params (?v=123) or fragments (#section)
87
+ const match = urlString.match(/^(?:https:\/\/hyperclay\.com)?\/tailwindcss\/([^?#]+)\.css(?:[?#].*)?$/);
88
+ return match ? match[1] : null;
89
+ }
90
+
91
+ function extractHrefs(html) {
92
+ const hrefs = [];
93
+ const regex = /href\s*=\s*["']([^"']+)["']/gi;
94
+ let match;
95
+ while ((match = regex.exec(html)) !== null) {
96
+ hrefs.push(match[1]);
97
+ }
98
+ return hrefs;
99
+ }
100
+
101
+ export function getTailwindCssName(html) {
102
+ for (const href of extractHrefs(html)) {
103
+ const name = getTailwindName(href);
104
+ if (name) return name;
105
+ }
106
+ return null;
107
+ }
108
+
83
109
  export function hasTailwindLink(html, appName) {
84
- const pattern = new RegExp(`https://hyperclay\\.com/tailwindcss/${appName}\\.css`);
85
- return pattern.test(html);
110
+ return extractHrefs(html).some(url => getTailwindName(url) === appName);
86
111
  }
87
112
 
88
113
  export function hasAnyTailwindLink(html) {
89
- return /https:\/\/hyperclay\.com\/tailwindcss\/[^"']+\.css/.test(html);
114
+ return extractHrefs(html).some(url => getTailwindName(url) !== null);
90
115
  }
91
116
 
92
117
  export function replaceTailwindLink(html, newName) {
93
118
  return html.replace(
94
- /https:\/\/hyperclay\.com\/tailwindcss\/[^"']+\.css/g,
95
- `https://hyperclay.com/tailwindcss/${newName}.css`
119
+ /(href\s*=\s*["'])([^"']+)(["'])/gi,
120
+ (match, prefix, url, suffix) => {
121
+ if (getTailwindName(url) !== null) {
122
+ return `${prefix}https://hyperclay.com/tailwindcss/${newName}.css${suffix}`;
123
+ }
124
+ return match;
125
+ }
96
126
  );
97
127
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tailwind-hyperclay",
3
- "version": "0.1.1",
3
+ "version": "0.1.3",
4
4
  "description": "On-save Tailwind CSS generator for Hyperclay",
5
5
  "type": "module",
6
6
  "main": "index.js",
package/test/test.js CHANGED
@@ -1,4 +1,4 @@
1
- import { compileTailwind, hasTailwindLink } from '../index.js';
1
+ import { compileTailwind, hasTailwindLink, hasAnyTailwindLink, replaceTailwindLink } from '../index.js';
2
2
 
3
3
  const testHTML = `
4
4
  <!DOCTYPE html>
@@ -15,20 +15,59 @@ const testHTML = `
15
15
  </html>
16
16
  `;
17
17
 
18
+ const testHTMLWithQueryParams = `
19
+ <!DOCTYPE html>
20
+ <html>
21
+ <head>
22
+ <link href="https://hyperclay.com/tailwindcss/myApp.css?v=123&t=456" rel="stylesheet">
23
+ </head>
24
+ <body></body>
25
+ </html>
26
+ `;
27
+
28
+ const testHTMLWithFragment = `
29
+ <!DOCTYPE html>
30
+ <html>
31
+ <head>
32
+ <link href="https://hyperclay.com/tailwindcss/myApp.css#section" rel="stylesheet">
33
+ </head>
34
+ <body></body>
35
+ </html>
36
+ `;
37
+
38
+ function test(name, actual, expected) {
39
+ const pass = actual === expected;
40
+ console.log(` ${pass ? '✓' : '✗'} ${name}: ${actual} (expected ${expected})`);
41
+ if (!pass) process.exitCode = 1;
42
+ }
43
+
18
44
  async function runTests() {
19
45
  console.log('Testing hasTailwindLink...');
20
- console.log(' myApp:', hasTailwindLink(testHTML, 'myApp')); // true
21
- console.log(' other:', hasTailwindLink(testHTML, 'other')); // false
46
+ test('myApp found', hasTailwindLink(testHTML, 'myApp'), true);
47
+ test('other not found', hasTailwindLink(testHTML, 'other'), false);
48
+ test('myApp with query params', hasTailwindLink(testHTMLWithQueryParams, 'myApp'), true);
49
+ test('myApp with fragment', hasTailwindLink(testHTMLWithFragment, 'myApp'), true);
50
+
51
+ console.log('\nTesting hasAnyTailwindLink...');
52
+ test('finds link', hasAnyTailwindLink(testHTML), true);
53
+ test('finds link with query params', hasAnyTailwindLink(testHTMLWithQueryParams), true);
54
+ test('no link', hasAnyTailwindLink('<html><body></body></html>'), false);
55
+
56
+ console.log('\nTesting replaceTailwindLink...');
57
+ const replaced = replaceTailwindLink(testHTML, 'newApp');
58
+ test('replaces app name', replaced.includes('https://hyperclay.com/tailwindcss/newApp.css'), true);
59
+ test('removes old app name', !replaced.includes('myApp'), true);
60
+
61
+ const replacedWithParams = replaceTailwindLink(testHTMLWithQueryParams, 'newApp');
62
+ test('replaces and strips query params', replacedWithParams.includes('https://hyperclay.com/tailwindcss/newApp.css"'), true);
63
+ test('query params removed', !replacedWithParams.includes('?v=123'), true);
22
64
 
23
65
  console.log('\nTesting compileTailwind...');
24
66
  const css = await compileTailwind(testHTML);
25
- console.log(' Generated CSS length:', css.length);
26
- console.log(' Contains .prose:', css.includes('.prose'));
27
- console.log(' Contains .form-input:', css.includes('.form-input'));
28
- console.log(' Contains .text-2xl:', css.includes('.text-2xl'));
29
-
30
- console.log('\nSample output (first 500 chars):');
31
- console.log(css.slice(0, 500));
67
+ test('generates CSS', css.length > 0, true);
68
+ test('contains .prose', css.includes('.prose'), true);
69
+ test('contains .form-input', css.includes('.form-input'), true);
70
+ test('contains .text-2xl', css.includes('.text-2xl'), true);
32
71
  }
33
72
 
34
73
  runTests().catch(console.error);