-
Notifications
You must be signed in to change notification settings - Fork 8
/
create-widget.js
executable file
·189 lines (163 loc) · 5.55 KB
/
create-widget.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
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
import fs from "fs-extra";
import path from "path";
import cp from "child_process";
import { fileURLToPath } from "url";
import inquirer from "inquirer";
import { globby } from "globby";
import isUtf8 from "is-utf8";
import mustache from "mustache";
const __dirname = path.dirname(fileURLToPath(import.meta.url));
const INITIAL_PROMPT = `This tool will create a FigJam widget project using a template that serves as a starting point for building your widget.
See the generated README.md for more information on how to use this template and get started building your widget.
You can find the API reference for widgets here: https://www.figma.com/widget-docs/api/api-reference/
Press ^C at any time to quit.\n`;
function makeid(length) {
var result = "";
var characters =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
var charactersLength = characters.length;
for (var i = 0; i < length; i++) {
result += characters.charAt(Math.floor(Math.random() * charactersLength));
}
return result;
}
function randomWidgetId() {
return "widget-id-" + makeid(10);
}
export async function replaceTemplatizedValues(directory, values) {
const filePaths = await globby("**/*", {
cwd: directory,
dot: true,
});
await Promise.all(
filePaths.map(async function (filePath) {
const absolutePath = path.join(directory, filePath);
const buffer = await fs.readFile(absolutePath);
const fileContents = isUtf8(buffer)
? mustache.render(buffer.toString(), values)
: buffer;
await fs.outputFile(absolutePath, fileContents);
})
);
}
async function installDependencies(cwd, widgetname, destinationPath) {
await new (function (resolve, reject) {
const command = "npm install";
cp.exec(command, { cwd }, function (error) {
if (error) {
reject(error);
return;
}
path.resolve();
console.log();
console.log(`
Your widget has been created!
Run the following commands to get started building your widget:
cd ${destinationPath}
npm run dev
Import your widget into FigJam to start testing it:
1. Open a FigJam file using the Figma Desktop app to import your widget.
2. Right click > Widgets > Development > Import widget from manifest… and import the manifest.json file in your widget directory.
3. Insert your your widget: "Right click > Widgets > Development > ${widgetname}"
`);
});
})();
}
async function copyTemplateFiles(pluginDirectoryPath, shouldAddUI) {
const templateName = shouldAddUI ? "widget-with-ui" : "widget-without-ui";
const templateDirectory = path.resolve(
__dirname,
"..",
"create-widget",
"templates",
templateName
);
await fs.copy(templateDirectory, pluginDirectoryPath);
}
export async function createWidget(input) {
try {
console.log(INITIAL_PROMPT);
let widgetName = input.options.name;
if (widgetName === undefined) {
const result = await inquirer.prompt([
{
message:
'Enter the name of your widget: (empty defaults to "Widget")',
name: "widgetName",
type: "input",
},
]);
widgetName = result.widgetName ? result.widgetName : "Widget";
}
let destinationPath = input.options["package-name"];
if (destinationPath === undefined) {
const defaultDestinationPath = `${widgetName.toLowerCase()}-widget`;
const result = await inquirer.prompt([
{
message: `Enter the folder name for your widget: (empty defaults to "${defaultDestinationPath}")`,
name: "destinationPath",
type: "input",
},
]);
destinationPath = result.destinationPath
? result.destinationPath
: defaultDestinationPath;
}
let directoryPath = path.join(process.cwd(), destinationPath);
while ((await fs.pathExists(directoryPath)) === true) {
throw new Error(
`${destinationPath} already exists. Please choose a different destination folder name.`
);
}
let rawEditorType = input.options["editor-type"];
let editorType;
if (rawEditorType === undefined) {
const result = await inquirer.prompt([
{
choices: ["figma", "figjam", "figma,figjam"],
message: `Select the editor type(s) name for your widget:")`,
name: "editorType",
type: "list",
},
]);
rawEditorType = result.editorType || "figjam";
editorType = rawEditorType
.split(",")
.map((e) => `\"${e}\"`)
.join(",");
console.log(editorType);
}
let shouldAddUI = input.options.iframe;
if (shouldAddUI === undefined) {
const result = await inquirer.prompt([
{
choices: ["Y", "N"],
message: "Are you building a widget with an iframe?",
name: "shouldAddIframe",
type: "list",
},
]);
shouldAddUI = result.shouldAddIframe;
}
shouldAddUI = shouldAddUI === "Y";
console.log(``);
console.log(
`Creating widget for ${rawEditorType} ${
shouldAddUI ? "with ui" : "without ui"
}...`
);
console.log(`Copying template into "${destinationPath}"...`);
await copyTemplateFiles(directoryPath, shouldAddUI);
await replaceTemplatizedValues(directoryPath, {
widgetName,
widgetId: randomWidgetId(),
widgetEditorType: editorType,
packageName: widgetName.toLowerCase(),
});
console.log("Installing dependencies...");
await installDependencies(directoryPath, widgetName, destinationPath);
} catch (error) {
console.log(error.message);
process.exit(1);
}
}