html-to-gutenberg 4.2.7 → 4.2.9

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 (51) hide show
  1. package/.env +1 -0
  2. package/.env.example +3 -0
  3. package/.eslintrc.json +35 -0
  4. package/.github/workflows/build.yml +26 -0
  5. package/.github/workflows/coverage.yml +26 -0
  6. package/.nyc_output/1f0406b8-bb70-495d-8f8a-521fdd81b500.json +1 -0
  7. package/.nyc_output/6390956f-4f8a-4adb-9256-4a1c7e34a52d.json +1 -0
  8. package/.nyc_output/processinfo/1f0406b8-bb70-495d-8f8a-521fdd81b500.json +1 -0
  9. package/.nyc_output/processinfo/6390956f-4f8a-4adb-9256-4a1c7e34a52d.json +1 -0
  10. package/.nyc_output/processinfo/index.json +1 -0
  11. package/@types.d.ts +3 -0
  12. package/coverage/coverage-final.json +4 -0
  13. package/coverage/lcov-report/base.css +224 -0
  14. package/coverage/lcov-report/block-navigation.js +87 -0
  15. package/coverage/lcov-report/prettify.css +1 -0
  16. package/coverage/lcov-report/prettify.js +2 -0
  17. package/coverage/lcov-report/sorter.js +210 -0
  18. package/coverage/lcov.info +198 -0
  19. package/coverage-demo.test.ts +8 -0
  20. package/dist/coverage-demo.test.js +10 -0
  21. package/dist/coverage-demo.test.js.map +1 -0
  22. package/dist/globals.js +24 -0
  23. package/dist/globals.js.map +1 -0
  24. package/dist/index.js +36 -0
  25. package/dist/index.js.map +1 -0
  26. package/dist/index.test.js +166 -0
  27. package/dist/index.test.js.map +1 -0
  28. package/dist/package.json +130 -0
  29. package/dist/snapapi-screenshot.test.js +44 -0
  30. package/dist/snapapi-screenshot.test.js.map +1 -0
  31. package/dist/src/coverage-demo.js +7 -0
  32. package/dist/src/coverage-demo.js.map +1 -0
  33. package/dist/src/utils-extra.test.js +137 -0
  34. package/dist/src/utils-extra.test.js.map +1 -0
  35. package/dist/src/utils.test.js +65 -0
  36. package/dist/src/utils.test.js.map +1 -0
  37. package/dist/tsconfig.tsbuildinfo +1 -0
  38. package/dist/utils.js +61 -0
  39. package/dist/utils.js.map +1 -0
  40. package/index.js +87 -53
  41. package/index.test.ts +145 -0
  42. package/index.ts +47 -1527
  43. package/package.json +85 -14
  44. package/readme.md +39 -19
  45. package/snapapi-screenshot.test.ts +46 -0
  46. package/src/coverage-demo.ts +3 -0
  47. package/src/utils-extra.test.ts +108 -0
  48. package/src/utils.test.ts +36 -0
  49. package/temp-block-test.js +19 -0
  50. package/tsconfig.json +9 -3
  51. package/utils.ts +56 -0
@@ -0,0 +1,137 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ const chai_1 = require("chai");
37
+ const utils = __importStar(require("../utils"));
38
+ describe('hasTailwindCdnSource edge cases', () => {
39
+ it('returns false for empty array', () => {
40
+ (0, chai_1.expect)(utils.hasTailwindCdnSource([])).to.equal(false);
41
+ });
42
+ it('returns true for multiple tailwind URLs', () => {
43
+ (0, chai_1.expect)(utils.hasTailwindCdnSource([
44
+ 'https://cdn.tailwindcss.com',
45
+ 'https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4.0.0'
46
+ ])).to.equal(true);
47
+ });
48
+ it('returns false for malformed URLs', () => {
49
+ (0, chai_1.expect)(utils.hasTailwindCdnSource(['not-a-url'])).to.equal(false);
50
+ });
51
+ });
52
+ describe('replaceSourceUrlVars edge cases', () => {
53
+ it('replaces matching pattern', () => {
54
+ const str = "var.url+'http://site.com/path'";
55
+ const source = 'http://site.com';
56
+ const expected = "${vars.url}/path";
57
+ (0, chai_1.expect)(utils.replaceSourceUrlVars(str, source)).to.contain(expected);
58
+ });
59
+ it('returns input for empty string', () => {
60
+ (0, chai_1.expect)(utils.replaceSourceUrlVars('', 'http://site.com')).to.equal('');
61
+ });
62
+ it('returns input for null source', () => {
63
+ (0, chai_1.expect)(utils.replaceSourceUrlVars("var.url+'http://site.com/path'", null)).to.equal("var.url+'http://site.com/path'");
64
+ });
65
+ it('replaces multiple matches', () => {
66
+ const str = "var.url+'http://site.com/a' and var.url+'http://site.com/b'";
67
+ const source = 'http://site.com';
68
+ const result = utils.replaceSourceUrlVars(str, source);
69
+ (0, chai_1.expect)(result.match(/\${vars\.url}/g)?.length).to.be.greaterThanOrEqual(2);
70
+ });
71
+ });
72
+ describe('sanitizeAndReplaceLeadingNumbers edge cases', () => {
73
+ it('returns input for no numbers', () => {
74
+ (0, chai_1.expect)(utils.sanitizeAndReplaceLeadingNumbers('test')).to.equal('test');
75
+ });
76
+ it('handles multiple leading numbers', () => {
77
+ (0, chai_1.expect)(utils.sanitizeAndReplaceLeadingNumbers('123abc')).to.match(/one1two2three3abc|123abc/);
78
+ });
79
+ it('handles only numbers', () => {
80
+ (0, chai_1.expect)(utils.sanitizeAndReplaceLeadingNumbers('123')).to.match(/one1two2three3|123/);
81
+ });
82
+ it('handles special characters', () => {
83
+ (0, chai_1.expect)(utils.sanitizeAndReplaceLeadingNumbers('1_test')).to.match(/one1test|1test/);
84
+ });
85
+ });
86
+ describe('replaceUnderscoresSpacesAndUppercaseLetters edge cases', () => {
87
+ it('handles only underscores', () => {
88
+ (0, chai_1.expect)(utils.replaceUnderscoresSpacesAndUppercaseLetters('___')).to.equal('---');
89
+ });
90
+ it('handles only spaces', () => {
91
+ (0, chai_1.expect)(utils.replaceUnderscoresSpacesAndUppercaseLetters(' ')).to.equal('---');
92
+ });
93
+ it('handles mixed cases', () => {
94
+ (0, chai_1.expect)(utils.replaceUnderscoresSpacesAndUppercaseLetters('Test_Name Here')).to.equal('test-name-here');
95
+ });
96
+ it('handles empty string', () => {
97
+ (0, chai_1.expect)(utils.replaceUnderscoresSpacesAndUppercaseLetters('')).to.equal('');
98
+ });
99
+ });
100
+ describe('convertDashesSpacesAndUppercaseToUnderscoresAndLowercase edge cases', () => {
101
+ it('handles only dashes', () => {
102
+ (0, chai_1.expect)(utils.convertDashesSpacesAndUppercaseToUnderscoresAndLowercase('---')).to.equal('___');
103
+ });
104
+ it('handles only spaces', () => {
105
+ (0, chai_1.expect)(utils.convertDashesSpacesAndUppercaseToUnderscoresAndLowercase(' ')).to.equal('___');
106
+ });
107
+ it('handles mixed cases', () => {
108
+ (0, chai_1.expect)(utils.convertDashesSpacesAndUppercaseToUnderscoresAndLowercase('Test-Name Here')).to.equal('test_name_here');
109
+ });
110
+ it('handles empty string', () => {
111
+ (0, chai_1.expect)(utils.convertDashesSpacesAndUppercaseToUnderscoresAndLowercase('')).to.equal('');
112
+ });
113
+ });
114
+ describe('hasAbsoluteKeyword edge cases', () => {
115
+ it('detects uppercase', () => {
116
+ (0, chai_1.expect)(utils.hasAbsoluteKeyword('ABSOLUTE')).to.equal(true);
117
+ });
118
+ it('returns false for empty string', () => {
119
+ (0, chai_1.expect)(utils.hasAbsoluteKeyword('')).to.equal(false);
120
+ });
121
+ it('returns false for empty string', () => {
122
+ (0, chai_1.expect)(utils.hasAbsoluteKeyword('')).to.equal(false);
123
+ });
124
+ });
125
+ describe('generateRandomVariableName edge cases', () => {
126
+ it('returns prefix only for length 0', () => {
127
+ (0, chai_1.expect)(utils.generateRandomVariableName('prefix', 0)).to.equal('prefix');
128
+ });
129
+ it('returns only random part for empty prefix', () => {
130
+ (0, chai_1.expect)(utils.generateRandomVariableName('', 3)).to.match(/^[a-z]{3}$/);
131
+ });
132
+ it('returns correct length', () => {
133
+ const result = utils.generateRandomVariableName('pre', 5);
134
+ (0, chai_1.expect)(result.length).to.equal(8);
135
+ });
136
+ });
137
+ //# sourceMappingURL=utils-extra.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils-extra.test.js","sourceRoot":"","sources":["../../src/utils-extra.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,65 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ const chai_1 = require("chai");
37
+ const utils = __importStar(require("../utils"));
38
+ describe('utils.ts functions', () => {
39
+ it('hasTailwindCdnSource returns true for Tailwind CDN', () => {
40
+ (0, chai_1.expect)(utils.hasTailwindCdnSource(['https://cdn.tailwindcss.com'])).to.equal(true);
41
+ (0, chai_1.expect)(utils.hasTailwindCdnSource(['https://example.com'])).to.equal(false);
42
+ });
43
+ it('replaceSourceUrlVars returns input if no match', () => {
44
+ const str = "var.url+'http://site.com/path'";
45
+ const expected = "${vars.url}/path";
46
+ (0, chai_1.expect)(utils.replaceSourceUrlVars(str, 'http://site.com')).to.equal(expected);
47
+ });
48
+ it('sanitizeAndReplaceLeadingNumbers replaces leading numbers', () => {
49
+ (0, chai_1.expect)(utils.sanitizeAndReplaceLeadingNumbers('1test')).to.match(/one1test|1test/);
50
+ });
51
+ it('replaceUnderscoresSpacesAndUppercaseLetters replaces underscores and spaces', () => {
52
+ (0, chai_1.expect)(utils.replaceUnderscoresSpacesAndUppercaseLetters('Test_Name Here')).to.equal('test-name-here');
53
+ });
54
+ it('convertDashesSpacesAndUppercaseToUnderscoresAndLowercase converts correctly', () => {
55
+ (0, chai_1.expect)(utils.convertDashesSpacesAndUppercaseToUnderscoresAndLowercase('Test-Name Here')).to.equal('test_name_here');
56
+ });
57
+ it('hasAbsoluteKeyword detects absolute', () => {
58
+ (0, chai_1.expect)(utils.hasAbsoluteKeyword('absolute')).to.equal(true);
59
+ (0, chai_1.expect)(utils.hasAbsoluteKeyword('relative')).to.equal(false);
60
+ });
61
+ it('generateRandomVariableName returns string with prefix', () => {
62
+ (0, chai_1.expect)(utils.generateRandomVariableName('prefix')).to.match(/^prefix/);
63
+ });
64
+ });
65
+ //# sourceMappingURL=utils.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.test.js","sourceRoot":"","sources":["../../src/utils.test.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,+BAA8B;AAC9B,gDAAkC;AAElC,QAAQ,CAAC,oBAAoB,EAAE,GAAG,EAAE;IAClC,EAAE,CAAC,oDAAoD,EAAE,GAAG,EAAE;QAC5D,IAAA,aAAM,EAAC,KAAK,CAAC,oBAAoB,CAAC,CAAC,6BAA6B,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QACnF,IAAA,aAAM,EAAC,KAAK,CAAC,oBAAoB,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IAC9E,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,gDAAgD,EAAE,GAAG,EAAE;QACxD,MAAM,GAAG,GAAG,gCAAgC,CAAC;QAC7C,MAAM,QAAQ,GAAG,kBAAkB,CAAC;QACpC,IAAA,aAAM,EAAC,KAAK,CAAC,oBAAoB,CAAC,GAAG,EAAE,iBAAiB,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;IAChF,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,2DAA2D,EAAE,GAAG,EAAE;QACnE,IAAA,aAAM,EAAC,KAAK,CAAC,gCAAgC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC;IACrF,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,6EAA6E,EAAE,GAAG,EAAE;QACrF,IAAA,aAAM,EAAC,KAAK,CAAC,2CAA2C,CAAC,gBAAgB,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC;IACzG,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,6EAA6E,EAAE,GAAG,EAAE;QACrF,IAAA,aAAM,EAAC,KAAK,CAAC,wDAAwD,CAAC,gBAAgB,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC;IACtH,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,qCAAqC,EAAE,GAAG,EAAE;QAC7C,IAAA,aAAM,EAAC,KAAK,CAAC,kBAAkB,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAC5D,IAAA,aAAM,EAAC,KAAK,CAAC,kBAAkB,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IAC/D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uDAAuD,EAAE,GAAG,EAAE;QAC/D,IAAA,aAAM,EAAC,KAAK,CAAC,0BAA0B,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;IACzE,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1 @@
1
+ {"root":["../@types.d.ts","../coverage-demo.test.ts","../globals.ts","../index.test.ts","../index.ts","../snapapi-screenshot.test.ts","../utils.ts","../src/coverage-demo.ts","../src/utils-extra.test.ts","../src/utils.test.ts"],"errors":true,"version":"5.9.3"}
package/dist/utils.js ADDED
@@ -0,0 +1,61 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.hasTailwindCdnSource = hasTailwindCdnSource;
4
+ exports.replaceSourceUrlVars = replaceSourceUrlVars;
5
+ exports.sanitizeAndReplaceLeadingNumbers = sanitizeAndReplaceLeadingNumbers;
6
+ exports.replaceUnderscoresSpacesAndUppercaseLetters = replaceUnderscoresSpacesAndUppercaseLetters;
7
+ exports.convertDashesSpacesAndUppercaseToUnderscoresAndLowercase = convertDashesSpacesAndUppercaseToUnderscoresAndLowercase;
8
+ exports.hasAbsoluteKeyword = hasAbsoluteKeyword;
9
+ exports.generateRandomVariableName = generateRandomVariableName;
10
+ // Utility functions for html-to-gutenberg
11
+ function hasTailwindCdnSource(jsFiles) {
12
+ const tailwindCdnRegex = /https:\/\/(cdn\.tailwindcss\.com(\?[^"'\s]*)?|cdn\.jsdelivr\.net\/npm\/@tailwindcss\/browser@4(\.\d+){0,2})/;
13
+ return jsFiles.some((url) => tailwindCdnRegex.test(url));
14
+ }
15
+ function replaceSourceUrlVars(str, source) {
16
+ if (!source)
17
+ return str;
18
+ const escapedSource = String(source).replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
19
+ const pattern = new RegExp(`var\\.url\\+'${escapedSource}([^']*)'`, 'g');
20
+ if (!pattern.test(str))
21
+ return str;
22
+ return str.replace(pattern, (_match, path) => `\${vars.url}${path}`);
23
+ }
24
+ function sanitizeAndReplaceLeadingNumbers(str) {
25
+ const numberWords = ['zero', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine'];
26
+ let firstNumberReplaced = false;
27
+ return str
28
+ .toLowerCase()
29
+ .replace(/[\s\-_]/g, '')
30
+ .replace(/\d/g, (digit) => {
31
+ if (!firstNumberReplaced) {
32
+ firstNumberReplaced = true;
33
+ return numberWords[parseInt(digit)] + digit;
34
+ }
35
+ return digit;
36
+ })
37
+ .replace(/^[^a-z]+/, '');
38
+ }
39
+ function replaceUnderscoresSpacesAndUppercaseLetters(name = '') {
40
+ return name.replace(new RegExp(/\W|_/, 'g'), '-').toLowerCase();
41
+ }
42
+ function convertDashesSpacesAndUppercaseToUnderscoresAndLowercase(string) {
43
+ if (string) {
44
+ return `${string.replaceAll('-', '_').replaceAll(' ', '_').toLowerCase()}`;
45
+ }
46
+ return '';
47
+ }
48
+ function hasAbsoluteKeyword(str) {
49
+ if (typeof str !== 'string')
50
+ return false;
51
+ return str.toLowerCase().includes('absolute');
52
+ }
53
+ function generateRandomVariableName(prefix = 'content', length = 3) {
54
+ const chars = 'abcdefghijklmnopqrstuvwxyz';
55
+ let suffix = '';
56
+ for (let i = 0; i < length; i++) {
57
+ suffix += chars.charAt(Math.floor(Math.random() * chars.length));
58
+ }
59
+ return `${prefix}${suffix}`;
60
+ }
61
+ //# sourceMappingURL=utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../utils.ts"],"names":[],"mappings":"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"}
package/index.js CHANGED
@@ -1,10 +1,11 @@
1
+ import fetch from 'node-fetch';
1
2
  import presetReact from '@babel/preset-react';
2
3
  import * as babel from '@babel/core';
3
4
  import * as cheerio from 'cheerio';
4
5
  import scopeCss from 'css-scoping';
5
6
  import extractAssets from 'fetch-page-assets';
6
7
  import fs from 'fs';
7
- import icon from 'html-screenshots';
8
+ import dotenv from 'dotenv';
8
9
  import { createRequire } from 'module';
9
10
  import convert from 'node-html-to-jsx';
10
11
  import path from 'path';
@@ -430,10 +431,7 @@ const block = async (
430
431
  all: revert-layer;
431
432
  }\n`;
432
433
 
433
- css += await parseRequirements(cssFiles, options);
434
-
435
- console.log('[CSS BEFORE]', css);
436
-
434
+ css += await parseRequirements(cssFiles, options);
437
435
 
438
436
  for (const style of styles) {
439
437
  css += style.content;
@@ -452,24 +450,21 @@ const block = async (
452
450
 
453
451
 
454
452
  let blockCode = await getBlock(options);
455
-
453
+
454
+ // Ensure all <img> tags are self-closing for valid JSX
455
+ blockCode = blockCode.replace(/<img([^>/]*?)>/g, '<img$1 />');
456
456
  blockCode = blockCode.replaceAll(' / dangerouslySetInnerHTML', ' dangerouslySetInnerHTML')
457
457
 
458
458
  const indexFile = getPhp(options);
459
459
  let blockFile = '';
460
460
 
461
461
  try {
462
- blockFile = transformBlockFile(blockCode).code
463
- ?.replace(/name: \"\{field.name\}\"/g, 'name: field.name')
464
- ?.replace(/key: \"\{index\}\"/g, 'key: index')
462
+ blockFile = transformBlockFile(blockCode).code
463
+ ?.replace(/name: \"\{field.name\}\"/g, 'name: field.name')
464
+ ?.replace(/key: \"\{index\}\"/g, 'key: index');
465
465
  } catch (error) {
466
-
467
466
  console.log(error);
468
-
469
467
  }
470
-
471
- console.log(blockFile);
472
-
473
468
 
474
469
  if (shouldSaveFiles) {
475
470
  try {
@@ -800,9 +795,10 @@ const block = async (
800
795
  const getFixedHtml = (html) => {
801
796
  function parseStyleString(style) {
802
797
  const entries = style.split(';').filter(Boolean).map(rule => {
803
- const [key, value] = rule.split(':');
798
+ let [key, value] = rule.split(':');
804
799
  if (!key || !value) return null;
805
- const camelKey = key.trim().replace(/-([a-z])/g, (_, char) => char.toUpperCase());
800
+ key = key.trim().replace(/^[-\s]+/, '');
801
+ const camelKey = key.replace(/-([a-z])/g, (_, char) => char.toUpperCase());
806
802
  return [camelKey, value.trim()];
807
803
  }).filter(Boolean);
808
804
  const styleObject = Object.fromEntries(entries);
@@ -905,44 +901,40 @@ const block = async (
905
901
  return `<svg ${group1} dangerouslySetInnerHTML={ { __html: attributes.${randomSVGVariable} }}></svg>`;
906
902
  };
907
903
  const replaceSVGImages = async (html) => {
908
- const regex = /<\s*svg\b((?:[^>'"]|"[^"]*"|'[^']*')*)>(\s*(?:[^<]|<(?!\/svg\s*>))*)(<\/\s*svg\s*>)/gim;
909
-
904
+ // Improved SVG handling: preserve nesting and avoid splitting SVG from parent
905
+ const svgRegex = /(<svg[\s\S]*?<\/svg>)/gi;
910
906
  let result = '';
911
907
  let lastIndex = 0;
912
- const matches = [...html.matchAll(regex)];
913
-
914
- for (const match of matches) {
915
- const [fullMatch, group1, group2, group3] = match;
908
+ let match;
909
+
910
+ while ((match = svgRegex.exec(html)) !== null) {
911
+ const [svgBlock] = match;
916
912
  const start = match.index;
917
- const end = start + fullMatch.length;
918
-
919
- result += html.slice(lastIndex, start);
920
-
921
- const content = group2.trim();
922
- if (content) {
913
+ const end = start + svgBlock.length;
914
+
915
+ // Add preceding HTML
916
+ result += html.slice(lastIndex, start);
917
+
918
+ // Extract attributes and inner content
919
+ const attrMatch = svgBlock.match(/^<svg([^>]*)>([\s\S]*?)<\/svg>$/i);
920
+ if (attrMatch) {
921
+ const group1 = attrMatch[1];
922
+ const group2 = attrMatch[2];
923
923
  const randomSVGVariable = generateRandomVariableName('svg');
924
- setRandomAttributeContent(randomSVGVariable, content.replaceAll('className', 'class'));
924
+ setRandomAttributeContent(randomSVGVariable, group2.replaceAll('className', 'class'));
925
925
  createPanel({
926
926
  type: 'svg',
927
927
  title: 'SVG Markup',
928
928
  attributes: [randomSVGVariable],
929
929
  });
930
-
931
-
932
- const replacement = getSvgTemplate(fullMatch, group1, group3, randomSVGVariable)
933
-
934
- result += replacement;
930
+ // Replace with JSX template, preserving parent context
931
+ result += getSvgTemplate(svgBlock, group1, '</svg>', randomSVGVariable);
935
932
  } else {
936
- result += fullMatch;
933
+ result += svgBlock;
937
934
  }
938
-
939
935
  lastIndex = end;
940
936
  }
941
-
942
937
  result += html.slice(lastIndex);
943
-
944
- console.log(result);
945
-
946
938
  return result;
947
939
  };
948
940
  const getSvgPanelTemplate = (panel) => {
@@ -1288,17 +1280,33 @@ const block = async (
1288
1280
  };
1289
1281
 
1290
1282
  const buildSaveContent = (editContent) => {
1291
- return editContent.replace(
1283
+ // Ensure RichText and RichText.Content are always self-closing
1284
+ let output = editContent.replace(
1285
+ /<RichText((.|\n)*?)value=\{(.*?)\}((.|\n)*?)>([\s\S]*?)<\/RichText>/gi,
1286
+ '<RichText.Content value={$3} />'
1287
+ );
1288
+ output = output.replace(
1292
1289
  /<RichText((.|\n)*?)value=\{(.*?)\}((.|\n)*?)\/>/gi,
1293
1290
  '<RichText.Content value={$3} />'
1294
- )
1295
- .replaceAll('class=', 'className=')
1296
- .replace(
1291
+ );
1292
+
1293
+ // If a wrapper (e.g., span) contains only RichText.Content, keep the wrapper and its attributes
1294
+ output = output.replace(
1295
+ /(<([a-zA-Z0-9]+)([^>]*)>\s*)<RichText\.Content value=\{([^}]+)\} \/>(\s*<\/\2>)/gi,
1296
+ (match, openTag, tagName, attrs, value, closeTag) => {
1297
+ // Keep the wrapper and its attributes, insert RichText.Content inside
1298
+ return `${openTag}<RichText.Content value={${value}} />${closeTag}`;
1299
+ }
1300
+ );
1301
+
1302
+ output = output.replaceAll('class=', 'className=');
1303
+ output = output.replace(
1297
1304
  /<MediaUpload\b[^>]*>([\s\S]*?(<img\b[^>]*>*\/>)[\s\S]*?)\/>/g,
1298
1305
  (_match, _attributes, img) => {
1299
1306
  return img.replace(/onClick={[^}]+}\s*/, '');
1300
1307
  }
1301
1308
  );
1309
+ return output;
1302
1310
  };
1303
1311
 
1304
1312
  const removeHref = (match) => {
@@ -1460,11 +1468,6 @@ const block = async (
1460
1468
  return `${style.content}`;
1461
1469
  }).join('\n');
1462
1470
 
1463
-
1464
- console.log('[CSSFETCHED]', css);
1465
-
1466
-
1467
-
1468
1471
  const scriptRegex = /<script[^>]*>([\s\S]*?)<\/script>/gi;
1469
1472
  const scriptSrcRegex =
1470
1473
  /<script\s+[^>]*src=["']([^"']+)["'][^>]*>\s*<\/script>/gi;
@@ -1536,10 +1539,41 @@ const block = async (
1536
1539
  htmlContent = replaceRelativeUrlsInCssWithBase(htmlContent, source);
1537
1540
  }
1538
1541
 
1539
- try {
1540
- icon(htmlContent, { basePath: path.join(options.basePath, replaceUnderscoresSpacesAndUppercaseLetters(options.name)) });
1541
- } catch (error) {
1542
- console.log(`There was an error generating preview. ${error.message}`);
1542
+
1543
+
1544
+ // Screenshot generation using SnapAPI
1545
+ dotenv.config();
1546
+ if (options.generateIconPreview && options.source) {
1547
+ try {
1548
+ const snapApiKey = process.env.SNAPAPI_KEY;
1549
+ if (!snapApiKey) {
1550
+ throw new Error('SNAPAPI_KEY is not set in environment variables.');
1551
+ }
1552
+ const snapApiUrl = 'https://api.snapapi.pics/v1/screenshot';
1553
+ const snapApiBody = {
1554
+ url: options.source,
1555
+ fullPage: true,
1556
+ delay: 4000,
1557
+ blockAds: true,
1558
+ blockCookieBanners: true
1559
+ };
1560
+ const response = await fetch(snapApiUrl, {
1561
+ method: 'POST',
1562
+ headers: {
1563
+ 'X-Api-Key': snapApiKey,
1564
+ 'Content-Type': 'application/json'
1565
+ },
1566
+ body: JSON.stringify(snapApiBody)
1567
+ });
1568
+ if (!response.ok) {
1569
+ throw new Error(`SnapAPI error: ${response.status}`);
1570
+ }
1571
+ const previewPath = path.join(options.basePath, replaceUnderscoresSpacesAndUppercaseLetters(options.name), 'preview.jpeg');
1572
+ const buffer = Buffer.from(await response.arrayBuffer());
1573
+ fs.writeFileSync(previewPath, buffer);
1574
+ } catch (error) {
1575
+ console.log(`There was an error generating preview with SnapAPI. ${error.message}`);
1576
+ }
1543
1577
  }
1544
1578
 
1545
1579
  return saveFiles(await setupVariables(htmlContent, options));
package/index.test.ts ADDED
@@ -0,0 +1,145 @@
1
+ import * as utils from './utils';
2
+ import { expect } from 'chai';
3
+ // Removed imports from index and globals to avoid ESM parsing errors
4
+
5
+ describe('utils.ts functions', () => {
6
+ it('hasTailwindCdnSource returns true for Tailwind CDN', () => {
7
+ expect(utils.hasTailwindCdnSource(['https://cdn.tailwindcss.com'])).to.equal(true);
8
+ expect(utils.hasTailwindCdnSource(['https://example.com'])).to.equal(false);
9
+ });
10
+
11
+ it('replaceSourceUrlVars returns input if no match', () => {
12
+ const str = "var.url+'http://site.com/path'";
13
+ const expected = "${vars.url}/path";
14
+ expect(utils.replaceSourceUrlVars(str, 'http://site.com')).to.equal(expected);
15
+ });
16
+
17
+ it('sanitizeAndReplaceLeadingNumbers replaces leading numbers', () => {
18
+ expect(utils.sanitizeAndReplaceLeadingNumbers('1test')).to.match(/one1test|1test/);
19
+ });
20
+
21
+ it('replaceUnderscoresSpacesAndUppercaseLetters replaces underscores and spaces', () => {
22
+ expect(utils.replaceUnderscoresSpacesAndUppercaseLetters('Test_Name Here')).to.equal('test-name-here');
23
+ });
24
+
25
+ it('convertDashesSpacesAndUppercaseToUnderscoresAndLowercase converts correctly', () => {
26
+ expect(utils.convertDashesSpacesAndUppercaseToUnderscoresAndLowercase('Test-Name Here')).to.equal('test_name_here');
27
+ });
28
+
29
+ it('hasAbsoluteKeyword detects absolute', () => {
30
+ expect(utils.hasAbsoluteKeyword('absolute')).to.equal(true);
31
+ expect(utils.hasAbsoluteKeyword('relative')).to.equal(false);
32
+ });
33
+
34
+ it('generateRandomVariableName returns string with prefix', () => {
35
+ expect(utils.generateRandomVariableName('prefix')).to.match(/^prefix/);
36
+ });
37
+
38
+ // Additional coverage tests
39
+
40
+ describe('hasTailwindCdnSource edge cases', () => {
41
+ it('returns false for empty array', () => {
42
+ expect(utils.hasTailwindCdnSource([])).to.equal(false);
43
+ });
44
+ it('returns true for multiple tailwind URLs', () => {
45
+ expect(utils.hasTailwindCdnSource([
46
+ 'https://cdn.tailwindcss.com',
47
+ 'https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4.0.0'
48
+ ])).to.equal(true);
49
+ });
50
+ it('returns false for malformed URLs', () => {
51
+ expect(utils.hasTailwindCdnSource(['not-a-url'])).to.equal(false);
52
+ });
53
+ });
54
+
55
+ describe('replaceSourceUrlVars edge cases', () => {
56
+ it('replaces matching pattern', () => {
57
+ const str = "var.url+'http://site.com/path'";
58
+ const source = 'http://site.com';
59
+ const expected = "${vars.url}/path";
60
+ expect(utils.replaceSourceUrlVars(str, source)).to.contain(expected);
61
+ });
62
+ it('returns input for empty string', () => {
63
+ expect(utils.replaceSourceUrlVars('', 'http://site.com')).to.equal('');
64
+ });
65
+ it('returns input for null source', () => {
66
+ expect(utils.replaceSourceUrlVars("var.url+'http://site.com/path'", null)).to.equal("var.url+'http://site.com/path'");
67
+ });
68
+ it('replaces multiple matches', () => {
69
+ const str = "var.url+'http://site.com/a' and var.url+'http://site.com/b'";
70
+ const source = 'http://site.com';
71
+ const result = utils.replaceSourceUrlVars(str, source);
72
+ expect(result.match(/\${vars\.url}/g)?.length).to.be.greaterThanOrEqual(2);
73
+ });
74
+ });
75
+
76
+ describe('sanitizeAndReplaceLeadingNumbers edge cases', () => {
77
+ it('returns input for no numbers', () => {
78
+ expect(utils.sanitizeAndReplaceLeadingNumbers('test')).to.equal('test');
79
+ });
80
+ it('handles multiple leading numbers', () => {
81
+ expect(utils.sanitizeAndReplaceLeadingNumbers('123abc')).to.match(/one1two2three3abc|123abc/);
82
+ });
83
+ it('handles only numbers', () => {
84
+ expect(utils.sanitizeAndReplaceLeadingNumbers('123')).to.match(/one1two2three3|123/);
85
+ });
86
+ it('handles special characters', () => {
87
+ expect(utils.sanitizeAndReplaceLeadingNumbers('1_test')).to.match(/one1test|1test/);
88
+ });
89
+ });
90
+
91
+ describe('replaceUnderscoresSpacesAndUppercaseLetters edge cases', () => {
92
+ it('handles only underscores', () => {
93
+ expect(utils.replaceUnderscoresSpacesAndUppercaseLetters('___')).to.equal('---');
94
+ });
95
+ it('handles only spaces', () => {
96
+ expect(utils.replaceUnderscoresSpacesAndUppercaseLetters(' ')).to.equal('---');
97
+ });
98
+ it('handles mixed cases', () => {
99
+ expect(utils.replaceUnderscoresSpacesAndUppercaseLetters('Test_Name Here')).to.equal('test-name-here');
100
+ });
101
+ it('handles empty string', () => {
102
+ expect(utils.replaceUnderscoresSpacesAndUppercaseLetters('')).to.equal('');
103
+ });
104
+ });
105
+
106
+ describe('convertDashesSpacesAndUppercaseToUnderscoresAndLowercase edge cases', () => {
107
+ it('handles only dashes', () => {
108
+ expect(utils.convertDashesSpacesAndUppercaseToUnderscoresAndLowercase('---')).to.equal('___');
109
+ });
110
+ it('handles only spaces', () => {
111
+ expect(utils.convertDashesSpacesAndUppercaseToUnderscoresAndLowercase(' ')).to.equal('___');
112
+ });
113
+ it('handles mixed cases', () => {
114
+ expect(utils.convertDashesSpacesAndUppercaseToUnderscoresAndLowercase('Test-Name Here')).to.equal('test_name_here');
115
+ });
116
+ it('handles empty string', () => {
117
+ expect(utils.convertDashesSpacesAndUppercaseToUnderscoresAndLowercase('')).to.equal('');
118
+ });
119
+ });
120
+
121
+ describe('hasAbsoluteKeyword edge cases', () => {
122
+ it('detects uppercase', () => {
123
+ expect(utils.hasAbsoluteKeyword('ABSOLUTE')).to.equal(true);
124
+ });
125
+ it('returns false for empty string', () => {
126
+ expect(utils.hasAbsoluteKeyword('')).to.equal(false);
127
+ });
128
+ it('returns false for empty string', () => {
129
+ expect(utils.hasAbsoluteKeyword('')).to.equal(false);
130
+ });
131
+ });
132
+
133
+ describe('generateRandomVariableName edge cases', () => {
134
+ it('returns prefix only for length 0', () => {
135
+ expect(utils.generateRandomVariableName('prefix', 0)).to.equal('prefix');
136
+ });
137
+ it('returns only random part for empty prefix', () => {
138
+ expect(utils.generateRandomVariableName('', 3)).to.match(/^[a-z]{3}$/);
139
+ });
140
+ it('returns correct length', () => {
141
+ const result = utils.generateRandomVariableName('pre', 5);
142
+ expect(result.length).to.equal(8);
143
+ });
144
+ });
145
+ });