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
|
/**
* Create a new recipe for your service
*/
const fs = require('fs-extra');
const path = require('path');
const open = require('open');
if (process.argv.length < 3) {
console.log(`Usage: pnpm run create <Recipe name> [Folder name]
For example:
pnpm run create WhatsApp
pnpm run create "Google Hangouts"
You can set "Folder name" to "FerdiDev" to use Ferdi's development instance instead:
pnpm run create WhatsApp FerdiDev
`);
throw new Error('Please provide the correct number of args!');
}
const recipeName = process.argv[2];
const recipe = recipeName.toLowerCase().replace(/\s/g, '-');
const folderName = process.argv[3] || 'Ferdi';
const filesThatNeedTextReplace = [
'package.json',
'index.js',
'webview.js',
];
const toPascalCase = (str) => {
const words = str
.replace(/[^a-z]/g, '')
.split(/\W/)
.map((word) => {
if (word.length === 0) {
return word;
}
// Capitalize the first letter, lowercase the rest
return word.charAt(0).toUpperCase() + word.slice(1).toLowerCase();
});
return words.join('');
}
const pascalCasedName = toPascalCase(recipe); // PascalCased recipe ID only containing a-z, for usage as the JavaScript class name
(async () => {
// Folder paths
const userData =
process.env.APPDATA ||
(process.platform == 'darwin'
? process.env.HOME + '/Library/Application Support'
: process.env.HOME + '/.config');
const recipesFolder = path.join(userData, folderName, 'recipes');
const devRecipeFolder = path.join(recipesFolder, 'dev');
const newRecipeFolder = path.join(devRecipeFolder, recipe);
const sampleRecipe = path.join(__dirname, 'sample_recipe');
// Make sure dev recipe folder exists
if (!fs.existsSync(recipesFolder)) {
console.log(
`Couldn't find your recipe folder (${recipesFolder}). Is Ferdi installed?`,
);
return;
}
await fs.ensureDir(devRecipeFolder);
if (fs.existsSync(newRecipeFolder)) {
console.log('⚠️ Recipe already exists');
return;
}
console.log('[Info] Passed pre-checks');
// Copy sample recipe to recipe folder
await fs.copy(sampleRecipe, newRecipeFolder);
console.log('[Info] Copied recipe');
// Replace placeholders with the recipe-specific values
for (const file of filesThatNeedTextReplace) {
const filePath = path.join(newRecipeFolder, file);
let contents = await fs.readFile(filePath, 'utf-8');
contents = contents.replace(/SERVICE/g, recipe);
contents = contents.replace(/SNAME/g, recipeName);
contents = contents.replace(/SPASCAL/g, pascalCasedName);
await fs.writeFile(filePath, contents);
}
console.log('[Info] Prepared new recipe');
open(newRecipeFolder);
console.log(`✅ Successfully created your recipe.
What's next?
- Make sure you restart Ferdi in order for the recipe to show up
- Customise "webview.js", "package.json" and "icon.svg" (see https://github.com/getferdi/recipes/blob/master/docs/integration.md#recipe-structure)
- Publish your recipe (see https://github.com/getferdi/recipes/blob/master/docs/integration.md#publishing)`);
})();
|