Skip to content

Commit 1c36da7

Browse files
chore: only auth once, show errors for everything in deploy
1 parent 4a535f2 commit 1c36da7

File tree

2 files changed

+51
-46
lines changed

2 files changed

+51
-46
lines changed

src/client/metadataApiDeploy.ts

Lines changed: 49 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -210,7 +210,38 @@ export class MetadataApiDeploy extends MetadataTransfer<
210210
const aabComponents = this.options.components.getAiAuthoringBundles().toArray();
211211

212212
if (aabComponents.length > 0) {
213-
await Promise.all(
213+
// we need to use a namedJWT connection for this request
214+
const { accessToken, instanceUrl } = connection.getConnectionOptions();
215+
if (!instanceUrl) {
216+
throw SfError.create({
217+
name: 'ApiAccessError',
218+
message: 'Missing Instance URL for org connection',
219+
});
220+
}
221+
if (!accessToken) {
222+
throw SfError.create({
223+
name: 'ApiAccessError',
224+
message: 'Missing Access Token for org connection',
225+
});
226+
}
227+
const url = `${instanceUrl}/agentforce/bootstrap/nameduser`;
228+
// For the namdeduser endpoint request to work we need to delete the access token
229+
delete connection.accessToken;
230+
const response = await connection.request<{
231+
access_token: string;
232+
}>(
233+
{
234+
method: 'GET',
235+
url,
236+
headers: {
237+
'Content-Type': 'application/json',
238+
Cookie: `sid=${accessToken}`,
239+
},
240+
},
241+
{ retry: { maxRetries: 3 } }
242+
);
243+
connection.accessToken = response.access_token;
244+
const results = await Promise.all(
214245
aabComponents.map(async (aab) => {
215246
// aab.content points to a directory, we need to find the .agent file and read it
216247
if (!aab.content) {
@@ -229,38 +260,6 @@ export class MetadataApiDeploy extends MetadataTransfer<
229260

230261
const agentContent = await fs.promises.readFile(contentPath, 'utf-8');
231262

232-
// we need to use a namedJWT connection for this request
233-
const { accessToken, instanceUrl } = connection.getConnectionOptions();
234-
if (!instanceUrl) {
235-
throw SfError.create({
236-
name: 'ApiAccessError',
237-
message: 'Missing Instance URL for org connection',
238-
});
239-
}
240-
if (!accessToken) {
241-
throw SfError.create({
242-
name: 'ApiAccessError',
243-
message: 'Missing Access Token for org connection',
244-
});
245-
}
246-
const url = `${instanceUrl}/agentforce/bootstrap/nameduser`;
247-
// For the namdeduser endpoint request to work we need to delete the access token
248-
delete connection.accessToken;
249-
const response = await connection.request<{
250-
access_token: string;
251-
}>(
252-
{
253-
method: 'GET',
254-
url,
255-
headers: {
256-
'Content-Type': 'application/json',
257-
Cookie: `sid=${accessToken}`,
258-
},
259-
},
260-
{ retry: { maxRetries: 3 } }
261-
);
262-
connection.accessToken = response.access_token;
263-
264263
// to avoid circular dependencies between libraries, just call the compile endpoint here
265264
const result = await connection.request<{
266265
// minimal typings here, more is returned, just using what we need
@@ -270,6 +269,8 @@ export class MetadataApiDeploy extends MetadataTransfer<
270269
lineStart: number;
271270
colStart: number;
272271
}>;
272+
// name added here for post-processing convenience
273+
name: string;
273274
}>({
274275
method: 'POST',
275276
// this will need to be api.salesforce once changes are in prod
@@ -289,19 +290,23 @@ export class MetadataApiDeploy extends MetadataTransfer<
289290
afScriptVersion: '1.0.1',
290291
}),
291292
});
292-
293-
if (result.status === 'failure') {
294-
throw SfError.create({
295-
message: `${EOL}${
296-
result.errors
297-
.map((e) => `${aab.name}.agent: ${e.description} ${e.lineStart}:${e.colStart}`)
298-
.join(EOL) ?? ''
299-
}`,
300-
name: 'AgentCompilationError',
301-
});
302-
}
293+
result.name = aab.name;
294+
return result;
303295
})
304296
);
297+
298+
const errors = results
299+
.filter((result) => result.status === 'failure')
300+
.map((result) =>
301+
result.errors.map((r) => `${result.name}.agent: ${r.description} ${r.lineStart}:${r.colStart}`).join(EOL)
302+
);
303+
304+
if (errors.length > 0) {
305+
throw SfError.create({
306+
message: `${EOL}${errors.join(EOL)}`,
307+
name: 'AgentCompilationError',
308+
});
309+
}
305310
}
306311
}
307312
// only do event hooks if source, (NOT a metadata format) deploy

test/client/metadataApiDeploy.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1514,8 +1514,8 @@ describe('MetadataApiDeploy', () => {
15141514

15151515
// Should read both agent files
15161516
expect(readFileStub.callCount).to.equal(2);
1517-
// Should call compile endpoint twice (once per AAB) and nameduser twice
1518-
expect(namedUserCallCount).to.equal(2);
1517+
// Should call compile endpoint twice (once per AAB) and nameduser once
1518+
expect(namedUserCallCount).to.equal(1);
15191519
expect(compileCallCount).to.equal(2);
15201520
});
15211521
});

0 commit comments

Comments
 (0)