@topolo/sdk 0.10.2 → 0.10.4
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.cjs +451 -34
- package/dist/index.d.cts +119 -1
- package/dist/index.d.ts +119 -1
- package/dist/index.js +437 -34
- package/dist/node/credential-store.cjs +254 -25
- package/dist/node/credential-store.d.cts +10 -3
- package/dist/node/credential-store.d.ts +10 -3
- package/dist/node/credential-store.js +251 -25
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -28,6 +28,8 @@ __export(index_exports, {
|
|
|
28
28
|
DEFAULT_APP_URLS: () => DEFAULT_APP_URLS,
|
|
29
29
|
IdentityModule: () => IdentityModule,
|
|
30
30
|
P2PModule: () => P2PModule,
|
|
31
|
+
TOPOLO_ENVIRONMENT_SERVICE_URLS: () => TOPOLO_ENVIRONMENT_SERVICE_URLS,
|
|
32
|
+
TOPOLO_RUNTIME_ENVIRONMENTS: () => TOPOLO_RUNTIME_ENVIRONMENTS,
|
|
31
33
|
TOPOLO_WIDGET_ENDPOINT: () => TOPOLO_WIDGET_ENDPOINT,
|
|
32
34
|
TOPOLO_WIDGET_REFRESH_INTERVAL_MS: () => TOPOLO_WIDGET_REFRESH_INTERVAL_MS,
|
|
33
35
|
TopoloAuthError: () => TopoloAuthError,
|
|
@@ -41,14 +43,21 @@ __export(index_exports, {
|
|
|
41
43
|
actionContractCompleteness: () => actionContractCompleteness,
|
|
42
44
|
applicationEntryFromCatalog: () => applicationEntryFromCatalog,
|
|
43
45
|
applicationRequirementScopes: () => applicationRequirementScopes,
|
|
46
|
+
assertTopoloServiceUrlEnvironment: () => assertTopoloServiceUrlEnvironment,
|
|
44
47
|
auditAllApplicationRequirements: () => auditAllApplicationRequirements,
|
|
45
48
|
auditApplicationEntries: () => auditApplicationEntries,
|
|
46
49
|
auditApplicationRequirements: () => auditApplicationRequirements,
|
|
50
|
+
canonicalTopoloErrorCode: () => canonicalTopoloErrorCode,
|
|
51
|
+
canonicalTopoloRequestId: () => canonicalTopoloRequestId,
|
|
52
|
+
canonicalTopoloRequired: () => canonicalTopoloRequired,
|
|
53
|
+
canonicalTopoloRetryAfter: () => canonicalTopoloRetryAfter,
|
|
47
54
|
compactActionCatalogEntry: () => compactActionCatalogEntry,
|
|
48
55
|
compactActionPlan: () => compactActionPlan,
|
|
56
|
+
compactActionPreparation: () => compactActionPreparation,
|
|
49
57
|
compactActionValidation: () => compactActionValidation,
|
|
50
58
|
compactApplicationAudit: () => compactApplicationAudit,
|
|
51
59
|
createTopolo: () => createTopolo,
|
|
60
|
+
createTopoloAgentExecutionContext: () => createTopoloAgentExecutionContext,
|
|
52
61
|
createTopoloWidgetError: () => createTopoloWidgetError,
|
|
53
62
|
createTopoloWidgetResponse: () => createTopoloWidgetResponse,
|
|
54
63
|
defineTopoloChartWidget: () => defineTopoloChartWidget,
|
|
@@ -58,17 +67,22 @@ __export(index_exports, {
|
|
|
58
67
|
defineTopoloStatsWidget: () => defineTopoloStatsWidget,
|
|
59
68
|
digestTopoloActionCatalog: () => digestTopoloActionCatalog,
|
|
60
69
|
enrichActionContract: () => enrichActionContract,
|
|
70
|
+
extractTopoloServiceErrorCode: () => extractTopoloServiceErrorCode,
|
|
71
|
+
extractTopoloServiceErrorDetails: () => extractTopoloServiceErrorDetails,
|
|
61
72
|
formatDirectoryApplicationIds: () => formatDirectoryApplicationIds,
|
|
62
73
|
friendlyAppId: () => friendlyAppId,
|
|
63
74
|
listApplicationDirectory: () => listApplicationDirectory,
|
|
64
75
|
parseTopoloActionUploadContract: () => parseTopoloActionUploadContract,
|
|
65
76
|
prepareTopoloActionBase64UploadInput: () => prepareTopoloActionBase64UploadInput,
|
|
66
77
|
prepareTopoloActionUploadInput: () => prepareTopoloActionUploadInput,
|
|
78
|
+
publicTopoloErrorMessage: () => publicTopoloErrorMessage,
|
|
67
79
|
requirementsForApplication: () => requirementsForApplication,
|
|
68
80
|
resolveApplicationDirectoryEntry: () => resolveApplicationDirectoryEntry,
|
|
69
81
|
resolveCatalogServiceUrl: () => resolveCatalogServiceUrl,
|
|
70
82
|
resolveServiceUrl: () => resolveServiceUrl,
|
|
71
83
|
staticApplicationDirectory: () => staticApplicationDirectory,
|
|
84
|
+
topoloErrorHint: () => topoloErrorHint,
|
|
85
|
+
topoloServiceOrigins: () => topoloServiceOrigins,
|
|
72
86
|
validateTopoloActionInput: () => validateTopoloActionInput,
|
|
73
87
|
validateTopoloWidgetResponse: () => validateTopoloWidgetResponse
|
|
74
88
|
});
|
|
@@ -103,6 +117,90 @@ var TopoloSdkError = class extends Error {
|
|
|
103
117
|
this.code = code;
|
|
104
118
|
}
|
|
105
119
|
};
|
|
120
|
+
var PUBLIC_ERROR_CODES = /* @__PURE__ */ new Set([
|
|
121
|
+
"action_app_identity_unavailable",
|
|
122
|
+
"action_authentication_required",
|
|
123
|
+
"action_catalog_summary_unavailable",
|
|
124
|
+
"action_catalog_unavailable",
|
|
125
|
+
"action_contract_mismatch",
|
|
126
|
+
"action_permission_required",
|
|
127
|
+
"action_runtime_authorization_required",
|
|
128
|
+
"action_service_not_allowed",
|
|
129
|
+
"auth_error",
|
|
130
|
+
"authentication_required",
|
|
131
|
+
"authorization_pending",
|
|
132
|
+
"bad_sig",
|
|
133
|
+
"confirmation_required",
|
|
134
|
+
"dependency_unavailable",
|
|
135
|
+
"environment_mismatch",
|
|
136
|
+
"environment_service_url_required",
|
|
137
|
+
"expired_token",
|
|
138
|
+
"forbidden",
|
|
139
|
+
"http_error",
|
|
140
|
+
"immutable_drift",
|
|
141
|
+
"integration_dependency_unavailable",
|
|
142
|
+
"integration_misconfigured",
|
|
143
|
+
"invalid_action",
|
|
144
|
+
"invalid_action_input",
|
|
145
|
+
"invalid_grant",
|
|
146
|
+
"invalid_input",
|
|
147
|
+
"invalid_token",
|
|
148
|
+
"mcp_error",
|
|
149
|
+
"membership_required",
|
|
150
|
+
"network_error",
|
|
151
|
+
"organization_context_required",
|
|
152
|
+
"organization_enrollment_required",
|
|
153
|
+
"permission_denied",
|
|
154
|
+
"rate_limited",
|
|
155
|
+
"request_failed",
|
|
156
|
+
"service_catalog_unavailable",
|
|
157
|
+
"service_path_origin_mismatch",
|
|
158
|
+
"service_required",
|
|
159
|
+
"slow_down",
|
|
160
|
+
"state_conflict",
|
|
161
|
+
"unauthorized",
|
|
162
|
+
"unknown_action",
|
|
163
|
+
"unknown_service"
|
|
164
|
+
]);
|
|
165
|
+
var ERROR_CODE_PATTERN = /^[a-z][a-z0-9_]{0,63}$/;
|
|
166
|
+
var TOPOLO_REQUEST_ID_PATTERN = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
|
|
167
|
+
var CLOUDFLARE_RAY_ID_PATTERN = /^[0-9a-f]{16}-[A-Z]{3}$/;
|
|
168
|
+
var PERMISSION_PATTERN = /^[a-z][a-z0-9_-]{0,63}(?:\.[a-z][a-z0-9_-]{0,63})*:(?:[a-z][a-z0-9_-]{0,63}|\*)$/;
|
|
169
|
+
var RETRY_AFTER_DATE_PATTERN = /^(?:Mon|Tue|Wed|Thu|Fri|Sat|Sun), \d{2} (?:Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec) \d{4} \d{2}:\d{2}:\d{2} GMT$/;
|
|
170
|
+
var PUBLIC_DETAIL_SOURCES = /* @__PURE__ */ new Set([
|
|
171
|
+
"api_key_introspection",
|
|
172
|
+
"api_key_validation",
|
|
173
|
+
"auth_context",
|
|
174
|
+
"auth_validate",
|
|
175
|
+
"catalog",
|
|
176
|
+
"credential",
|
|
177
|
+
"runtime",
|
|
178
|
+
"service_token_provider",
|
|
179
|
+
"service_verify_key",
|
|
180
|
+
"token_validation",
|
|
181
|
+
"upstream"
|
|
182
|
+
]);
|
|
183
|
+
function canonicalTopoloErrorCode(value) {
|
|
184
|
+
if (typeof value !== "string") return null;
|
|
185
|
+
const candidate = value.trim().toLowerCase();
|
|
186
|
+
if (!ERROR_CODE_PATTERN.test(candidate) || !PUBLIC_ERROR_CODES.has(candidate)) return null;
|
|
187
|
+
return candidate;
|
|
188
|
+
}
|
|
189
|
+
function canonicalTopoloRequestId(value) {
|
|
190
|
+
if (typeof value !== "string") return void 0;
|
|
191
|
+
const candidate = value.trim();
|
|
192
|
+
return TOPOLO_REQUEST_ID_PATTERN.test(candidate) || CLOUDFLARE_RAY_ID_PATTERN.test(candidate) ? candidate : void 0;
|
|
193
|
+
}
|
|
194
|
+
function canonicalTopoloRetryAfter(value) {
|
|
195
|
+
if (typeof value !== "string") return void 0;
|
|
196
|
+
const candidate = value.trim();
|
|
197
|
+
if (/^\d{1,10}$/.test(candidate) || RETRY_AFTER_DATE_PATTERN.test(candidate)) return candidate;
|
|
198
|
+
return void 0;
|
|
199
|
+
}
|
|
200
|
+
function canonicalTopoloRequired(value) {
|
|
201
|
+
if (!Array.isArray(value)) return [];
|
|
202
|
+
return [...new Set(value.filter((item) => typeof item === "string" && PERMISSION_PATTERN.test(item)))].slice(0, 32);
|
|
203
|
+
}
|
|
106
204
|
var TopoloAuthError = class extends TopoloSdkError {
|
|
107
205
|
status;
|
|
108
206
|
body;
|
|
@@ -110,15 +208,19 @@ var TopoloAuthError = class extends TopoloSdkError {
|
|
|
110
208
|
path;
|
|
111
209
|
requestId;
|
|
112
210
|
retryAfter;
|
|
211
|
+
details;
|
|
113
212
|
constructor(message, code = "auth_error", options = {}) {
|
|
114
|
-
super(code, message);
|
|
213
|
+
super(canonicalTopoloErrorCode(code) ?? "auth_error", message);
|
|
115
214
|
this.name = "TopoloAuthError";
|
|
116
215
|
this.status = options.status ?? 401;
|
|
117
216
|
this.body = options.body;
|
|
118
217
|
this.service = options.service;
|
|
119
218
|
this.path = options.path;
|
|
120
|
-
this.requestId = options.requestId;
|
|
121
|
-
this.retryAfter = options.retryAfter;
|
|
219
|
+
this.requestId = canonicalTopoloRequestId(options.requestId);
|
|
220
|
+
this.retryAfter = canonicalTopoloRetryAfter(options.retryAfter);
|
|
221
|
+
this.details = extractTopoloServiceErrorDetails(
|
|
222
|
+
options.details === void 0 ? options.body : { details: options.details }
|
|
223
|
+
);
|
|
122
224
|
}
|
|
123
225
|
};
|
|
124
226
|
var TopoloPermissionError = class extends TopoloSdkError {
|
|
@@ -129,28 +231,140 @@ var TopoloPermissionError = class extends TopoloSdkError {
|
|
|
129
231
|
path;
|
|
130
232
|
requestId;
|
|
131
233
|
retryAfter;
|
|
234
|
+
details;
|
|
132
235
|
constructor(message, required, options = {}) {
|
|
133
|
-
super(
|
|
236
|
+
super(
|
|
237
|
+
canonicalTopoloErrorCode(options.code) ?? serviceErrorCode(options.body, "permission_denied"),
|
|
238
|
+
message
|
|
239
|
+
);
|
|
134
240
|
this.name = "TopoloPermissionError";
|
|
135
|
-
this.required = required;
|
|
241
|
+
this.required = canonicalTopoloRequired(required);
|
|
136
242
|
this.status = options.status ?? 403;
|
|
137
243
|
this.body = options.body;
|
|
138
244
|
this.service = options.service;
|
|
139
245
|
this.path = options.path;
|
|
140
|
-
this.requestId = options.requestId;
|
|
141
|
-
this.retryAfter = options.retryAfter;
|
|
246
|
+
this.requestId = canonicalTopoloRequestId(options.requestId);
|
|
247
|
+
this.retryAfter = canonicalTopoloRetryAfter(options.retryAfter);
|
|
248
|
+
this.details = extractTopoloServiceErrorDetails(
|
|
249
|
+
options.details === void 0 ? options.body : { details: options.details }
|
|
250
|
+
);
|
|
142
251
|
}
|
|
143
252
|
};
|
|
144
|
-
function
|
|
145
|
-
if (!body || typeof body !== "object" || Array.isArray(body)) return
|
|
253
|
+
function extractTopoloServiceErrorCode(body) {
|
|
254
|
+
if (!body || typeof body !== "object" || Array.isArray(body)) return null;
|
|
146
255
|
const record = body;
|
|
147
|
-
|
|
256
|
+
const topLevel = canonicalTopoloErrorCode(record.code);
|
|
257
|
+
if (topLevel) return topLevel;
|
|
148
258
|
const nested = record.error;
|
|
259
|
+
const nestedString = canonicalTopoloErrorCode(nested);
|
|
260
|
+
if (nestedString) return nestedString;
|
|
149
261
|
if (nested && typeof nested === "object" && !Array.isArray(nested)) {
|
|
150
262
|
const code = nested.code;
|
|
151
|
-
|
|
263
|
+
const nestedCode = canonicalTopoloErrorCode(code);
|
|
264
|
+
if (nestedCode) return nestedCode;
|
|
265
|
+
}
|
|
266
|
+
return null;
|
|
267
|
+
}
|
|
268
|
+
function serviceErrorCode(body, fallback) {
|
|
269
|
+
return extractTopoloServiceErrorCode(body) ?? fallback;
|
|
270
|
+
}
|
|
271
|
+
function extractTopoloServiceErrorDetails(body) {
|
|
272
|
+
if (!body || typeof body !== "object" || Array.isArray(body)) return void 0;
|
|
273
|
+
const record = body;
|
|
274
|
+
let candidate = record.details;
|
|
275
|
+
const nested = record.error;
|
|
276
|
+
if (nested && typeof nested === "object" && !Array.isArray(nested)) {
|
|
277
|
+
const nestedRecord = nested;
|
|
278
|
+
if (candidate === void 0) candidate = nestedRecord.details ?? nestedRecord;
|
|
279
|
+
}
|
|
280
|
+
if (candidate === void 0) candidate = record;
|
|
281
|
+
if (!candidate || typeof candidate !== "object" || Array.isArray(candidate)) return void 0;
|
|
282
|
+
const source = candidate;
|
|
283
|
+
const safe = {};
|
|
284
|
+
for (const [key, value] of Object.entries(source)) {
|
|
285
|
+
if (/present$/i.test(key) && typeof value === "boolean") {
|
|
286
|
+
safe[key] = value;
|
|
287
|
+
continue;
|
|
288
|
+
}
|
|
289
|
+
if (key === "retryable" && typeof value === "boolean") {
|
|
290
|
+
safe.retryable = value;
|
|
291
|
+
continue;
|
|
292
|
+
}
|
|
293
|
+
if (key === "code") {
|
|
294
|
+
const sanitized = canonicalTopoloErrorCode(value);
|
|
295
|
+
if (sanitized) safe.code = sanitized;
|
|
296
|
+
continue;
|
|
297
|
+
}
|
|
298
|
+
if (key === "source") {
|
|
299
|
+
const sanitized = typeof value === "string" ? value.trim().toLowerCase() : "";
|
|
300
|
+
if (PUBLIC_DETAIL_SOURCES.has(sanitized)) safe.source = sanitized;
|
|
301
|
+
continue;
|
|
302
|
+
}
|
|
303
|
+
if (key === "dependency" || key === "platform") {
|
|
304
|
+
safe[`${key}Present`] = value !== null && value !== void 0;
|
|
305
|
+
continue;
|
|
306
|
+
}
|
|
307
|
+
if (key === "error" && !safe.code) {
|
|
308
|
+
const sanitized = canonicalTopoloErrorCode(value);
|
|
309
|
+
if (sanitized) safe.code = sanitized;
|
|
310
|
+
continue;
|
|
311
|
+
}
|
|
312
|
+
if (key === "required" && Array.isArray(value)) {
|
|
313
|
+
const required = canonicalTopoloRequired(value);
|
|
314
|
+
if (required.length) safe.required = required;
|
|
315
|
+
continue;
|
|
316
|
+
}
|
|
317
|
+
if (["missingFields", "fields", "paths"].includes(key) && Array.isArray(value)) {
|
|
318
|
+
const paths = value.filter((item) => typeof item === "string" && /^[$.a-z0-9_[\]-]{1,160}$/i.test(item));
|
|
319
|
+
if (paths.length) safe[key] = paths;
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
return Object.keys(safe).length ? safe : void 0;
|
|
323
|
+
}
|
|
324
|
+
function publicTopoloErrorMessage(error) {
|
|
325
|
+
const code = canonicalTopoloErrorCode(
|
|
326
|
+
typeof error === "string" ? error : error.code ?? extractTopoloServiceErrorCode(error.body)
|
|
327
|
+
) ?? "request_failed";
|
|
328
|
+
if (/(?:organization|org).*(?:enroll|membership|member|admission)/.test(code)) {
|
|
329
|
+
return "Organization or application enrollment is required.";
|
|
330
|
+
}
|
|
331
|
+
if (/(?:organization|org).*(?:context|required|missing|invalid|unknown|not_found)/.test(code)) {
|
|
332
|
+
return "Organization context is unavailable.";
|
|
333
|
+
}
|
|
334
|
+
if (["auth_error", "authentication_required", "unauthorized", "invalid_token", "expired_token"].includes(code)) {
|
|
335
|
+
return "Authentication failed.";
|
|
336
|
+
}
|
|
337
|
+
if (code === "permission_denied" || code === "forbidden") return "Permission denied.";
|
|
338
|
+
if (code === "confirmation_required") return "Confirmation is required.";
|
|
339
|
+
return `Topolo request failed (${code}).`;
|
|
340
|
+
}
|
|
341
|
+
function topoloErrorHint(error) {
|
|
342
|
+
const code = canonicalTopoloErrorCode(
|
|
343
|
+
typeof error === "string" ? error : error.code ?? extractTopoloServiceErrorCode(error.body)
|
|
344
|
+
);
|
|
345
|
+
if (!code) return void 0;
|
|
346
|
+
if (code === "auth_error" || code === "authentication_required" || code === "unauthorized" || code === "invalid_token" || code === "expired_token") {
|
|
347
|
+
return "Run `topolo auth login`, then verify the effective Topolo identity and organization.";
|
|
348
|
+
}
|
|
349
|
+
if (code === "confirmation_required") {
|
|
350
|
+
return "Review the unchanged action plan, obtain approval, and retry once with --confirm or confirm:true.";
|
|
351
|
+
}
|
|
352
|
+
if (code === "enrollment_required" || code === "membership_required" || /(?:organization|org).*(?:enroll|membership|member|admission)|(?:enroll|membership).*(?:organization|org)/.test(code)) {
|
|
353
|
+
return "The current identity is not enrolled for this organization or application. Use an enrolled identity or ask an organization administrator to complete enrollment.";
|
|
152
354
|
}
|
|
153
|
-
|
|
355
|
+
if (/(?:organization|org).*(?:context|required|missing|invalid|unknown|not_found)/.test(code)) {
|
|
356
|
+
return "Select a signed-in organization context, then verify the effective identity and organization before retrying.";
|
|
357
|
+
}
|
|
358
|
+
if (code === "permission_denied" || code === "forbidden") {
|
|
359
|
+
return "The current identity or resource context is not authorized. Review the structured details and published authorization contract.";
|
|
360
|
+
}
|
|
361
|
+
if (code === "environment_mismatch") {
|
|
362
|
+
return "Use service origins and credentials from one explicit Topolo environment only.";
|
|
363
|
+
}
|
|
364
|
+
if (code === "invalid_action_input" || code === "invalid_input") {
|
|
365
|
+
return "Correct only the reported schema paths, then prepare the action again.";
|
|
366
|
+
}
|
|
367
|
+
return void 0;
|
|
154
368
|
}
|
|
155
369
|
var TopoloConfirmationRequiredError = class extends TopoloSdkError {
|
|
156
370
|
constructor(message) {
|
|
@@ -165,18 +379,86 @@ var TopoloHttpError = class extends TopoloSdkError {
|
|
|
165
379
|
path;
|
|
166
380
|
requestId;
|
|
167
381
|
retryAfter;
|
|
382
|
+
details;
|
|
168
383
|
constructor(service, path, status, body, message, options = {}) {
|
|
169
|
-
super(
|
|
384
|
+
super(serviceErrorCode(body, "http_error"), message ?? `HTTP ${status} from ${service}${path}`);
|
|
170
385
|
this.name = "TopoloHttpError";
|
|
171
386
|
this.status = status;
|
|
172
387
|
this.body = body;
|
|
173
388
|
this.service = service;
|
|
174
389
|
this.path = path;
|
|
175
|
-
this.requestId = options.requestId;
|
|
176
|
-
this.retryAfter = options.retryAfter;
|
|
390
|
+
this.requestId = canonicalTopoloRequestId(options.requestId);
|
|
391
|
+
this.retryAfter = canonicalTopoloRetryAfter(options.retryAfter);
|
|
392
|
+
this.details = extractTopoloServiceErrorDetails(
|
|
393
|
+
options.details === void 0 ? body : { details: options.details }
|
|
394
|
+
);
|
|
177
395
|
}
|
|
178
396
|
};
|
|
179
397
|
|
|
398
|
+
// src/environment.ts
|
|
399
|
+
var TOPOLO_RUNTIME_ENVIRONMENTS = ["production", "staging", "development", "local"];
|
|
400
|
+
var TOPOLO_ENVIRONMENT_SERVICE_URLS = {
|
|
401
|
+
production: {
|
|
402
|
+
auth: "https://auth.topolo.app",
|
|
403
|
+
developers: "https://developers.topolo.app"
|
|
404
|
+
},
|
|
405
|
+
staging: {
|
|
406
|
+
auth: "https://auth.stg.topolo.us",
|
|
407
|
+
developers: "https://developers.stg.topolo.us",
|
|
408
|
+
seed: "https://seed.stg.topolo.us"
|
|
409
|
+
},
|
|
410
|
+
development: {
|
|
411
|
+
auth: "https://auth.topolo.dev",
|
|
412
|
+
developers: "https://developers.topolo.dev"
|
|
413
|
+
},
|
|
414
|
+
local: {}
|
|
415
|
+
};
|
|
416
|
+
function hostnameHasSuffix(hostname, suffix) {
|
|
417
|
+
return hostname === suffix || hostname.endsWith(`.${suffix}`);
|
|
418
|
+
}
|
|
419
|
+
function workersDevAccountMatches(hostname, account) {
|
|
420
|
+
if (!hostname.endsWith(".workers.dev")) return false;
|
|
421
|
+
const labels = hostname.slice(0, -".workers.dev".length).split(".");
|
|
422
|
+
return labels.length >= 2 && labels.at(-1) === account;
|
|
423
|
+
}
|
|
424
|
+
function originMatchesEnvironment(url, environment) {
|
|
425
|
+
const hostname = url.hostname.toLowerCase();
|
|
426
|
+
if (environment === "local") {
|
|
427
|
+
return hostname === "localhost" || hostname.endsWith(".localhost") || hostname === "127.0.0.1" || hostname === "[::1]";
|
|
428
|
+
}
|
|
429
|
+
if (url.protocol !== "https:") return false;
|
|
430
|
+
if (environment === "production") {
|
|
431
|
+
return hostnameHasSuffix(hostname, "topolo.app") || hostnameHasSuffix(hostname, "topolo.io") || workersDevAccountMatches(hostname, "topolo");
|
|
432
|
+
}
|
|
433
|
+
if (environment === "staging") {
|
|
434
|
+
return hostnameHasSuffix(hostname, "stg.topolo.us") || workersDevAccountMatches(hostname, "topolo-staging");
|
|
435
|
+
}
|
|
436
|
+
return hostnameHasSuffix(hostname, "topolo.dev") || workersDevAccountMatches(hostname, "topolo-development");
|
|
437
|
+
}
|
|
438
|
+
function assertTopoloServiceUrlEnvironment(service, value, environment) {
|
|
439
|
+
let url;
|
|
440
|
+
try {
|
|
441
|
+
url = new URL(value);
|
|
442
|
+
} catch {
|
|
443
|
+
throw new TopoloSdkError("invalid_service_url", `Invalid URL configured for Topolo service "${service}".`);
|
|
444
|
+
}
|
|
445
|
+
if (url.protocol !== "https:" && url.protocol !== "http:" || url.username || url.password || !originMatchesEnvironment(url, environment)) {
|
|
446
|
+
throw new TopoloSdkError(
|
|
447
|
+
"environment_mismatch",
|
|
448
|
+
`Refusing Topolo service "${service}": ${url.origin} does not belong to ${environment}.`
|
|
449
|
+
);
|
|
450
|
+
}
|
|
451
|
+
return url.origin;
|
|
452
|
+
}
|
|
453
|
+
function topoloServiceOrigins(serviceUrls, environment) {
|
|
454
|
+
return Object.fromEntries(
|
|
455
|
+
Object.entries(serviceUrls ?? {}).sort(([left], [right]) => left.localeCompare(right)).map(([service, value]) => [
|
|
456
|
+
service,
|
|
457
|
+
assertTopoloServiceUrlEnvironment(service, value, environment)
|
|
458
|
+
])
|
|
459
|
+
);
|
|
460
|
+
}
|
|
461
|
+
|
|
180
462
|
// src/bootstrap-services.ts
|
|
181
463
|
var APP_API_URLS = {
|
|
182
464
|
auth: "https://auth.topolo.app",
|
|
@@ -2945,6 +3227,7 @@ var TopoloClient = class _TopoloClient {
|
|
|
2945
3227
|
credential;
|
|
2946
3228
|
agent;
|
|
2947
3229
|
serviceUrls;
|
|
3230
|
+
environment;
|
|
2948
3231
|
appIds;
|
|
2949
3232
|
requireConfirmForWrites;
|
|
2950
3233
|
timeoutMs;
|
|
@@ -2973,7 +3256,8 @@ var TopoloClient = class _TopoloClient {
|
|
|
2973
3256
|
if (!options.agent?.clientName) throw new TopoloAuthError("agent.clientName is required");
|
|
2974
3257
|
this.credential = options.credential;
|
|
2975
3258
|
this.agent = options.agent;
|
|
2976
|
-
this.
|
|
3259
|
+
this.environment = options.environment;
|
|
3260
|
+
this.serviceUrls = options.environment ? topoloServiceOrigins(options.serviceUrls, options.environment) : options.serviceUrls;
|
|
2977
3261
|
this.appIds = options.appIds;
|
|
2978
3262
|
this.requireConfirmForWrites = options.requireConfirmForWrites !== false;
|
|
2979
3263
|
this.timeoutMs = options.timeoutMs ?? 3e4;
|
|
@@ -3002,9 +3286,15 @@ var TopoloClient = class _TopoloClient {
|
|
|
3002
3286
|
);
|
|
3003
3287
|
}
|
|
3004
3288
|
await this.loadCurrentCredential();
|
|
3005
|
-
const resolvedService = opts.baseUrl ? { serviceKey: normalizeLookupKey(opts.service), baseUrl:
|
|
3289
|
+
const resolvedService = opts.baseUrl ? { serviceKey: normalizeLookupKey(opts.service), baseUrl: this.validatedServiceOrigin(opts.service, opts.baseUrl) } : await this.resolveRequestService(opts.service);
|
|
3006
3290
|
const baseUrl = resolvedService.baseUrl;
|
|
3007
3291
|
const url = new URL(opts.path, baseUrl.endsWith("/") ? baseUrl : `${baseUrl}/`);
|
|
3292
|
+
if (url.origin !== new URL(baseUrl).origin) {
|
|
3293
|
+
throw new TopoloSdkError(
|
|
3294
|
+
"service_path_origin_mismatch",
|
|
3295
|
+
`Refusing Topolo request path because it changes the resolved ${resolvedService.serviceKey || opts.service} service origin.`
|
|
3296
|
+
);
|
|
3297
|
+
}
|
|
3008
3298
|
if (opts.query) {
|
|
3009
3299
|
for (const [k, v] of Object.entries(opts.query)) {
|
|
3010
3300
|
if (v !== void 0) url.searchParams.set(k, String(v));
|
|
@@ -3075,7 +3365,7 @@ var TopoloClient = class _TopoloClient {
|
|
|
3075
3365
|
url: urlStr,
|
|
3076
3366
|
requestId,
|
|
3077
3367
|
durationMs: Date.now() - startedAt,
|
|
3078
|
-
error:
|
|
3368
|
+
error: "network_error"
|
|
3079
3369
|
});
|
|
3080
3370
|
throw err;
|
|
3081
3371
|
}
|
|
@@ -3084,6 +3374,7 @@ var TopoloClient = class _TopoloClient {
|
|
|
3084
3374
|
if (!res.ok) {
|
|
3085
3375
|
const durationMs = Date.now() - startedAt;
|
|
3086
3376
|
const message = describeError(parsed, `HTTP ${res.status}`);
|
|
3377
|
+
const publicCode = extractTopoloServiceErrorCode(parsed) ?? "http_error";
|
|
3087
3378
|
this.emit({
|
|
3088
3379
|
phase: "error",
|
|
3089
3380
|
method,
|
|
@@ -3092,7 +3383,7 @@ var TopoloClient = class _TopoloClient {
|
|
|
3092
3383
|
url: urlStr,
|
|
3093
3384
|
requestId,
|
|
3094
3385
|
durationMs,
|
|
3095
|
-
error:
|
|
3386
|
+
error: publicCode,
|
|
3096
3387
|
status: res.status
|
|
3097
3388
|
});
|
|
3098
3389
|
const errorContext = {
|
|
@@ -3100,17 +3391,21 @@ var TopoloClient = class _TopoloClient {
|
|
|
3100
3391
|
body: parsed,
|
|
3101
3392
|
service: resolvedService.serviceKey,
|
|
3102
3393
|
path: opts.path,
|
|
3103
|
-
requestId: res.headers.get("X-Topolo-Request-Id")
|
|
3104
|
-
retryAfter: res.headers.get("Retry-After")
|
|
3394
|
+
requestId: canonicalTopoloRequestId(res.headers.get("X-Topolo-Request-Id")) ?? requestId,
|
|
3395
|
+
retryAfter: canonicalTopoloRetryAfter(res.headers.get("Retry-After"))
|
|
3105
3396
|
};
|
|
3106
3397
|
if (res.status === 401) {
|
|
3107
|
-
throw new TopoloAuthError(
|
|
3398
|
+
throw new TopoloAuthError(
|
|
3399
|
+
describeError(parsed, "Unauthorized"),
|
|
3400
|
+
extractTopoloServiceErrorCode(parsed) ?? "auth_error",
|
|
3401
|
+
errorContext
|
|
3402
|
+
);
|
|
3108
3403
|
}
|
|
3109
3404
|
if (res.status === 403) {
|
|
3110
3405
|
throw new TopoloPermissionError(
|
|
3111
3406
|
describeError(parsed, "Permission denied"),
|
|
3112
3407
|
extractRequired(parsed),
|
|
3113
|
-
errorContext
|
|
3408
|
+
{ ...errorContext, code: extractTopoloServiceErrorCode(parsed) ?? "permission_denied" }
|
|
3114
3409
|
);
|
|
3115
3410
|
}
|
|
3116
3411
|
throw new TopoloHttpError(
|
|
@@ -3160,6 +3455,17 @@ var TopoloClient = class _TopoloClient {
|
|
|
3160
3455
|
});
|
|
3161
3456
|
return this.refreshInFlight;
|
|
3162
3457
|
}
|
|
3458
|
+
validatedServiceOrigin(service, value) {
|
|
3459
|
+
const origin = requireHttpOrigin(value);
|
|
3460
|
+
return this.environment ? assertTopoloServiceUrlEnvironment(service, origin, this.environment) : origin;
|
|
3461
|
+
}
|
|
3462
|
+
validatedActionEntry(entry) {
|
|
3463
|
+
if (!entry.apiBaseUrl) return entry;
|
|
3464
|
+
return {
|
|
3465
|
+
...entry,
|
|
3466
|
+
apiBaseUrl: this.validatedServiceOrigin(entry.appSlug || entry.appId, entry.apiBaseUrl)
|
|
3467
|
+
};
|
|
3468
|
+
}
|
|
3163
3469
|
async resolveRequestService(service) {
|
|
3164
3470
|
const serviceKey = normalizeLookupKey(service);
|
|
3165
3471
|
if (!serviceKey) {
|
|
@@ -3167,17 +3473,20 @@ var TopoloClient = class _TopoloClient {
|
|
|
3167
3473
|
}
|
|
3168
3474
|
if (serviceKey === "auth" || serviceKey === "developers") {
|
|
3169
3475
|
const overrideUrl = resolveConfiguredServiceUrl(serviceKey, this.serviceUrls);
|
|
3170
|
-
if (overrideUrl) return { serviceKey, baseUrl: overrideUrl };
|
|
3476
|
+
if (overrideUrl) return { serviceKey, baseUrl: this.validatedServiceOrigin(serviceKey, overrideUrl) };
|
|
3171
3477
|
if (serviceKey === "developers") {
|
|
3172
3478
|
const derived = deriveDevelopersFromAuth(resolveConfiguredServiceUrl("auth", this.serviceUrls));
|
|
3173
|
-
if (derived) return { serviceKey, baseUrl: derived };
|
|
3479
|
+
if (derived) return { serviceKey, baseUrl: this.validatedServiceOrigin(serviceKey, derived) };
|
|
3174
3480
|
}
|
|
3175
|
-
return {
|
|
3481
|
+
return {
|
|
3482
|
+
serviceKey,
|
|
3483
|
+
baseUrl: this.validatedServiceOrigin(serviceKey, DEFAULT_APP_URLS[serviceKey])
|
|
3484
|
+
};
|
|
3176
3485
|
}
|
|
3177
3486
|
const live = await this.resolveLiveCallableService(serviceKey);
|
|
3178
3487
|
if (live) {
|
|
3179
3488
|
const overrideUrl = resolveConfiguredServiceUrl(serviceKey, this.serviceUrls);
|
|
3180
|
-
return overrideUrl ? { ...live, baseUrl: overrideUrl } : live;
|
|
3489
|
+
return overrideUrl ? { ...live, baseUrl: this.validatedServiceOrigin(serviceKey, overrideUrl) } : { ...live, baseUrl: this.validatedServiceOrigin(serviceKey, live.baseUrl) };
|
|
3181
3490
|
}
|
|
3182
3491
|
throw new TopoloSdkError(
|
|
3183
3492
|
"unknown_service",
|
|
@@ -3191,10 +3500,10 @@ var TopoloClient = class _TopoloClient {
|
|
|
3191
3500
|
serviceKey,
|
|
3192
3501
|
overrides: this.serviceUrls
|
|
3193
3502
|
});
|
|
3194
|
-
if (baseUrl) return { serviceKey, baseUrl };
|
|
3503
|
+
if (baseUrl) return { serviceKey, baseUrl: this.validatedServiceOrigin(serviceKey, baseUrl) };
|
|
3195
3504
|
const actionPage = await this.searchActions({ service: match.appId, limit: 1 }).catch(() => null);
|
|
3196
3505
|
const actionBaseUrl = actionPage?.actions.find((action) => action.apiBaseUrl)?.apiBaseUrl ?? null;
|
|
3197
|
-
return actionBaseUrl ? { serviceKey, baseUrl:
|
|
3506
|
+
return actionBaseUrl ? { serviceKey, baseUrl: this.validatedServiceOrigin(serviceKey, actionBaseUrl) } : null;
|
|
3198
3507
|
}
|
|
3199
3508
|
/**
|
|
3200
3509
|
* Resolve a service-slug → opaque app-id via caller config or TopoloAuth.
|
|
@@ -3214,7 +3523,7 @@ var TopoloClient = class _TopoloClient {
|
|
|
3214
3523
|
if (!normalized) return null;
|
|
3215
3524
|
const configuredAppId = resolveConfiguredAppId(normalized, this.appIds);
|
|
3216
3525
|
if (configuredAppId) return configuredAppId;
|
|
3217
|
-
const authBase = resolveServiceUrl("developers", this.serviceUrls);
|
|
3526
|
+
const authBase = this.validatedServiceOrigin("developers", resolveServiceUrl("developers", this.serviceUrls));
|
|
3218
3527
|
const cacheKey = `${authBase}|${normalized}`;
|
|
3219
3528
|
const now = Date.now();
|
|
3220
3529
|
const cached = _TopoloClient.appIdCache.get(cacheKey);
|
|
@@ -3390,7 +3699,7 @@ var TopoloClient = class _TopoloClient {
|
|
|
3390
3699
|
"TopoloAuth did not return an action catalog for the current credential."
|
|
3391
3700
|
);
|
|
3392
3701
|
}
|
|
3393
|
-
const entries = raw.map((item) => normalizeActionCatalogEntry(item)).filter((entry) => Boolean(entry));
|
|
3702
|
+
const entries = raw.map((item) => normalizeActionCatalogEntry(item)).filter((entry) => Boolean(entry)).map((entry) => this.validatedActionEntry(entry));
|
|
3394
3703
|
return {
|
|
3395
3704
|
actions: entries,
|
|
3396
3705
|
page: normalizeCatalogPage(
|
|
@@ -3455,7 +3764,7 @@ var TopoloClient = class _TopoloClient {
|
|
|
3455
3764
|
const raw = res.data?.action ?? res.action;
|
|
3456
3765
|
const match = normalizeActionCatalogEntry(raw);
|
|
3457
3766
|
if (!match) throw new TopoloSdkError("unknown_action", `Unknown or unavailable Topolo action "${action}".`);
|
|
3458
|
-
return match;
|
|
3767
|
+
return this.validatedActionEntry(match);
|
|
3459
3768
|
}
|
|
3460
3769
|
async callAction(action, input = {}, options = {}) {
|
|
3461
3770
|
const entry = await this.getAction(action);
|
|
@@ -3532,6 +3841,25 @@ var TopoloClient = class _TopoloClient {
|
|
|
3532
3841
|
}
|
|
3533
3842
|
async planAction(action, input = {}, options = {}) {
|
|
3534
3843
|
const entry = await this.getAction(action);
|
|
3844
|
+
return this.planResolvedAction(entry, input, options);
|
|
3845
|
+
}
|
|
3846
|
+
async prepareAction(action, input, options = {}) {
|
|
3847
|
+
const entry = await this.getAction(action);
|
|
3848
|
+
const example = (entry.agentContract?.examples ?? []).find((candidate) => Boolean(candidate?.input) && typeof candidate.input === "object" && !Array.isArray(candidate.input) && validateTopoloActionInput(entry.inputSchema, candidate.input).valid) ?? null;
|
|
3849
|
+
const selectedInput = input ?? example?.input ?? {};
|
|
3850
|
+
const plan = this.planResolvedAction(entry, selectedInput, options);
|
|
3851
|
+
return {
|
|
3852
|
+
action: entry,
|
|
3853
|
+
example,
|
|
3854
|
+
input: selectedInput,
|
|
3855
|
+
inputSource: input ? "provided" : example ? "example" : "empty",
|
|
3856
|
+
missingFields: [...new Set(
|
|
3857
|
+
plan.validation.errors.filter((issue) => issue.code === "required").map((issue) => issue.path)
|
|
3858
|
+
)],
|
|
3859
|
+
plan
|
|
3860
|
+
};
|
|
3861
|
+
}
|
|
3862
|
+
planResolvedAction(entry, input, options) {
|
|
3535
3863
|
const validation = validateTopoloActionInput(entry.inputSchema, input);
|
|
3536
3864
|
const agentAccess = entry.agentAccess ?? (entry.destructive ? "off" : entry.readOnly && !entry.requiresConfirmation ? "auto" : "confirm");
|
|
3537
3865
|
const confirmationRequired = agentAccess === "confirm" || entry.requiresConfirmation || entry.destructive;
|
|
@@ -3989,7 +4317,16 @@ function pickString(value) {
|
|
|
3989
4317
|
function extractRequired(body) {
|
|
3990
4318
|
if (body && typeof body === "object") {
|
|
3991
4319
|
const maybe = body;
|
|
3992
|
-
if (Array.isArray(maybe.required)) return maybe.required
|
|
4320
|
+
if (Array.isArray(maybe.required)) return canonicalTopoloRequired(maybe.required);
|
|
4321
|
+
for (const nested of [maybe.details, maybe.error]) {
|
|
4322
|
+
if (!nested || typeof nested !== "object" || Array.isArray(nested)) continue;
|
|
4323
|
+
const record = nested;
|
|
4324
|
+
if (Array.isArray(record.required)) return canonicalTopoloRequired(record.required);
|
|
4325
|
+
if (record.details && typeof record.details === "object" && !Array.isArray(record.details)) {
|
|
4326
|
+
const required = record.details.required;
|
|
4327
|
+
if (Array.isArray(required)) return canonicalTopoloRequired(required);
|
|
4328
|
+
}
|
|
4329
|
+
}
|
|
3993
4330
|
}
|
|
3994
4331
|
return [];
|
|
3995
4332
|
}
|
|
@@ -4039,6 +4376,72 @@ function compactActionPlan(plan) {
|
|
|
4039
4376
|
nextActionIds: plan.nextActionIds
|
|
4040
4377
|
};
|
|
4041
4378
|
}
|
|
4379
|
+
function requiredContextText(value, field) {
|
|
4380
|
+
if (typeof value !== "string" || !value.trim() || value.trim().toLowerCase() === "unknown") {
|
|
4381
|
+
throw new TopoloSdkError("invalid_identity_context", `Effective Topolo ${field} is incomplete.`);
|
|
4382
|
+
}
|
|
4383
|
+
return value.trim();
|
|
4384
|
+
}
|
|
4385
|
+
function createTopoloAgentExecutionContext(input) {
|
|
4386
|
+
if (input.contextKey !== null && input.contextKey !== "personal" && !/^org:[^:]+$/.test(input.contextKey)) {
|
|
4387
|
+
throw new TopoloSdkError("invalid_identity_context", "Effective Topolo context key is invalid.");
|
|
4388
|
+
}
|
|
4389
|
+
const user = Object.freeze({
|
|
4390
|
+
id: requiredContextText(input.identity.user.id, "user id"),
|
|
4391
|
+
email: requiredContextText(input.identity.user.email, "user email"),
|
|
4392
|
+
name: input.identity.user.name?.trim() || null,
|
|
4393
|
+
role: requiredContextText(input.identity.user.role, "user role")
|
|
4394
|
+
});
|
|
4395
|
+
const organization = input.identity.organization ? Object.freeze({
|
|
4396
|
+
id: requiredContextText(input.identity.organization.id, "organization id"),
|
|
4397
|
+
slug: requiredContextText(input.identity.organization.slug, "organization slug"),
|
|
4398
|
+
name: requiredContextText(input.identity.organization.name, "organization name")
|
|
4399
|
+
}) : null;
|
|
4400
|
+
if (input.contextKey === "personal" && organization) {
|
|
4401
|
+
throw new TopoloSdkError("identity_context_mismatch", "Personal Topolo context resolved an organization.");
|
|
4402
|
+
}
|
|
4403
|
+
if (input.contextKey?.startsWith("org:")) {
|
|
4404
|
+
const expectedOrganizationId = input.contextKey.slice("org:".length);
|
|
4405
|
+
if (!organization || organization.id !== expectedOrganizationId) {
|
|
4406
|
+
throw new TopoloSdkError("identity_context_mismatch", "Pinned Topolo organization does not match the effective identity.");
|
|
4407
|
+
}
|
|
4408
|
+
}
|
|
4409
|
+
return Object.freeze({
|
|
4410
|
+
environment: input.environment,
|
|
4411
|
+
contextKey: input.contextKey,
|
|
4412
|
+
user,
|
|
4413
|
+
organization,
|
|
4414
|
+
serviceOrigins: Object.freeze(topoloServiceOrigins(input.serviceUrls, input.environment))
|
|
4415
|
+
});
|
|
4416
|
+
}
|
|
4417
|
+
function compactActionPreparationCore(preparation) {
|
|
4418
|
+
const example = preparation.example ? { title: preparation.example.title ?? null, input: preparation.example.input } : null;
|
|
4419
|
+
const effectiveInput = preparation.inputSource === "example" ? { source: "example" } : { source: preparation.inputSource, value: preparation.input };
|
|
4420
|
+
return {
|
|
4421
|
+
action: {
|
|
4422
|
+
id: preparation.action.actionId,
|
|
4423
|
+
title: preparation.action.title,
|
|
4424
|
+
docsUrl: preparation.action.agentContract?.docsUrl ?? null
|
|
4425
|
+
},
|
|
4426
|
+
example,
|
|
4427
|
+
input: effectiveInput,
|
|
4428
|
+
missingFields: preparation.missingFields,
|
|
4429
|
+
valid: preparation.plan.validation.valid,
|
|
4430
|
+
errors: preparation.plan.validation.errors,
|
|
4431
|
+
request: preparation.plan.request,
|
|
4432
|
+
confirmation: {
|
|
4433
|
+
required: preparation.plan.confirmationRequired,
|
|
4434
|
+
provided: preparation.plan.confirmationProvided
|
|
4435
|
+
},
|
|
4436
|
+
executable: preparation.plan.executable,
|
|
4437
|
+
verification: preparation.plan.verification,
|
|
4438
|
+
rollbackActionId: preparation.plan.rollbackActionId
|
|
4439
|
+
};
|
|
4440
|
+
}
|
|
4441
|
+
function compactActionPreparation(preparation, context) {
|
|
4442
|
+
const compact = compactActionPreparationCore(preparation);
|
|
4443
|
+
return context ? { context, ...compact } : compact;
|
|
4444
|
+
}
|
|
4042
4445
|
function compactApplicationAudit(report) {
|
|
4043
4446
|
return {
|
|
4044
4447
|
version: report.version,
|
|
@@ -4299,7 +4702,7 @@ function sampleString(schema, hint) {
|
|
|
4299
4702
|
if (schema.format === "uri" || schema.format === "url") return "https://topolo.app";
|
|
4300
4703
|
if (schema.format === "date-time") return patternedString(schema.pattern || "", hint) || "2026-01-15T12:00:00Z";
|
|
4301
4704
|
const words = String(hint || "value").replace(/([a-z0-9])([A-Z])/g, "$1 $2").replace(/[_-]+/g, " ").toLowerCase();
|
|
4302
|
-
let value = typeof schema.pattern === "string" ? patternedString(schema.pattern, hint) : /(^|\s)id$/.test(words) ? `${slugify(words.replace(/\sid$/, "") || "resource")}_01` : words.includes("date") ? "2026-01-15" : words.includes("period") || words.includes("month") ? "2026-01" : words.includes("year") ? "2026" : `Sample ${words}`;
|
|
4705
|
+
let value = typeof schema.pattern === "string" ? patternedString(schema.pattern, hint) : words === "workspace" ? "ws_example" : /(^|\s)id$/.test(words) ? `${slugify(words.replace(/\sid$/, "") || "resource")}_01` : words.includes("date") ? "2026-01-15" : words.includes("period") || words.includes("month") ? "2026-01" : words.includes("year") ? "2026" : `Sample ${words}`;
|
|
4303
4706
|
const minimum = Number.isInteger(schema.minLength) ? schema.minLength : 0;
|
|
4304
4707
|
const maximum = Number.isInteger(schema.maxLength) ? schema.maxLength : null;
|
|
4305
4708
|
if (value.length < minimum) value = value.padEnd(minimum, "x");
|
|
@@ -5059,6 +5462,8 @@ function createTopolo(options) {
|
|
|
5059
5462
|
DEFAULT_APP_URLS,
|
|
5060
5463
|
IdentityModule,
|
|
5061
5464
|
P2PModule,
|
|
5465
|
+
TOPOLO_ENVIRONMENT_SERVICE_URLS,
|
|
5466
|
+
TOPOLO_RUNTIME_ENVIRONMENTS,
|
|
5062
5467
|
TOPOLO_WIDGET_ENDPOINT,
|
|
5063
5468
|
TOPOLO_WIDGET_REFRESH_INTERVAL_MS,
|
|
5064
5469
|
TopoloAuthError,
|
|
@@ -5072,14 +5477,21 @@ function createTopolo(options) {
|
|
|
5072
5477
|
actionContractCompleteness,
|
|
5073
5478
|
applicationEntryFromCatalog,
|
|
5074
5479
|
applicationRequirementScopes,
|
|
5480
|
+
assertTopoloServiceUrlEnvironment,
|
|
5075
5481
|
auditAllApplicationRequirements,
|
|
5076
5482
|
auditApplicationEntries,
|
|
5077
5483
|
auditApplicationRequirements,
|
|
5484
|
+
canonicalTopoloErrorCode,
|
|
5485
|
+
canonicalTopoloRequestId,
|
|
5486
|
+
canonicalTopoloRequired,
|
|
5487
|
+
canonicalTopoloRetryAfter,
|
|
5078
5488
|
compactActionCatalogEntry,
|
|
5079
5489
|
compactActionPlan,
|
|
5490
|
+
compactActionPreparation,
|
|
5080
5491
|
compactActionValidation,
|
|
5081
5492
|
compactApplicationAudit,
|
|
5082
5493
|
createTopolo,
|
|
5494
|
+
createTopoloAgentExecutionContext,
|
|
5083
5495
|
createTopoloWidgetError,
|
|
5084
5496
|
createTopoloWidgetResponse,
|
|
5085
5497
|
defineTopoloChartWidget,
|
|
@@ -5089,17 +5501,22 @@ function createTopolo(options) {
|
|
|
5089
5501
|
defineTopoloStatsWidget,
|
|
5090
5502
|
digestTopoloActionCatalog,
|
|
5091
5503
|
enrichActionContract,
|
|
5504
|
+
extractTopoloServiceErrorCode,
|
|
5505
|
+
extractTopoloServiceErrorDetails,
|
|
5092
5506
|
formatDirectoryApplicationIds,
|
|
5093
5507
|
friendlyAppId,
|
|
5094
5508
|
listApplicationDirectory,
|
|
5095
5509
|
parseTopoloActionUploadContract,
|
|
5096
5510
|
prepareTopoloActionBase64UploadInput,
|
|
5097
5511
|
prepareTopoloActionUploadInput,
|
|
5512
|
+
publicTopoloErrorMessage,
|
|
5098
5513
|
requirementsForApplication,
|
|
5099
5514
|
resolveApplicationDirectoryEntry,
|
|
5100
5515
|
resolveCatalogServiceUrl,
|
|
5101
5516
|
resolveServiceUrl,
|
|
5102
5517
|
staticApplicationDirectory,
|
|
5518
|
+
topoloErrorHint,
|
|
5519
|
+
topoloServiceOrigins,
|
|
5103
5520
|
validateTopoloActionInput,
|
|
5104
5521
|
validateTopoloWidgetResponse
|
|
5105
5522
|
});
|