{"version":3,"file":"template.mjs","names":[],"sources":["../../src/codegen/template.ts"],"sourcesContent":["/**\n * Lightweight string template engine.\n *\n * Syntax:\n * - `{{var}}` — interpolation\n * - `{{#arr}}...{{/arr}}` — iteration (`.` refers to current item)\n * - `{{#bool}}...{{/bool}}` — conditional blocks\n * - `{{>partial}}` — include a named sub-template\n */\n\ntype TemplateRenderer = (data: Record<string, unknown>, partials?: Record<string, string>) => string;\n\n/**\n * Compile a template string into a reusable render function.\n */\nexport function template(text: string): TemplateRenderer {\n  return (data: Record<string, unknown>, partials?: Record<string, string>) => {\n    return render(text, data, partials);\n  };\n}\n\nfunction render(text: string, data: Record<string, unknown>, partials?: Record<string, string>): string {\n  let result = text;\n\n  // Process block sections: {{#key}}...{{/key}}\n  result = result.replace(/\\{\\{#(\\w+)\\}\\}([\\s\\S]*?)\\{\\{\\/\\1\\}\\}/g, (_match, key: string, body: string) => {\n    const value = data[key];\n\n    if (value === undefined || value === null || value === false) {\n      return '';\n    }\n\n    if (Array.isArray(value)) {\n      return value\n        .map((item) => {\n          if (typeof item === 'object' && item !== null) {\n            return render(body, item as Record<string, unknown>, partials);\n          }\n          // For primitive items, replace {{.}} with the item value\n          return body.replace(/\\{\\{\\.\\}\\}/g, String(item));\n        })\n        .join('');\n    }\n\n    // Truthy conditional\n    if (typeof value === 'object') {\n      return render(body, value as Record<string, unknown>, partials);\n    }\n    return render(body, data, partials);\n  });\n\n  // Process partials: {{>partialName}}\n  if (partials) {\n    result = result.replace(/\\{\\{>(\\w+)\\}\\}/g, (_match, name: string) => {\n      const partialText = partials[name];\n      if (!partialText) return '';\n      return render(partialText, data, partials);\n    });\n  }\n\n  // Process interpolation: {{var}}\n  result = result.replace(/\\{\\{(\\w+)\\}\\}/g, (_match, key: string) => {\n    const value = data[key];\n    if (value === undefined || value === null) return '';\n    return String(value);\n  });\n\n  return result;\n}\n"],"mappings":";;;;AAeA,SAAgB,SAAS,MAAgC;CACvD,QAAQ,MAA+B,aAAsC;EAC3E,OAAO,OAAO,MAAM,MAAM,QAAQ;CACpC;AACF;AAEA,SAAS,OAAO,MAAc,MAA+B,UAA2C;CACtG,IAAI,SAAS;CAGb,SAAS,OAAO,QAAQ,0CAA0C,QAAQ,KAAa,SAAiB;EACtG,MAAM,QAAQ,KAAK;EAEnB,IAAI,UAAU,KAAA,KAAa,UAAU,QAAQ,UAAU,OACrD,OAAO;EAGT,IAAI,MAAM,QAAQ,KAAK,GACrB,OAAO,MACJ,KAAK,SAAS;GACb,IAAI,OAAO,SAAS,YAAY,SAAS,MACvC,OAAO,OAAO,MAAM,MAAiC,QAAQ;GAG/D,OAAO,KAAK,QAAQ,eAAe,OAAO,IAAI,CAAC;EACjD,CAAC,CAAC,CACD,KAAK,EAAE;EAIZ,IAAI,OAAO,UAAU,UACnB,OAAO,OAAO,MAAM,OAAkC,QAAQ;EAEhE,OAAO,OAAO,MAAM,MAAM,QAAQ;CACpC,CAAC;CAGD,IAAI,UACF,SAAS,OAAO,QAAQ,oBAAoB,QAAQ,SAAiB;EACnE,MAAM,cAAc,SAAS;EAC7B,IAAI,CAAC,aAAa,OAAO;EACzB,OAAO,OAAO,aAAa,MAAM,QAAQ;CAC3C,CAAC;CAIH,SAAS,OAAO,QAAQ,mBAAmB,QAAQ,QAAgB;EACjE,MAAM,QAAQ,KAAK;EACnB,IAAI,UAAU,KAAA,KAAa,UAAU,MAAM,OAAO;EAClD,OAAO,OAAO,KAAK;CACrB,CAAC;CAED,OAAO;AACT"}