@topolo/sdk 0.3.0 → 0.4.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 +1 -1
- package/dist/index.cjs +149 -78
- package/dist/index.d.cts +81 -56
- package/dist/index.d.ts +81 -56
- package/dist/index.js +149 -77
- package/package.json +5 -2
- package/src/application-requirements.ts +10 -6
- package/src/applications.generated.ts +61 -40
- package/src/client.test.ts +108 -19
- package/src/client.ts +126 -8
- package/src/index.ts +1 -1
- package/src/modules/p2p.test.ts +27 -11
- package/src/services.generated.ts +2 -32
- package/src/services.test.ts +6 -23
- package/src/services.ts +1 -2
- package/src/widgets.test.ts +7 -7
package/dist/index.d.ts
CHANGED
|
@@ -65,12 +65,14 @@ declare const SERVICES: {
|
|
|
65
65
|
readonly p2p: "https://p2p.topolo.app";
|
|
66
66
|
readonly pay: "https://pay.topolo.app";
|
|
67
67
|
readonly people: "https://people.topolo.app";
|
|
68
|
+
readonly pulse: "https://pulse.topolo.app";
|
|
68
69
|
readonly "quro.api": "https://api.ol0.me";
|
|
69
70
|
readonly "quro.redirect": "https://ol0.me";
|
|
70
71
|
readonly roadmapper: "https://roadmapper-api.topolo.app";
|
|
71
72
|
readonly sign: "https://sign.topolo.app";
|
|
72
73
|
readonly social_studio: "https://studio-api.topolo.app";
|
|
73
74
|
readonly socialize: "https://socialize-api.topolo.app";
|
|
75
|
+
readonly spaces: "https://spaces.topolo.app";
|
|
74
76
|
readonly status: "https://status.topolo.app";
|
|
75
77
|
readonly support: "https://support.topolo.app";
|
|
76
78
|
readonly survey: "https://survey.topolo.app";
|
|
@@ -78,15 +80,6 @@ declare const SERVICES: {
|
|
|
78
80
|
readonly web: "https://web-api.topolo.app";
|
|
79
81
|
};
|
|
80
82
|
type ServiceId = keyof typeof SERVICES;
|
|
81
|
-
/**
|
|
82
|
-
* @deprecated since 0.3.0 — opaque service ids are no longer baked into the
|
|
83
|
-
* SDK. Use `TopoloClient.getServiceIdBySlug(slug)` which hits
|
|
84
|
-
* `GET /api/services/by-slug/:slug` on TopoloAuth at runtime. This map is
|
|
85
|
-
* still populated as a build-time snapshot for backward compatibility and
|
|
86
|
-
* will be removed in 0.4.0. Stale entries are expected — do not rely on
|
|
87
|
-
* presence/absence for catalog membership.
|
|
88
|
-
*/
|
|
89
|
-
declare const PLATFORM_SERVICE_IDS: Partial<Record<ServiceId, string>>;
|
|
90
83
|
|
|
91
84
|
declare const APPLICATIONS: {
|
|
92
85
|
readonly admin: {
|
|
@@ -144,6 +137,22 @@ declare const APPLICATIONS: {
|
|
|
144
137
|
readonly serviceId: "auth";
|
|
145
138
|
}];
|
|
146
139
|
};
|
|
140
|
+
readonly backup: {
|
|
141
|
+
readonly id: "backup";
|
|
142
|
+
readonly appDir: "TopoloBackup";
|
|
143
|
+
readonly name: "topolo-backup";
|
|
144
|
+
readonly packageName: "topolo-backup";
|
|
145
|
+
readonly productionUrl: null;
|
|
146
|
+
readonly services: readonly [];
|
|
147
|
+
readonly deployTargets: readonly [{
|
|
148
|
+
readonly name: "topolo-backup";
|
|
149
|
+
readonly kind: "worker";
|
|
150
|
+
readonly apiUrl: null;
|
|
151
|
+
readonly domains: readonly [];
|
|
152
|
+
readonly routes: readonly [];
|
|
153
|
+
readonly serviceId: null;
|
|
154
|
+
}];
|
|
155
|
+
};
|
|
147
156
|
readonly books: {
|
|
148
157
|
readonly id: "books";
|
|
149
158
|
readonly appDir: "TopoloBooks";
|
|
@@ -247,15 +256,6 @@ declare const APPLICATIONS: {
|
|
|
247
256
|
readonly serviceId: "chat";
|
|
248
257
|
}];
|
|
249
258
|
};
|
|
250
|
-
readonly cli: {
|
|
251
|
-
readonly id: "cli";
|
|
252
|
-
readonly appDir: "TopoloCli";
|
|
253
|
-
readonly name: "@topolo/cli";
|
|
254
|
-
readonly packageName: "@topolo/cli";
|
|
255
|
-
readonly productionUrl: null;
|
|
256
|
-
readonly services: readonly [];
|
|
257
|
-
readonly deployTargets: readonly [];
|
|
258
|
-
};
|
|
259
259
|
readonly cloudcontrol: {
|
|
260
260
|
readonly id: "cloudcontrol";
|
|
261
261
|
readonly appDir: "TopoloCloudControl";
|
|
@@ -373,22 +373,6 @@ declare const APPLICATIONS: {
|
|
|
373
373
|
readonly serviceId: "customer_success";
|
|
374
374
|
}];
|
|
375
375
|
};
|
|
376
|
-
readonly d1_backup: {
|
|
377
|
-
readonly id: "d1_backup";
|
|
378
|
-
readonly appDir: "TopoloD1Backup";
|
|
379
|
-
readonly name: "topolo-d1-backup";
|
|
380
|
-
readonly packageName: "topolo-d1-backup";
|
|
381
|
-
readonly productionUrl: null;
|
|
382
|
-
readonly services: readonly [];
|
|
383
|
-
readonly deployTargets: readonly [{
|
|
384
|
-
readonly name: "topolo-d1-backup";
|
|
385
|
-
readonly kind: "worker";
|
|
386
|
-
readonly apiUrl: null;
|
|
387
|
-
readonly domains: readonly [];
|
|
388
|
-
readonly routes: readonly [];
|
|
389
|
-
readonly serviceId: null;
|
|
390
|
-
}];
|
|
391
|
-
};
|
|
392
376
|
readonly developers: {
|
|
393
377
|
readonly id: "developers";
|
|
394
378
|
readonly appDir: "TopoloDevelopers";
|
|
@@ -625,15 +609,6 @@ declare const APPLICATIONS: {
|
|
|
625
609
|
readonly serviceId: "mail";
|
|
626
610
|
}];
|
|
627
611
|
};
|
|
628
|
-
readonly mcp: {
|
|
629
|
-
readonly id: "mcp";
|
|
630
|
-
readonly appDir: "TopoloMCP";
|
|
631
|
-
readonly name: "@topolo/mcp";
|
|
632
|
-
readonly packageName: "@topolo/mcp";
|
|
633
|
-
readonly productionUrl: null;
|
|
634
|
-
readonly services: readonly [];
|
|
635
|
-
readonly deployTargets: readonly [];
|
|
636
|
-
};
|
|
637
612
|
readonly mdm: {
|
|
638
613
|
readonly id: "mdm";
|
|
639
614
|
readonly appDir: "TopoloMDM";
|
|
@@ -731,7 +706,7 @@ declare const APPLICATIONS: {
|
|
|
731
706
|
readonly one: {
|
|
732
707
|
readonly id: "one";
|
|
733
708
|
readonly appDir: "TopoloOne";
|
|
734
|
-
readonly name: "
|
|
709
|
+
readonly name: "TopoloOne";
|
|
735
710
|
readonly packageName: "topolo-oneclick-sso";
|
|
736
711
|
readonly productionUrl: "https://one.topolo.app";
|
|
737
712
|
readonly services: readonly ["one"];
|
|
@@ -811,9 +786,16 @@ declare const APPLICATIONS: {
|
|
|
811
786
|
readonly appDir: "TopoloPulse";
|
|
812
787
|
readonly name: "topolo-pulse";
|
|
813
788
|
readonly packageName: "topolo-pulse";
|
|
814
|
-
readonly productionUrl:
|
|
815
|
-
readonly services: readonly [];
|
|
816
|
-
readonly deployTargets: readonly [
|
|
789
|
+
readonly productionUrl: "https://pulse.topolo.app";
|
|
790
|
+
readonly services: readonly ["pulse"];
|
|
791
|
+
readonly deployTargets: readonly [{
|
|
792
|
+
readonly name: "topolo-pulse";
|
|
793
|
+
readonly kind: "worker";
|
|
794
|
+
readonly apiUrl: "https://pulse.topolo.app";
|
|
795
|
+
readonly domains: readonly ["pulse.topolo.app"];
|
|
796
|
+
readonly routes: readonly ["pulse.topolo.app"];
|
|
797
|
+
readonly serviceId: "pulse";
|
|
798
|
+
}];
|
|
817
799
|
};
|
|
818
800
|
readonly quro: {
|
|
819
801
|
readonly id: "quro";
|
|
@@ -944,6 +926,22 @@ declare const APPLICATIONS: {
|
|
|
944
926
|
readonly serviceId: null;
|
|
945
927
|
}];
|
|
946
928
|
};
|
|
929
|
+
readonly spaces: {
|
|
930
|
+
readonly id: "spaces";
|
|
931
|
+
readonly appDir: "TopoloSpaces";
|
|
932
|
+
readonly name: "topolo-spaces";
|
|
933
|
+
readonly packageName: "@topolo/spaces";
|
|
934
|
+
readonly productionUrl: "https://spaces.topolo.app";
|
|
935
|
+
readonly services: readonly ["spaces"];
|
|
936
|
+
readonly deployTargets: readonly [{
|
|
937
|
+
readonly name: "topolo-spaces";
|
|
938
|
+
readonly kind: "worker";
|
|
939
|
+
readonly apiUrl: "https://spaces.topolo.app";
|
|
940
|
+
readonly domains: readonly ["spaces.topolo.app"];
|
|
941
|
+
readonly routes: readonly ["spaces.topolo.app"];
|
|
942
|
+
readonly serviceId: "spaces";
|
|
943
|
+
}];
|
|
944
|
+
};
|
|
947
945
|
readonly status: {
|
|
948
946
|
readonly id: "status";
|
|
949
947
|
readonly appDir: "TopoloStatus";
|
|
@@ -1110,8 +1108,8 @@ declare const APPLICATION_REQUIREMENTS: readonly [{
|
|
|
1110
1108
|
readonly title: "Use the shared Topolo auth boundary";
|
|
1111
1109
|
readonly summary: "Applications must derive identity, organization, scopes, and service entitlement from TopoloAuth rather than inventing parallel auth state.";
|
|
1112
1110
|
readonly appliesTo: readonly ["browser", "api", "tooling", "agent_surface"];
|
|
1113
|
-
readonly evidence: readonly ["@topolo/auth-client or @topolo/
|
|
1114
|
-
readonly implementation: readonly ["Use shared auth packages instead of copying token parsing or browser storage flows", "Derive organization from the credential on every request", "Route OAuth, refresh, logout, and SSO paths according to the shared Auth contract"];
|
|
1111
|
+
readonly evidence: readonly ["@topolo/auth-client or @topolo-io/worker-runtime is used where applicable", "No public command, tool, or SDK method accepts orgId", "Service slug and Auth service registration are documented for protected services"];
|
|
1112
|
+
readonly implementation: readonly ["Use shared auth/runtime packages instead of copying token parsing, gateway, or browser storage flows", "Derive organization from the credential on every request", "Route OAuth, refresh, logout, and SSO paths according to the shared Auth contract"];
|
|
1115
1113
|
}, {
|
|
1116
1114
|
readonly id: "shared-shell-and-launcher";
|
|
1117
1115
|
readonly title: "Use the shared shell, launcher, and account menu";
|
|
@@ -1198,6 +1196,8 @@ interface TopoloClientOptions {
|
|
|
1198
1196
|
agent: AgentIdentity;
|
|
1199
1197
|
/** Per-service URL overrides. Useful for staging/dev. */
|
|
1200
1198
|
serviceUrls?: Partial<Record<ServiceId, string>>;
|
|
1199
|
+
/** Per-service TopoloAuth service id overrides from the owning app/deployment. */
|
|
1200
|
+
serviceIds?: Partial<Record<ServiceId, string>>;
|
|
1201
1201
|
/**
|
|
1202
1202
|
* When true, mutating helpers (POST/PUT/PATCH/DELETE) require callers to pass
|
|
1203
1203
|
* `{ confirm: true }`. Defaults to true. Set false only for trusted surfaces.
|
|
@@ -1254,10 +1254,26 @@ interface RequestOptions {
|
|
|
1254
1254
|
headers?: Record<string, string>;
|
|
1255
1255
|
signal?: AbortSignal;
|
|
1256
1256
|
}
|
|
1257
|
+
/**
|
|
1258
|
+
* A single entry from the live platform service catalog. Returned by
|
|
1259
|
+
* {@link TopoloClient.listServices}. Shape mirrors the public-safe projection
|
|
1260
|
+
* from TopoloAuth `GET /api/services/catalog`.
|
|
1261
|
+
*/
|
|
1262
|
+
interface TopoloServiceCatalogEntry {
|
|
1263
|
+
serviceId: string;
|
|
1264
|
+
slug: string | null;
|
|
1265
|
+
name: string | null;
|
|
1266
|
+
description: string | null;
|
|
1267
|
+
baseUrl: string | null;
|
|
1268
|
+
status: string | null;
|
|
1269
|
+
surfaceKind: string | null;
|
|
1270
|
+
launchable: boolean;
|
|
1271
|
+
}
|
|
1257
1272
|
declare class TopoloClient {
|
|
1258
1273
|
private readonly credential;
|
|
1259
1274
|
private readonly agent;
|
|
1260
1275
|
private readonly serviceUrls?;
|
|
1276
|
+
private readonly serviceIds?;
|
|
1261
1277
|
private readonly requireConfirmForWrites;
|
|
1262
1278
|
private readonly timeoutMs;
|
|
1263
1279
|
private readonly fetchImpl;
|
|
@@ -1283,12 +1299,7 @@ declare class TopoloClient {
|
|
|
1283
1299
|
*/
|
|
1284
1300
|
request<T = unknown>(opts: RequestOptions): Promise<T>;
|
|
1285
1301
|
/**
|
|
1286
|
-
* Resolve a service-slug → opaque service-id via TopoloAuth.
|
|
1287
|
-
*
|
|
1288
|
-
* Replaces the SDK-baked `PLATFORM_SERVICE_IDS` map (deprecated in 0.3.0,
|
|
1289
|
-
* removed in 0.4.0). Slug shape accepted: either the canonical Auth slug
|
|
1290
|
-
* (e.g. `topolo-notify`) or the SDK short id (`notify`) — Auth's resolver
|
|
1291
|
-
* understands both.
|
|
1302
|
+
* Resolve a service-slug → opaque service-id via caller config or TopoloAuth.
|
|
1292
1303
|
*
|
|
1293
1304
|
* Cache: 5 minutes per process per `(slug, auth_base_url)`. Negative
|
|
1294
1305
|
* results (404) are cached for 60s so a typo doesn't hot-loop the
|
|
@@ -1300,6 +1311,20 @@ declare class TopoloClient {
|
|
|
1300
1311
|
* has acquired an access token.
|
|
1301
1312
|
*/
|
|
1302
1313
|
getServiceIdBySlug(slug: string): Promise<string | null>;
|
|
1314
|
+
/**
|
|
1315
|
+
* List the platform service catalog from the live registry
|
|
1316
|
+
* (`GET /api/services/catalog` on TopoloAuth). Credential-aware: the
|
|
1317
|
+
* caller's credential is attached, so an authenticated caller in an
|
|
1318
|
+
* entitled org also receives the `developer_only` services its role
|
|
1319
|
+
* permits; an unauthenticated/agent caller receives `active` only.
|
|
1320
|
+
*
|
|
1321
|
+
* Resilient: on any network/HTTP failure this falls back to the
|
|
1322
|
+
* build-time generated `APPLICATIONS` snapshot so offline/degraded
|
|
1323
|
+
* callers still get a usable (if static) catalog. The live result is
|
|
1324
|
+
* authoritative; the snapshot is a floor, not a cap.
|
|
1325
|
+
*/
|
|
1326
|
+
listServices(): Promise<TopoloServiceCatalogEntry[]>;
|
|
1327
|
+
private generatedCatalogFallback;
|
|
1303
1328
|
/**
|
|
1304
1329
|
* Introspect the current credential. Returns the caller's resolved identity,
|
|
1305
1330
|
* organization, and permission set. Used by CLI `whoami` and by MCP to gate
|
|
@@ -1831,4 +1856,4 @@ declare function createTopolo(options: TopoloClientOptions): {
|
|
|
1831
1856
|
};
|
|
1832
1857
|
type Topolo = ReturnType<typeof createTopolo>;
|
|
1833
1858
|
|
|
1834
|
-
export { APPLICATIONS, APPLICATION_REQUIREMENTS, APPLICATION_REQUIREMENTS_VERSION, type AgentIdentity, type ApplicationCatalogEntry, type ApplicationDeployTarget, type ApplicationId, type ApplicationRequirement, type ApplicationRequirementAudit, type ApplicationRequirementFinding, type ApplicationRequirementMigrationItem, type ApplicationRequirementScope, type ApplicationRequirementScore, type ApplicationRequirementStatus, type ApplicationRequirementsAuditReport, type CredentialIntrospection, type CrmContactSummary, CrmModule, DEFAULT_SERVICE_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,
|
|
1859
|
+
export { APPLICATIONS, APPLICATION_REQUIREMENTS, APPLICATION_REQUIREMENTS_VERSION, type AgentIdentity, type ApplicationCatalogEntry, type ApplicationDeployTarget, type ApplicationId, type ApplicationRequirement, type ApplicationRequirementAudit, type ApplicationRequirementFinding, type ApplicationRequirementMigrationItem, type ApplicationRequirementScope, type ApplicationRequirementScore, type ApplicationRequirementStatus, type ApplicationRequirementsAuditReport, type CredentialIntrospection, type CrmContactSummary, CrmModule, DEFAULT_SERVICE_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 ServiceId, TOPOLO_WIDGET_ENDPOINT, TOPOLO_WIDGET_REFRESH_INTERVAL_MS, type TokenResponse, type Topolo, TopoloAuthError, type TopoloChartWidget, TopoloClient, type TopoloClientOptions, type TopoloCredential, type TopoloDebugEvent, TopoloHttpError, type TopoloNotificationsWidget, TopoloOAuth, TopoloPermissionError, type TopoloQuickActionsWidget, type TopoloRecentActivityWidget, TopoloSdkError, type TopoloServiceCatalogEntry, type TopoloStatsWidget, type TopoloWidget, type TopoloWidgetActionItem, type TopoloWidgetActivityItem, type TopoloWidgetApiResponse, type TopoloWidgetBase, type TopoloWidgetConfig, type TopoloWidgetDraft, type TopoloWidgetMetric, type TopoloWidgetNotificationItem, type TopoloWidgetResponseOptions, type TopoloWidgetSnapshotMetadata, type TopoloWidgetSnapshotMetric, type TopoloWidgetType, type TopoloWidgetValidationResult, applicationRequirementScopes, auditAllApplicationRequirements, auditApplicationRequirements, createTopolo, createTopoloWidgetError, createTopoloWidgetResponse, defineTopoloChartWidget, defineTopoloNotificationsWidget, defineTopoloQuickActionsWidget, defineTopoloRecentActivityWidget, defineTopoloStatsWidget, requirementsForApplication, resolveServiceUrl, validateTopoloWidgetResponse };
|
package/dist/index.js
CHANGED
|
@@ -91,41 +91,20 @@ var SERVICES = {
|
|
|
91
91
|
p2p: "https://p2p.topolo.app",
|
|
92
92
|
pay: "https://pay.topolo.app",
|
|
93
93
|
people: "https://people.topolo.app",
|
|
94
|
+
pulse: "https://pulse.topolo.app",
|
|
94
95
|
"quro.api": "https://api.ol0.me",
|
|
95
96
|
"quro.redirect": "https://ol0.me",
|
|
96
97
|
roadmapper: "https://roadmapper-api.topolo.app",
|
|
97
98
|
sign: "https://sign.topolo.app",
|
|
98
99
|
social_studio: "https://studio-api.topolo.app",
|
|
99
100
|
socialize: "https://socialize-api.topolo.app",
|
|
101
|
+
spaces: "https://spaces.topolo.app",
|
|
100
102
|
status: "https://status.topolo.app",
|
|
101
103
|
support: "https://support.topolo.app",
|
|
102
104
|
survey: "https://survey.topolo.app",
|
|
103
105
|
voice: "https://voice.topolo.app",
|
|
104
106
|
web: "https://web-api.topolo.app"
|
|
105
107
|
};
|
|
106
|
-
var PLATFORM_SERVICE_IDS = {
|
|
107
|
-
books: "srv_0g260hbN8oqv",
|
|
108
|
-
bugfix: "srv_kQ1t8qUSDgNs",
|
|
109
|
-
compose: "srv_aR3ETYmgygmd",
|
|
110
|
-
consent: "srv_8FIGR7Q7zP9r",
|
|
111
|
-
crm: "srv_iCwM4jGXcwlj",
|
|
112
|
-
customer_success: "srv_RWpOxkgZdZbH",
|
|
113
|
-
developers: "srv_NjDq9G9qyyjr",
|
|
114
|
-
director: "srv_wRCnLLbtvmVT",
|
|
115
|
-
flow: "srv_GBCuKkHhnRXv",
|
|
116
|
-
forms: "srv_UE7IcGe80J5o",
|
|
117
|
-
home: "srv_hE6HBldVzjth",
|
|
118
|
-
insights: "srv_DgbBMwWSIhmC",
|
|
119
|
-
inventory: "srv_hmvjbv3ZxDnh",
|
|
120
|
-
localize: "srv_Ze1g9OmXuZjF",
|
|
121
|
-
notify: "srv_9pRdkIjYyKX0",
|
|
122
|
-
p2p: "srv_4BzeLqH0wCve",
|
|
123
|
-
people: "srv_VDMBAonA5fKb",
|
|
124
|
-
sign: "srv_Bd8pRw5ZqRBT",
|
|
125
|
-
status: "srv_topolo_status",
|
|
126
|
-
survey: "srv_RCOi7CJkwf7R",
|
|
127
|
-
voice: "srv_BZANHkshGAK5"
|
|
128
|
-
};
|
|
129
108
|
|
|
130
109
|
// src/applications.generated.ts
|
|
131
110
|
var APPLICATIONS = {
|
|
@@ -205,6 +184,24 @@ var APPLICATIONS = {
|
|
|
205
184
|
}
|
|
206
185
|
]
|
|
207
186
|
},
|
|
187
|
+
"backup": {
|
|
188
|
+
"id": "backup",
|
|
189
|
+
"appDir": "TopoloBackup",
|
|
190
|
+
"name": "topolo-backup",
|
|
191
|
+
"packageName": "topolo-backup",
|
|
192
|
+
"productionUrl": null,
|
|
193
|
+
"services": [],
|
|
194
|
+
"deployTargets": [
|
|
195
|
+
{
|
|
196
|
+
"name": "topolo-backup",
|
|
197
|
+
"kind": "worker",
|
|
198
|
+
"apiUrl": null,
|
|
199
|
+
"domains": [],
|
|
200
|
+
"routes": [],
|
|
201
|
+
"serviceId": null
|
|
202
|
+
}
|
|
203
|
+
]
|
|
204
|
+
},
|
|
208
205
|
"books": {
|
|
209
206
|
"id": "books",
|
|
210
207
|
"appDir": "TopoloBooks",
|
|
@@ -355,15 +352,6 @@ var APPLICATIONS = {
|
|
|
355
352
|
}
|
|
356
353
|
]
|
|
357
354
|
},
|
|
358
|
-
"cli": {
|
|
359
|
-
"id": "cli",
|
|
360
|
-
"appDir": "TopoloCli",
|
|
361
|
-
"name": "@topolo/cli",
|
|
362
|
-
"packageName": "@topolo/cli",
|
|
363
|
-
"productionUrl": null,
|
|
364
|
-
"services": [],
|
|
365
|
-
"deployTargets": []
|
|
366
|
-
},
|
|
367
355
|
"cloudcontrol": {
|
|
368
356
|
"id": "cloudcontrol",
|
|
369
357
|
"appDir": "TopoloCloudControl",
|
|
@@ -529,24 +517,6 @@ var APPLICATIONS = {
|
|
|
529
517
|
}
|
|
530
518
|
]
|
|
531
519
|
},
|
|
532
|
-
"d1_backup": {
|
|
533
|
-
"id": "d1_backup",
|
|
534
|
-
"appDir": "TopoloD1Backup",
|
|
535
|
-
"name": "topolo-d1-backup",
|
|
536
|
-
"packageName": "topolo-d1-backup",
|
|
537
|
-
"productionUrl": null,
|
|
538
|
-
"services": [],
|
|
539
|
-
"deployTargets": [
|
|
540
|
-
{
|
|
541
|
-
"name": "topolo-d1-backup",
|
|
542
|
-
"kind": "worker",
|
|
543
|
-
"apiUrl": null,
|
|
544
|
-
"domains": [],
|
|
545
|
-
"routes": [],
|
|
546
|
-
"serviceId": null
|
|
547
|
-
}
|
|
548
|
-
]
|
|
549
|
-
},
|
|
550
520
|
"developers": {
|
|
551
521
|
"id": "developers",
|
|
552
522
|
"appDir": "TopoloDevelopers",
|
|
@@ -889,15 +859,6 @@ var APPLICATIONS = {
|
|
|
889
859
|
}
|
|
890
860
|
]
|
|
891
861
|
},
|
|
892
|
-
"mcp": {
|
|
893
|
-
"id": "mcp",
|
|
894
|
-
"appDir": "TopoloMCP",
|
|
895
|
-
"name": "@topolo/mcp",
|
|
896
|
-
"packageName": "@topolo/mcp",
|
|
897
|
-
"productionUrl": null,
|
|
898
|
-
"services": [],
|
|
899
|
-
"deployTargets": []
|
|
900
|
-
},
|
|
901
862
|
"mdm": {
|
|
902
863
|
"id": "mdm",
|
|
903
864
|
"appDir": "TopoloMDM",
|
|
@@ -1032,7 +993,7 @@ var APPLICATIONS = {
|
|
|
1032
993
|
"one": {
|
|
1033
994
|
"id": "one",
|
|
1034
995
|
"appDir": "TopoloOne",
|
|
1035
|
-
"name": "
|
|
996
|
+
"name": "TopoloOne",
|
|
1036
997
|
"packageName": "topolo-oneclick-sso",
|
|
1037
998
|
"productionUrl": "https://one.topolo.app",
|
|
1038
999
|
"services": [
|
|
@@ -1153,9 +1114,24 @@ var APPLICATIONS = {
|
|
|
1153
1114
|
"appDir": "TopoloPulse",
|
|
1154
1115
|
"name": "topolo-pulse",
|
|
1155
1116
|
"packageName": "topolo-pulse",
|
|
1156
|
-
"productionUrl":
|
|
1157
|
-
"services": [
|
|
1158
|
-
|
|
1117
|
+
"productionUrl": "https://pulse.topolo.app",
|
|
1118
|
+
"services": [
|
|
1119
|
+
"pulse"
|
|
1120
|
+
],
|
|
1121
|
+
"deployTargets": [
|
|
1122
|
+
{
|
|
1123
|
+
"name": "topolo-pulse",
|
|
1124
|
+
"kind": "worker",
|
|
1125
|
+
"apiUrl": "https://pulse.topolo.app",
|
|
1126
|
+
"domains": [
|
|
1127
|
+
"pulse.topolo.app"
|
|
1128
|
+
],
|
|
1129
|
+
"routes": [
|
|
1130
|
+
"pulse.topolo.app"
|
|
1131
|
+
],
|
|
1132
|
+
"serviceId": "pulse"
|
|
1133
|
+
}
|
|
1134
|
+
]
|
|
1159
1135
|
},
|
|
1160
1136
|
"quro": {
|
|
1161
1137
|
"id": "quro",
|
|
@@ -1338,6 +1314,30 @@ var APPLICATIONS = {
|
|
|
1338
1314
|
}
|
|
1339
1315
|
]
|
|
1340
1316
|
},
|
|
1317
|
+
"spaces": {
|
|
1318
|
+
"id": "spaces",
|
|
1319
|
+
"appDir": "TopoloSpaces",
|
|
1320
|
+
"name": "topolo-spaces",
|
|
1321
|
+
"packageName": "@topolo/spaces",
|
|
1322
|
+
"productionUrl": "https://spaces.topolo.app",
|
|
1323
|
+
"services": [
|
|
1324
|
+
"spaces"
|
|
1325
|
+
],
|
|
1326
|
+
"deployTargets": [
|
|
1327
|
+
{
|
|
1328
|
+
"name": "topolo-spaces",
|
|
1329
|
+
"kind": "worker",
|
|
1330
|
+
"apiUrl": "https://spaces.topolo.app",
|
|
1331
|
+
"domains": [
|
|
1332
|
+
"spaces.topolo.app"
|
|
1333
|
+
],
|
|
1334
|
+
"routes": [
|
|
1335
|
+
"spaces.topolo.app"
|
|
1336
|
+
],
|
|
1337
|
+
"serviceId": "spaces"
|
|
1338
|
+
}
|
|
1339
|
+
]
|
|
1340
|
+
},
|
|
1341
1341
|
"status": {
|
|
1342
1342
|
"id": "status",
|
|
1343
1343
|
"appDir": "TopoloStatus",
|
|
@@ -1519,12 +1519,12 @@ var APPLICATION_REQUIREMENTS = [
|
|
|
1519
1519
|
summary: "Applications must derive identity, organization, scopes, and service entitlement from TopoloAuth rather than inventing parallel auth state.",
|
|
1520
1520
|
appliesTo: ["browser", "api", "tooling", "agent_surface"],
|
|
1521
1521
|
evidence: [
|
|
1522
|
-
"@topolo/auth-client or @topolo/
|
|
1522
|
+
"@topolo/auth-client or @topolo-io/worker-runtime is used where applicable",
|
|
1523
1523
|
"No public command, tool, or SDK method accepts orgId",
|
|
1524
1524
|
"Service slug and Auth service registration are documented for protected services"
|
|
1525
1525
|
],
|
|
1526
1526
|
implementation: [
|
|
1527
|
-
"Use shared auth packages instead of copying token parsing or browser storage flows",
|
|
1527
|
+
"Use shared auth/runtime packages instead of copying token parsing, gateway, or browser storage flows",
|
|
1528
1528
|
"Derive organization from the credential on every request",
|
|
1529
1529
|
"Route OAuth, refresh, logout, and SSO paths according to the shared Auth contract"
|
|
1530
1530
|
]
|
|
@@ -1664,14 +1664,15 @@ var APPLICATION_REQUIREMENTS = [
|
|
|
1664
1664
|
];
|
|
1665
1665
|
function applicationRequirementScopes(application) {
|
|
1666
1666
|
const scopes = /* @__PURE__ */ new Set(["all"]);
|
|
1667
|
+
const appId = application.id;
|
|
1667
1668
|
const hasBrowserSurface = Boolean(application.productionUrl) || application.deployTargets.some((target) => target.kind === "pages");
|
|
1668
1669
|
const hasApiSurface = application.services.length > 0 || application.deployTargets.some((target) => Boolean(target.apiUrl));
|
|
1669
1670
|
if (hasBrowserSurface) scopes.add("browser");
|
|
1670
1671
|
if (hasApiSurface) scopes.add("api");
|
|
1671
|
-
if (
|
|
1672
|
+
if (appId === "cli" || appId === "mcp" || appId === "cloudcontrol") {
|
|
1672
1673
|
scopes.add("tooling");
|
|
1673
1674
|
}
|
|
1674
|
-
if (
|
|
1675
|
+
if (appId === "cli" || appId === "mcp" || hasApiSurface) {
|
|
1675
1676
|
scopes.add("agent_surface");
|
|
1676
1677
|
}
|
|
1677
1678
|
return Array.from(scopes);
|
|
@@ -1790,12 +1791,13 @@ function evaluateRequirement(application, requirement) {
|
|
|
1790
1791
|
return finding(requirement, "met", "CloudControl deploy target metadata is present.", evidence);
|
|
1791
1792
|
}
|
|
1792
1793
|
case "agent-and-operator-surfaces": {
|
|
1794
|
+
const appId = application.id;
|
|
1793
1795
|
if (application.services.length > 0) {
|
|
1794
1796
|
evidence.push(`services=${application.services.join(",")}`);
|
|
1795
1797
|
return finding(requirement, "partial", "SDK service discovery exists; typed SDK/CLI/MCP workflow coverage should be checked as APIs stabilize.", evidence);
|
|
1796
1798
|
}
|
|
1797
|
-
if (
|
|
1798
|
-
evidence.push(`tooling=${
|
|
1799
|
+
if (appId === "cli" || appId === "mcp" || appId === "cloudcontrol") {
|
|
1800
|
+
evidence.push(`tooling=${appId}`);
|
|
1799
1801
|
return finding(requirement, "met", "This application is itself an agent/operator surface.", evidence);
|
|
1800
1802
|
}
|
|
1801
1803
|
return finding(requirement, "missing", "No SDK service or tooling surface is registered.", evidence);
|
|
@@ -1876,6 +1878,7 @@ var TopoloClient = class _TopoloClient {
|
|
|
1876
1878
|
credential;
|
|
1877
1879
|
agent;
|
|
1878
1880
|
serviceUrls;
|
|
1881
|
+
serviceIds;
|
|
1879
1882
|
requireConfirmForWrites;
|
|
1880
1883
|
timeoutMs;
|
|
1881
1884
|
fetchImpl;
|
|
@@ -1900,6 +1903,7 @@ var TopoloClient = class _TopoloClient {
|
|
|
1900
1903
|
this.credential = options.credential;
|
|
1901
1904
|
this.agent = options.agent;
|
|
1902
1905
|
this.serviceUrls = options.serviceUrls;
|
|
1906
|
+
this.serviceIds = options.serviceIds;
|
|
1903
1907
|
this.requireConfirmForWrites = options.requireConfirmForWrites !== false;
|
|
1904
1908
|
this.timeoutMs = options.timeoutMs ?? 3e4;
|
|
1905
1909
|
this.fetchImpl = options.fetch ?? fetch;
|
|
@@ -1934,7 +1938,7 @@ var TopoloClient = class _TopoloClient {
|
|
|
1934
1938
|
const headers = new Headers();
|
|
1935
1939
|
headers.set("Accept", "application/json");
|
|
1936
1940
|
if (opts.body !== void 0) headers.set("Content-Type", "application/json");
|
|
1937
|
-
const platformServiceId =
|
|
1941
|
+
const platformServiceId = resolveConfiguredServiceId(opts.service, this.serviceIds);
|
|
1938
1942
|
if (platformServiceId) headers.set("X-Service-ID", platformServiceId);
|
|
1939
1943
|
applyAuthHeaders(headers, this.credential);
|
|
1940
1944
|
const requestId = generateRequestId();
|
|
@@ -2009,12 +2013,7 @@ var TopoloClient = class _TopoloClient {
|
|
|
2009
2013
|
return parsed;
|
|
2010
2014
|
}
|
|
2011
2015
|
/**
|
|
2012
|
-
* Resolve a service-slug → opaque service-id via TopoloAuth.
|
|
2013
|
-
*
|
|
2014
|
-
* Replaces the SDK-baked `PLATFORM_SERVICE_IDS` map (deprecated in 0.3.0,
|
|
2015
|
-
* removed in 0.4.0). Slug shape accepted: either the canonical Auth slug
|
|
2016
|
-
* (e.g. `topolo-notify`) or the SDK short id (`notify`) — Auth's resolver
|
|
2017
|
-
* understands both.
|
|
2016
|
+
* Resolve a service-slug → opaque service-id via caller config or TopoloAuth.
|
|
2018
2017
|
*
|
|
2019
2018
|
* Cache: 5 minutes per process per `(slug, auth_base_url)`. Negative
|
|
2020
2019
|
* results (404) are cached for 60s so a typo doesn't hot-loop the
|
|
@@ -2029,6 +2028,8 @@ var TopoloClient = class _TopoloClient {
|
|
|
2029
2028
|
if (typeof slug !== "string") return null;
|
|
2030
2029
|
const normalized = slug.trim().toLowerCase();
|
|
2031
2030
|
if (!normalized) return null;
|
|
2031
|
+
const configuredServiceId = resolveConfiguredServiceId(normalized, this.serviceIds);
|
|
2032
|
+
if (configuredServiceId) return configuredServiceId;
|
|
2032
2033
|
const authBase = resolveServiceUrl("auth", this.serviceUrls);
|
|
2033
2034
|
const cacheKey = `${authBase}|${normalized}`;
|
|
2034
2035
|
const now = Date.now();
|
|
@@ -2068,6 +2069,58 @@ var TopoloClient = class _TopoloClient {
|
|
|
2068
2069
|
});
|
|
2069
2070
|
return value;
|
|
2070
2071
|
}
|
|
2072
|
+
/**
|
|
2073
|
+
* List the platform service catalog from the live registry
|
|
2074
|
+
* (`GET /api/services/catalog` on TopoloAuth). Credential-aware: the
|
|
2075
|
+
* caller's credential is attached, so an authenticated caller in an
|
|
2076
|
+
* entitled org also receives the `developer_only` services its role
|
|
2077
|
+
* permits; an unauthenticated/agent caller receives `active` only.
|
|
2078
|
+
*
|
|
2079
|
+
* Resilient: on any network/HTTP failure this falls back to the
|
|
2080
|
+
* build-time generated `APPLICATIONS` snapshot so offline/degraded
|
|
2081
|
+
* callers still get a usable (if static) catalog. The live result is
|
|
2082
|
+
* authoritative; the snapshot is a floor, not a cap.
|
|
2083
|
+
*/
|
|
2084
|
+
async listServices() {
|
|
2085
|
+
try {
|
|
2086
|
+
const res = await this.request({ service: "auth", method: "GET", path: "/api/services/catalog" });
|
|
2087
|
+
const raw = res.data?.services ?? res.services;
|
|
2088
|
+
if (Array.isArray(raw) && raw.length > 0) {
|
|
2089
|
+
const entries = [];
|
|
2090
|
+
for (const item of raw) {
|
|
2091
|
+
const s = item;
|
|
2092
|
+
const serviceId = typeof s.service_id === "string" ? s.service_id : typeof s.id === "string" ? s.id : null;
|
|
2093
|
+
if (!serviceId) continue;
|
|
2094
|
+
entries.push({
|
|
2095
|
+
serviceId,
|
|
2096
|
+
slug: typeof s.app_slug === "string" ? s.app_slug : null,
|
|
2097
|
+
name: typeof s.name === "string" ? s.name : null,
|
|
2098
|
+
description: typeof s.description === "string" ? s.description : null,
|
|
2099
|
+
baseUrl: typeof s.base_url === "string" ? s.base_url : null,
|
|
2100
|
+
status: typeof s.status === "string" ? s.status : null,
|
|
2101
|
+
surfaceKind: typeof s.surface_kind === "string" ? s.surface_kind : null,
|
|
2102
|
+
launchable: s.launchable === true
|
|
2103
|
+
});
|
|
2104
|
+
}
|
|
2105
|
+
if (entries.length > 0) return entries;
|
|
2106
|
+
}
|
|
2107
|
+
} catch {
|
|
2108
|
+
}
|
|
2109
|
+
return this.generatedCatalogFallback();
|
|
2110
|
+
}
|
|
2111
|
+
generatedCatalogFallback() {
|
|
2112
|
+
const apps = Object.values(APPLICATIONS);
|
|
2113
|
+
return apps.map((app) => ({
|
|
2114
|
+
serviceId: app.id,
|
|
2115
|
+
slug: app.id,
|
|
2116
|
+
name: app.name ?? app.id,
|
|
2117
|
+
description: null,
|
|
2118
|
+
baseUrl: app.productionUrl ?? null,
|
|
2119
|
+
status: "active",
|
|
2120
|
+
surfaceKind: "application",
|
|
2121
|
+
launchable: Boolean(app.productionUrl)
|
|
2122
|
+
}));
|
|
2123
|
+
}
|
|
2071
2124
|
/**
|
|
2072
2125
|
* Introspect the current credential. Returns the caller's resolved identity,
|
|
2073
2126
|
* organization, and permission set. Used by CLI `whoami` and by MCP to gate
|
|
@@ -2104,6 +2157,26 @@ var TopoloClient = class _TopoloClient {
|
|
|
2104
2157
|
};
|
|
2105
2158
|
}
|
|
2106
2159
|
};
|
|
2160
|
+
function resolveConfiguredServiceId(slug, serviceIds) {
|
|
2161
|
+
for (const serviceKey of serviceKeyCandidates(slug)) {
|
|
2162
|
+
const configured = serviceIds?.[serviceKey];
|
|
2163
|
+
if (typeof configured === "string" && configured.trim()) return configured.trim();
|
|
2164
|
+
const envKey = `TOPOLO_SERVICE_ID_${serviceKey.replace(/\./g, "_").toUpperCase()}`;
|
|
2165
|
+
const envValue = typeof process !== "undefined" ? process.env?.[envKey] : void 0;
|
|
2166
|
+
if (typeof envValue === "string" && envValue.trim()) return envValue.trim();
|
|
2167
|
+
}
|
|
2168
|
+
return null;
|
|
2169
|
+
}
|
|
2170
|
+
function serviceKeyCandidates(slug) {
|
|
2171
|
+
const normalized = slug.trim().toLowerCase();
|
|
2172
|
+
const withoutTopolo = normalized.startsWith("topolo-") ? normalized.slice("topolo-".length) : normalized;
|
|
2173
|
+
return [.../* @__PURE__ */ new Set([
|
|
2174
|
+
normalized,
|
|
2175
|
+
normalized.replace(/-/g, "_"),
|
|
2176
|
+
withoutTopolo,
|
|
2177
|
+
withoutTopolo.replace(/-/g, "_")
|
|
2178
|
+
])];
|
|
2179
|
+
}
|
|
2107
2180
|
function describeError(body, fallback) {
|
|
2108
2181
|
if (body && typeof body === "object") {
|
|
2109
2182
|
const maybe = body;
|
|
@@ -2669,7 +2742,6 @@ export {
|
|
|
2669
2742
|
DEFAULT_SERVICE_URLS,
|
|
2670
2743
|
IdentityModule,
|
|
2671
2744
|
P2PModule,
|
|
2672
|
-
PLATFORM_SERVICE_IDS,
|
|
2673
2745
|
TOPOLO_WIDGET_ENDPOINT,
|
|
2674
2746
|
TOPOLO_WIDGET_REFRESH_INTERVAL_MS,
|
|
2675
2747
|
TopoloAuthError,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@topolo/sdk",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "Typed client SDK for the Topolo platform. Used by TopoloCli, TopoloMCP, and third-party agents.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -25,10 +25,13 @@
|
|
|
25
25
|
"dev": "tsup src/index.ts --format esm,cjs --dts --watch",
|
|
26
26
|
"typecheck": "node scripts/generate-services.mjs && tsc --noEmit",
|
|
27
27
|
"test": "vitest run",
|
|
28
|
-
"test:watch": "vitest"
|
|
28
|
+
"test:watch": "vitest",
|
|
29
|
+
"prepublishOnly": "npm run build",
|
|
30
|
+
"coverage": "vitest run --coverage"
|
|
29
31
|
},
|
|
30
32
|
"devDependencies": {
|
|
31
33
|
"@types/node": "^20.19.39",
|
|
34
|
+
"@vitest/coverage-v8": "^2.1.0",
|
|
32
35
|
"tsup": "^8.0.0",
|
|
33
36
|
"typescript": "^5.4.0",
|
|
34
37
|
"vitest": "^2.1.0"
|