@topolo/cli 0.1.27 → 0.1.28
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 +99 -14
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -2046,15 +2046,88 @@ function statusRank(status) {
|
|
|
2046
2046
|
return 2;
|
|
2047
2047
|
}
|
|
2048
2048
|
var DEFAULT_SERVICE_URLS = SERVICES;
|
|
2049
|
+
function resolveCatalogServiceUrl(entry, options = {}) {
|
|
2050
|
+
const keys = catalogServiceKeyCandidates(entry, options.serviceKey);
|
|
2051
|
+
const override = resolveServiceUrlOverride(keys, options.overrides);
|
|
2052
|
+
if (override) return override;
|
|
2053
|
+
const apiBaseUrl = firstString(entry.apiBaseUrl, entry.api_base_url);
|
|
2054
|
+
if (apiBaseUrl) return apiBaseUrl;
|
|
2055
|
+
const bundledUrl = firstBundledServiceUrl(keys);
|
|
2056
|
+
const liveUrl = firstString(entry.baseUrl);
|
|
2057
|
+
if (bundledUrl && (!liveUrl || sameUrlEnvironment(bundledUrl, liveUrl))) return bundledUrl;
|
|
2058
|
+
return liveUrl ?? bundledUrl ?? null;
|
|
2059
|
+
}
|
|
2049
2060
|
function resolveServiceUrl(service, overrides) {
|
|
2050
|
-
const override =
|
|
2061
|
+
const override = resolveServiceUrlOverride([service], overrides);
|
|
2051
2062
|
if (override) return override;
|
|
2052
|
-
const envKey = `TOPOLO_SERVICE_URL_${service.replace(/\./g, "_").toUpperCase()}`;
|
|
2053
|
-
const envValue = typeof process !== "undefined" ? process.env?.[envKey] : void 0;
|
|
2054
|
-
if (envValue) return envValue;
|
|
2055
2063
|
return DEFAULT_SERVICE_URLS[service];
|
|
2056
2064
|
}
|
|
2065
|
+
function catalogServiceKeyCandidates(entry, preferred) {
|
|
2066
|
+
const values = [preferred, entry.slug, entry.name, entry.serviceId].filter(
|
|
2067
|
+
(value) => typeof value === "string" && value.trim().length > 0
|
|
2068
|
+
);
|
|
2069
|
+
const keys = /* @__PURE__ */ new Set();
|
|
2070
|
+
for (const value of values) {
|
|
2071
|
+
for (const candidate of serviceKeyCandidates(value)) keys.add(candidate);
|
|
2072
|
+
}
|
|
2073
|
+
return [...keys];
|
|
2074
|
+
}
|
|
2075
|
+
function serviceKeyCandidates(value) {
|
|
2076
|
+
const normalized = value.trim().toLowerCase().replace(/\s+/g, "-");
|
|
2077
|
+
const withoutTopolo = normalized.startsWith("topolo-") ? normalized.slice("topolo-".length) : normalized;
|
|
2078
|
+
return [.../* @__PURE__ */ new Set([
|
|
2079
|
+
normalized,
|
|
2080
|
+
normalized.replace(/-/g, "_"),
|
|
2081
|
+
withoutTopolo,
|
|
2082
|
+
withoutTopolo.replace(/-/g, "_")
|
|
2083
|
+
])].filter(Boolean);
|
|
2084
|
+
}
|
|
2085
|
+
function resolveServiceUrlOverride(keys, overrides) {
|
|
2086
|
+
for (const key of keys) {
|
|
2087
|
+
const direct = overrides?.[key];
|
|
2088
|
+
if (direct) return direct;
|
|
2089
|
+
const envStyleKey = key.replace(/\./g, "_");
|
|
2090
|
+
const envStyle = overrides?.[envStyleKey];
|
|
2091
|
+
if (envStyle) return envStyle;
|
|
2092
|
+
}
|
|
2093
|
+
for (const key of keys) {
|
|
2094
|
+
const envKey = `TOPOLO_SERVICE_URL_${key.replace(/\./g, "_").toUpperCase()}`;
|
|
2095
|
+
const envValue = typeof process !== "undefined" ? process.env?.[envKey] : void 0;
|
|
2096
|
+
if (envValue) return envValue;
|
|
2097
|
+
}
|
|
2098
|
+
return null;
|
|
2099
|
+
}
|
|
2100
|
+
function firstBundledServiceUrl(keys) {
|
|
2101
|
+
for (const key of keys) {
|
|
2102
|
+
const url = DEFAULT_SERVICE_URLS[key];
|
|
2103
|
+
if (url) return url;
|
|
2104
|
+
}
|
|
2105
|
+
return null;
|
|
2106
|
+
}
|
|
2107
|
+
function firstString(...values) {
|
|
2108
|
+
for (const value of values) {
|
|
2109
|
+
if (typeof value === "string" && value.trim()) return value.trim();
|
|
2110
|
+
}
|
|
2111
|
+
return null;
|
|
2112
|
+
}
|
|
2113
|
+
function sameUrlEnvironment(left, right) {
|
|
2114
|
+
return urlEnvironment(left) === urlEnvironment(right);
|
|
2115
|
+
}
|
|
2116
|
+
function urlEnvironment(value) {
|
|
2117
|
+
try {
|
|
2118
|
+
const url = new URL(value);
|
|
2119
|
+
const host = url.hostname.toLowerCase();
|
|
2120
|
+
if (host === "localhost" || host === "127.0.0.1") return "local";
|
|
2121
|
+
if (host.endsWith(".stg.topolo.us") || host.includes("topolo-staging")) return "staging";
|
|
2122
|
+
if (host.endsWith(".topolo.app") || host.endsWith(".topolo.us")) return "production";
|
|
2123
|
+
return "external";
|
|
2124
|
+
} catch {
|
|
2125
|
+
return "external";
|
|
2126
|
+
}
|
|
2127
|
+
}
|
|
2057
2128
|
var WRITE_METHODS = /* @__PURE__ */ new Set(["POST", "PUT", "PATCH", "DELETE"]);
|
|
2129
|
+
var TOPOLO_ACTION_ID_HEADER = "X-Topolo-Action-Id";
|
|
2130
|
+
var TOPOLO_ACTION_NAME_HEADER = "X-Topolo-Action-Name";
|
|
2058
2131
|
var POSITIVE_CACHE_TTL_MS = 5 * 60 * 1e3;
|
|
2059
2132
|
var NEGATIVE_CACHE_TTL_MS = 60 * 1e3;
|
|
2060
2133
|
var CATALOG_CACHE_TTL_MS = 60 * 1e3;
|
|
@@ -2222,8 +2295,12 @@ var TopoloClient = class _TopoloClient {
|
|
|
2222
2295
|
async resolveLiveCallableService(serviceKey) {
|
|
2223
2296
|
const catalog = await this.listServices();
|
|
2224
2297
|
const match = catalog.find((entry) => catalogEntryMatches(entry, serviceKey));
|
|
2225
|
-
if (!match
|
|
2226
|
-
|
|
2298
|
+
if (!match || !isCallableCatalogEntry(match)) return null;
|
|
2299
|
+
const baseUrl = resolveCatalogServiceUrl(match, {
|
|
2300
|
+
serviceKey,
|
|
2301
|
+
overrides: this.serviceUrls
|
|
2302
|
+
});
|
|
2303
|
+
return baseUrl ? { serviceKey, baseUrl } : null;
|
|
2227
2304
|
}
|
|
2228
2305
|
/**
|
|
2229
2306
|
* Resolve a service-slug → opaque service-id via caller config or TopoloAuth.
|
|
@@ -2317,6 +2394,8 @@ var TopoloClient = class _TopoloClient {
|
|
|
2317
2394
|
name: typeof s.name === "string" ? s.name : null,
|
|
2318
2395
|
description: typeof s.description === "string" ? s.description : null,
|
|
2319
2396
|
baseUrl: typeof s.base_url === "string" ? s.base_url : null,
|
|
2397
|
+
apiBaseUrl: typeof s.api_base_url === "string" ? s.api_base_url : typeof s.apiBaseUrl === "string" ? s.apiBaseUrl : null,
|
|
2398
|
+
launchUrl: typeof s.launch_url === "string" ? s.launch_url : typeof s.launchUrl === "string" ? s.launchUrl : null,
|
|
2320
2399
|
status: typeof s.status === "string" ? s.status : null,
|
|
2321
2400
|
surfaceKind: typeof s.surface_kind === "string" ? s.surface_kind : null,
|
|
2322
2401
|
launchable: s.launchable === true,
|
|
@@ -2383,6 +2462,10 @@ var TopoloClient = class _TopoloClient {
|
|
|
2383
2462
|
path: mapped.path,
|
|
2384
2463
|
...mapped.query ? { query: mapped.query } : {},
|
|
2385
2464
|
...mapped.body !== void 0 ? { body: mapped.body } : {},
|
|
2465
|
+
headers: {
|
|
2466
|
+
[TOPOLO_ACTION_ID_HEADER]: entry.actionId,
|
|
2467
|
+
[TOPOLO_ACTION_NAME_HEADER]: entry.name
|
|
2468
|
+
},
|
|
2386
2469
|
confirm: options.confirm === true
|
|
2387
2470
|
});
|
|
2388
2471
|
}
|
|
@@ -2398,6 +2481,8 @@ var TopoloClient = class _TopoloClient {
|
|
|
2398
2481
|
name: app.name ?? app.id,
|
|
2399
2482
|
description: null,
|
|
2400
2483
|
baseUrl: app.productionUrl ?? null,
|
|
2484
|
+
apiBaseUrl: null,
|
|
2485
|
+
launchUrl: app.productionUrl ?? null,
|
|
2401
2486
|
status: "bundled",
|
|
2402
2487
|
surfaceKind: "application",
|
|
2403
2488
|
launchable: Boolean(app.productionUrl),
|
|
@@ -2441,7 +2526,7 @@ var TopoloClient = class _TopoloClient {
|
|
|
2441
2526
|
}
|
|
2442
2527
|
};
|
|
2443
2528
|
function resolveConfiguredServiceId(slug, serviceIds) {
|
|
2444
|
-
for (const serviceKey of
|
|
2529
|
+
for (const serviceKey of serviceKeyCandidates2(slug)) {
|
|
2445
2530
|
const configured = serviceIds?.[serviceKey];
|
|
2446
2531
|
if (typeof configured === "string" && configured.trim()) return configured.trim();
|
|
2447
2532
|
const envKey = `TOPOLO_SERVICE_ID_${serviceKey.replace(/\./g, "_").toUpperCase()}`;
|
|
@@ -2451,7 +2536,7 @@ function resolveConfiguredServiceId(slug, serviceIds) {
|
|
|
2451
2536
|
return null;
|
|
2452
2537
|
}
|
|
2453
2538
|
function resolveConfiguredServiceUrl(slug, serviceUrls) {
|
|
2454
|
-
for (const serviceKey of
|
|
2539
|
+
for (const serviceKey of serviceKeyCandidates2(slug)) {
|
|
2455
2540
|
const configured = serviceUrls?.[serviceKey];
|
|
2456
2541
|
if (typeof configured === "string" && configured.trim()) return configured.trim();
|
|
2457
2542
|
const envKey = `TOPOLO_SERVICE_URL_${serviceKey.replace(/\./g, "_").toUpperCase()}`;
|
|
@@ -2460,7 +2545,7 @@ function resolveConfiguredServiceUrl(slug, serviceUrls) {
|
|
|
2460
2545
|
}
|
|
2461
2546
|
return null;
|
|
2462
2547
|
}
|
|
2463
|
-
function
|
|
2548
|
+
function serviceKeyCandidates2(slug) {
|
|
2464
2549
|
const normalized = normalizeLookupKey(slug);
|
|
2465
2550
|
const withoutTopolo = normalized.startsWith("topolo-") ? normalized.slice("topolo-".length) : normalized;
|
|
2466
2551
|
return [.../* @__PURE__ */ new Set([
|
|
@@ -2482,7 +2567,7 @@ function catalogEntryLookupKeys(entry) {
|
|
|
2482
2567
|
for (const value of values) {
|
|
2483
2568
|
const normalized = normalizeLookupKey(value);
|
|
2484
2569
|
if (!normalized) continue;
|
|
2485
|
-
for (const candidate of
|
|
2570
|
+
for (const candidate of serviceKeyCandidates2(normalized)) {
|
|
2486
2571
|
keys.add(candidate);
|
|
2487
2572
|
}
|
|
2488
2573
|
}
|
|
@@ -2492,7 +2577,7 @@ function isCallableCatalogEntry(entry) {
|
|
|
2492
2577
|
const kind = normalizeLookupKey(entry.surfaceKind || "");
|
|
2493
2578
|
if (kind === "api" || kind === "technical_service" || kind === "service") return true;
|
|
2494
2579
|
return Boolean(
|
|
2495
|
-
entry.baseUrl && catalogEntryLookupKeys(entry).some((key) => Object.prototype.hasOwnProperty.call(DEFAULT_SERVICE_URLS, key))
|
|
2580
|
+
(entry.baseUrl || entry.apiBaseUrl) && catalogEntryLookupKeys(entry).some((key) => Object.prototype.hasOwnProperty.call(DEFAULT_SERVICE_URLS, key))
|
|
2496
2581
|
);
|
|
2497
2582
|
}
|
|
2498
2583
|
function normalizeActionCatalogEntry(item) {
|
|
@@ -8754,7 +8839,7 @@ function buildRows(catalog, overrides, environment = selectedEnvironment()) {
|
|
|
8754
8839
|
const resolvedOverrides = resolveServiceUrls(overrides, environment);
|
|
8755
8840
|
return catalog.map((entry) => {
|
|
8756
8841
|
const id = displayServiceId(entry);
|
|
8757
|
-
const defaultUrl = defaultServiceUrl(id, entry
|
|
8842
|
+
const defaultUrl = defaultServiceUrl(id, entry);
|
|
8758
8843
|
const configuredUrl = configuredServiceUrl(id, resolvedOverrides);
|
|
8759
8844
|
const effectiveUrl = configuredUrl || defaultUrl;
|
|
8760
8845
|
return {
|
|
@@ -8799,8 +8884,8 @@ function displayServiceId(entry) {
|
|
|
8799
8884
|
}
|
|
8800
8885
|
return serviceIdCandidates(entry.slug || entry.serviceId)[0] || entry.serviceId;
|
|
8801
8886
|
}
|
|
8802
|
-
function defaultServiceUrl(id,
|
|
8803
|
-
return
|
|
8887
|
+
function defaultServiceUrl(id, entry) {
|
|
8888
|
+
return resolveCatalogServiceUrl(entry, { serviceKey: id }) ?? DEFAULT_SERVICE_URLS[id] ?? "";
|
|
8804
8889
|
}
|
|
8805
8890
|
function configuredServiceUrl(id, overrides) {
|
|
8806
8891
|
if (!overrides) return null;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@topolo/cli",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.28",
|
|
4
4
|
"description": "Command-line interface for Topolo developers, operators, and agents, with internal first-party scaffolding available under the topolo platform namespace.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|