1import * as fs from 'fs-extra';
2import { join } from 'path';
3
4import { SelfPath } from './Paths';
5import { Platform } from './Platform';
6import TemplateEvaluator from './TemplateEvaluator';
7
8export interface ProjectFile {
9  platform: Platform;
10  copy(projectPath: string, outputPath: string): Promise<void>;
11  evaluate(projectPath: string, filePath: string, evaluator: TemplateEvaluator): Promise<void>;
12}
13
14export class TemplateFile implements ProjectFile {
15  constructor(
16    public template: string,
17    public platform: Platform = Platform.Both,
18    public shouldBeEvaluated: boolean = false
19  ) {}
20
21  async copy(projectPath: string, outputPath: string): Promise<void> {
22    return fs.copy(
23      join(SelfPath, 'templates', this.template, outputPath),
24      join(projectPath, outputPath),
25      {
26        recursive: true,
27      }
28    );
29  }
30
31  async evaluate(
32    projectPath: string,
33    filePath: string,
34    evaluator: TemplateEvaluator
35  ): Promise<void> {
36    if (this.shouldBeEvaluated) {
37      return evaluator.compileFileAsync(join(projectPath, filePath));
38    }
39
40    return Promise.resolve();
41  }
42}
43
44export class UserFile implements ProjectFile {
45  constructor(
46    public userFilePath: string,
47    public platform: Platform = Platform.Both,
48    public shouldBeEvaluated: boolean = false
49  ) {}
50
51  copy(projectPath: string, outputPath: string): Promise<void> {
52    return fs.copy(this.userFilePath, join(projectPath, outputPath), {
53      recursive: true,
54    });
55  }
56
57  evaluate(projectPath: string, filePath: string, evaluator: any): Promise<void> {
58    if (this.shouldBeEvaluated) {
59      return evaluator.compileFileAsync(join(projectPath, filePath));
60    }
61
62    return Promise.resolve();
63  }
64}
65
66export class TemplateFilesFactory {
67  constructor(private template: string) {}
68
69  file(shouldBeEvaluated: boolean = false): TemplateFile {
70    return new TemplateFile(this.template, Platform.Both, shouldBeEvaluated);
71  }
72
73  androidFile(shouldBeEvaluated: boolean = false): TemplateFile {
74    return new TemplateFile(this.template, Platform.Android, shouldBeEvaluated);
75  }
76
77  iosFile(shouldBeEvaluated: boolean = false): TemplateFile {
78    return new TemplateFile(this.template, Platform.iOS, shouldBeEvaluated);
79  }
80}
81