@topolo/sdk 0.3.0 → 0.4.1
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 +17 -5
- package/dist/index.cjs +582 -252
- package/dist/index.d.cts +504 -287
- package/dist/index.d.ts +504 -287
- package/dist/index.js +582 -251
- package/package.json +5 -2
- package/src/application-requirements.ts +26 -11
- package/src/applications.generated.ts +399 -200
- package/src/client.test.ts +211 -19
- package/src/client.ts +234 -21
- package/src/index.ts +1 -1
- package/src/modules/p2p.test.ts +27 -11
- package/src/services.generated.ts +6 -34
- package/src/services.test.ts +17 -28
- package/src/services.ts +1 -2
- package/src/widgets.test.ts +7 -7
package/src/services.test.ts
CHANGED
|
@@ -14,20 +14,17 @@ const EXPECTED_APPLICATION_IDS = [
|
|
|
14
14
|
'admin',
|
|
15
15
|
'agent',
|
|
16
16
|
'auth',
|
|
17
|
+
'backup',
|
|
17
18
|
'books',
|
|
18
19
|
'bugfix',
|
|
19
20
|
'bytes',
|
|
20
21
|
'calendar',
|
|
21
22
|
'capacity',
|
|
22
23
|
'chat',
|
|
23
|
-
'cli',
|
|
24
|
-
'cloudcontrol',
|
|
25
24
|
'commerce',
|
|
26
25
|
'compose',
|
|
27
26
|
'consent',
|
|
28
27
|
'crm',
|
|
29
|
-
'customer_success',
|
|
30
|
-
'd1_backup',
|
|
31
28
|
'developers',
|
|
32
29
|
'director',
|
|
33
30
|
'docs',
|
|
@@ -41,9 +38,8 @@ const EXPECTED_APPLICATION_IDS = [
|
|
|
41
38
|
'learn',
|
|
42
39
|
'localize',
|
|
43
40
|
'mail',
|
|
44
|
-
'mcp',
|
|
45
41
|
'mdm',
|
|
46
|
-
'
|
|
42
|
+
'messages',
|
|
47
43
|
'nexus',
|
|
48
44
|
'notify',
|
|
49
45
|
'observability_watch',
|
|
@@ -57,7 +53,9 @@ const EXPECTED_APPLICATION_IDS = [
|
|
|
57
53
|
'sign',
|
|
58
54
|
'social_studio',
|
|
59
55
|
'socialize',
|
|
56
|
+
'spaces',
|
|
60
57
|
'status',
|
|
58
|
+
'success',
|
|
61
59
|
'support',
|
|
62
60
|
'survey',
|
|
63
61
|
'voice',
|
|
@@ -76,7 +74,7 @@ describe('service registry', () => {
|
|
|
76
74
|
web: 'https://web-api.topolo.app',
|
|
77
75
|
});
|
|
78
76
|
expect(DEFAULT_SERVICE_URLS).toMatchObject({
|
|
79
|
-
|
|
77
|
+
success: 'https://success.topolo.app',
|
|
80
78
|
forms: 'https://forms.topolo.app',
|
|
81
79
|
survey: 'https://survey.topolo.app',
|
|
82
80
|
});
|
|
@@ -84,20 +82,10 @@ describe('service registry', () => {
|
|
|
84
82
|
expect(DEFAULT_SERVICE_URLS).not.toHaveProperty('web.runtime');
|
|
85
83
|
});
|
|
86
84
|
|
|
87
|
-
it('
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
// is non-empty and that the values look like opaque service ids; specific
|
|
92
|
-
// ids are no longer load-bearing.
|
|
93
|
-
const { PLATFORM_SERVICE_IDS } = await import('./services.js');
|
|
94
|
-
|
|
95
|
-
const entries = Object.entries(PLATFORM_SERVICE_IDS);
|
|
96
|
-
expect(entries.length).toBeGreaterThan(0);
|
|
97
|
-
for (const [, id] of entries) {
|
|
98
|
-
expect(typeof id).toBe('string');
|
|
99
|
-
expect(id).toMatch(/^srv_/);
|
|
100
|
-
}
|
|
85
|
+
it('does not bake opaque Auth service ids into the generated registry', async () => {
|
|
86
|
+
const services = await import('./services.js');
|
|
87
|
+
|
|
88
|
+
expect(services).not.toHaveProperty('PLATFORM_SERVICE_IDS');
|
|
101
89
|
});
|
|
102
90
|
|
|
103
91
|
it('maps every callable service back to an application catalog entry', () => {
|
|
@@ -129,14 +117,21 @@ describe('application catalog', () => {
|
|
|
129
117
|
}
|
|
130
118
|
});
|
|
131
119
|
|
|
132
|
-
it('treats TopoloWeb runtime as a deploy
|
|
120
|
+
it('treats TopoloWeb runtime as a standalone deploy, not an agent-callable API service', () => {
|
|
133
121
|
expect(APPLICATIONS.web.services).toEqual(['web']);
|
|
134
122
|
expect(
|
|
135
123
|
APPLICATIONS.web.deployTargets.find((target) => target.name === 'topolo-web-api')?.serviceId,
|
|
136
124
|
).toBe('web');
|
|
125
|
+
// topolo-web-runtime (Astro, sites.topolo.app) deploys from its own wrangler
|
|
126
|
+
// config and is intentionally listed as non-callable, so it can never be an
|
|
127
|
+
// agent-callable service.
|
|
137
128
|
expect(
|
|
138
129
|
APPLICATIONS.web.deployTargets.find((target) => target.name === 'topolo-web-runtime')?.serviceId,
|
|
139
130
|
).toBeNull();
|
|
131
|
+
const callableTargetNames = APPLICATIONS.web.deployTargets
|
|
132
|
+
.filter((target) => target.serviceId)
|
|
133
|
+
.map((target) => target.name);
|
|
134
|
+
expect(callableTargetNames).not.toContain('topolo-web-runtime');
|
|
140
135
|
});
|
|
141
136
|
|
|
142
137
|
it('treats TopoloFeed analytics as telemetry, not an agent-callable API service', () => {
|
|
@@ -169,23 +164,17 @@ describe('application requirements', () => {
|
|
|
169
164
|
expect(applicationRequirementScopes(APPLICATIONS.mail)).toEqual(
|
|
170
165
|
expect.arrayContaining(['all', 'browser', 'api', 'agent_surface']),
|
|
171
166
|
);
|
|
172
|
-
expect(applicationRequirementScopes(APPLICATIONS.cli)).toEqual(
|
|
173
|
-
expect.arrayContaining(['all', 'tooling', 'agent_surface']),
|
|
174
|
-
);
|
|
175
167
|
});
|
|
176
168
|
|
|
177
169
|
it('filters requirements for a target application', () => {
|
|
178
170
|
const adminRequirementIds = requirementsForApplication('admin').map((requirement) => requirement.id);
|
|
179
171
|
const mailRequirementIds = requirementsForApplication('mail').map((requirement) => requirement.id);
|
|
180
|
-
const cliRequirementIds = requirementsForApplication('cli').map((requirement) => requirement.id);
|
|
181
172
|
|
|
182
173
|
expect(adminRequirementIds).toContain('shared-shell-and-launcher');
|
|
183
174
|
expect(adminRequirementIds).not.toContain('organization-scoped-data');
|
|
184
175
|
expect(mailRequirementIds).toContain('organization-scoped-data');
|
|
185
176
|
expect(mailRequirementIds).toContain('service-registration-and-scopes');
|
|
186
177
|
expect(mailRequirementIds).toContain('native-dashboard-widget');
|
|
187
|
-
expect(cliRequirementIds).toContain('agent-and-operator-surfaces');
|
|
188
|
-
expect(cliRequirementIds).not.toContain('service-registration-and-scopes');
|
|
189
178
|
});
|
|
190
179
|
|
|
191
180
|
it('audits one application against the catalog-backed requirements', () => {
|
package/src/services.ts
CHANGED
|
@@ -15,7 +15,6 @@
|
|
|
15
15
|
*/
|
|
16
16
|
import {
|
|
17
17
|
SERVICES,
|
|
18
|
-
PLATFORM_SERVICE_IDS,
|
|
19
18
|
type ServiceId,
|
|
20
19
|
} from './services.generated.js';
|
|
21
20
|
import {
|
|
@@ -41,7 +40,7 @@ export {
|
|
|
41
40
|
type ApplicationRequirementsAuditReport,
|
|
42
41
|
} from './application-requirements.js';
|
|
43
42
|
|
|
44
|
-
export { SERVICES
|
|
43
|
+
export { SERVICES };
|
|
45
44
|
export type { ServiceId };
|
|
46
45
|
export { APPLICATIONS };
|
|
47
46
|
export type { ApplicationCatalogEntry, ApplicationDeployTarget, ApplicationId };
|
package/src/widgets.test.ts
CHANGED
|
@@ -15,7 +15,7 @@ describe("Topolo widget contract", () => {
|
|
|
15
15
|
|
|
16
16
|
it("stamps service metadata and timestamp onto widget drafts", () => {
|
|
17
17
|
const response = createTopoloWidgetResponse({
|
|
18
|
-
serviceId: "
|
|
18
|
+
serviceId: "service_bytes",
|
|
19
19
|
serviceName: "Bytes",
|
|
20
20
|
now: "2026-04-25T00:00:00.000Z",
|
|
21
21
|
widgets: [
|
|
@@ -30,7 +30,7 @@ describe("Topolo widget contract", () => {
|
|
|
30
30
|
success: true,
|
|
31
31
|
widgets: [
|
|
32
32
|
{
|
|
33
|
-
serviceId: "
|
|
33
|
+
serviceId: "service_bytes",
|
|
34
34
|
serviceName: "Bytes",
|
|
35
35
|
lastUpdated: "2026-04-25T00:00:00.000Z",
|
|
36
36
|
type: "stats",
|
|
@@ -42,12 +42,12 @@ describe("Topolo widget contract", () => {
|
|
|
42
42
|
|
|
43
43
|
it("keeps explicit widget metadata when an app needs multiple service cards", () => {
|
|
44
44
|
const response = createTopoloWidgetResponse({
|
|
45
|
-
serviceId: "
|
|
45
|
+
serviceId: "service_platform",
|
|
46
46
|
serviceName: "Platform",
|
|
47
47
|
now: "2026-04-25T00:00:00.000Z",
|
|
48
48
|
widgets: [
|
|
49
49
|
{
|
|
50
|
-
serviceId: "
|
|
50
|
+
serviceId: "service_crm",
|
|
51
51
|
serviceName: "CRM",
|
|
52
52
|
lastUpdated: "2026-04-24T23:00:00.000Z",
|
|
53
53
|
type: "stats",
|
|
@@ -57,7 +57,7 @@ describe("Topolo widget contract", () => {
|
|
|
57
57
|
});
|
|
58
58
|
|
|
59
59
|
expect(response.widgets[0]).toMatchObject({
|
|
60
|
-
serviceId: "
|
|
60
|
+
serviceId: "service_crm",
|
|
61
61
|
serviceName: "CRM",
|
|
62
62
|
lastUpdated: "2026-04-24T23:00:00.000Z",
|
|
63
63
|
});
|
|
@@ -73,7 +73,7 @@ describe("Topolo widget contract", () => {
|
|
|
73
73
|
|
|
74
74
|
it("validates a compliant response", () => {
|
|
75
75
|
const response = createTopoloWidgetResponse({
|
|
76
|
-
serviceId: "
|
|
76
|
+
serviceId: "service_crm",
|
|
77
77
|
serviceName: "CRM",
|
|
78
78
|
now: "2026-04-25T00:00:00.000Z",
|
|
79
79
|
widgets: [
|
|
@@ -102,7 +102,7 @@ describe("Topolo widget contract", () => {
|
|
|
102
102
|
|
|
103
103
|
it("keeps optional snapshot metadata for configurable TopoloOne datapoints", () => {
|
|
104
104
|
const response = createTopoloWidgetResponse({
|
|
105
|
-
serviceId: "
|
|
105
|
+
serviceId: "service_admin",
|
|
106
106
|
serviceName: "Admin",
|
|
107
107
|
now: "2026-04-28T00:00:00.000Z",
|
|
108
108
|
widgets: [
|