@vention/vention-cli 0.6.1 → 0.8.0
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/cli.esm.js +59 -2
- package/package.json +1 -1
- package/src/file-system.d.ts +3 -0
package/cli.esm.js
CHANGED
|
@@ -165,6 +165,9 @@ const shouldIgnoreFileSystemNode = (nodeName, ignoredNodes) => {
|
|
|
165
165
|
}
|
|
166
166
|
return false;
|
|
167
167
|
};
|
|
168
|
+
const getSafeAppName = (appName) => {
|
|
169
|
+
return appName.replace(/[^a-zA-Z0-9-_]/g, "_");
|
|
170
|
+
};
|
|
168
171
|
const serializeFileSystem = (sourceDirectory, ignoredFileSystemNodes, shouldBase64Encoded) => {
|
|
169
172
|
const fileSystemNode = {};
|
|
170
173
|
const directoryContents = fs.readdirSync(sourceDirectory);
|
|
@@ -228,12 +231,17 @@ const checkIfDirectoryExists = async (directory) => {
|
|
|
228
231
|
.catch(() => false);
|
|
229
232
|
return exists;
|
|
230
233
|
};
|
|
234
|
+
const checkIfAppDirectoryExists = async (appName, targetDirectory) => {
|
|
235
|
+
const safeAppName = appName.replace(/[^a-zA-Z0-9-_]/g, "_");
|
|
236
|
+
const appDirectoryPath = path.join(targetDirectory, safeAppName);
|
|
237
|
+
return await checkIfDirectoryExists(appDirectoryPath);
|
|
238
|
+
};
|
|
231
239
|
const writeApplicationToDisk = async (appName, sourceCode, targetDirectory, overwriteExisting = false) => {
|
|
232
240
|
if (overwriteExisting) {
|
|
233
241
|
await createFileSystemFromJson(sourceCode, targetDirectory);
|
|
234
242
|
return targetDirectory;
|
|
235
243
|
}
|
|
236
|
-
const safeAppName = appName
|
|
244
|
+
const safeAppName = getSafeAppName(appName);
|
|
237
245
|
const appDirectoryPath = path.join(targetDirectory, safeAppName);
|
|
238
246
|
await createFileSystemFromJson(sourceCode, appDirectoryPath);
|
|
239
247
|
return appDirectoryPath;
|
|
@@ -249,6 +257,7 @@ const getAppFromDigitalTwin = async (session, appId, appName) => {
|
|
|
249
257
|
const allApplications = await getAllApplicationsWithSourceCode(session);
|
|
250
258
|
const targetApp = allApplications.find((app) => app.id === appId);
|
|
251
259
|
if (!targetApp) {
|
|
260
|
+
console.log();
|
|
252
261
|
console.error(chalk.red(`Application "${appName}" (ID: ${appId}) not found in the digital twin.`));
|
|
253
262
|
process.exit(1);
|
|
254
263
|
}
|
|
@@ -264,14 +273,17 @@ const createNewAppDirectory = async (session, currentDir) => {
|
|
|
264
273
|
process.exit(1);
|
|
265
274
|
}
|
|
266
275
|
const linkedAllocation = await checkIfDesignHasLiveAllocation(session, session.linkedDesignId);
|
|
276
|
+
console.log();
|
|
267
277
|
console.log(chalk.blue(`You are currently linked to design: ${linkedAllocation === null || linkedAllocation === void 0 ? void 0 : linkedAllocation.designName}`));
|
|
268
278
|
if (!linkedAllocation) {
|
|
279
|
+
console.log();
|
|
269
280
|
console.error(chalk.red("Sorry, it seems you do not have that design open with the MachineLogic tab selected."));
|
|
270
281
|
console.error(chalk.red("Please go to your browser, open your design, and navigate to the MachineLogic page."));
|
|
271
282
|
process.exit(1);
|
|
272
283
|
}
|
|
273
284
|
const availableApps = await getAvailableAppsFromDigitalTwin(session);
|
|
274
285
|
if (availableApps.length === 0) {
|
|
286
|
+
console.log();
|
|
275
287
|
console.log(chalk.yellow("No machine code applications found in the digital twin"));
|
|
276
288
|
process.exit(1);
|
|
277
289
|
}
|
|
@@ -282,11 +294,22 @@ const createNewAppDirectory = async (session, currentDir) => {
|
|
|
282
294
|
value: app,
|
|
283
295
|
})),
|
|
284
296
|
});
|
|
297
|
+
console.log();
|
|
285
298
|
console.log(chalk.blue(`\nPulling application "${selectedApp.name}"...`));
|
|
286
299
|
if (!selectedApp.sourceCode) {
|
|
300
|
+
console.log();
|
|
287
301
|
console.log(chalk.yellow("No source code found for this application."));
|
|
288
302
|
process.exit(1);
|
|
289
303
|
}
|
|
304
|
+
const appDirectoryExists = await checkIfAppDirectoryExists(selectedApp.name, currentDir);
|
|
305
|
+
const safeAppName = getSafeAppName(selectedApp.name);
|
|
306
|
+
if (appDirectoryExists) {
|
|
307
|
+
console.log();
|
|
308
|
+
console.error(chalk.red(`You already have a directory with name "${safeAppName}" here.`));
|
|
309
|
+
console.error(chalk.red("If that is the machine code app you are trying to pull, please navigate to the root folder of the app and run the 'vention pull' command from there."));
|
|
310
|
+
console.error(chalk.red("If not, please rename that directory and try again."));
|
|
311
|
+
process.exit(1);
|
|
312
|
+
}
|
|
290
313
|
const appDirectoryPath = await writeApplicationToDisk(selectedApp.name, selectedApp.sourceCode, currentDir);
|
|
291
314
|
await writeMachineCodeAppDirectoryInfo(appDirectoryPath, {
|
|
292
315
|
appName: selectedApp.name,
|
|
@@ -296,9 +319,10 @@ const createNewAppDirectory = async (session, currentDir) => {
|
|
|
296
319
|
environment: session.environment,
|
|
297
320
|
uuid: selectedApp.uuid,
|
|
298
321
|
});
|
|
322
|
+
console.log();
|
|
299
323
|
console.log(chalk.green(`✅ Successfully pulled "${selectedApp.name}" to: ${appDirectoryPath}`));
|
|
300
324
|
console.log(chalk.blue(`📁 To navigate to your project, run:`));
|
|
301
|
-
console.log(chalk.cyan(`cd "${
|
|
325
|
+
console.log(chalk.cyan(`cd "${safeAppName}"`));
|
|
302
326
|
console.log(chalk.blue("💡 You can now start working on your application!"));
|
|
303
327
|
};
|
|
304
328
|
const updateExistingAppDirectory = async (session, projectState, currentDir) => {
|
|
@@ -306,6 +330,7 @@ const updateExistingAppDirectory = async (session, projectState, currentDir) =>
|
|
|
306
330
|
console.log(chalk.blue(`Design ID: ${projectState.designId}, App ID: ${projectState.applicationId}`));
|
|
307
331
|
const linkedAllocation = await checkIfDesignHasLiveAllocation(session, projectState.designId);
|
|
308
332
|
if (!linkedAllocation) {
|
|
333
|
+
console.log();
|
|
309
334
|
console.error(chalk.red("Sorry, it seems you do not have that design open with the MachineLogic tab selected."));
|
|
310
335
|
console.error(chalk.red("Please go to your browser, open your design, and navigate to the MachineLogic page."));
|
|
311
336
|
process.exit(1);
|
|
@@ -314,12 +339,25 @@ const updateExistingAppDirectory = async (session, projectState, currentDir) =>
|
|
|
314
339
|
const appWithSourceCode = await getAppFromDigitalTwin(session, projectState.applicationId, projectState.appName);
|
|
315
340
|
await writeApplicationToDisk(appWithSourceCode.name, appWithSourceCode.sourceCode, currentDir, true);
|
|
316
341
|
await writeMachineCodeAppDirectoryInfo(currentDir, Object.assign(Object.assign({}, projectState), { lastPulledAt: new Date().toISOString() }));
|
|
342
|
+
console.log();
|
|
317
343
|
console.log(chalk.green(`✅ Successfully pulled "${appWithSourceCode.name}" to: ${currentDir}`));
|
|
318
344
|
console.log(chalk.blue("💡 Your project has been updated with the latest changes!"));
|
|
319
345
|
};
|
|
320
346
|
|
|
321
347
|
const program = new Command();
|
|
322
348
|
program.name("vention").description("CLI tool for Vention").version("0.2.0");
|
|
349
|
+
const ventionLogo = `
|
|
350
|
+
╔════════════════════════════════════════════════════════════════════════════════════════════════════════╗
|
|
351
|
+
║ ║
|
|
352
|
+
║ ██╗ ██╗███████╗███╗ ██╗████████╗██╗ ██████╗ ███╗ ██╗ ██████╗██╗ ██╗ ║
|
|
353
|
+
║ ██║ ██║██╔════╝████╗ ██║╚══██╔══╝██║██╔═══██╗████╗ ██║ ██╔════╝██║ ██║ ║
|
|
354
|
+
║ ██║ ██║█████╗ ██╔██╗ ██║ ██║ ██║██║ ██║██╔██╗ ██║ ██║ ██║ ██║ ║
|
|
355
|
+
║ ╚██╗ ██╔╝██╔══╝ ██║╚██╗██║ ██║ ██║██║ ██║██║╚██╗██║ ██║ ██║ ██║ ║
|
|
356
|
+
║ ╚████╔╝ ███████╗██║ ╚████║ ██║ ██║╚██████╔╝██║ ╚████║ ╚██████╗███████╗██║ ║
|
|
357
|
+
║ ╚═══╝ ╚══════╝╚═╝ ╚═══╝ ╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚═══╝ ╚═════╝╚══════╝╚═╝ ║
|
|
358
|
+
║ ║
|
|
359
|
+
╚════════════════════════════════════════════════════════════════════════════════════════════════════════╝
|
|
360
|
+
`;
|
|
323
361
|
program
|
|
324
362
|
.command("login")
|
|
325
363
|
.description("Login to Vention")
|
|
@@ -354,9 +392,11 @@ program
|
|
|
354
392
|
: undefined;
|
|
355
393
|
await saveSession(Object.assign({ environment,
|
|
356
394
|
ventionSession }, (environment !== "local" ? { stytchSessionJwt, ventionIdpSession } : {})));
|
|
395
|
+
console.log();
|
|
357
396
|
console.log(chalk.green("Successfully logged in!"));
|
|
358
397
|
}
|
|
359
398
|
catch (error) {
|
|
399
|
+
console.log();
|
|
360
400
|
console.error(chalk.red("Login failed:"), error);
|
|
361
401
|
process.exit(1);
|
|
362
402
|
}
|
|
@@ -373,6 +413,7 @@ program
|
|
|
373
413
|
}
|
|
374
414
|
const allocations = await getUserAllocations(session);
|
|
375
415
|
if (allocations.length === 0) {
|
|
416
|
+
console.log();
|
|
376
417
|
console.log(chalk.yellow("No active allocations found. Please open a design and navigate to the machine logic tab to activate a digital twin."));
|
|
377
418
|
process.exit(1);
|
|
378
419
|
}
|
|
@@ -384,9 +425,11 @@ program
|
|
|
384
425
|
})),
|
|
385
426
|
});
|
|
386
427
|
await saveSession(Object.assign(Object.assign({}, session), { linkedDesignId: selectedDesign.id, linkedSessionToken: selectedDesign.sessionId }));
|
|
428
|
+
console.log();
|
|
387
429
|
console.log(chalk.green(`\nSuccessfully linked to design "${selectedDesign.name}" (ID: ${selectedDesign.id})`));
|
|
388
430
|
}
|
|
389
431
|
catch (error) {
|
|
432
|
+
console.log();
|
|
390
433
|
console.error(chalk.red("Failed to get allocations:"));
|
|
391
434
|
console.error(chalk.red(`Error: ${error instanceof Error ? error.message : String(error)}`));
|
|
392
435
|
process.exit(1);
|
|
@@ -409,14 +452,17 @@ program
|
|
|
409
452
|
const allocations = await getUserAllocations(session);
|
|
410
453
|
const linkedAllocation = allocations.find(a => a.designId === session.linkedDesignId);
|
|
411
454
|
if (!linkedAllocation) {
|
|
455
|
+
console.log();
|
|
412
456
|
console.error(chalk.red("Linked design is not currently allocated. Please check if the digital twin is running."));
|
|
413
457
|
process.exit(1);
|
|
414
458
|
}
|
|
415
459
|
const digitalTwinResponse = await makeTestRequestToLinkedDigitalTwin(session);
|
|
460
|
+
console.log();
|
|
416
461
|
console.log(chalk.green("Digital twin response:"));
|
|
417
462
|
console.log(chalk.green(JSON.stringify(digitalTwinResponse, null, 2)));
|
|
418
463
|
}
|
|
419
464
|
catch (error) {
|
|
465
|
+
console.log();
|
|
420
466
|
console.error(chalk.red("Failed to get digital twin response:"));
|
|
421
467
|
console.error(chalk.red(`Error: ${error instanceof Error ? error.message : String(error)}`));
|
|
422
468
|
process.exit(1);
|
|
@@ -443,6 +489,7 @@ program
|
|
|
443
489
|
}
|
|
444
490
|
}
|
|
445
491
|
catch (error) {
|
|
492
|
+
console.log();
|
|
446
493
|
console.error(chalk.red("Failed to pull application:"));
|
|
447
494
|
console.error(chalk.red(`Error: ${error instanceof Error ? error.message : String(error)}`));
|
|
448
495
|
process.exit(1);
|
|
@@ -461,19 +508,23 @@ program
|
|
|
461
508
|
const currentDir = process.cwd();
|
|
462
509
|
const machineCodeAppDirectoryInfo = await readMachineCodeAppDirectoryInfo(currentDir);
|
|
463
510
|
if (!machineCodeAppDirectoryInfo) {
|
|
511
|
+
console.log();
|
|
464
512
|
console.error(chalk.red("Not in a machine code application directory. Please run 'vention pull' first to create a project."));
|
|
465
513
|
console.error(chalk.red("Make sure you are in the root directory of a machine code application you have created using the 'vention pull' command."));
|
|
466
514
|
process.exit(1);
|
|
467
515
|
}
|
|
516
|
+
console.log();
|
|
468
517
|
console.log(chalk.blue(`Pushing changes for project: ${machineCodeAppDirectoryInfo.appName}`));
|
|
469
518
|
console.log(chalk.blue(`Design ID: ${machineCodeAppDirectoryInfo.designId}, App ID: ${machineCodeAppDirectoryInfo.applicationId}`));
|
|
470
519
|
const linkedAllocation = await checkIfDesignHasLiveAllocation(session, machineCodeAppDirectoryInfo.designId);
|
|
471
520
|
if (!linkedAllocation) {
|
|
521
|
+
console.log();
|
|
472
522
|
console.error(chalk.red("Sorry, it seems you do not have that design open with the MachineLogic tab selected."));
|
|
473
523
|
console.error(chalk.red("Please go to your browser, open your design, and navigate to the MachineLogic page."));
|
|
474
524
|
process.exit(1);
|
|
475
525
|
}
|
|
476
526
|
await saveSession(Object.assign(Object.assign({}, session), { linkedDesignId: machineCodeAppDirectoryInfo.designId, linkedSessionToken: linkedAllocation.sessionId }));
|
|
527
|
+
console.log();
|
|
477
528
|
console.log(chalk.blue("Serializing local files..."));
|
|
478
529
|
const ignorePatterns = getDefaultIgnorePatterns();
|
|
479
530
|
const serializedSourceCode = serializeFileSystem(currentDir, ignorePatterns, true);
|
|
@@ -487,10 +538,12 @@ program
|
|
|
487
538
|
console.log(chalk.blue("Pushing to digital twin..."));
|
|
488
539
|
await pushApplicationToDigitalTwin(session, applicationToPush);
|
|
489
540
|
await writeMachineCodeAppDirectoryInfo(currentDir, Object.assign(Object.assign({}, machineCodeAppDirectoryInfo), { lastPushedAt: new Date().toISOString() }));
|
|
541
|
+
console.log();
|
|
490
542
|
console.log(chalk.green(`✅ Successfully pushed "${machineCodeAppDirectoryInfo.appName}" to digital twin`));
|
|
491
543
|
console.log(chalk.blue("💡 Your changes have been uploaded!"));
|
|
492
544
|
}
|
|
493
545
|
catch (error) {
|
|
546
|
+
console.log();
|
|
494
547
|
console.error(chalk.red("Failed to push application:"));
|
|
495
548
|
console.error(chalk.red(`Error: ${error instanceof Error ? error.message : String(error)}`));
|
|
496
549
|
process.exit(1);
|
|
@@ -499,6 +552,10 @@ program
|
|
|
499
552
|
const resolvedArgv = realpathSync(process.argv[1]);
|
|
500
553
|
const resolvedUrl = new URL(import.meta.url).pathname;
|
|
501
554
|
if (resolvedArgv === resolvedUrl) {
|
|
555
|
+
const showLogoConditions = [process.argv.length <= 2, process.argv.includes("--help"), process.argv.includes("-h")];
|
|
556
|
+
if (showLogoConditions.some(Boolean)) {
|
|
557
|
+
console.log(chalk.cyan(ventionLogo));
|
|
558
|
+
}
|
|
502
559
|
program.parse(process.argv);
|
|
503
560
|
}
|
|
504
561
|
|
package/package.json
CHANGED
package/src/file-system.d.ts
CHANGED
|
@@ -3,6 +3,9 @@ export interface FileSystemNode {
|
|
|
3
3
|
}
|
|
4
4
|
export declare const getDefaultIgnorePatterns: () => Set<string | RegExp>;
|
|
5
5
|
export declare const shouldIgnoreFileSystemNode: (nodeName: string, ignoredNodes: Set<string | RegExp>) => boolean;
|
|
6
|
+
export declare const getSafeAppName: (appName: string) => string;
|
|
6
7
|
export declare const serializeFileSystem: (sourceDirectory: string, ignoredFileSystemNodes: Set<string | RegExp>, shouldBase64Encoded: boolean) => FileSystemNode;
|
|
7
8
|
export declare const createFileSystemFromJson: (fileSystemNode: FileSystemNode, targetDirectory: string) => Promise<void>;
|
|
9
|
+
export declare const checkIfDirectoryExists: (directory: string) => Promise<boolean>;
|
|
10
|
+
export declare const checkIfAppDirectoryExists: (appName: string, targetDirectory: string) => Promise<boolean>;
|
|
8
11
|
export declare const writeApplicationToDisk: (appName: string, sourceCode: FileSystemNode, targetDirectory: string, overwriteExisting?: boolean) => Promise<string>;
|