Skip to content

Commit c83402c

Browse files
committed
Address comments and make ProjectId reference optional.
1 parent ca974fb commit c83402c

File tree

6 files changed

+42
-48
lines changed

6 files changed

+42
-48
lines changed

src/crashlytics/getIssueDetails.spec.ts

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,8 @@ chai.use(chaiAsPromised);
1010
const expect = chai.expect;
1111

1212
describe("getIssueDetails", () => {
13-
const projectId = "my-project";
1413
const appId = "1:1234567890:android:abcdef1234567890";
15-
const requestProjectId = "1234567890";
14+
const requestProjectNumber = "1234567890";
1615
const issueId = "test_issue_id";
1716

1817
afterEach(() => {
@@ -23,21 +22,21 @@ describe("getIssueDetails", () => {
2322
const mockResponse = { id: issueId, title: "Crash" };
2423

2524
nock(crashlyticsApiOrigin())
26-
.get(`/v1alpha/projects/${requestProjectId}/apps/${appId}/issues/${issueId}`)
25+
.get(`/v1alpha/projects/${requestProjectNumber}/apps/${appId}/issues/${issueId}`)
2726
.reply(200, mockResponse);
2827

29-
const result = await getIssueDetails(projectId, appId, issueId);
28+
const result = await getIssueDetails(appId, issueId);
3029

3130
expect(result).to.deep.equal(mockResponse);
3231
expect(nock.isDone()).to.be.true;
3332
});
3433

3534
it("should throw a FirebaseError if the API call fails", async () => {
3635
nock(crashlyticsApiOrigin())
37-
.get(`/v1alpha/projects/${requestProjectId}/apps/${appId}/issues/${issueId}`)
36+
.get(`/v1alpha/projects/${requestProjectNumber}/apps/${appId}/issues/${issueId}`)
3837
.reply(500, { error: "Internal Server Error" });
3938

40-
await expect(getIssueDetails(projectId, appId, issueId)).to.be.rejectedWith(
39+
await expect(getIssueDetails(appId, issueId)).to.be.rejectedWith(
4140
FirebaseError,
4241
/Failed to fetch the issue details/,
4342
);
@@ -46,7 +45,7 @@ describe("getIssueDetails", () => {
4645
it("should throw a FirebaseError if the appId is invalid", async () => {
4746
const invalidAppId = "invalid-app-id";
4847

49-
await expect(getIssueDetails(projectId, invalidAppId, issueId)).to.be.rejectedWith(
48+
await expect(getIssueDetails(invalidAppId, issueId)).to.be.rejectedWith(
5049
FirebaseError,
5150
"Unable to get the projectId from the AppId.",
5251
);

src/crashlytics/getIssueDetails.ts

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,10 @@ const apiClient = new Client({
1010
apiVersion: "v1alpha",
1111
});
1212

13-
export async function getIssueDetails(
14-
projectId: string,
15-
appId: string,
16-
issueId: string,
17-
): Promise<string> {
13+
export async function getIssueDetails(appId: string, issueId: string): Promise<string> {
1814
try {
19-
const requestProjectId = parseProjectId(appId);
20-
if (requestProjectId === undefined) {
15+
const requestProjectNumber = parseProjectNumber(appId);
16+
if (requestProjectNumber === undefined) {
2117
throw new FirebaseError("Unable to get the projectId from the AppId.");
2218
}
2319

@@ -26,21 +22,21 @@ export async function getIssueDetails(
2622
headers: {
2723
"Content-Type": "application/json",
2824
},
29-
path: `/projects/${requestProjectId}/apps/${appId}/issues/${issueId}`,
25+
path: `/projects/${requestProjectNumber}/apps/${appId}/issues/${issueId}`,
3026
timeout: TIMEOUT,
3127
});
3228

3329
return response.body;
3430
} catch (err: any) {
3531
logger.debug(err.message);
3632
throw new FirebaseError(
37-
`Failed to fetch the issue details for the Firebase Project ${projectId}, AppId ${appId}, IssueId ${issueId}. Error: ${err}.`,
33+
`Failed to fetch the issue details for the Firebase AppId ${appId}, IssueId ${issueId}. Error: ${err}.`,
3834
{ original: err },
3935
);
4036
}
4137
}
4238

43-
function parseProjectId(appId: string): string | undefined {
39+
function parseProjectNumber(appId: string): string | undefined {
4440
const appIdParts = appId.split(":");
4541
if (appIdParts.length > 1) {
4642
return appIdParts[1];

src/crashlytics/getSampleCrash.spec.ts

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,8 @@ chai.use(chaiAsPromised);
1010
const expect = chai.expect;
1111

1212
describe("getSampleCrash", () => {
13-
const projectId = "my-project";
1413
const appId = "1:1234567890:android:abcdef1234567890";
15-
const requestProjectId = "1234567890";
14+
const requestProjectNumber = "1234567890";
1615
const issueId = "test_issue_id";
1716
const variantId = "test_variant_id";
1817
const sampleCount = 10;
@@ -25,14 +24,14 @@ describe("getSampleCrash", () => {
2524
const mockResponse = { events: [{ event_id: "1" }] };
2625

2726
nock(crashlyticsApiOrigin())
28-
.get(`/v1alpha/projects/${requestProjectId}/apps/${appId}/events`)
27+
.get(`/v1alpha/projects/${requestProjectNumber}/apps/${appId}/events`)
2928
.query({
3029
"filter.issue.id": issueId,
3130
page_size: String(sampleCount),
3231
})
3332
.reply(200, mockResponse);
3433

35-
const result = await getSampleCrash(projectId, appId, issueId, undefined, sampleCount);
34+
const result = await getSampleCrash(appId, issueId, sampleCount, undefined);
3635

3736
expect(result).to.deep.equal(mockResponse);
3837
expect(nock.isDone()).to.be.true;
@@ -42,39 +41,41 @@ describe("getSampleCrash", () => {
4241
const mockResponse = { events: [{ event_id: "1" }] };
4342

4443
nock(crashlyticsApiOrigin())
45-
.get(`/v1alpha/projects/${requestProjectId}/apps/${appId}/events`)
44+
.get(`/v1alpha/projects/${requestProjectNumber}/apps/${appId}/events`)
4645
.query({
4746
"filter.issue.id": issueId,
4847
"filter.issue.variant_id": variantId,
4948
page_size: String(sampleCount),
5049
})
5150
.reply(200, mockResponse);
5251

53-
const result = await getSampleCrash(projectId, appId, issueId, variantId, sampleCount);
52+
const result = await getSampleCrash(appId, issueId, sampleCount, variantId);
5453

5554
expect(result).to.deep.equal(mockResponse);
5655
expect(nock.isDone()).to.be.true;
5756
});
5857

5958
it("should throw a FirebaseError if the API call fails", async () => {
6059
nock(crashlyticsApiOrigin())
61-
.get(`/v1alpha/projects/${requestProjectId}/apps/${appId}/events`)
60+
.get(`/v1alpha/projects/${requestProjectNumber}/apps/${appId}/events`)
6261
.query({
6362
"filter.issue.id": issueId,
6463
page_size: String(sampleCount),
6564
})
6665
.reply(500, { error: "Internal Server Error" });
6766

68-
await expect(
69-
getSampleCrash(projectId, appId, issueId, undefined, sampleCount),
70-
).to.be.rejectedWith(FirebaseError, /Failed to fetch the same crash/);
67+
await expect(getSampleCrash(appId, issueId, sampleCount, undefined)).to.be.rejectedWith(
68+
FirebaseError,
69+
/Failed to fetch the same crash/,
70+
);
7171
});
7272

7373
it("should throw a FirebaseError if the appId is invalid", async () => {
7474
const invalidAppId = "invalid-app-id";
7575

76-
await expect(
77-
getSampleCrash(projectId, invalidAppId, issueId, undefined, sampleCount),
78-
).to.be.rejectedWith(FirebaseError, "Unable to get the projectId from the AppId.");
76+
await expect(getSampleCrash(invalidAppId, issueId, sampleCount, undefined)).to.be.rejectedWith(
77+
FirebaseError,
78+
"Unable to get the projectId from the AppId.",
79+
);
7980
});
8081
});

src/crashlytics/getSampleCrash.ts

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -11,22 +11,21 @@ const apiClient = new Client({
1111
});
1212

1313
export async function getSampleCrash(
14-
projectId: string,
1514
appId: string,
1615
issueId: string,
16+
sampleCount: number,
1717
variantId?: string,
18-
sampleCount?: number,
1918
): Promise<string> {
2019
try {
2120
const queryParams = new URLSearchParams();
22-
queryParams.set("filter.issue.id", `${issueId}`);
23-
queryParams.set("page_size", String(sampleCount!));
21+
queryParams.set("filter.issue.id", issueId);
22+
queryParams.set("page_size", String(sampleCount));
2423
if (variantId) {
25-
queryParams.set("filter.issue.variant_id", `${variantId!}`);
24+
queryParams.set("filter.issue.variant_id", variantId);
2625
}
2726

28-
const requestProjectId = parseProjectId(appId);
29-
if (requestProjectId === undefined) {
27+
const requestProjectNumber = parseProjectNumber(appId);
28+
if (requestProjectNumber === undefined) {
3029
throw new FirebaseError("Unable to get the projectId from the AppId.");
3130
}
3231

@@ -35,7 +34,7 @@ export async function getSampleCrash(
3534
headers: {
3635
"Content-Type": "application/json",
3736
},
38-
path: `/projects/${requestProjectId}/apps/${appId}/events`,
37+
path: `/projects/${requestProjectNumber}/apps/${appId}/events`,
3938
queryParams: queryParams,
4039
timeout: TIMEOUT,
4140
});
@@ -44,13 +43,13 @@ export async function getSampleCrash(
4443
} catch (err: any) {
4544
logger.debug(err.message);
4645
throw new FirebaseError(
47-
`Failed to fetch the same crash for the Firebase Project ${projectId}, AppId ${appId}, IssueId ${issueId}. Error: ${err}.`,
46+
`Failed to fetch the same crash for the Firebase AppId ${appId}, IssueId ${issueId}. Error: ${err}.`,
4847
{ original: err },
4948
);
5049
}
5150
}
5251

53-
function parseProjectId(appId: string): string | undefined {
52+
function parseProjectNumber(appId: string): string | undefined {
5453
const appIdParts = appId.split(":");
5554
if (appIdParts.length > 1) {
5655
return appIdParts[1];

src/mcp/tools/crashlytics/get_issue_details.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ export const get_issue_details = tool(
1111
app_id: z
1212
.string()
1313
.describe(
14-
"AppId for which the issues list should be fetched. For an Android application, read the mobilesdk_app_id value specified in the google-services.json file for the current package name. For an iOS Application, read the GOOGLE_APP_ID from GoogleService-Info.plist. If neither is available, use the `firebase_list_apps` tool to find an app_id to pass to this tool.",
14+
"The AppID for which the issues list should be fetched. For an Android application, read the mobilesdk_app_id value specified in the google-services.json file for the current package name. For an iOS Application, read the GOOGLE_APP_ID from GoogleService-Info.plist. If neither is available, use the `firebase_list_apps` tool to find an app_id to pass to this tool.",
1515
),
1616
issue_id: z
1717
.string()
@@ -25,13 +25,13 @@ export const get_issue_details = tool(
2525
},
2626
_meta: {
2727
requiresAuth: true,
28-
requiresProject: true,
28+
requiresProject: false,
2929
},
3030
},
31-
async ({ app_id, issue_id }, { projectId }) => {
31+
async ({ app_id, issue_id }) => {
3232
if (!app_id) return mcpError(`Must specify 'app_id' parameter.`);
3333
if (!issue_id) return mcpError(`Must specify 'issue_id' parameter.`);
3434

35-
return toContent(await getIssueDetails(projectId, app_id, issue_id));
35+
return toContent(await getIssueDetails(app_id, issue_id));
3636
},
3737
);

src/mcp/tools/crashlytics/get_sample_crash.ts

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ export const get_sample_crash = tool(
2424
.describe("The issue variant Id used as a filter to get sample issues."),
2525
sample_count: z
2626
.number()
27-
.optional()
2827
.describe("Number of samples that needs to be fetched. Maximum value is 3. Defaults to 1.")
2928
.default(1),
3029
}),
@@ -34,15 +33,15 @@ export const get_sample_crash = tool(
3433
},
3534
_meta: {
3635
requiresAuth: true,
37-
requiresProject: true,
36+
requiresProject: false,
3837
},
3938
},
40-
async ({ app_id, issue_id, variant_id, sample_count }, { projectId }) => {
39+
async ({ app_id, issue_id, variant_id, sample_count }) => {
4140
if (!app_id) return mcpError(`Must specify 'app_id' parameter.`);
4241
if (!issue_id) return mcpError(`Must specify 'issue_id' parameter.`);
4342

4443
if (sample_count > 3) sample_count = 3;
4544

46-
return toContent(await getSampleCrash(projectId, app_id, issue_id, variant_id, sample_count));
45+
return toContent(await getSampleCrash(app_id, issue_id, sample_count, variant_id));
4746
},
4847
);

0 commit comments

Comments
 (0)