@topolo/cli 0.1.27 → 0.1.29

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 +85 -31
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -89,7 +89,7 @@ var SERVICES = {
89
89
  inventory: "https://inventory.topolo.app",
90
90
  learn: "https://learn-api.topolo.app",
91
91
  localize: "https://localize.topolo.app",
92
- mail: "https://mail.topolo.app",
92
+ mail: "https://mail-api.topolo.app",
93
93
  mdm: "https://mdm-api.topolo.app",
94
94
  messages: "https://messages.topolo.app",
95
95
  nexus: "https://nexus-api.topolo.app",
@@ -925,15 +925,17 @@ var APPLICATIONS = {
925
925
  "mail.topolo.app"
926
926
  ],
927
927
  "routes": [],
928
- "serviceId": "mail"
928
+ "serviceId": null
929
929
  },
930
930
  {
931
931
  "name": "topolo-mail-api",
932
932
  "kind": "worker",
933
- "apiUrl": null,
934
- "domains": [],
933
+ "apiUrl": "https://mail-api.topolo.app",
934
+ "domains": [
935
+ "mail-api.topolo.app"
936
+ ],
935
937
  "routes": [],
936
- "serviceId": null
938
+ "serviceId": "mail"
937
939
  }
938
940
  ]
939
941
  },
@@ -2046,15 +2048,63 @@ function statusRank(status) {
2046
2048
  return 2;
2047
2049
  }
2048
2050
  var DEFAULT_SERVICE_URLS = SERVICES;
2051
+ function resolveCatalogServiceUrl(entry, options = {}) {
2052
+ const keys = catalogServiceKeyCandidates(entry, options.serviceKey);
2053
+ const override = resolveServiceUrlOverride(keys, options.overrides);
2054
+ if (override) return override;
2055
+ const apiBaseUrl = firstString(entry.apiBaseUrl, entry.api_base_url);
2056
+ if (apiBaseUrl) return apiBaseUrl;
2057
+ return null;
2058
+ }
2049
2059
  function resolveServiceUrl(service, overrides) {
2050
- const override = overrides?.[service];
2060
+ const override = resolveServiceUrlOverride([service], overrides);
2051
2061
  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
2062
  return DEFAULT_SERVICE_URLS[service];
2056
2063
  }
2064
+ function catalogServiceKeyCandidates(entry, preferred) {
2065
+ const values = [preferred, entry.slug, entry.name, entry.serviceId].filter(
2066
+ (value) => typeof value === "string" && value.trim().length > 0
2067
+ );
2068
+ const keys = /* @__PURE__ */ new Set();
2069
+ for (const value of values) {
2070
+ for (const candidate of serviceKeyCandidates(value)) keys.add(candidate);
2071
+ }
2072
+ return [...keys];
2073
+ }
2074
+ function serviceKeyCandidates(value) {
2075
+ const normalized = value.trim().toLowerCase().replace(/\s+/g, "-");
2076
+ const withoutTopolo = normalized.startsWith("topolo-") ? normalized.slice("topolo-".length) : normalized;
2077
+ return [.../* @__PURE__ */ new Set([
2078
+ normalized,
2079
+ normalized.replace(/-/g, "_"),
2080
+ withoutTopolo,
2081
+ withoutTopolo.replace(/-/g, "_")
2082
+ ])].filter(Boolean);
2083
+ }
2084
+ function resolveServiceUrlOverride(keys, overrides) {
2085
+ for (const key of keys) {
2086
+ const direct = overrides?.[key];
2087
+ if (direct) return direct;
2088
+ const envStyleKey = key.replace(/\./g, "_");
2089
+ const envStyle = overrides?.[envStyleKey];
2090
+ if (envStyle) return envStyle;
2091
+ }
2092
+ for (const key of keys) {
2093
+ const envKey = `TOPOLO_SERVICE_URL_${key.replace(/\./g, "_").toUpperCase()}`;
2094
+ const envValue = typeof process !== "undefined" ? process.env?.[envKey] : void 0;
2095
+ if (envValue) return envValue;
2096
+ }
2097
+ return null;
2098
+ }
2099
+ function firstString(...values) {
2100
+ for (const value of values) {
2101
+ if (typeof value === "string" && value.trim()) return value.trim();
2102
+ }
2103
+ return null;
2104
+ }
2057
2105
  var WRITE_METHODS = /* @__PURE__ */ new Set(["POST", "PUT", "PATCH", "DELETE"]);
2106
+ var TOPOLO_ACTION_ID_HEADER = "X-Topolo-Action-Id";
2107
+ var TOPOLO_ACTION_NAME_HEADER = "X-Topolo-Action-Name";
2058
2108
  var POSITIVE_CACHE_TTL_MS = 5 * 60 * 1e3;
2059
2109
  var NEGATIVE_CACHE_TTL_MS = 60 * 1e3;
2060
2110
  var CATALOG_CACHE_TTL_MS = 60 * 1e3;
@@ -2222,8 +2272,12 @@ var TopoloClient = class _TopoloClient {
2222
2272
  async resolveLiveCallableService(serviceKey) {
2223
2273
  const catalog = await this.listServices();
2224
2274
  const match = catalog.find((entry) => catalogEntryMatches(entry, serviceKey));
2225
- if (!match?.baseUrl || !isCallableCatalogEntry(match)) return null;
2226
- return { serviceKey, baseUrl: match.baseUrl };
2275
+ if (!match) return null;
2276
+ const baseUrl = resolveCatalogServiceUrl(match, {
2277
+ serviceKey,
2278
+ overrides: this.serviceUrls
2279
+ });
2280
+ return baseUrl ? { serviceKey, baseUrl } : null;
2227
2281
  }
2228
2282
  /**
2229
2283
  * Resolve a service-slug → opaque service-id via caller config or TopoloAuth.
@@ -2316,7 +2370,8 @@ var TopoloClient = class _TopoloClient {
2316
2370
  slug: typeof s.app_slug === "string" ? s.app_slug : null,
2317
2371
  name: typeof s.name === "string" ? s.name : null,
2318
2372
  description: typeof s.description === "string" ? s.description : null,
2319
- baseUrl: typeof s.base_url === "string" ? s.base_url : null,
2373
+ apiBaseUrl: typeof s.api_base_url === "string" ? s.api_base_url : typeof s.apiBaseUrl === "string" ? s.apiBaseUrl : null,
2374
+ launchUrl: typeof s.launch_url === "string" ? s.launch_url : typeof s.launchUrl === "string" ? s.launchUrl : null,
2320
2375
  status: typeof s.status === "string" ? s.status : null,
2321
2376
  surfaceKind: typeof s.surface_kind === "string" ? s.surface_kind : null,
2322
2377
  launchable: s.launchable === true,
@@ -2383,6 +2438,10 @@ var TopoloClient = class _TopoloClient {
2383
2438
  path: mapped.path,
2384
2439
  ...mapped.query ? { query: mapped.query } : {},
2385
2440
  ...mapped.body !== void 0 ? { body: mapped.body } : {},
2441
+ headers: {
2442
+ [TOPOLO_ACTION_ID_HEADER]: entry.actionId,
2443
+ [TOPOLO_ACTION_NAME_HEADER]: entry.name
2444
+ },
2386
2445
  confirm: options.confirm === true
2387
2446
  });
2388
2447
  }
@@ -2397,7 +2456,8 @@ var TopoloClient = class _TopoloClient {
2397
2456
  slug: app.id,
2398
2457
  name: app.name ?? app.id,
2399
2458
  description: null,
2400
- baseUrl: app.productionUrl ?? null,
2459
+ apiBaseUrl: null,
2460
+ launchUrl: app.productionUrl ?? null,
2401
2461
  status: "bundled",
2402
2462
  surfaceKind: "application",
2403
2463
  launchable: Boolean(app.productionUrl),
@@ -2441,7 +2501,7 @@ var TopoloClient = class _TopoloClient {
2441
2501
  }
2442
2502
  };
2443
2503
  function resolveConfiguredServiceId(slug, serviceIds) {
2444
- for (const serviceKey of serviceKeyCandidates(slug)) {
2504
+ for (const serviceKey of serviceKeyCandidates2(slug)) {
2445
2505
  const configured = serviceIds?.[serviceKey];
2446
2506
  if (typeof configured === "string" && configured.trim()) return configured.trim();
2447
2507
  const envKey = `TOPOLO_SERVICE_ID_${serviceKey.replace(/\./g, "_").toUpperCase()}`;
@@ -2451,7 +2511,7 @@ function resolveConfiguredServiceId(slug, serviceIds) {
2451
2511
  return null;
2452
2512
  }
2453
2513
  function resolveConfiguredServiceUrl(slug, serviceUrls) {
2454
- for (const serviceKey of serviceKeyCandidates(slug)) {
2514
+ for (const serviceKey of serviceKeyCandidates2(slug)) {
2455
2515
  const configured = serviceUrls?.[serviceKey];
2456
2516
  if (typeof configured === "string" && configured.trim()) return configured.trim();
2457
2517
  const envKey = `TOPOLO_SERVICE_URL_${serviceKey.replace(/\./g, "_").toUpperCase()}`;
@@ -2460,7 +2520,7 @@ function resolveConfiguredServiceUrl(slug, serviceUrls) {
2460
2520
  }
2461
2521
  return null;
2462
2522
  }
2463
- function serviceKeyCandidates(slug) {
2523
+ function serviceKeyCandidates2(slug) {
2464
2524
  const normalized = normalizeLookupKey(slug);
2465
2525
  const withoutTopolo = normalized.startsWith("topolo-") ? normalized.slice("topolo-".length) : normalized;
2466
2526
  return [.../* @__PURE__ */ new Set([
@@ -2482,19 +2542,12 @@ function catalogEntryLookupKeys(entry) {
2482
2542
  for (const value of values) {
2483
2543
  const normalized = normalizeLookupKey(value);
2484
2544
  if (!normalized) continue;
2485
- for (const candidate of serviceKeyCandidates(normalized)) {
2545
+ for (const candidate of serviceKeyCandidates2(normalized)) {
2486
2546
  keys.add(candidate);
2487
2547
  }
2488
2548
  }
2489
2549
  return [...keys];
2490
2550
  }
2491
- function isCallableCatalogEntry(entry) {
2492
- const kind = normalizeLookupKey(entry.surfaceKind || "");
2493
- if (kind === "api" || kind === "technical_service" || kind === "service") return true;
2494
- return Boolean(
2495
- entry.baseUrl && catalogEntryLookupKeys(entry).some((key) => Object.prototype.hasOwnProperty.call(DEFAULT_SERVICE_URLS, key))
2496
- );
2497
- }
2498
2551
  function normalizeActionCatalogEntry(item) {
2499
2552
  if (!item || typeof item !== "object" || Array.isArray(item)) return null;
2500
2553
  const a = item;
@@ -8167,7 +8220,7 @@ function applicationRowsFromCatalog(catalog) {
8167
8220
  name: entry.name ?? entry.slug ?? entry.serviceId,
8168
8221
  appDir: "-",
8169
8222
  packageName: null,
8170
- productionUrl: entry.baseUrl,
8223
+ productionUrl: entry.launchUrl ?? null,
8171
8224
  services: [displayCatalogId(entry)],
8172
8225
  deployTargets: 0
8173
8226
  })).sort((left, right) => left.id.localeCompare(right.id));
@@ -8754,7 +8807,7 @@ function buildRows(catalog, overrides, environment = selectedEnvironment()) {
8754
8807
  const resolvedOverrides = resolveServiceUrls(overrides, environment);
8755
8808
  return catalog.map((entry) => {
8756
8809
  const id = displayServiceId(entry);
8757
- const defaultUrl = defaultServiceUrl(id, entry.baseUrl);
8810
+ const defaultUrl = defaultServiceUrl(id, entry);
8758
8811
  const configuredUrl = configuredServiceUrl(id, resolvedOverrides);
8759
8812
  const effectiveUrl = configuredUrl || defaultUrl;
8760
8813
  return {
@@ -8764,22 +8817,23 @@ function buildRows(catalog, overrides, environment = selectedEnvironment()) {
8764
8817
  defaultUrl,
8765
8818
  effectiveUrl,
8766
8819
  overridden: Boolean(configuredUrl && configuredUrl !== defaultUrl),
8767
- environmentSafe: environment !== "staging" || isStagingUrl(effectiveUrl),
8820
+ environmentSafe: environment !== "staging" || !effectiveUrl || isStagingUrl(effectiveUrl),
8768
8821
  permissions: [...entry.permissions]
8769
8822
  };
8770
8823
  }).sort((left, right) => left.id.localeCompare(right.id));
8771
8824
  }
8772
8825
  function formatRows2(rows, environment = selectedEnvironment()) {
8773
8826
  const idWidth = Math.max(3, ...rows.map((r) => r.id.length));
8774
- const urlWidth = Math.max(7, ...rows.map((r) => r.effectiveUrl.length));
8827
+ const urlWidth = Math.max(7, ...rows.map((r) => (r.effectiveUrl ?? "-").length));
8775
8828
  const lines = [];
8776
8829
  lines.push(`Environment: ${environment}`);
8777
8830
  lines.push("");
8778
8831
  lines.push(`${"ID".padEnd(idWidth)} ${"URL".padEnd(urlWidth)} OVERRIDE READY`);
8779
8832
  lines.push(`${"-".repeat(idWidth)} ${"-".repeat(urlWidth)} -------- -----`);
8780
8833
  for (const r of rows) {
8834
+ const effectiveUrl = r.effectiveUrl ?? "-";
8781
8835
  lines.push(
8782
- `${r.id.padEnd(idWidth)} ${r.effectiveUrl.padEnd(urlWidth)} ${r.overridden ? "yes" : "".padEnd(8)} ${r.environmentSafe ? "yes" : "no"}`
8836
+ `${r.id.padEnd(idWidth)} ${effectiveUrl.padEnd(urlWidth)} ${r.overridden ? "yes" : "".padEnd(8)} ${r.environmentSafe ? "yes" : "no"}`
8783
8837
  );
8784
8838
  }
8785
8839
  return lines.join("\n");
@@ -8799,8 +8853,8 @@ function displayServiceId(entry) {
8799
8853
  }
8800
8854
  return serviceIdCandidates(entry.slug || entry.serviceId)[0] || entry.serviceId;
8801
8855
  }
8802
- function defaultServiceUrl(id, fallback) {
8803
- return fallback ?? DEFAULT_SERVICE_URLS[id] ?? "";
8856
+ function defaultServiceUrl(id, entry) {
8857
+ return resolveCatalogServiceUrl(entry, { serviceKey: id });
8804
8858
  }
8805
8859
  function configuredServiceUrl(id, overrides) {
8806
8860
  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.29",
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": {