deno.land / x / eta@v1.12.3 / file-utils.ts

file-utils.ts
View Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
import { existsSync, path, readFileSync } from "./file-methods.ts";const _BOM = /^\uFEFF/;
// express is set like: app.engine('html', require('eta').renderFile)
import EtaErr from "./err.ts";
/* TYPES */
import type { EtaConfig } from "./config.ts";
/* END TYPES */
/** * Get the path to the included file from the parent file path and the * specified path. * * If `name` does not have an extension, it will default to `.eta` * * @param name specified path * @param parentfile parent file path * @param isDirectory whether parentfile is a directory * @return absolute path to template */
function getWholeFilePath( name: string, parentfile: string, isDirectory?: boolean,): string { const includePath = path.resolve( isDirectory ? parentfile : path.dirname(parentfile), // returns directory the parent file is in name, // file ) + (path.extname(name) ? "" : ".eta"); return includePath;}
/** * Get the absolute path to an included template * * If this is called with an absolute path (for example, starting with '/' or 'C:\') * then Eta will attempt to resolve the absolute path within options.views. If it cannot, * Eta will fallback to options.root or '/' * * If this is called with a relative path, Eta will: * - Look relative to the current template (if the current template has the `filename` property) * - Look inside each directory in options.views * * Note: if Eta is unable to find a template using path and options, it will throw an error. * * @param path specified path * @param options compilation options * @return absolute path to template */
function getPath(path: string, options: EtaConfig): string { let includePath: string | false = false; const views = options.views; let searchedPaths: Array<string> = [];
// If these four values are the same, // getPath() will return the same result every time. // We can cache the result to avoid expensive // file operations. const pathOptions = JSON.stringify({ filename: options.filename, // filename of the template which called includeFile() path: path, root: options.root, views: options.views, });
if ( options.cache && options.filepathCache && options.filepathCache[pathOptions] ) { // Use the cached filepath return options.filepathCache[pathOptions]; }
/** Add a filepath to the list of paths we've checked for a template */ function addPathToSearched(pathSearched: string) { if (!searchedPaths.includes(pathSearched)) { searchedPaths.push(pathSearched); } }
/** * Take a filepath (like 'partials/mypartial.eta'). Attempt to find the template file inside `views`; * return the resulting template file path, or `false` to indicate that the template was not found. * * @param views the filepath that holds templates, or an array of filepaths that hold templates * @param path the path to the template */
function searchViews( views: Array<string> | string | undefined, path: string, ): string | false { let filePath;
// If views is an array, then loop through each directory // And attempt to find the template if ( Array.isArray(views) && views.some(function (v) { filePath = getWholeFilePath(path, v, true);
addPathToSearched(filePath);
return existsSync(filePath); }) ) { // If the above returned true, we know that the filePath was just set to a path // That exists (Array.some() returns as soon as it finds a valid element) return (filePath as unknown) as string; } else if (typeof views === "string") { // Search for the file if views is a single directory filePath = getWholeFilePath(path, views, true);
addPathToSearched(filePath);
if (existsSync(filePath)) { return filePath; } }
// Unable to find a file return false; }
// Path starts with '/', 'C:\', etc. const match = /^[A-Za-z]+:\\|^\//.exec(path);
// Absolute path, like /partials/partial.eta if (match && match.length) { // We have to trim the beginning '/' off the path, or else // path.resolve(dir, path) will always resolve to just path const formattedPath = path.replace(/^\/*/, "");
// First, try to resolve the path within options.views includePath = searchViews(views, formattedPath); if (!includePath) { // If that fails, searchViews will return false. Try to find the path // inside options.root (by default '/', the base of the filesystem) const pathFromRoot = getWholeFilePath( formattedPath, options.root || "/", true, );
addPathToSearched(pathFromRoot);
includePath = pathFromRoot; } } else { // Relative paths // Look relative to a passed filename first if (options.filename) { const filePath = getWholeFilePath(path, options.filename);
addPathToSearched(filePath);
if (existsSync(filePath)) { includePath = filePath; } } // Then look for the template in options.views if (!includePath) { includePath = searchViews(views, path); } if (!includePath) { throw EtaErr( 'Could not find the template "' + path + '". Paths tried: ' + searchedPaths, ); } }
// If caching and filepathCache are enabled, // cache the input & output of this function. if (options.cache && options.filepathCache) { options.filepathCache[pathOptions] = includePath; }
return includePath;}
/** * Reads a file synchronously */
function readFile(filePath: string): string { try { return readFileSync(filePath).toString().replace(_BOM, "") // TODO: is replacing BOM's necessary? ; } catch { throw EtaErr("Failed to read template at '" + filePath + "'"); }}
export { getPath, readFile };
eta
Embedded JS template engine for Node, Deno, and the browser. Lighweight, fast, and pluggable. Written in TypeScript
DocumentationDocumentation
GitHub Repositoryeta-dev/eta
GitHub Stars
527

Version Info

Tagged at
10 months ago

External Dependencies

1 external dependency