@layr-labs/ecloud-cli 0.1.1-dev → 0.1.2-dev
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/VERSION +2 -2
- package/dist/commands/auth/generate.js +2 -2
- package/dist/commands/auth/generate.js.map +1 -1
- package/dist/commands/auth/login.js.map +1 -1
- package/dist/commands/auth/logout.js.map +1 -1
- package/dist/commands/auth/migrate.js.map +1 -1
- package/dist/commands/auth/whoami.js +5 -3
- package/dist/commands/auth/whoami.js.map +1 -1
- package/dist/commands/billing/cancel.js +5 -3
- package/dist/commands/billing/cancel.js.map +1 -1
- package/dist/commands/billing/status.js +5 -3
- package/dist/commands/billing/status.js.map +1 -1
- package/dist/commands/billing/subscribe.js +10 -6
- package/dist/commands/billing/subscribe.js.map +1 -1
- package/dist/commands/compute/app/create.js.map +1 -1
- package/dist/commands/compute/app/deploy.js +143 -76
- package/dist/commands/compute/app/deploy.js.map +1 -1
- package/dist/commands/compute/app/info.js +54 -8
- package/dist/commands/compute/app/info.js.map +1 -1
- package/dist/commands/compute/app/list.js +6 -7
- package/dist/commands/compute/app/list.js.map +1 -1
- package/dist/commands/compute/app/logs.js +55 -9
- package/dist/commands/compute/app/logs.js.map +1 -1
- package/dist/commands/compute/app/profile/set.js +141 -20
- package/dist/commands/compute/app/profile/set.js.map +1 -1
- package/dist/commands/compute/app/start.js +55 -9
- package/dist/commands/compute/app/start.js.map +1 -1
- package/dist/commands/compute/app/stop.js +55 -9
- package/dist/commands/compute/app/stop.js.map +1 -1
- package/dist/commands/compute/app/terminate.js +55 -9
- package/dist/commands/compute/app/terminate.js.map +1 -1
- package/dist/commands/compute/app/upgrade.js +172 -49
- package/dist/commands/compute/app/upgrade.js.map +1 -1
- package/dist/commands/compute/environment/list.js.map +1 -1
- package/dist/commands/compute/environment/set.js.map +1 -1
- package/dist/commands/compute/environment/show.js.map +1 -1
- package/dist/commands/compute/undelegate.js +6 -7
- package/dist/commands/compute/undelegate.js.map +1 -1
- package/dist/commands/telemetry/disable.js.map +1 -1
- package/dist/commands/telemetry/enable.js.map +1 -1
- package/dist/commands/telemetry/status.js.map +1 -1
- package/dist/commands/upgrade.js.map +1 -1
- package/dist/commands/version.js.map +1 -1
- package/package.json +3 -2
|
@@ -2,14 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
// src/commands/compute/app/deploy.ts
|
|
4
4
|
import { Command, Flags as Flags2 } from "@oclif/core";
|
|
5
|
-
import {
|
|
6
|
-
getEnvironmentConfig as getEnvironmentConfig2,
|
|
7
|
-
UserApiClient as UserApiClient3,
|
|
8
|
-
isMainnet,
|
|
9
|
-
prepareDeploy,
|
|
10
|
-
executeDeploy,
|
|
11
|
-
watchDeployment
|
|
12
|
-
} from "@layr-labs/ecloud-sdk";
|
|
5
|
+
import { getEnvironmentConfig as getEnvironmentConfig3, isMainnet, UserApiClient as UserApiClient3 } from "@layr-labs/ecloud-sdk";
|
|
13
6
|
|
|
14
7
|
// src/telemetry.ts
|
|
15
8
|
import {
|
|
@@ -71,6 +64,29 @@ function saveGlobalConfig(config) {
|
|
|
71
64
|
const content = dumpYaml(config, { lineWidth: -1 });
|
|
72
65
|
fs.writeFileSync(configPath, content, { mode: 420 });
|
|
73
66
|
}
|
|
67
|
+
function normalizeDirectoryPath(directoryPath) {
|
|
68
|
+
const resolved = path.resolve(directoryPath);
|
|
69
|
+
try {
|
|
70
|
+
return fs.realpathSync(resolved);
|
|
71
|
+
} catch {
|
|
72
|
+
return resolved;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
function setLinkedAppForDirectory(environment, directoryPath, appId) {
|
|
76
|
+
if (!directoryPath || !environment) {
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
const config = loadGlobalConfig();
|
|
80
|
+
if (!config.directory_links) {
|
|
81
|
+
config.directory_links = {};
|
|
82
|
+
}
|
|
83
|
+
if (!config.directory_links[environment]) {
|
|
84
|
+
config.directory_links[environment] = {};
|
|
85
|
+
}
|
|
86
|
+
const normalizedPath = normalizeDirectoryPath(directoryPath);
|
|
87
|
+
config.directory_links[environment][normalizedPath] = appId.toLowerCase();
|
|
88
|
+
saveGlobalConfig(config);
|
|
89
|
+
}
|
|
74
90
|
function getDefaultEnvironment() {
|
|
75
91
|
const config = loadGlobalConfig();
|
|
76
92
|
return config.default_environment;
|
|
@@ -161,6 +177,7 @@ async function withTelemetry(command, action) {
|
|
|
161
177
|
|
|
162
178
|
// src/flags.ts
|
|
163
179
|
import { Flags } from "@oclif/core";
|
|
180
|
+
import { getBuildType as getBuildType3 } from "@layr-labs/ecloud-sdk";
|
|
164
181
|
|
|
165
182
|
// src/utils/prompts.ts
|
|
166
183
|
import { input, select, password, confirm as inquirerConfirm } from "@inquirer/prompts";
|
|
@@ -256,7 +273,7 @@ function findAvailableName(environment, baseName) {
|
|
|
256
273
|
|
|
257
274
|
// src/utils/version.ts
|
|
258
275
|
function getCliVersion() {
|
|
259
|
-
return true ? "0.1.
|
|
276
|
+
return true ? "0.1.2-dev" : "0.0.0";
|
|
260
277
|
}
|
|
261
278
|
function getClientId() {
|
|
262
279
|
return `ecloud-cli/v${getCliVersion()}`;
|
|
@@ -710,8 +727,8 @@ async function getPrivateKeyInteractive(privateKey) {
|
|
|
710
727
|
}
|
|
711
728
|
return privateKey;
|
|
712
729
|
}
|
|
713
|
-
const { getPrivateKeyWithSource } = await import("@layr-labs/ecloud-sdk");
|
|
714
|
-
const result = await
|
|
730
|
+
const { getPrivateKeyWithSource: getPrivateKeyWithSource2 } = await import("@layr-labs/ecloud-sdk");
|
|
731
|
+
const result = await getPrivateKeyWithSource2({ privateKey: void 0 });
|
|
715
732
|
if (result) {
|
|
716
733
|
return result.key;
|
|
717
734
|
}
|
|
@@ -730,6 +747,50 @@ async function getPrivateKeyInteractive(privateKey) {
|
|
|
730
747
|
});
|
|
731
748
|
return key.trim();
|
|
732
749
|
}
|
|
750
|
+
async function getEnvironmentInteractive(environment) {
|
|
751
|
+
if (environment) {
|
|
752
|
+
try {
|
|
753
|
+
getEnvironmentConfig(environment);
|
|
754
|
+
if (!isEnvironmentAvailable(environment)) {
|
|
755
|
+
throw new Error(`Environment ${environment} is not available in this build`);
|
|
756
|
+
}
|
|
757
|
+
return environment;
|
|
758
|
+
} catch {
|
|
759
|
+
}
|
|
760
|
+
}
|
|
761
|
+
const availableEnvs = getAvailableEnvironments();
|
|
762
|
+
let defaultEnv;
|
|
763
|
+
const configDefaultEnv = getDefaultEnvironment();
|
|
764
|
+
if (configDefaultEnv && availableEnvs.includes(configDefaultEnv)) {
|
|
765
|
+
try {
|
|
766
|
+
getEnvironmentConfig(configDefaultEnv);
|
|
767
|
+
defaultEnv = configDefaultEnv;
|
|
768
|
+
} catch {
|
|
769
|
+
}
|
|
770
|
+
}
|
|
771
|
+
const choices = [];
|
|
772
|
+
if (availableEnvs.includes("sepolia")) {
|
|
773
|
+
choices.push({ name: "sepolia - Ethereum Sepolia testnet", value: "sepolia" });
|
|
774
|
+
}
|
|
775
|
+
if (availableEnvs.includes("sepolia-dev")) {
|
|
776
|
+
choices.push({ name: "sepolia-dev - Ethereum Sepolia testnet (dev)", value: "sepolia-dev" });
|
|
777
|
+
}
|
|
778
|
+
if (availableEnvs.includes("mainnet-alpha")) {
|
|
779
|
+
choices.push({
|
|
780
|
+
name: "mainnet-alpha - Ethereum mainnet (\u26A0\uFE0F uses real funds)",
|
|
781
|
+
value: "mainnet-alpha"
|
|
782
|
+
});
|
|
783
|
+
}
|
|
784
|
+
if (choices.length === 0) {
|
|
785
|
+
throw new Error("No environments available in this build");
|
|
786
|
+
}
|
|
787
|
+
const env = await select({
|
|
788
|
+
message: "Select environment:",
|
|
789
|
+
choices,
|
|
790
|
+
default: defaultEnv
|
|
791
|
+
});
|
|
792
|
+
return env;
|
|
793
|
+
}
|
|
733
794
|
var MAX_DESCRIPTION_LENGTH = 1e3;
|
|
734
795
|
var MAX_IMAGE_SIZE = 4 * 1024 * 1024;
|
|
735
796
|
var VALID_IMAGE_EXTENSIONS = [".jpg", ".jpeg", ".png"];
|
|
@@ -957,7 +1018,8 @@ var commonFlags = {
|
|
|
957
1018
|
environment: Flags.string({
|
|
958
1019
|
required: false,
|
|
959
1020
|
description: "Deployment environment to use",
|
|
960
|
-
env: "ECLOUD_ENV"
|
|
1021
|
+
env: "ECLOUD_ENV",
|
|
1022
|
+
default: async () => getDefaultEnvironment() || (getBuildType3() === "dev" ? "sepolia-dev" : "sepolia")
|
|
961
1023
|
}),
|
|
962
1024
|
"private-key": Flags.string({
|
|
963
1025
|
required: false,
|
|
@@ -975,6 +1037,41 @@ var commonFlags = {
|
|
|
975
1037
|
default: false
|
|
976
1038
|
})
|
|
977
1039
|
};
|
|
1040
|
+
async function validateCommonFlags(flags) {
|
|
1041
|
+
flags["environment"] = await getEnvironmentInteractive(flags["environment"]);
|
|
1042
|
+
flags["private-key"] = await getPrivateKeyInteractive(flags["private-key"]);
|
|
1043
|
+
return flags;
|
|
1044
|
+
}
|
|
1045
|
+
|
|
1046
|
+
// src/client.ts
|
|
1047
|
+
import {
|
|
1048
|
+
createComputeModule,
|
|
1049
|
+
createBillingModule,
|
|
1050
|
+
getEnvironmentConfig as getEnvironmentConfig2,
|
|
1051
|
+
requirePrivateKey,
|
|
1052
|
+
getPrivateKeyWithSource
|
|
1053
|
+
} from "@layr-labs/ecloud-sdk";
|
|
1054
|
+
async function createComputeClient(flags) {
|
|
1055
|
+
flags = await validateCommonFlags(flags);
|
|
1056
|
+
const environment = flags.environment;
|
|
1057
|
+
const environmentConfig = getEnvironmentConfig2(environment);
|
|
1058
|
+
const rpcUrl = flags["rpc-url"] || environmentConfig.defaultRPCURL;
|
|
1059
|
+
const { key: privateKey, source } = await requirePrivateKey({
|
|
1060
|
+
privateKey: flags["private-key"]
|
|
1061
|
+
});
|
|
1062
|
+
if (flags.verbose) {
|
|
1063
|
+
console.log(`Using private key from: ${source}`);
|
|
1064
|
+
}
|
|
1065
|
+
return createComputeModule({
|
|
1066
|
+
verbose: flags.verbose,
|
|
1067
|
+
privateKey,
|
|
1068
|
+
rpcUrl,
|
|
1069
|
+
environment,
|
|
1070
|
+
clientId: getClientId(),
|
|
1071
|
+
skipTelemetry: true
|
|
1072
|
+
// CLI already has telemetry, skip SDK telemetry
|
|
1073
|
+
});
|
|
1074
|
+
}
|
|
978
1075
|
|
|
979
1076
|
// src/commands/compute/app/deploy.ts
|
|
980
1077
|
import chalk from "chalk";
|
|
@@ -1045,16 +1142,11 @@ var AppDeploy = class _AppDeploy extends Command {
|
|
|
1045
1142
|
async run() {
|
|
1046
1143
|
return withTelemetry(this, async () => {
|
|
1047
1144
|
const { flags } = await this.parse(_AppDeploy);
|
|
1048
|
-
const
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
error: (msg) => this.error(msg),
|
|
1052
|
-
debug: (msg) => flags.verbose && this.log(msg)
|
|
1053
|
-
};
|
|
1054
|
-
const environment = flags.environment || "sepolia";
|
|
1055
|
-
const environmentConfig = getEnvironmentConfig2(environment);
|
|
1145
|
+
const compute = await createComputeClient(flags);
|
|
1146
|
+
const environment = flags.environment;
|
|
1147
|
+
const environmentConfig = getEnvironmentConfig3(environment);
|
|
1056
1148
|
const rpcUrl = flags["rpc-url"] || environmentConfig.defaultRPCURL;
|
|
1057
|
-
const privateKey =
|
|
1149
|
+
const privateKey = flags["private-key"];
|
|
1058
1150
|
const dockerfilePath = await getDockerfileInteractive(flags.dockerfile);
|
|
1059
1151
|
const buildFromDockerfile = dockerfilePath !== "";
|
|
1060
1152
|
const imageRef = await getImageReferenceInteractive(flags["image-ref"], buildFromDockerfile);
|
|
@@ -1078,22 +1170,15 @@ var AppDeploy = class _AppDeploy extends Command {
|
|
|
1078
1170
|
flags["resource-usage-monitoring"]
|
|
1079
1171
|
);
|
|
1080
1172
|
const logVisibility = logSettings.publicLogs ? "public" : logSettings.logRedirect ? "private" : "off";
|
|
1081
|
-
const { prepared, gasEstimate } = await prepareDeploy(
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
instanceType,
|
|
1091
|
-
logVisibility,
|
|
1092
|
-
resourceUsageMonitoring,
|
|
1093
|
-
skipTelemetry: true
|
|
1094
|
-
},
|
|
1095
|
-
logger
|
|
1096
|
-
);
|
|
1173
|
+
const { prepared, gasEstimate } = await compute.app.prepareDeploy({
|
|
1174
|
+
name: appName,
|
|
1175
|
+
dockerfile: dockerfilePath,
|
|
1176
|
+
imageRef,
|
|
1177
|
+
envFile: envFilePath,
|
|
1178
|
+
instanceType,
|
|
1179
|
+
logVisibility,
|
|
1180
|
+
resourceUsageMonitoring
|
|
1181
|
+
});
|
|
1097
1182
|
this.log(`
|
|
1098
1183
|
Estimated transaction cost: ${chalk.cyan(gasEstimate.maxCostEth)} ETH`);
|
|
1099
1184
|
if (isMainnet(environmentConfig)) {
|
|
@@ -1104,16 +1189,10 @@ ${chalk.gray(`Deployment cancelled`)}`);
|
|
|
1104
1189
|
return;
|
|
1105
1190
|
}
|
|
1106
1191
|
}
|
|
1107
|
-
const res = await executeDeploy(
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
maxPriorityFeePerGas: gasEstimate.maxPriorityFeePerGas
|
|
1112
|
-
},
|
|
1113
|
-
logger,
|
|
1114
|
-
true
|
|
1115
|
-
// skipTelemetry
|
|
1116
|
-
);
|
|
1192
|
+
const res = await compute.app.executeDeploy(prepared, {
|
|
1193
|
+
maxFeePerGas: gasEstimate.maxFeePerGas,
|
|
1194
|
+
maxPriorityFeePerGas: gasEstimate.maxPriorityFeePerGas
|
|
1195
|
+
});
|
|
1117
1196
|
if (!flags["skip-profile"]) {
|
|
1118
1197
|
const hasProfileFlags = flags.website || flags.description || flags["x-url"] || flags.image;
|
|
1119
1198
|
let profile = null;
|
|
@@ -1132,47 +1211,35 @@ ${chalk.gray(`Deployment cancelled`)}`);
|
|
|
1132
1211
|
try {
|
|
1133
1212
|
profile = await getAppProfileInteractive(appName, true) || null;
|
|
1134
1213
|
} catch {
|
|
1135
|
-
|
|
1214
|
+
if (flags.verbose) {
|
|
1215
|
+
this.log("Profile collection skipped or cancelled");
|
|
1216
|
+
}
|
|
1136
1217
|
}
|
|
1137
1218
|
}
|
|
1138
1219
|
if (profile) {
|
|
1139
|
-
|
|
1220
|
+
this.log("Uploading app profile...");
|
|
1140
1221
|
try {
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
privateKey,
|
|
1144
|
-
rpcUrl,
|
|
1145
|
-
getClientId()
|
|
1146
|
-
);
|
|
1147
|
-
await userApiClient.uploadAppProfile(
|
|
1148
|
-
res.appId,
|
|
1149
|
-
profile.name,
|
|
1150
|
-
profile.website,
|
|
1151
|
-
profile.description,
|
|
1152
|
-
profile.xURL,
|
|
1153
|
-
profile.imagePath
|
|
1154
|
-
);
|
|
1155
|
-
logger.info("\u2713 Profile uploaded successfully");
|
|
1222
|
+
await compute.app.setProfile(res.appId, profile);
|
|
1223
|
+
this.log("\u2713 Profile uploaded successfully");
|
|
1156
1224
|
try {
|
|
1157
1225
|
invalidateProfileCache(environment);
|
|
1158
1226
|
} catch (cacheErr) {
|
|
1159
|
-
|
|
1227
|
+
if (flags.verbose) {
|
|
1228
|
+
this.log(`Failed to invalidate profile cache: ${cacheErr.message}`);
|
|
1229
|
+
}
|
|
1160
1230
|
}
|
|
1161
1231
|
} catch (uploadErr) {
|
|
1162
|
-
|
|
1232
|
+
this.warn(`Failed to upload profile: ${uploadErr.message}`);
|
|
1163
1233
|
}
|
|
1164
1234
|
}
|
|
1165
1235
|
}
|
|
1166
|
-
const ipAddress = await watchDeployment(
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
logger
|
|
1172
|
-
|
|
1173
|
-
true
|
|
1174
|
-
// skipTelemetry - CLI already has telemetry
|
|
1175
|
-
);
|
|
1236
|
+
const ipAddress = await compute.app.watchDeployment(res.appId);
|
|
1237
|
+
try {
|
|
1238
|
+
const cwd = process.env.INIT_CWD || process.cwd();
|
|
1239
|
+
setLinkedAppForDirectory(environment, cwd, res.appId);
|
|
1240
|
+
} catch (err) {
|
|
1241
|
+
logger.debug(`Failed to link directory to app: ${err.message}`);
|
|
1242
|
+
}
|
|
1176
1243
|
this.log(
|
|
1177
1244
|
`
|
|
1178
1245
|
\u2705 ${chalk.green(`App deployed successfully ${chalk.bold(`(id: ${res.appId}, ip: ${ipAddress})`)}`)}`
|