@vention/vention-cli 0.6.0 → 0.7.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/README.md +1 -1
- package/cli.esm.js +43 -2
- package/package.json +1 -1
- package/src/file-system.d.ts +3 -0
package/README.md
CHANGED
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,6 +339,7 @@ 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
|
};
|
|
@@ -354,9 +380,11 @@ program
|
|
|
354
380
|
: undefined;
|
|
355
381
|
await saveSession(Object.assign({ environment,
|
|
356
382
|
ventionSession }, (environment !== "local" ? { stytchSessionJwt, ventionIdpSession } : {})));
|
|
383
|
+
console.log();
|
|
357
384
|
console.log(chalk.green("Successfully logged in!"));
|
|
358
385
|
}
|
|
359
386
|
catch (error) {
|
|
387
|
+
console.log();
|
|
360
388
|
console.error(chalk.red("Login failed:"), error);
|
|
361
389
|
process.exit(1);
|
|
362
390
|
}
|
|
@@ -373,6 +401,7 @@ program
|
|
|
373
401
|
}
|
|
374
402
|
const allocations = await getUserAllocations(session);
|
|
375
403
|
if (allocations.length === 0) {
|
|
404
|
+
console.log();
|
|
376
405
|
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
406
|
process.exit(1);
|
|
378
407
|
}
|
|
@@ -384,9 +413,11 @@ program
|
|
|
384
413
|
})),
|
|
385
414
|
});
|
|
386
415
|
await saveSession(Object.assign(Object.assign({}, session), { linkedDesignId: selectedDesign.id, linkedSessionToken: selectedDesign.sessionId }));
|
|
416
|
+
console.log();
|
|
387
417
|
console.log(chalk.green(`\nSuccessfully linked to design "${selectedDesign.name}" (ID: ${selectedDesign.id})`));
|
|
388
418
|
}
|
|
389
419
|
catch (error) {
|
|
420
|
+
console.log();
|
|
390
421
|
console.error(chalk.red("Failed to get allocations:"));
|
|
391
422
|
console.error(chalk.red(`Error: ${error instanceof Error ? error.message : String(error)}`));
|
|
392
423
|
process.exit(1);
|
|
@@ -409,14 +440,17 @@ program
|
|
|
409
440
|
const allocations = await getUserAllocations(session);
|
|
410
441
|
const linkedAllocation = allocations.find(a => a.designId === session.linkedDesignId);
|
|
411
442
|
if (!linkedAllocation) {
|
|
443
|
+
console.log();
|
|
412
444
|
console.error(chalk.red("Linked design is not currently allocated. Please check if the digital twin is running."));
|
|
413
445
|
process.exit(1);
|
|
414
446
|
}
|
|
415
447
|
const digitalTwinResponse = await makeTestRequestToLinkedDigitalTwin(session);
|
|
448
|
+
console.log();
|
|
416
449
|
console.log(chalk.green("Digital twin response:"));
|
|
417
450
|
console.log(chalk.green(JSON.stringify(digitalTwinResponse, null, 2)));
|
|
418
451
|
}
|
|
419
452
|
catch (error) {
|
|
453
|
+
console.log();
|
|
420
454
|
console.error(chalk.red("Failed to get digital twin response:"));
|
|
421
455
|
console.error(chalk.red(`Error: ${error instanceof Error ? error.message : String(error)}`));
|
|
422
456
|
process.exit(1);
|
|
@@ -443,6 +477,7 @@ program
|
|
|
443
477
|
}
|
|
444
478
|
}
|
|
445
479
|
catch (error) {
|
|
480
|
+
console.log();
|
|
446
481
|
console.error(chalk.red("Failed to pull application:"));
|
|
447
482
|
console.error(chalk.red(`Error: ${error instanceof Error ? error.message : String(error)}`));
|
|
448
483
|
process.exit(1);
|
|
@@ -461,19 +496,23 @@ program
|
|
|
461
496
|
const currentDir = process.cwd();
|
|
462
497
|
const machineCodeAppDirectoryInfo = await readMachineCodeAppDirectoryInfo(currentDir);
|
|
463
498
|
if (!machineCodeAppDirectoryInfo) {
|
|
499
|
+
console.log();
|
|
464
500
|
console.error(chalk.red("Not in a machine code application directory. Please run 'vention pull' first to create a project."));
|
|
465
501
|
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
502
|
process.exit(1);
|
|
467
503
|
}
|
|
504
|
+
console.log();
|
|
468
505
|
console.log(chalk.blue(`Pushing changes for project: ${machineCodeAppDirectoryInfo.appName}`));
|
|
469
506
|
console.log(chalk.blue(`Design ID: ${machineCodeAppDirectoryInfo.designId}, App ID: ${machineCodeAppDirectoryInfo.applicationId}`));
|
|
470
507
|
const linkedAllocation = await checkIfDesignHasLiveAllocation(session, machineCodeAppDirectoryInfo.designId);
|
|
471
508
|
if (!linkedAllocation) {
|
|
509
|
+
console.log();
|
|
472
510
|
console.error(chalk.red("Sorry, it seems you do not have that design open with the MachineLogic tab selected."));
|
|
473
511
|
console.error(chalk.red("Please go to your browser, open your design, and navigate to the MachineLogic page."));
|
|
474
512
|
process.exit(1);
|
|
475
513
|
}
|
|
476
514
|
await saveSession(Object.assign(Object.assign({}, session), { linkedDesignId: machineCodeAppDirectoryInfo.designId, linkedSessionToken: linkedAllocation.sessionId }));
|
|
515
|
+
console.log();
|
|
477
516
|
console.log(chalk.blue("Serializing local files..."));
|
|
478
517
|
const ignorePatterns = getDefaultIgnorePatterns();
|
|
479
518
|
const serializedSourceCode = serializeFileSystem(currentDir, ignorePatterns, true);
|
|
@@ -487,10 +526,12 @@ program
|
|
|
487
526
|
console.log(chalk.blue("Pushing to digital twin..."));
|
|
488
527
|
await pushApplicationToDigitalTwin(session, applicationToPush);
|
|
489
528
|
await writeMachineCodeAppDirectoryInfo(currentDir, Object.assign(Object.assign({}, machineCodeAppDirectoryInfo), { lastPushedAt: new Date().toISOString() }));
|
|
529
|
+
console.log();
|
|
490
530
|
console.log(chalk.green(`✅ Successfully pushed "${machineCodeAppDirectoryInfo.appName}" to digital twin`));
|
|
491
531
|
console.log(chalk.blue("💡 Your changes have been uploaded!"));
|
|
492
532
|
}
|
|
493
533
|
catch (error) {
|
|
534
|
+
console.log();
|
|
494
535
|
console.error(chalk.red("Failed to push application:"));
|
|
495
536
|
console.error(chalk.red(`Error: ${error instanceof Error ? error.message : String(error)}`));
|
|
496
537
|
process.exit(1);
|
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>;
|