@vojtaholik/static-kit-core 2.1.9 → 2.1.11

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vojtaholik/static-kit-core",
3
- "version": "2.1.9",
3
+ "version": "2.1.11",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": {
package/src/config.ts CHANGED
@@ -18,6 +18,8 @@ export const configSchema = z.object({
18
18
  devPort: z.number().default(3000),
19
19
  /** HTML output format: "formatted" (pretty-printed) or "minified" */
20
20
  htmlOutput: z.enum(["formatted", "minified"]).default("formatted"),
21
+ /** CSS output format: "formatted" (as-is) or "minified" */
22
+ cssOutput: z.enum(["formatted", "minified"]).default("formatted"),
21
23
  /** URL path prefix for production builds — all internal links get this prefix */
22
24
  basePath: z
23
25
  .string()
@@ -120,8 +120,8 @@ export async function renderPage(
120
120
  }
121
121
  }
122
122
 
123
- // Update <html> attributes
124
- if (node.nodeName === "html") {
123
+ // Update <html> attributes (data-page-id only in dev for HMR)
124
+ if (node.nodeName === "html" && options.isDev) {
125
125
  setAttr(node, "data-page-id", page.id);
126
126
  }
127
127
 
@@ -134,13 +134,13 @@ export async function renderPage(
134
134
  if (node.nodeName === "link") {
135
135
  const rel = getAttr(node, "rel");
136
136
  const href = getAttr(node, "href");
137
- if (rel === "stylesheet" && href && href.endsWith(".css")) {
137
+ if (rel === "stylesheet" && href && href.endsWith(".css") && !href.includes("?v=")) {
138
138
  setAttr(node, "href", `${href}?v=${options.cacheBust}`);
139
139
  }
140
140
  }
141
141
  if (node.nodeName === "script") {
142
142
  const src = getAttr(node, "src");
143
- if (src && src.endsWith(".js")) {
143
+ if (src && src.endsWith(".js") && !src.includes("?v=")) {
144
144
  setAttr(node, "src", `${src}?v=${options.cacheBust}`);
145
145
  }
146
146
  }
@@ -176,9 +176,11 @@ export async function renderPage(
176
176
  );
177
177
 
178
178
  // Replace markers with actual region content
179
+ // Uses split/join instead of replace() to avoid issues with $ in content
180
+ // being interpreted as replacement patterns
179
181
  for (const [regionName, content] of Object.entries(regionContent)) {
180
182
  const marker = `<!--__REGION_CONTENT_${regionName}__-->`;
181
- html = html.replace(marker, content);
183
+ html = html.split(marker).join(content);
182
184
  }
183
185
 
184
186
  // Czech typography: non-breaking spaces after single-char prepositions
@@ -434,7 +434,10 @@ function compileRenderSlot(element: Element, indent: number): string {
434
434
  } else if (indexExpr) {
435
435
  // Build prop path from index (assumes we're iterating over an array prop)
436
436
  // This creates paths like "posts[0]", "posts[1]" etc.
437
- addrExpr = `{ ...addr, propPath: (addr.propPath ? addr.propPath + "[" + ${indexExpr} + "]" : "[" + ${indexExpr} + "]") }`;
437
+ // When addr.propPath is set, appends index: "posts[0]"
438
+ // When addr.propPath is missing, uses the :props expression base as prefix
439
+ const propsBase = propsExpr.replace(/^props\./, "").split(/[.[]/)[0];
440
+ addrExpr = `{ ...addr, propPath: (addr.propPath ? addr.propPath + "[" + ${indexExpr} + "]" : "${propsBase}[" + ${indexExpr} + "]") }`;
438
441
  } else {
439
442
  // No prop path
440
443
  addrExpr = "addr";
@@ -477,7 +480,16 @@ function compileTextWithInterpolation(text: string, indent: number): string {
477
480
 
478
481
  // Split on {{{ ... }}} (raw) and {{ ... }} (escaped)
479
482
  // Order matters: match triple braces first
480
- const parts = text.split(/(\{\{\{.+?\}\}\}|\{\{.+?\}\})/g);
483
+ // Uses [\s\S] instead of . to support multiline expressions
484
+ const parts = text.split(/(\{\{\{[\s\S]+?\}\}\}|\{\{[\s\S]+?\}\})/g);
485
+
486
+ // Detect unmatched braces in static text parts (every other part is static)
487
+ for (let j = 0; j < parts.length; j += 2) {
488
+ const staticPart = parts[j];
489
+ if (staticPart && /\{\{/.test(staticPart)) {
490
+ throw new Error(`Unmatched interpolation braces in template text: "${staticPart.trim().slice(0, 60)}"`);
491
+ }
492
+ }
481
493
 
482
494
  for (let i = 0; i < parts.length; i++) {
483
495
  const part = parts[i];