@vention/vention-cli 0.8.0 → 0.9.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 +163 -185
- package/package.json +1 -1
- package/src/cli-helpers.d.ts +15 -2
- package/src/config.d.ts +0 -3
- package/src/digital-twin-client.d.ts +2 -3
package/cli.esm.js
CHANGED
|
@@ -31,40 +31,6 @@ const loadSession = async () => {
|
|
|
31
31
|
}
|
|
32
32
|
};
|
|
33
33
|
|
|
34
|
-
const getBaseRailsUrl = (environment) => {
|
|
35
|
-
switch (environment) {
|
|
36
|
-
case "local":
|
|
37
|
-
return "http://localhost:3000";
|
|
38
|
-
case "demo":
|
|
39
|
-
return "https://vention.foo";
|
|
40
|
-
case "prod":
|
|
41
|
-
return "https://vention.io";
|
|
42
|
-
default:
|
|
43
|
-
throw new Error("Invalid environment");
|
|
44
|
-
}
|
|
45
|
-
};
|
|
46
|
-
const getUserAllocations = async (session) => {
|
|
47
|
-
const baseUrl = getBaseRailsUrl(session.environment);
|
|
48
|
-
const res = await fetch(`${baseUrl}/api/v3/digital_twin_infrastructure/allocations`, {
|
|
49
|
-
method: "GET",
|
|
50
|
-
headers: {
|
|
51
|
-
Accept: "application/json",
|
|
52
|
-
Origin: baseUrl,
|
|
53
|
-
Referer: `${baseUrl}/`,
|
|
54
|
-
Cookie: [
|
|
55
|
-
`vention_session=${session.ventionSession}`,
|
|
56
|
-
...(session.stytchSessionJwt ? [`stytch_session_jwt=${session.stytchSessionJwt}`] : []),
|
|
57
|
-
...(session.ventionIdpSession ? [`vention_idp_session=${session.ventionIdpSession}`] : []),
|
|
58
|
-
].join("; "),
|
|
59
|
-
},
|
|
60
|
-
});
|
|
61
|
-
if (!res.ok) {
|
|
62
|
-
throw new Error(`Request failed: ${res.status} ${res.statusText}`);
|
|
63
|
-
}
|
|
64
|
-
const response = await res.json();
|
|
65
|
-
return response;
|
|
66
|
-
};
|
|
67
|
-
|
|
68
34
|
const getDigitalTwinUrl = (environment, sessionId) => {
|
|
69
35
|
switch (environment) {
|
|
70
36
|
case "local":
|
|
@@ -77,33 +43,16 @@ const getDigitalTwinUrl = (environment, sessionId) => {
|
|
|
77
43
|
throw new Error("Invalid environment");
|
|
78
44
|
}
|
|
79
45
|
};
|
|
80
|
-
const
|
|
81
|
-
if (!
|
|
82
|
-
throw new Error("Linked session token is not set");
|
|
83
|
-
}
|
|
84
|
-
const digitalTwinUrl = getDigitalTwinUrl(session.environment, session.linkedSessionToken);
|
|
85
|
-
const res = await fetch(`${digitalTwinUrl}/v1/library`, {
|
|
86
|
-
method: "GET",
|
|
87
|
-
headers: {
|
|
88
|
-
Accept: "application/json",
|
|
89
|
-
Cookie: `digital-twin-session-${session.linkedDesignId}=s%3A${session.linkedSessionToken}.s`,
|
|
90
|
-
},
|
|
91
|
-
});
|
|
92
|
-
if (!res.ok) {
|
|
93
|
-
throw new Error(`Request failed: ${res.status} ${res.statusText}`);
|
|
94
|
-
}
|
|
95
|
-
return await res.json();
|
|
96
|
-
};
|
|
97
|
-
const getAllApplicationsWithSourceCode = async (session) => {
|
|
98
|
-
if (!session.linkedSessionToken) {
|
|
46
|
+
const getAllApplicationsWithSourceCode = async (environment, designId, sessionId) => {
|
|
47
|
+
if (!sessionId) {
|
|
99
48
|
throw new Error("Linked session token is not set");
|
|
100
49
|
}
|
|
101
|
-
const digitalTwinUrl = getDigitalTwinUrl(
|
|
50
|
+
const digitalTwinUrl = getDigitalTwinUrl(environment, sessionId);
|
|
102
51
|
const res = await fetch(`${digitalTwinUrl}/v2/library`, {
|
|
103
52
|
method: "GET",
|
|
104
53
|
headers: {
|
|
105
54
|
Accept: "application/json",
|
|
106
|
-
Cookie: `digital-twin-session-${
|
|
55
|
+
Cookie: `digital-twin-session-${designId}=s%3A${sessionId}.s`,
|
|
107
56
|
},
|
|
108
57
|
});
|
|
109
58
|
if (!res.ok) {
|
|
@@ -112,17 +61,17 @@ const getAllApplicationsWithSourceCode = async (session) => {
|
|
|
112
61
|
const response = await res.json();
|
|
113
62
|
return response.applications || [];
|
|
114
63
|
};
|
|
115
|
-
const pushApplicationToDigitalTwin = async (
|
|
116
|
-
if (!
|
|
64
|
+
const pushApplicationToDigitalTwin = async (environment, designId, sessionId, application) => {
|
|
65
|
+
if (!sessionId) {
|
|
117
66
|
throw new Error("Linked session token is not set");
|
|
118
67
|
}
|
|
119
|
-
const digitalTwinUrl = getDigitalTwinUrl(
|
|
68
|
+
const digitalTwinUrl = getDigitalTwinUrl(environment, sessionId);
|
|
120
69
|
const res = await fetch(`${digitalTwinUrl}/v1/library`, {
|
|
121
70
|
method: "PUT",
|
|
122
71
|
headers: {
|
|
123
72
|
"Content-Type": "application/json",
|
|
124
73
|
Accept: "application/json",
|
|
125
|
-
Cookie: `digital-twin-session-${
|
|
74
|
+
Cookie: `digital-twin-session-${designId}=s%3A${sessionId}.s`,
|
|
126
75
|
},
|
|
127
76
|
body: JSON.stringify(application),
|
|
128
77
|
});
|
|
@@ -151,6 +100,40 @@ const readMachineCodeAppDirectoryInfo = async (projectPath) => {
|
|
|
151
100
|
}
|
|
152
101
|
};
|
|
153
102
|
|
|
103
|
+
const getBaseRailsUrl = (environment) => {
|
|
104
|
+
switch (environment) {
|
|
105
|
+
case "local":
|
|
106
|
+
return "http://localhost:3000";
|
|
107
|
+
case "demo":
|
|
108
|
+
return "https://vention.foo";
|
|
109
|
+
case "prod":
|
|
110
|
+
return "https://vention.io";
|
|
111
|
+
default:
|
|
112
|
+
throw new Error("Invalid environment");
|
|
113
|
+
}
|
|
114
|
+
};
|
|
115
|
+
const getUserAllocations = async (session) => {
|
|
116
|
+
const baseUrl = getBaseRailsUrl(session.environment);
|
|
117
|
+
const res = await fetch(`${baseUrl}/api/v3/digital_twin_infrastructure/allocations`, {
|
|
118
|
+
method: "GET",
|
|
119
|
+
headers: {
|
|
120
|
+
Accept: "application/json",
|
|
121
|
+
Origin: baseUrl,
|
|
122
|
+
Referer: `${baseUrl}/`,
|
|
123
|
+
Cookie: [
|
|
124
|
+
`vention_session=${session.ventionSession}`,
|
|
125
|
+
...(session.stytchSessionJwt ? [`stytch_session_jwt=${session.stytchSessionJwt}`] : []),
|
|
126
|
+
...(session.ventionIdpSession ? [`vention_idp_session=${session.ventionIdpSession}`] : []),
|
|
127
|
+
].join("; "),
|
|
128
|
+
},
|
|
129
|
+
});
|
|
130
|
+
if (!res.ok) {
|
|
131
|
+
throw new Error(`Request failed: ${res.status} ${res.statusText}`);
|
|
132
|
+
}
|
|
133
|
+
const response = await res.json();
|
|
134
|
+
return response;
|
|
135
|
+
};
|
|
136
|
+
|
|
154
137
|
const getDefaultIgnorePatterns = () => {
|
|
155
138
|
return new Set(["venv", "node_modules", "dist", "build", "__pycache__", /\.egg-info$/, ".machine-code-app-directory-info.json"]);
|
|
156
139
|
};
|
|
@@ -252,50 +235,23 @@ const checkIfDesignHasLiveAllocation = async (session, designId) => {
|
|
|
252
235
|
const linkedAllocation = allocations.find(a => a.designId === designId);
|
|
253
236
|
return linkedAllocation;
|
|
254
237
|
};
|
|
255
|
-
const getAppFromDigitalTwin = async (
|
|
238
|
+
const getAppFromDigitalTwin = async (environment, machineCodeAppDirectoryInfo, sessionId) => {
|
|
256
239
|
console.log(chalk.blue("Fetching all applications with source code from digital twin..."));
|
|
257
|
-
const allApplications = await getAllApplicationsWithSourceCode(
|
|
258
|
-
const targetApp = allApplications.find((app) => app.id ===
|
|
240
|
+
const allApplications = await getAllApplicationsWithSourceCode(environment, machineCodeAppDirectoryInfo.designId, sessionId);
|
|
241
|
+
const targetApp = allApplications.find((app) => app.id === machineCodeAppDirectoryInfo.applicationId);
|
|
259
242
|
if (!targetApp) {
|
|
260
243
|
console.log();
|
|
261
|
-
console.error(chalk.red(`Application "${appName}" (ID: ${
|
|
244
|
+
console.error(chalk.red(`Application "${machineCodeAppDirectoryInfo.appName}" (ID: ${machineCodeAppDirectoryInfo.applicationId}) not found in the digital twin.`));
|
|
262
245
|
process.exit(1);
|
|
263
246
|
}
|
|
264
247
|
return targetApp;
|
|
265
248
|
};
|
|
266
|
-
const getAvailableAppsFromDigitalTwin = async (
|
|
267
|
-
const allApplications = await getAllApplicationsWithSourceCode(
|
|
249
|
+
const getAvailableAppsFromDigitalTwin = async (environment, designId, sessionId) => {
|
|
250
|
+
const allApplications = await getAllApplicationsWithSourceCode(environment, designId, sessionId);
|
|
268
251
|
return allApplications.filter((app) => app.type === "machine_code");
|
|
269
252
|
};
|
|
270
253
|
const createNewAppDirectory = async (session, currentDir) => {
|
|
271
|
-
|
|
272
|
-
console.error(chalk.red("No design linked. Please run 'vention link' first."));
|
|
273
|
-
process.exit(1);
|
|
274
|
-
}
|
|
275
|
-
const linkedAllocation = await checkIfDesignHasLiveAllocation(session, session.linkedDesignId);
|
|
276
|
-
console.log();
|
|
277
|
-
console.log(chalk.blue(`You are currently linked to design: ${linkedAllocation === null || linkedAllocation === void 0 ? void 0 : linkedAllocation.designName}`));
|
|
278
|
-
if (!linkedAllocation) {
|
|
279
|
-
console.log();
|
|
280
|
-
console.error(chalk.red("Sorry, it seems you do not have that design open with the MachineLogic tab selected."));
|
|
281
|
-
console.error(chalk.red("Please go to your browser, open your design, and navigate to the MachineLogic page."));
|
|
282
|
-
process.exit(1);
|
|
283
|
-
}
|
|
284
|
-
const availableApps = await getAvailableAppsFromDigitalTwin(session);
|
|
285
|
-
if (availableApps.length === 0) {
|
|
286
|
-
console.log();
|
|
287
|
-
console.log(chalk.yellow("No machine code applications found in the digital twin"));
|
|
288
|
-
process.exit(1);
|
|
289
|
-
}
|
|
290
|
-
const selectedApp = await select({
|
|
291
|
-
message: "Select an application to pull:",
|
|
292
|
-
choices: availableApps.map((app) => ({
|
|
293
|
-
name: app.name,
|
|
294
|
-
value: app,
|
|
295
|
-
})),
|
|
296
|
-
});
|
|
297
|
-
console.log();
|
|
298
|
-
console.log(chalk.blue(`\nPulling application "${selectedApp.name}"...`));
|
|
254
|
+
const { selectedDesign, selectedApp } = await selectDesignAndApp(session);
|
|
299
255
|
if (!selectedApp.sourceCode) {
|
|
300
256
|
console.log();
|
|
301
257
|
console.log(chalk.yellow("No source code found for this application."));
|
|
@@ -313,7 +269,7 @@ const createNewAppDirectory = async (session, currentDir) => {
|
|
|
313
269
|
const appDirectoryPath = await writeApplicationToDisk(selectedApp.name, selectedApp.sourceCode, currentDir);
|
|
314
270
|
await writeMachineCodeAppDirectoryInfo(appDirectoryPath, {
|
|
315
271
|
appName: selectedApp.name,
|
|
316
|
-
designId:
|
|
272
|
+
designId: selectedDesign.id,
|
|
317
273
|
applicationId: selectedApp.id,
|
|
318
274
|
lastPulledAt: new Date().toISOString(),
|
|
319
275
|
environment: session.environment,
|
|
@@ -325,24 +281,55 @@ const createNewAppDirectory = async (session, currentDir) => {
|
|
|
325
281
|
console.log(chalk.cyan(`cd "${safeAppName}"`));
|
|
326
282
|
console.log(chalk.blue("💡 You can now start working on your application!"));
|
|
327
283
|
};
|
|
328
|
-
const updateExistingAppDirectory = async (session,
|
|
329
|
-
console.log(chalk.blue(`Found existing project: ${
|
|
330
|
-
console.log(chalk.blue(`Design ID: ${
|
|
331
|
-
const linkedAllocation = await checkIfDesignHasLiveAllocation(session,
|
|
284
|
+
const updateExistingAppDirectory = async (session, machineCodeAppDirectoryInfo, currentDir) => {
|
|
285
|
+
console.log(chalk.blue(`Found existing project: ${machineCodeAppDirectoryInfo.appName}`));
|
|
286
|
+
console.log(chalk.blue(`Design ID: ${machineCodeAppDirectoryInfo.designId}, App ID: ${machineCodeAppDirectoryInfo.applicationId}`));
|
|
287
|
+
const linkedAllocation = await checkIfDesignHasLiveAllocation(session, machineCodeAppDirectoryInfo.designId);
|
|
332
288
|
if (!linkedAllocation) {
|
|
333
289
|
console.log();
|
|
334
290
|
console.error(chalk.red("Sorry, it seems you do not have that design open with the MachineLogic tab selected."));
|
|
335
291
|
console.error(chalk.red("Please go to your browser, open your design, and navigate to the MachineLogic page."));
|
|
336
292
|
process.exit(1);
|
|
337
293
|
}
|
|
338
|
-
await
|
|
339
|
-
const appWithSourceCode = await getAppFromDigitalTwin(session, projectState.applicationId, projectState.appName);
|
|
294
|
+
const appWithSourceCode = await getAppFromDigitalTwin(session.environment, machineCodeAppDirectoryInfo, linkedAllocation.sessionId);
|
|
340
295
|
await writeApplicationToDisk(appWithSourceCode.name, appWithSourceCode.sourceCode, currentDir, true);
|
|
341
|
-
await writeMachineCodeAppDirectoryInfo(currentDir, Object.assign(Object.assign({},
|
|
296
|
+
await writeMachineCodeAppDirectoryInfo(currentDir, Object.assign(Object.assign({}, machineCodeAppDirectoryInfo), { lastPulledAt: new Date().toISOString() }));
|
|
342
297
|
console.log();
|
|
343
298
|
console.log(chalk.green(`✅ Successfully pulled "${appWithSourceCode.name}" to: ${currentDir}`));
|
|
344
299
|
console.log(chalk.blue("💡 Your project has been updated with the latest changes!"));
|
|
345
300
|
};
|
|
301
|
+
const selectDesignAndApp = async (session) => {
|
|
302
|
+
const allocations = await getUserAllocations(session);
|
|
303
|
+
if (allocations.length === 0) {
|
|
304
|
+
console.log();
|
|
305
|
+
console.log(chalk.yellow("No active allocations found. Please open a design and navigate to the machine logic tab to activate a digital twin."));
|
|
306
|
+
process.exit(1);
|
|
307
|
+
}
|
|
308
|
+
const selectedDesign = await select({
|
|
309
|
+
message: "Select a design:",
|
|
310
|
+
choices: allocations.map((allocation) => ({
|
|
311
|
+
name: `${allocation.designName} (ID: ${allocation.designId})`,
|
|
312
|
+
value: { id: allocation.designId, name: allocation.designName, sessionId: allocation.sessionId },
|
|
313
|
+
})),
|
|
314
|
+
});
|
|
315
|
+
const availableApps = await getAvailableAppsFromDigitalTwin(session.environment, selectedDesign.id, selectedDesign.sessionId);
|
|
316
|
+
if (availableApps.length === 0) {
|
|
317
|
+
console.log();
|
|
318
|
+
console.log(chalk.yellow("No machine code applications found in the digital twin"));
|
|
319
|
+
process.exit(1);
|
|
320
|
+
}
|
|
321
|
+
const selectedApp = await select({
|
|
322
|
+
message: "Select an application:",
|
|
323
|
+
choices: availableApps.map((app) => ({
|
|
324
|
+
name: app.name,
|
|
325
|
+
value: app,
|
|
326
|
+
})),
|
|
327
|
+
});
|
|
328
|
+
return {
|
|
329
|
+
selectedDesign,
|
|
330
|
+
selectedApp,
|
|
331
|
+
};
|
|
332
|
+
};
|
|
346
333
|
|
|
347
334
|
const program = new Command();
|
|
348
335
|
program.name("vention").description("CLI tool for Vention").version("0.2.0");
|
|
@@ -403,7 +390,7 @@ program
|
|
|
403
390
|
});
|
|
404
391
|
program
|
|
405
392
|
.command("link")
|
|
406
|
-
.description("Link to a
|
|
393
|
+
.description("Link current directory to a Vention design application")
|
|
407
394
|
.action(async () => {
|
|
408
395
|
try {
|
|
409
396
|
const session = await loadSession();
|
|
@@ -411,33 +398,31 @@ program
|
|
|
411
398
|
console.error(chalk.red("Not logged in. Please run 'vention login' first."));
|
|
412
399
|
process.exit(1);
|
|
413
400
|
}
|
|
414
|
-
const
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
name: `${allocation.designName} (ID: ${allocation.designId})`,
|
|
424
|
-
value: { id: allocation.designId, name: allocation.designName, sessionId: allocation.sessionId },
|
|
425
|
-
})),
|
|
401
|
+
const currentDir = process.cwd();
|
|
402
|
+
const { selectedDesign, selectedApp } = await selectDesignAndApp(session);
|
|
403
|
+
await writeMachineCodeAppDirectoryInfo(currentDir, {
|
|
404
|
+
appName: selectedApp.name,
|
|
405
|
+
designId: selectedDesign.id,
|
|
406
|
+
applicationId: selectedApp.id,
|
|
407
|
+
lastPulledAt: new Date().toISOString(),
|
|
408
|
+
environment: session.environment,
|
|
409
|
+
uuid: selectedApp.uuid,
|
|
426
410
|
});
|
|
427
|
-
await saveSession(Object.assign(Object.assign({}, session), { linkedDesignId: selectedDesign.id, linkedSessionToken: selectedDesign.sessionId }));
|
|
428
411
|
console.log();
|
|
429
|
-
console.log(chalk.green(
|
|
412
|
+
console.log(chalk.green(`Successfully linked current directory to design "${selectedDesign.name}" (ID: ${selectedDesign.id})`));
|
|
413
|
+
console.log(chalk.green(`Application: "${selectedApp.name}" (ID: ${selectedApp.id})`));
|
|
414
|
+
console.log(chalk.blue("You can now use 'vention pull' to download app content or 'vention push' to upload local changes."));
|
|
430
415
|
}
|
|
431
416
|
catch (error) {
|
|
432
417
|
console.log();
|
|
433
|
-
console.error(chalk.red("Failed to
|
|
418
|
+
console.error(chalk.red("Failed to link directory:"));
|
|
434
419
|
console.error(chalk.red(`Error: ${error instanceof Error ? error.message : String(error)}`));
|
|
435
420
|
process.exit(1);
|
|
436
421
|
}
|
|
437
422
|
});
|
|
438
423
|
program
|
|
439
|
-
.command("
|
|
440
|
-
.description("
|
|
424
|
+
.command("push")
|
|
425
|
+
.description("Push local changes from this directory to the linked digital twin")
|
|
441
426
|
.action(async () => {
|
|
442
427
|
try {
|
|
443
428
|
const session = await loadSession();
|
|
@@ -445,32 +430,78 @@ program
|
|
|
445
430
|
console.error(chalk.red("Not logged in. Please run 'vention login' first."));
|
|
446
431
|
process.exit(1);
|
|
447
432
|
}
|
|
448
|
-
|
|
449
|
-
|
|
433
|
+
const currentDir = process.cwd();
|
|
434
|
+
const machineCodeAppDirectoryInfo = await readMachineCodeAppDirectoryInfo(currentDir);
|
|
435
|
+
if (!machineCodeAppDirectoryInfo) {
|
|
436
|
+
console.log();
|
|
437
|
+
console.log(chalk.yellow("This directory is not linked to a Vention application."));
|
|
438
|
+
const shouldLink = await select({
|
|
439
|
+
message: "Would you like to link this directory to an application?",
|
|
440
|
+
choices: [
|
|
441
|
+
{ name: "Yes, link this directory", value: true },
|
|
442
|
+
{ name: "No, cancel push operation", value: false },
|
|
443
|
+
],
|
|
444
|
+
});
|
|
445
|
+
if (!shouldLink) {
|
|
446
|
+
console.log(chalk.blue("Push operation cancelled. Run 'vention link' when you're ready to link this directory."));
|
|
447
|
+
process.exit(0);
|
|
448
|
+
}
|
|
449
|
+
const { selectedDesign, selectedApp } = await selectDesignAndApp(session);
|
|
450
|
+
await writeMachineCodeAppDirectoryInfo(currentDir, {
|
|
451
|
+
appName: selectedApp.name,
|
|
452
|
+
designId: selectedDesign.id,
|
|
453
|
+
applicationId: selectedApp.id,
|
|
454
|
+
lastPulledAt: new Date().toISOString(),
|
|
455
|
+
environment: session.environment,
|
|
456
|
+
uuid: selectedApp.uuid,
|
|
457
|
+
});
|
|
458
|
+
console.log(chalk.green(`Successfully linked directory to design "${selectedDesign.name}" (ID: ${selectedDesign.id})`));
|
|
459
|
+
console.log(chalk.green(`Application: "${selectedApp.name}" (ID: ${selectedApp.id})`));
|
|
460
|
+
console.log(chalk.blue("Continuing with push operation..."));
|
|
461
|
+
}
|
|
462
|
+
const updatedMachineCodeAppDirectoryInfo = await readMachineCodeAppDirectoryInfo(currentDir);
|
|
463
|
+
if (!updatedMachineCodeAppDirectoryInfo) {
|
|
464
|
+
console.log(chalk.red("Error reading directory metadata after linking."));
|
|
450
465
|
process.exit(1);
|
|
451
466
|
}
|
|
452
|
-
|
|
453
|
-
|
|
467
|
+
console.log();
|
|
468
|
+
console.log(chalk.blue(`Pushing changes for project: ${updatedMachineCodeAppDirectoryInfo.appName}`));
|
|
469
|
+
console.log(chalk.blue(`Design ID: ${updatedMachineCodeAppDirectoryInfo.designId}, App ID: ${updatedMachineCodeAppDirectoryInfo.applicationId}`));
|
|
470
|
+
const linkedAllocation = await checkIfDesignHasLiveAllocation(session, updatedMachineCodeAppDirectoryInfo.designId);
|
|
454
471
|
if (!linkedAllocation) {
|
|
455
472
|
console.log();
|
|
456
|
-
console.error(chalk.red("
|
|
473
|
+
console.error(chalk.red("Sorry, it seems you do not have that design open with the MachineLogic tab selected."));
|
|
474
|
+
console.error(chalk.red("Please go to your browser, open your design, and navigate to the MachineLogic page."));
|
|
457
475
|
process.exit(1);
|
|
458
476
|
}
|
|
459
|
-
const digitalTwinResponse = await makeTestRequestToLinkedDigitalTwin(session);
|
|
460
477
|
console.log();
|
|
461
|
-
console.log(chalk.
|
|
462
|
-
|
|
478
|
+
console.log(chalk.blue("Serializing local files..."));
|
|
479
|
+
const ignorePatterns = getDefaultIgnorePatterns();
|
|
480
|
+
const serializedSourceCode = serializeFileSystem(currentDir, ignorePatterns, true);
|
|
481
|
+
const applicationToPush = {
|
|
482
|
+
name: updatedMachineCodeAppDirectoryInfo.appName,
|
|
483
|
+
id: updatedMachineCodeAppDirectoryInfo.applicationId,
|
|
484
|
+
type: "machine_code",
|
|
485
|
+
sourceCode: serializedSourceCode,
|
|
486
|
+
uuid: updatedMachineCodeAppDirectoryInfo.uuid,
|
|
487
|
+
};
|
|
488
|
+
console.log(chalk.blue("Pushing to digital twin..."));
|
|
489
|
+
await pushApplicationToDigitalTwin(session.environment, updatedMachineCodeAppDirectoryInfo.designId, linkedAllocation.sessionId, applicationToPush);
|
|
490
|
+
await writeMachineCodeAppDirectoryInfo(currentDir, Object.assign(Object.assign({}, updatedMachineCodeAppDirectoryInfo), { lastPushedAt: new Date().toISOString() }));
|
|
491
|
+
console.log();
|
|
492
|
+
console.log(chalk.green(`✅ Successfully pushed to digital twin`));
|
|
493
|
+
console.log(chalk.blue("💡 Your changes have been uploaded!"));
|
|
463
494
|
}
|
|
464
495
|
catch (error) {
|
|
465
496
|
console.log();
|
|
466
|
-
console.error(chalk.red("Failed to
|
|
497
|
+
console.error(chalk.red("Failed to push application:"));
|
|
467
498
|
console.error(chalk.red(`Error: ${error instanceof Error ? error.message : String(error)}`));
|
|
468
499
|
process.exit(1);
|
|
469
500
|
}
|
|
470
501
|
});
|
|
471
502
|
program
|
|
472
503
|
.command("pull")
|
|
473
|
-
.description("Pull an application from
|
|
504
|
+
.description("Pull an application from a design to this directory")
|
|
474
505
|
.action(async () => {
|
|
475
506
|
try {
|
|
476
507
|
const session = await loadSession();
|
|
@@ -480,8 +511,9 @@ program
|
|
|
480
511
|
}
|
|
481
512
|
const currentDir = process.cwd();
|
|
482
513
|
const machineCodeAppDirectoryInfo = await readMachineCodeAppDirectoryInfo(currentDir);
|
|
483
|
-
|
|
484
|
-
|
|
514
|
+
if (machineCodeAppDirectoryInfo) {
|
|
515
|
+
console.log(chalk.blue(`This directory is linked to app: ${machineCodeAppDirectoryInfo.appName}`));
|
|
516
|
+
console.log(chalk.blue(`Pulling latest content from design ID: ${machineCodeAppDirectoryInfo.designId}`));
|
|
485
517
|
await updateExistingAppDirectory(session, machineCodeAppDirectoryInfo, currentDir);
|
|
486
518
|
}
|
|
487
519
|
else {
|
|
@@ -495,60 +527,6 @@ program
|
|
|
495
527
|
process.exit(1);
|
|
496
528
|
}
|
|
497
529
|
});
|
|
498
|
-
program
|
|
499
|
-
.command("push")
|
|
500
|
-
.description("Push local changes back to the digital twin")
|
|
501
|
-
.action(async () => {
|
|
502
|
-
try {
|
|
503
|
-
const session = await loadSession();
|
|
504
|
-
if (!session) {
|
|
505
|
-
console.error(chalk.red("Not logged in. Please run 'vention login' first."));
|
|
506
|
-
process.exit(1);
|
|
507
|
-
}
|
|
508
|
-
const currentDir = process.cwd();
|
|
509
|
-
const machineCodeAppDirectoryInfo = await readMachineCodeAppDirectoryInfo(currentDir);
|
|
510
|
-
if (!machineCodeAppDirectoryInfo) {
|
|
511
|
-
console.log();
|
|
512
|
-
console.error(chalk.red("Not in a machine code application directory. Please run 'vention pull' first to create a project."));
|
|
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."));
|
|
514
|
-
process.exit(1);
|
|
515
|
-
}
|
|
516
|
-
console.log();
|
|
517
|
-
console.log(chalk.blue(`Pushing changes for project: ${machineCodeAppDirectoryInfo.appName}`));
|
|
518
|
-
console.log(chalk.blue(`Design ID: ${machineCodeAppDirectoryInfo.designId}, App ID: ${machineCodeAppDirectoryInfo.applicationId}`));
|
|
519
|
-
const linkedAllocation = await checkIfDesignHasLiveAllocation(session, machineCodeAppDirectoryInfo.designId);
|
|
520
|
-
if (!linkedAllocation) {
|
|
521
|
-
console.log();
|
|
522
|
-
console.error(chalk.red("Sorry, it seems you do not have that design open with the MachineLogic tab selected."));
|
|
523
|
-
console.error(chalk.red("Please go to your browser, open your design, and navigate to the MachineLogic page."));
|
|
524
|
-
process.exit(1);
|
|
525
|
-
}
|
|
526
|
-
await saveSession(Object.assign(Object.assign({}, session), { linkedDesignId: machineCodeAppDirectoryInfo.designId, linkedSessionToken: linkedAllocation.sessionId }));
|
|
527
|
-
console.log();
|
|
528
|
-
console.log(chalk.blue("Serializing local files..."));
|
|
529
|
-
const ignorePatterns = getDefaultIgnorePatterns();
|
|
530
|
-
const serializedSourceCode = serializeFileSystem(currentDir, ignorePatterns, true);
|
|
531
|
-
const applicationToPush = {
|
|
532
|
-
name: machineCodeAppDirectoryInfo.appName,
|
|
533
|
-
id: machineCodeAppDirectoryInfo.applicationId,
|
|
534
|
-
type: "machine_code",
|
|
535
|
-
sourceCode: serializedSourceCode,
|
|
536
|
-
uuid: machineCodeAppDirectoryInfo.uuid,
|
|
537
|
-
};
|
|
538
|
-
console.log(chalk.blue("Pushing to digital twin..."));
|
|
539
|
-
await pushApplicationToDigitalTwin(session, applicationToPush);
|
|
540
|
-
await writeMachineCodeAppDirectoryInfo(currentDir, Object.assign(Object.assign({}, machineCodeAppDirectoryInfo), { lastPushedAt: new Date().toISOString() }));
|
|
541
|
-
console.log();
|
|
542
|
-
console.log(chalk.green(`✅ Successfully pushed "${machineCodeAppDirectoryInfo.appName}" to digital twin`));
|
|
543
|
-
console.log(chalk.blue("💡 Your changes have been uploaded!"));
|
|
544
|
-
}
|
|
545
|
-
catch (error) {
|
|
546
|
-
console.log();
|
|
547
|
-
console.error(chalk.red("Failed to push application:"));
|
|
548
|
-
console.error(chalk.red(`Error: ${error instanceof Error ? error.message : String(error)}`));
|
|
549
|
-
process.exit(1);
|
|
550
|
-
}
|
|
551
|
-
});
|
|
552
530
|
const resolvedArgv = realpathSync(process.argv[1]);
|
|
553
531
|
const resolvedUrl = new URL(import.meta.url).pathname;
|
|
554
532
|
if (resolvedArgv === resolvedUrl) {
|
package/package.json
CHANGED
package/src/cli-helpers.d.ts
CHANGED
|
@@ -1,5 +1,18 @@
|
|
|
1
1
|
import { SessionData } from "./config";
|
|
2
|
+
import { Application } from "./digital-twin-client";
|
|
2
3
|
import { MachineCodeAppDirectoryInfo } from "./machine-code-app-directory-info";
|
|
3
|
-
|
|
4
|
+
import { AllocationResponse } from "./rails-client";
|
|
5
|
+
export declare const checkIfDesignHasLiveAllocation: (session: SessionData, designId: number) => Promise<AllocationResponse | undefined>;
|
|
6
|
+
export declare const getAppFromDigitalTwin: (environment: SessionData["environment"], machineCodeAppDirectoryInfo: MachineCodeAppDirectoryInfo, sessionId: string) => Promise<Application>;
|
|
7
|
+
export declare const getAvailableAppsFromDigitalTwin: (environment: SessionData["environment"], designId: number, sessionId: string) => Promise<Application[]>;
|
|
4
8
|
export declare const createNewAppDirectory: (session: SessionData, currentDir: string) => Promise<void>;
|
|
5
|
-
export declare const updateExistingAppDirectory: (session: SessionData,
|
|
9
|
+
export declare const updateExistingAppDirectory: (session: SessionData, machineCodeAppDirectoryInfo: MachineCodeAppDirectoryInfo, currentDir: string) => Promise<void>;
|
|
10
|
+
export interface DesignAndAppSelection {
|
|
11
|
+
selectedDesign: {
|
|
12
|
+
id: number;
|
|
13
|
+
name: string;
|
|
14
|
+
sessionId: string;
|
|
15
|
+
};
|
|
16
|
+
selectedApp: Application;
|
|
17
|
+
}
|
|
18
|
+
export declare const selectDesignAndApp: (session: SessionData) => Promise<DesignAndAppSelection>;
|
package/src/config.d.ts
CHANGED
|
@@ -3,9 +3,6 @@ export interface SessionData {
|
|
|
3
3
|
ventionSession: string;
|
|
4
4
|
stytchSessionJwt?: string;
|
|
5
5
|
ventionIdpSession?: string;
|
|
6
|
-
linkedDesignId?: number;
|
|
7
|
-
lastTaskId?: string;
|
|
8
|
-
linkedSessionToken?: string;
|
|
9
6
|
}
|
|
10
7
|
export declare const getConfigPath: () => string;
|
|
11
8
|
export declare const saveSession: (data: SessionData) => Promise<void>;
|
|
@@ -10,6 +10,5 @@ export interface Application {
|
|
|
10
10
|
sourceCode: FileSystemNode;
|
|
11
11
|
}
|
|
12
12
|
export declare const getDigitalTwinUrl: (environment: SessionData["environment"], sessionId: string) => string;
|
|
13
|
-
export declare const
|
|
14
|
-
export declare const
|
|
15
|
-
export declare const pushApplicationToDigitalTwin: (session: SessionData, application: Application) => Promise<void>;
|
|
13
|
+
export declare const getAllApplicationsWithSourceCode: (environment: SessionData["environment"], designId: number, sessionId: string) => Promise<Application[]>;
|
|
14
|
+
export declare const pushApplicationToDigitalTwin: (environment: SessionData["environment"], designId: number, sessionId: string, application: Application) => Promise<void>;
|