-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbaguette.js
128 lines (119 loc) · 3.24 KB
/
baguette.js
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
const path = require("path");
const klaw = require("klaw");
const fs = require("fs").promises;
const font = require("./font");
const TEMPLATE_KEYWORD_REGEX = "baguette";
const DEFAULT_DEST = "src";
const DEFAULT_NAME = "IDidntSupplyAName";
const DEFAULT_CONFIG = {
dest: DEFAULT_DEST,
includeFolder: true,
};
function getAllFiles(dir) {
const files = [];
return new Promise((resolve, reject) => {
klaw(dir)
.on("data", (file) => {
if (file.stats.isFile()) {
files.push(file.path);
}
})
.on("error", (err) => reject(err))
.on("end", () => resolve(files));
});
}
function createComponent({ name = DEFAULT_NAME, template, config }) {
const { dest, includeFolder } = config;
console.log(
font.task(`👨🍳 Baking ${font.bold(name)}`),
font.task(`from ${template} recipe in ${dest}\n`)
);
const templateDir = path.resolve(process.cwd(), "baguettes", template);
const destDir = path.resolve(process.cwd(), dest, includeFolder ? name : "");
const replacer = replaceComponentReferences(TEMPLATE_KEYWORD_REGEX, name);
return getAllFiles(templateDir)
.catch((e) => {
if (e.message.includes("no such file or directory")) {
throw new Error(
"No baguettes template folder found. You should create one."
);
} else {
throw e;
}
})
.then((files) =>
Promise.all([files, fs.mkdir(destDir, { recursive: true })])
)
.then(([files]) => {
return Promise.all(
files.map((file) => {
const fileDest = replacer(file.replace(templateDir, ""));
const dest = path.join(destDir, path.dirname(fileDest));
return fs
.mkdir(dest, { recursive: true })
.then(() =>
fs.readFile(path.resolve(templateDir, file), {
encoding: "utf-8",
})
)
.then((data) => {
const contents = replacer(data);
const destFile = path.join(destDir, fileDest);
console.log(
font.task(
`📝 Writing file ${destFile.replace(
path.resolve(process.cwd()),
""
)}...`
)
);
return fs.writeFile(destFile, contents);
});
})
);
})
.then(() =>
console.log(
font.success(`\n🥖 ${font.bold(name)}`),
font.success(`successfully baked in ${dest}\n`)
)
);
}
const replaceComponentReferences = (oldName, newName) => (str) =>
str.replace(new RegExp(oldName, "ig"), newName);
function getConfig() {
return fs
.readFile(path.resolve(process.cwd(), "baguettes/config.json"), {
encoding: "utf-8",
})
.then(JSON.parse)
.catch((e) => {
if (e instanceof SyntaxError) {
throw new Error("Malformed JSON in config.json file");
} else if (e.code === "ENOENT") {
console.log(
font.error(
"No config.json file found in baguettes directory, using default config."
)
);
return Promise.resolve({});
}
});
}
module.exports = function baguette({ name, template, ...options }) {
return getConfig()
.then((config) => {
const mergedConfig =
typeof config[template] === "string"
? { ...DEFAULT_CONFIG, dest: config[template], ...options }
: { ...DEFAULT_CONFIG, ...config[template], ...options };
return createComponent({
name,
template,
config: mergedConfig,
});
})
.catch((e) => {
console.log(font.error(e.message));
});
};