@topolo/sdk 0.8.2 → 0.8.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -129,6 +129,7 @@ var APP_API_URLS = {
129
129
  bugfix: "https://bugfix.topolo.app",
130
130
  bytes: "https://bytes.topolo.app",
131
131
  calendar: "https://calendar.topolo.app",
132
+ campaigns: "https://campaigns.topolo.app",
132
133
  capacity: "https://capacity.topolo.app",
133
134
  chat: "https://chat.topolo.app",
134
135
  commerce: "https://commerce.topolo.app",
@@ -389,6 +390,38 @@ var APPLICATIONS = {
389
390
  }
390
391
  ]
391
392
  },
393
+ "campaigns": {
394
+ "id": "campaigns",
395
+ "appDir": "TopoloCampaigns",
396
+ "name": "topolo-campaigns",
397
+ "packageName": "topolo-campaigns",
398
+ "productionUrl": "https://campaigns.topolo.app",
399
+ "services": [
400
+ "campaigns"
401
+ ],
402
+ "deployTargets": [
403
+ {
404
+ "name": "topolo-campaigns",
405
+ "kind": "worker",
406
+ "apiUrl": "https://campaigns.topolo.app",
407
+ "domains": [
408
+ "campaigns.topolo.app"
409
+ ],
410
+ "routes": [
411
+ "campaigns.topolo.app"
412
+ ],
413
+ "appId": "campaigns"
414
+ },
415
+ {
416
+ "name": "topolo-campaigns-api",
417
+ "kind": "worker",
418
+ "apiUrl": null,
419
+ "domains": [],
420
+ "routes": [],
421
+ "appId": null
422
+ }
423
+ ]
424
+ },
392
425
  "capacity": {
393
426
  "id": "capacity",
394
427
  "appDir": "TopoloCapacity",
@@ -2570,6 +2603,20 @@ var TopoloClient = class _TopoloClient {
2570
2603
  }
2571
2604
  async callAction(action, input = {}, options = {}) {
2572
2605
  const entry = await this.getAction(action);
2606
+ return this.executeResolvedAction(entry, input, options);
2607
+ }
2608
+ async readAction(action, input = {}, options = {}) {
2609
+ const entry = await this.getAction(action);
2610
+ const agentAccess = entry.agentAccess ?? (entry.destructive ? "off" : entry.readOnly && !entry.requiresConfirmation ? "auto" : "confirm");
2611
+ if (entry.method !== "GET" || !entry.readOnly || entry.destructive || entry.requiresConfirmation || agentAccess !== "auto") {
2612
+ throw new TopoloPermissionError(
2613
+ `Topolo action "${entry.actionId}" is not an automatic read-only action.`,
2614
+ entry.requiredPermission ? [entry.requiredPermission] : []
2615
+ );
2616
+ }
2617
+ return this.executeResolvedAction(entry, input, options);
2618
+ }
2619
+ async executeResolvedAction(entry, input, options) {
2573
2620
  const agentAccess = entry.agentAccess ?? (entry.destructive ? "off" : entry.readOnly && !entry.requiresConfirmation ? "auto" : "confirm");
2574
2621
  if (agentAccess === "off") {
2575
2622
  throw new TopoloPermissionError(
package/dist/index.d.cts CHANGED
@@ -267,6 +267,13 @@ declare class TopoloClient {
267
267
  resourceId: string;
268
268
  };
269
269
  }): Promise<T>;
270
+ readAction<T = unknown>(action: string, input?: Record<string, unknown>, options?: {
271
+ resource?: {
272
+ resourceType: string;
273
+ resourceId: string;
274
+ };
275
+ }): Promise<T>;
276
+ private executeResolvedAction;
270
277
  /**
271
278
  * Bundled generated registry for tooling that audits platform packaging, not
272
279
  * for deciding what the current credential may use.
@@ -326,6 +333,7 @@ declare const APP_API_URLS: {
326
333
  readonly bugfix: "https://bugfix.topolo.app";
327
334
  readonly bytes: "https://bytes.topolo.app";
328
335
  readonly calendar: "https://calendar.topolo.app";
336
+ readonly campaigns: "https://campaigns.topolo.app";
329
337
  readonly capacity: "https://capacity.topolo.app";
330
338
  readonly chat: "https://chat.topolo.app";
331
339
  readonly commerce: "https://commerce.topolo.app";
@@ -533,6 +541,29 @@ declare const APPLICATIONS: {
533
541
  readonly appId: null;
534
542
  }];
535
543
  };
544
+ readonly campaigns: {
545
+ readonly id: "campaigns";
546
+ readonly appDir: "TopoloCampaigns";
547
+ readonly name: "topolo-campaigns";
548
+ readonly packageName: "topolo-campaigns";
549
+ readonly productionUrl: "https://campaigns.topolo.app";
550
+ readonly services: readonly ["campaigns"];
551
+ readonly deployTargets: readonly [{
552
+ readonly name: "topolo-campaigns";
553
+ readonly kind: "worker";
554
+ readonly apiUrl: "https://campaigns.topolo.app";
555
+ readonly domains: readonly ["campaigns.topolo.app"];
556
+ readonly routes: readonly ["campaigns.topolo.app"];
557
+ readonly appId: "campaigns";
558
+ }, {
559
+ readonly name: "topolo-campaigns-api";
560
+ readonly kind: "worker";
561
+ readonly apiUrl: null;
562
+ readonly domains: readonly [];
563
+ readonly routes: readonly [];
564
+ readonly appId: null;
565
+ }];
566
+ };
536
567
  readonly capacity: {
537
568
  readonly id: "capacity";
538
569
  readonly appDir: "TopoloCapacity";
package/dist/index.d.ts CHANGED
@@ -267,6 +267,13 @@ declare class TopoloClient {
267
267
  resourceId: string;
268
268
  };
269
269
  }): Promise<T>;
270
+ readAction<T = unknown>(action: string, input?: Record<string, unknown>, options?: {
271
+ resource?: {
272
+ resourceType: string;
273
+ resourceId: string;
274
+ };
275
+ }): Promise<T>;
276
+ private executeResolvedAction;
270
277
  /**
271
278
  * Bundled generated registry for tooling that audits platform packaging, not
272
279
  * for deciding what the current credential may use.
@@ -326,6 +333,7 @@ declare const APP_API_URLS: {
326
333
  readonly bugfix: "https://bugfix.topolo.app";
327
334
  readonly bytes: "https://bytes.topolo.app";
328
335
  readonly calendar: "https://calendar.topolo.app";
336
+ readonly campaigns: "https://campaigns.topolo.app";
329
337
  readonly capacity: "https://capacity.topolo.app";
330
338
  readonly chat: "https://chat.topolo.app";
331
339
  readonly commerce: "https://commerce.topolo.app";
@@ -533,6 +541,29 @@ declare const APPLICATIONS: {
533
541
  readonly appId: null;
534
542
  }];
535
543
  };
544
+ readonly campaigns: {
545
+ readonly id: "campaigns";
546
+ readonly appDir: "TopoloCampaigns";
547
+ readonly name: "topolo-campaigns";
548
+ readonly packageName: "topolo-campaigns";
549
+ readonly productionUrl: "https://campaigns.topolo.app";
550
+ readonly services: readonly ["campaigns"];
551
+ readonly deployTargets: readonly [{
552
+ readonly name: "topolo-campaigns";
553
+ readonly kind: "worker";
554
+ readonly apiUrl: "https://campaigns.topolo.app";
555
+ readonly domains: readonly ["campaigns.topolo.app"];
556
+ readonly routes: readonly ["campaigns.topolo.app"];
557
+ readonly appId: "campaigns";
558
+ }, {
559
+ readonly name: "topolo-campaigns-api";
560
+ readonly kind: "worker";
561
+ readonly apiUrl: null;
562
+ readonly domains: readonly [];
563
+ readonly routes: readonly [];
564
+ readonly appId: null;
565
+ }];
566
+ };
536
567
  readonly capacity: {
537
568
  readonly id: "capacity";
538
569
  readonly appDir: "TopoloCapacity";
package/dist/index.js CHANGED
@@ -71,6 +71,7 @@ var APP_API_URLS = {
71
71
  bugfix: "https://bugfix.topolo.app",
72
72
  bytes: "https://bytes.topolo.app",
73
73
  calendar: "https://calendar.topolo.app",
74
+ campaigns: "https://campaigns.topolo.app",
74
75
  capacity: "https://capacity.topolo.app",
75
76
  chat: "https://chat.topolo.app",
76
77
  commerce: "https://commerce.topolo.app",
@@ -331,6 +332,38 @@ var APPLICATIONS = {
331
332
  }
332
333
  ]
333
334
  },
335
+ "campaigns": {
336
+ "id": "campaigns",
337
+ "appDir": "TopoloCampaigns",
338
+ "name": "topolo-campaigns",
339
+ "packageName": "topolo-campaigns",
340
+ "productionUrl": "https://campaigns.topolo.app",
341
+ "services": [
342
+ "campaigns"
343
+ ],
344
+ "deployTargets": [
345
+ {
346
+ "name": "topolo-campaigns",
347
+ "kind": "worker",
348
+ "apiUrl": "https://campaigns.topolo.app",
349
+ "domains": [
350
+ "campaigns.topolo.app"
351
+ ],
352
+ "routes": [
353
+ "campaigns.topolo.app"
354
+ ],
355
+ "appId": "campaigns"
356
+ },
357
+ {
358
+ "name": "topolo-campaigns-api",
359
+ "kind": "worker",
360
+ "apiUrl": null,
361
+ "domains": [],
362
+ "routes": [],
363
+ "appId": null
364
+ }
365
+ ]
366
+ },
334
367
  "capacity": {
335
368
  "id": "capacity",
336
369
  "appDir": "TopoloCapacity",
@@ -2512,6 +2545,20 @@ var TopoloClient = class _TopoloClient {
2512
2545
  }
2513
2546
  async callAction(action, input = {}, options = {}) {
2514
2547
  const entry = await this.getAction(action);
2548
+ return this.executeResolvedAction(entry, input, options);
2549
+ }
2550
+ async readAction(action, input = {}, options = {}) {
2551
+ const entry = await this.getAction(action);
2552
+ const agentAccess = entry.agentAccess ?? (entry.destructive ? "off" : entry.readOnly && !entry.requiresConfirmation ? "auto" : "confirm");
2553
+ if (entry.method !== "GET" || !entry.readOnly || entry.destructive || entry.requiresConfirmation || agentAccess !== "auto") {
2554
+ throw new TopoloPermissionError(
2555
+ `Topolo action "${entry.actionId}" is not an automatic read-only action.`,
2556
+ entry.requiredPermission ? [entry.requiredPermission] : []
2557
+ );
2558
+ }
2559
+ return this.executeResolvedAction(entry, input, options);
2560
+ }
2561
+ async executeResolvedAction(entry, input, options) {
2515
2562
  const agentAccess = entry.agentAccess ?? (entry.destructive ? "off" : entry.readOnly && !entry.requiresConfirmation ? "auto" : "confirm");
2516
2563
  if (agentAccess === "off") {
2517
2564
  throw new TopoloPermissionError(
@@ -31,6 +31,7 @@ __export(credential_store_exports, {
31
31
  normalizeEnvironment: () => normalizeEnvironment,
32
32
  profileForEnvironment: () => profileForEnvironment,
33
33
  readConfig: () => readConfig,
34
+ refreshContextCredentialIfNeeded: () => refreshContextCredentialIfNeeded,
34
35
  refreshCredentialIfNeeded: () => refreshCredentialIfNeeded,
35
36
  resolveAgentName: () => resolveAgentName,
36
37
  resolveCredential: () => resolveCredential,
@@ -86,6 +87,7 @@ var APP_API_URLS = {
86
87
  bugfix: "https://bugfix.topolo.app",
87
88
  bytes: "https://bytes.topolo.app",
88
89
  calendar: "https://calendar.topolo.app",
90
+ campaigns: "https://campaigns.topolo.app",
89
91
  capacity: "https://capacity.topolo.app",
90
92
  chat: "https://chat.topolo.app",
91
93
  commerce: "https://commerce.topolo.app",
@@ -427,6 +429,46 @@ async function refreshCredentialIfNeeded(environment = selectedEnvironment(), op
427
429
  return cred;
428
430
  }
429
431
  }
432
+ async function refreshContextCredentialIfNeeded(environment, key, options = {}) {
433
+ const config = await readConfig();
434
+ const profile = profileForEnvironment(config, environment);
435
+ const context = profile.contexts?.[key];
436
+ const credential = context?.credential;
437
+ if (!credential || credential.kind !== "access_token") return credential ?? null;
438
+ const oauthClientId = context.oauthClientId ?? profile.oauthClientId;
439
+ if (!credential.refreshToken || !credential.expiresAt || !oauthClientId) return credential;
440
+ const now = Math.floor(Date.now() / 1e3);
441
+ if (!options.force && credential.expiresAt - REFRESH_SKEW_SECONDS > now) return credential;
442
+ try {
443
+ const oauth = new TopoloOAuth({
444
+ serviceUrls: resolveServiceUrls(profile.serviceUrls, environment)
445
+ });
446
+ const tokens = await oauth.refreshToken({
447
+ clientId: oauthClientId,
448
+ refreshToken: credential.refreshToken
449
+ });
450
+ const refreshed = {
451
+ kind: "access_token",
452
+ accessToken: tokens.access_token,
453
+ ...tokens.refresh_token ? { refreshToken: tokens.refresh_token } : { refreshToken: credential.refreshToken },
454
+ expiresAt: Math.floor(Date.now() / 1e3) + tokens.expires_in
455
+ };
456
+ await writeConfig(writeProfileConfig(config, environment, {
457
+ ...profile.activeContext === key ? { credential: refreshed } : {},
458
+ contexts: {
459
+ ...profile.contexts ?? {},
460
+ [key]: {
461
+ ...context,
462
+ credential: refreshed,
463
+ oauthClientId
464
+ }
465
+ }
466
+ }));
467
+ return refreshed;
468
+ } catch {
469
+ return credential;
470
+ }
471
+ }
430
472
  function resolveAgentName(configAgentName) {
431
473
  return process.env.TOPOLO_AGENT_NAME ?? configAgentName;
432
474
  }
@@ -470,6 +512,7 @@ function resolvedProfileConfig(config, environment = selectedEnvironment()) {
470
512
  normalizeEnvironment,
471
513
  profileForEnvironment,
472
514
  readConfig,
515
+ refreshContextCredentialIfNeeded,
473
516
  refreshCredentialIfNeeded,
474
517
  resolveAgentName,
475
518
  resolveCredential,
@@ -103,8 +103,12 @@ declare function resolveCredential(environment?: TopoloEnvironment): Promise<Top
103
103
  declare function refreshCredentialIfNeeded(environment?: TopoloEnvironment, options?: {
104
104
  force?: boolean;
105
105
  }): Promise<TopoloCredential | null>;
106
+ /** Refresh one stored context without changing which context is active. */
107
+ declare function refreshContextCredentialIfNeeded(environment: TopoloEnvironment, key: string, options?: {
108
+ force?: boolean;
109
+ }): Promise<TopoloCredential | null>;
106
110
  declare function resolveAgentName(configAgentName?: string): string | undefined;
107
111
  declare function resolveServiceUrls(configUrls?: Record<string, string>, environment?: TopoloEnvironment): Record<string, string> | undefined;
108
112
  declare function resolvedProfileConfig(config: TopoloConfig, environment?: TopoloEnvironment): TopoloEnvironmentProfile;
109
113
 
110
- export { ENVIRONMENT_DEFAULT_SERVICE_URLS, TOPOLO_ENVIRONMENTS, type TopoloConfig, type TopoloContextCredential, type TopoloEnvironment, type TopoloEnvironmentProfile, activateContext, clearProfileCredential, configPath, contextKey, credentialSourceFromConfig, envVarPrefix, normalizeEnvironment, profileForEnvironment, readConfig, refreshCredentialIfNeeded, resolveAgentName, resolveCredential, resolveServiceUrls, resolvedProfileConfig, selectedEnvironment, writeConfig, writeContextCredential, writeProfileConfig };
114
+ export { ENVIRONMENT_DEFAULT_SERVICE_URLS, TOPOLO_ENVIRONMENTS, type TopoloConfig, type TopoloContextCredential, type TopoloEnvironment, type TopoloEnvironmentProfile, activateContext, clearProfileCredential, configPath, contextKey, credentialSourceFromConfig, envVarPrefix, normalizeEnvironment, profileForEnvironment, readConfig, refreshContextCredentialIfNeeded, refreshCredentialIfNeeded, resolveAgentName, resolveCredential, resolveServiceUrls, resolvedProfileConfig, selectedEnvironment, writeConfig, writeContextCredential, writeProfileConfig };
@@ -103,8 +103,12 @@ declare function resolveCredential(environment?: TopoloEnvironment): Promise<Top
103
103
  declare function refreshCredentialIfNeeded(environment?: TopoloEnvironment, options?: {
104
104
  force?: boolean;
105
105
  }): Promise<TopoloCredential | null>;
106
+ /** Refresh one stored context without changing which context is active. */
107
+ declare function refreshContextCredentialIfNeeded(environment: TopoloEnvironment, key: string, options?: {
108
+ force?: boolean;
109
+ }): Promise<TopoloCredential | null>;
106
110
  declare function resolveAgentName(configAgentName?: string): string | undefined;
107
111
  declare function resolveServiceUrls(configUrls?: Record<string, string>, environment?: TopoloEnvironment): Record<string, string> | undefined;
108
112
  declare function resolvedProfileConfig(config: TopoloConfig, environment?: TopoloEnvironment): TopoloEnvironmentProfile;
109
113
 
110
- export { ENVIRONMENT_DEFAULT_SERVICE_URLS, TOPOLO_ENVIRONMENTS, type TopoloConfig, type TopoloContextCredential, type TopoloEnvironment, type TopoloEnvironmentProfile, activateContext, clearProfileCredential, configPath, contextKey, credentialSourceFromConfig, envVarPrefix, normalizeEnvironment, profileForEnvironment, readConfig, refreshCredentialIfNeeded, resolveAgentName, resolveCredential, resolveServiceUrls, resolvedProfileConfig, selectedEnvironment, writeConfig, writeContextCredential, writeProfileConfig };
114
+ export { ENVIRONMENT_DEFAULT_SERVICE_URLS, TOPOLO_ENVIRONMENTS, type TopoloConfig, type TopoloContextCredential, type TopoloEnvironment, type TopoloEnvironmentProfile, activateContext, clearProfileCredential, configPath, contextKey, credentialSourceFromConfig, envVarPrefix, normalizeEnvironment, profileForEnvironment, readConfig, refreshContextCredentialIfNeeded, refreshCredentialIfNeeded, resolveAgentName, resolveCredential, resolveServiceUrls, resolvedProfileConfig, selectedEnvironment, writeConfig, writeContextCredential, writeProfileConfig };
@@ -43,6 +43,7 @@ var APP_API_URLS = {
43
43
  bugfix: "https://bugfix.topolo.app",
44
44
  bytes: "https://bytes.topolo.app",
45
45
  calendar: "https://calendar.topolo.app",
46
+ campaigns: "https://campaigns.topolo.app",
46
47
  capacity: "https://capacity.topolo.app",
47
48
  chat: "https://chat.topolo.app",
48
49
  commerce: "https://commerce.topolo.app",
@@ -384,6 +385,46 @@ async function refreshCredentialIfNeeded(environment = selectedEnvironment(), op
384
385
  return cred;
385
386
  }
386
387
  }
388
+ async function refreshContextCredentialIfNeeded(environment, key, options = {}) {
389
+ const config = await readConfig();
390
+ const profile = profileForEnvironment(config, environment);
391
+ const context = profile.contexts?.[key];
392
+ const credential = context?.credential;
393
+ if (!credential || credential.kind !== "access_token") return credential ?? null;
394
+ const oauthClientId = context.oauthClientId ?? profile.oauthClientId;
395
+ if (!credential.refreshToken || !credential.expiresAt || !oauthClientId) return credential;
396
+ const now = Math.floor(Date.now() / 1e3);
397
+ if (!options.force && credential.expiresAt - REFRESH_SKEW_SECONDS > now) return credential;
398
+ try {
399
+ const oauth = new TopoloOAuth({
400
+ serviceUrls: resolveServiceUrls(profile.serviceUrls, environment)
401
+ });
402
+ const tokens = await oauth.refreshToken({
403
+ clientId: oauthClientId,
404
+ refreshToken: credential.refreshToken
405
+ });
406
+ const refreshed = {
407
+ kind: "access_token",
408
+ accessToken: tokens.access_token,
409
+ ...tokens.refresh_token ? { refreshToken: tokens.refresh_token } : { refreshToken: credential.refreshToken },
410
+ expiresAt: Math.floor(Date.now() / 1e3) + tokens.expires_in
411
+ };
412
+ await writeConfig(writeProfileConfig(config, environment, {
413
+ ...profile.activeContext === key ? { credential: refreshed } : {},
414
+ contexts: {
415
+ ...profile.contexts ?? {},
416
+ [key]: {
417
+ ...context,
418
+ credential: refreshed,
419
+ oauthClientId
420
+ }
421
+ }
422
+ }));
423
+ return refreshed;
424
+ } catch {
425
+ return credential;
426
+ }
427
+ }
387
428
  function resolveAgentName(configAgentName) {
388
429
  return process.env.TOPOLO_AGENT_NAME ?? configAgentName;
389
430
  }
@@ -426,6 +467,7 @@ export {
426
467
  normalizeEnvironment,
427
468
  profileForEnvironment,
428
469
  readConfig,
470
+ refreshContextCredentialIfNeeded,
429
471
  refreshCredentialIfNeeded,
430
472
  resolveAgentName,
431
473
  resolveCredential,
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@topolo/sdk",
3
- "version": "0.8.2",
4
- "topoloPublishedVersion": "0.8.2",
3
+ "version": "0.8.4",
4
+ "topoloPublishedVersion": "0.8.4",
5
5
  "description": "Typed client SDK for the Topolo platform. Used by TopoloCli, TopoloMCP, and third-party agents.",
6
6
  "type": "module",
7
7
  "main": "./dist/index.js",