@turboops/cli 1.0.0-dev.579 → 1.0.0-dev.580
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/dist/index.js +250 -101
- package/package.json +2 -1
package/dist/index.js
CHANGED
|
@@ -196,6 +196,10 @@ var API_URLS = {
|
|
|
196
196
|
production: "https://api.turbo-ops.de",
|
|
197
197
|
dev: "https://api.dev.turbo-ops.de"
|
|
198
198
|
};
|
|
199
|
+
var APP_URLS = {
|
|
200
|
+
production: "https://turbo-ops.de",
|
|
201
|
+
dev: "https://dev.turbo-ops.de"
|
|
202
|
+
};
|
|
199
203
|
function getDefaultApiUrl() {
|
|
200
204
|
const version = getCurrentVersion();
|
|
201
205
|
const isDevVersion = version.includes("-dev");
|
|
@@ -232,6 +236,15 @@ var configService = {
|
|
|
232
236
|
setApiUrl(url) {
|
|
233
237
|
config.set("apiUrl", url);
|
|
234
238
|
},
|
|
239
|
+
/**
|
|
240
|
+
* Get App URL (frontend)
|
|
241
|
+
* Returns the appropriate frontend URL based on CLI version
|
|
242
|
+
*/
|
|
243
|
+
getAppUrl() {
|
|
244
|
+
const version = getCurrentVersion();
|
|
245
|
+
const isDevVersion = version.includes("-dev");
|
|
246
|
+
return isDevVersion ? APP_URLS.dev : APP_URLS.production;
|
|
247
|
+
},
|
|
235
248
|
/**
|
|
236
249
|
* Get authentication token
|
|
237
250
|
*/
|
|
@@ -336,7 +349,6 @@ var configService = {
|
|
|
336
349
|
|
|
337
350
|
// src/commands/login.ts
|
|
338
351
|
import { Command } from "commander";
|
|
339
|
-
import prompts from "prompts";
|
|
340
352
|
|
|
341
353
|
// src/services/api.ts
|
|
342
354
|
function isProjectToken(token) {
|
|
@@ -634,6 +646,137 @@ var apiClient = {
|
|
|
634
646
|
}
|
|
635
647
|
};
|
|
636
648
|
|
|
649
|
+
// src/services/auth.ts
|
|
650
|
+
import os from "os";
|
|
651
|
+
var authService = {
|
|
652
|
+
/**
|
|
653
|
+
* Start browser-based authentication flow
|
|
654
|
+
* Returns the auth code and URL for the browser
|
|
655
|
+
*/
|
|
656
|
+
async initAuth() {
|
|
657
|
+
const apiUrl = configService.getApiUrl();
|
|
658
|
+
const version = getCurrentVersion();
|
|
659
|
+
const platform = os.platform();
|
|
660
|
+
const hostname = os.hostname();
|
|
661
|
+
try {
|
|
662
|
+
const response = await fetch(`${apiUrl}/cli/auth/init`, {
|
|
663
|
+
body: JSON.stringify({
|
|
664
|
+
cliVersion: version,
|
|
665
|
+
hostname,
|
|
666
|
+
platform
|
|
667
|
+
}),
|
|
668
|
+
headers: {
|
|
669
|
+
"Content-Type": "application/json"
|
|
670
|
+
},
|
|
671
|
+
method: "POST"
|
|
672
|
+
});
|
|
673
|
+
if (!response.ok) {
|
|
674
|
+
return null;
|
|
675
|
+
}
|
|
676
|
+
return await response.json();
|
|
677
|
+
} catch {
|
|
678
|
+
return null;
|
|
679
|
+
}
|
|
680
|
+
},
|
|
681
|
+
/**
|
|
682
|
+
* Poll for authentication status
|
|
683
|
+
*/
|
|
684
|
+
async pollAuth(code, pollToken) {
|
|
685
|
+
const apiUrl = configService.getApiUrl();
|
|
686
|
+
try {
|
|
687
|
+
const response = await fetch(`${apiUrl}/cli/auth/poll/${code}`, {
|
|
688
|
+
headers: {
|
|
689
|
+
"X-Poll-Token": pollToken
|
|
690
|
+
}
|
|
691
|
+
});
|
|
692
|
+
if (!response.ok) {
|
|
693
|
+
return { status: "expired" };
|
|
694
|
+
}
|
|
695
|
+
return await response.json();
|
|
696
|
+
} catch {
|
|
697
|
+
return { status: "expired" };
|
|
698
|
+
}
|
|
699
|
+
},
|
|
700
|
+
/**
|
|
701
|
+
* Validate a CLI token
|
|
702
|
+
*/
|
|
703
|
+
async validateToken(token) {
|
|
704
|
+
const apiUrl = configService.getApiUrl();
|
|
705
|
+
try {
|
|
706
|
+
const response = await fetch(`${apiUrl}/cli/auth/validate`, {
|
|
707
|
+
headers: {
|
|
708
|
+
Authorization: `Bearer ${token}`
|
|
709
|
+
}
|
|
710
|
+
});
|
|
711
|
+
if (!response.ok) {
|
|
712
|
+
return { valid: false };
|
|
713
|
+
}
|
|
714
|
+
return await response.json();
|
|
715
|
+
} catch {
|
|
716
|
+
return { valid: false };
|
|
717
|
+
}
|
|
718
|
+
},
|
|
719
|
+
/**
|
|
720
|
+
* Perform browser-based login
|
|
721
|
+
* Opens browser, waits for user to authorize, returns user info
|
|
722
|
+
*/
|
|
723
|
+
async browserLogin() {
|
|
724
|
+
const open = (await import("open")).default;
|
|
725
|
+
logger.info("Initialisiere Anmeldung...");
|
|
726
|
+
const authInit = await this.initAuth();
|
|
727
|
+
if (!authInit) {
|
|
728
|
+
return { error: "Konnte Authentifizierung nicht initialisieren", success: false };
|
|
729
|
+
}
|
|
730
|
+
logger.newline();
|
|
731
|
+
logger.info("Bitte autorisieren Sie die CLI in Ihrem Browser.");
|
|
732
|
+
logger.newline();
|
|
733
|
+
logger.info(`Autorisierungscode: ${authInit.code}`);
|
|
734
|
+
logger.newline();
|
|
735
|
+
try {
|
|
736
|
+
await open(authInit.authUrl);
|
|
737
|
+
logger.info("Browser wurde ge\xF6ffnet...");
|
|
738
|
+
} catch {
|
|
739
|
+
logger.warning("Browser konnte nicht ge\xF6ffnet werden.");
|
|
740
|
+
logger.info(`Bitte \xF6ffnen Sie diese URL manuell: ${authInit.authUrl}`);
|
|
741
|
+
}
|
|
742
|
+
logger.newline();
|
|
743
|
+
logger.info("Warte auf Autorisierung...");
|
|
744
|
+
const maxAttempts = 150;
|
|
745
|
+
const pollInterval = 2e3;
|
|
746
|
+
for (let attempt = 0; attempt < maxAttempts; attempt++) {
|
|
747
|
+
const result = await this.pollAuth(authInit.code, authInit.pollToken);
|
|
748
|
+
if (result.status === "authorized" && result.token) {
|
|
749
|
+
configService.setToken(result.token);
|
|
750
|
+
if (result.user) {
|
|
751
|
+
configService.setUserId(result.user.id);
|
|
752
|
+
}
|
|
753
|
+
return {
|
|
754
|
+
success: true,
|
|
755
|
+
user: result.user
|
|
756
|
+
};
|
|
757
|
+
}
|
|
758
|
+
if (result.status === "expired" || result.status === "consumed") {
|
|
759
|
+
return { error: "Autorisierungscode abgelaufen oder bereits verwendet", success: false };
|
|
760
|
+
}
|
|
761
|
+
await new Promise((resolve) => setTimeout(resolve, pollInterval));
|
|
762
|
+
}
|
|
763
|
+
return { error: "Zeit\xFCberschreitung bei der Anmeldung", success: false };
|
|
764
|
+
},
|
|
765
|
+
/**
|
|
766
|
+
* Check if current token is a CLI token and validate it
|
|
767
|
+
*/
|
|
768
|
+
async checkCliToken() {
|
|
769
|
+
const token = configService.getToken();
|
|
770
|
+
if (!token) {
|
|
771
|
+
return { valid: false };
|
|
772
|
+
}
|
|
773
|
+
if (!token.startsWith("turbo_cli_")) {
|
|
774
|
+
return { valid: true };
|
|
775
|
+
}
|
|
776
|
+
return await this.validateToken(token);
|
|
777
|
+
}
|
|
778
|
+
};
|
|
779
|
+
|
|
637
780
|
// src/utils/spinner.ts
|
|
638
781
|
import ora from "ora";
|
|
639
782
|
function createSpinner(text) {
|
|
@@ -660,60 +803,59 @@ var loginCommand = new Command("login").description("Authenticate with TurboOps
|
|
|
660
803
|
logger.header("TurboOps Login");
|
|
661
804
|
if (options.token) {
|
|
662
805
|
configService.setToken(options.token);
|
|
663
|
-
|
|
806
|
+
if (options.token.startsWith("turbo_cli_")) {
|
|
807
|
+
const { data: data2, error: error2 } = await withSpinner("Verifying token...", async () => {
|
|
808
|
+
const result2 = await authService.validateToken(options.token);
|
|
809
|
+
if (result2.valid && result2.user) {
|
|
810
|
+
return { data: result2.user, error: void 0 };
|
|
811
|
+
}
|
|
812
|
+
return { data: void 0, error: "Invalid token" };
|
|
813
|
+
});
|
|
814
|
+
if (error2 || !data2) {
|
|
815
|
+
configService.clearToken();
|
|
816
|
+
logger.error(`Authentication failed: ${error2 || "Invalid token"}`);
|
|
817
|
+
process.exit(10 /* AUTH_ERROR */);
|
|
818
|
+
}
|
|
819
|
+
configService.setUserId(data2.id);
|
|
820
|
+
addJsonData({
|
|
821
|
+
authenticated: true,
|
|
822
|
+
user: { email: data2.email, id: data2.id }
|
|
823
|
+
});
|
|
824
|
+
logger.success(`Authenticated as ${data2.email}`);
|
|
825
|
+
return;
|
|
826
|
+
}
|
|
827
|
+
const { data, error } = await withSpinner(
|
|
664
828
|
"Verifying token...",
|
|
665
829
|
() => apiClient.whoami()
|
|
666
830
|
);
|
|
667
|
-
if (
|
|
831
|
+
if (error || !data) {
|
|
668
832
|
configService.clearToken();
|
|
669
|
-
logger.error(`Authentication failed: ${
|
|
833
|
+
logger.error(`Authentication failed: ${error || "Invalid token"}`);
|
|
670
834
|
process.exit(10 /* AUTH_ERROR */);
|
|
671
835
|
}
|
|
672
|
-
configService.setUserId(
|
|
836
|
+
configService.setUserId(data.id);
|
|
673
837
|
addJsonData({
|
|
674
838
|
authenticated: true,
|
|
675
|
-
user: {
|
|
839
|
+
user: { email: data.email, id: data.id }
|
|
676
840
|
});
|
|
677
|
-
logger.success(`Authenticated as ${
|
|
841
|
+
logger.success(`Authenticated as ${data.email}`);
|
|
678
842
|
return;
|
|
679
843
|
}
|
|
680
|
-
const
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
message: "Email:",
|
|
685
|
-
validate: (value) => value.includes("@") || "Please enter a valid email"
|
|
686
|
-
},
|
|
687
|
-
{
|
|
688
|
-
type: "password",
|
|
689
|
-
name: "password",
|
|
690
|
-
message: "Password:"
|
|
691
|
-
}
|
|
692
|
-
]);
|
|
693
|
-
if (!response.email || !response.password) {
|
|
694
|
-
logger.warning("Login cancelled");
|
|
695
|
-
addJsonData({ authenticated: false, cancelled: true });
|
|
696
|
-
return;
|
|
697
|
-
}
|
|
698
|
-
const { data, error } = await withSpinner(
|
|
699
|
-
"Logging in...",
|
|
700
|
-
() => apiClient.login(response.email, response.password)
|
|
701
|
-
);
|
|
702
|
-
if (error || !data) {
|
|
703
|
-
logger.error(`Login failed: ${error || "Unknown error"}`);
|
|
704
|
-
addJsonData({ authenticated: false, error: error || "Unknown error" });
|
|
844
|
+
const result = await authService.browserLogin();
|
|
845
|
+
if (!result.success) {
|
|
846
|
+
logger.error(`Login failed: ${result.error || "Unknown error"}`);
|
|
847
|
+
addJsonData({ authenticated: false, error: result.error || "Unknown error" });
|
|
705
848
|
process.exit(10 /* AUTH_ERROR */);
|
|
706
849
|
}
|
|
707
|
-
configService.setToken(data.token);
|
|
708
|
-
configService.setUserId(data.user.id);
|
|
709
850
|
addJsonData({
|
|
710
851
|
authenticated: true,
|
|
711
|
-
user: {
|
|
852
|
+
user: result.user ? { email: result.user.email, fullName: result.user.fullName, id: result.user.id } : void 0
|
|
712
853
|
});
|
|
713
|
-
logger.success(`Logged in as ${data.user.email}`);
|
|
714
854
|
logger.newline();
|
|
715
|
-
logger.
|
|
716
|
-
logger.
|
|
855
|
+
logger.success(`Angemeldet als ${result.user?.email || "Unknown"}`);
|
|
856
|
+
logger.newline();
|
|
857
|
+
logger.info("Ihre Anmeldedaten wurden gespeichert.");
|
|
858
|
+
logger.info("F\xFChren Sie `turbo whoami` aus, um Ihre Authentifizierung zu \xFCberpr\xFCfen.");
|
|
717
859
|
});
|
|
718
860
|
var logoutCommand = new Command("logout").description("Remove stored authentication").action(() => {
|
|
719
861
|
configService.clearToken();
|
|
@@ -726,6 +868,36 @@ var whoamiCommand = new Command("whoami").description("Show current authenticate
|
|
|
726
868
|
addJsonData({ authenticated: false });
|
|
727
869
|
process.exit(10 /* AUTH_ERROR */);
|
|
728
870
|
}
|
|
871
|
+
const token = configService.getToken();
|
|
872
|
+
if (token?.startsWith("turbo_cli_")) {
|
|
873
|
+
const { data: data2, error: error2 } = await withSpinner("Fetching user info...", async () => {
|
|
874
|
+
const result = await authService.validateToken(token);
|
|
875
|
+
if (result.valid && result.user) {
|
|
876
|
+
return { data: result.user, error: void 0 };
|
|
877
|
+
}
|
|
878
|
+
return { data: void 0, error: "Invalid token" };
|
|
879
|
+
});
|
|
880
|
+
if (error2 || !data2) {
|
|
881
|
+
logger.error(`Failed to fetch user info: ${error2 || "Unknown error"}`);
|
|
882
|
+
addJsonData({ authenticated: false, error: error2 || "Unknown error" });
|
|
883
|
+
process.exit(13 /* API_ERROR */);
|
|
884
|
+
}
|
|
885
|
+
addJsonData({
|
|
886
|
+
authenticated: true,
|
|
887
|
+
user: {
|
|
888
|
+
email: data2.email,
|
|
889
|
+
id: data2.id,
|
|
890
|
+
name: data2.fullName || null
|
|
891
|
+
}
|
|
892
|
+
});
|
|
893
|
+
logger.header("Current User");
|
|
894
|
+
logger.table({
|
|
895
|
+
Email: data2.email,
|
|
896
|
+
ID: data2.id,
|
|
897
|
+
Name: data2.fullName || "-"
|
|
898
|
+
});
|
|
899
|
+
return;
|
|
900
|
+
}
|
|
729
901
|
const { data, error } = await withSpinner(
|
|
730
902
|
"Fetching user info...",
|
|
731
903
|
() => apiClient.whoami()
|
|
@@ -738,15 +910,15 @@ var whoamiCommand = new Command("whoami").description("Show current authenticate
|
|
|
738
910
|
addJsonData({
|
|
739
911
|
authenticated: true,
|
|
740
912
|
user: {
|
|
741
|
-
id: data.id,
|
|
742
913
|
email: data.email,
|
|
914
|
+
id: data.id,
|
|
743
915
|
name: data.name || null
|
|
744
916
|
}
|
|
745
917
|
});
|
|
746
918
|
logger.header("Current User");
|
|
747
919
|
logger.table({
|
|
748
|
-
ID: data.id,
|
|
749
920
|
Email: data.email,
|
|
921
|
+
ID: data.id,
|
|
750
922
|
Name: data.name || "-"
|
|
751
923
|
});
|
|
752
924
|
});
|
|
@@ -1151,128 +1323,105 @@ envCommand.addCommand(envUnsetCommand);
|
|
|
1151
1323
|
|
|
1152
1324
|
// src/commands/init.ts
|
|
1153
1325
|
import { Command as Command5 } from "commander";
|
|
1154
|
-
import
|
|
1326
|
+
import prompts from "prompts";
|
|
1155
1327
|
import chalk6 from "chalk";
|
|
1156
1328
|
var initCommand = new Command5("init").description("Initialize TurboOps project in current directory").action(async () => {
|
|
1157
1329
|
logger.header("TurboOps Project Initialization");
|
|
1158
1330
|
if (!configService.isAuthenticated()) {
|
|
1159
|
-
logger.warning("
|
|
1331
|
+
logger.warning("Nicht authentifiziert. Bitte melden Sie sich zuerst an.");
|
|
1160
1332
|
logger.newline();
|
|
1161
|
-
const { shouldLogin } = await
|
|
1162
|
-
|
|
1333
|
+
const { shouldLogin } = await prompts({
|
|
1334
|
+
initial: true,
|
|
1335
|
+
message: "M\xF6chten Sie sich jetzt anmelden?",
|
|
1163
1336
|
name: "shouldLogin",
|
|
1164
|
-
|
|
1165
|
-
initial: true
|
|
1337
|
+
type: "confirm"
|
|
1166
1338
|
});
|
|
1167
1339
|
if (!shouldLogin) {
|
|
1168
|
-
logger.info("
|
|
1340
|
+
logger.info("F\xFChren Sie `turbo login` aus, wenn Sie bereit sind.");
|
|
1169
1341
|
addJsonData({ initialized: false, reason: "not_authenticated" });
|
|
1170
1342
|
return;
|
|
1171
1343
|
}
|
|
1172
|
-
const
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
name: "email",
|
|
1176
|
-
message: "Email:",
|
|
1177
|
-
validate: (value) => value.includes("@") || "Please enter a valid email"
|
|
1178
|
-
},
|
|
1179
|
-
{
|
|
1180
|
-
type: "password",
|
|
1181
|
-
name: "password",
|
|
1182
|
-
message: "Password:"
|
|
1183
|
-
}
|
|
1184
|
-
]);
|
|
1185
|
-
if (!credentials.email || !credentials.password) {
|
|
1186
|
-
logger.warning("Login cancelled");
|
|
1187
|
-
addJsonData({ initialized: false, reason: "login_cancelled" });
|
|
1188
|
-
return;
|
|
1189
|
-
}
|
|
1190
|
-
const { data, error } = await withSpinner(
|
|
1191
|
-
"Logging in...",
|
|
1192
|
-
() => apiClient.login(credentials.email, credentials.password)
|
|
1193
|
-
);
|
|
1194
|
-
if (error || !data) {
|
|
1195
|
-
logger.error(`Login failed: ${error || "Unknown error"}`);
|
|
1344
|
+
const result = await authService.browserLogin();
|
|
1345
|
+
if (!result.success) {
|
|
1346
|
+
logger.error(`Anmeldung fehlgeschlagen: ${result.error || "Unbekannter Fehler"}`);
|
|
1196
1347
|
addJsonData({
|
|
1348
|
+
error: result.error || "Unknown error",
|
|
1197
1349
|
initialized: false,
|
|
1198
|
-
reason: "login_failed"
|
|
1199
|
-
error: error || "Unknown error"
|
|
1350
|
+
reason: "login_failed"
|
|
1200
1351
|
});
|
|
1201
1352
|
process.exit(10 /* AUTH_ERROR */);
|
|
1202
1353
|
}
|
|
1203
|
-
|
|
1204
|
-
configService.setUserId(data.user.id);
|
|
1205
|
-
logger.success(`Logged in as ${data.user.email}`);
|
|
1354
|
+
logger.success(`Angemeldet als ${result.user?.email || "Unknown"}`);
|
|
1206
1355
|
}
|
|
1207
1356
|
logger.newline();
|
|
1208
|
-
const { projectSlug } = await
|
|
1209
|
-
|
|
1357
|
+
const { projectSlug } = await prompts({
|
|
1358
|
+
hint: "Der Slug Ihres TurboOps-Projekts",
|
|
1359
|
+
message: "Projekt-Slug:",
|
|
1210
1360
|
name: "projectSlug",
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
validate: (value) => value.length > 0 || "Project slug is required"
|
|
1361
|
+
type: "text",
|
|
1362
|
+
validate: (value) => value.length > 0 || "Projekt-Slug ist erforderlich"
|
|
1214
1363
|
});
|
|
1215
1364
|
if (!projectSlug) {
|
|
1216
|
-
logger.warning("
|
|
1365
|
+
logger.warning("Initialisierung abgebrochen");
|
|
1217
1366
|
addJsonData({ initialized: false, reason: "cancelled" });
|
|
1218
1367
|
return;
|
|
1219
1368
|
}
|
|
1220
1369
|
const { data: project, error: projectError } = await withSpinner(
|
|
1221
|
-
"
|
|
1370
|
+
"Verifiziere Projekt...",
|
|
1222
1371
|
() => apiClient.getProject(projectSlug)
|
|
1223
1372
|
);
|
|
1224
1373
|
if (projectError || !project) {
|
|
1225
1374
|
logger.error(
|
|
1226
|
-
`
|
|
1375
|
+
`Projekt "${projectSlug}" nicht gefunden oder Sie haben keinen Zugriff.`
|
|
1227
1376
|
);
|
|
1228
1377
|
logger.info(
|
|
1229
|
-
"
|
|
1378
|
+
"Stellen Sie sicher, dass das Projekt in TurboOps existiert und Sie die Berechtigung haben, darauf zuzugreifen."
|
|
1230
1379
|
);
|
|
1231
1380
|
addJsonData({
|
|
1232
1381
|
initialized: false,
|
|
1233
|
-
|
|
1234
|
-
|
|
1382
|
+
projectSlug,
|
|
1383
|
+
reason: "project_not_found"
|
|
1235
1384
|
});
|
|
1236
1385
|
process.exit(12 /* NOT_FOUND */);
|
|
1237
1386
|
}
|
|
1238
1387
|
configService.setProject(projectSlug);
|
|
1239
1388
|
logger.newline();
|
|
1240
|
-
logger.success("
|
|
1389
|
+
logger.success("Projekt initialisiert!");
|
|
1241
1390
|
logger.newline();
|
|
1242
|
-
logger.header("
|
|
1391
|
+
logger.header("Projektdetails");
|
|
1243
1392
|
logger.table({
|
|
1244
1393
|
Name: project.name,
|
|
1245
|
-
|
|
1246
|
-
|
|
1394
|
+
Repository: project.repositoryUrl || "-",
|
|
1395
|
+
Slug: project.slug
|
|
1247
1396
|
});
|
|
1248
1397
|
const { data: environments } = await apiClient.getEnvironments(project.id);
|
|
1249
1398
|
const envList = environments && environments.length > 0 ? environments.map((env) => ({
|
|
1250
|
-
slug: env.slug,
|
|
1251
1399
|
name: env.name,
|
|
1400
|
+
slug: env.slug,
|
|
1252
1401
|
type: env.type
|
|
1253
1402
|
})) : [];
|
|
1254
1403
|
addJsonData({
|
|
1404
|
+
environments: envList,
|
|
1255
1405
|
initialized: true,
|
|
1256
1406
|
project: {
|
|
1257
1407
|
name: project.name,
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
}
|
|
1261
|
-
environments: envList
|
|
1408
|
+
repositoryUrl: project.repositoryUrl || null,
|
|
1409
|
+
slug: project.slug
|
|
1410
|
+
}
|
|
1262
1411
|
});
|
|
1263
1412
|
if (environments && environments.length > 0) {
|
|
1264
1413
|
logger.newline();
|
|
1265
|
-
logger.header("
|
|
1414
|
+
logger.header("Verf\xFCgbare Umgebungen");
|
|
1266
1415
|
for (const env of environments) {
|
|
1267
1416
|
console.log(` ${chalk6.bold(env.slug)} - ${env.name} (${env.type})`);
|
|
1268
1417
|
}
|
|
1269
1418
|
}
|
|
1270
1419
|
logger.newline();
|
|
1271
|
-
logger.header("
|
|
1420
|
+
logger.header("N\xE4chste Schritte");
|
|
1272
1421
|
logger.list([
|
|
1273
|
-
"
|
|
1274
|
-
"
|
|
1275
|
-
"
|
|
1422
|
+
"F\xFChren Sie `turbo status` aus, um alle Umgebungen zu sehen",
|
|
1423
|
+
"F\xFChren Sie `turbo deploy <umgebung>` aus, um zu deployen",
|
|
1424
|
+
"F\xFChren Sie `turbo logs <umgebung>` aus, um Logs anzuzeigen"
|
|
1276
1425
|
]);
|
|
1277
1426
|
});
|
|
1278
1427
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@turboops/cli",
|
|
3
|
-
"version": "1.0.0-dev.
|
|
3
|
+
"version": "1.0.0-dev.580",
|
|
4
4
|
"description": "TurboCLI - Command line interface for TurboOps deployments",
|
|
5
5
|
"author": "lenne.tech GmbH",
|
|
6
6
|
"license": "MIT",
|
|
@@ -26,6 +26,7 @@
|
|
|
26
26
|
"chalk": "^5.3.0",
|
|
27
27
|
"commander": "^12.1.0",
|
|
28
28
|
"conf": "^13.0.1",
|
|
29
|
+
"open": "^10.1.0",
|
|
29
30
|
"ora": "^8.0.1",
|
|
30
31
|
"prompts": "^2.4.2",
|
|
31
32
|
"socket.io-client": "^4.7.0"
|