Search code examples
javascripttypescriptyaml

Typescript: Using HandleBars for manipulating YAML file changing the file format to unicode


I am trying to create a YAML file based on a template. When I try to use the compiledTemplate, the " are converted to " . How can I prevent from this happening?

OUTPUT

apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
  name: n11-adapter-service
  namespace: argocd-prod
spec:
  generators:
    - list:
        - namespace: namespace1
          environment: dev
          region: eu
          path: eu-west-1/namespace1/dev
          clusterurl: url_dev_eu
        - namespace: namespace2
          environment: dev
          region: us
          path: us-east-1/namespace2/dev
          clusterurl: url_dev_us
        - namespace: namespace2
          environment: dev
          region: us
          path: us-east-1/namespace2/dev
          clusterurl: url_dev_us

  template:
    metadata:
      name: "{{environment}}-{{region}}-{{namespace}}-n11-adapter-service"
      labels:
        service: n11-adapter-service-{{environment}}
        tribe: core-engineering
        squad: partnerships
        environment: "{{environment}}"
        region: "{{region}}"
    spec:
      project: partnerships
      source:
        targetRevision: HEAD
        path: "{{path}}"
      destination:
        server: "{{clusterurl}}"
        namespace: "{{namespace}}"
      syncPolicy:
        automated:
          prune: true
          selfHeal: true
          allowEmpty: true
        syncOptions:
          - CreateNamespace=true

TEMPLATE

apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
  name: {{serviceName}}
  namespace: argocd-prod
spec:
  generators:
    - list:
{{#application}}
        - namespace: {{namespace}}
          environment: {{env}}
          region: {{region}}
          path: {{path}}
          clusterurl: {{clusterUrl}}
{{/application}}
{{! BEGIN template block }}
{{templatePlaceholder}}
{{! END template block }}

JS

import 'core-js/features/string/replace-all';
import { ApplicationSet, Owner } from './interfaces/types';
import * as fs from 'fs';
import * as Handlebars from 'handlebars';

const yamlTemplate = 'templates/argocd-appset.yaml';
export function generateApp(appset: ApplicationSet, owner: Owner): string {
  console.log("###################");
  // Define the replacements
  const replacements = {
    '##SERVICE_NAME##': appset.serviceName,
    '##SQUAD_NAME##': owner.squad,
    '##TRIBE_NAME##': owner.tribe,
  };

  // Moving this to a file did not work as the Handler tries to replace everything
  // under {{variable}}, escaping did not work.
  // Its worth a try with some other Handlebars if exists.
  var templateBlock = `
  template:
    metadata:
      name: "{{environment}}-{{region}}-{{namespace}}-##SERVICE_NAME##"
      labels:
        service: ##SERVICE_NAME##-{{environment}}
        tribe: ##TRIBE_NAME##
        squad: ##SQUAD_NAME##
        environment: "{{environment}}"
        region: "{{region}}"
    spec:
      project: ##SQUAD_NAME##
      source:
        targetRevision: HEAD
        path: "{{path}}"
      destination:
        server: "{{clusterurl}}"
        namespace: "{{namespace}}"
      syncPolicy:
        automated:
          prune: true
          selfHeal: true
          allowEmpty: true
        syncOptions:
          - CreateNamespace=true
  `;
  console.log(appset);
  const yamlData = fs.readFileSync(yamlTemplate, 'utf8');
  const compiledTemplate = Handlebars.compile(yamlData);
  // ReplaceAll doesnt work.
  //templateBlock = templateBlock.replaceAll("##SERVICE_NAME##",appset.serviceName) 
  for (const placeholder in replacements) {
    templateBlock = templateBlock.replace(new RegExp(placeholder, 'g'), replacements[placeholder]);
  }
  // Here the string is right
  console.log(templateBlock);
  const merged = {...appset,...owner,templatePlaceholder: templateBlock}
  const renderedYAML = compiledTemplate(merged);
  //console.log(renderedYAML)
  return renderedYAML;
}

I could do a replace again on my renderedTempalte, which I think is not a good solution. Is there any other way that I could do the convert of the file in an efficient way?


Solution

  • From the docs:

    Because it was originally designed to generate HTML, Handlebars escapes values returned by a {{expression}}. If you don't want Handlebars to escape a value, use the "triple-stash", {{{

    So using {{{templatePlaceholder}}} instead of {{templatePlaceholder}} should do the trick