@joystick.js/cli-canary 0.0.0-canary.8 → 0.0.0-canary.81
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/functions/start/index.js +4 -470
- package/dist/functions/start/onWarn.js +1 -1
- package/dist/lib/build/buildFiles.js +63 -7
- package/dist/lib/build/buildPlugins.js +18 -15
- package/dist/lib/build/getCodeFrame.js +3 -4
- package/dist/lib/build/onWarn.js +1 -1
- package/dist/lib/build/removeDeletedDependenciesFromMap.js +1 -1
- package/dist/lib/dev/cleanup.js +15 -27
- package/dist/lib/dev/databases/mongodb/index.js +1 -1
- package/dist/lib/dev/databases/postgresql/index.js +2 -2
- package/dist/lib/dev/databases/providerMap.js +1 -1
- package/dist/lib/dev/index.js +101 -27
- package/dist/lib/dev/isWindows.js +5 -0
- package/dist/lib/dev/loadSettings.js +1 -3
- package/dist/lib/dev/startApp.js +43 -3
- package/dist/lib/dev/startDatabases.js +12 -5
- package/dist/lib/dev/startHMR.js +30 -5
- package/dist/lib/getProcessIdFromPort.js +60 -0
- package/dist/lib/types.js +6 -0
- package/package.json +1 -1
- package/src/functions/start/index.js +615 -612
- package/src/functions/start/onWarn.js +1 -1
- package/src/lib/build/buildFiles.js +74 -8
- package/src/lib/build/buildPlugins.js +29 -22
- package/src/lib/build/getCodeFrame.js +3 -4
- package/src/lib/build/onWarn.js +1 -1
- package/src/lib/build/removeDeletedDependenciesFromMap.js +1 -1
- package/src/lib/dev/cleanup.js +20 -28
- package/src/lib/dev/databases/mongodb/index.js +1 -1
- package/src/lib/dev/databases/postgresql/index.js +2 -2
- package/src/lib/dev/databases/providerMap.js +1 -1
- package/src/lib/dev/index.js +121 -35
- package/src/lib/dev/isWindows.js +3 -0
- package/src/lib/dev/loadSettings.js +1 -3
- package/src/lib/dev/startApp.js +52 -6
- package/src/lib/dev/startDatabases.js +12 -6
- package/src/lib/dev/startHMR.js +36 -7
- package/src/lib/getProcessIdFromPort.js +92 -0
- package/src/lib/types.js +3 -0
|
@@ -1,198 +1,4 @@
|
|
|
1
1
|
import dev from "../../lib/dev/index.js";
|
|
2
|
-
const majorVersion = parseInt(
|
|
3
|
-
process?.version?.split(".")[0]?.replace("v", ""),
|
|
4
|
-
10
|
|
5
|
-
);
|
|
6
|
-
const __filename = fileURLToPath(import.meta.url);
|
|
7
|
-
const __dirname = dirname(__filename);
|
|
8
|
-
const killProcess = (pid = 0) => {
|
|
9
|
-
return new Promise((resolve) => {
|
|
10
|
-
ps.kill(pid, () => {
|
|
11
|
-
resolve();
|
|
12
|
-
});
|
|
13
|
-
});
|
|
14
|
-
};
|
|
15
|
-
const watchlist = [
|
|
16
|
-
{ path: "ui" },
|
|
17
|
-
{ path: "lib" },
|
|
18
|
-
{ path: "i18n" },
|
|
19
|
-
{ path: "api" },
|
|
20
|
-
{ path: "email" },
|
|
21
|
-
{ path: "fixtures" },
|
|
22
|
-
{ path: "routes" },
|
|
23
|
-
{ path: "index.client.js" },
|
|
24
|
-
{ path: "index.server.js" },
|
|
25
|
-
...filesToCopy
|
|
26
|
-
];
|
|
27
|
-
const requiredFileCheck = () => {
|
|
28
|
-
return new Promise((resolve) => {
|
|
29
|
-
const requiredFiles = [
|
|
30
|
-
{ path: "index.server.js", type: "file" },
|
|
31
|
-
{ path: "index.html", type: "file" },
|
|
32
|
-
{ path: "index.client.js", type: "file" },
|
|
33
|
-
{ path: "api", type: "directory" },
|
|
34
|
-
{ path: "i18n", type: "directory" },
|
|
35
|
-
{ path: "lib", type: "directory" },
|
|
36
|
-
{ path: "public", type: "directory" },
|
|
37
|
-
{ path: "ui", type: "directory" },
|
|
38
|
-
{ path: "ui/components", type: "directory" },
|
|
39
|
-
{ path: "ui/layouts", type: "directory" },
|
|
40
|
-
{ path: "ui/pages", type: "directory" }
|
|
41
|
-
];
|
|
42
|
-
requiredFiles.forEach((requiredFile) => {
|
|
43
|
-
const exists = fs.existsSync(`${process.cwd()}/${requiredFile.path}`);
|
|
44
|
-
const stats = exists && fs.statSync(`${process.cwd()}/${requiredFile.path}`);
|
|
45
|
-
const isFile = stats && stats.isFile();
|
|
46
|
-
const isDirectory = stats && stats.isDirectory();
|
|
47
|
-
if (requiredFile && requiredFile.type === "file") {
|
|
48
|
-
if (!exists || exists && !isFile) {
|
|
49
|
-
CLILog(
|
|
50
|
-
`The path ${requiredFile.path} must exist in your project and must be a file (not a directory).`,
|
|
51
|
-
{
|
|
52
|
-
level: "danger",
|
|
53
|
-
docs: "https://github.com/cheatcode/joystick#folder-and-file-structure"
|
|
54
|
-
}
|
|
55
|
-
);
|
|
56
|
-
process.exit(0);
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
if (requiredFile && requiredFile.type === "directory") {
|
|
60
|
-
if (!exists || exists && !isDirectory) {
|
|
61
|
-
CLILog(
|
|
62
|
-
`The path ${requiredFile.path} must exist in your project and must be a directory (not a file).`,
|
|
63
|
-
{
|
|
64
|
-
level: "danger",
|
|
65
|
-
docs: "https://github.com/cheatcode/joystick#folder-and-file-structure"
|
|
66
|
-
}
|
|
67
|
-
);
|
|
68
|
-
process.exit(0);
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
});
|
|
72
|
-
resolve();
|
|
73
|
-
});
|
|
74
|
-
};
|
|
75
|
-
const handleCleanup = async (processIds = [process?.serverProcess?.pid, process?.hmrProcess?.pid]) => {
|
|
76
|
-
for (let i = 0; i < processIds?.length; i += 1) {
|
|
77
|
-
const processId = processIds[i];
|
|
78
|
-
if (processId) {
|
|
79
|
-
await killProcess(processId);
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
const databases = Object.entries(process._databases || {});
|
|
83
|
-
for (let i = 0; i < databases?.length; i += 1) {
|
|
84
|
-
const [provider, providerConnection] = databases[i];
|
|
85
|
-
if (providerConnection?.pid) {
|
|
86
|
-
await killProcess(providerConnection.pid);
|
|
87
|
-
}
|
|
88
|
-
if (!providerConnection?.pid) {
|
|
89
|
-
const providerConnections = Object.entries(providerConnection);
|
|
90
|
-
for (let pc = 0; pc < providerConnections?.length; pc += 1) {
|
|
91
|
-
const [_connectionName, connection] = providerConnections[pc];
|
|
92
|
-
if (connection?.pid) {
|
|
93
|
-
await killProcess(connection?.pid);
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
};
|
|
99
|
-
const getDatabaseProcessIds = () => {
|
|
100
|
-
const databaseProcessIds = [];
|
|
101
|
-
const databases = Object.entries(process._databases || {});
|
|
102
|
-
for (let i = 0; i < databases?.length; i += 1) {
|
|
103
|
-
const [_provider, providerConnection] = databases[i];
|
|
104
|
-
if (providerConnection?.pid) {
|
|
105
|
-
databaseProcessIds.push(providerConnection.pid);
|
|
106
|
-
}
|
|
107
|
-
if (!providerConnection?.pid) {
|
|
108
|
-
const providerConnections = Object.entries(providerConnection);
|
|
109
|
-
for (let pc = 0; pc < providerConnections?.length; pc += 1) {
|
|
110
|
-
const [_connectionName, connection] = providerConnections[pc];
|
|
111
|
-
if (connection?.pid) {
|
|
112
|
-
databaseProcessIds.push(connection.pid);
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
return databaseProcessIds;
|
|
118
|
-
};
|
|
119
|
-
const handleSignalEvents = (processIds = []) => {
|
|
120
|
-
const execArgv = ["--no-warnings"];
|
|
121
|
-
if (majorVersion < 19) {
|
|
122
|
-
execArgv.push("--experimental-specifier-resolution=node");
|
|
123
|
-
}
|
|
124
|
-
const cleanupProcess = child_process.fork(
|
|
125
|
-
path.resolve(`${__dirname}/cleanup/index.js`),
|
|
126
|
-
[],
|
|
127
|
-
{
|
|
128
|
-
// NOTE: Run in detached mode so when parent process dies, the child still runs
|
|
129
|
-
// and cleanup completes.
|
|
130
|
-
detached: true,
|
|
131
|
-
execArgv,
|
|
132
|
-
// NOTE: Pipe stdin, stdout, and stderr. IPC establishes a message channel so we
|
|
133
|
-
// communicate with the child_process.
|
|
134
|
-
silent: true
|
|
135
|
-
}
|
|
136
|
-
);
|
|
137
|
-
process.on("SIGINT", async () => {
|
|
138
|
-
const databaseProcessIds = getDatabaseProcessIds();
|
|
139
|
-
cleanupProcess.send(JSON.stringify({ processIds: [...processIds, ...databaseProcessIds] }));
|
|
140
|
-
process.exit();
|
|
141
|
-
});
|
|
142
|
-
process.on("SIGTERM", async () => {
|
|
143
|
-
const databaseProcessIds = getDatabaseProcessIds();
|
|
144
|
-
cleanupProcess.send(JSON.stringify({ processIds: [...processIds, ...databaseProcessIds] }));
|
|
145
|
-
process.exit();
|
|
146
|
-
});
|
|
147
|
-
};
|
|
148
|
-
const handleHMRProcessMessages = () => {
|
|
149
|
-
process.hmrProcess.on("message", (message) => {
|
|
150
|
-
const processMessages = [
|
|
151
|
-
"SERVER_CLOSED",
|
|
152
|
-
"HAS_HMR_CONNECTIONS",
|
|
153
|
-
"HAS_NO_HMR_CONNECTIONS",
|
|
154
|
-
"HMR_UPDATE_COMPLETED"
|
|
155
|
-
];
|
|
156
|
-
if (!processMessages.includes(message?.type)) {
|
|
157
|
-
process.loader.stable(message);
|
|
158
|
-
}
|
|
159
|
-
if (message?.type === "HAS_HMR_CONNECTIONS") {
|
|
160
|
-
process.hmrProcess.hasConnections = true;
|
|
161
|
-
}
|
|
162
|
-
if (message?.type === "HAS_NO_HMR_CONNECTIONS") {
|
|
163
|
-
process.hmrProcess.hasConnections = false;
|
|
164
|
-
}
|
|
165
|
-
if (message?.type === "HMR_UPDATE_COMPLETED") {
|
|
166
|
-
setTimeout(() => {
|
|
167
|
-
restartApplicationProcess(message?.sessions);
|
|
168
|
-
}, 500);
|
|
169
|
-
}
|
|
170
|
-
});
|
|
171
|
-
};
|
|
172
|
-
const handleHMRProcessSTDIO = () => {
|
|
173
|
-
try {
|
|
174
|
-
if (process.hmrProcess) {
|
|
175
|
-
process.hmrProcess.on("error", (error) => {
|
|
176
|
-
CLILog(error.toString(), {
|
|
177
|
-
level: "danger",
|
|
178
|
-
docs: "https://github.com/cheatcode/joystick"
|
|
179
|
-
});
|
|
180
|
-
});
|
|
181
|
-
process.hmrProcess.stdout.on("data", (data) => {
|
|
182
|
-
console.log(data.toString());
|
|
183
|
-
});
|
|
184
|
-
process.hmrProcess.stderr.on("data", (data) => {
|
|
185
|
-
process.loader.stop();
|
|
186
|
-
CLILog(data.toString(), {
|
|
187
|
-
level: "danger",
|
|
188
|
-
docs: "https://github.com/cheatcode/joystick"
|
|
189
|
-
});
|
|
190
|
-
});
|
|
191
|
-
}
|
|
192
|
-
} catch (exception) {
|
|
193
|
-
throw new Error(`[dev.handleHMRProcessSTDIO] ${exception.message}`);
|
|
194
|
-
}
|
|
195
|
-
};
|
|
196
2
|
const startHMRProcess = () => {
|
|
197
3
|
const execArgv = ["--no-warnings"];
|
|
198
4
|
if (majorVersion < 19) {
|
|
@@ -212,284 +18,12 @@ const startHMRProcess = () => {
|
|
|
212
18
|
handleHMRProcessSTDIO();
|
|
213
19
|
handleHMRProcessMessages();
|
|
214
20
|
};
|
|
215
|
-
const notifyHMRClients = (indexHTMLChanged = false) => {
|
|
216
|
-
const settings = loadSettings(process.env.NODE_ENV);
|
|
217
|
-
process.hmrProcess.send(
|
|
218
|
-
JSON.stringify({
|
|
219
|
-
type: "RESTART_SERVER",
|
|
220
|
-
settings,
|
|
221
|
-
indexHTMLChanged
|
|
222
|
-
})
|
|
223
|
-
);
|
|
224
|
-
};
|
|
225
|
-
const handleServerProcessMessages = () => {
|
|
226
|
-
process.serverProcess.on("message", (message) => {
|
|
227
|
-
const processMessages = ["SERVER_CLOSED"];
|
|
228
|
-
if (!processMessages.includes(message)) {
|
|
229
|
-
process.loader.stable(message);
|
|
230
|
-
}
|
|
231
|
-
});
|
|
232
|
-
};
|
|
233
|
-
const handleServerProcessSTDIO = () => {
|
|
234
|
-
try {
|
|
235
|
-
if (process.serverProcess) {
|
|
236
|
-
process.serverProcess.on("error", (error) => {
|
|
237
|
-
console.log(error);
|
|
238
|
-
});
|
|
239
|
-
process.serverProcess.stdout.on("data", (data) => {
|
|
240
|
-
const message = data.toString();
|
|
241
|
-
if (message && message.includes("App running at:")) {
|
|
242
|
-
process.loader.stable(message);
|
|
243
|
-
} else {
|
|
244
|
-
if (message && !message.includes("BUILD_ERROR")) {
|
|
245
|
-
console.log(message);
|
|
246
|
-
}
|
|
247
|
-
}
|
|
248
|
-
});
|
|
249
|
-
process.serverProcess.stderr.on("data", (data) => {
|
|
250
|
-
process.loader.stop();
|
|
251
|
-
CLILog(data.toString(), {
|
|
252
|
-
level: "danger",
|
|
253
|
-
docs: "https://github.com/cheatcode/joystick"
|
|
254
|
-
});
|
|
255
|
-
});
|
|
256
|
-
}
|
|
257
|
-
} catch (exception) {
|
|
258
|
-
throw new Error(`[dev.handleServerProcessSTDIO] ${exception.message}`);
|
|
259
|
-
}
|
|
260
|
-
};
|
|
261
|
-
const startApplicationProcess = (sessionsBeforeHMRUpdate = null) => {
|
|
262
|
-
const execArgv = ["--no-warnings"];
|
|
263
|
-
if (majorVersion < 19) {
|
|
264
|
-
execArgv.push("--experimental-specifier-resolution=node");
|
|
265
|
-
}
|
|
266
|
-
if (process.env.NODE_ENV === "development" && process.env.IS_DEBUG_MODE === "true") {
|
|
267
|
-
execArgv.push("--inspect");
|
|
268
|
-
}
|
|
269
|
-
const serverProcess = child_process.fork(
|
|
270
|
-
path.resolve(".joystick/build/index.server.js"),
|
|
271
|
-
[],
|
|
272
|
-
{
|
|
273
|
-
execArgv,
|
|
274
|
-
// NOTE: Pipe stdin, stdout, and stderr. IPC establishes a message channel so we
|
|
275
|
-
// communicate with the child_process.
|
|
276
|
-
silent: true,
|
|
277
|
-
env: {
|
|
278
|
-
FORCE_COLOR: "1",
|
|
279
|
-
LOGS_PATH: process.env.LOGS_PATH,
|
|
280
|
-
NODE_ENV: process.env.NODE_ENV,
|
|
281
|
-
ROOT_URL: process.env.ROOT_URL,
|
|
282
|
-
PORT: process.env.PORT,
|
|
283
|
-
JOYSTICK_SETTINGS: process.env.JOYSTICK_SETTINGS,
|
|
284
|
-
HMR_SESSIONS: sessionsBeforeHMRUpdate
|
|
285
|
-
}
|
|
286
|
-
}
|
|
287
|
-
);
|
|
288
|
-
process.serverProcess = serverProcess;
|
|
289
|
-
handleServerProcessSTDIO();
|
|
290
|
-
handleServerProcessMessages();
|
|
291
|
-
return serverProcess;
|
|
292
|
-
};
|
|
293
|
-
const restartApplicationProcess = async (sessionsBeforeHMRUpdate = null) => {
|
|
294
|
-
if (process.serverProcess && process.serverProcess.pid) {
|
|
295
|
-
process.loader.text("Restarting app...");
|
|
296
|
-
process.serverProcess.kill();
|
|
297
|
-
startApplicationProcess(sessionsBeforeHMRUpdate);
|
|
298
|
-
return Promise.resolve();
|
|
299
|
-
}
|
|
300
|
-
process.loader.text("Starting app...");
|
|
301
|
-
startApplicationProcess();
|
|
302
|
-
if (!process.hmrProcess) {
|
|
303
|
-
startHMRProcess();
|
|
304
|
-
}
|
|
305
|
-
};
|
|
306
|
-
const initialBuild = async (buildSettings = {}) => {
|
|
307
|
-
const buildPath = `.joystick/build`;
|
|
308
|
-
const fileMapPath = `.joystick/build/fileMap.json`;
|
|
309
|
-
if (!fs.existsSync(buildPath)) {
|
|
310
|
-
fs.mkdirSync(".joystick/build");
|
|
311
|
-
}
|
|
312
|
-
if (fs.existsSync(fileMapPath)) {
|
|
313
|
-
fs.unlinkSync(fileMapPath);
|
|
314
|
-
}
|
|
315
|
-
process.loader.text("Building app...");
|
|
316
|
-
await requiredFileCheck();
|
|
317
|
-
const filesToBuild = getFilesToBuild(buildSettings?.excludedPaths, "start");
|
|
318
|
-
const fileResults = await buildFiles(
|
|
319
|
-
filesToBuild,
|
|
320
|
-
null,
|
|
321
|
-
process.env.NODE_ENV
|
|
322
|
-
);
|
|
323
|
-
const hasErrors = [...fileResults].filter((result) => !!result).map(({ success }) => success).includes(false);
|
|
324
|
-
if (!hasErrors) {
|
|
325
|
-
startApplicationProcess();
|
|
326
|
-
startHMRProcess();
|
|
327
|
-
}
|
|
328
|
-
};
|
|
329
|
-
const startWatcher = async (buildSettings = {}) => {
|
|
330
|
-
await initialBuild(buildSettings);
|
|
331
|
-
const watcher = chokidar.watch(
|
|
332
|
-
watchlist.map(({ path: path2 }) => path2),
|
|
333
|
-
{
|
|
334
|
-
ignoreInitial: true
|
|
335
|
-
}
|
|
336
|
-
);
|
|
337
|
-
watcher.on("all", async (event, path2) => {
|
|
338
|
-
await requiredFileCheck();
|
|
339
|
-
process.loader.text("Rebuilding app...");
|
|
340
|
-
const isHTMLUpdate = path2 === "index.html";
|
|
341
|
-
const isUIPath = path2?.includes("ui/") || path2 === "index.css" || isHTMLUpdate;
|
|
342
|
-
const isUIUpdate = process.hmrProcess.hasConnections && isUIPath || false;
|
|
343
|
-
if (["addDir"].includes(event) && fs.existsSync(path2) && fs.lstatSync(path2).isDirectory() && !fs.existsSync(`./.joystick/build/${path2}`)) {
|
|
344
|
-
fs.mkdirSync(`./.joystick/build/${path2}`);
|
|
345
|
-
if (isUIUpdate) {
|
|
346
|
-
notifyHMRClients(isHTMLUpdate);
|
|
347
|
-
} else {
|
|
348
|
-
restartApplicationProcess();
|
|
349
|
-
}
|
|
350
|
-
return;
|
|
351
|
-
}
|
|
352
|
-
if (!!filesToCopy.find((fileToCopy) => fileToCopy.path === path2)) {
|
|
353
|
-
const isDirectory = fs.statSync(path2).isDirectory();
|
|
354
|
-
if (isDirectory && !fs.existsSync(`./.joystick/build/${path2}`)) {
|
|
355
|
-
fs.mkdirSync(`./.joystick/build/${path2}`);
|
|
356
|
-
}
|
|
357
|
-
if (!isDirectory) {
|
|
358
|
-
fs.writeFileSync(`./.joystick/build/${path2}`, fs.readFileSync(path2));
|
|
359
|
-
}
|
|
360
|
-
loadSettings(process.env.NODE_ENV);
|
|
361
|
-
if (isUIUpdate) {
|
|
362
|
-
notifyHMRClients(isHTMLUpdate);
|
|
363
|
-
} else {
|
|
364
|
-
restartApplicationProcess();
|
|
365
|
-
}
|
|
366
|
-
return;
|
|
367
|
-
}
|
|
368
|
-
if (["add", "change"].includes(event) && fs.existsSync(path2)) {
|
|
369
|
-
const codependencies = getCodependenciesForFile(path2);
|
|
370
|
-
const fileResults = await buildFiles(
|
|
371
|
-
[path2, ...codependencies?.existing || []],
|
|
372
|
-
null,
|
|
373
|
-
process.env.NODE_ENV
|
|
374
|
-
);
|
|
375
|
-
const fileResultsHaveErrors = fileResults.filter((result) => !!result).map(({ success }) => success).includes(false);
|
|
376
|
-
removeDeletedDependenciesFromMap(codependencies.deleted);
|
|
377
|
-
const hasErrors = fileResultsHaveErrors;
|
|
378
|
-
if (process.serverProcess && hasErrors) {
|
|
379
|
-
process.serverProcess.send(
|
|
380
|
-
JSON.stringify({
|
|
381
|
-
error: "BUILD_ERROR",
|
|
382
|
-
paths: fileResults.filter(({ success }) => !success).map(({ path: pathWithError, error }) => ({
|
|
383
|
-
path: pathWithError,
|
|
384
|
-
error
|
|
385
|
-
}))
|
|
386
|
-
})
|
|
387
|
-
);
|
|
388
|
-
return;
|
|
389
|
-
}
|
|
390
|
-
if (!hasErrors) {
|
|
391
|
-
process.initialBuildComplete = true;
|
|
392
|
-
if (isUIUpdate) {
|
|
393
|
-
notifyHMRClients(isHTMLUpdate);
|
|
394
|
-
} else {
|
|
395
|
-
restartApplicationProcess();
|
|
396
|
-
}
|
|
397
|
-
return;
|
|
398
|
-
}
|
|
399
|
-
}
|
|
400
|
-
if (["unlink", "unlinkDir"].includes(event) && !fs.existsSync(`./.joystick/build/${path2}`)) {
|
|
401
|
-
if (isUIUpdate) {
|
|
402
|
-
notifyHMRClients(isHTMLUpdate);
|
|
403
|
-
} else {
|
|
404
|
-
restartApplicationProcess();
|
|
405
|
-
}
|
|
406
|
-
return;
|
|
407
|
-
}
|
|
408
|
-
if (["unlink", "unlinkDir"].includes(event) && fs.existsSync(`./.joystick/build/${path2}`)) {
|
|
409
|
-
const pathToUnlink = `./.joystick/build/${path2}`;
|
|
410
|
-
const stats = fs.lstatSync(pathToUnlink);
|
|
411
|
-
if (stats.isDirectory()) {
|
|
412
|
-
fs.rmdirSync(pathToUnlink, { recursive: true });
|
|
413
|
-
}
|
|
414
|
-
if (stats.isFile()) {
|
|
415
|
-
fs.unlinkSync(pathToUnlink);
|
|
416
|
-
}
|
|
417
|
-
if (isUIUpdate) {
|
|
418
|
-
notifyHMRClients(isHTMLUpdate);
|
|
419
|
-
} else {
|
|
420
|
-
restartApplicationProcess();
|
|
421
|
-
}
|
|
422
|
-
return;
|
|
423
|
-
}
|
|
424
|
-
});
|
|
425
|
-
};
|
|
426
|
-
const startDatabase = async (database = {}, databasePort = 2610, hasMultipleOfProvider = false) => {
|
|
427
|
-
process._databases = {
|
|
428
|
-
...process._databases || {},
|
|
429
|
-
[database.provider]: !hasMultipleOfProvider ? await startDatabaseProvider(database, databasePort) : {
|
|
430
|
-
...process._databases && process._databases[database.provider] || {},
|
|
431
|
-
[database?.name || `${database.provider}_${databasePort}`]: await startDatabaseProvider(database, databasePort)
|
|
432
|
-
}
|
|
433
|
-
};
|
|
434
|
-
return Promise.resolve(process._databases);
|
|
435
|
-
};
|
|
436
|
-
const startDatabases = async (databasePortStart = 2610) => {
|
|
437
|
-
try {
|
|
438
|
-
const hasSettings = !!process.env.JOYSTICK_SETTINGS;
|
|
439
|
-
const settings = hasSettings && JSON.parse(process.env.JOYSTICK_SETTINGS);
|
|
440
|
-
const databases = settings?.config?.databases || [];
|
|
441
|
-
if (databases && Array.isArray(databases) && databases.length > 0) {
|
|
442
|
-
validateDatabasesFromSettings(databases);
|
|
443
|
-
for (let i = 0; i < databases?.length; i += 1) {
|
|
444
|
-
const database = databases[i];
|
|
445
|
-
const hasMultipleOfProvider = databases?.filter((database2) => database2?.provider === database2?.provider)?.length > 1;
|
|
446
|
-
await startDatabase(database, databasePortStart + i, hasMultipleOfProvider);
|
|
447
|
-
}
|
|
448
|
-
return Promise.resolve();
|
|
449
|
-
}
|
|
450
|
-
return Promise.resolve();
|
|
451
|
-
} catch (exception) {
|
|
452
|
-
console.warn(exception);
|
|
453
|
-
}
|
|
454
|
-
};
|
|
455
|
-
const loadSettings = () => {
|
|
456
|
-
const environment = process.env.NODE_ENV;
|
|
457
|
-
const settingsFilePath = `${process.cwd()}/settings.${environment}.json`;
|
|
458
|
-
const hasSettingsFile = fs.existsSync(settingsFilePath);
|
|
459
|
-
if (!hasSettingsFile) {
|
|
460
|
-
CLILog(
|
|
461
|
-
`A settings file could not be found for this environment (${environment}). Create a settings.${environment}.json file at the root of your project and restart Joystick.`,
|
|
462
|
-
{
|
|
463
|
-
level: "danger",
|
|
464
|
-
docs: "https://github.com/cheatcode/joystick#settings"
|
|
465
|
-
}
|
|
466
|
-
);
|
|
467
|
-
process.exit(0);
|
|
468
|
-
}
|
|
469
|
-
const rawSettingsFile = fs.readFileSync(settingsFilePath, "utf-8");
|
|
470
|
-
const isValidJSON = isValidJSONString(rawSettingsFile);
|
|
471
|
-
if (!isValidJSON) {
|
|
472
|
-
CLILog(
|
|
473
|
-
`Failed to parse settings file. Double-check the syntax in your settings.${environment}.json file at the root of your project and restart Joystick.`,
|
|
474
|
-
{
|
|
475
|
-
level: "danger",
|
|
476
|
-
docs: "https://github.com/cheatcode/joystick#settings",
|
|
477
|
-
tools: [{ title: "JSON Linter", url: "https://jsonlint.com/" }]
|
|
478
|
-
}
|
|
479
|
-
);
|
|
480
|
-
process.exit(0);
|
|
481
|
-
}
|
|
482
|
-
const settingsFile = isValidJSON ? rawSettingsFile : "{}";
|
|
483
|
-
process.env.JOYSTICK_SETTINGS = settingsFile;
|
|
484
|
-
return JSON.parse(settingsFile);
|
|
485
|
-
};
|
|
486
|
-
const checkIfJoystickProject = () => {
|
|
487
|
-
return fs.existsSync(`${process.cwd()}/.joystick`);
|
|
488
|
-
};
|
|
489
21
|
var start_default = async (args = {}, options = {}) => {
|
|
22
|
+
const port = options?.port ? parseInt(options?.port) : 2600;
|
|
490
23
|
await dev({
|
|
491
|
-
environment:
|
|
492
|
-
process
|
|
24
|
+
environment: args?.environment || "development",
|
|
25
|
+
process,
|
|
26
|
+
port
|
|
493
27
|
});
|
|
494
28
|
};
|
|
495
29
|
export {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import chalk from "chalk";
|
|
2
2
|
import { OBJECT_REGEX } from "../../lib/regexes.js";
|
|
3
3
|
import rainbowRoad from "../../lib/rainbowRoad.js";
|
|
4
|
-
import getCodeFrame from "../../lib/getCodeFrame.js";
|
|
4
|
+
import getCodeFrame from "../../lib/build/getCodeFrame.js";
|
|
5
5
|
const removeLocationDataFromStackTrace = (stackTrace = "") => {
|
|
6
6
|
return stackTrace.replace(OBJECT_REGEX, "");
|
|
7
7
|
};
|
|
@@ -8,6 +8,37 @@ import browserPathExclusions from "./browserPathExclusions.js";
|
|
|
8
8
|
import nodePaths from "./nodePaths.js";
|
|
9
9
|
import nodePathExclusions from "./nodePathExclusions.js";
|
|
10
10
|
import buildPlugins from "./buildPlugins.js";
|
|
11
|
+
import getCodeFrame from "./getCodeFrame.js";
|
|
12
|
+
import onWarn from "./onWarn.js";
|
|
13
|
+
const handleBuildException = (exception = {}, file = "") => {
|
|
14
|
+
try {
|
|
15
|
+
const error = exception?.errors && exception?.errors[0];
|
|
16
|
+
const snippet = fs.existsSync(file) ? getCodeFrame(file, {
|
|
17
|
+
line: error?.location?.line,
|
|
18
|
+
column: error?.location?.column
|
|
19
|
+
}) : null;
|
|
20
|
+
onWarn({
|
|
21
|
+
file,
|
|
22
|
+
stack: exception?.stack,
|
|
23
|
+
line: error?.location?.line,
|
|
24
|
+
column: error?.location?.column,
|
|
25
|
+
snippet,
|
|
26
|
+
lineWithError: error?.location?.lineText?.trim(),
|
|
27
|
+
message: error?.text
|
|
28
|
+
});
|
|
29
|
+
return snippet;
|
|
30
|
+
} catch (exception2) {
|
|
31
|
+
throw new Error(`[actionName.handleBuildException] ${exception2.message}`);
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
const handleParseFilePathFromException = (exception = {}) => {
|
|
35
|
+
try {
|
|
36
|
+
const rawErrorMessage = exception?.message?.split(":");
|
|
37
|
+
return rawErrorMessage[1] && rawErrorMessage[1]?.replace("\n", "") || "";
|
|
38
|
+
} catch (exception2) {
|
|
39
|
+
throw new Error(`[actionName.handleParseFilePathFromException] ${exception2.message}`);
|
|
40
|
+
}
|
|
41
|
+
};
|
|
11
42
|
const handleBuildForNode = (nodePaths2 = [], options = {}) => {
|
|
12
43
|
try {
|
|
13
44
|
return esbuild.build({
|
|
@@ -60,7 +91,7 @@ const handleCopyFiles = (files = [], outputPath = "") => {
|
|
|
60
91
|
for (let i = 0; i < files?.length; i += 1) {
|
|
61
92
|
const file = files[i];
|
|
62
93
|
const fileContents = fs.readFileSync(file.path);
|
|
63
|
-
fs.
|
|
94
|
+
fs.outputFileSync(
|
|
64
95
|
`${outputPath || "./.joystick/build"}/${file.path}`,
|
|
65
96
|
fileContents
|
|
66
97
|
);
|
|
@@ -71,7 +102,7 @@ const handleCopyFiles = (files = [], outputPath = "") => {
|
|
|
71
102
|
};
|
|
72
103
|
const isNodePath = (path = "") => {
|
|
73
104
|
try {
|
|
74
|
-
return nodePaths.some((nodePath) => {
|
|
105
|
+
return !isNotJavaScript(path) && nodePaths.some((nodePath) => {
|
|
75
106
|
return path.includes(nodePath);
|
|
76
107
|
}) && !nodePathExclusions.some((nodeExclusionPath) => {
|
|
77
108
|
return path.includes(nodeExclusionPath);
|
|
@@ -82,7 +113,7 @@ const isNodePath = (path = "") => {
|
|
|
82
113
|
};
|
|
83
114
|
const isBrowserPath = (path = "") => {
|
|
84
115
|
try {
|
|
85
|
-
return browserPaths.some((browserPath) => {
|
|
116
|
+
return !isNotJavaScript(path) && browserPaths.some((browserPath) => {
|
|
86
117
|
return path.includes(browserPath);
|
|
87
118
|
}) && !browserPathExclusions.some((browserExclusionPath) => {
|
|
88
119
|
return path.includes(browserExclusionPath);
|
|
@@ -161,16 +192,41 @@ const buildFiles = async (options, { resolve, reject }) => {
|
|
|
161
192
|
const browserFiles = filesWithPlatform?.filter((file) => file?.platform === "browser");
|
|
162
193
|
const nodeFiles = filesWithPlatform?.filter((file) => file?.platform === "node");
|
|
163
194
|
handleCopyFiles(copyFiles, options?.outputPath);
|
|
164
|
-
await Promise.all([
|
|
165
|
-
handleBuildForBrowser(browserFiles, options)
|
|
166
|
-
|
|
195
|
+
const fileResults = await Promise.all([
|
|
196
|
+
handleBuildForBrowser(browserFiles, options).then(() => {
|
|
197
|
+
return { success: true };
|
|
198
|
+
}).catch((exception) => {
|
|
199
|
+
const file = handleParseFilePathFromException(exception);
|
|
200
|
+
console.log(file, exception);
|
|
201
|
+
const snippet = handleBuildException(exception, file);
|
|
202
|
+
return {
|
|
203
|
+
success: false,
|
|
204
|
+
path: file,
|
|
205
|
+
error: {
|
|
206
|
+
stack: exception?.stack,
|
|
207
|
+
snippet
|
|
208
|
+
}
|
|
209
|
+
};
|
|
210
|
+
}),
|
|
211
|
+
handleBuildForNode(nodeFiles, options).catch((exception) => {
|
|
212
|
+
const file = handleParseFilePathFromException(exception);
|
|
213
|
+
const snippet = handleBuildException(exception, file);
|
|
214
|
+
return {
|
|
215
|
+
success: false,
|
|
216
|
+
path: file,
|
|
217
|
+
error: {
|
|
218
|
+
stack: exception?.stack,
|
|
219
|
+
snippet
|
|
220
|
+
}
|
|
221
|
+
};
|
|
222
|
+
})
|
|
167
223
|
]);
|
|
168
224
|
if (options?.environment !== "development") {
|
|
169
225
|
await Promise.all([browserFiles, nodeFiles].map((file) => {
|
|
170
226
|
return minifyFile(`${options?.outputPath || "./.joystick/build"}/${file.path}`);
|
|
171
227
|
}));
|
|
172
228
|
}
|
|
173
|
-
resolve();
|
|
229
|
+
resolve(fileResults);
|
|
174
230
|
} catch (exception) {
|
|
175
231
|
reject(`[buildFiles] ${exception.message}`);
|
|
176
232
|
}
|
|
@@ -114,21 +114,24 @@ var buildPlugins_default = {
|
|
|
114
114
|
});
|
|
115
115
|
build.onEnd(() => {
|
|
116
116
|
return new Promise((resolve) => {
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
117
|
+
for (let i = 0; i < build?.initialOptions?.entryPoints?.length; i += 1) {
|
|
118
|
+
const entryPoint = build?.initialOptions?.entryPoints[i];
|
|
119
|
+
const shouldSetComponentId = [
|
|
120
|
+
getPlatformSafePath("ui/"),
|
|
121
|
+
getPlatformSafePath("email/")
|
|
122
|
+
].some((bootstrapTarget) => {
|
|
123
|
+
return entryPoint.includes(bootstrapTarget);
|
|
124
|
+
});
|
|
125
|
+
if (shouldSetComponentId) {
|
|
126
|
+
const file = fs.readFileSync(`${build?.initialOptions?.outdir}/${entryPoint}`, "utf-8");
|
|
127
|
+
const joystickUIMatches = file?.match(JOYSTICK_COMPONENT_REGEX) || [];
|
|
128
|
+
if (joystickUIMatches?.length > 0) {
|
|
129
|
+
let contents = setComponentId(file)?.replace(
|
|
130
|
+
/\.component\(\/\*\*\//g,
|
|
131
|
+
".component("
|
|
132
|
+
);
|
|
133
|
+
fs.writeFileSync(`${build?.initialOptions?.outdir}/${entryPoint}`, contents);
|
|
134
|
+
}
|
|
132
135
|
}
|
|
133
136
|
}
|
|
134
137
|
resolve();
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import fs from "fs";
|
|
2
2
|
import { codeFrameColumns } from "@babel/code-frame";
|
|
3
|
-
var getCodeFrame_default = (
|
|
4
|
-
const file = fs.readFileSync(
|
|
5
|
-
|
|
6
|
-
return frame;
|
|
3
|
+
var getCodeFrame_default = (path = "", location = {}) => {
|
|
4
|
+
const file = fs.readFileSync(path, "utf-8");
|
|
5
|
+
return codeFrameColumns(file, { start: location });
|
|
7
6
|
};
|
|
8
7
|
export {
|
|
9
8
|
getCodeFrame_default as default
|
package/dist/lib/build/onWarn.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import chalk from "chalk";
|
|
2
2
|
import { OBJECT_REGEX } from "../regexes.js";
|
|
3
3
|
import rainbowRoad from "../rainbowRoad.js";
|
|
4
|
-
import getCodeFrame from "
|
|
4
|
+
import getCodeFrame from "./getCodeFrame.js";
|
|
5
5
|
const removeLocationDataFromStackTrace = (stackTrace = "") => {
|
|
6
6
|
return stackTrace.replace(OBJECT_REGEX, "");
|
|
7
7
|
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import fs from "fs";
|
|
2
|
-
import readFileDependencyMap from "
|
|
2
|
+
import readFileDependencyMap from "../dev/readFileDependencyMap.js";
|
|
3
3
|
var removeDeletedDependenciesFromMap_default = (deletedDependencies = []) => {
|
|
4
4
|
const fileDependencyMap = readFileDependencyMap();
|
|
5
5
|
deletedDependencies.forEach((dependency) => {
|