@thyn/core 0.0.352 → 0.0.353
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/plugin/utils.js +95 -25
- package/docs/package-lock.json +4 -4
- package/docs/package.json +1 -1
- package/package.json +1 -1
- package/src/plugin/utils.ts +103 -25
package/dist/plugin/utils.js
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
export function extractParts(code) {
|
|
2
2
|
// Helper to check if a position is inside a string literal or comment
|
|
3
|
-
|
|
3
|
+
// within a specific range (used for checking script content only)
|
|
4
|
+
function isInsideStringOrComment(code, startPos, endPos) {
|
|
4
5
|
let inString = false;
|
|
5
6
|
let stringChar = '';
|
|
6
7
|
let escaped = false;
|
|
7
8
|
let inLineComment = false;
|
|
8
9
|
let inBlockComment = false;
|
|
9
|
-
for (let i =
|
|
10
|
+
for (let i = startPos; i < endPos; i++) {
|
|
10
11
|
const char = code[i];
|
|
11
12
|
const nextChar = code[i + 1];
|
|
12
13
|
if (inLineComment) {
|
|
@@ -52,45 +53,114 @@ export function extractParts(code) {
|
|
|
52
53
|
}
|
|
53
54
|
return inString || inLineComment || inBlockComment;
|
|
54
55
|
}
|
|
55
|
-
// Find
|
|
56
|
-
function
|
|
56
|
+
// Find all script tag positions with their boundaries
|
|
57
|
+
function findScriptBoundaries(code) {
|
|
58
|
+
const boundaries = [];
|
|
57
59
|
const openRegex = /<script([^>]*)>/gi;
|
|
60
|
+
const closeRegex = /<\/script>/gi;
|
|
58
61
|
let openMatch;
|
|
59
62
|
while ((openMatch = openRegex.exec(code)) !== null) {
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
63
|
+
const openIndex = openMatch.index;
|
|
64
|
+
const openLength = openMatch[0].length;
|
|
65
|
+
const attrs = openMatch[1] || '';
|
|
66
|
+
// Find matching close tag
|
|
67
|
+
closeRegex.lastIndex = openIndex + openLength;
|
|
68
|
+
let closeMatch;
|
|
69
|
+
while ((closeMatch = closeRegex.exec(code)) !== null) {
|
|
70
|
+
// Check if this close tag is inside a JS string within this script
|
|
71
|
+
const contentStart = openIndex + openLength;
|
|
72
|
+
if (!isInsideStringOrComment(code, contentStart, closeMatch.index)) {
|
|
73
|
+
boundaries.push({
|
|
74
|
+
start: openIndex,
|
|
75
|
+
end: closeMatch.index + closeMatch[0].length,
|
|
76
|
+
attrs
|
|
77
|
+
});
|
|
78
|
+
break;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
return boundaries;
|
|
83
|
+
}
|
|
84
|
+
// Find the real script section (not inside a string of another script)
|
|
85
|
+
function findScriptSection(code) {
|
|
86
|
+
const allBoundaries = findScriptBoundaries(code);
|
|
87
|
+
if (allBoundaries.length === 0)
|
|
88
|
+
return null;
|
|
89
|
+
// The first script tag is the real one if it's not inside any other script's string
|
|
90
|
+
// Check each boundary to see if it's inside another script's content
|
|
91
|
+
for (const boundary of allBoundaries) {
|
|
92
|
+
let isInsideAnotherScript = false;
|
|
93
|
+
for (const other of allBoundaries) {
|
|
94
|
+
if (other === boundary)
|
|
95
|
+
continue;
|
|
96
|
+
// Check if this boundary is inside another script's content
|
|
97
|
+
const otherContentStart = other.start + code.slice(other.start, other.end).indexOf('>') + 1;
|
|
98
|
+
const otherContentEnd = other.end - code.slice(other.end - 10, other.end).indexOf('<') - 10 + code.slice(other.end - 10, other.end).indexOf('<');
|
|
99
|
+
if (boundary.start > otherContentStart && boundary.start < other.end) {
|
|
100
|
+
// This boundary is inside another script's content area
|
|
101
|
+
// Check if it's inside a JS string
|
|
102
|
+
if (isInsideStringOrComment(code, otherContentStart, boundary.start)) {
|
|
103
|
+
isInsideAnotherScript = true;
|
|
104
|
+
break;
|
|
74
105
|
}
|
|
75
106
|
}
|
|
76
107
|
}
|
|
108
|
+
if (!isInsideAnotherScript) {
|
|
109
|
+
// This is the real script section
|
|
110
|
+
const openTagEnd = code.indexOf('>', boundary.start) + 1;
|
|
111
|
+
const closeTagStart = code.lastIndexOf('<', boundary.end - 1);
|
|
112
|
+
return {
|
|
113
|
+
start: boundary.start,
|
|
114
|
+
contentStart: openTagEnd,
|
|
115
|
+
contentEnd: closeTagStart,
|
|
116
|
+
end: boundary.end,
|
|
117
|
+
attrs: boundary.attrs
|
|
118
|
+
};
|
|
119
|
+
}
|
|
77
120
|
}
|
|
78
121
|
return null;
|
|
79
122
|
}
|
|
80
|
-
// Find
|
|
123
|
+
// Find the real style section (outside of script sections)
|
|
81
124
|
function findStyleSection(code) {
|
|
125
|
+
const scriptBoundaries = findScriptBoundaries(code);
|
|
82
126
|
const openRegex = /<style[^>]*>/gi;
|
|
127
|
+
const closeRegex = /<\/style>/gi;
|
|
83
128
|
let openMatch;
|
|
84
129
|
while ((openMatch = openRegex.exec(code)) !== null) {
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
130
|
+
const openIndex = openMatch.index;
|
|
131
|
+
// Check if this style tag is inside any script section
|
|
132
|
+
let isInsideScript = false;
|
|
133
|
+
for (const script of scriptBoundaries) {
|
|
134
|
+
const contentStart = script.start + code.slice(script.start, script.end).indexOf('>') + 1;
|
|
135
|
+
const contentEnd = script.end - code.slice(script.end - 10, script.end).indexOf('<') - 10 + code.slice(script.end - 10, script.end).indexOf('<');
|
|
136
|
+
if (openIndex >= contentStart && openIndex < script.end) {
|
|
137
|
+
// It's in the script section, check if inside a JS string
|
|
138
|
+
if (isInsideStringOrComment(code, contentStart, openIndex)) {
|
|
139
|
+
isInsideScript = true;
|
|
140
|
+
break;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
if (!isInsideScript) {
|
|
145
|
+
// Found a real style tag, now find its close tag
|
|
146
|
+
const contentStart = openIndex + openMatch[0].length;
|
|
147
|
+
closeRegex.lastIndex = contentStart;
|
|
89
148
|
let closeMatch;
|
|
90
149
|
while ((closeMatch = closeRegex.exec(code)) !== null) {
|
|
91
|
-
|
|
150
|
+
// Make sure close tag is also outside scripts
|
|
151
|
+
let closeIsInsideScript = false;
|
|
152
|
+
for (const script of scriptBoundaries) {
|
|
153
|
+
const scriptContentStart = script.start + code.slice(script.start, script.end).indexOf('>') + 1;
|
|
154
|
+
if (closeMatch.index >= scriptContentStart && closeMatch.index < script.end) {
|
|
155
|
+
if (isInsideStringOrComment(code, scriptContentStart, closeMatch.index)) {
|
|
156
|
+
closeIsInsideScript = true;
|
|
157
|
+
break;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
if (!closeIsInsideScript) {
|
|
92
162
|
return {
|
|
93
|
-
start:
|
|
163
|
+
start: openIndex,
|
|
94
164
|
contentStart: contentStart,
|
|
95
165
|
contentEnd: closeMatch.index,
|
|
96
166
|
end: closeMatch.index + closeMatch[0].length
|
package/docs/package-lock.json
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
"name": "thyn-app",
|
|
9
9
|
"version": "0.0.0",
|
|
10
10
|
"devDependencies": {
|
|
11
|
-
"@thyn/core": "^0.0.
|
|
11
|
+
"@thyn/core": "^0.0.352",
|
|
12
12
|
"vite": "^6.3.5"
|
|
13
13
|
}
|
|
14
14
|
},
|
|
@@ -742,9 +742,9 @@
|
|
|
742
742
|
]
|
|
743
743
|
},
|
|
744
744
|
"node_modules/@thyn/core": {
|
|
745
|
-
"version": "0.0.
|
|
746
|
-
"resolved": "https://registry.npmjs.org/@thyn/core/-/core-0.0.
|
|
747
|
-
"integrity": "sha512-
|
|
745
|
+
"version": "0.0.352",
|
|
746
|
+
"resolved": "https://registry.npmjs.org/@thyn/core/-/core-0.0.352.tgz",
|
|
747
|
+
"integrity": "sha512-XvVkZ63CdWxF+OIOnLoxPOesQ0OFlfr/1CY4/LNrZO2QTK4/I92cRlbDaW1ajN3YDSuvf7BeEuWZe5hYn8Jd/Q==",
|
|
748
748
|
"dev": true,
|
|
749
749
|
"license": "MIT",
|
|
750
750
|
"dependencies": {
|
package/docs/package.json
CHANGED
package/package.json
CHANGED
package/src/plugin/utils.ts
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
export function extractParts(code: string) {
|
|
2
2
|
// Helper to check if a position is inside a string literal or comment
|
|
3
|
-
|
|
3
|
+
// within a specific range (used for checking script content only)
|
|
4
|
+
function isInsideStringOrComment(code: string, startPos: number, endPos: number): boolean {
|
|
4
5
|
let inString = false;
|
|
5
6
|
let stringChar = '';
|
|
6
7
|
let escaped = false;
|
|
7
8
|
let inLineComment = false;
|
|
8
9
|
let inBlockComment = false;
|
|
9
10
|
|
|
10
|
-
for (let i =
|
|
11
|
+
for (let i = startPos; i < endPos; i++) {
|
|
11
12
|
const char = code[i];
|
|
12
13
|
const nextChar = code[i + 1];
|
|
13
14
|
|
|
@@ -61,50 +62,127 @@ export function extractParts(code: string) {
|
|
|
61
62
|
return inString || inLineComment || inBlockComment;
|
|
62
63
|
}
|
|
63
64
|
|
|
64
|
-
// Find
|
|
65
|
-
function
|
|
65
|
+
// Find all script tag positions with their boundaries
|
|
66
|
+
function findScriptBoundaries(code: string): Array<{ start: number; end: number; attrs: string }> {
|
|
67
|
+
const boundaries = [];
|
|
66
68
|
const openRegex = /<script([^>]*)>/gi;
|
|
69
|
+
const closeRegex = /<\/script>/gi;
|
|
67
70
|
let openMatch;
|
|
68
71
|
|
|
69
72
|
while ((openMatch = openRegex.exec(code)) !== null) {
|
|
70
|
-
|
|
71
|
-
|
|
73
|
+
const openIndex = openMatch.index;
|
|
74
|
+
const openLength = openMatch[0].length;
|
|
75
|
+
const attrs = openMatch[1] || '';
|
|
76
|
+
|
|
77
|
+
// Find matching close tag
|
|
78
|
+
closeRegex.lastIndex = openIndex + openLength;
|
|
79
|
+
let closeMatch;
|
|
80
|
+
while ((closeMatch = closeRegex.exec(code)) !== null) {
|
|
81
|
+
// Check if this close tag is inside a JS string within this script
|
|
82
|
+
const contentStart = openIndex + openLength;
|
|
83
|
+
if (!isInsideStringOrComment(code, contentStart, closeMatch.index)) {
|
|
84
|
+
boundaries.push({
|
|
85
|
+
start: openIndex,
|
|
86
|
+
end: closeMatch.index + closeMatch[0].length,
|
|
87
|
+
attrs
|
|
88
|
+
});
|
|
89
|
+
break;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
return boundaries;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// Find the real script section (not inside a string of another script)
|
|
98
|
+
function findScriptSection(code: string): { start: number; contentStart: number; contentEnd: number; end: number; attrs: string } | null {
|
|
99
|
+
const allBoundaries = findScriptBoundaries(code);
|
|
100
|
+
if (allBoundaries.length === 0) return null;
|
|
101
|
+
|
|
102
|
+
// The first script tag is the real one if it's not inside any other script's string
|
|
103
|
+
// Check each boundary to see if it's inside another script's content
|
|
104
|
+
for (const boundary of allBoundaries) {
|
|
105
|
+
let isInsideAnotherScript = false;
|
|
106
|
+
|
|
107
|
+
for (const other of allBoundaries) {
|
|
108
|
+
if (other === boundary) continue;
|
|
72
109
|
|
|
73
|
-
//
|
|
74
|
-
const
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
attrs: openMatch[1] || ''
|
|
84
|
-
};
|
|
110
|
+
// Check if this boundary is inside another script's content
|
|
111
|
+
const otherContentStart = other.start + code.slice(other.start, other.end).indexOf('>') + 1;
|
|
112
|
+
const otherContentEnd = other.end - code.slice(other.end - 10, other.end).indexOf('<') - 10 + code.slice(other.end - 10, other.end).indexOf('<');
|
|
113
|
+
|
|
114
|
+
if (boundary.start > otherContentStart && boundary.start < other.end) {
|
|
115
|
+
// This boundary is inside another script's content area
|
|
116
|
+
// Check if it's inside a JS string
|
|
117
|
+
if (isInsideStringOrComment(code, otherContentStart, boundary.start)) {
|
|
118
|
+
isInsideAnotherScript = true;
|
|
119
|
+
break;
|
|
85
120
|
}
|
|
86
121
|
}
|
|
87
122
|
}
|
|
123
|
+
|
|
124
|
+
if (!isInsideAnotherScript) {
|
|
125
|
+
// This is the real script section
|
|
126
|
+
const openTagEnd = code.indexOf('>', boundary.start) + 1;
|
|
127
|
+
const closeTagStart = code.lastIndexOf('<', boundary.end - 1);
|
|
128
|
+
return {
|
|
129
|
+
start: boundary.start,
|
|
130
|
+
contentStart: openTagEnd,
|
|
131
|
+
contentEnd: closeTagStart,
|
|
132
|
+
end: boundary.end,
|
|
133
|
+
attrs: boundary.attrs
|
|
134
|
+
};
|
|
135
|
+
}
|
|
88
136
|
}
|
|
137
|
+
|
|
89
138
|
return null;
|
|
90
139
|
}
|
|
91
140
|
|
|
92
|
-
// Find
|
|
141
|
+
// Find the real style section (outside of script sections)
|
|
93
142
|
function findStyleSection(code: string): { start: number; contentStart: number; contentEnd: number; end: number } | null {
|
|
143
|
+
const scriptBoundaries = findScriptBoundaries(code);
|
|
94
144
|
const openRegex = /<style[^>]*>/gi;
|
|
145
|
+
const closeRegex = /<\/style>/gi;
|
|
95
146
|
let openMatch;
|
|
96
147
|
|
|
97
148
|
while ((openMatch = openRegex.exec(code)) !== null) {
|
|
98
|
-
|
|
99
|
-
|
|
149
|
+
const openIndex = openMatch.index;
|
|
150
|
+
|
|
151
|
+
// Check if this style tag is inside any script section
|
|
152
|
+
let isInsideScript = false;
|
|
153
|
+
for (const script of scriptBoundaries) {
|
|
154
|
+
const contentStart = script.start + code.slice(script.start, script.end).indexOf('>') + 1;
|
|
155
|
+
const contentEnd = script.end - code.slice(script.end - 10, script.end).indexOf('<') - 10 + code.slice(script.end - 10, script.end).indexOf('<');
|
|
100
156
|
|
|
101
|
-
|
|
102
|
-
|
|
157
|
+
if (openIndex >= contentStart && openIndex < script.end) {
|
|
158
|
+
// It's in the script section, check if inside a JS string
|
|
159
|
+
if (isInsideStringOrComment(code, contentStart, openIndex)) {
|
|
160
|
+
isInsideScript = true;
|
|
161
|
+
break;
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
if (!isInsideScript) {
|
|
167
|
+
// Found a real style tag, now find its close tag
|
|
168
|
+
const contentStart = openIndex + openMatch[0].length;
|
|
169
|
+
closeRegex.lastIndex = contentStart;
|
|
103
170
|
let closeMatch;
|
|
104
171
|
while ((closeMatch = closeRegex.exec(code)) !== null) {
|
|
105
|
-
|
|
172
|
+
// Make sure close tag is also outside scripts
|
|
173
|
+
let closeIsInsideScript = false;
|
|
174
|
+
for (const script of scriptBoundaries) {
|
|
175
|
+
const scriptContentStart = script.start + code.slice(script.start, script.end).indexOf('>') + 1;
|
|
176
|
+
if (closeMatch.index >= scriptContentStart && closeMatch.index < script.end) {
|
|
177
|
+
if (isInsideStringOrComment(code, scriptContentStart, closeMatch.index)) {
|
|
178
|
+
closeIsInsideScript = true;
|
|
179
|
+
break;
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
if (!closeIsInsideScript) {
|
|
106
184
|
return {
|
|
107
|
-
start:
|
|
185
|
+
start: openIndex,
|
|
108
186
|
contentStart: contentStart,
|
|
109
187
|
contentEnd: closeMatch.index,
|
|
110
188
|
end: closeMatch.index + closeMatch[0].length
|