@topolo/sdk 0.14.3 → 0.15.0
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/README.md +60 -0
- package/dist/index.cjs +264 -31
- package/dist/index.d.cts +60 -1
- package/dist/index.d.ts +60 -1
- package/dist/index.js +258 -31
- package/package.json +9 -4
package/README.md
CHANGED
|
@@ -86,6 +86,66 @@ Every request sends:
|
|
|
86
86
|
Combined with the credential identity, this makes every platform API call
|
|
87
87
|
traceable to a specific agent invocation.
|
|
88
88
|
|
|
89
|
+
### Actor provenance
|
|
90
|
+
|
|
91
|
+
`ActorEnvelope` is the versioned authority and provenance contract for work
|
|
92
|
+
performed by humans, Topolo-managed agents, external harness installations,
|
|
93
|
+
services, and declared browser automation. It always records the accountable
|
|
94
|
+
subject and actual performer independently and binds them to one organization,
|
|
95
|
+
task/run lineage, channel, assurance level, action, resource, and canonical
|
|
96
|
+
input hash.
|
|
97
|
+
|
|
98
|
+
```ts
|
|
99
|
+
import {
|
|
100
|
+
parseActorEnvelope,
|
|
101
|
+
sha256CanonicalValue,
|
|
102
|
+
type ActorEnvelope,
|
|
103
|
+
} from '@topolo/sdk';
|
|
104
|
+
|
|
105
|
+
const actionInput = { designId: 'design_123', decision: 'approve' };
|
|
106
|
+
const actorEnvelope: ActorEnvelope = parseActorEnvelope({
|
|
107
|
+
schemaVersion: 1,
|
|
108
|
+
organizationId: 'org_acme',
|
|
109
|
+
accountableSubject: {
|
|
110
|
+
principalType: 'human',
|
|
111
|
+
principalId: 'usr_ashley',
|
|
112
|
+
displayName: 'Ashley Lane',
|
|
113
|
+
},
|
|
114
|
+
performer: {
|
|
115
|
+
principalType: 'external_agent',
|
|
116
|
+
principalId: 'installation_codex_macbook',
|
|
117
|
+
installationId: 'installation_codex_macbook',
|
|
118
|
+
provider: 'openai',
|
|
119
|
+
model: 'gpt-5',
|
|
120
|
+
},
|
|
121
|
+
delegation: {
|
|
122
|
+
taskId: 'task_123',
|
|
123
|
+
runId: 'run_456',
|
|
124
|
+
lineage: [
|
|
125
|
+
{ principalType: 'human', principalId: 'usr_ashley' },
|
|
126
|
+
{ principalType: 'external_agent', principalId: 'installation_codex_macbook' },
|
|
127
|
+
],
|
|
128
|
+
},
|
|
129
|
+
channel: 'mcp',
|
|
130
|
+
assurance: { level: 'workload_identity', methods: ['oauth_client'] },
|
|
131
|
+
action: {
|
|
132
|
+
requestId: 'req_789',
|
|
133
|
+
actionId: 'app_topolo_design.designs.approve',
|
|
134
|
+
resourceType: 'design',
|
|
135
|
+
resourceId: 'design_123',
|
|
136
|
+
inputHash: await sha256CanonicalValue(actionInput),
|
|
137
|
+
},
|
|
138
|
+
issuedAt: new Date().toISOString(),
|
|
139
|
+
});
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
The parser rejects unknown fields, unsupported principal types, partial
|
|
143
|
+
resource bindings, malformed hashes, and non-human performers without a
|
|
144
|
+
delegation chain. External agents require an installation and provider;
|
|
145
|
+
managed agents require an agent instance; browser automation requires both an
|
|
146
|
+
installation and a browser-session identity. `X-Topolo-Agent` remains useful
|
|
147
|
+
telemetry but is never trusted as provenance or approval authority.
|
|
148
|
+
|
|
89
149
|
## Modules
|
|
90
150
|
|
|
91
151
|
| Surface | Methods |
|
package/dist/index.cjs
CHANGED
|
@@ -21,6 +21,8 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
21
21
|
var index_exports = {};
|
|
22
22
|
__export(index_exports, {
|
|
23
23
|
ACTION_CATALOG_DIGEST_ALGORITHM: () => ACTION_CATALOG_DIGEST_ALGORITHM,
|
|
24
|
+
ACTOR_ENVELOPE_VERSION: () => ACTOR_ENVELOPE_VERSION,
|
|
25
|
+
ActorEnvelopeValidationError: () => ActorEnvelopeValidationError,
|
|
24
26
|
CrmModule: () => CrmModule,
|
|
25
27
|
DEFAULT_APP_URLS: () => DEFAULT_APP_URLS,
|
|
26
28
|
IdentityModule: () => IdentityModule,
|
|
@@ -42,10 +44,12 @@ __export(index_exports, {
|
|
|
42
44
|
actionContractCompleteness: () => actionContractCompleteness,
|
|
43
45
|
applicationEntryFromCatalog: () => applicationEntryFromCatalog,
|
|
44
46
|
assertTopoloServiceUrlEnvironment: () => assertTopoloServiceUrlEnvironment,
|
|
47
|
+
canonicalJson: () => canonicalJson,
|
|
45
48
|
canonicalTopoloErrorCode: () => canonicalTopoloErrorCode,
|
|
46
49
|
canonicalTopoloRequestId: () => canonicalTopoloRequestId,
|
|
47
50
|
canonicalTopoloRequired: () => canonicalTopoloRequired,
|
|
48
51
|
canonicalTopoloRetryAfter: () => canonicalTopoloRetryAfter,
|
|
52
|
+
canonicalizeActorEnvelope: () => canonicalizeActorEnvelope,
|
|
49
53
|
compactActionCatalogEntry: () => compactActionCatalogEntry,
|
|
50
54
|
compactActionPlan: () => compactActionPlan,
|
|
51
55
|
compactActionPreparation: () => compactActionPreparation,
|
|
@@ -69,6 +73,7 @@ __export(index_exports, {
|
|
|
69
73
|
friendlyAppId: () => friendlyAppId,
|
|
70
74
|
isTopoloWidgetOutputSchema: () => isTopoloWidgetOutputSchema,
|
|
71
75
|
listApplicationDirectory: () => listApplicationDirectory,
|
|
76
|
+
parseActorEnvelope: () => parseActorEnvelope,
|
|
72
77
|
parseTopoloActionUploadContract: () => parseTopoloActionUploadContract,
|
|
73
78
|
preferExactActionMatches: () => preferExactActionMatches,
|
|
74
79
|
prepareTopoloActionBase64UploadInput: () => prepareTopoloActionBase64UploadInput,
|
|
@@ -77,6 +82,7 @@ __export(index_exports, {
|
|
|
77
82
|
resolveApplicationDirectoryEntry: () => resolveApplicationDirectoryEntry,
|
|
78
83
|
resolveCatalogServiceUrl: () => resolveCatalogServiceUrl,
|
|
79
84
|
resolveServiceUrl: () => resolveServiceUrl,
|
|
85
|
+
sha256CanonicalValue: () => sha256CanonicalValue,
|
|
80
86
|
topoloErrorHint: () => topoloErrorHint,
|
|
81
87
|
topoloServiceOrigins: () => topoloServiceOrigins,
|
|
82
88
|
validateTopoloActionInput: () => validateTopoloActionInput,
|
|
@@ -250,10 +256,10 @@ var TopoloPermissionError = class extends TopoloSdkError {
|
|
|
250
256
|
};
|
|
251
257
|
function extractTopoloServiceErrorCode(body) {
|
|
252
258
|
if (!body || typeof body !== "object" || Array.isArray(body)) return null;
|
|
253
|
-
const
|
|
254
|
-
const topLevel = canonicalTopoloErrorCode(
|
|
259
|
+
const record2 = body;
|
|
260
|
+
const topLevel = canonicalTopoloErrorCode(record2.code);
|
|
255
261
|
if (topLevel) return topLevel;
|
|
256
|
-
const nested =
|
|
262
|
+
const nested = record2.error;
|
|
257
263
|
const nestedString = canonicalTopoloErrorCode(nested);
|
|
258
264
|
if (nestedString) return nestedString;
|
|
259
265
|
if (nested && typeof nested === "object" && !Array.isArray(nested)) {
|
|
@@ -268,14 +274,14 @@ function serviceErrorCode(body, fallback) {
|
|
|
268
274
|
}
|
|
269
275
|
function extractTopoloServiceErrorDetails(body) {
|
|
270
276
|
if (!body || typeof body !== "object" || Array.isArray(body)) return void 0;
|
|
271
|
-
const
|
|
272
|
-
let candidate =
|
|
273
|
-
const nested =
|
|
277
|
+
const record2 = body;
|
|
278
|
+
let candidate = record2.details;
|
|
279
|
+
const nested = record2.error;
|
|
274
280
|
if (nested && typeof nested === "object" && !Array.isArray(nested)) {
|
|
275
281
|
const nestedRecord = nested;
|
|
276
282
|
if (candidate === void 0) candidate = nestedRecord.details ?? nestedRecord;
|
|
277
283
|
}
|
|
278
|
-
if (candidate === void 0) candidate =
|
|
284
|
+
if (candidate === void 0) candidate = record2;
|
|
279
285
|
if (Array.isArray(candidate)) {
|
|
280
286
|
const paths = canonicalTopoloValidationPaths(candidate);
|
|
281
287
|
return paths.length ? { paths } : void 0;
|
|
@@ -327,8 +333,8 @@ function canonicalTopoloValidationPaths(issues) {
|
|
|
327
333
|
const paths = [];
|
|
328
334
|
for (const issue of issues) {
|
|
329
335
|
if (!issue || typeof issue !== "object" || Array.isArray(issue)) continue;
|
|
330
|
-
const
|
|
331
|
-
const path = canonicalTopoloValidationPath(
|
|
336
|
+
const record2 = issue;
|
|
337
|
+
const path = canonicalTopoloValidationPath(record2.field) ?? canonicalTopoloValidationPath(record2.path);
|
|
332
338
|
if (path && !paths.includes(path)) paths.push(path);
|
|
333
339
|
if (paths.length === 32) break;
|
|
334
340
|
}
|
|
@@ -1670,14 +1676,14 @@ var TopoloClient = class _TopoloClient {
|
|
|
1670
1676
|
if (!raw || typeof raw !== "object" || Array.isArray(raw)) {
|
|
1671
1677
|
throw new TopoloSdkError("action_catalog_summary_unavailable", "Action catalog summary is unavailable.");
|
|
1672
1678
|
}
|
|
1673
|
-
const
|
|
1674
|
-
if (
|
|
1679
|
+
const record2 = raw;
|
|
1680
|
+
if (record2.algorithm !== "sha256-v1" || typeof record2.digest !== "string" || !/^[a-f0-9]{64}$/.test(record2.digest) || !Number.isSafeInteger(record2.actionCount) || Number(record2.actionCount) < 0) {
|
|
1675
1681
|
throw new TopoloSdkError("action_catalog_summary_unavailable", "Action catalog summary is invalid.");
|
|
1676
1682
|
}
|
|
1677
1683
|
return {
|
|
1678
1684
|
algorithm: "sha256-v1",
|
|
1679
|
-
digest:
|
|
1680
|
-
actionCount: Number(
|
|
1685
|
+
digest: record2.digest,
|
|
1686
|
+
actionCount: Number(record2.actionCount)
|
|
1681
1687
|
};
|
|
1682
1688
|
}
|
|
1683
1689
|
/** @deprecated Prefer searchActions() so callers retain the continuation cursor. */
|
|
@@ -2050,12 +2056,21 @@ function redactActionResult(value) {
|
|
|
2050
2056
|
if (!isRecord3(value)) return value;
|
|
2051
2057
|
return Object.fromEntries(Object.entries(value).map(([key, item]) => [
|
|
2052
2058
|
key,
|
|
2053
|
-
isSensitiveActionResultKey(key) ? "[REDACTED]" : redactActionResult(item)
|
|
2059
|
+
isSensitiveActionResultKey(key, item) ? "[REDACTED]" : redactActionResult(item)
|
|
2054
2060
|
]));
|
|
2055
2061
|
}
|
|
2056
|
-
function isSensitiveActionResultKey(key) {
|
|
2062
|
+
function isSensitiveActionResultKey(key, value) {
|
|
2057
2063
|
const normalized = key.toLowerCase().replace(/[^a-z0-9]/g, "");
|
|
2058
|
-
|
|
2064
|
+
if (normalized === "capability") return isCredentialShaped(value);
|
|
2065
|
+
return ["authorization", "cookie", "setcookie", "proxyauthorization"].includes(normalized) || /(token|secret|password|privatekey|apikey)$/.test(normalized);
|
|
2066
|
+
}
|
|
2067
|
+
var PLAIN_ENUM_VALUE = /^[a-z][a-z0-9_-]{0,31}$/;
|
|
2068
|
+
function isCredentialShaped(value) {
|
|
2069
|
+
if (typeof value !== "string") return value !== null && value !== void 0 && typeof value !== "boolean" && typeof value !== "number";
|
|
2070
|
+
const trimmed = value.trim();
|
|
2071
|
+
if (!trimmed) return false;
|
|
2072
|
+
if (/^[a-z][a-z0-9+.-]*:\/\//i.test(trimmed)) return true;
|
|
2073
|
+
return !PLAIN_ENUM_VALUE.test(trimmed);
|
|
2059
2074
|
}
|
|
2060
2075
|
function resolveConfiguredServiceUrl(slug, serviceUrls) {
|
|
2061
2076
|
for (const serviceKey of serviceKeyCandidates2(slug)) {
|
|
@@ -2301,10 +2316,10 @@ function extractRequired(body) {
|
|
|
2301
2316
|
if (Array.isArray(maybe.required)) return canonicalTopoloRequired(maybe.required);
|
|
2302
2317
|
for (const nested of [maybe.details, maybe.error]) {
|
|
2303
2318
|
if (!nested || typeof nested !== "object" || Array.isArray(nested)) continue;
|
|
2304
|
-
const
|
|
2305
|
-
if (Array.isArray(
|
|
2306
|
-
if (
|
|
2307
|
-
const required =
|
|
2319
|
+
const record2 = nested;
|
|
2320
|
+
if (Array.isArray(record2.required)) return canonicalTopoloRequired(record2.required);
|
|
2321
|
+
if (record2.details && typeof record2.details === "object" && !Array.isArray(record2.details)) {
|
|
2322
|
+
const required = record2.details.required;
|
|
2308
2323
|
if (Array.isArray(required)) return canonicalTopoloRequired(required);
|
|
2309
2324
|
}
|
|
2310
2325
|
}
|
|
@@ -2381,8 +2396,8 @@ function compactResultValue(value, depth, budget) {
|
|
|
2381
2396
|
return value.length > ACTION_RESULT_MAX_ITEMS ? { count: value.length, items, omittedItems: value.length - ACTION_RESULT_MAX_ITEMS } : items;
|
|
2382
2397
|
}
|
|
2383
2398
|
if (typeof value === "object") {
|
|
2384
|
-
const
|
|
2385
|
-
const allKeys = Object.keys(
|
|
2399
|
+
const record2 = value;
|
|
2400
|
+
const allKeys = Object.keys(record2);
|
|
2386
2401
|
const ranked = allKeys.sort((left, right) => resultKeyPriority(left) - resultKeyPriority(right));
|
|
2387
2402
|
const prioritized = ranked.filter((key) => resultKeyPriority(key) < 2);
|
|
2388
2403
|
const ordinary = ranked.filter((key) => resultKeyPriority(key) === 2);
|
|
@@ -2391,7 +2406,7 @@ function compactResultValue(value, depth, budget) {
|
|
|
2391
2406
|
...prioritized,
|
|
2392
2407
|
...ordinary.slice(0, ordinaryLimit)
|
|
2393
2408
|
].slice(0, ACTION_RESULT_MAX_KEYS);
|
|
2394
|
-
const compact = Object.fromEntries(keys.map((key) => [key, compactResultValue(
|
|
2409
|
+
const compact = Object.fromEntries(keys.map((key) => [key, compactResultValue(record2[key], depth + 1, budget)]));
|
|
2395
2410
|
if (allKeys.length > keys.length) compact["_omittedKeys"] = allKeys.length - keys.length;
|
|
2396
2411
|
return compact;
|
|
2397
2412
|
}
|
|
@@ -2507,8 +2522,8 @@ function canonicalPermission(value, appId) {
|
|
|
2507
2522
|
function stableJson(value) {
|
|
2508
2523
|
if (Array.isArray(value)) return `[${value.map(stableJson).join(",")}]`;
|
|
2509
2524
|
if (value && typeof value === "object") {
|
|
2510
|
-
const
|
|
2511
|
-
return `{${Object.keys(
|
|
2525
|
+
const record2 = value;
|
|
2526
|
+
return `{${Object.keys(record2).sort().map((key) => `${JSON.stringify(key)}:${stableJson(record2[key])}`).join(",")}}`;
|
|
2512
2527
|
}
|
|
2513
2528
|
return JSON.stringify(value);
|
|
2514
2529
|
}
|
|
@@ -2649,8 +2664,8 @@ function resourceSchema(resource) {
|
|
|
2649
2664
|
function derivedOutputSchema(action) {
|
|
2650
2665
|
const resource = resourceFor(action);
|
|
2651
2666
|
const operation = operationFor(action);
|
|
2652
|
-
const
|
|
2653
|
-
const records = { type: "array", items:
|
|
2667
|
+
const record2 = resourceSchema(resource);
|
|
2668
|
+
const records = { type: "array", items: record2 };
|
|
2654
2669
|
const provenance = {
|
|
2655
2670
|
"x-topolo-contract-source": "derived-action-metadata",
|
|
2656
2671
|
"x-topolo-contract-precision": "structural"
|
|
@@ -2682,12 +2697,12 @@ function derivedOutputSchema(action) {
|
|
|
2682
2697
|
title: `${action.title || action.name} response`,
|
|
2683
2698
|
description: `Resource response returned by ${action.name}. The service may return the resource directly or in an envelope.`,
|
|
2684
2699
|
oneOf: [
|
|
2685
|
-
|
|
2700
|
+
record2,
|
|
2686
2701
|
{
|
|
2687
2702
|
type: "object",
|
|
2688
2703
|
properties: {
|
|
2689
|
-
data:
|
|
2690
|
-
[resource]:
|
|
2704
|
+
data: record2,
|
|
2705
|
+
[resource]: record2
|
|
2691
2706
|
},
|
|
2692
2707
|
additionalProperties: true
|
|
2693
2708
|
}
|
|
@@ -2702,7 +2717,7 @@ function derivedOutputSchema(action) {
|
|
|
2702
2717
|
properties: {
|
|
2703
2718
|
success: { type: "boolean" },
|
|
2704
2719
|
id: { type: "string" },
|
|
2705
|
-
data: { oneOf: [
|
|
2720
|
+
data: { oneOf: [record2, { type: "object", additionalProperties: true }] },
|
|
2706
2721
|
result: { type: "object", additionalProperties: true },
|
|
2707
2722
|
message: { type: "string" }
|
|
2708
2723
|
},
|
|
@@ -3001,6 +3016,218 @@ var IdentityModule = class {
|
|
|
3001
3016
|
}
|
|
3002
3017
|
};
|
|
3003
3018
|
|
|
3019
|
+
// src/actor-envelope.ts
|
|
3020
|
+
var ACTOR_ENVELOPE_VERSION = 1;
|
|
3021
|
+
var PRINCIPAL_TYPES = /* @__PURE__ */ new Set([
|
|
3022
|
+
"human",
|
|
3023
|
+
"managed_agent",
|
|
3024
|
+
"external_agent",
|
|
3025
|
+
"service",
|
|
3026
|
+
"browser_automation"
|
|
3027
|
+
]);
|
|
3028
|
+
var ACCOUNTABLE_SUBJECT_TYPES = /* @__PURE__ */ new Set(["human", "organization"]);
|
|
3029
|
+
var CHANNELS = /* @__PURE__ */ new Set(["web", "mobile", "cli", "mcp", "api", "workflow", "browser_automation"]);
|
|
3030
|
+
var ASSURANCE_LEVELS = /* @__PURE__ */ new Set(["authenticated", "workload_identity", "user_verified"]);
|
|
3031
|
+
var HASH_PATTERN = /^sha256:[a-f0-9]{64}$/;
|
|
3032
|
+
var ActorEnvelopeValidationError = class extends Error {
|
|
3033
|
+
path;
|
|
3034
|
+
constructor(path, message) {
|
|
3035
|
+
super(`${path}: ${message}`);
|
|
3036
|
+
this.name = "ActorEnvelopeValidationError";
|
|
3037
|
+
this.path = path;
|
|
3038
|
+
}
|
|
3039
|
+
};
|
|
3040
|
+
function parseActorEnvelope(value) {
|
|
3041
|
+
const envelope = record(value, "actorEnvelope");
|
|
3042
|
+
exactKeys(envelope, [
|
|
3043
|
+
"schemaVersion",
|
|
3044
|
+
"organizationId",
|
|
3045
|
+
"accountableSubject",
|
|
3046
|
+
"performer",
|
|
3047
|
+
"delegation",
|
|
3048
|
+
"channel",
|
|
3049
|
+
"assurance",
|
|
3050
|
+
"action",
|
|
3051
|
+
"issuedAt",
|
|
3052
|
+
"expiresAt"
|
|
3053
|
+
], "actorEnvelope");
|
|
3054
|
+
if (envelope.schemaVersion !== ACTOR_ENVELOPE_VERSION) {
|
|
3055
|
+
fail("actorEnvelope.schemaVersion", `must equal ${ACTOR_ENVELOPE_VERSION}`);
|
|
3056
|
+
}
|
|
3057
|
+
const accountableSubject = parseAccountableSubject(envelope.accountableSubject);
|
|
3058
|
+
const performer = parseIdentity(envelope.performer, "actorEnvelope.performer");
|
|
3059
|
+
const organizationId = text(envelope.organizationId, "actorEnvelope.organizationId");
|
|
3060
|
+
const channel = member(envelope.channel, CHANNELS, "actorEnvelope.channel");
|
|
3061
|
+
const issuedAt = timestamp(envelope.issuedAt, "actorEnvelope.issuedAt");
|
|
3062
|
+
const expiresAt = envelope.expiresAt === void 0 ? void 0 : timestamp(envelope.expiresAt, "actorEnvelope.expiresAt");
|
|
3063
|
+
if (expiresAt && Date.parse(expiresAt) <= Date.parse(issuedAt)) {
|
|
3064
|
+
fail("actorEnvelope.expiresAt", "must be later than issuedAt");
|
|
3065
|
+
}
|
|
3066
|
+
const assuranceValue = record(envelope.assurance, "actorEnvelope.assurance");
|
|
3067
|
+
exactKeys(assuranceValue, ["level", "methods"], "actorEnvelope.assurance");
|
|
3068
|
+
const assurance = {
|
|
3069
|
+
level: member(assuranceValue.level, ASSURANCE_LEVELS, "actorEnvelope.assurance.level"),
|
|
3070
|
+
methods: textArray(assuranceValue.methods, "actorEnvelope.assurance.methods")
|
|
3071
|
+
};
|
|
3072
|
+
const actionValue = record(envelope.action, "actorEnvelope.action");
|
|
3073
|
+
exactKeys(actionValue, ["requestId", "actionId", "resourceType", "resourceId", "inputHash"], "actorEnvelope.action");
|
|
3074
|
+
const inputHash = text(actionValue.inputHash, "actorEnvelope.action.inputHash");
|
|
3075
|
+
if (!HASH_PATTERN.test(inputHash)) fail("actorEnvelope.action.inputHash", "must be a lowercase sha256 digest");
|
|
3076
|
+
const action = {
|
|
3077
|
+
requestId: text(actionValue.requestId, "actorEnvelope.action.requestId"),
|
|
3078
|
+
actionId: text(actionValue.actionId, "actorEnvelope.action.actionId"),
|
|
3079
|
+
...actionValue.resourceType === void 0 ? {} : { resourceType: text(actionValue.resourceType, "actorEnvelope.action.resourceType") },
|
|
3080
|
+
...actionValue.resourceId === void 0 ? {} : { resourceId: text(actionValue.resourceId, "actorEnvelope.action.resourceId") },
|
|
3081
|
+
inputHash
|
|
3082
|
+
};
|
|
3083
|
+
if (action.resourceType === void 0 !== (action.resourceId === void 0)) {
|
|
3084
|
+
fail("actorEnvelope.action", "resourceType and resourceId must be provided together");
|
|
3085
|
+
}
|
|
3086
|
+
const delegation = parseDelegation(envelope.delegation);
|
|
3087
|
+
const directHuman = performer.principalType === "human" && performer.principalId === accountableSubject.principalId;
|
|
3088
|
+
if (directHuman && delegation !== null) fail("actorEnvelope.delegation", "must be null for direct human action");
|
|
3089
|
+
if (!directHuman && delegation === null) fail("actorEnvelope.delegation", "is required when performer differs from accountable subject");
|
|
3090
|
+
if (delegation) {
|
|
3091
|
+
const finalHop = delegation.lineage.at(-1);
|
|
3092
|
+
if (!finalHop || finalHop.principalId !== performer.principalId || finalHop.principalType !== performer.principalType) {
|
|
3093
|
+
fail("actorEnvelope.delegation.lineage", "must end with the performer");
|
|
3094
|
+
}
|
|
3095
|
+
}
|
|
3096
|
+
if (performer.principalType === "external_agent" && (!performer.installationId || !performer.provider)) {
|
|
3097
|
+
fail("actorEnvelope.performer", "external_agent requires installationId and provider");
|
|
3098
|
+
}
|
|
3099
|
+
if (performer.principalType === "managed_agent" && !performer.agentInstanceId) {
|
|
3100
|
+
fail("actorEnvelope.performer.agentInstanceId", "is required for managed_agent");
|
|
3101
|
+
}
|
|
3102
|
+
if (performer.principalType === "browser_automation" && (!performer.installationId || !performer.browserSessionId)) {
|
|
3103
|
+
fail("actorEnvelope.performer", "browser_automation requires installationId and browserSessionId");
|
|
3104
|
+
}
|
|
3105
|
+
return {
|
|
3106
|
+
schemaVersion: ACTOR_ENVELOPE_VERSION,
|
|
3107
|
+
organizationId,
|
|
3108
|
+
accountableSubject,
|
|
3109
|
+
performer,
|
|
3110
|
+
delegation,
|
|
3111
|
+
channel,
|
|
3112
|
+
assurance,
|
|
3113
|
+
action,
|
|
3114
|
+
issuedAt,
|
|
3115
|
+
...expiresAt ? { expiresAt } : {}
|
|
3116
|
+
};
|
|
3117
|
+
}
|
|
3118
|
+
function canonicalizeActorEnvelope(value) {
|
|
3119
|
+
return canonicalJson(parseActorEnvelope(value));
|
|
3120
|
+
}
|
|
3121
|
+
function canonicalJson(value) {
|
|
3122
|
+
if (value === null) return "null";
|
|
3123
|
+
if (typeof value === "string" || typeof value === "boolean") return JSON.stringify(value);
|
|
3124
|
+
if (typeof value === "number") {
|
|
3125
|
+
if (!Number.isFinite(value)) throw new TypeError("Canonical JSON accepts finite numbers only.");
|
|
3126
|
+
return JSON.stringify(value);
|
|
3127
|
+
}
|
|
3128
|
+
if (Array.isArray(value)) return `[${value.map(canonicalJson).join(",")}]`;
|
|
3129
|
+
if (typeof value !== "object" || !value || ![Object.prototype, null].includes(Object.getPrototypeOf(value))) {
|
|
3130
|
+
throw new TypeError("Canonical JSON accepts JSON objects, arrays, and primitives only.");
|
|
3131
|
+
}
|
|
3132
|
+
const entries = Object.entries(value).filter(([, item]) => item !== void 0).sort(([left], [right]) => left.localeCompare(right));
|
|
3133
|
+
return `{${entries.map(([key, item]) => `${JSON.stringify(key)}:${canonicalJson(item)}`).join(",")}}`;
|
|
3134
|
+
}
|
|
3135
|
+
function parseAccountableSubject(value) {
|
|
3136
|
+
const path = "actorEnvelope.accountableSubject";
|
|
3137
|
+
const subject = record(value, path);
|
|
3138
|
+
exactKeys(subject, ["principalType", "principalId", "displayName"], path);
|
|
3139
|
+
return {
|
|
3140
|
+
principalType: member(subject.principalType, ACCOUNTABLE_SUBJECT_TYPES, `${path}.principalType`),
|
|
3141
|
+
principalId: text(subject.principalId, `${path}.principalId`),
|
|
3142
|
+
...subject.displayName === void 0 ? {} : { displayName: text(subject.displayName, `${path}.displayName`) }
|
|
3143
|
+
};
|
|
3144
|
+
}
|
|
3145
|
+
async function sha256CanonicalValue(value) {
|
|
3146
|
+
const bytes = new TextEncoder().encode(canonicalJson(value));
|
|
3147
|
+
const digest = await crypto.subtle.digest("SHA-256", bytes);
|
|
3148
|
+
return `sha256:${Array.from(new Uint8Array(digest), (byte) => byte.toString(16).padStart(2, "0")).join("")}`;
|
|
3149
|
+
}
|
|
3150
|
+
function parseIdentity(value, path) {
|
|
3151
|
+
const identity = record(value, path);
|
|
3152
|
+
exactKeys(identity, [
|
|
3153
|
+
"principalType",
|
|
3154
|
+
"principalId",
|
|
3155
|
+
"displayName",
|
|
3156
|
+
"installationId",
|
|
3157
|
+
"agentInstanceId",
|
|
3158
|
+
"browserSessionId",
|
|
3159
|
+
"provider",
|
|
3160
|
+
"model"
|
|
3161
|
+
], path);
|
|
3162
|
+
return {
|
|
3163
|
+
principalType: member(identity.principalType, PRINCIPAL_TYPES, `${path}.principalType`),
|
|
3164
|
+
principalId: text(identity.principalId, `${path}.principalId`),
|
|
3165
|
+
...optionalTextFields(identity, path, [
|
|
3166
|
+
"displayName",
|
|
3167
|
+
"installationId",
|
|
3168
|
+
"agentInstanceId",
|
|
3169
|
+
"browserSessionId",
|
|
3170
|
+
"provider",
|
|
3171
|
+
"model"
|
|
3172
|
+
])
|
|
3173
|
+
};
|
|
3174
|
+
}
|
|
3175
|
+
function parseDelegation(value) {
|
|
3176
|
+
if (value === null) return null;
|
|
3177
|
+
const delegation = record(value, "actorEnvelope.delegation");
|
|
3178
|
+
exactKeys(delegation, ["taskId", "runId", "lineage"], "actorEnvelope.delegation");
|
|
3179
|
+
if (!Array.isArray(delegation.lineage) || delegation.lineage.length === 0 || delegation.lineage.length > 16) {
|
|
3180
|
+
fail("actorEnvelope.delegation.lineage", "must contain between 1 and 16 hops");
|
|
3181
|
+
}
|
|
3182
|
+
return {
|
|
3183
|
+
taskId: text(delegation.taskId, "actorEnvelope.delegation.taskId"),
|
|
3184
|
+
runId: text(delegation.runId, "actorEnvelope.delegation.runId"),
|
|
3185
|
+
lineage: delegation.lineage.map((value2, index) => {
|
|
3186
|
+
const hop = record(value2, `actorEnvelope.delegation.lineage[${index}]`);
|
|
3187
|
+
exactKeys(hop, ["principalType", "principalId"], `actorEnvelope.delegation.lineage[${index}]`);
|
|
3188
|
+
return {
|
|
3189
|
+
principalType: member(hop.principalType, PRINCIPAL_TYPES, `actorEnvelope.delegation.lineage[${index}].principalType`),
|
|
3190
|
+
principalId: text(hop.principalId, `actorEnvelope.delegation.lineage[${index}].principalId`)
|
|
3191
|
+
};
|
|
3192
|
+
})
|
|
3193
|
+
};
|
|
3194
|
+
}
|
|
3195
|
+
function record(value, path) {
|
|
3196
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) fail(path, "must be an object");
|
|
3197
|
+
return value;
|
|
3198
|
+
}
|
|
3199
|
+
function exactKeys(value, allowed, path) {
|
|
3200
|
+
const unknown = Object.keys(value).filter((key) => !allowed.includes(key));
|
|
3201
|
+
if (unknown.length) fail(path, `contains unknown field ${unknown[0]}`);
|
|
3202
|
+
}
|
|
3203
|
+
function text(value, path) {
|
|
3204
|
+
if (typeof value !== "string" || value.trim() !== value || value.length === 0 || value.length > 256) {
|
|
3205
|
+
fail(path, "must be a non-empty trimmed string of at most 256 characters");
|
|
3206
|
+
}
|
|
3207
|
+
return value;
|
|
3208
|
+
}
|
|
3209
|
+
function timestamp(value, path) {
|
|
3210
|
+
const result = text(value, path);
|
|
3211
|
+
if (!/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d{3})?Z$/.test(result) || Number.isNaN(Date.parse(result))) {
|
|
3212
|
+
fail(path, "must be an RFC 3339 UTC timestamp");
|
|
3213
|
+
}
|
|
3214
|
+
return result;
|
|
3215
|
+
}
|
|
3216
|
+
function member(value, values, path) {
|
|
3217
|
+
if (typeof value !== "string" || !values.has(value)) fail(path, "contains an unsupported value");
|
|
3218
|
+
return value;
|
|
3219
|
+
}
|
|
3220
|
+
function textArray(value, path) {
|
|
3221
|
+
if (!Array.isArray(value) || value.length === 0 || value.length > 16) fail(path, "must contain between 1 and 16 values");
|
|
3222
|
+
return value.map((item, index) => text(item, `${path}[${index}]`));
|
|
3223
|
+
}
|
|
3224
|
+
function optionalTextFields(value, path, keys) {
|
|
3225
|
+
return Object.fromEntries(keys.flatMap((key) => value[key] === void 0 ? [] : [[key, text(value[key], `${path}.${key}`)]]));
|
|
3226
|
+
}
|
|
3227
|
+
function fail(path, message) {
|
|
3228
|
+
throw new ActorEnvelopeValidationError(path, message);
|
|
3229
|
+
}
|
|
3230
|
+
|
|
3004
3231
|
// src/modules/workspaces.ts
|
|
3005
3232
|
var ACTIONS = {
|
|
3006
3233
|
list: "app_topolo_auth.workspaces.list",
|
|
@@ -4492,6 +4719,8 @@ function createTopolo(options) {
|
|
|
4492
4719
|
// Annotate the CommonJS export names for ESM import in node:
|
|
4493
4720
|
0 && (module.exports = {
|
|
4494
4721
|
ACTION_CATALOG_DIGEST_ALGORITHM,
|
|
4722
|
+
ACTOR_ENVELOPE_VERSION,
|
|
4723
|
+
ActorEnvelopeValidationError,
|
|
4495
4724
|
CrmModule,
|
|
4496
4725
|
DEFAULT_APP_URLS,
|
|
4497
4726
|
IdentityModule,
|
|
@@ -4513,10 +4742,12 @@ function createTopolo(options) {
|
|
|
4513
4742
|
actionContractCompleteness,
|
|
4514
4743
|
applicationEntryFromCatalog,
|
|
4515
4744
|
assertTopoloServiceUrlEnvironment,
|
|
4745
|
+
canonicalJson,
|
|
4516
4746
|
canonicalTopoloErrorCode,
|
|
4517
4747
|
canonicalTopoloRequestId,
|
|
4518
4748
|
canonicalTopoloRequired,
|
|
4519
4749
|
canonicalTopoloRetryAfter,
|
|
4750
|
+
canonicalizeActorEnvelope,
|
|
4520
4751
|
compactActionCatalogEntry,
|
|
4521
4752
|
compactActionPlan,
|
|
4522
4753
|
compactActionPreparation,
|
|
@@ -4540,6 +4771,7 @@ function createTopolo(options) {
|
|
|
4540
4771
|
friendlyAppId,
|
|
4541
4772
|
isTopoloWidgetOutputSchema,
|
|
4542
4773
|
listApplicationDirectory,
|
|
4774
|
+
parseActorEnvelope,
|
|
4543
4775
|
parseTopoloActionUploadContract,
|
|
4544
4776
|
preferExactActionMatches,
|
|
4545
4777
|
prepareTopoloActionBase64UploadInput,
|
|
@@ -4548,6 +4780,7 @@ function createTopolo(options) {
|
|
|
4548
4780
|
resolveApplicationDirectoryEntry,
|
|
4549
4781
|
resolveCatalogServiceUrl,
|
|
4550
4782
|
resolveServiceUrl,
|
|
4783
|
+
sha256CanonicalValue,
|
|
4551
4784
|
topoloErrorHint,
|
|
4552
4785
|
topoloServiceOrigins,
|
|
4553
4786
|
validateTopoloActionInput,
|
package/dist/index.d.cts
CHANGED
|
@@ -254,6 +254,7 @@ interface TopoloActionCatalogEntry {
|
|
|
254
254
|
}
|
|
255
255
|
interface TopoloActionAgentContract {
|
|
256
256
|
docsUrl?: string;
|
|
257
|
+
requiredReleaseCapability?: string;
|
|
257
258
|
resourceContext?: {
|
|
258
259
|
kind?: string;
|
|
259
260
|
required?: boolean;
|
|
@@ -901,6 +902,64 @@ declare class IdentityModule {
|
|
|
901
902
|
whoami(): Promise<CredentialIntrospection>;
|
|
902
903
|
}
|
|
903
904
|
|
|
905
|
+
declare const ACTOR_ENVELOPE_VERSION: 1;
|
|
906
|
+
type ActorPrincipalType = 'human' | 'managed_agent' | 'external_agent' | 'service' | 'browser_automation';
|
|
907
|
+
type AccountableSubjectType = 'human' | 'organization';
|
|
908
|
+
type ActorChannel = 'web' | 'mobile' | 'cli' | 'mcp' | 'api' | 'workflow' | 'browser_automation';
|
|
909
|
+
type ActorAssurance = 'authenticated' | 'workload_identity' | 'user_verified';
|
|
910
|
+
interface ActorIdentity {
|
|
911
|
+
principalType: ActorPrincipalType;
|
|
912
|
+
principalId: string;
|
|
913
|
+
displayName?: string;
|
|
914
|
+
installationId?: string;
|
|
915
|
+
agentInstanceId?: string;
|
|
916
|
+
browserSessionId?: string;
|
|
917
|
+
provider?: string;
|
|
918
|
+
model?: string;
|
|
919
|
+
}
|
|
920
|
+
interface AccountableSubject {
|
|
921
|
+
principalType: AccountableSubjectType;
|
|
922
|
+
principalId: string;
|
|
923
|
+
displayName?: string;
|
|
924
|
+
}
|
|
925
|
+
interface ActorDelegationHop {
|
|
926
|
+
principalType: ActorPrincipalType;
|
|
927
|
+
principalId: string;
|
|
928
|
+
}
|
|
929
|
+
interface ActorEnvelope {
|
|
930
|
+
schemaVersion: typeof ACTOR_ENVELOPE_VERSION;
|
|
931
|
+
organizationId: string;
|
|
932
|
+
accountableSubject: AccountableSubject;
|
|
933
|
+
performer: ActorIdentity;
|
|
934
|
+
delegation: {
|
|
935
|
+
taskId: string;
|
|
936
|
+
runId: string;
|
|
937
|
+
lineage: ActorDelegationHop[];
|
|
938
|
+
} | null;
|
|
939
|
+
channel: ActorChannel;
|
|
940
|
+
assurance: {
|
|
941
|
+
level: ActorAssurance;
|
|
942
|
+
methods: string[];
|
|
943
|
+
};
|
|
944
|
+
action: {
|
|
945
|
+
requestId: string;
|
|
946
|
+
actionId: string;
|
|
947
|
+
resourceType?: string;
|
|
948
|
+
resourceId?: string;
|
|
949
|
+
inputHash: string;
|
|
950
|
+
};
|
|
951
|
+
issuedAt: string;
|
|
952
|
+
expiresAt?: string;
|
|
953
|
+
}
|
|
954
|
+
declare class ActorEnvelopeValidationError extends Error {
|
|
955
|
+
readonly path: string;
|
|
956
|
+
constructor(path: string, message: string);
|
|
957
|
+
}
|
|
958
|
+
declare function parseActorEnvelope(value: unknown): ActorEnvelope;
|
|
959
|
+
declare function canonicalizeActorEnvelope(value: unknown): string;
|
|
960
|
+
declare function canonicalJson(value: unknown): string;
|
|
961
|
+
declare function sha256CanonicalValue(value: unknown): Promise<string>;
|
|
962
|
+
|
|
904
963
|
interface TopoloWorkspace {
|
|
905
964
|
id: string;
|
|
906
965
|
appId: string;
|
|
@@ -1593,4 +1652,4 @@ declare function createTopolo(options: TopoloClientOptions): {
|
|
|
1593
1652
|
};
|
|
1594
1653
|
type Topolo = ReturnType<typeof createTopolo>;
|
|
1595
1654
|
|
|
1596
|
-
export { ACTION_CATALOG_DIGEST_ALGORITHM, type ActionContractManifest, type ActionContractSource, type AgentIdentity, type AppApiId, type ApplicationCatalogEntry, type ApplicationDeployTarget, type ApplicationDirectory, type ApplicationDirectoryApplication, type ApplicationDirectoryClient, type ApplicationDirectorySource, type ApplicationId, type CredentialIntrospection, type CrmContactSummary, CrmModule, DEFAULT_APP_URLS, type DeviceAuthorizationResponse, IdentityModule, type ListContactsOptions, type ListContactsResult, type OAuthHelperOptions, type P2PActionDetail, type P2PActionRequestInput, type P2PActionRequestResult, type P2PActionRow, type P2PActionRun, type P2PCapability, type P2PConnection, type P2PHold, type P2PLedgerEntry, P2PModule, type P2PPolicy, type P2PPricingModel, type P2PSettlementBatch, type P2PSettlementGroup, type PublishCapabilityInput, type RequestOptions, type ServiceCatalogUrlEntry, TOPOLO_ENVIRONMENT_SERVICE_URLS, TOPOLO_RUNTIME_ENVIRONMENTS, TOPOLO_WIDGET_CONTRACT_VERSION, TOPOLO_WIDGET_ENDPOINT, TOPOLO_WIDGET_OUTPUT_SCHEMA, TOPOLO_WIDGET_REFRESH_INTERVAL_MS, type TokenResponse, type Topolo, type TopoloActionAgentContract, type TopoloActionCatalogEntry, type TopoloActionCatalogSummary, type TopoloActionDigestInput, type TopoloActionPlan, type TopoloActionPreparation, type TopoloActionUploadOptions, type TopoloActionValidationIssue, type TopoloActionValidationResult, type TopoloActionsWidget, type TopoloActivityWidget, type TopoloAgentExecutionContext, type TopoloApiKeyResourceMetadata, TopoloAuthError, type TopoloBinaryResponse, type TopoloBindableResource, type TopoloBindableResourceCatalog, type TopoloChartWidget, TopoloClient, type TopoloClientOptions, TopoloConfirmationRequiredError, type TopoloCredential, type TopoloDebugEvent, TopoloHttpError, type TopoloInlineBase64UploadContract, type TopoloJsonSchema, type TopoloNotificationsWidget, TopoloOAuth, TopoloPermissionError, type TopoloRuntimeEnvironment, TopoloSdkError, type TopoloServiceCatalogEntry, type TopoloStatsWidget, type TopoloWidget, type TopoloWidgetAccessibility, type TopoloWidgetActionBinding, type TopoloWidgetActionRecovery, type TopoloWidgetActivityItem, type TopoloWidgetApiError, type TopoloWidgetApiErrorResponse, type TopoloWidgetApiResponse, type TopoloWidgetApiSuccessResponse, type TopoloWidgetBase, type TopoloWidgetConfig, type TopoloWidgetConfiguration, type TopoloWidgetConfigurationField, type TopoloWidgetConfigurationOption, type TopoloWidgetContext, type TopoloWidgetContribution, type TopoloWidgetDatasetDefinition, type TopoloWidgetDimension, type TopoloWidgetDimensionDefinition, type TopoloWidgetDraft, type TopoloWidgetDrilldown, type TopoloWidgetErrorResponseOptions, type TopoloWidgetEventDefinition, type TopoloWidgetLifecycleStage, type TopoloWidgetLocalization, type TopoloWidgetMetric, type TopoloWidgetMetricAggregation, type TopoloWidgetMetricComparison, type TopoloWidgetMetricDefinition, type TopoloWidgetMetricSemantic, type TopoloWidgetNotificationItem, type TopoloWidgetPeriod, type TopoloWidgetPresentation, type TopoloWidgetRefreshPolicy, type TopoloWidgetResourceBinding, type TopoloWidgetResponseOptions, type TopoloWidgetSeries, type TopoloWidgetSeriesDefinition, type TopoloWidgetSeriesPoint, type TopoloWidgetSize, type TopoloWidgetState, type TopoloWidgetStatus, type TopoloWidgetType, type TopoloWidgetValidationResult, type TopoloWidgetVisualizationFamily, type TopoloWidgetWorkspaceSelector, type TopoloWorkspace, type TopoloWorkspaceListResult, type TopoloWorkspaceMutationResult, type TopoloWorkspacePolicy, WorkspacesModule, actionContractCompleteness, applicationEntryFromCatalog, assertTopoloServiceUrlEnvironment, canonicalTopoloErrorCode, canonicalTopoloRequestId, canonicalTopoloRequired, canonicalTopoloRetryAfter, compactActionCatalogEntry, compactActionPlan, compactActionPreparation, compactActionResult, compactActionValidation, createTopolo, createTopoloAgentExecutionContext, createTopoloWidgetError, createTopoloWidgetResponse, defineTopoloActionsWidget, defineTopoloActivityWidget, defineTopoloChartWidget, defineTopoloNotificationsWidget, defineTopoloStatsWidget, digestTopoloActionCatalog, encodeTopoloActionBase64, enrichActionContract, extractTopoloServiceErrorCode, extractTopoloServiceErrorDetails, formatDirectoryApplicationIds, friendlyAppId, isTopoloWidgetOutputSchema, listApplicationDirectory, parseTopoloActionUploadContract, preferExactActionMatches, prepareTopoloActionBase64UploadInput, prepareTopoloActionUploadInput, publicTopoloErrorMessage, resolveApplicationDirectoryEntry, resolveCatalogServiceUrl, resolveServiceUrl, topoloErrorHint, topoloServiceOrigins, validateTopoloActionInput, validateTopoloWidgetResponse };
|
|
1655
|
+
export { ACTION_CATALOG_DIGEST_ALGORITHM, ACTOR_ENVELOPE_VERSION, type AccountableSubject, type AccountableSubjectType, type ActionContractManifest, type ActionContractSource, type ActorAssurance, type ActorChannel, type ActorDelegationHop, type ActorEnvelope, ActorEnvelopeValidationError, type ActorIdentity, type ActorPrincipalType, type AgentIdentity, type AppApiId, type ApplicationCatalogEntry, type ApplicationDeployTarget, type ApplicationDirectory, type ApplicationDirectoryApplication, type ApplicationDirectoryClient, type ApplicationDirectorySource, type ApplicationId, type CredentialIntrospection, type CrmContactSummary, CrmModule, DEFAULT_APP_URLS, type DeviceAuthorizationResponse, IdentityModule, type ListContactsOptions, type ListContactsResult, type OAuthHelperOptions, type P2PActionDetail, type P2PActionRequestInput, type P2PActionRequestResult, type P2PActionRow, type P2PActionRun, type P2PCapability, type P2PConnection, type P2PHold, type P2PLedgerEntry, P2PModule, type P2PPolicy, type P2PPricingModel, type P2PSettlementBatch, type P2PSettlementGroup, type PublishCapabilityInput, type RequestOptions, type ServiceCatalogUrlEntry, TOPOLO_ENVIRONMENT_SERVICE_URLS, TOPOLO_RUNTIME_ENVIRONMENTS, TOPOLO_WIDGET_CONTRACT_VERSION, TOPOLO_WIDGET_ENDPOINT, TOPOLO_WIDGET_OUTPUT_SCHEMA, TOPOLO_WIDGET_REFRESH_INTERVAL_MS, type TokenResponse, type Topolo, type TopoloActionAgentContract, type TopoloActionCatalogEntry, type TopoloActionCatalogSummary, type TopoloActionDigestInput, type TopoloActionPlan, type TopoloActionPreparation, type TopoloActionUploadOptions, type TopoloActionValidationIssue, type TopoloActionValidationResult, type TopoloActionsWidget, type TopoloActivityWidget, type TopoloAgentExecutionContext, type TopoloApiKeyResourceMetadata, TopoloAuthError, type TopoloBinaryResponse, type TopoloBindableResource, type TopoloBindableResourceCatalog, type TopoloChartWidget, TopoloClient, type TopoloClientOptions, TopoloConfirmationRequiredError, type TopoloCredential, type TopoloDebugEvent, TopoloHttpError, type TopoloInlineBase64UploadContract, type TopoloJsonSchema, type TopoloNotificationsWidget, TopoloOAuth, TopoloPermissionError, type TopoloRuntimeEnvironment, TopoloSdkError, type TopoloServiceCatalogEntry, type TopoloStatsWidget, type TopoloWidget, type TopoloWidgetAccessibility, type TopoloWidgetActionBinding, type TopoloWidgetActionRecovery, type TopoloWidgetActivityItem, type TopoloWidgetApiError, type TopoloWidgetApiErrorResponse, type TopoloWidgetApiResponse, type TopoloWidgetApiSuccessResponse, type TopoloWidgetBase, type TopoloWidgetConfig, type TopoloWidgetConfiguration, type TopoloWidgetConfigurationField, type TopoloWidgetConfigurationOption, type TopoloWidgetContext, type TopoloWidgetContribution, type TopoloWidgetDatasetDefinition, type TopoloWidgetDimension, type TopoloWidgetDimensionDefinition, type TopoloWidgetDraft, type TopoloWidgetDrilldown, type TopoloWidgetErrorResponseOptions, type TopoloWidgetEventDefinition, type TopoloWidgetLifecycleStage, type TopoloWidgetLocalization, type TopoloWidgetMetric, type TopoloWidgetMetricAggregation, type TopoloWidgetMetricComparison, type TopoloWidgetMetricDefinition, type TopoloWidgetMetricSemantic, type TopoloWidgetNotificationItem, type TopoloWidgetPeriod, type TopoloWidgetPresentation, type TopoloWidgetRefreshPolicy, type TopoloWidgetResourceBinding, type TopoloWidgetResponseOptions, type TopoloWidgetSeries, type TopoloWidgetSeriesDefinition, type TopoloWidgetSeriesPoint, type TopoloWidgetSize, type TopoloWidgetState, type TopoloWidgetStatus, type TopoloWidgetType, type TopoloWidgetValidationResult, type TopoloWidgetVisualizationFamily, type TopoloWidgetWorkspaceSelector, type TopoloWorkspace, type TopoloWorkspaceListResult, type TopoloWorkspaceMutationResult, type TopoloWorkspacePolicy, WorkspacesModule, actionContractCompleteness, applicationEntryFromCatalog, assertTopoloServiceUrlEnvironment, canonicalJson, canonicalTopoloErrorCode, canonicalTopoloRequestId, canonicalTopoloRequired, canonicalTopoloRetryAfter, canonicalizeActorEnvelope, compactActionCatalogEntry, compactActionPlan, compactActionPreparation, compactActionResult, compactActionValidation, createTopolo, createTopoloAgentExecutionContext, createTopoloWidgetError, createTopoloWidgetResponse, defineTopoloActionsWidget, defineTopoloActivityWidget, defineTopoloChartWidget, defineTopoloNotificationsWidget, defineTopoloStatsWidget, digestTopoloActionCatalog, encodeTopoloActionBase64, enrichActionContract, extractTopoloServiceErrorCode, extractTopoloServiceErrorDetails, formatDirectoryApplicationIds, friendlyAppId, isTopoloWidgetOutputSchema, listApplicationDirectory, parseActorEnvelope, parseTopoloActionUploadContract, preferExactActionMatches, prepareTopoloActionBase64UploadInput, prepareTopoloActionUploadInput, publicTopoloErrorMessage, resolveApplicationDirectoryEntry, resolveCatalogServiceUrl, resolveServiceUrl, sha256CanonicalValue, topoloErrorHint, topoloServiceOrigins, validateTopoloActionInput, validateTopoloWidgetResponse };
|
package/dist/index.d.ts
CHANGED
|
@@ -254,6 +254,7 @@ interface TopoloActionCatalogEntry {
|
|
|
254
254
|
}
|
|
255
255
|
interface TopoloActionAgentContract {
|
|
256
256
|
docsUrl?: string;
|
|
257
|
+
requiredReleaseCapability?: string;
|
|
257
258
|
resourceContext?: {
|
|
258
259
|
kind?: string;
|
|
259
260
|
required?: boolean;
|
|
@@ -901,6 +902,64 @@ declare class IdentityModule {
|
|
|
901
902
|
whoami(): Promise<CredentialIntrospection>;
|
|
902
903
|
}
|
|
903
904
|
|
|
905
|
+
declare const ACTOR_ENVELOPE_VERSION: 1;
|
|
906
|
+
type ActorPrincipalType = 'human' | 'managed_agent' | 'external_agent' | 'service' | 'browser_automation';
|
|
907
|
+
type AccountableSubjectType = 'human' | 'organization';
|
|
908
|
+
type ActorChannel = 'web' | 'mobile' | 'cli' | 'mcp' | 'api' | 'workflow' | 'browser_automation';
|
|
909
|
+
type ActorAssurance = 'authenticated' | 'workload_identity' | 'user_verified';
|
|
910
|
+
interface ActorIdentity {
|
|
911
|
+
principalType: ActorPrincipalType;
|
|
912
|
+
principalId: string;
|
|
913
|
+
displayName?: string;
|
|
914
|
+
installationId?: string;
|
|
915
|
+
agentInstanceId?: string;
|
|
916
|
+
browserSessionId?: string;
|
|
917
|
+
provider?: string;
|
|
918
|
+
model?: string;
|
|
919
|
+
}
|
|
920
|
+
interface AccountableSubject {
|
|
921
|
+
principalType: AccountableSubjectType;
|
|
922
|
+
principalId: string;
|
|
923
|
+
displayName?: string;
|
|
924
|
+
}
|
|
925
|
+
interface ActorDelegationHop {
|
|
926
|
+
principalType: ActorPrincipalType;
|
|
927
|
+
principalId: string;
|
|
928
|
+
}
|
|
929
|
+
interface ActorEnvelope {
|
|
930
|
+
schemaVersion: typeof ACTOR_ENVELOPE_VERSION;
|
|
931
|
+
organizationId: string;
|
|
932
|
+
accountableSubject: AccountableSubject;
|
|
933
|
+
performer: ActorIdentity;
|
|
934
|
+
delegation: {
|
|
935
|
+
taskId: string;
|
|
936
|
+
runId: string;
|
|
937
|
+
lineage: ActorDelegationHop[];
|
|
938
|
+
} | null;
|
|
939
|
+
channel: ActorChannel;
|
|
940
|
+
assurance: {
|
|
941
|
+
level: ActorAssurance;
|
|
942
|
+
methods: string[];
|
|
943
|
+
};
|
|
944
|
+
action: {
|
|
945
|
+
requestId: string;
|
|
946
|
+
actionId: string;
|
|
947
|
+
resourceType?: string;
|
|
948
|
+
resourceId?: string;
|
|
949
|
+
inputHash: string;
|
|
950
|
+
};
|
|
951
|
+
issuedAt: string;
|
|
952
|
+
expiresAt?: string;
|
|
953
|
+
}
|
|
954
|
+
declare class ActorEnvelopeValidationError extends Error {
|
|
955
|
+
readonly path: string;
|
|
956
|
+
constructor(path: string, message: string);
|
|
957
|
+
}
|
|
958
|
+
declare function parseActorEnvelope(value: unknown): ActorEnvelope;
|
|
959
|
+
declare function canonicalizeActorEnvelope(value: unknown): string;
|
|
960
|
+
declare function canonicalJson(value: unknown): string;
|
|
961
|
+
declare function sha256CanonicalValue(value: unknown): Promise<string>;
|
|
962
|
+
|
|
904
963
|
interface TopoloWorkspace {
|
|
905
964
|
id: string;
|
|
906
965
|
appId: string;
|
|
@@ -1593,4 +1652,4 @@ declare function createTopolo(options: TopoloClientOptions): {
|
|
|
1593
1652
|
};
|
|
1594
1653
|
type Topolo = ReturnType<typeof createTopolo>;
|
|
1595
1654
|
|
|
1596
|
-
export { ACTION_CATALOG_DIGEST_ALGORITHM, type ActionContractManifest, type ActionContractSource, type AgentIdentity, type AppApiId, type ApplicationCatalogEntry, type ApplicationDeployTarget, type ApplicationDirectory, type ApplicationDirectoryApplication, type ApplicationDirectoryClient, type ApplicationDirectorySource, type ApplicationId, type CredentialIntrospection, type CrmContactSummary, CrmModule, DEFAULT_APP_URLS, type DeviceAuthorizationResponse, IdentityModule, type ListContactsOptions, type ListContactsResult, type OAuthHelperOptions, type P2PActionDetail, type P2PActionRequestInput, type P2PActionRequestResult, type P2PActionRow, type P2PActionRun, type P2PCapability, type P2PConnection, type P2PHold, type P2PLedgerEntry, P2PModule, type P2PPolicy, type P2PPricingModel, type P2PSettlementBatch, type P2PSettlementGroup, type PublishCapabilityInput, type RequestOptions, type ServiceCatalogUrlEntry, TOPOLO_ENVIRONMENT_SERVICE_URLS, TOPOLO_RUNTIME_ENVIRONMENTS, TOPOLO_WIDGET_CONTRACT_VERSION, TOPOLO_WIDGET_ENDPOINT, TOPOLO_WIDGET_OUTPUT_SCHEMA, TOPOLO_WIDGET_REFRESH_INTERVAL_MS, type TokenResponse, type Topolo, type TopoloActionAgentContract, type TopoloActionCatalogEntry, type TopoloActionCatalogSummary, type TopoloActionDigestInput, type TopoloActionPlan, type TopoloActionPreparation, type TopoloActionUploadOptions, type TopoloActionValidationIssue, type TopoloActionValidationResult, type TopoloActionsWidget, type TopoloActivityWidget, type TopoloAgentExecutionContext, type TopoloApiKeyResourceMetadata, TopoloAuthError, type TopoloBinaryResponse, type TopoloBindableResource, type TopoloBindableResourceCatalog, type TopoloChartWidget, TopoloClient, type TopoloClientOptions, TopoloConfirmationRequiredError, type TopoloCredential, type TopoloDebugEvent, TopoloHttpError, type TopoloInlineBase64UploadContract, type TopoloJsonSchema, type TopoloNotificationsWidget, TopoloOAuth, TopoloPermissionError, type TopoloRuntimeEnvironment, TopoloSdkError, type TopoloServiceCatalogEntry, type TopoloStatsWidget, type TopoloWidget, type TopoloWidgetAccessibility, type TopoloWidgetActionBinding, type TopoloWidgetActionRecovery, type TopoloWidgetActivityItem, type TopoloWidgetApiError, type TopoloWidgetApiErrorResponse, type TopoloWidgetApiResponse, type TopoloWidgetApiSuccessResponse, type TopoloWidgetBase, type TopoloWidgetConfig, type TopoloWidgetConfiguration, type TopoloWidgetConfigurationField, type TopoloWidgetConfigurationOption, type TopoloWidgetContext, type TopoloWidgetContribution, type TopoloWidgetDatasetDefinition, type TopoloWidgetDimension, type TopoloWidgetDimensionDefinition, type TopoloWidgetDraft, type TopoloWidgetDrilldown, type TopoloWidgetErrorResponseOptions, type TopoloWidgetEventDefinition, type TopoloWidgetLifecycleStage, type TopoloWidgetLocalization, type TopoloWidgetMetric, type TopoloWidgetMetricAggregation, type TopoloWidgetMetricComparison, type TopoloWidgetMetricDefinition, type TopoloWidgetMetricSemantic, type TopoloWidgetNotificationItem, type TopoloWidgetPeriod, type TopoloWidgetPresentation, type TopoloWidgetRefreshPolicy, type TopoloWidgetResourceBinding, type TopoloWidgetResponseOptions, type TopoloWidgetSeries, type TopoloWidgetSeriesDefinition, type TopoloWidgetSeriesPoint, type TopoloWidgetSize, type TopoloWidgetState, type TopoloWidgetStatus, type TopoloWidgetType, type TopoloWidgetValidationResult, type TopoloWidgetVisualizationFamily, type TopoloWidgetWorkspaceSelector, type TopoloWorkspace, type TopoloWorkspaceListResult, type TopoloWorkspaceMutationResult, type TopoloWorkspacePolicy, WorkspacesModule, actionContractCompleteness, applicationEntryFromCatalog, assertTopoloServiceUrlEnvironment, canonicalTopoloErrorCode, canonicalTopoloRequestId, canonicalTopoloRequired, canonicalTopoloRetryAfter, compactActionCatalogEntry, compactActionPlan, compactActionPreparation, compactActionResult, compactActionValidation, createTopolo, createTopoloAgentExecutionContext, createTopoloWidgetError, createTopoloWidgetResponse, defineTopoloActionsWidget, defineTopoloActivityWidget, defineTopoloChartWidget, defineTopoloNotificationsWidget, defineTopoloStatsWidget, digestTopoloActionCatalog, encodeTopoloActionBase64, enrichActionContract, extractTopoloServiceErrorCode, extractTopoloServiceErrorDetails, formatDirectoryApplicationIds, friendlyAppId, isTopoloWidgetOutputSchema, listApplicationDirectory, parseTopoloActionUploadContract, preferExactActionMatches, prepareTopoloActionBase64UploadInput, prepareTopoloActionUploadInput, publicTopoloErrorMessage, resolveApplicationDirectoryEntry, resolveCatalogServiceUrl, resolveServiceUrl, topoloErrorHint, topoloServiceOrigins, validateTopoloActionInput, validateTopoloWidgetResponse };
|
|
1655
|
+
export { ACTION_CATALOG_DIGEST_ALGORITHM, ACTOR_ENVELOPE_VERSION, type AccountableSubject, type AccountableSubjectType, type ActionContractManifest, type ActionContractSource, type ActorAssurance, type ActorChannel, type ActorDelegationHop, type ActorEnvelope, ActorEnvelopeValidationError, type ActorIdentity, type ActorPrincipalType, type AgentIdentity, type AppApiId, type ApplicationCatalogEntry, type ApplicationDeployTarget, type ApplicationDirectory, type ApplicationDirectoryApplication, type ApplicationDirectoryClient, type ApplicationDirectorySource, type ApplicationId, type CredentialIntrospection, type CrmContactSummary, CrmModule, DEFAULT_APP_URLS, type DeviceAuthorizationResponse, IdentityModule, type ListContactsOptions, type ListContactsResult, type OAuthHelperOptions, type P2PActionDetail, type P2PActionRequestInput, type P2PActionRequestResult, type P2PActionRow, type P2PActionRun, type P2PCapability, type P2PConnection, type P2PHold, type P2PLedgerEntry, P2PModule, type P2PPolicy, type P2PPricingModel, type P2PSettlementBatch, type P2PSettlementGroup, type PublishCapabilityInput, type RequestOptions, type ServiceCatalogUrlEntry, TOPOLO_ENVIRONMENT_SERVICE_URLS, TOPOLO_RUNTIME_ENVIRONMENTS, TOPOLO_WIDGET_CONTRACT_VERSION, TOPOLO_WIDGET_ENDPOINT, TOPOLO_WIDGET_OUTPUT_SCHEMA, TOPOLO_WIDGET_REFRESH_INTERVAL_MS, type TokenResponse, type Topolo, type TopoloActionAgentContract, type TopoloActionCatalogEntry, type TopoloActionCatalogSummary, type TopoloActionDigestInput, type TopoloActionPlan, type TopoloActionPreparation, type TopoloActionUploadOptions, type TopoloActionValidationIssue, type TopoloActionValidationResult, type TopoloActionsWidget, type TopoloActivityWidget, type TopoloAgentExecutionContext, type TopoloApiKeyResourceMetadata, TopoloAuthError, type TopoloBinaryResponse, type TopoloBindableResource, type TopoloBindableResourceCatalog, type TopoloChartWidget, TopoloClient, type TopoloClientOptions, TopoloConfirmationRequiredError, type TopoloCredential, type TopoloDebugEvent, TopoloHttpError, type TopoloInlineBase64UploadContract, type TopoloJsonSchema, type TopoloNotificationsWidget, TopoloOAuth, TopoloPermissionError, type TopoloRuntimeEnvironment, TopoloSdkError, type TopoloServiceCatalogEntry, type TopoloStatsWidget, type TopoloWidget, type TopoloWidgetAccessibility, type TopoloWidgetActionBinding, type TopoloWidgetActionRecovery, type TopoloWidgetActivityItem, type TopoloWidgetApiError, type TopoloWidgetApiErrorResponse, type TopoloWidgetApiResponse, type TopoloWidgetApiSuccessResponse, type TopoloWidgetBase, type TopoloWidgetConfig, type TopoloWidgetConfiguration, type TopoloWidgetConfigurationField, type TopoloWidgetConfigurationOption, type TopoloWidgetContext, type TopoloWidgetContribution, type TopoloWidgetDatasetDefinition, type TopoloWidgetDimension, type TopoloWidgetDimensionDefinition, type TopoloWidgetDraft, type TopoloWidgetDrilldown, type TopoloWidgetErrorResponseOptions, type TopoloWidgetEventDefinition, type TopoloWidgetLifecycleStage, type TopoloWidgetLocalization, type TopoloWidgetMetric, type TopoloWidgetMetricAggregation, type TopoloWidgetMetricComparison, type TopoloWidgetMetricDefinition, type TopoloWidgetMetricSemantic, type TopoloWidgetNotificationItem, type TopoloWidgetPeriod, type TopoloWidgetPresentation, type TopoloWidgetRefreshPolicy, type TopoloWidgetResourceBinding, type TopoloWidgetResponseOptions, type TopoloWidgetSeries, type TopoloWidgetSeriesDefinition, type TopoloWidgetSeriesPoint, type TopoloWidgetSize, type TopoloWidgetState, type TopoloWidgetStatus, type TopoloWidgetType, type TopoloWidgetValidationResult, type TopoloWidgetVisualizationFamily, type TopoloWidgetWorkspaceSelector, type TopoloWorkspace, type TopoloWorkspaceListResult, type TopoloWorkspaceMutationResult, type TopoloWorkspacePolicy, WorkspacesModule, actionContractCompleteness, applicationEntryFromCatalog, assertTopoloServiceUrlEnvironment, canonicalJson, canonicalTopoloErrorCode, canonicalTopoloRequestId, canonicalTopoloRequired, canonicalTopoloRetryAfter, canonicalizeActorEnvelope, compactActionCatalogEntry, compactActionPlan, compactActionPreparation, compactActionResult, compactActionValidation, createTopolo, createTopoloAgentExecutionContext, createTopoloWidgetError, createTopoloWidgetResponse, defineTopoloActionsWidget, defineTopoloActivityWidget, defineTopoloChartWidget, defineTopoloNotificationsWidget, defineTopoloStatsWidget, digestTopoloActionCatalog, encodeTopoloActionBase64, enrichActionContract, extractTopoloServiceErrorCode, extractTopoloServiceErrorDetails, formatDirectoryApplicationIds, friendlyAppId, isTopoloWidgetOutputSchema, listApplicationDirectory, parseActorEnvelope, parseTopoloActionUploadContract, preferExactActionMatches, prepareTopoloActionBase64UploadInput, prepareTopoloActionUploadInput, publicTopoloErrorMessage, resolveApplicationDirectoryEntry, resolveCatalogServiceUrl, resolveServiceUrl, sha256CanonicalValue, topoloErrorHint, topoloServiceOrigins, validateTopoloActionInput, validateTopoloWidgetResponse };
|
package/dist/index.js
CHANGED
|
@@ -164,10 +164,10 @@ var TopoloPermissionError = class extends TopoloSdkError {
|
|
|
164
164
|
};
|
|
165
165
|
function extractTopoloServiceErrorCode(body) {
|
|
166
166
|
if (!body || typeof body !== "object" || Array.isArray(body)) return null;
|
|
167
|
-
const
|
|
168
|
-
const topLevel = canonicalTopoloErrorCode(
|
|
167
|
+
const record2 = body;
|
|
168
|
+
const topLevel = canonicalTopoloErrorCode(record2.code);
|
|
169
169
|
if (topLevel) return topLevel;
|
|
170
|
-
const nested =
|
|
170
|
+
const nested = record2.error;
|
|
171
171
|
const nestedString = canonicalTopoloErrorCode(nested);
|
|
172
172
|
if (nestedString) return nestedString;
|
|
173
173
|
if (nested && typeof nested === "object" && !Array.isArray(nested)) {
|
|
@@ -182,14 +182,14 @@ function serviceErrorCode(body, fallback) {
|
|
|
182
182
|
}
|
|
183
183
|
function extractTopoloServiceErrorDetails(body) {
|
|
184
184
|
if (!body || typeof body !== "object" || Array.isArray(body)) return void 0;
|
|
185
|
-
const
|
|
186
|
-
let candidate =
|
|
187
|
-
const nested =
|
|
185
|
+
const record2 = body;
|
|
186
|
+
let candidate = record2.details;
|
|
187
|
+
const nested = record2.error;
|
|
188
188
|
if (nested && typeof nested === "object" && !Array.isArray(nested)) {
|
|
189
189
|
const nestedRecord = nested;
|
|
190
190
|
if (candidate === void 0) candidate = nestedRecord.details ?? nestedRecord;
|
|
191
191
|
}
|
|
192
|
-
if (candidate === void 0) candidate =
|
|
192
|
+
if (candidate === void 0) candidate = record2;
|
|
193
193
|
if (Array.isArray(candidate)) {
|
|
194
194
|
const paths = canonicalTopoloValidationPaths(candidate);
|
|
195
195
|
return paths.length ? { paths } : void 0;
|
|
@@ -241,8 +241,8 @@ function canonicalTopoloValidationPaths(issues) {
|
|
|
241
241
|
const paths = [];
|
|
242
242
|
for (const issue of issues) {
|
|
243
243
|
if (!issue || typeof issue !== "object" || Array.isArray(issue)) continue;
|
|
244
|
-
const
|
|
245
|
-
const path = canonicalTopoloValidationPath(
|
|
244
|
+
const record2 = issue;
|
|
245
|
+
const path = canonicalTopoloValidationPath(record2.field) ?? canonicalTopoloValidationPath(record2.path);
|
|
246
246
|
if (path && !paths.includes(path)) paths.push(path);
|
|
247
247
|
if (paths.length === 32) break;
|
|
248
248
|
}
|
|
@@ -1584,14 +1584,14 @@ var TopoloClient = class _TopoloClient {
|
|
|
1584
1584
|
if (!raw || typeof raw !== "object" || Array.isArray(raw)) {
|
|
1585
1585
|
throw new TopoloSdkError("action_catalog_summary_unavailable", "Action catalog summary is unavailable.");
|
|
1586
1586
|
}
|
|
1587
|
-
const
|
|
1588
|
-
if (
|
|
1587
|
+
const record2 = raw;
|
|
1588
|
+
if (record2.algorithm !== "sha256-v1" || typeof record2.digest !== "string" || !/^[a-f0-9]{64}$/.test(record2.digest) || !Number.isSafeInteger(record2.actionCount) || Number(record2.actionCount) < 0) {
|
|
1589
1589
|
throw new TopoloSdkError("action_catalog_summary_unavailable", "Action catalog summary is invalid.");
|
|
1590
1590
|
}
|
|
1591
1591
|
return {
|
|
1592
1592
|
algorithm: "sha256-v1",
|
|
1593
|
-
digest:
|
|
1594
|
-
actionCount: Number(
|
|
1593
|
+
digest: record2.digest,
|
|
1594
|
+
actionCount: Number(record2.actionCount)
|
|
1595
1595
|
};
|
|
1596
1596
|
}
|
|
1597
1597
|
/** @deprecated Prefer searchActions() so callers retain the continuation cursor. */
|
|
@@ -1964,12 +1964,21 @@ function redactActionResult(value) {
|
|
|
1964
1964
|
if (!isRecord3(value)) return value;
|
|
1965
1965
|
return Object.fromEntries(Object.entries(value).map(([key, item]) => [
|
|
1966
1966
|
key,
|
|
1967
|
-
isSensitiveActionResultKey(key) ? "[REDACTED]" : redactActionResult(item)
|
|
1967
|
+
isSensitiveActionResultKey(key, item) ? "[REDACTED]" : redactActionResult(item)
|
|
1968
1968
|
]));
|
|
1969
1969
|
}
|
|
1970
|
-
function isSensitiveActionResultKey(key) {
|
|
1970
|
+
function isSensitiveActionResultKey(key, value) {
|
|
1971
1971
|
const normalized = key.toLowerCase().replace(/[^a-z0-9]/g, "");
|
|
1972
|
-
|
|
1972
|
+
if (normalized === "capability") return isCredentialShaped(value);
|
|
1973
|
+
return ["authorization", "cookie", "setcookie", "proxyauthorization"].includes(normalized) || /(token|secret|password|privatekey|apikey)$/.test(normalized);
|
|
1974
|
+
}
|
|
1975
|
+
var PLAIN_ENUM_VALUE = /^[a-z][a-z0-9_-]{0,31}$/;
|
|
1976
|
+
function isCredentialShaped(value) {
|
|
1977
|
+
if (typeof value !== "string") return value !== null && value !== void 0 && typeof value !== "boolean" && typeof value !== "number";
|
|
1978
|
+
const trimmed = value.trim();
|
|
1979
|
+
if (!trimmed) return false;
|
|
1980
|
+
if (/^[a-z][a-z0-9+.-]*:\/\//i.test(trimmed)) return true;
|
|
1981
|
+
return !PLAIN_ENUM_VALUE.test(trimmed);
|
|
1973
1982
|
}
|
|
1974
1983
|
function resolveConfiguredServiceUrl(slug, serviceUrls) {
|
|
1975
1984
|
for (const serviceKey of serviceKeyCandidates2(slug)) {
|
|
@@ -2215,10 +2224,10 @@ function extractRequired(body) {
|
|
|
2215
2224
|
if (Array.isArray(maybe.required)) return canonicalTopoloRequired(maybe.required);
|
|
2216
2225
|
for (const nested of [maybe.details, maybe.error]) {
|
|
2217
2226
|
if (!nested || typeof nested !== "object" || Array.isArray(nested)) continue;
|
|
2218
|
-
const
|
|
2219
|
-
if (Array.isArray(
|
|
2220
|
-
if (
|
|
2221
|
-
const required =
|
|
2227
|
+
const record2 = nested;
|
|
2228
|
+
if (Array.isArray(record2.required)) return canonicalTopoloRequired(record2.required);
|
|
2229
|
+
if (record2.details && typeof record2.details === "object" && !Array.isArray(record2.details)) {
|
|
2230
|
+
const required = record2.details.required;
|
|
2222
2231
|
if (Array.isArray(required)) return canonicalTopoloRequired(required);
|
|
2223
2232
|
}
|
|
2224
2233
|
}
|
|
@@ -2295,8 +2304,8 @@ function compactResultValue(value, depth, budget) {
|
|
|
2295
2304
|
return value.length > ACTION_RESULT_MAX_ITEMS ? { count: value.length, items, omittedItems: value.length - ACTION_RESULT_MAX_ITEMS } : items;
|
|
2296
2305
|
}
|
|
2297
2306
|
if (typeof value === "object") {
|
|
2298
|
-
const
|
|
2299
|
-
const allKeys = Object.keys(
|
|
2307
|
+
const record2 = value;
|
|
2308
|
+
const allKeys = Object.keys(record2);
|
|
2300
2309
|
const ranked = allKeys.sort((left, right) => resultKeyPriority(left) - resultKeyPriority(right));
|
|
2301
2310
|
const prioritized = ranked.filter((key) => resultKeyPriority(key) < 2);
|
|
2302
2311
|
const ordinary = ranked.filter((key) => resultKeyPriority(key) === 2);
|
|
@@ -2305,7 +2314,7 @@ function compactResultValue(value, depth, budget) {
|
|
|
2305
2314
|
...prioritized,
|
|
2306
2315
|
...ordinary.slice(0, ordinaryLimit)
|
|
2307
2316
|
].slice(0, ACTION_RESULT_MAX_KEYS);
|
|
2308
|
-
const compact = Object.fromEntries(keys.map((key) => [key, compactResultValue(
|
|
2317
|
+
const compact = Object.fromEntries(keys.map((key) => [key, compactResultValue(record2[key], depth + 1, budget)]));
|
|
2309
2318
|
if (allKeys.length > keys.length) compact["_omittedKeys"] = allKeys.length - keys.length;
|
|
2310
2319
|
return compact;
|
|
2311
2320
|
}
|
|
@@ -2421,8 +2430,8 @@ function canonicalPermission(value, appId) {
|
|
|
2421
2430
|
function stableJson(value) {
|
|
2422
2431
|
if (Array.isArray(value)) return `[${value.map(stableJson).join(",")}]`;
|
|
2423
2432
|
if (value && typeof value === "object") {
|
|
2424
|
-
const
|
|
2425
|
-
return `{${Object.keys(
|
|
2433
|
+
const record2 = value;
|
|
2434
|
+
return `{${Object.keys(record2).sort().map((key) => `${JSON.stringify(key)}:${stableJson(record2[key])}`).join(",")}}`;
|
|
2426
2435
|
}
|
|
2427
2436
|
return JSON.stringify(value);
|
|
2428
2437
|
}
|
|
@@ -2563,8 +2572,8 @@ function resourceSchema(resource) {
|
|
|
2563
2572
|
function derivedOutputSchema(action) {
|
|
2564
2573
|
const resource = resourceFor(action);
|
|
2565
2574
|
const operation = operationFor(action);
|
|
2566
|
-
const
|
|
2567
|
-
const records = { type: "array", items:
|
|
2575
|
+
const record2 = resourceSchema(resource);
|
|
2576
|
+
const records = { type: "array", items: record2 };
|
|
2568
2577
|
const provenance = {
|
|
2569
2578
|
"x-topolo-contract-source": "derived-action-metadata",
|
|
2570
2579
|
"x-topolo-contract-precision": "structural"
|
|
@@ -2596,12 +2605,12 @@ function derivedOutputSchema(action) {
|
|
|
2596
2605
|
title: `${action.title || action.name} response`,
|
|
2597
2606
|
description: `Resource response returned by ${action.name}. The service may return the resource directly or in an envelope.`,
|
|
2598
2607
|
oneOf: [
|
|
2599
|
-
|
|
2608
|
+
record2,
|
|
2600
2609
|
{
|
|
2601
2610
|
type: "object",
|
|
2602
2611
|
properties: {
|
|
2603
|
-
data:
|
|
2604
|
-
[resource]:
|
|
2612
|
+
data: record2,
|
|
2613
|
+
[resource]: record2
|
|
2605
2614
|
},
|
|
2606
2615
|
additionalProperties: true
|
|
2607
2616
|
}
|
|
@@ -2616,7 +2625,7 @@ function derivedOutputSchema(action) {
|
|
|
2616
2625
|
properties: {
|
|
2617
2626
|
success: { type: "boolean" },
|
|
2618
2627
|
id: { type: "string" },
|
|
2619
|
-
data: { oneOf: [
|
|
2628
|
+
data: { oneOf: [record2, { type: "object", additionalProperties: true }] },
|
|
2620
2629
|
result: { type: "object", additionalProperties: true },
|
|
2621
2630
|
message: { type: "string" }
|
|
2622
2631
|
},
|
|
@@ -2915,6 +2924,218 @@ var IdentityModule = class {
|
|
|
2915
2924
|
}
|
|
2916
2925
|
};
|
|
2917
2926
|
|
|
2927
|
+
// src/actor-envelope.ts
|
|
2928
|
+
var ACTOR_ENVELOPE_VERSION = 1;
|
|
2929
|
+
var PRINCIPAL_TYPES = /* @__PURE__ */ new Set([
|
|
2930
|
+
"human",
|
|
2931
|
+
"managed_agent",
|
|
2932
|
+
"external_agent",
|
|
2933
|
+
"service",
|
|
2934
|
+
"browser_automation"
|
|
2935
|
+
]);
|
|
2936
|
+
var ACCOUNTABLE_SUBJECT_TYPES = /* @__PURE__ */ new Set(["human", "organization"]);
|
|
2937
|
+
var CHANNELS = /* @__PURE__ */ new Set(["web", "mobile", "cli", "mcp", "api", "workflow", "browser_automation"]);
|
|
2938
|
+
var ASSURANCE_LEVELS = /* @__PURE__ */ new Set(["authenticated", "workload_identity", "user_verified"]);
|
|
2939
|
+
var HASH_PATTERN = /^sha256:[a-f0-9]{64}$/;
|
|
2940
|
+
var ActorEnvelopeValidationError = class extends Error {
|
|
2941
|
+
path;
|
|
2942
|
+
constructor(path, message) {
|
|
2943
|
+
super(`${path}: ${message}`);
|
|
2944
|
+
this.name = "ActorEnvelopeValidationError";
|
|
2945
|
+
this.path = path;
|
|
2946
|
+
}
|
|
2947
|
+
};
|
|
2948
|
+
function parseActorEnvelope(value) {
|
|
2949
|
+
const envelope = record(value, "actorEnvelope");
|
|
2950
|
+
exactKeys(envelope, [
|
|
2951
|
+
"schemaVersion",
|
|
2952
|
+
"organizationId",
|
|
2953
|
+
"accountableSubject",
|
|
2954
|
+
"performer",
|
|
2955
|
+
"delegation",
|
|
2956
|
+
"channel",
|
|
2957
|
+
"assurance",
|
|
2958
|
+
"action",
|
|
2959
|
+
"issuedAt",
|
|
2960
|
+
"expiresAt"
|
|
2961
|
+
], "actorEnvelope");
|
|
2962
|
+
if (envelope.schemaVersion !== ACTOR_ENVELOPE_VERSION) {
|
|
2963
|
+
fail("actorEnvelope.schemaVersion", `must equal ${ACTOR_ENVELOPE_VERSION}`);
|
|
2964
|
+
}
|
|
2965
|
+
const accountableSubject = parseAccountableSubject(envelope.accountableSubject);
|
|
2966
|
+
const performer = parseIdentity(envelope.performer, "actorEnvelope.performer");
|
|
2967
|
+
const organizationId = text(envelope.organizationId, "actorEnvelope.organizationId");
|
|
2968
|
+
const channel = member(envelope.channel, CHANNELS, "actorEnvelope.channel");
|
|
2969
|
+
const issuedAt = timestamp(envelope.issuedAt, "actorEnvelope.issuedAt");
|
|
2970
|
+
const expiresAt = envelope.expiresAt === void 0 ? void 0 : timestamp(envelope.expiresAt, "actorEnvelope.expiresAt");
|
|
2971
|
+
if (expiresAt && Date.parse(expiresAt) <= Date.parse(issuedAt)) {
|
|
2972
|
+
fail("actorEnvelope.expiresAt", "must be later than issuedAt");
|
|
2973
|
+
}
|
|
2974
|
+
const assuranceValue = record(envelope.assurance, "actorEnvelope.assurance");
|
|
2975
|
+
exactKeys(assuranceValue, ["level", "methods"], "actorEnvelope.assurance");
|
|
2976
|
+
const assurance = {
|
|
2977
|
+
level: member(assuranceValue.level, ASSURANCE_LEVELS, "actorEnvelope.assurance.level"),
|
|
2978
|
+
methods: textArray(assuranceValue.methods, "actorEnvelope.assurance.methods")
|
|
2979
|
+
};
|
|
2980
|
+
const actionValue = record(envelope.action, "actorEnvelope.action");
|
|
2981
|
+
exactKeys(actionValue, ["requestId", "actionId", "resourceType", "resourceId", "inputHash"], "actorEnvelope.action");
|
|
2982
|
+
const inputHash = text(actionValue.inputHash, "actorEnvelope.action.inputHash");
|
|
2983
|
+
if (!HASH_PATTERN.test(inputHash)) fail("actorEnvelope.action.inputHash", "must be a lowercase sha256 digest");
|
|
2984
|
+
const action = {
|
|
2985
|
+
requestId: text(actionValue.requestId, "actorEnvelope.action.requestId"),
|
|
2986
|
+
actionId: text(actionValue.actionId, "actorEnvelope.action.actionId"),
|
|
2987
|
+
...actionValue.resourceType === void 0 ? {} : { resourceType: text(actionValue.resourceType, "actorEnvelope.action.resourceType") },
|
|
2988
|
+
...actionValue.resourceId === void 0 ? {} : { resourceId: text(actionValue.resourceId, "actorEnvelope.action.resourceId") },
|
|
2989
|
+
inputHash
|
|
2990
|
+
};
|
|
2991
|
+
if (action.resourceType === void 0 !== (action.resourceId === void 0)) {
|
|
2992
|
+
fail("actorEnvelope.action", "resourceType and resourceId must be provided together");
|
|
2993
|
+
}
|
|
2994
|
+
const delegation = parseDelegation(envelope.delegation);
|
|
2995
|
+
const directHuman = performer.principalType === "human" && performer.principalId === accountableSubject.principalId;
|
|
2996
|
+
if (directHuman && delegation !== null) fail("actorEnvelope.delegation", "must be null for direct human action");
|
|
2997
|
+
if (!directHuman && delegation === null) fail("actorEnvelope.delegation", "is required when performer differs from accountable subject");
|
|
2998
|
+
if (delegation) {
|
|
2999
|
+
const finalHop = delegation.lineage.at(-1);
|
|
3000
|
+
if (!finalHop || finalHop.principalId !== performer.principalId || finalHop.principalType !== performer.principalType) {
|
|
3001
|
+
fail("actorEnvelope.delegation.lineage", "must end with the performer");
|
|
3002
|
+
}
|
|
3003
|
+
}
|
|
3004
|
+
if (performer.principalType === "external_agent" && (!performer.installationId || !performer.provider)) {
|
|
3005
|
+
fail("actorEnvelope.performer", "external_agent requires installationId and provider");
|
|
3006
|
+
}
|
|
3007
|
+
if (performer.principalType === "managed_agent" && !performer.agentInstanceId) {
|
|
3008
|
+
fail("actorEnvelope.performer.agentInstanceId", "is required for managed_agent");
|
|
3009
|
+
}
|
|
3010
|
+
if (performer.principalType === "browser_automation" && (!performer.installationId || !performer.browserSessionId)) {
|
|
3011
|
+
fail("actorEnvelope.performer", "browser_automation requires installationId and browserSessionId");
|
|
3012
|
+
}
|
|
3013
|
+
return {
|
|
3014
|
+
schemaVersion: ACTOR_ENVELOPE_VERSION,
|
|
3015
|
+
organizationId,
|
|
3016
|
+
accountableSubject,
|
|
3017
|
+
performer,
|
|
3018
|
+
delegation,
|
|
3019
|
+
channel,
|
|
3020
|
+
assurance,
|
|
3021
|
+
action,
|
|
3022
|
+
issuedAt,
|
|
3023
|
+
...expiresAt ? { expiresAt } : {}
|
|
3024
|
+
};
|
|
3025
|
+
}
|
|
3026
|
+
function canonicalizeActorEnvelope(value) {
|
|
3027
|
+
return canonicalJson(parseActorEnvelope(value));
|
|
3028
|
+
}
|
|
3029
|
+
function canonicalJson(value) {
|
|
3030
|
+
if (value === null) return "null";
|
|
3031
|
+
if (typeof value === "string" || typeof value === "boolean") return JSON.stringify(value);
|
|
3032
|
+
if (typeof value === "number") {
|
|
3033
|
+
if (!Number.isFinite(value)) throw new TypeError("Canonical JSON accepts finite numbers only.");
|
|
3034
|
+
return JSON.stringify(value);
|
|
3035
|
+
}
|
|
3036
|
+
if (Array.isArray(value)) return `[${value.map(canonicalJson).join(",")}]`;
|
|
3037
|
+
if (typeof value !== "object" || !value || ![Object.prototype, null].includes(Object.getPrototypeOf(value))) {
|
|
3038
|
+
throw new TypeError("Canonical JSON accepts JSON objects, arrays, and primitives only.");
|
|
3039
|
+
}
|
|
3040
|
+
const entries = Object.entries(value).filter(([, item]) => item !== void 0).sort(([left], [right]) => left.localeCompare(right));
|
|
3041
|
+
return `{${entries.map(([key, item]) => `${JSON.stringify(key)}:${canonicalJson(item)}`).join(",")}}`;
|
|
3042
|
+
}
|
|
3043
|
+
function parseAccountableSubject(value) {
|
|
3044
|
+
const path = "actorEnvelope.accountableSubject";
|
|
3045
|
+
const subject = record(value, path);
|
|
3046
|
+
exactKeys(subject, ["principalType", "principalId", "displayName"], path);
|
|
3047
|
+
return {
|
|
3048
|
+
principalType: member(subject.principalType, ACCOUNTABLE_SUBJECT_TYPES, `${path}.principalType`),
|
|
3049
|
+
principalId: text(subject.principalId, `${path}.principalId`),
|
|
3050
|
+
...subject.displayName === void 0 ? {} : { displayName: text(subject.displayName, `${path}.displayName`) }
|
|
3051
|
+
};
|
|
3052
|
+
}
|
|
3053
|
+
async function sha256CanonicalValue(value) {
|
|
3054
|
+
const bytes = new TextEncoder().encode(canonicalJson(value));
|
|
3055
|
+
const digest = await crypto.subtle.digest("SHA-256", bytes);
|
|
3056
|
+
return `sha256:${Array.from(new Uint8Array(digest), (byte) => byte.toString(16).padStart(2, "0")).join("")}`;
|
|
3057
|
+
}
|
|
3058
|
+
function parseIdentity(value, path) {
|
|
3059
|
+
const identity = record(value, path);
|
|
3060
|
+
exactKeys(identity, [
|
|
3061
|
+
"principalType",
|
|
3062
|
+
"principalId",
|
|
3063
|
+
"displayName",
|
|
3064
|
+
"installationId",
|
|
3065
|
+
"agentInstanceId",
|
|
3066
|
+
"browserSessionId",
|
|
3067
|
+
"provider",
|
|
3068
|
+
"model"
|
|
3069
|
+
], path);
|
|
3070
|
+
return {
|
|
3071
|
+
principalType: member(identity.principalType, PRINCIPAL_TYPES, `${path}.principalType`),
|
|
3072
|
+
principalId: text(identity.principalId, `${path}.principalId`),
|
|
3073
|
+
...optionalTextFields(identity, path, [
|
|
3074
|
+
"displayName",
|
|
3075
|
+
"installationId",
|
|
3076
|
+
"agentInstanceId",
|
|
3077
|
+
"browserSessionId",
|
|
3078
|
+
"provider",
|
|
3079
|
+
"model"
|
|
3080
|
+
])
|
|
3081
|
+
};
|
|
3082
|
+
}
|
|
3083
|
+
function parseDelegation(value) {
|
|
3084
|
+
if (value === null) return null;
|
|
3085
|
+
const delegation = record(value, "actorEnvelope.delegation");
|
|
3086
|
+
exactKeys(delegation, ["taskId", "runId", "lineage"], "actorEnvelope.delegation");
|
|
3087
|
+
if (!Array.isArray(delegation.lineage) || delegation.lineage.length === 0 || delegation.lineage.length > 16) {
|
|
3088
|
+
fail("actorEnvelope.delegation.lineage", "must contain between 1 and 16 hops");
|
|
3089
|
+
}
|
|
3090
|
+
return {
|
|
3091
|
+
taskId: text(delegation.taskId, "actorEnvelope.delegation.taskId"),
|
|
3092
|
+
runId: text(delegation.runId, "actorEnvelope.delegation.runId"),
|
|
3093
|
+
lineage: delegation.lineage.map((value2, index) => {
|
|
3094
|
+
const hop = record(value2, `actorEnvelope.delegation.lineage[${index}]`);
|
|
3095
|
+
exactKeys(hop, ["principalType", "principalId"], `actorEnvelope.delegation.lineage[${index}]`);
|
|
3096
|
+
return {
|
|
3097
|
+
principalType: member(hop.principalType, PRINCIPAL_TYPES, `actorEnvelope.delegation.lineage[${index}].principalType`),
|
|
3098
|
+
principalId: text(hop.principalId, `actorEnvelope.delegation.lineage[${index}].principalId`)
|
|
3099
|
+
};
|
|
3100
|
+
})
|
|
3101
|
+
};
|
|
3102
|
+
}
|
|
3103
|
+
function record(value, path) {
|
|
3104
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) fail(path, "must be an object");
|
|
3105
|
+
return value;
|
|
3106
|
+
}
|
|
3107
|
+
function exactKeys(value, allowed, path) {
|
|
3108
|
+
const unknown = Object.keys(value).filter((key) => !allowed.includes(key));
|
|
3109
|
+
if (unknown.length) fail(path, `contains unknown field ${unknown[0]}`);
|
|
3110
|
+
}
|
|
3111
|
+
function text(value, path) {
|
|
3112
|
+
if (typeof value !== "string" || value.trim() !== value || value.length === 0 || value.length > 256) {
|
|
3113
|
+
fail(path, "must be a non-empty trimmed string of at most 256 characters");
|
|
3114
|
+
}
|
|
3115
|
+
return value;
|
|
3116
|
+
}
|
|
3117
|
+
function timestamp(value, path) {
|
|
3118
|
+
const result = text(value, path);
|
|
3119
|
+
if (!/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d{3})?Z$/.test(result) || Number.isNaN(Date.parse(result))) {
|
|
3120
|
+
fail(path, "must be an RFC 3339 UTC timestamp");
|
|
3121
|
+
}
|
|
3122
|
+
return result;
|
|
3123
|
+
}
|
|
3124
|
+
function member(value, values, path) {
|
|
3125
|
+
if (typeof value !== "string" || !values.has(value)) fail(path, "contains an unsupported value");
|
|
3126
|
+
return value;
|
|
3127
|
+
}
|
|
3128
|
+
function textArray(value, path) {
|
|
3129
|
+
if (!Array.isArray(value) || value.length === 0 || value.length > 16) fail(path, "must contain between 1 and 16 values");
|
|
3130
|
+
return value.map((item, index) => text(item, `${path}[${index}]`));
|
|
3131
|
+
}
|
|
3132
|
+
function optionalTextFields(value, path, keys) {
|
|
3133
|
+
return Object.fromEntries(keys.flatMap((key) => value[key] === void 0 ? [] : [[key, text(value[key], `${path}.${key}`)]]));
|
|
3134
|
+
}
|
|
3135
|
+
function fail(path, message) {
|
|
3136
|
+
throw new ActorEnvelopeValidationError(path, message);
|
|
3137
|
+
}
|
|
3138
|
+
|
|
2918
3139
|
// src/modules/workspaces.ts
|
|
2919
3140
|
var ACTIONS = {
|
|
2920
3141
|
list: "app_topolo_auth.workspaces.list",
|
|
@@ -4405,6 +4626,8 @@ function createTopolo(options) {
|
|
|
4405
4626
|
}
|
|
4406
4627
|
export {
|
|
4407
4628
|
ACTION_CATALOG_DIGEST_ALGORITHM,
|
|
4629
|
+
ACTOR_ENVELOPE_VERSION,
|
|
4630
|
+
ActorEnvelopeValidationError,
|
|
4408
4631
|
CrmModule,
|
|
4409
4632
|
DEFAULT_APP_URLS,
|
|
4410
4633
|
IdentityModule,
|
|
@@ -4426,10 +4649,12 @@ export {
|
|
|
4426
4649
|
actionContractCompleteness,
|
|
4427
4650
|
applicationEntryFromCatalog,
|
|
4428
4651
|
assertTopoloServiceUrlEnvironment,
|
|
4652
|
+
canonicalJson,
|
|
4429
4653
|
canonicalTopoloErrorCode,
|
|
4430
4654
|
canonicalTopoloRequestId,
|
|
4431
4655
|
canonicalTopoloRequired,
|
|
4432
4656
|
canonicalTopoloRetryAfter,
|
|
4657
|
+
canonicalizeActorEnvelope,
|
|
4433
4658
|
compactActionCatalogEntry,
|
|
4434
4659
|
compactActionPlan,
|
|
4435
4660
|
compactActionPreparation,
|
|
@@ -4453,6 +4678,7 @@ export {
|
|
|
4453
4678
|
friendlyAppId,
|
|
4454
4679
|
isTopoloWidgetOutputSchema,
|
|
4455
4680
|
listApplicationDirectory,
|
|
4681
|
+
parseActorEnvelope,
|
|
4456
4682
|
parseTopoloActionUploadContract,
|
|
4457
4683
|
preferExactActionMatches,
|
|
4458
4684
|
prepareTopoloActionBase64UploadInput,
|
|
@@ -4461,6 +4687,7 @@ export {
|
|
|
4461
4687
|
resolveApplicationDirectoryEntry,
|
|
4462
4688
|
resolveCatalogServiceUrl,
|
|
4463
4689
|
resolveServiceUrl,
|
|
4690
|
+
sha256CanonicalValue,
|
|
4464
4691
|
topoloErrorHint,
|
|
4465
4692
|
topoloServiceOrigins,
|
|
4466
4693
|
validateTopoloActionInput,
|
package/package.json
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@topolo/sdk",
|
|
3
|
-
"
|
|
4
|
-
"
|
|
3
|
+
"packageManager": "pnpm@10.17.1",
|
|
4
|
+
"version": "0.15.0",
|
|
5
|
+
"topoloPublishedVersion": "0.15.0",
|
|
5
6
|
"description": "Typed client SDK for the Topolo platform. Used by TopoloCli, TopoloMCP, and third-party agents.",
|
|
6
7
|
"license": "UNLICENSED",
|
|
7
8
|
"author": "Topolo",
|
|
@@ -32,7 +33,7 @@
|
|
|
32
33
|
"test": "vitest run",
|
|
33
34
|
"test:watch": "vitest",
|
|
34
35
|
"prepublishOnly": "npm run build && npm run verify:package",
|
|
35
|
-
"verify:package": "
|
|
36
|
+
"verify:package": "npm pack --dry-run",
|
|
36
37
|
"coverage": "vitest run --coverage"
|
|
37
38
|
},
|
|
38
39
|
"topolo_quality": {
|
|
@@ -50,7 +51,7 @@
|
|
|
50
51
|
"tsconfig.json",
|
|
51
52
|
"vitest.config.ts"
|
|
52
53
|
],
|
|
53
|
-
"digest": "
|
|
54
|
+
"digest": "764b584c653234937a1ba11f34a898941c62ebd8bf973db6ed0869b7f4a11951"
|
|
54
55
|
}
|
|
55
56
|
}
|
|
56
57
|
]
|
|
@@ -64,5 +65,9 @@
|
|
|
64
65
|
},
|
|
65
66
|
"engines": {
|
|
66
67
|
"node": ">=20"
|
|
68
|
+
},
|
|
69
|
+
"repository": {
|
|
70
|
+
"type": "git",
|
|
71
|
+
"url": "git+https://github.com/Topolo-io/topolo-sdk.git"
|
|
67
72
|
}
|
|
68
73
|
}
|