simplemdg-dev-cli 2.5.0 → 2.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 +33 -0
- package/USER_GUIDE.md +58 -1
- package/dist/commands/cache.command.d.ts +2 -0
- package/dist/commands/cache.command.js +129 -0
- package/dist/commands/cache.command.js.map +1 -0
- package/dist/commands/cf.command.js +201 -122
- package/dist/commands/cf.command.js.map +1 -1
- package/dist/commands/gitlab.command.js +33 -23
- package/dist/commands/gitlab.command.js.map +1 -1
- package/dist/core/cache/smart-cache-events.d.ts +3 -0
- package/dist/core/cache/smart-cache-events.js +20 -0
- package/dist/core/cache/smart-cache-events.js.map +1 -0
- package/dist/core/cache/smart-cache-manager.d.ts +20 -0
- package/dist/core/cache/smart-cache-manager.js +148 -0
- package/dist/core/cache/smart-cache-manager.js.map +1 -0
- package/dist/core/cache/smart-cache-store.d.ts +8 -0
- package/dist/core/cache/smart-cache-store.js +74 -0
- package/dist/core/cache/smart-cache-store.js.map +1 -0
- package/dist/core/cache/smart-cache.d.ts +18 -0
- package/dist/core/cache/smart-cache.js +117 -0
- package/dist/core/cache/smart-cache.js.map +1 -0
- package/dist/core/cache/smart-cache.types.d.ts +62 -0
- package/dist/core/cache/smart-cache.types.js +17 -0
- package/dist/core/cache/smart-cache.types.js.map +1 -0
- package/dist/core/cf/cf-target-cache.d.ts +7 -0
- package/dist/core/cf/cf-target-cache.js +58 -0
- package/dist/core/cf/cf-target-cache.js.map +1 -0
- package/dist/core/cf/cf-target.types.d.ts +11 -0
- package/dist/core/cf/cf-target.types.js +11 -0
- package/dist/core/cf/cf-target.types.js.map +1 -0
- package/dist/core/db/db-studio-client.d.ts +1 -1
- package/dist/core/db/db-studio-client.js +250 -55
- package/dist/core/db/db-studio-client.js.map +1 -1
- package/dist/core/db/db-studio-server.js +171 -0
- package/dist/core/db/db-studio-server.js.map +1 -1
- package/dist/core/db/db-studio-styles.d.ts +1 -1
- package/dist/core/db/db-studio-styles.js +63 -0
- package/dist/core/db/db-studio-styles.js.map +1 -1
- package/dist/core/db/db-types.d.ts +54 -0
- package/dist/core/db/studio/sql-formatter.d.ts +25 -0
- package/dist/core/db/studio/sql-formatter.js +139 -0
- package/dist/core/db/studio/sql-formatter.js.map +1 -0
- package/dist/core/db/studio/studio-settings.d.ts +4 -0
- package/dist/core/db/studio/studio-settings.js +39 -0
- package/dist/core/db/studio/studio-settings.js.map +1 -0
- package/dist/core/db/studio/workspace-cache.d.ts +3 -0
- package/dist/core/db/studio/workspace-cache.js +51 -0
- package/dist/core/db/studio/workspace-cache.js.map +1 -0
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/commands/cache.command.ts +159 -0
- package/src/commands/cf.command.ts +232 -129
- package/src/commands/gitlab.command.ts +37 -21
- package/src/core/cache/smart-cache-events.ts +20 -0
- package/src/core/cache/smart-cache-manager.ts +169 -0
- package/src/core/cache/smart-cache-store.ts +83 -0
- package/src/core/cache/smart-cache.ts +97 -0
- package/src/core/cache/smart-cache.types.ts +79 -0
- package/src/core/cf/cf-target-cache.ts +61 -0
- package/src/core/cf/cf-target.types.ts +17 -0
- package/src/core/db/db-studio-client.ts +250 -55
- package/src/core/db/db-studio-server.ts +156 -1
- package/src/core/db/db-studio-styles.ts +63 -0
- package/src/core/db/db-types.ts +61 -0
- package/src/core/db/studio/sql-formatter.ts +139 -0
- package/src/core/db/studio/studio-settings.ts +36 -0
- package/src/core/db/studio/workspace-cache.ts +51 -0
- package/src/index.ts +3 -1
|
@@ -20,6 +20,9 @@ const process_1 = require("../core/process");
|
|
|
20
20
|
const repository_1 = require("../core/repository");
|
|
21
21
|
const prompts_2 = require("../core/prompts");
|
|
22
22
|
const tooling_1 = require("../core/tooling");
|
|
23
|
+
const smart_cache_1 = require("../core/cache/smart-cache");
|
|
24
|
+
const cf_target_cache_1 = require("../core/cf/cf-target-cache");
|
|
25
|
+
const cf_target_types_1 = require("../core/cf/cf-target.types");
|
|
23
26
|
function validateRequired(value) {
|
|
24
27
|
return value.trim() ? true : "Value is required";
|
|
25
28
|
}
|
|
@@ -907,152 +910,212 @@ async function getCloudFoundryOrganizationsAcrossRegions(options) {
|
|
|
907
910
|
}
|
|
908
911
|
return fallbackEntries;
|
|
909
912
|
}
|
|
913
|
+
function orgEntryToTarget(entry) {
|
|
914
|
+
return { region: entry.region, apiEndpoint: entry.apiEndpoint, org: entry.org, space: "", lastRefreshedAt: entry.updatedAt };
|
|
915
|
+
}
|
|
916
|
+
function dedupeTargets(targets) {
|
|
917
|
+
const seen = new Set();
|
|
918
|
+
const result = [];
|
|
919
|
+
for (const target of targets) {
|
|
920
|
+
const key = (0, cf_target_types_1.cfTargetKey)(target);
|
|
921
|
+
if (seen.has(key))
|
|
922
|
+
continue;
|
|
923
|
+
seen.add(key);
|
|
924
|
+
result.push(target);
|
|
925
|
+
}
|
|
926
|
+
return result;
|
|
927
|
+
}
|
|
928
|
+
async function switchToCfTarget(target, options) {
|
|
929
|
+
const apiEndpoint = target.apiEndpoint;
|
|
930
|
+
if (!apiEndpoint) {
|
|
931
|
+
throw new Error("Cannot determine CF API endpoint for the selected target.");
|
|
932
|
+
}
|
|
933
|
+
const region = target.region || (0, cf_1.inferCloudFoundryRegionFromApiEndpoint)(apiEndpoint);
|
|
934
|
+
const authenticatedProfile = await ensureCloudFoundryAuthenticatedForApiEndpoint({
|
|
935
|
+
apiEndpoint,
|
|
936
|
+
preferredOrg: target.org,
|
|
937
|
+
preferredSpace: options.space ?? target.space,
|
|
938
|
+
reason: "switch-target",
|
|
939
|
+
});
|
|
940
|
+
const orgExitCode = await (0, cf_1.targetCloudFoundryOrg)(target.org);
|
|
941
|
+
if (orgExitCode !== 0) {
|
|
942
|
+
console.log(chalk_1.default.yellow("Cannot switch to this org after automatic authentication."));
|
|
943
|
+
console.log(chalk_1.default.gray("Run smdg cf login, save the password, then try again."));
|
|
944
|
+
process.exitCode = orgExitCode;
|
|
945
|
+
return;
|
|
946
|
+
}
|
|
947
|
+
let space = options.space?.trim() || target.space?.trim() || "";
|
|
948
|
+
if (!space) {
|
|
949
|
+
const spaces = await (0, cf_1.listCloudFoundrySpaces)().catch(() => []);
|
|
950
|
+
const currentAfter = await (0, cf_1.readCloudFoundryTarget)();
|
|
951
|
+
const preferred = currentAfter.space || (spaces.includes("app") ? "app" : spaces[0]);
|
|
952
|
+
space = spaces.length
|
|
953
|
+
? await (0, prompts_2.searchableSelectChoice)({
|
|
954
|
+
message: "Select CF space",
|
|
955
|
+
choices: [
|
|
956
|
+
...spaces.filter((s) => s === preferred).map((s) => ({ title: `${s} ${chalk_1.default.gray("suggested")}`, value: s })),
|
|
957
|
+
...spaces.filter((s) => s !== preferred).map((s) => ({ title: s, value: s })),
|
|
958
|
+
],
|
|
959
|
+
validateCustomValue: validateRequired,
|
|
960
|
+
customValueTitle: (value) => `Use typed CF space: ${value}`,
|
|
961
|
+
})
|
|
962
|
+
: await (0, prompts_2.selectFromHistoryOrInput)({ message: "Enter CF space", values: [], initialValue: "app" });
|
|
963
|
+
}
|
|
964
|
+
if (space) {
|
|
965
|
+
const spaceExitCode = await (0, cf_1.targetCloudFoundrySpace)(space);
|
|
966
|
+
if (spaceExitCode !== 0) {
|
|
967
|
+
process.exitCode = spaceExitCode;
|
|
968
|
+
return;
|
|
969
|
+
}
|
|
970
|
+
}
|
|
971
|
+
await (0, cf_target_cache_1.addRecentTarget)({ region, apiEndpoint, org: target.org, space });
|
|
972
|
+
if (authenticatedProfile?.password) {
|
|
973
|
+
await (0, cache_1.rememberCloudFoundryLoginProfile)({ ...authenticatedProfile, apiEndpoint, org: target.org, space, updatedAt: new Date().toISOString() });
|
|
974
|
+
}
|
|
975
|
+
console.log(chalk_1.default.green("CF target switched."));
|
|
976
|
+
printTarget(await (0, cf_1.readCloudFoundryTarget)());
|
|
977
|
+
if (!(await (0, cf_target_cache_1.isFavoriteTarget)({ region, apiEndpoint, org: target.org, space }))) {
|
|
978
|
+
const favorite = await (0, prompts_1.default)({ type: "confirm", name: "fav", message: "Mark this target as favorite?", initial: false });
|
|
979
|
+
if (favorite.fav) {
|
|
980
|
+
await (0, cf_target_cache_1.addFavoriteTarget)({ region, apiEndpoint, org: target.org, space });
|
|
981
|
+
console.log(chalk_1.default.gray("Added to favorites."));
|
|
982
|
+
}
|
|
983
|
+
}
|
|
984
|
+
}
|
|
985
|
+
async function manageFavoriteTargets(favorites) {
|
|
986
|
+
if (!favorites.length) {
|
|
987
|
+
console.log(chalk_1.default.gray("No favorites yet. Switch to a target and choose to favorite it."));
|
|
988
|
+
return;
|
|
989
|
+
}
|
|
990
|
+
const selected = await (0, prompts_2.searchableSelectChoice)({
|
|
991
|
+
message: "Favorites — select one to remove",
|
|
992
|
+
choices: [
|
|
993
|
+
...favorites.map((target, index) => ({ title: `★ ${(0, cf_target_types_1.cfTargetLabel)(target)}`, value: String(index) })),
|
|
994
|
+
{ title: "Cancel", value: "__cancel__" },
|
|
995
|
+
],
|
|
996
|
+
allowCustomValue: false,
|
|
997
|
+
});
|
|
998
|
+
if (selected === "__cancel__") {
|
|
999
|
+
return;
|
|
1000
|
+
}
|
|
1001
|
+
await (0, cf_target_cache_1.removeFavoriteTarget)(favorites[Number(selected)]);
|
|
1002
|
+
console.log(chalk_1.default.green("Removed from favorites."));
|
|
1003
|
+
}
|
|
1004
|
+
function printTargetSections(favorites, recent, orgEntries, current) {
|
|
1005
|
+
console.log(chalk_1.default.bold("CF Target Switcher"));
|
|
1006
|
+
console.log("");
|
|
1007
|
+
if (favorites.length) {
|
|
1008
|
+
console.log(chalk_1.default.yellow("Favorites"));
|
|
1009
|
+
favorites.forEach((target) => console.log(` ${chalk_1.default.yellow("★")} ${(0, cf_target_types_1.cfTargetLabel)(target)}`));
|
|
1010
|
+
console.log("");
|
|
1011
|
+
}
|
|
1012
|
+
if (recent.length) {
|
|
1013
|
+
console.log(chalk_1.default.cyan("Recent"));
|
|
1014
|
+
recent.forEach((target) => console.log(` ${chalk_1.default.gray("◷")} ${(0, cf_target_types_1.cfTargetLabel)(target)}`));
|
|
1015
|
+
console.log("");
|
|
1016
|
+
}
|
|
1017
|
+
console.log(chalk_1.default.gray(`All Targets (${orgEntries.length})`));
|
|
1018
|
+
for (const entry of orgEntries) {
|
|
1019
|
+
const marker = entry.apiEndpoint === current.apiEndpoint && entry.org === current.org ? chalk_1.default.green("*") : " ";
|
|
1020
|
+
console.log(`${marker} ${entry.region} / ${entry.org}`);
|
|
1021
|
+
}
|
|
1022
|
+
}
|
|
910
1023
|
async function runOrgCommand(options) {
|
|
911
|
-
const
|
|
1024
|
+
const latestTarget = await (0, cf_1.readCloudFoundryTarget)();
|
|
1025
|
+
const favorites = await (0, cf_target_cache_1.listFavoriteTargets)();
|
|
1026
|
+
const recent = await (0, cf_target_cache_1.listRecentTargets)();
|
|
1027
|
+
// Direct switch via flags.
|
|
1028
|
+
if (options.org?.trim()) {
|
|
1029
|
+
await (0, tooling_1.ensureExternalTool)("cf");
|
|
1030
|
+
const apiEndpoint = options.api?.trim() || latestTarget.apiEndpoint || "";
|
|
1031
|
+
const region = (0, cf_1.inferCloudFoundryRegionFromApiEndpoint)(apiEndpoint || "current");
|
|
1032
|
+
await switchToCfTarget({ region, apiEndpoint, org: options.org.trim(), space: options.space?.trim() || "" }, { space: options.space });
|
|
1033
|
+
return;
|
|
1034
|
+
}
|
|
912
1035
|
const action = options.list
|
|
913
1036
|
? "list"
|
|
914
1037
|
: options.switch
|
|
915
1038
|
? "switch"
|
|
916
1039
|
: await (0, prompts_2.searchableSelectChoice)({
|
|
917
|
-
message: "
|
|
1040
|
+
message: "CF target switcher",
|
|
918
1041
|
choices: [
|
|
919
|
-
{ title: "
|
|
920
|
-
{ title: "
|
|
1042
|
+
{ title: "Switch to a target (favorites, recent, all)", value: "switch" },
|
|
1043
|
+
{ title: "Refresh all regions", value: "refresh" },
|
|
1044
|
+
{ title: "List targets", value: "list" },
|
|
1045
|
+
{ title: "Manage favorites", value: "favorites" },
|
|
1046
|
+
{ title: "Show current target", value: "current" },
|
|
921
1047
|
],
|
|
922
|
-
|
|
923
|
-
const normalizedValue = value.trim().toLowerCase();
|
|
924
|
-
return normalizedValue === "list" || normalizedValue === "switch"
|
|
925
|
-
? true
|
|
926
|
-
: "Type list or switch, or select one option.";
|
|
927
|
-
},
|
|
1048
|
+
allowCustomValue: false,
|
|
928
1049
|
});
|
|
929
|
-
|
|
930
|
-
api: options.api,
|
|
931
|
-
refresh: options.refresh,
|
|
932
|
-
});
|
|
933
|
-
const organizationRegionCount = new Set(organizationEntries.map((entry) => entry.region)).size;
|
|
934
|
-
const latestTarget = await (0, cf_1.readCloudFoundryTarget)();
|
|
935
|
-
if (action === "list") {
|
|
1050
|
+
if (action === "current") {
|
|
936
1051
|
printTarget(latestTarget);
|
|
937
|
-
console.log("");
|
|
938
|
-
if (!organizationEntries.length) {
|
|
939
|
-
console.log(chalk_1.default.yellow("No orgs found for current CF user. Run smdg cf login, save the password, then run smdg cf org again."));
|
|
940
|
-
return;
|
|
941
|
-
}
|
|
942
|
-
console.log(chalk_1.default.gray(`Showing ${organizationEntries.length} org(s) across ${organizationRegionCount} region(s).`));
|
|
943
|
-
console.log("");
|
|
944
|
-
for (const entry of organizationEntries) {
|
|
945
|
-
const marker = entry.apiEndpoint === latestTarget.apiEndpoint && entry.org === latestTarget.org ? chalk_1.default.green("*") : " ";
|
|
946
|
-
console.log(`${marker} ${formatCloudFoundryOrgEntry(entry, latestTarget)}`);
|
|
947
|
-
}
|
|
948
1052
|
return;
|
|
949
1053
|
}
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
};
|
|
1054
|
+
if (action === "favorites") {
|
|
1055
|
+
await manageFavoriteTargets(favorites);
|
|
1056
|
+
return;
|
|
1057
|
+
}
|
|
1058
|
+
let orgEntries;
|
|
1059
|
+
if (action === "refresh" || options.refresh) {
|
|
1060
|
+
await (0, tooling_1.ensureExternalTool)("cf");
|
|
1061
|
+
console.log(chalk_1.default.gray("Refreshing CF orgs across regions..."));
|
|
1062
|
+
orgEntries = await getCloudFoundryOrganizationsAcrossRegions({ api: options.api, refresh: true });
|
|
1063
|
+
console.log(chalk_1.default.green(`Refresh completed · ${orgEntries.length} target(s) found.`));
|
|
1064
|
+
console.log("");
|
|
962
1065
|
}
|
|
963
1066
|
else {
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
console.log(chalk_1.default.gray("Run smdg cf login and save the password, then run smdg cf org --list --refresh."));
|
|
967
|
-
return;
|
|
968
|
-
}
|
|
969
|
-
const selectedIndex = await (0, prompts_2.searchableSelectChoice)({
|
|
970
|
-
message: `Search CF org across ${organizationRegionCount} region(s)`,
|
|
971
|
-
choices: organizationEntries.map((entry, index) => ({
|
|
972
|
-
title: formatCloudFoundryOrgEntry(entry, latestTarget),
|
|
973
|
-
value: String(index),
|
|
974
|
-
})),
|
|
975
|
-
validateCustomValue: validateRequired,
|
|
976
|
-
customValueTitle: (value) => `Use typed CF org in current region: ${value}`,
|
|
977
|
-
});
|
|
978
|
-
selectedEntry = organizationEntries[Number(selectedIndex)] ?? {
|
|
979
|
-
apiEndpoint: latestTarget.apiEndpoint ?? "",
|
|
980
|
-
region: (0, cf_1.inferCloudFoundryRegionFromApiEndpoint)(latestTarget.apiEndpoint ?? "current"),
|
|
981
|
-
org: selectedIndex,
|
|
982
|
-
updatedAt: new Date().toISOString(),
|
|
983
|
-
};
|
|
1067
|
+
const cache = await (0, cache_1.readCache)();
|
|
1068
|
+
orgEntries = cache.cloudFoundry.orgsAcrossRegions ?? [];
|
|
984
1069
|
}
|
|
985
|
-
if (
|
|
986
|
-
|
|
1070
|
+
if (action === "list") {
|
|
1071
|
+
printTargetSections(favorites, recent, orgEntries, latestTarget);
|
|
1072
|
+
return;
|
|
987
1073
|
}
|
|
988
|
-
const
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
const orgExitCode = await (0, cf_1.targetCloudFoundryOrg)(selectedEntry.org);
|
|
995
|
-
if (orgExitCode !== 0) {
|
|
996
|
-
console.log(chalk_1.default.yellow("Cannot switch to this org after automatic authentication."));
|
|
997
|
-
console.log(chalk_1.default.gray("Run smdg cf login, save the password, then try again."));
|
|
998
|
-
process.exitCode = orgExitCode;
|
|
1074
|
+
const allTargets = orgEntries.map(orgEntryToTarget);
|
|
1075
|
+
const recentKeys = new Set(recent.map((target) => (0, cf_target_types_1.cfTargetKey)(target)));
|
|
1076
|
+
const combined = dedupeTargets([...favorites, ...recent, ...allTargets]);
|
|
1077
|
+
if (!combined.length) {
|
|
1078
|
+
console.log(chalk_1.default.yellow("No cached targets yet."));
|
|
1079
|
+
console.log(chalk_1.default.gray("Choose 'Refresh all regions', or run smdg cf login and save the password."));
|
|
999
1080
|
return;
|
|
1000
1081
|
}
|
|
1001
|
-
const
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
...spaces
|
|
1008
|
-
.filter((spaceName) => spaceName === preferredSpace)
|
|
1009
|
-
.map((spaceName) => ({ title: `${spaceName} ${spaceName === currentTargetAfterOrgSwitch.space ? chalk_1.default.gray("current") : chalk_1.default.gray("suggested")}`, value: spaceName })),
|
|
1010
|
-
...spaces
|
|
1011
|
-
.filter((spaceName) => spaceName !== preferredSpace)
|
|
1012
|
-
.map((spaceName) => ({ title: spaceName, value: spaceName })),
|
|
1013
|
-
],
|
|
1082
|
+
const selectedIndex = await (0, prompts_2.searchableSelectChoice)({
|
|
1083
|
+
message: `Select CF target (${favorites.length} favorite · ${recent.length} recent · ${allTargets.length} all)`,
|
|
1084
|
+
choices: combined.map((target, index) => {
|
|
1085
|
+
const marker = target.isFavorite ? chalk_1.default.yellow("★ ") : recentKeys.has((0, cf_target_types_1.cfTargetKey)(target)) ? chalk_1.default.gray("◷ ") : " ";
|
|
1086
|
+
return { title: `${marker}${(0, cf_target_types_1.cfTargetLabel)(target)}`, value: String(index) };
|
|
1087
|
+
}),
|
|
1014
1088
|
validateCustomValue: validateRequired,
|
|
1015
|
-
customValueTitle: (value) => `Use typed
|
|
1089
|
+
customValueTitle: (value) => `Use typed org in current region: ${value}`,
|
|
1016
1090
|
});
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
await (0, cache_1.rememberCloudFoundryLoginProfile)({
|
|
1026
|
-
...authenticatedProfile,
|
|
1027
|
-
apiEndpoint: selectedEntry.apiEndpoint,
|
|
1028
|
-
org: selectedEntry.org,
|
|
1029
|
-
space,
|
|
1030
|
-
updatedAt: new Date().toISOString(),
|
|
1031
|
-
});
|
|
1032
|
-
}
|
|
1033
|
-
const switchedTarget = await (0, cf_1.readCloudFoundryTarget)();
|
|
1034
|
-
console.log(chalk_1.default.green("CF org/space switched."));
|
|
1035
|
-
printTarget(switchedTarget);
|
|
1091
|
+
const chosen = combined[Number(selectedIndex)] ?? {
|
|
1092
|
+
region: (0, cf_1.inferCloudFoundryRegionFromApiEndpoint)(latestTarget.apiEndpoint ?? "current"),
|
|
1093
|
+
apiEndpoint: latestTarget.apiEndpoint ?? "",
|
|
1094
|
+
org: selectedIndex,
|
|
1095
|
+
space: "",
|
|
1096
|
+
};
|
|
1097
|
+
await (0, tooling_1.ensureExternalTool)("cf");
|
|
1098
|
+
await switchToCfTarget(chosen, { space: options.space });
|
|
1036
1099
|
}
|
|
1037
1100
|
async function runAppsCommand(options) {
|
|
1038
|
-
const target = await (
|
|
1039
|
-
const targetKey = (0, cf_1.buildCloudFoundryTargetKey)(target);
|
|
1040
|
-
const cache = await (0, cache_1.readCache)();
|
|
1041
|
-
const cachedEntry = cache.cloudFoundry.appListsByTarget[targetKey];
|
|
1101
|
+
const target = await ensureCloudFoundrySessionFromCache();
|
|
1042
1102
|
printTarget(target);
|
|
1043
1103
|
console.log("");
|
|
1044
|
-
const
|
|
1045
|
-
const
|
|
1046
|
-
|
|
1047
|
-
|
|
1104
|
+
const region = target.apiEndpoint ? (0, cf_1.inferCloudFoundryRegionFromApiEndpoint)(target.apiEndpoint) : "current";
|
|
1105
|
+
const cacheKey = (0, smart_cache_1.buildCfAppsKey)(region, target.org ?? "?", target.space ?? "?");
|
|
1106
|
+
const targetLabel = `${region} / ${target.org ?? "?"} / ${target.space ?? "?"}`;
|
|
1107
|
+
const result = await (0, smart_cache_1.smartRead)({
|
|
1108
|
+
namespace: "cf-apps",
|
|
1109
|
+
key: cacheKey,
|
|
1110
|
+
ttlMs: smart_cache_1.DEFAULT_CACHE_TTL.cfApps,
|
|
1111
|
+
mode: options.refresh ? "network-only" : "stale-while-revalidate",
|
|
1112
|
+
fetcher: cf_1.listCloudFoundryApps,
|
|
1048
1113
|
});
|
|
1049
|
-
if (
|
|
1050
|
-
console.log(chalk_1.default.gray(`Using cached
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
else if (options.refresh) {
|
|
1055
|
-
console.log(chalk_1.default.green(`Refreshed cf apps cache for ${targetKey}.`));
|
|
1114
|
+
if (result.fromCache) {
|
|
1115
|
+
console.log(chalk_1.default.gray(`Using cached apps for ${targetLabel} from ${(0, smart_cache_1.formatRelativeTime)(result.updatedAt)}.`));
|
|
1116
|
+
if (result.isRefreshing) {
|
|
1117
|
+
console.log(chalk_1.default.gray("Refreshing apps in background..."));
|
|
1118
|
+
}
|
|
1056
1119
|
console.log("");
|
|
1057
1120
|
}
|
|
1058
1121
|
if (options.select) {
|
|
@@ -1060,9 +1123,25 @@ async function runAppsCommand(options) {
|
|
|
1060
1123
|
console.log(appName);
|
|
1061
1124
|
return;
|
|
1062
1125
|
}
|
|
1063
|
-
for (const app of
|
|
1126
|
+
for (const app of result.data) {
|
|
1064
1127
|
console.log([app.name, app.requestedState, app.processes, app.routes].filter(Boolean).join(" | "));
|
|
1065
1128
|
}
|
|
1129
|
+
// Mirror the smart-cache apps into the legacy per-target cache used by
|
|
1130
|
+
// resolveAppSelection so bind/debug/logs stay in sync.
|
|
1131
|
+
await (0, cache_1.rememberCloudFoundryApps)((0, cf_1.buildCloudFoundryTargetKey)(target), result.data).catch(() => undefined);
|
|
1132
|
+
if (result.refreshPromise) {
|
|
1133
|
+
try {
|
|
1134
|
+
const fresh = await result.refreshPromise;
|
|
1135
|
+
await (0, cache_1.rememberCloudFoundryApps)((0, cf_1.buildCloudFoundryTargetKey)(target), fresh).catch(() => undefined);
|
|
1136
|
+
console.log("");
|
|
1137
|
+
console.log(chalk_1.default.gray("Background refresh completed. Cache updated."));
|
|
1138
|
+
}
|
|
1139
|
+
catch (error) {
|
|
1140
|
+
console.log("");
|
|
1141
|
+
console.log(chalk_1.default.yellow(`Background refresh failed: ${error instanceof Error ? error.message : String(error)}`));
|
|
1142
|
+
console.log(chalk_1.default.gray("Showing cached apps. Run smdg cf login if your session expired."));
|
|
1143
|
+
}
|
|
1144
|
+
}
|
|
1066
1145
|
}
|
|
1067
1146
|
async function runAppsCacheRefreshCommand() {
|
|
1068
1147
|
await refreshAppsCacheForCurrentTarget();
|