-
-
Notifications
You must be signed in to change notification settings - Fork 75
/
formats.ts
103 lines (83 loc) 路 2.57 KB
/
formats.ts
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
import type { Engine } from "./renderer.ts";
import type { Loader } from "./fs.ts";
export interface Format {
/** The file extension for this format */
ext: string;
/** The type of page */
pageType?: "page" | "asset";
/** The file loader used for this format (used by pages, includes, components, etc) */
loader?: Loader;
/** The loader used as asset */
assetLoader?: Loader;
/** Loader for _data files in this format */
dataLoader?: Loader;
/**
* The template engines used to render this format
* Used to render the page and components
*/
engines?: Engine[];
/** Whether this file must be copied instead loaded */
copy?: boolean | ((path: string) => string);
}
/** Class to store loaders, engines and other stuff related with different formats */
export default class Formats {
entries = new Map<string, Format>();
get size(): number {
return this.entries.size;
}
/** Assign a value to a extension */
set(format: Format, override = true): void {
const ext = format.ext.toLowerCase();
const existing = this.entries.get(ext);
if (existing) {
if (override) {
this.entries.set(ext, { ...existing, ...format });
} else {
this.entries.set(ext, { ...format, ...existing });
}
return;
}
// Simple extension (.ts, .js, .json)
if (ext.match(/^\.\w+$/)) {
this.entries.set(ext, format);
return;
}
// Chained extension (.tmpl.js) goes first
if (ext.match(/^\.\w+\.\w+$/)) {
const entries = Array.from(this.entries.entries());
entries.unshift([ext, format]);
this.entries = new Map(entries);
return;
}
throw new Error(
`Invalid file extension: "${ext}". It must start with '.'`,
);
}
/** Returns a format by extension */
get(extension: string): Format | undefined {
return this.entries.get(extension.toLowerCase());
}
/** Delete a format */
delete(extension: string): void {
this.entries.delete(extension.toLowerCase());
}
/** Returns if a format exists */
has(extension: string): boolean {
return this.entries.has(extension.toLowerCase());
}
/** Search and return the associated format for a path */
search(path: string): Format | undefined {
path = path.toLowerCase();
for (const format of this.entries.values()) {
if (path.endsWith(format.ext)) {
return format;
}
}
}
/** Delete a cached template */
deleteCache(file: string): void {
for (const format of this.entries.values()) {
format.engines?.forEach((engine) => engine.deleteCache(file));
}
}
}