@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.
Files changed (2) hide show
  1. package/dist/index.js +99 -14
  2. 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 = overrides?.[service];
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?.baseUrl || !isCallableCatalogEntry(match)) return null;
2226
- return { serviceKey, baseUrl: match.baseUrl };
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 serviceKeyCandidates(slug)) {
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 serviceKeyCandidates(slug)) {
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 serviceKeyCandidates(slug) {
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 serviceKeyCandidates(normalized)) {
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.baseUrl);
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, fallback) {
8803
- return fallback ?? DEFAULT_SERVICE_URLS[id] ?? "";
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.27",
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": {