@lass-lang/core 0.0.1

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.
@@ -0,0 +1,650 @@
1
+ /**
2
+ * Transpiler pipeline functions for @lass-lang/core
3
+ *
4
+ * Each function represents a step in the transpilation story.
5
+ * See index.ts for the main entry point that orchestrates these steps.
6
+ */
7
+ import { Scanner } from './scanner.js';
8
+ import { cutByBraces, findPropertyValue } from './scope-tracker.js';
9
+ import { escapeForTemplateLiteral, escapeForJs } from './helpers.js';
10
+ import { LASS_SCRIPT_EXPRESSION_HELPER, LASS_SCRIPT_LOOKUP_HELPER } from './constants.js';
11
+ import { createContextState, updateContextState, isInProtectedContext } from './context-tracker.js';
12
+ // ============================================================================
13
+ // STEP 1: ZONE DETECTION
14
+ // ============================================================================
15
+ /**
16
+ * Step 1: Detect and split zones.
17
+ *
18
+ * Finds the --- separator and splits source into preamble and CSS zones.
19
+ * If no separator, entire source is the CSS zone (pure CSS passthrough).
20
+ *
21
+ * @param source - Raw Lass source code
22
+ * @param options - Transpile options (filename for errors)
23
+ * @returns Detected zones with preamble and cssZone
24
+ */
25
+ export function detectZones(source, options) {
26
+ const scanner = new Scanner(source, { filename: options.filename });
27
+ const zones = scanner.findSeparator();
28
+ return {
29
+ preamble: zones.preamble,
30
+ cssZone: zones.cssZone,
31
+ hasSeparator: zones.hasSeparator,
32
+ };
33
+ }
34
+ // ============================================================================
35
+ // STEP 2: COMMENT STRIPPING
36
+ // ============================================================================
37
+ /**
38
+ * Step 2: Strip // comments from CSS zone.
39
+ *
40
+ * Story 4.4: Single-line comment stripping.
41
+ * Removes // comments while respecting protected contexts (strings, url(), block comments).
42
+ *
43
+ * @param cssZone - The CSS zone content
44
+ * @returns CSS zone with // comments removed
45
+ */
46
+ export function stripLineComments(cssZone) {
47
+ return Scanner.stripLineCommentsStatic(cssZone);
48
+ }
49
+ // ============================================================================
50
+ // STEP 3a: STYLE LOOKUP SHORTHAND NORMALIZATION
51
+ // ============================================================================
52
+ /**
53
+ * Step 3a: Normalize @prop shorthands to @(prop) form.
54
+ *
55
+ * Story 4.2: Style Lookup Shorthand
56
+ *
57
+ * Finds @prop patterns in CSS value position and converts them to @(prop).
58
+ * This runs BEFORE @(prop) resolution so all lookups are handled uniformly.
59
+ *
60
+ * Detection rules:
61
+ * - @prop shorthand only works when identifier starts with a letter [a-zA-Z]
62
+ * - NOT detected inside {{ }} script blocks
63
+ * - NOT detected inside protected contexts: strings, comments, url()
64
+ *
65
+ * @param cssZone - The CSS zone content
66
+ * @returns CSS zone with @prop normalized to @(prop)
67
+ */
68
+ export function normalizeStyleLookupShorthands(cssZone) {
69
+ if (!cssZone) {
70
+ return cssZone;
71
+ }
72
+ const shorthands = Scanner.findStyleLookupShorthandsStatic(cssZone);
73
+ if (shorthands.length === 0) {
74
+ return cssZone;
75
+ }
76
+ // Process from end to start so indices remain valid
77
+ let result = cssZone;
78
+ for (let i = shorthands.length - 1; i >= 0; i--) {
79
+ const shorthand = shorthands[i];
80
+ const { propName, startIndex, endIndex } = shorthand;
81
+ // Replace @prop with @(prop)
82
+ result = result.slice(0, startIndex) + `@(${propName})` + result.slice(endIndex);
83
+ }
84
+ return result;
85
+ }
86
+ // ============================================================================
87
+ // STEP 3b: PROPERTY ACCESSOR RESOLUTION
88
+ // ============================================================================
89
+ /**
90
+ * Step 3b: Resolve @(prop) accessors in CSS zone.
91
+ *
92
+ * Story 3.2: Basic Property Lookup
93
+ * Story 3.3: Lookup in {{ }} Context
94
+ * Refactored: Changed from @prop to @(prop) for unambiguous syntax
95
+ *
96
+ * Finds @(prop) patterns in CSS value position and resolves them to their
97
+ * previously-declared values using scope tracking utilities.
98
+ *
99
+ * Resolution rules:
100
+ * - Property found in CSS context -> Replace @(prop) with resolved value
101
+ * - Property found in JS context (inside {{ }}) -> Replace with quoted value
102
+ * - Property not found -> Preserve @(prop) unchanged (PostCSS/future CSS compatibility)
103
+ *
104
+ * This is Phase 1 of transpilation and runs BEFORE {{ }} processing.
105
+ *
106
+ * @param cssZone - The CSS zone content
107
+ * @param options - Transpile options (filename for errors)
108
+ * @returns CSS zone with @(prop) accessors resolved (or preserved if not found)
109
+ */
110
+ export function resolvePropertyAccessors(cssZone, _options) {
111
+ if (!cssZone) {
112
+ return cssZone;
113
+ }
114
+ // Use static method to avoid creating unnecessary Scanner instance
115
+ const accessors = Scanner.findPropertyAccessorsStatic(cssZone);
116
+ if (accessors.length === 0) {
117
+ return cssZone;
118
+ }
119
+ // Get scope slices for property lookup
120
+ const { slices } = cutByBraces(cssZone);
121
+ // Build a map of character positions to slice indices
122
+ // cutByBraces splits at braces, so we need to track where each slice starts
123
+ // Use openedBy to determine brace size: '{{' = 2, '@{' = 2, '{' = 1, null = 0
124
+ const sliceStartPositions = [];
125
+ let pos = 0;
126
+ for (let s = 0; s < slices.length; s++) {
127
+ sliceStartPositions.push(pos);
128
+ pos += slices[s].content.length;
129
+ // Add brace characters between slices (except after last)
130
+ if (s < slices.length - 1) {
131
+ // Look at the NEXT slice to determine what brace opened it
132
+ const nextSlice = slices[s + 1];
133
+ switch (nextSlice.openedBy) {
134
+ case '{{':
135
+ case '@{':
136
+ pos += 2; // {{ or @{ are 2 chars
137
+ break;
138
+ case '{':
139
+ pos += 1; // { is 1 char
140
+ break;
141
+ default:
142
+ // Closing brace - need to determine size from current slice's context
143
+ // If current was opened by {{ → closing is }} (2 chars)
144
+ // If current was opened by @{ → closing is } (1 char)
145
+ // If current was opened by { → closing is } (1 char)
146
+ const currentSlice = slices[s];
147
+ if (currentSlice.openedBy === '{{') {
148
+ pos += 2; // }}
149
+ }
150
+ else {
151
+ pos += 1; // }
152
+ }
153
+ }
154
+ }
155
+ }
156
+ // Build result by replacing @(prop) with resolved values (or preserving)
157
+ // Process from end to start so indices remain valid
158
+ let result = cssZone;
159
+ for (let i = accessors.length - 1; i >= 0; i--) {
160
+ const accessor = accessors[i];
161
+ const { propName, startIndex, endIndex } = accessor;
162
+ // Find which slice contains this @(prop)
163
+ let sliceIndex = 0;
164
+ for (let s = slices.length - 1; s >= 0; s--) {
165
+ if (startIndex >= sliceStartPositions[s]) {
166
+ sliceIndex = s;
167
+ break;
168
+ }
169
+ }
170
+ // Position within the slice (for self-reference protection)
171
+ const positionInSlice = startIndex - sliceStartPositions[sliceIndex];
172
+ // Look up the property value
173
+ const value = findPropertyValue(propName, slices, sliceIndex, positionInSlice);
174
+ // Only replace if we found a value (non-empty string)
175
+ // If not found, preserve the original @(prop) (PostCSS/future CSS compatibility)
176
+ if (value !== '') {
177
+ // Story 3.3: If @(prop) is inside a JS-type slice, quote the value
178
+ const slice = slices[sliceIndex];
179
+ const replacement = slice.type === 'js'
180
+ ? `"${escapeForJs(value)}"`
181
+ : value;
182
+ result = result.slice(0, startIndex) + replacement + result.slice(endIndex);
183
+ }
184
+ }
185
+ return result;
186
+ }
187
+ // ============================================================================
188
+ // STEP 4: DOLLAR VARIABLE RESOLUTION
189
+ // ============================================================================
190
+ /**
191
+ * Step 4: Replace $param variables with __lassScriptLookup() calls.
192
+ *
193
+ * Story 4.1: Variable Substitution
194
+ *
195
+ * Finds $param patterns in CSS zone and converts them to helper function calls.
196
+ * This enables $-prefixed variables from the preamble to be substituted into CSS
197
+ * with proper handling of null (-> 'unset') and undefined/missing (-> preserved).
198
+ *
199
+ * Protected contexts (strings, url(), comments) are skipped - $param inside these
200
+ * remains as literal text. Use {{ $param }} for dynamic content in protected contexts.
201
+ *
202
+ * @param cssZone - The CSS zone content
203
+ * @param _options - Transpile options (filename for errors)
204
+ * @returns Result with modified CSS zone and flag indicating if helpers needed
205
+ */
206
+ export function resolveDollarVariables(cssZone, _options) {
207
+ if (!cssZone) {
208
+ return { cssZone, hasDollarVariables: false };
209
+ }
210
+ // Use static method to find all $param occurrences
211
+ const variables = Scanner.findDollarVariablesStatic(cssZone);
212
+ if (variables.length === 0) {
213
+ return { cssZone, hasDollarVariables: false };
214
+ }
215
+ // Process from end to start so indices remain valid
216
+ let result = cssZone;
217
+ for (let i = variables.length - 1; i >= 0; i--) {
218
+ const variable = variables[i];
219
+ const { varName, startIndex, endIndex } = variable;
220
+ // Replace $varName with ${__lassScriptLookup('name', () => $varName)}
221
+ // The name parameter is without the $ prefix (helper adds it back for preserved output)
222
+ const nameWithoutDollar = varName.slice(1); // Remove leading $
223
+ const replacement = `\${__lassScriptLookup('${nameWithoutDollar}', () => ${varName})}`;
224
+ result = result.slice(0, startIndex) + replacement + result.slice(endIndex);
225
+ }
226
+ return { cssZone: result, hasDollarVariables: true };
227
+ }
228
+ // ============================================================================
229
+ // STEP 5a: STYLE BLOCK TRANSLATION
230
+ // ============================================================================
231
+ /**
232
+ * Normalizes style block content by trimming and dedenting.
233
+ *
234
+ * Single-line (no newlines): Trim leading/trailing whitespace.
235
+ * Multi-line:
236
+ * - Dedent all lines by the minimum indentation found
237
+ * - Trim leading and trailing whitespace
238
+ *
239
+ * @param content - Raw content from inside @{ }
240
+ * @returns Normalized content
241
+ */
242
+ export function normalizeStyleBlockContent(content) {
243
+ // Single-line: just trim
244
+ if (!content.includes('\n')) {
245
+ return content.trim();
246
+ }
247
+ const lines = content.split('\n');
248
+ // Find minimum indent of non-empty lines
249
+ let minIndent = Infinity;
250
+ for (const line of lines) {
251
+ if (line.trim() !== '') {
252
+ const leadingSpaces = line.match(/^[ \t]*/)?.[0].length ?? 0;
253
+ minIndent = Math.min(minIndent, leadingSpaces);
254
+ }
255
+ }
256
+ if (minIndent === Infinity) {
257
+ minIndent = 0;
258
+ }
259
+ // Dedent all lines
260
+ const dedented = lines.map(line => {
261
+ if (line.trim() === '') {
262
+ return ''; // Empty lines become empty
263
+ }
264
+ return line.slice(minIndent);
265
+ });
266
+ // Join and trim
267
+ return dedented.join('\n').trim();
268
+ }
269
+ /**
270
+ * Translates @{ } style blocks to JS template literals.
271
+ *
272
+ * Story 5.1: Style Block Syntax
273
+ *
274
+ * @{ } is purely delimiter translation:
275
+ * - @{ → backtick (`)
276
+ * - } (matching @{) → backtick (`)
277
+ * - {{ }} inside @{ } → ${ } with __lassScriptExpression helper
278
+ * - $param inside @{ } → ${__lassScriptLookup(...)} for proper null/undefined handling
279
+ *
280
+ * This function handles brace matching to find the correct closing }.
281
+ * Nested braces (from object literals, ternaries, etc.) are tracked.
282
+ *
283
+ * Protected contexts (where @{ is NOT translated):
284
+ * - Inside string literals ("..." or '...')
285
+ * - Inside block comments
286
+ * - Note: url() is NOT protected - @{ inside url() IS translated
287
+ *
288
+ * @param text - JS code containing @{ } style blocks
289
+ * @returns Result with translated text and flag for $param usage
290
+ */
291
+ export function translateStyleBlocks(text) {
292
+ if (!text || !text.includes('@{')) {
293
+ return { text, hasDollarVariables: false };
294
+ }
295
+ const state = createContextState();
296
+ let result = '';
297
+ let i = 0;
298
+ let hasDollarVars = false;
299
+ while (i < text.length) {
300
+ const char = text[i];
301
+ const nextChar = text[i + 1];
302
+ // Update context state for strings and block comments
303
+ const consumed = updateContextState(text, i, state);
304
+ if (consumed === 2) {
305
+ result += text.slice(i, i + 2);
306
+ i += 2;
307
+ continue;
308
+ }
309
+ // Skip string quote characters
310
+ if (char === '"' || char === "'") {
311
+ result += char;
312
+ i++;
313
+ continue;
314
+ }
315
+ // Skip if in protected context
316
+ if (isInProtectedContext(state)) {
317
+ result += char;
318
+ i++;
319
+ continue;
320
+ }
321
+ // Check for @{ style block opener
322
+ if (char === '@' && nextChar === '{') {
323
+ // Found style block - find matching }
324
+ const closeIndex = findStyleBlockClose(text, i + 2);
325
+ if (closeIndex === -1) {
326
+ // No matching } found - treat as literal text
327
+ result += '@{';
328
+ i += 2;
329
+ continue;
330
+ }
331
+ // Extract content between @{ and }
332
+ const content = text.slice(i + 2, closeIndex);
333
+ // Normalize whitespace: dedent and trim boundary empty lines
334
+ const normalizedContent = normalizeStyleBlockContent(content);
335
+ // Recursively translate any nested @{ } inside
336
+ const nestedResult = translateStyleBlocks(normalizedContent);
337
+ if (nestedResult.hasDollarVariables) {
338
+ hasDollarVars = true;
339
+ }
340
+ // Translate $param to ${__lassScriptLookup(...)} inside the style block content
341
+ const dollarResult = translateDollarVariablesInStyleBlock(nestedResult.text);
342
+ if (dollarResult.hasDollarVariables) {
343
+ hasDollarVars = true;
344
+ }
345
+ // Translate {{ }} to ${__lassScriptExpression(...)} inside the style block content
346
+ const finalContent = translateMustacheToInterpolation(dollarResult.text);
347
+ // Output as template literal
348
+ result += '`' + finalContent + '`';
349
+ i = closeIndex + 1;
350
+ continue;
351
+ }
352
+ result += char;
353
+ i++;
354
+ }
355
+ return { text: result, hasDollarVariables: hasDollarVars };
356
+ }
357
+ /**
358
+ * Finds the matching closing } for a style block.
359
+ *
360
+ * Tracks brace depth to handle nested braces from:
361
+ * - Object literals: { key: value }
362
+ * - Ternary expressions: { ... } in conditionals
363
+ * - CSS blocks inside {{ }}
364
+ *
365
+ * But {{ and }} are treated specially - they don't affect brace depth.
366
+ *
367
+ * @param text - Full text to scan
368
+ * @param startIndex - Index right after @{ (first char of content)
369
+ * @returns Index of closing } or -1 if not found
370
+ */
371
+ function findStyleBlockClose(text, startIndex) {
372
+ const state = createContextState();
373
+ let braceDepth = 0;
374
+ let i = startIndex;
375
+ while (i < text.length) {
376
+ const char = text[i];
377
+ const nextChar = text[i + 1];
378
+ // Update context state for strings and block comments
379
+ const consumed = updateContextState(text, i, state);
380
+ if (consumed === 2) {
381
+ i += 2;
382
+ continue;
383
+ }
384
+ // Skip string quote characters
385
+ if (char === '"' || char === "'") {
386
+ i++;
387
+ continue;
388
+ }
389
+ // Skip if in protected context
390
+ if (isInProtectedContext(state)) {
391
+ i++;
392
+ continue;
393
+ }
394
+ // Handle {{ - don't count as single {
395
+ if (char === '{' && nextChar === '{') {
396
+ i += 2;
397
+ continue;
398
+ }
399
+ // Handle }} - don't count as single }
400
+ if (char === '}' && nextChar === '}') {
401
+ i += 2;
402
+ continue;
403
+ }
404
+ // Handle nested @{ - increase depth
405
+ if (char === '@' && nextChar === '{') {
406
+ braceDepth++;
407
+ i += 2;
408
+ continue;
409
+ }
410
+ // Single { increases depth
411
+ if (char === '{') {
412
+ braceDepth++;
413
+ i++;
414
+ continue;
415
+ }
416
+ // Single } decreases depth or closes style block
417
+ if (char === '}') {
418
+ if (braceDepth === 0) {
419
+ // This is our closing }
420
+ return i;
421
+ }
422
+ braceDepth--;
423
+ i++;
424
+ continue;
425
+ }
426
+ i++;
427
+ }
428
+ // No matching } found
429
+ return -1;
430
+ }
431
+ /**
432
+ * Gets the leading whitespace (indent) at a given position by looking backwards to line start.
433
+ *
434
+ * @param text - The full text
435
+ * @param pos - Position to find indent for
436
+ * @returns The whitespace string at the start of the line, or empty string if none
437
+ */
438
+ function getIndentAtPosition(text, pos) {
439
+ // Find the start of the line containing this position
440
+ let lineStart = pos;
441
+ while (lineStart > 0 && text[lineStart - 1] !== '\n') {
442
+ lineStart--;
443
+ }
444
+ // Extract leading whitespace
445
+ let indent = '';
446
+ for (let i = lineStart; i < pos; i++) {
447
+ const char = text[i];
448
+ if (char === ' ' || char === '\t') {
449
+ indent += char;
450
+ }
451
+ else {
452
+ // Non-whitespace found - this is the effective indent up to this point
453
+ break;
454
+ }
455
+ }
456
+ return indent;
457
+ }
458
+ /**
459
+ * Translates {{ expr }} to ${__lassScriptExpression(expr, indent)} inside style block content.
460
+ *
461
+ * This is applied after @{ } is translated to backticks, so any {{ }} inside
462
+ * becomes template literal interpolations with proper array/null handling.
463
+ *
464
+ * Indent is calculated from the position of {{ within the style block content
465
+ * to enable proper multi-line re-indentation at runtime.
466
+ *
467
+ * @param text - Content inside a style block
468
+ * @returns Text with {{ }} translated to ${__lassScriptExpression(...)}
469
+ */
470
+ function translateMustacheToInterpolation(text) {
471
+ let result = '';
472
+ let i = 0;
473
+ while (i < text.length) {
474
+ // Check for {{
475
+ if (text[i] === '{' && text[i + 1] === '{') {
476
+ // Find matching }}
477
+ let depth = 0;
478
+ let j = i + 2;
479
+ while (j < text.length - 1) {
480
+ if (text[j] === '{') {
481
+ depth++;
482
+ }
483
+ else if (text[j] === '}') {
484
+ if (depth === 0 && text[j + 1] === '}') {
485
+ // Found closing }}
486
+ break;
487
+ }
488
+ depth--;
489
+ }
490
+ j++;
491
+ }
492
+ if (j < text.length - 1 && text[j] === '}' && text[j + 1] === '}') {
493
+ // Extract expression and wrap with helper
494
+ const expr = text.slice(i + 2, j).trim();
495
+ // Calculate indent at {{ position for multi-line re-indentation
496
+ const indent = getIndentAtPosition(text, i);
497
+ if (indent) {
498
+ result += '${__lassScriptExpression(' + expr + ', "' + indent + '")}';
499
+ }
500
+ else {
501
+ result += '${__lassScriptExpression(' + expr + ')}';
502
+ }
503
+ i = j + 2;
504
+ continue;
505
+ }
506
+ }
507
+ result += text[i];
508
+ i++;
509
+ }
510
+ return result;
511
+ }
512
+ /**
513
+ * Translates $param variables to ${__lassScriptLookup(...)} inside style block content.
514
+ *
515
+ * Story 5.1: Inside @{ } style blocks, $param should use the same helper as
516
+ * CSS zone to properly handle:
517
+ * - null -> 'unset' (CSS-meaningful fallback)
518
+ * - undefined or ReferenceError -> preserve '$name' unchanged
519
+ * - other values -> String coercion
520
+ *
521
+ * Reuses Scanner.findDollarVariablesStatic() for detection, which handles:
522
+ * - Protected contexts (strings, block comments)
523
+ * - {{ }} script block depth tracking
524
+ *
525
+ * @param text - Content inside a style block
526
+ * @returns Result with text and flag for $param usage
527
+ */
528
+ function translateDollarVariablesInStyleBlock(text) {
529
+ // Reuse Scanner's detection logic - it handles all protected contexts and {{ }}
530
+ const variables = Scanner.findDollarVariablesStatic(text);
531
+ if (variables.length === 0) {
532
+ return { text, hasDollarVariables: false };
533
+ }
534
+ // Process from end to start so indices remain valid
535
+ let result = text;
536
+ for (let i = variables.length - 1; i >= 0; i--) {
537
+ const variable = variables[i];
538
+ const { varName, startIndex, endIndex } = variable;
539
+ // Replace $varName with ${__lassScriptLookup('name', () => $varName)}
540
+ const nameWithoutDollar = varName.slice(1);
541
+ const replacement = `\${__lassScriptLookup('${nameWithoutDollar}', () => ${varName})}`;
542
+ result = result.slice(0, startIndex) + replacement + result.slice(endIndex);
543
+ }
544
+ return { text: result, hasDollarVariables: true };
545
+ }
546
+ // ============================================================================
547
+ // STEP 5b: EXPRESSION PROCESSING
548
+ // ============================================================================
549
+ /**
550
+ * Step 5b: Process expressions in CSS zone.
551
+ *
552
+ * Finds {{ expr }} expressions and converts them to template literal interpolations.
553
+ * Story 2.5: Expressions are processed EVERYWHERE in CSS zone (strings, url(), comments).
554
+ * Story 5.1: Also translates @{ } style blocks within expressions.
555
+ *
556
+ * @param cssZone - The CSS zone content
557
+ * @param hasDollarVariables - Whether $param variables were found in CSS zone
558
+ * @param options - Transpile options (filename for errors)
559
+ * @returns Processed template with body and expression flag
560
+ */
561
+ export function processExpressions(cssZone, hasDollarVariables, options) {
562
+ const scanner = new Scanner(cssZone, { filename: options.filename });
563
+ const exprSplit = scanner.findExpressions(cssZone);
564
+ const hasExpressions = exprSplit.parts.length > 1;
565
+ let styleBlockHasDollarVars = false;
566
+ // Build template literal content with ${} interpolations
567
+ let templateBody = '';
568
+ let exprIndex = 0;
569
+ for (let i = 0; i < exprSplit.parts.length; i++) {
570
+ if (i % 2 === 0) {
571
+ // CSS chunk - escape for template literal
572
+ templateBody += escapeForTemplateLiteral(exprSplit.parts[i]);
573
+ }
574
+ else {
575
+ // JS expression - translate @{ } style blocks, then wrap in helper
576
+ // Use V1 (recursive) which properly normalizes entire style block content
577
+ const exprContent = exprSplit.parts[i];
578
+ const hasStyleBlock = exprContent.includes('@{');
579
+ const styleBlockResult = translateStyleBlocks(exprContent);
580
+ if (styleBlockResult.hasDollarVariables) {
581
+ styleBlockHasDollarVars = true;
582
+ }
583
+ // Only pass indent for expressions containing style blocks
584
+ // Plain JS expressions (like .join('\n...')) should not be re-indented
585
+ if (hasStyleBlock) {
586
+ const exprPos = exprSplit.expressionPositions[exprIndex];
587
+ const indent = getIndentAtPosition(cssZone, exprPos);
588
+ if (indent) {
589
+ templateBody += '${__lassScriptExpression(' + styleBlockResult.text + ', "' + indent + '")}';
590
+ }
591
+ else {
592
+ templateBody += '${__lassScriptExpression(' + styleBlockResult.text + ')}';
593
+ }
594
+ }
595
+ else {
596
+ templateBody += '${__lassScriptExpression(' + styleBlockResult.text + ')}';
597
+ }
598
+ exprIndex++;
599
+ }
600
+ }
601
+ // Include $param usage from both CSS zone and style blocks
602
+ const finalHasDollarVariables = hasDollarVariables || styleBlockHasDollarVars;
603
+ return { templateBody, hasExpressions, hasDollarVariables: finalHasDollarVariables };
604
+ }
605
+ // ============================================================================
606
+ // STEP 6: OUTPUT BUILDING
607
+ // ============================================================================
608
+ /**
609
+ * Step 6: Build final JavaScript module output.
610
+ *
611
+ * Assembles preamble, helper functions (if needed), and template literal export.
612
+ * Story 5.1: Also translates @{ } style blocks in preamble.
613
+ *
614
+ * @param zones - Detected zones from step 1
615
+ * @param template - Processed template from step 5
616
+ * @returns Final JavaScript module code
617
+ */
618
+ export function buildOutput(zones, template) {
619
+ // Translate @{ } style blocks in preamble (Story 5.1)
620
+ // Use V1 (recursive) which properly normalizes entire style block content
621
+ let preambleHasDollarVars = false;
622
+ let translatedPreamble = zones.preamble;
623
+ if (zones.hasSeparator && zones.preamble.trim()) {
624
+ const preambleResult = translateStyleBlocks(zones.preamble);
625
+ translatedPreamble = preambleResult.text;
626
+ preambleHasDollarVars = preambleResult.hasDollarVariables;
627
+ }
628
+ // Include helper functions as needed
629
+ let helpers = '';
630
+ if (template.hasExpressions) {
631
+ helpers += LASS_SCRIPT_EXPRESSION_HELPER + '\n';
632
+ }
633
+ if (template.hasDollarVariables || preambleHasDollarVars) {
634
+ helpers += LASS_SCRIPT_LOOKUP_HELPER + '\n';
635
+ }
636
+ if (helpers) {
637
+ helpers += '\n'; // Extra blank line after helpers
638
+ }
639
+ // Include preamble if present (non-empty after trimming)
640
+ if (zones.hasSeparator && zones.preamble.trim()) {
641
+ // Helpers (if needed) + Preamble + blank line + export
642
+ // Preamble executes when module is imported, variables are in scope
643
+ return `${helpers}${translatedPreamble}\n\nexport default \`${template.templateBody}\`;`;
644
+ }
645
+ else {
646
+ // No separator or empty/whitespace-only preamble - just export (with helpers if needed)
647
+ return `${helpers}export default \`${template.templateBody}\`;`;
648
+ }
649
+ }
650
+ //# sourceMappingURL=transpiler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transpiler.js","sourceRoot":"","sources":["../src/transpiler.ts"],"names":[],"mappings":"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"}