@stacksjs/stx 0.2.160 → 0.2.162
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/cli.js +4394 -1312
- package/dist/craft.js +2516 -864
- package/dist/expressions.d.ts +21 -2
- package/dist/expressions.js +35 -6
- package/dist/pwa.js +2479 -827
- package/dist/ssg.js +2399 -747
- package/dist/variable-extractor.js +6 -1
- package/package.json +5 -5
package/dist/expressions.d.ts
CHANGED
|
@@ -106,6 +106,24 @@ export declare function usesSignalsInScript(template: string): boolean;
|
|
|
106
106
|
* attributes and surrounding HTML are left alone.
|
|
107
107
|
*/
|
|
108
108
|
export declare function interpolateScriptExpressions(scriptBody: string, context: Record<string, any>): string;
|
|
109
|
+
/**
|
|
110
|
+
* Interpolate expressions in a `<script>` tag's ATTRIBUTES.
|
|
111
|
+
*
|
|
112
|
+
* Attributes are HTML, not JavaScript, so they get HTML rules rather than the
|
|
113
|
+
* JSON-stringifying rules {@link interpolateScriptExpressions} applies to a
|
|
114
|
+
* body: `data-id="{{ id }}"` must become `data-id="7"`, never `data-id=""7""`.
|
|
115
|
+
*
|
|
116
|
+
* This is the only channel a module island has for server data. A module
|
|
117
|
+
* script is emitted verbatim — no IIFE, no server-data bridge — so
|
|
118
|
+
* `<script type="module" data-session="{{ id }}">` was the documented way to
|
|
119
|
+
* pass a value in, and it shipped the literal text `{{ id }}` to the browser.
|
|
120
|
+
* The failure is silent: the markup looks right, and only the code reading
|
|
121
|
+
* `dataset.session` sees a mustache.
|
|
122
|
+
*
|
|
123
|
+
* Unresolvable expressions are left untouched, matching the "preserve for the
|
|
124
|
+
* client" semantics used everywhere else.
|
|
125
|
+
*/
|
|
126
|
+
export declare function interpolateScriptAttributes(attrs: string, context: Record<string, any>): string;
|
|
109
127
|
/**
|
|
110
128
|
* Options for {@link interpolateScriptsInTemplate}.
|
|
111
129
|
*/
|
|
@@ -123,8 +141,9 @@ export interface InterpolateScriptsOptions {
|
|
|
123
141
|
* skipping any script that opts out via `data-raw`, `type="application/json"`,
|
|
124
142
|
* or a `src=` attribute (external scripts don't have inline content to template).
|
|
125
143
|
*
|
|
126
|
-
* Each matched script has its body passed through {@link interpolateScriptExpressions}
|
|
127
|
-
*
|
|
144
|
+
* Each matched script has its body passed through {@link interpolateScriptExpressions}
|
|
145
|
+
* and its attributes through {@link interpolateScriptAttributes}. Tag structure
|
|
146
|
+
* is otherwise untouched.
|
|
128
147
|
*/
|
|
129
148
|
export declare function interpolateScriptsInTemplate(template: string, context: Record<string, any>, options?: InterpolateScriptsOptions): string;
|
|
130
149
|
/**
|
package/dist/expressions.js
CHANGED
|
@@ -325,22 +325,51 @@ export function interpolateScriptExpressions(scriptBody, context) {
|
|
|
325
325
|
});
|
|
326
326
|
return output;
|
|
327
327
|
}
|
|
328
|
+
export function interpolateScriptAttributes(attrs, context) {
|
|
329
|
+
if (!attrs.includes("{"))
|
|
330
|
+
return attrs;
|
|
331
|
+
let output = attrs;
|
|
332
|
+
output = output.replace(/\{!!([\s\S]*?)!!\}/g, (match, expr) => {
|
|
333
|
+
try {
|
|
334
|
+
const value = evaluateExpression(expr, context);
|
|
335
|
+
if (value === void 0)
|
|
336
|
+
return match;
|
|
337
|
+
return value === null ? "" : String(value);
|
|
338
|
+
} catch {
|
|
339
|
+
return match;
|
|
340
|
+
}
|
|
341
|
+
});
|
|
342
|
+
output = output.replace(/\{\{([\s\S]*?)\}\}/g, (match, expr) => {
|
|
343
|
+
const trimmed = expr.trim();
|
|
344
|
+
if (/^__[A-Z_]+__$/.test(trimmed))
|
|
345
|
+
return match;
|
|
346
|
+
try {
|
|
347
|
+
const value = evaluateExpression(expr, context);
|
|
348
|
+
if (value === void 0)
|
|
349
|
+
return match;
|
|
350
|
+
if (value === null)
|
|
351
|
+
return "";
|
|
352
|
+
return String(value).replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
353
|
+
} catch {
|
|
354
|
+
return match;
|
|
355
|
+
}
|
|
356
|
+
});
|
|
357
|
+
return output;
|
|
358
|
+
}
|
|
328
359
|
export function interpolateScriptsInTemplate(template, context, options = {}) {
|
|
329
360
|
const { output, scripts } = stashScriptElements(template), interpolatedScripts = scripts.map((full) => {
|
|
330
361
|
const match = full.match(/^<script\b([^>]*)>([\s\S]*?)<\/script\s*>$/i), opening = full.match(/^<script\b[^>]*>/i), closingStart = full.search(/<\/script\s*>$/i);
|
|
331
362
|
if (!match || !opening || closingStart === -1)
|
|
332
363
|
return full;
|
|
333
364
|
const attrs = match[1], body = match[2];
|
|
334
|
-
if (/\bsrc\s*=/.test(attrs))
|
|
335
|
-
return full;
|
|
336
365
|
if (/\bdata-raw\b/.test(attrs))
|
|
337
366
|
return full;
|
|
338
|
-
if (/\btype\s*=\s*["']application\/json["']/.test(attrs))
|
|
339
|
-
return full;
|
|
340
367
|
if (options.skipServer && /\bserver\b/.test(attrs))
|
|
341
368
|
return full;
|
|
342
|
-
const
|
|
343
|
-
|
|
369
|
+
const openTag = `<script${interpolateScriptAttributes(attrs, context)}>`;
|
|
370
|
+
if (/\bsrc\s*=/.test(attrs) || /\btype\s*=\s*["']application\/json["']/.test(attrs))
|
|
371
|
+
return openTag + body + full.slice(closingStart);
|
|
372
|
+
return openTag + interpolateScriptExpressions(body, context) + full.slice(closingStart);
|
|
344
373
|
});
|
|
345
374
|
return restoreStashedScripts(output, interpolatedScripts);
|
|
346
375
|
}
|