index.ts 5.31 KB
Newer Older
Ludan Stoecklé's avatar
Ludan Stoecklé committed
1
import fs = require('fs');
Ludan Stoecklé's avatar
1.3.2  
Ludan Stoecklé committed
2
import path = require('path');
Ludan Stoecklé's avatar
Ludan Stoecklé committed
3
import stream = require('stream');
Ludan Stoecklé's avatar
1.10.0  
Ludan Stoecklé committed
4
import rosaenlg = require('rosaenlg');
Ludan Stoecklé's avatar
Ludan Stoecklé committed
5 6 7
import browserify = require('browserify');
import minify = require('minify-stream');

Ludan Stoecklé's avatar
1.13.0  
Ludan Stoecklé committed
8
import { PackagedTemplate, CompileInfo, Autotest, Languages, TemplatesMap } from 'rosaenlg-server-toolkit';
Ludan Stoecklé's avatar
Ludan Stoecklé committed
9

Ludan Stoecklé's avatar
1.12.0  
Ludan Stoecklé committed
10 11 12 13 14 15
export interface PackagedTemplateParams {
  templateId: string;
  entryTemplate: string;
  compileInfo: CompileInfo;
  autotest?: Autotest;
}
Ludan Stoecklé's avatar
Ludan Stoecklé committed
16

Ludan Stoecklé's avatar
1.13.0  
Ludan Stoecklé committed
17
const FORMAT = '2.0.0';
Ludan Stoecklé's avatar
1.10.0  
Ludan Stoecklé committed
18

Ludan Stoecklé's avatar
Ludan Stoecklé committed
19 20
export function renderTemplateInFile(template: string, dest: string, options: any): void {
  if (!template) {
Ludan Stoecklé's avatar
Ludan Stoecklé committed
21
    const err = new Error();
Ludan Stoecklé's avatar
Ludan Stoecklé committed
22 23 24 25 26
    err.name = 'InvalidArgumentError';
    err.message = 'template is mandatory';
    throw err;
  }
  if (!dest) {
Ludan Stoecklé's avatar
Ludan Stoecklé committed
27
    const err = new Error();
Ludan Stoecklé's avatar
Ludan Stoecklé committed
28 29 30 31 32
    err.name = 'InvalidArgumentError';
    err.message = 'destination file is mandatory';
    throw err;
  }

Ludan Stoecklé's avatar
1.10.0  
Ludan Stoecklé committed
33
  const rendered = rosaenlg.renderFile(template, options);
Ludan Stoecklé's avatar
Ludan Stoecklé committed
34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
  fs.writeFileSync(dest, rendered);
}

interface SourceAndName {
  source: string;
  name: string;
}

export function compileTemplates(
  sourcesAndNames: SourceAndName[],
  language: Languages,
  dest: string,
  holderName: string,
  tinyify: boolean,
): fs.WriteStream {
  if (!dest) {
Ludan Stoecklé's avatar
Ludan Stoecklé committed
50
    const err = new Error();
Ludan Stoecklé's avatar
Ludan Stoecklé committed
51 52 53 54 55
    err.name = 'InvalidArgumentError';
    err.message = 'destination file is mandatory';
    throw err;
  }
  if (!holderName) {
Ludan Stoecklé's avatar
Ludan Stoecklé committed
56
    const err = new Error();
Ludan Stoecklé's avatar
Ludan Stoecklé committed
57 58 59 60 61
    err.name = 'InvalidArgumentError';
    err.message = 'holder name is mandatory';
    throw err;
  }

Ludan Stoecklé's avatar
Ludan Stoecklé committed
62
  const s = new stream.Readable();
Ludan Stoecklé's avatar
Ludan Stoecklé committed
63

Ludan Stoecklé's avatar
1.13.0  
Ludan Stoecklé committed
64 65
  sourcesAndNames.forEach(function (sourceAndName: SourceAndName): void {
    //console.log(`template ${sourceAndName.source} => ${sourceAndName.name}`);
Ludan Stoecklé's avatar
1.10.0  
Ludan Stoecklé committed
66
    const compiled = rosaenlg.compileFileClient(sourceAndName.source, {
Ludan Stoecklé's avatar
Ludan Stoecklé committed
67 68 69 70 71 72 73 74
      language: language,
      compileDebug: false,
      embedResources: true,
      name: sourceAndName.name,
    });
    s.push(compiled.toString());
  });

Ludan Stoecklé's avatar
1.13.0  
Ludan Stoecklé committed
75
  const names = sourcesAndNames.map(function (elt): string {
Ludan Stoecklé's avatar
Ludan Stoecklé committed
76 77 78 79 80 81 82
    return elt.name;
  });
  s.push(`\nmodule.exports = {${names.join(',')}};`);
  s.push(null);

  const outputStream = fs.createWriteStream(dest);

Ludan Stoecklé's avatar
Ludan Stoecklé committed
83
  const b = browserify({
Ludan Stoecklé's avatar
Ludan Stoecklé committed
84 85 86 87
    standalone: holderName,
  });
  /* istanbul ignore if : tinyify is too long for gitlab CI */
  // if (tinyify) {
Ludan Stoecklé's avatar
Ludan Stoecklé committed
88
  // b.plugin('tinyify');
Ludan Stoecklé's avatar
Ludan Stoecklé committed
89 90 91 92
  // }
  b.add(s);

  if (tinyify) {
Ludan Stoecklé's avatar
Ludan Stoecklé committed
93 94
    return b
      .bundle()
Ludan Stoecklé's avatar
Ludan Stoecklé committed
95 96 97 98 99 100
      .pipe(minify({ sourceMap: false }))
      .pipe(outputStream);
  } else {
    return b.bundle().pipe(outputStream);
  }
}
Ludan Stoecklé's avatar
1.3.2  
Ludan Stoecklé committed
101

Ludan Stoecklé's avatar
1.13.0  
Ludan Stoecklé committed
102
const includeRe = new RegExp('^\\s*include\\s+([^\\s]+)\\s*$');
Ludan Stoecklé's avatar
Ludan Stoecklé committed
103 104 105 106 107 108 109 110 111 112 113

function getFinalFileName(baseDir: string, template: string): string {
  const pathElts = path.parse(template);
  const templateWithExt = pathElts.ext == null || pathElts.ext == '' ? template + '.pug' : template;

  const fullPath = baseDir ? path.join(baseDir, templateWithExt) : templateWithExt;
  const finalFileName = fullPath.replace(new RegExp('\\\\', 'g'), '/'); // change to linux paths

  return finalFileName;
}

Ludan Stoecklé's avatar
1.13.0  
Ludan Stoecklé committed
114 115 116 117
function getAllIncludes(baseDir: string, template: string, templatesMap: TemplatesMap): TemplatesMap {
  //console.log('starting to process: ' + template);
  templatesMap = templatesMap || {};

Ludan Stoecklé's avatar
Ludan Stoecklé committed
118 119 120
  const finalFileName = getFinalFileName(baseDir, template);
  // console.log('finalFileName is: ' + finalFileName);
  const content = fs.readFileSync(finalFileName, 'utf8');
Ludan Stoecklé's avatar
1.13.0  
Ludan Stoecklé committed
121 122 123 124 125 126 127 128 129 130 131

  // add this one
  templatesMap[finalFileName] = content;

  // check includes
  const lines = content.split(/\r?\n/);
  for (let i = 0; i < lines.length; i++) {
    const line = lines[i];
    const matches = line.match(includeRe);
    if (matches && matches[1]) {
      const matched = matches[1];
Ludan Stoecklé's avatar
Ludan Stoecklé committed
132 133 134
      // console.log('found included: ' + matched);
      const newBaseDir = path.parse(finalFileName).dir;
      // console.log('newBaseDir: ' + newBaseDir);
Ludan Stoecklé's avatar
1.13.0  
Ludan Stoecklé committed
135 136 137 138
      templatesMap = getAllIncludes(newBaseDir, matched, templatesMap);
    }
  }
  return templatesMap;
Ludan Stoecklé's avatar
1.3.2  
Ludan Stoecklé committed
139 140 141 142
}

export function packageTemplateJson(params: PackagedTemplateParams): PackagedTemplate {
  const res: PackagedTemplate = {
Ludan Stoecklé's avatar
1.10.0  
Ludan Stoecklé committed
143
    format: FORMAT,
Ludan Stoecklé's avatar
1.3.2  
Ludan Stoecklé committed
144
    templateId: params.templateId,
Ludan Stoecklé's avatar
1.10.0  
Ludan Stoecklé committed
145 146 147 148 149
    src: {
      entryTemplate: params.entryTemplate,
      compileInfo: Object.assign({}, params.compileInfo), // as we will modify the object in res
      templates: {},
    },
Ludan Stoecklé's avatar
1.3.2  
Ludan Stoecklé committed
150 151
  };

Ludan Stoecklé's avatar
1.3.3  
Ludan Stoecklé committed
152
  // as it is not useful in the result
Ludan Stoecklé's avatar
1.10.0  
Ludan Stoecklé committed
153 154
  if (res.src.compileInfo && res.src.compileInfo.activate != null) {
    delete res.src.compileInfo.activate;
Ludan Stoecklé's avatar
1.3.3  
Ludan Stoecklé committed
155 156
  }

Ludan Stoecklé's avatar
1.3.2  
Ludan Stoecklé committed
157 158
  // autotest data if present
  if (params.autotest) {
Ludan Stoecklé's avatar
1.10.0  
Ludan Stoecklé committed
159
    res.src.autotest = params.autotest;
Ludan Stoecklé's avatar
1.3.2  
Ludan Stoecklé committed
160
  }
Ludan Stoecklé's avatar
1.13.0  
Ludan Stoecklé committed
161 162
  // get file list and their content
  const templatesMap: TemplatesMap = getAllIncludes(null, params.entryTemplate, null);
Ludan Stoecklé's avatar
1.3.2  
Ludan Stoecklé committed
163

Ludan Stoecklé's avatar
1.13.0  
Ludan Stoecklé committed
164 165
  // console.log(templatesMap);
  res.src.templates = templatesMap;
Ludan Stoecklé's avatar
1.3.2  
Ludan Stoecklé committed
166 167 168

  // compile if asked
  if (params.compileInfo && params.compileInfo.activate) {
Ludan Stoecklé's avatar
1.13.0  
Ludan Stoecklé committed
169
    const compiled = rosaenlg.compileFileClient(params.entryTemplate, {
Ludan Stoecklé's avatar
1.3.2  
Ludan Stoecklé committed
170 171 172 173
      language: params.compileInfo.language,
      compileDebug: params.compileInfo.compileDebug,
      embedResources: true,
    });
Ludan Stoecklé's avatar
1.10.0  
Ludan Stoecklé committed
174 175 176 177 178 179
    res.comp = {
      compiled: compiled,
      compiledWithVersion: rosaenlg.getRosaeNlgVersion(),
      compiledBy: 'gulp-rosaenlg',
      compiledWhen: new Date().toISOString(),
    };
Ludan Stoecklé's avatar
1.3.2  
Ludan Stoecklé committed
180 181 182 183
  }

  return res;
}