@ornncompute/cli 0.2.19 → 0.2.21

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ornncompute/cli",
3
- "version": "0.2.19",
3
+ "version": "0.2.21",
4
4
  "description": "Command-line interface for Ornn compute access workflows.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -211,10 +211,10 @@ export function resolveInstallerBaseUrl({ env = process.env } = {}) {
211
211
  }
212
212
 
213
213
  function operatorProxyEndpoint(endpoint) {
214
- return `/v1/cli/operator${normalizeComputePath(endpoint)}`;
214
+ return normalizeComputePath(endpoint);
215
215
  }
216
216
 
217
- // Staff path: CLI bearer → gateway /v1/cli/operator → the owning service.
217
+ // Staff path: CLI bearer → gateway /v1/orchestrator/ → the owning service.
218
218
  // The gateway resolves the bearer and applies staff policy; the CLI never ships
219
219
  // a reviewer or service secret.
220
220
  export async function operatorRequest({
@@ -241,11 +241,6 @@ export async function operatorRequest({
241
241
  });
242
242
  }
243
243
 
244
- export function computeEndpoint(path) {
245
- const normalized = normalizeComputePath(path);
246
- return `/v1/cli/compute${normalized}`;
247
- }
248
-
249
244
  export function normalizeComputePath(path) {
250
245
  if (!path || typeof path !== "string") {
251
246
  throw new CliApiError("API path is required.");
@@ -7,7 +7,6 @@ import {
7
7
  loadRequiredSession,
8
8
  operatorRequest,
9
9
  resolveApiBaseUrl,
10
- resolveInstallerBaseUrl,
11
10
  } from "./api-client.mjs";
12
11
 
13
12
  async function collectSse(url, headers, durationMs, maxEvents, fetchImpl) {
@@ -85,6 +84,102 @@ export async function confirmCatalogMutation({ stdin, stdout, yes, label }) {
85
84
  }
86
85
  }
87
86
 
87
+ function splitCatalogPath(input) {
88
+ const trimmed = input.startsWith("/") ? input : `/${input}`;
89
+ const queryIndex = trimmed.indexOf("?");
90
+ return queryIndex === -1
91
+ ? { pathname: trimmed, search: "" }
92
+ : { pathname: trimmed.slice(0, queryIndex), search: trimmed.slice(queryIndex) };
93
+ }
94
+
95
+ function catalogSegments(pathname) {
96
+ return pathname.split("/").filter(Boolean);
97
+ }
98
+
99
+ function isComposedStaffPath(pathname) {
100
+ const parts = catalogSegments(pathname);
101
+ if (parts[0] === "internal" && parts[1] === "commerce-reservations") return true;
102
+ if (parts[0] === "internal" && parts[1] === "users") return true;
103
+ if (parts[0] === "internal" && parts[1] === "reservations" && parts[3] === "transfer") return true;
104
+ if (parts[0] === "internal" && parts[1] === "nodes" && parts[3] === "deploy") return true;
105
+ if (parts[0] === "internal" && parts[1] === "nodes" && parts[3] === "reservation-access") return true;
106
+ return (
107
+ parts[0] === "internal" &&
108
+ parts[1] === "nodes" &&
109
+ parts[3] === "off-grid" &&
110
+ parts[4] === "resolve"
111
+ );
112
+ }
113
+
114
+ function canonicalStaffCatalogPath(pathname) {
115
+ const parts = catalogSegments(pathname);
116
+ if (parts[0] === "provisioning" && parts[1] === "operators") {
117
+ return `/internal/v1/operators${parts.length > 2 ? `/${parts.slice(2).join("/")}` : ""}`;
118
+ }
119
+ if (parts[0] === "provisioning" && parts[1] === "facilities") {
120
+ return `/internal/v1/facilities${parts.length > 2 ? `/${parts.slice(2).join("/")}` : ""}`;
121
+ }
122
+ if (parts[0] === "inventory") {
123
+ return `/internal/v1/listings${parts.length > 1 ? `/${parts.slice(1).join("/")}` : ""}`;
124
+ }
125
+ if (
126
+ parts[0] === "internal" &&
127
+ parts[1] === "reservations" &&
128
+ parts[3] !== "network-validation" &&
129
+ parts[3] !== "node-rollout" &&
130
+ !(parts[3] === "nodes" && parts[4] === "assign")
131
+ ) {
132
+ return `/internal/v1/reservations${parts.length > 2 ? `/${parts.slice(2).join("/")}` : ""}`;
133
+ }
134
+ if (parts[0] === "internal" && parts[1] === "bids") {
135
+ return `/internal/v1/bids${parts.length > 2 ? `/${parts.slice(2).join("/")}` : ""}`;
136
+ }
137
+ if (parts[0] === "internal" && parts[1] === "invoices") {
138
+ return `/internal/v1/invoices${parts.length > 2 ? `/${parts.slice(2).join("/")}` : ""}`;
139
+ }
140
+ if (parts[0] === "enrollment" && parts[1] === "tokens") {
141
+ return `/enrollment-tokens${parts.length > 2 ? `/${parts.slice(2).join("/")}` : ""}`;
142
+ }
143
+ if (parts[0] === "internal" && parts[1] === "enrollment-tokens") {
144
+ return `/enrollment-tokens${parts.length > 2 ? `/${parts.slice(2).join("/")}` : ""}`;
145
+ }
146
+ if (parts[0] === "internal" && parts[1] === "organizations" && parts.length === 3) {
147
+ return `/internal/v1/organizations/${parts[2]}`;
148
+ }
149
+ return pathname;
150
+ }
151
+
152
+ function mapStaffCatalogPath(path) {
153
+ const { pathname, search } = splitCatalogPath(path);
154
+ if (isComposedStaffPath(pathname)) {
155
+ return `/v1/staff${pathname}${search}`;
156
+ }
157
+ const canonical = canonicalStaffCatalogPath(pathname);
158
+ if (
159
+ canonical.startsWith("/internal/v1/") ||
160
+ canonical.startsWith("/commerce/") ||
161
+ canonical.startsWith("/v1/organizations/")
162
+ ) {
163
+ return `${canonical}${search}`;
164
+ }
165
+ if (canonical.startsWith("/v1/")) {
166
+ return `${canonical}${search}`;
167
+ }
168
+ return `/v1/orchestrator${canonical}${search}`;
169
+ }
170
+
171
+ function mapCustomerCatalogPath(path) {
172
+ const { pathname, search } = splitCatalogPath(path);
173
+ const parts = catalogSegments(pathname);
174
+ if (parts[0] === "inventory" || parts[0] === "listings" || parts[0] === "marketplace") {
175
+ return `/v1/workflows/commerce${pathname}${search}`;
176
+ }
177
+ if (pathname.startsWith("/v1/") || parts[0] === "commerce") {
178
+ return `${pathname}${search}`;
179
+ }
180
+ return `/v1/workflows/compute${pathname}${search}`;
181
+ }
182
+
88
183
  function catalogFetch({ env, fetchImpl }) {
89
184
  return async (path, init) => {
90
185
  const method = init?.method ?? "GET";
@@ -97,14 +192,17 @@ function catalogFetch({ env, fetchImpl }) {
97
192
  path.startsWith("/internal") ||
98
193
  path.startsWith("/provisioning") ||
99
194
  path === "/inventory" ||
100
- path.startsWith("/inventory/");
195
+ path.startsWith("/inventory/") ||
196
+ path === "/enrollment-tokens" ||
197
+ path.startsWith("/enrollment-tokens/") ||
198
+ path.startsWith("/enrollment/");
101
199
  const request = staffPath ? operatorRequest : cliRequest;
102
- const requestPath = staffObservability ? path.slice(observabilityPrefix.length) : path;
200
+ const requestPath = staffPath ? mapStaffCatalogPath(path) : mapCustomerCatalogPath(path);
103
201
  if (init?.headers?.Accept === "text/event-stream") {
104
202
  const session = await loadRequiredSession({ env });
105
203
  const base = resolveApiBaseUrl({ env, session });
106
204
  const parsed = new URL(
107
- staffObservability ? `/v1/cli/operator${requestPath}` : path,
205
+ requestPath,
108
206
  `${base.replace(/\/+$/, "")}/`,
109
207
  );
110
208
  const duration = Number(parsed.searchParams.get("duration") ?? "20") * 1000;