@vention/vention-cli 0.22.0 → 0.23.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 +16 -57
- package/package.json +1 -1
package/cli.esm.js
CHANGED
|
@@ -6008,9 +6008,6 @@ const TokenResponseSchema = z.object({
|
|
|
6008
6008
|
const openBrowser = url => {
|
|
6009
6009
|
const platform = process.platform;
|
|
6010
6010
|
const command = platform === "darwin" ? `open "${url}"` : platform === "win32" ? `start "${url}"` : `xdg-open "${url}"`;
|
|
6011
|
-
|
|
6012
|
-
// URL is constructed from trusted constants and internal params (not user input)
|
|
6013
|
-
// nosemgrep: javascript.lang.security.detect-child-process.detect-child-process
|
|
6014
6011
|
exec$9(command, error => {
|
|
6015
6012
|
if (error) {
|
|
6016
6013
|
console.log("Please open this URL in your browser:", url);
|
|
@@ -6030,9 +6027,6 @@ const startCallbackServer = async expectedState => {
|
|
|
6030
6027
|
const server = http.createServer();
|
|
6031
6028
|
const waitForCode = (async () => {
|
|
6032
6029
|
try {
|
|
6033
|
-
// Keep listening until we get the expected /callback request
|
|
6034
|
-
// This avoids external mutable resolve/reject handlers.
|
|
6035
|
-
// eslint-disable-next-line no-constant-condition
|
|
6036
6030
|
while (true) {
|
|
6037
6031
|
const [req, res] = await once(server, "request");
|
|
6038
6032
|
const url = new URL(req.url || "/", `http://127.0.0.1`);
|
|
@@ -6094,7 +6088,7 @@ const startCallbackServer = async expectedState => {
|
|
|
6094
6088
|
const getSsoConfig = environment => {
|
|
6095
6089
|
if (environment === "local") throw new Error("SSO is not supported for local environment. Use cookie-based login.");
|
|
6096
6090
|
const ssoConfig = CONNECTED_APP_SSO_CONFIG[environment];
|
|
6097
|
-
if (!(ssoConfig
|
|
6091
|
+
if (!(ssoConfig === null || ssoConfig === void 0 ? void 0 : ssoConfig.clientId)) throw new Error("Missing CONNECTED_APP clientId for selected environment in sso-constants.ts");
|
|
6098
6092
|
if (!ssoConfig.tokenUrl) throw new Error("Missing tokenUrl for selected environment in sso-constants.ts");
|
|
6099
6093
|
return {
|
|
6100
6094
|
clientId: ssoConfig.clientId,
|
|
@@ -6130,7 +6124,7 @@ const exchangeAuthorizationCodeForTokens = async (config, code, codeVerifier, re
|
|
|
6130
6124
|
};
|
|
6131
6125
|
};
|
|
6132
6126
|
const refreshAccessToken = async (config, refreshToken) => {
|
|
6133
|
-
var
|
|
6127
|
+
var _a;
|
|
6134
6128
|
const body = new URLSearchParams$2({
|
|
6135
6129
|
grant_type: "refresh_token",
|
|
6136
6130
|
refresh_token: refreshToken,
|
|
@@ -6150,7 +6144,7 @@ const refreshAccessToken = async (config, refreshToken) => {
|
|
|
6150
6144
|
const parsed = TokenResponseSchema.parse(json);
|
|
6151
6145
|
return {
|
|
6152
6146
|
accessToken: parsed.access_token,
|
|
6153
|
-
refreshToken: (
|
|
6147
|
+
refreshToken: (_a = parsed.refresh_token) !== null && _a !== void 0 ? _a : refreshToken,
|
|
6154
6148
|
expiresInSeconds: parsed.expires_in
|
|
6155
6149
|
};
|
|
6156
6150
|
};
|
|
@@ -6164,7 +6158,6 @@ const loginWithSso = async environment => {
|
|
|
6164
6158
|
verifier,
|
|
6165
6159
|
challenge
|
|
6166
6160
|
} = generatePkce();
|
|
6167
|
-
// OAuth 2.0 state: per-request nonce used to prevent CSRF and bind the callback to this initiation
|
|
6168
6161
|
const state = generateRandomBase64Url(16);
|
|
6169
6162
|
const {
|
|
6170
6163
|
port,
|
|
@@ -6348,7 +6341,7 @@ async function assertApiResponseOk(res, url) {
|
|
|
6348
6341
|
try {
|
|
6349
6342
|
text = await res.text();
|
|
6350
6343
|
responseBody = text ? JSON.parse(text) : null;
|
|
6351
|
-
} catch (
|
|
6344
|
+
} catch (_a) {
|
|
6352
6345
|
responseBody = text || null;
|
|
6353
6346
|
}
|
|
6354
6347
|
throw new ApiError(`Request failed: ${res.status} ${res.statusText}`, res.status, res.statusText, responseBody, url);
|
|
@@ -6386,15 +6379,15 @@ const ERROR_SUGGESTIONS = {
|
|
|
6386
6379
|
};
|
|
6387
6380
|
const ENDPOINT_PATTERNS = [["allocations", "/allocations"], ["library", "/library"]];
|
|
6388
6381
|
const getEndpointFromUrl = url => {
|
|
6389
|
-
var
|
|
6390
|
-
return (
|
|
6382
|
+
var _a;
|
|
6383
|
+
return (_a = ENDPOINT_PATTERNS.find(([, pattern]) => url.includes(pattern))) === null || _a === void 0 ? void 0 : _a[0];
|
|
6391
6384
|
};
|
|
6392
6385
|
const getErrorSuggestions = (status, url) => {
|
|
6393
|
-
var
|
|
6394
|
-
const entry = (
|
|
6386
|
+
var _a, _b, _c;
|
|
6387
|
+
const entry = (_a = ERROR_SUGGESTIONS[status]) !== null && _a !== void 0 ? _a : status >= 500 ? ERROR_SUGGESTIONS[500] : undefined;
|
|
6395
6388
|
if (!entry) return [];
|
|
6396
6389
|
const endpoint = getEndpointFromUrl(url);
|
|
6397
|
-
return (
|
|
6390
|
+
return (_c = endpoint && ((_b = entry.byEndpoint) === null || _b === void 0 ? void 0 : _b[endpoint])) !== null && _c !== void 0 ? _c : entry.default;
|
|
6398
6391
|
};
|
|
6399
6392
|
const handleCommandError = (error, context) => {
|
|
6400
6393
|
console.error(chalk.red(`${context}:`));
|
|
@@ -6437,7 +6430,6 @@ const fetchJson = async (url, options = {}) => {
|
|
|
6437
6430
|
const getDigitalTwinUrl = (environment, sessionId) => {
|
|
6438
6431
|
switch (environment) {
|
|
6439
6432
|
case "local":
|
|
6440
|
-
// This is where execution-engine-cad is served on vention-stack
|
|
6441
6433
|
return `http://localhost:3101`;
|
|
6442
6434
|
case "demo":
|
|
6443
6435
|
return `https://digital-twin.vention.foo/digital-twin/machine-motion/passthrough/${sessionId}/80`;
|
|
@@ -6759,7 +6751,7 @@ const getUserAllocations = async session => {
|
|
|
6759
6751
|
});
|
|
6760
6752
|
};
|
|
6761
6753
|
const getAuthHeaders = async session => {
|
|
6762
|
-
var
|
|
6754
|
+
var _a;
|
|
6763
6755
|
const baseUrl = getBaseRailsUrl(session.environment);
|
|
6764
6756
|
const baseHeaders = {
|
|
6765
6757
|
Accept: "application/json",
|
|
@@ -6770,11 +6762,11 @@ const getAuthHeaders = async session => {
|
|
|
6770
6762
|
if (!session.ventionSession) {
|
|
6771
6763
|
throw new Error("Local environment requires vention_session. Please run 'vention login' and provide the cookie value.");
|
|
6772
6764
|
}
|
|
6773
|
-
return Object.assign({}, baseHeaders, {
|
|
6765
|
+
return Object.assign(Object.assign({}, baseHeaders), {
|
|
6774
6766
|
Cookie: `vention_session=${session.ventionSession}`
|
|
6775
6767
|
});
|
|
6776
6768
|
}
|
|
6777
|
-
if (!((
|
|
6769
|
+
if (!((_a = session.oauth) === null || _a === void 0 ? void 0 : _a.accessToken)) {
|
|
6778
6770
|
throw new Error("Not authenticated. Please run 'vention login' to authenticate via SSO.");
|
|
6779
6771
|
}
|
|
6780
6772
|
const bufferMs = 5 * 60 * 1000;
|
|
@@ -6787,7 +6779,7 @@ const getAuthHeaders = async session => {
|
|
|
6787
6779
|
session.oauth.expiresAt = refreshed.expiresInSeconds ? Date.now() + refreshed.expiresInSeconds * 1000 : session.oauth.expiresAt;
|
|
6788
6780
|
await saveSession(session);
|
|
6789
6781
|
}
|
|
6790
|
-
return Object.assign({}, baseHeaders, {
|
|
6782
|
+
return Object.assign(Object.assign({}, baseHeaders), {
|
|
6791
6783
|
Authorization: `Bearer ${session.oauth.accessToken}`
|
|
6792
6784
|
});
|
|
6793
6785
|
};
|
|
@@ -10121,11 +10113,6 @@ const shouldIgnoreFileSystemNode = (nodeName, ignoredNodes) => {
|
|
|
10121
10113
|
const getSafeAppName = appName => {
|
|
10122
10114
|
return appName.replace(/[^a-zA-Z0-9-_]/g, "_");
|
|
10123
10115
|
};
|
|
10124
|
-
|
|
10125
|
-
/**
|
|
10126
|
-
* Serializes a file system directory into a JSON representation
|
|
10127
|
-
* Based on the logic from mm-execution-engine's MachineCodeDirectoryUtils.ts
|
|
10128
|
-
*/
|
|
10129
10116
|
const serializeFileSystem = (sourceDirectory, ignoredFileSystemNodes, shouldBase64Encoded) => {
|
|
10130
10117
|
const fileSystemNode = {};
|
|
10131
10118
|
const directoryContents = fs.readdirSync(sourceDirectory);
|
|
@@ -10144,18 +10131,11 @@ const serializeFileSystem = (sourceDirectory, ignoredFileSystemNodes, shouldBase
|
|
|
10144
10131
|
});
|
|
10145
10132
|
return fileSystemNode;
|
|
10146
10133
|
};
|
|
10147
|
-
|
|
10148
|
-
/**
|
|
10149
|
-
* Creates a file system structure from a JSON representation.
|
|
10150
|
-
* Based on the logic from mm-execution-engine's MachineCodeDirectoryUtils.ts
|
|
10151
|
-
*/
|
|
10152
10134
|
const createFileSystemFromJson = async (fileSystemNode, targetDirectory) => {
|
|
10153
10135
|
await ensureDirectoryExists(targetDirectory);
|
|
10154
10136
|
const writeFiles = async (node, currentPath) => {
|
|
10155
10137
|
for (const [entryName, contentOrNode] of Object.entries(node)) {
|
|
10156
10138
|
const fullPath = path$2.join(currentPath, entryName);
|
|
10157
|
-
|
|
10158
|
-
// A node either represents the string contents of a file, or a subdirectory
|
|
10159
10139
|
if (typeof contentOrNode === "string") {
|
|
10160
10140
|
const decodedContent = Buffer.from(contentOrNode, "base64");
|
|
10161
10141
|
const fileHandle = await fs.promises.open(fullPath, "w");
|
|
@@ -10172,9 +10152,6 @@ const createFileSystemFromJson = async (fileSystemNode, targetDirectory) => {
|
|
|
10172
10152
|
}
|
|
10173
10153
|
};
|
|
10174
10154
|
await writeFiles(fileSystemNode, targetDirectory);
|
|
10175
|
-
|
|
10176
|
-
// fsync on directories is not supported on Windows, so we skip it there
|
|
10177
|
-
// On Unix systems, this ensures directory metadata is persisted to disk
|
|
10178
10155
|
if (process.platform !== "win32") {
|
|
10179
10156
|
const dirHandle = await fs.promises.open(targetDirectory, "r");
|
|
10180
10157
|
try {
|
|
@@ -10192,27 +10169,15 @@ const ensureDirectoryExists = async directory => {
|
|
|
10192
10169
|
});
|
|
10193
10170
|
}
|
|
10194
10171
|
};
|
|
10195
|
-
|
|
10196
|
-
/**
|
|
10197
|
-
* Checks if a directory already exists at the given path
|
|
10198
|
-
*/
|
|
10199
10172
|
const checkIfDirectoryExists = async directory => {
|
|
10200
10173
|
const exists = await fs.promises.access(directory).then(() => true).catch(() => false);
|
|
10201
10174
|
return exists;
|
|
10202
10175
|
};
|
|
10203
|
-
|
|
10204
|
-
/**
|
|
10205
|
-
* Checks if an application directory with the given name already exists in the target directory
|
|
10206
|
-
*/
|
|
10207
10176
|
const checkIfAppDirectoryExists = async (appName, targetDirectory) => {
|
|
10208
10177
|
const safeAppName = appName.replace(/[^a-zA-Z0-9-_]/g, "_");
|
|
10209
10178
|
const appDirectoryPath = path$2.join(targetDirectory, safeAppName);
|
|
10210
10179
|
return await checkIfDirectoryExists(appDirectoryPath);
|
|
10211
10180
|
};
|
|
10212
|
-
|
|
10213
|
-
/**
|
|
10214
|
-
* Writes application source code to disk in a new directory
|
|
10215
|
-
*/
|
|
10216
10181
|
const writeApplicationToDisk = async (appName, sourceCode, targetDirectory, overwriteExisting = false) => {
|
|
10217
10182
|
if (overwriteExisting) {
|
|
10218
10183
|
await createFileSystemFromJson(sourceCode, targetDirectory);
|
|
@@ -10290,7 +10255,7 @@ const updateExistingAppDirectory = async (session, machineCodeAppDirectoryInfo,
|
|
|
10290
10255
|
}
|
|
10291
10256
|
const appWithSourceCode = await getAppFromDigitalTwin(session.environment, machineCodeAppDirectoryInfo, linkedAllocation.sessionId);
|
|
10292
10257
|
await writeApplicationToDisk(appWithSourceCode.name, appWithSourceCode.sourceCode, currentDir, true);
|
|
10293
|
-
await writeMachineCodeAppDirectoryInfo(currentDir, Object.assign({}, machineCodeAppDirectoryInfo, {
|
|
10258
|
+
await writeMachineCodeAppDirectoryInfo(currentDir, Object.assign(Object.assign({}, machineCodeAppDirectoryInfo), {
|
|
10294
10259
|
lastPulledAt: new Date().toISOString()
|
|
10295
10260
|
}));
|
|
10296
10261
|
console.log();
|
|
@@ -10338,7 +10303,7 @@ const require$1 = createRequire(import.meta.url);
|
|
|
10338
10303
|
function loadPackageJson() {
|
|
10339
10304
|
try {
|
|
10340
10305
|
return require$1("./package.json");
|
|
10341
|
-
} catch (
|
|
10306
|
+
} catch (_a) {
|
|
10342
10307
|
return require$1("../package.json");
|
|
10343
10308
|
}
|
|
10344
10309
|
}
|
|
@@ -10510,7 +10475,7 @@ program.command("push").description("Push local changes from this directory to t
|
|
|
10510
10475
|
};
|
|
10511
10476
|
console.log(chalk.blue("Pushing to digital twin..."));
|
|
10512
10477
|
await pushApplicationToDigitalTwin(session.environment, updatedMachineCodeAppDirectoryInfo.designId, linkedAllocation.sessionId, applicationToPush);
|
|
10513
|
-
await writeMachineCodeAppDirectoryInfo(currentDir, Object.assign({}, updatedMachineCodeAppDirectoryInfo, {
|
|
10478
|
+
await writeMachineCodeAppDirectoryInfo(currentDir, Object.assign(Object.assign({}, updatedMachineCodeAppDirectoryInfo), {
|
|
10514
10479
|
lastPushedAt: new Date().toISOString()
|
|
10515
10480
|
}));
|
|
10516
10481
|
console.log();
|
|
@@ -10540,15 +10505,9 @@ program.command("pull").description("Pull an application from a design to this d
|
|
|
10540
10505
|
handleCommandError(error, "Failed to pull application");
|
|
10541
10506
|
}
|
|
10542
10507
|
});
|
|
10543
|
-
|
|
10544
|
-
// Only run the CLI if this is the main module (not imported for testing)
|
|
10545
|
-
// we need to resolve the real path, because in local development, the path is a symlink
|
|
10546
10508
|
const resolvedArgv = realpathSync(process.argv[1]);
|
|
10547
|
-
// fileURLToPath correctly handles Windows paths (C:\...) vs Unix paths (/...)
|
|
10548
|
-
// Without this, Windows comparisons fail due to leading slash in pathname
|
|
10549
10509
|
const resolvedUrlPath = realpathSync(fileURLToPath(import.meta.url));
|
|
10550
10510
|
if (resolvedArgv === resolvedUrlPath) {
|
|
10551
|
-
// Only show logo when no command is provided or help is requested
|
|
10552
10511
|
const showLogoConditions = [process.argv.length <= 2, process.argv.includes("--help"), process.argv.includes("-h")];
|
|
10553
10512
|
if (showLogoConditions.some(Boolean)) {
|
|
10554
10513
|
console.log(chalk.cyan(ventionLogo));
|