rwsdk 0.2.0-alpha.16-test.20250825032050 → 0.2.0-alpha.18
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.
|
@@ -28,23 +28,18 @@ function hasJsxFunctions(text) {
|
|
|
28
28
|
text.includes('jsxDEV("link"') ||
|
|
29
29
|
text.includes("jsxDEV('link'"));
|
|
30
30
|
}
|
|
31
|
-
// Transform import statements in script content using ts-morph
|
|
32
31
|
function transformScriptImports(scriptContent, manifest) {
|
|
33
32
|
const scriptProject = new Project({ useInMemoryFileSystem: true });
|
|
34
33
|
try {
|
|
35
|
-
// Wrap in a function to make it valid JavaScript
|
|
36
34
|
const wrappedContent = `function __wrapper() {${scriptContent}}`;
|
|
37
35
|
const scriptFile = scriptProject.createSourceFile("script.js", wrappedContent);
|
|
38
36
|
let hasChanges = false;
|
|
39
37
|
const entryPoints = [];
|
|
40
|
-
// Find all CallExpressions that look like import("path")
|
|
41
38
|
scriptFile
|
|
42
39
|
.getDescendantsOfKind(SyntaxKind.CallExpression)
|
|
43
40
|
.forEach((callExpr) => {
|
|
44
41
|
const expr = callExpr.getExpression();
|
|
45
|
-
// Check for both "import()" and "await import()" patterns
|
|
46
42
|
const isImport = expr.getText() === "import";
|
|
47
|
-
// Check for await import pattern
|
|
48
43
|
const isAwaitImport = expr.getKind() === SyntaxKind.PropertyAccessExpression &&
|
|
49
44
|
expr.getText().endsWith(".import");
|
|
50
45
|
if (isImport || isAwaitImport) {
|
|
@@ -54,7 +49,7 @@ function transformScriptImports(scriptContent, manifest) {
|
|
|
54
49
|
if (importPath.startsWith("/")) {
|
|
55
50
|
log("Found dynamic import with root-relative path: %s", importPath);
|
|
56
51
|
entryPoints.push(importPath);
|
|
57
|
-
const path = importPath.slice(1);
|
|
52
|
+
const path = importPath.slice(1);
|
|
58
53
|
if (manifest[path]) {
|
|
59
54
|
const transformedSrc = `/${manifest[path].file}`;
|
|
60
55
|
args[0].setLiteralValue(transformedSrc);
|
|
@@ -65,19 +60,15 @@ function transformScriptImports(scriptContent, manifest) {
|
|
|
65
60
|
}
|
|
66
61
|
});
|
|
67
62
|
if (hasChanges) {
|
|
68
|
-
// Extract the transformed content from inside the wrapper function
|
|
69
63
|
const fullText = scriptFile.getFullText();
|
|
70
|
-
// Find content between the first { and the last }
|
|
71
64
|
const startPos = fullText.indexOf("{") + 1;
|
|
72
65
|
const endPos = fullText.lastIndexOf("}");
|
|
73
66
|
const transformedContent = fullText.substring(startPos, endPos);
|
|
74
67
|
return { content: transformedContent, hasChanges: true, entryPoints };
|
|
75
68
|
}
|
|
76
|
-
// Return the original content when no changes are made
|
|
77
69
|
return { content: scriptContent, hasChanges: false, entryPoints };
|
|
78
70
|
}
|
|
79
71
|
catch (error) {
|
|
80
|
-
// If parsing fails, fall back to the original content
|
|
81
72
|
console.warn("Failed to parse inline script content:", error);
|
|
82
73
|
return { content: undefined, hasChanges: false, entryPoints: [] };
|
|
83
74
|
}
|
|
@@ -93,15 +84,12 @@ export async function transformJsxScriptTagsCode(code, manifest = {}) {
|
|
|
93
84
|
const modifications = [];
|
|
94
85
|
const needsRequestInfoImportRef = { value: false };
|
|
95
86
|
const entryPointsPerCallExpr = new Map();
|
|
96
|
-
// Check for existing imports up front
|
|
97
87
|
let hasRequestInfoImport = false;
|
|
98
88
|
let sdkWorkerImportDecl;
|
|
99
|
-
// Scan for imports only once
|
|
100
89
|
sourceFile.getImportDeclarations().forEach((importDecl) => {
|
|
101
90
|
const moduleSpecifier = importDecl.getModuleSpecifierValue();
|
|
102
91
|
if (moduleSpecifier === "rwsdk/worker") {
|
|
103
92
|
sdkWorkerImportDecl = importDecl;
|
|
104
|
-
// Check if requestInfo is already imported
|
|
105
93
|
if (importDecl
|
|
106
94
|
.getNamedImports()
|
|
107
95
|
.some((namedImport) => namedImport.getName() === "requestInfo")) {
|
|
@@ -109,65 +97,52 @@ export async function transformJsxScriptTagsCode(code, manifest = {}) {
|
|
|
109
97
|
}
|
|
110
98
|
}
|
|
111
99
|
});
|
|
112
|
-
// Look for jsx function calls (jsx, jsxs, jsxDEV)
|
|
113
100
|
sourceFile
|
|
114
101
|
.getDescendantsOfKind(SyntaxKind.CallExpression)
|
|
115
102
|
.forEach((callExpr) => {
|
|
116
103
|
const expression = callExpr.getExpression();
|
|
117
104
|
const expressionText = expression.getText();
|
|
118
|
-
// Only process jsx/jsxs/jsxDEV calls
|
|
119
105
|
if (expressionText !== "jsx" &&
|
|
120
106
|
expressionText !== "jsxs" &&
|
|
121
107
|
expressionText !== "jsxDEV") {
|
|
122
108
|
return;
|
|
123
109
|
}
|
|
124
|
-
// Get arguments of the jsx call
|
|
125
110
|
const args = callExpr.getArguments();
|
|
126
111
|
if (args.length < 2)
|
|
127
112
|
return;
|
|
128
|
-
// First argument should be the element type
|
|
129
113
|
const elementType = args[0];
|
|
130
114
|
if (!Node.isStringLiteral(elementType))
|
|
131
115
|
return;
|
|
132
116
|
const tagName = elementType.getLiteralValue();
|
|
133
117
|
const entryPoints = [];
|
|
134
|
-
// Process script and link tags
|
|
135
118
|
if (tagName === "script" || tagName === "link") {
|
|
136
|
-
// Second argument should be the props object
|
|
137
119
|
const propsArg = args[1];
|
|
138
|
-
// Handle object literals with properties
|
|
139
120
|
if (Node.isObjectLiteralExpression(propsArg)) {
|
|
140
121
|
const properties = propsArg.getProperties();
|
|
141
|
-
// Variables to track script attributes
|
|
142
122
|
let hasDangerouslySetInnerHTML = false;
|
|
143
123
|
let hasNonce = false;
|
|
144
124
|
let hasStringLiteralChildren = false;
|
|
145
125
|
let hasSrc = false;
|
|
146
|
-
// Variables to track link attributes
|
|
147
126
|
let isPreload = false;
|
|
148
127
|
let hrefValue = null;
|
|
149
128
|
for (const prop of properties) {
|
|
150
129
|
if (Node.isPropertyAssignment(prop)) {
|
|
151
130
|
const propName = prop.getName();
|
|
152
131
|
const initializer = prop.getInitializer();
|
|
153
|
-
// Check for existing nonce
|
|
154
132
|
if (propName === "nonce") {
|
|
155
133
|
hasNonce = true;
|
|
156
134
|
}
|
|
157
|
-
// Check for dangerouslySetInnerHTML
|
|
158
135
|
if (propName === "dangerouslySetInnerHTML") {
|
|
159
136
|
hasDangerouslySetInnerHTML = true;
|
|
160
137
|
}
|
|
161
|
-
// Check for src attribute
|
|
162
138
|
if (tagName === "script" && propName === "src") {
|
|
163
139
|
hasSrc = true;
|
|
164
|
-
// Also process src for manifest transformation if needed
|
|
165
140
|
if (Node.isStringLiteral(initializer) ||
|
|
166
141
|
Node.isNoSubstitutionTemplateLiteral(initializer)) {
|
|
167
142
|
const srcValue = initializer.getLiteralValue();
|
|
168
143
|
if (srcValue.startsWith("/")) {
|
|
169
144
|
entryPoints.push(srcValue);
|
|
170
|
-
const path = srcValue.slice(1);
|
|
145
|
+
const path = srcValue.slice(1);
|
|
171
146
|
if (manifest[path]) {
|
|
172
147
|
const transformedSrc = `/${manifest[path].file}`;
|
|
173
148
|
modifications.push({
|
|
@@ -179,18 +154,15 @@ export async function transformJsxScriptTagsCode(code, manifest = {}) {
|
|
|
179
154
|
}
|
|
180
155
|
}
|
|
181
156
|
}
|
|
182
|
-
// Check for string literal children
|
|
183
157
|
if (tagName === "script" &&
|
|
184
158
|
propName === "children" &&
|
|
185
159
|
(Node.isStringLiteral(initializer) ||
|
|
186
160
|
Node.isNoSubstitutionTemplateLiteral(initializer))) {
|
|
187
161
|
hasStringLiteralChildren = true;
|
|
188
162
|
const scriptContent = initializer.getLiteralValue();
|
|
189
|
-
// Transform import statements in script content using ts-morph
|
|
190
163
|
const { content: transformedContent, hasChanges: contentHasChanges, entryPoints: dynamicEntryPoints, } = transformScriptImports(scriptContent, manifest);
|
|
191
164
|
entryPoints.push(...dynamicEntryPoints);
|
|
192
165
|
if (contentHasChanges && transformedContent) {
|
|
193
|
-
// Get the raw text with quotes to determine the exact format
|
|
194
166
|
const isTemplateLiteral = Node.isNoSubstitutionTemplateLiteral(initializer);
|
|
195
167
|
const replacementText = isTemplateLiteral
|
|
196
168
|
? "`" + transformedContent + "`"
|
|
@@ -202,7 +174,6 @@ export async function transformJsxScriptTagsCode(code, manifest = {}) {
|
|
|
202
174
|
});
|
|
203
175
|
}
|
|
204
176
|
}
|
|
205
|
-
// For link tags, first check if it's a preload/modulepreload
|
|
206
177
|
if (tagName === "link") {
|
|
207
178
|
if (propName === "rel" &&
|
|
208
179
|
(Node.isStringLiteral(initializer) ||
|
|
@@ -220,12 +191,10 @@ export async function transformJsxScriptTagsCode(code, manifest = {}) {
|
|
|
220
191
|
}
|
|
221
192
|
}
|
|
222
193
|
}
|
|
223
|
-
// Add nonce to script tags if needed
|
|
224
194
|
if (tagName === "script" &&
|
|
225
195
|
!hasNonce &&
|
|
226
196
|
!hasDangerouslySetInnerHTML &&
|
|
227
197
|
(hasStringLiteralChildren || hasSrc)) {
|
|
228
|
-
// Collect nonce property addition
|
|
229
198
|
modifications.push({
|
|
230
199
|
type: "addProperty",
|
|
231
200
|
node: propsArg,
|
|
@@ -236,13 +205,12 @@ export async function transformJsxScriptTagsCode(code, manifest = {}) {
|
|
|
236
205
|
needsRequestInfoImportRef.value = true;
|
|
237
206
|
}
|
|
238
207
|
}
|
|
239
|
-
// Transform href if this is a preload link
|
|
240
208
|
if (tagName === "link" &&
|
|
241
209
|
isPreload &&
|
|
242
210
|
hrefValue &&
|
|
243
211
|
hrefValue.startsWith("/") &&
|
|
244
212
|
manifest[hrefValue.slice(1)]) {
|
|
245
|
-
const path = hrefValue.slice(1);
|
|
213
|
+
const path = hrefValue.slice(1);
|
|
246
214
|
for (const prop of properties) {
|
|
247
215
|
if (Node.isPropertyAssignment(prop) &&
|
|
248
216
|
prop.getName() === "href") {
|
|
@@ -255,7 +223,6 @@ export async function transformJsxScriptTagsCode(code, manifest = {}) {
|
|
|
255
223
|
const quote = isTemplateLiteral
|
|
256
224
|
? "`"
|
|
257
225
|
: originalText.charAt(0);
|
|
258
|
-
// Preserve the original quote style and prepare replacement text
|
|
259
226
|
let replacementText;
|
|
260
227
|
if (isTemplateLiteral) {
|
|
261
228
|
replacementText = `\`/${transformedHref}\``;
|
|
@@ -284,23 +251,18 @@ export async function transformJsxScriptTagsCode(code, manifest = {}) {
|
|
|
284
251
|
.join(",\n");
|
|
285
252
|
const leadingCommentRanges = callExpr.getLeadingCommentRanges();
|
|
286
253
|
const pureComment = leadingCommentRanges.find((r) => r.getText().includes("@__PURE__"));
|
|
287
|
-
// Store position and static data for later processing
|
|
288
254
|
const wrapInfo = {
|
|
289
255
|
callExpr: callExpr,
|
|
290
256
|
sideEffects: sideEffects,
|
|
291
257
|
pureCommentText: pureComment?.getText(),
|
|
292
258
|
};
|
|
293
|
-
// We'll collect the actual wrap modifications after simple modifications are applied
|
|
294
259
|
if (!entryPointsPerCallExpr.has(callExpr)) {
|
|
295
260
|
entryPointsPerCallExpr.set(callExpr, wrapInfo);
|
|
296
261
|
}
|
|
297
262
|
needsRequestInfoImportRef.value = true;
|
|
298
263
|
}
|
|
299
264
|
});
|
|
300
|
-
// Apply all collected modifications
|
|
301
265
|
if (modifications.length > 0 || entryPointsPerCallExpr.size > 0) {
|
|
302
|
-
// Apply modifications in the right order to avoid invalidating nodes
|
|
303
|
-
// Apply simple modifications first (these are less likely to invalidate other nodes)
|
|
304
266
|
for (const mod of modifications) {
|
|
305
267
|
if (mod.type === "literalValue") {
|
|
306
268
|
mod.node.setLiteralValue(mod.value);
|
|
@@ -315,15 +277,12 @@ export async function transformJsxScriptTagsCode(code, manifest = {}) {
|
|
|
315
277
|
});
|
|
316
278
|
}
|
|
317
279
|
}
|
|
318
|
-
// Apply CallExpr wrapping last (these can invalidate other nodes)
|
|
319
|
-
// Now collect the wrap modifications with fresh data after simple modifications
|
|
320
280
|
const wrapModifications = [];
|
|
321
281
|
for (const [callExpr, wrapInfo] of entryPointsPerCallExpr) {
|
|
322
282
|
const fullStart = callExpr.getFullStart();
|
|
323
283
|
const end = callExpr.getEnd();
|
|
324
284
|
const callExprText = callExpr.getText();
|
|
325
285
|
const fullText = callExpr.getFullText();
|
|
326
|
-
// Extract leading whitespace/newlines before the call expression
|
|
327
286
|
const leadingWhitespace = fullText.substring(0, fullText.length - callExprText.length);
|
|
328
287
|
let pureCommentText;
|
|
329
288
|
let leadingTriviaText;
|
|
@@ -342,7 +301,6 @@ export async function transformJsxScriptTagsCode(code, manifest = {}) {
|
|
|
342
301
|
leadingWhitespace: leadingWhitespace,
|
|
343
302
|
});
|
|
344
303
|
}
|
|
345
|
-
// Sort by position in reverse order to avoid invalidating later nodes
|
|
346
304
|
wrapModifications.sort((a, b) => b.fullStart - a.fullStart);
|
|
347
305
|
for (const mod of wrapModifications) {
|
|
348
306
|
if (mod.pureCommentText && mod.leadingTriviaText) {
|
|
@@ -351,13 +309,9 @@ ${mod.sideEffects},
|
|
|
351
309
|
${mod.pureCommentText} ${mod.callExprText}
|
|
352
310
|
)`;
|
|
353
311
|
const newLeadingTriviaText = mod.leadingTriviaText.replace(mod.pureCommentText, "");
|
|
354
|
-
// By replacing from `getFullStart`, we remove the original node and all its leading trivia
|
|
355
|
-
// and replace it with our manually reconstructed string.
|
|
356
|
-
// This should correctly move the pure comment and preserve other comments and whitespace.
|
|
357
312
|
sourceFile.replaceText([mod.fullStart, mod.end], newLeadingTriviaText + newText);
|
|
358
313
|
}
|
|
359
314
|
else {
|
|
360
|
-
// Extract just the newlines and basic indentation, ignore extra padding
|
|
361
315
|
const leadingNewlines = mod.leadingWhitespace.match(/\n\s*/)?.[0] || "";
|
|
362
316
|
sourceFile.replaceText([mod.fullStart, mod.end], `${leadingNewlines}(
|
|
363
317
|
${mod.sideEffects},
|
|
@@ -365,16 +319,13 @@ ${mod.callExprText}
|
|
|
365
319
|
)`);
|
|
366
320
|
}
|
|
367
321
|
}
|
|
368
|
-
// Add requestInfo import if needed and not already imported
|
|
369
322
|
if (needsRequestInfoImportRef.value) {
|
|
370
323
|
if (sdkWorkerImportDecl) {
|
|
371
|
-
// Module is imported but need to add requestInfo
|
|
372
324
|
if (!hasRequestInfoImport) {
|
|
373
325
|
sdkWorkerImportDecl.addNamedImport("requestInfo");
|
|
374
326
|
}
|
|
375
327
|
}
|
|
376
328
|
else {
|
|
377
|
-
// Add new import declaration
|
|
378
329
|
sourceFile.addImportDeclaration({
|
|
379
330
|
moduleSpecifier: "rwsdk/worker",
|
|
380
331
|
namedImports: ["requestInfo"],
|