UNPKG

2.52 kBJavaScriptView Raw
1const vm = require("vm");
2const asyncro = require("asyncro");
3const mime = require("mime");
4const CleanCSS = require("clean-css");
5
6const resource = require("./resource");
7
8const transformers = new Map;
9const cleanCss = new CleanCSS;
10
11const DEFAULT_TRANSFORMS = [{
12 name: "string",
13 transform(source, content, encoding = "utf8") {
14 if (Buffer.isBuffer(content)) {
15 content = content.toString(encoding);
16 }
17 return content;
18 }
19}, {
20 name: "cssmin",
21 transform(source, content) {
22 return cleanCss.minify(content).styles;
23 }
24}, {
25 name: "docstring",
26 transform(source, content) {
27 return content.match(/`((\\`|[^`])+)`/)[1];
28 }
29}, {
30 name: "stringify",
31 transform(source, content) {
32 return JSON.stringify(content);
33 }
34}, {
35 name: "dataurl",
36 transform(source, content, type = getMimeType(source), charset = "") {
37 if (!Buffer.isBuffer(content) || type.startsWith("text")) {
38 if (!charset) charset = "utf8";
39 if (!Buffer.isBuffer(content)) {
40 content = Buffer.from(content, charset);
41 }
42 }
43 if (charset) {
44 charset = `;charset=${charset}`;
45 }
46 return `data:${type}${charset};base64,${content.toString("base64")}`;
47 }
48}, {
49 name: "eval",
50 transform(source, content, code) {
51 return vm.runInNewContext(code, {$0: content});
52 }
53}, {
54 name: "markdown",
55 transform(source, content, type) {
56 if (type == "codeblock") {
57 return "```\n" + content + "\n```";
58 }
59 if (type == "code") {
60 return "`" + content + "`";
61 }
62 if (type == "quote") {
63 return content.split("\n").map(l => "> " + l).join("\n");
64 }
65 }
66}, {
67 name: "parse",
68 transform(source, content, ...props) {
69 var json = JSON.parse(content);
70 while (props.length) {
71 json = json[props.shift()];
72 }
73 return json;
74 }
75}, {
76 name: "trim",
77 transform(source, content) {
78 return content.trim();
79 }
80}];
81
82DEFAULT_TRANSFORMS.forEach(add);
83
84function getMimeType(source) {
85 return source && resource.PATH_LIKE.has(source.name) &&
86 mime.getType(source.args[0]) ||
87 "text/plain";
88}
89
90function add(transformer) {
91 transformers.set(transformer.name, transformer);
92}
93
94// async
95function transform(source, content, transforms) {
96 return asyncro.reduce(
97 transforms,
98 (content, transform) => {
99 const transformer = transformers.get(transform.name);
100 return transformer.transform(source, content, ...transform.args);
101 },
102 content
103 );
104}
105
106function has(name) {
107 return transformers.has(name);
108}
109
110module.exports = {add, transform, has};