Skip to content

Commit 5dda196

Browse files
authored
Merge pull request #509 from DanielMicrosoft/34561023-exploring-refactoring-opportunities
[Refactor]: add api clients and refactor components
2 parents baf225e + 8b19085 commit 5dda196

15 files changed

+836
-691
lines changed

src/web/src/services/cliApi.ts

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
import axios from "axios";
2+
3+
export const cliApi = {
4+
getCliProfiles: async (): Promise<string[]> => {
5+
const res = await axios.get(`/CLI/Az/Profiles`);
6+
return res.data;
7+
},
8+
9+
getCliModules: async (repoName: string): Promise<any[]> => {
10+
const res = await axios.get(`/CLI/Az/${repoName}/Modules`);
11+
return res.data;
12+
},
13+
14+
createCliModule: async (repoName: string, moduleName: string): Promise<any> => {
15+
const res = await axios.post(`/CLI/Az/${repoName}/Modules`, { name: moduleName });
16+
return res.data;
17+
},
18+
19+
getCliModule: async (repoName: string, moduleName: string): Promise<any> => {
20+
const res = await axios.get(`/CLI/Az/${repoName}/Modules/${moduleName}`);
21+
return res.data;
22+
},
23+
24+
getSpecsCommand: async (names: string[]): Promise<any> => {
25+
const res = await axios.get(
26+
`/AAZ/Specs/CommandTree/Nodes/aaz/${names.slice(0, -1).join("/")}/Leaves/${names[names.length - 1]}`,
27+
);
28+
return res.data;
29+
},
30+
31+
retrieveCommands: async (namesList: string[][]): Promise<any[]> => {
32+
const namesListData = namesList.map((names) => ["aaz", ...names]);
33+
const res = await axios.post(`/AAZ/Specs/CommandTree/Nodes/Leaves`, namesListData);
34+
return res.data;
35+
},
36+
37+
getSimpleCommandTree: async (): Promise<any> => {
38+
const res = await axios.get(`/AAZ/Specs/CommandTree/Simple`);
39+
return res.data;
40+
},
41+
42+
updateCliModule: async (repoName: string, moduleName: string, data: any): Promise<void> => {
43+
await axios.put(`/CLI/Az/${repoName}/Modules/${moduleName}`, data);
44+
},
45+
46+
patchCliModule: async (repoName: string, moduleName: string, data: any): Promise<void> => {
47+
await axios.patch(`/CLI/Az/${repoName}/Modules/${moduleName}`, data);
48+
},
49+
} as const;

src/web/src/services/commandApi.ts

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
import axios from "axios";
2+
3+
export const commandApi = {
4+
getCommand: async (leafUrl: string): Promise<any> => {
5+
const res = await axios.get(leafUrl);
6+
return res.data;
7+
},
8+
9+
getCommandsForResource: async (resourceUrl: string): Promise<any[]> => {
10+
const res = await axios.get(`${resourceUrl}/Commands`);
11+
return res.data;
12+
},
13+
14+
deleteResource: async (resourceUrl: string): Promise<void> => {
15+
await axios.delete(resourceUrl);
16+
},
17+
18+
updateCommand: async (leafUrl: string, data: any): Promise<any> => {
19+
const res = await axios.patch(leafUrl, data);
20+
return res.data;
21+
},
22+
23+
renameCommand: async (leafUrl: string, newName: string): Promise<any> => {
24+
const res = await axios.post(`${leafUrl}/Rename`, { name: newName });
25+
return res.data;
26+
},
27+
28+
updateCommandExamples: async (leafUrl: string, examples: any[]): Promise<any> => {
29+
const res = await axios.patch(leafUrl, { examples });
30+
return res.data;
31+
},
32+
33+
generateSwaggerExamples: async (leafUrl: string): Promise<any[]> => {
34+
const res = await axios.post(`${leafUrl}/GenerateExamples`, { source: "swagger" });
35+
return res.data.map((v: any) => ({
36+
name: v.name,
37+
commands: v.commands,
38+
}));
39+
},
40+
41+
addSubcommands: async (resourceUrl: string, data: any): Promise<void> => {
42+
await axios.post(resourceUrl, data);
43+
},
44+
45+
updateCommandOutputs: async (leafUrl: string, outputs: any[]): Promise<any> => {
46+
const res = await axios.patch(leafUrl, { outputs });
47+
return res.data;
48+
},
49+
50+
updateCommandArgument: async (argumentUrl: string, data: any): Promise<void> => {
51+
await axios.patch(argumentUrl, data);
52+
},
53+
54+
updateArgumentById: async (argId: string, data: any): Promise<void> => {
55+
await axios.patch(argId, data);
56+
},
57+
58+
flattenArgument: async (flattenUrl: string, data?: any): Promise<void> => {
59+
if (data) {
60+
await axios.post(flattenUrl, data);
61+
} else {
62+
await axios.post(flattenUrl);
63+
}
64+
},
65+
66+
unwrapClassArgument: async (flattenUrl: string): Promise<void> => {
67+
await axios.post(flattenUrl);
68+
},
69+
70+
deleteCommandGroup: async (nodeUrl: string): Promise<void> => {
71+
await axios.delete(nodeUrl);
72+
},
73+
74+
updateCommandGroup: async (
75+
nodeUrl: string,
76+
data: { help: { short: string; lines: string[] }; stage: string },
77+
): Promise<any> => {
78+
const res = await axios.patch(nodeUrl, data);
79+
return res.data;
80+
},
81+
82+
renameCommandGroup: async (nodeUrl: string, name: string): Promise<any> => {
83+
const res = await axios.post(`${nodeUrl}/Rename`, { name });
84+
return res.data;
85+
},
86+
87+
findSimilarArguments: async (commandUrl: string, argVar: string): Promise<any> => {
88+
const similarUrl = `${commandUrl}/Arguments/${argVar}/FindSimilar`;
89+
const res = await axios.post(similarUrl);
90+
return res.data;
91+
},
92+
93+
createSubresource: async (
94+
subresourceUrl: string,
95+
data: {
96+
commandGroupName: string;
97+
refArgsOptions: { [argVar: string]: string[] };
98+
arg: string;
99+
},
100+
): Promise<any> => {
101+
const response = await axios.post(subresourceUrl, data);
102+
return response.data;
103+
},
104+
} as const;
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
export const errorHandlerApi = {
2+
getErrorMessage: (err: any): string => {
3+
console.log("err: ", err);
4+
5+
if (err.response?.data?.message) {
6+
const data = err.response.data;
7+
const details = data.details ? `: ${JSON.stringify(data.details)}` : "";
8+
return `ResponseError: ${data.message}${details}`;
9+
}
10+
11+
if (err instanceof Error && err.message) {
12+
return err.message;
13+
}
14+
15+
if (err && typeof err === "object" && err.message) {
16+
return err.message;
17+
}
18+
19+
if (typeof err === "string") {
20+
return err;
21+
}
22+
23+
return "An unexpected error occurred";
24+
},
25+
26+
isHttpError: (err: any, statusCode: number): boolean => {
27+
return err.response?.status === statusCode;
28+
},
29+
} as const;

src/web/src/services/index.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
export { workspaceApi, type Workspace, type CreateWorkspaceData, type ClientConfig } from "./workspaceApi";
2+
export { specsApi, specsHelper, type Plane, type Resource } from "./specsApi";
3+
export { commandApi } from "./commandApi";
4+
export { errorHandlerApi } from "./errorHandlerApi";
5+
export { cliApi } from "./cliApi";

src/web/src/services/specsApi.ts

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
import axios from "axios";
2+
3+
export interface Plane {
4+
name: string;
5+
displayName: string;
6+
moduleOptions?: string[];
7+
}
8+
9+
export interface Resource {
10+
id: string;
11+
version: string;
12+
}
13+
14+
export const specsApi = {
15+
getPlanes: async (): Promise<Plane[]> => {
16+
const res = await axios.get(`/AAZ/Specs/Planes`);
17+
return res.data.map((v: any) => ({
18+
name: v.name,
19+
displayName: v.displayName,
20+
moduleOptions: undefined,
21+
}));
22+
},
23+
24+
getPlaneNames: async (): Promise<string[]> => {
25+
const res = await axios.get(`/AAZ/Specs/Planes`);
26+
return res.data.map((v: any) => v.name);
27+
},
28+
29+
getModulesForPlane: async (planeName: string): Promise<string[]> => {
30+
const res = await axios.get(`/Swagger/Specs/${planeName}`);
31+
return res.data.map((v: any) => v.url);
32+
},
33+
34+
getResourceProviders: async (moduleUrl: string): Promise<string[]> => {
35+
const res = await axios.get(`${moduleUrl}/ResourceProviders`);
36+
return res.data.map((v: any) => v.url);
37+
},
38+
39+
getResources: async (resourceProviderUrl: string): Promise<Resource[]> => {
40+
const res = await axios.get(`${resourceProviderUrl}/Resources`);
41+
return res.data;
42+
},
43+
44+
getSwaggerModules: async (plane: string): Promise<string[]> => {
45+
const res = await axios.get(`/Swagger/Specs/${plane}`);
46+
return res.data.map((v: any) => v.url);
47+
},
48+
49+
getResourceProvidersWithType: async (moduleUrl: string, type?: string): Promise<string[]> => {
50+
let url = `${moduleUrl}/ResourceProviders`;
51+
if (type) {
52+
url += `?type=${type}`;
53+
}
54+
const res = await axios.get(url);
55+
return res.data.map((v: any) => v.url);
56+
},
57+
58+
getProviderResources: async (resourceProviderUrl: string): Promise<any> => {
59+
const res = await axios.get(`${resourceProviderUrl}/Resources`);
60+
return res.data;
61+
},
62+
63+
filterResourcesByPlane: async (plane: string, resourceIds: string[]): Promise<any> => {
64+
const filterBody = { resources: resourceIds };
65+
const res = await axios.post(`/AAZ/Specs/Resources/${plane}/Filter`, filterBody);
66+
return res.data;
67+
},
68+
} as const;
69+
70+
export const specsHelper = {
71+
removeCommonPrefix: (options: string[], prefix: string): string[] => {
72+
return options.map((option) => option.replace(prefix, ""));
73+
},
74+
75+
isClientConfigurablePlane: async (planeName: string): Promise<boolean> => {
76+
const planeNames = await specsApi.getPlaneNames();
77+
return !planeNames.includes(planeName);
78+
},
79+
80+
buildResourceProviderUrl: (plane: string, modNames: string[], rpName: string, source: string): string => {
81+
const basePath = `/Swagger/Specs/${plane}/${modNames.join("/")}`;
82+
const resourceProviderPath = `/ResourceProviders/${rpName}`;
83+
const suffix = source.toLowerCase() === "typespec" ? "/TypeSpec" : "";
84+
return `${basePath}${resourceProviderPath}${suffix}`;
85+
},
86+
} as const;

0 commit comments

Comments
 (0)