@enactprotocol/api 2.0.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/package.json +34 -0
- package/src/attestations.ts +461 -0
- package/src/auth.ts +293 -0
- package/src/client.ts +349 -0
- package/src/download.ts +298 -0
- package/src/index.ts +109 -0
- package/src/publish.ts +316 -0
- package/src/search.ts +147 -0
- package/src/trust.ts +203 -0
- package/src/types.ts +468 -0
- package/src/utils.ts +86 -0
package/src/search.ts
ADDED
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tool search functionality
|
|
3
|
+
* Implements semantic search via registry API
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import type { EnactApiClient } from "./client";
|
|
7
|
+
import type { ToolSearchResult } from "./types";
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Search options
|
|
11
|
+
*/
|
|
12
|
+
export interface SearchOptions {
|
|
13
|
+
/** Search query (semantic) */
|
|
14
|
+
query: string;
|
|
15
|
+
/** Filter by tags (comma-separated or array) */
|
|
16
|
+
tags?: string | string[] | undefined;
|
|
17
|
+
/** Maximum results (default: 20, max: 100) */
|
|
18
|
+
limit?: number | undefined;
|
|
19
|
+
/** Pagination offset */
|
|
20
|
+
offset?: number | undefined;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Single search result with parsed data (v2)
|
|
25
|
+
*/
|
|
26
|
+
export interface SearchResult {
|
|
27
|
+
/** Tool name */
|
|
28
|
+
name: string;
|
|
29
|
+
/** Tool description */
|
|
30
|
+
description: string;
|
|
31
|
+
/** Tool tags */
|
|
32
|
+
tags: string[];
|
|
33
|
+
/** Latest version */
|
|
34
|
+
version: string;
|
|
35
|
+
/** Author */
|
|
36
|
+
author: {
|
|
37
|
+
username: string;
|
|
38
|
+
avatarUrl?: string | undefined;
|
|
39
|
+
};
|
|
40
|
+
/** Download count */
|
|
41
|
+
downloads: number;
|
|
42
|
+
/** Trust status */
|
|
43
|
+
trustStatus?:
|
|
44
|
+
| {
|
|
45
|
+
auditorCount: number;
|
|
46
|
+
}
|
|
47
|
+
| undefined;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Search response with pagination info
|
|
52
|
+
*/
|
|
53
|
+
export interface SearchResponse {
|
|
54
|
+
/** Search results */
|
|
55
|
+
results: SearchResult[];
|
|
56
|
+
/** Total matching tools */
|
|
57
|
+
total: number;
|
|
58
|
+
/** Results limit used */
|
|
59
|
+
limit: number;
|
|
60
|
+
/** Results offset used */
|
|
61
|
+
offset: number;
|
|
62
|
+
/** Whether more results are available */
|
|
63
|
+
hasMore: boolean;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Raw API search response v2
|
|
68
|
+
*/
|
|
69
|
+
interface RawSearchResponse {
|
|
70
|
+
tools: ToolSearchResult[];
|
|
71
|
+
total: number;
|
|
72
|
+
limit: number;
|
|
73
|
+
offset: number;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Convert raw API result to clean SearchResult
|
|
78
|
+
*/
|
|
79
|
+
function toSearchResult(raw: ToolSearchResult): SearchResult {
|
|
80
|
+
return {
|
|
81
|
+
name: raw.name,
|
|
82
|
+
description: raw.description,
|
|
83
|
+
tags: raw.tags,
|
|
84
|
+
version: raw.version,
|
|
85
|
+
author: {
|
|
86
|
+
username: raw.author.username,
|
|
87
|
+
avatarUrl: raw.author.avatar_url,
|
|
88
|
+
},
|
|
89
|
+
downloads: raw.downloads,
|
|
90
|
+
trustStatus: raw.trust_status
|
|
91
|
+
? {
|
|
92
|
+
auditorCount: raw.trust_status.auditor_count,
|
|
93
|
+
}
|
|
94
|
+
: undefined,
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Search for tools in the registry
|
|
100
|
+
*
|
|
101
|
+
* @param client - API client instance
|
|
102
|
+
* @param options - Search options
|
|
103
|
+
* @returns Search results with pagination
|
|
104
|
+
*
|
|
105
|
+
* @example
|
|
106
|
+
* ```ts
|
|
107
|
+
* const client = createApiClient();
|
|
108
|
+
* const results = await searchTools(client, {
|
|
109
|
+
* query: "pdf extraction",
|
|
110
|
+
* tags: ["ai", "document"],
|
|
111
|
+
* limit: 10
|
|
112
|
+
* });
|
|
113
|
+
* ```
|
|
114
|
+
*/
|
|
115
|
+
export async function searchTools(
|
|
116
|
+
client: EnactApiClient,
|
|
117
|
+
options: SearchOptions
|
|
118
|
+
): Promise<SearchResponse> {
|
|
119
|
+
const params = new URLSearchParams();
|
|
120
|
+
|
|
121
|
+
params.set("q", options.query);
|
|
122
|
+
|
|
123
|
+
if (options.tags) {
|
|
124
|
+
const tagsStr = Array.isArray(options.tags) ? options.tags.join(",") : options.tags;
|
|
125
|
+
params.set("tags", tagsStr);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
if (options.limit !== undefined) {
|
|
129
|
+
params.set("limit", String(Math.min(options.limit, 100)));
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
if (options.offset !== undefined) {
|
|
133
|
+
params.set("offset", String(options.offset));
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
const response = await client.get<RawSearchResponse>(`/tools/search?${params.toString()}`);
|
|
137
|
+
|
|
138
|
+
const results = response.data.tools.map(toSearchResult);
|
|
139
|
+
|
|
140
|
+
return {
|
|
141
|
+
results,
|
|
142
|
+
total: response.data.total,
|
|
143
|
+
limit: response.data.limit,
|
|
144
|
+
offset: response.data.offset,
|
|
145
|
+
hasMore: response.data.offset + results.length < response.data.total,
|
|
146
|
+
};
|
|
147
|
+
}
|
package/src/trust.ts
ADDED
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Trust configuration management (v2)
|
|
3
|
+
* Functions for managing user trust settings
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import type { EnactApiClient } from "./client";
|
|
7
|
+
import type { UpdateTrustConfigRequest, UpdateTrustConfigResponse, UserTrustConfig } from "./types";
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Get a user's trust configuration (v2)
|
|
11
|
+
*
|
|
12
|
+
* This is public information - anyone can see which auditors a user trusts.
|
|
13
|
+
*
|
|
14
|
+
* @param client - API client instance
|
|
15
|
+
* @param username - Username to look up
|
|
16
|
+
* @returns User's trust configuration
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* ```ts
|
|
20
|
+
* const trustConfig = await getUserTrust(client, "alice");
|
|
21
|
+
* console.log(`Alice trusts ${trustConfig.trusted_auditors.length} auditors`);
|
|
22
|
+
* ```
|
|
23
|
+
*/
|
|
24
|
+
export async function getUserTrust(
|
|
25
|
+
client: EnactApiClient,
|
|
26
|
+
username: string
|
|
27
|
+
): Promise<UserTrustConfig> {
|
|
28
|
+
const response = await client.get<UserTrustConfig>(`/users/${username}/trust`);
|
|
29
|
+
return response.data;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Update current user's trust configuration (v2)
|
|
34
|
+
*
|
|
35
|
+
* Replace the entire list of trusted auditors.
|
|
36
|
+
*
|
|
37
|
+
* @param client - API client instance (must be authenticated)
|
|
38
|
+
* @param trustedAuditors - Array of auditor emails to trust
|
|
39
|
+
* @returns Updated trust configuration
|
|
40
|
+
*
|
|
41
|
+
* @example
|
|
42
|
+
* ```ts
|
|
43
|
+
* const updated = await updateMyTrust(client, [
|
|
44
|
+
* "security@example.com",
|
|
45
|
+
* "bob@github.com",
|
|
46
|
+
* "audit-team@company.com"
|
|
47
|
+
* ]);
|
|
48
|
+
* console.log(`Now trusting ${updated.trusted_auditors.length} auditors`);
|
|
49
|
+
* ```
|
|
50
|
+
*/
|
|
51
|
+
export async function updateMyTrust(
|
|
52
|
+
client: EnactApiClient,
|
|
53
|
+
trustedAuditors: string[]
|
|
54
|
+
): Promise<{
|
|
55
|
+
trustedAuditors: Array<{
|
|
56
|
+
identity: string;
|
|
57
|
+
addedAt: Date;
|
|
58
|
+
}>;
|
|
59
|
+
updatedAt: Date;
|
|
60
|
+
}> {
|
|
61
|
+
const response = await client.put<UpdateTrustConfigResponse>("/users/me/trust", {
|
|
62
|
+
trusted_auditors: trustedAuditors,
|
|
63
|
+
} as UpdateTrustConfigRequest);
|
|
64
|
+
|
|
65
|
+
return {
|
|
66
|
+
trustedAuditors: response.data.trusted_auditors.map((ta) => ({
|
|
67
|
+
identity: ta.identity,
|
|
68
|
+
addedAt: new Date(ta.added_at),
|
|
69
|
+
})),
|
|
70
|
+
updatedAt: new Date(response.data.updated_at),
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Add an auditor to the current user's trust list
|
|
76
|
+
*
|
|
77
|
+
* This is a convenience wrapper that fetches current trust config,
|
|
78
|
+
* adds the auditor if not already present, and updates.
|
|
79
|
+
*
|
|
80
|
+
* @param client - API client instance (must be authenticated)
|
|
81
|
+
* @param auditorEmail - Auditor email to trust
|
|
82
|
+
* @returns Updated trust configuration
|
|
83
|
+
*
|
|
84
|
+
* @example
|
|
85
|
+
* ```ts
|
|
86
|
+
* await addTrustedAuditor(client, "new-auditor@example.com");
|
|
87
|
+
* ```
|
|
88
|
+
*/
|
|
89
|
+
export async function addTrustedAuditor(
|
|
90
|
+
client: EnactApiClient,
|
|
91
|
+
auditorEmail: string
|
|
92
|
+
): Promise<{
|
|
93
|
+
trustedAuditors: Array<{
|
|
94
|
+
identity: string;
|
|
95
|
+
addedAt: Date;
|
|
96
|
+
}>;
|
|
97
|
+
updatedAt: Date;
|
|
98
|
+
}> {
|
|
99
|
+
// First get current user to know their username
|
|
100
|
+
const currentUser = await client.get<{ username: string }>("/auth/me");
|
|
101
|
+
const username = currentUser.data.username;
|
|
102
|
+
|
|
103
|
+
// Get current trust config
|
|
104
|
+
const currentTrust = await getUserTrust(client, username);
|
|
105
|
+
|
|
106
|
+
// Add new auditor if not already present
|
|
107
|
+
const currentAuditors = currentTrust.trusted_auditors.map((ta) => ta.identity);
|
|
108
|
+
if (!currentAuditors.includes(auditorEmail)) {
|
|
109
|
+
currentAuditors.push(auditorEmail);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// Update trust config
|
|
113
|
+
return updateMyTrust(client, currentAuditors);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Remove an auditor from the current user's trust list
|
|
118
|
+
*
|
|
119
|
+
* This is a convenience wrapper that fetches current trust config,
|
|
120
|
+
* removes the auditor if present, and updates.
|
|
121
|
+
*
|
|
122
|
+
* @param client - API client instance (must be authenticated)
|
|
123
|
+
* @param auditorEmail - Auditor email to remove
|
|
124
|
+
* @returns Updated trust configuration
|
|
125
|
+
*
|
|
126
|
+
* @example
|
|
127
|
+
* ```ts
|
|
128
|
+
* await removeTrustedAuditor(client, "old-auditor@example.com");
|
|
129
|
+
* ```
|
|
130
|
+
*/
|
|
131
|
+
export async function removeTrustedAuditor(
|
|
132
|
+
client: EnactApiClient,
|
|
133
|
+
auditorEmail: string
|
|
134
|
+
): Promise<{
|
|
135
|
+
trustedAuditors: Array<{
|
|
136
|
+
identity: string;
|
|
137
|
+
addedAt: Date;
|
|
138
|
+
}>;
|
|
139
|
+
updatedAt: Date;
|
|
140
|
+
}> {
|
|
141
|
+
// First get current user to know their username
|
|
142
|
+
const currentUser = await client.get<{ username: string }>("/auth/me");
|
|
143
|
+
const username = currentUser.data.username;
|
|
144
|
+
|
|
145
|
+
// Get current trust config
|
|
146
|
+
const currentTrust = await getUserTrust(client, username);
|
|
147
|
+
|
|
148
|
+
// Remove auditor
|
|
149
|
+
const updatedAuditors = currentTrust.trusted_auditors
|
|
150
|
+
.map((ta) => ta.identity)
|
|
151
|
+
.filter((email) => email !== auditorEmail);
|
|
152
|
+
|
|
153
|
+
// Update trust config
|
|
154
|
+
return updateMyTrust(client, updatedAuditors);
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* Check if a user trusts a specific auditor
|
|
159
|
+
*
|
|
160
|
+
* @param client - API client instance
|
|
161
|
+
* @param username - Username to check
|
|
162
|
+
* @param auditorEmail - Auditor email to check
|
|
163
|
+
* @returns True if the user trusts this auditor
|
|
164
|
+
*
|
|
165
|
+
* @example
|
|
166
|
+
* ```ts
|
|
167
|
+
* const trusts = await userTrustsAuditor(client, "alice", "security@example.com");
|
|
168
|
+
* if (trusts) {
|
|
169
|
+
* console.log("Alice trusts this auditor");
|
|
170
|
+
* }
|
|
171
|
+
* ```
|
|
172
|
+
*/
|
|
173
|
+
export async function userTrustsAuditor(
|
|
174
|
+
client: EnactApiClient,
|
|
175
|
+
username: string,
|
|
176
|
+
auditorEmail: string
|
|
177
|
+
): Promise<boolean> {
|
|
178
|
+
const trustConfig = await getUserTrust(client, username);
|
|
179
|
+
return trustConfig.trusted_auditors.some((ta) => ta.identity === auditorEmail);
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
/**
|
|
183
|
+
* Get list of auditors trusted by the current user
|
|
184
|
+
*
|
|
185
|
+
* @param client - API client instance (must be authenticated)
|
|
186
|
+
* @returns Array of trusted auditor emails
|
|
187
|
+
*
|
|
188
|
+
* @example
|
|
189
|
+
* ```ts
|
|
190
|
+
* const auditors = await getMyTrustedAuditors(client);
|
|
191
|
+
* console.log(`You trust: ${auditors.join(", ")}`);
|
|
192
|
+
* ```
|
|
193
|
+
*/
|
|
194
|
+
export async function getMyTrustedAuditors(client: EnactApiClient): Promise<string[]> {
|
|
195
|
+
// First get current user to know their username
|
|
196
|
+
const currentUser = await client.get<{ username: string }>("/auth/me");
|
|
197
|
+
const username = currentUser.data.username;
|
|
198
|
+
|
|
199
|
+
// Get trust config
|
|
200
|
+
const trustConfig = await getUserTrust(client, username);
|
|
201
|
+
|
|
202
|
+
return trustConfig.trusted_auditors.map((ta) => ta.identity);
|
|
203
|
+
}
|