Skip to content

Commit 2d2cea0

Browse files
Adam Erbsvc-squareup-copybara
authored andcommitted
Minor refactor to web-actions after last set of changes
GitOrigin-RevId: d9d291b132a09b659cae0b93b6cf7182f159c868
1 parent b3b11f7 commit 2d2cea0

21 files changed

+217
-196
lines changed

misk-admin-web-actions/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
"test": " npx jest src",
88
"build": "webpack",
99
"start": "webpack serve --mode development",
10-
"lint": "npx eslint src && npx prettier src --check",
10+
"lint": " tsc --noEmit && npx eslint src && npx prettier src --check",
1111
"format": "npx prettier src --write",
1212
"proxy": "cd development-proxy && npm install && npm run dev"
1313
},

misk-admin-web-actions/src/index.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ import EndpointSelector from '@web-actions/ui/EndpointSelection';
2323
import { ViewState } from 'src/viewState';
2424
import { fetchCached } from '@web-actions/network/http';
2525
import {
26-
ActionGroup,
26+
MiskRoute,
2727
MiskMetadataResponse,
2828
} from '@web-actions/api/responseTypes';
2929
import { createIcon } from '@chakra-ui/icons';
@@ -56,7 +56,7 @@ function App() {
5656
() => requestEditorRef.current?.editor?.getValue() ?? '',
5757
);
5858

59-
useAppEvent(APP_EVENTS.ENDPOINT_SELECTED, (selectedAction: ActionGroup) => {
59+
useAppEvent(APP_EVENTS.ENDPOINT_SELECTED, (selectedAction: MiskRoute) => {
6060
requestEditorRef.current?.setEndpointSelection(selectedAction);
6161

6262
setViewState((curr) => ({
@@ -198,7 +198,7 @@ function App() {
198198
});
199199
}}
200200
/>
201-
{viewState.selectedAction?.canCall === true && (
201+
{viewState.selectedAction?.callable === true && (
202202
<IconButton
203203
aria-label="Run"
204204
colorScheme={'green'}
Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
1-
import {
2-
ActionGroup,
3-
MiskWebActionDefinition,
4-
} from '@web-actions/api/responseTypes';
5-
import { Header } from '@web-actions/services/ApiService';
1+
import { MiskRoute } from '@web-actions/api/responseTypes';
62

73
export interface ViewState {
84
path: string;
9-
selectedAction: ActionGroup | null;
5+
selectedAction: MiskRoute | null;
106
loading: boolean;
117
isHelpOpen: boolean;
128
headers: Header[];
139
}
10+
11+
export interface Header {
12+
key: string;
13+
value: string;
14+
}
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
import {
2+
MiskRoute,
3+
MiskWebActionDefinition,
4+
} from 'src/web-actions/api/responseTypes';
5+
import { MediaTypes } from '@web-actions/api/MediaTypes';
6+
import { parseNull } from '@web-actions/utils/common';
7+
8+
export function buildRoutes(actions: MiskWebActionDefinition[]): MiskRoute[] {
9+
const routeMap: Record<string, MiskRoute> = {};
10+
11+
for (const it of actions) {
12+
const qualifiedName = `${it.packageName}.${it.name}`;
13+
const groupKey = `${it.httpMethod} ${it.pathPattern} ${qualifiedName}`;
14+
let group = routeMap[groupKey];
15+
16+
if (group === undefined) {
17+
group = {
18+
actionName: qualifiedName,
19+
path: it.pathPattern,
20+
httpMethod: it.httpMethod || '',
21+
responseMediaTypes: new MediaTypes(),
22+
requestMediaTypes: new MediaTypes(),
23+
types: it.types,
24+
requestType: it.requestType,
25+
all: [],
26+
};
27+
routeMap[groupKey] = group;
28+
}
29+
group.requestMediaTypes.push(...it.requestMediaTypes);
30+
group.responseMediaTypes.push(it.responseMediaType);
31+
group.all.push({
32+
...it,
33+
requestType: parseNull(it.requestType),
34+
});
35+
}
36+
37+
const routes = Object.values(routeMap);
38+
39+
for (const group of routes) {
40+
if (group.httpMethod === 'GET') {
41+
group.callable = true;
42+
} else if (group.httpMethod === 'PUT' || group.httpMethod === 'POST') {
43+
if (
44+
group.requestMediaTypes.hasJson() ||
45+
group.requestMediaTypes.hasAny() ||
46+
group.requestMediaTypes.isUnspecified()
47+
) {
48+
group.callable = true;
49+
}
50+
}
51+
}
52+
return routes;
53+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
export class MediaTypes {
2+
private readonly types: string[];
3+
4+
constructor(types: string[] = []) {
5+
this.types = types;
6+
}
7+
8+
push(...types: string[]) {
9+
this.types.push(...types);
10+
}
11+
12+
static of(types: string[]): MediaTypes {
13+
return new MediaTypes(types);
14+
}
15+
16+
hasJson(): boolean {
17+
return this.types.some((type) => type.startsWith('application/json'));
18+
}
19+
20+
hasAny(): boolean {
21+
return this.types.some((type) => type.startsWith('*/*'));
22+
}
23+
24+
isUnspecified(): boolean {
25+
return this.types.length === 0;
26+
}
27+
}
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import { MiskActions } from '@web-actions/api/responseTypes';
1+
import { MiskRoute } from '@web-actions/api/responseTypes';
22

33
export default interface MetadataClient {
4-
fetchMetadata(): Promise<MiskActions>;
4+
fetchMetadata(): Promise<MiskRoute[]>;
55
}
Lines changed: 5 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -1,61 +1,15 @@
11
import {
2-
ActionGroup,
3-
MiskActions,
42
MiskMetadataResponse,
5-
MiskWebActionDefinition,
3+
MiskRoute,
64
} from '@web-actions/api/responseTypes';
75
import { fetchCached } from '@web-actions/network/http';
86
import MetadataClient from '@web-actions/api/MetadataClient';
9-
10-
function containsJsonOrAny(mediaType: string[]) {
11-
return (
12-
mediaType.length == 0 ||
13-
mediaType.some((it) => it.startsWith('application/json')) ||
14-
mediaType.some((it) => it.startsWith('*/*'))
15-
);
16-
}
7+
import { buildRoutes } from 'src/web-actions/api/BuildRoutes';
178

189
export default class RealMetadataClient implements MetadataClient {
19-
async fetchMetadata(): Promise<MiskActions> {
20-
const response = await fetchCached<MiskMetadataResponse>(
21-
`/api/web-actions/metadata`,
10+
async fetchMetadata(): Promise<MiskRoute[]> {
11+
return fetchCached<MiskMetadataResponse>(`/api/web-actions/metadata`).then(
12+
(it) => buildRoutes(it.all['web-actions'].metadata),
2213
);
23-
const actionMap: Record<string, ActionGroup> = {};
24-
25-
response.all['web-actions'].metadata.forEach((it) => {
26-
it.requestType = it.requestType === 'null' ? null : it.requestType;
27-
28-
const qualifiedName = `${it.packageName}.${it.name}`;
29-
const groupKey = `${it.httpMethod} ${it.pathPattern} ${qualifiedName}`;
30-
let group = actionMap[groupKey];
31-
32-
if (group === undefined) {
33-
group = {
34-
actionName: qualifiedName,
35-
path: it.pathPattern,
36-
httpMethod: it.httpMethod || '',
37-
callables: [],
38-
all: [],
39-
responseMediaTypes: [],
40-
requestMediaTypes: [],
41-
canCall: false,
42-
types: it.types,
43-
requestType: it.requestType,
44-
};
45-
actionMap[groupKey] = group;
46-
}
47-
48-
if (it.httpMethod === 'GET' || containsJsonOrAny(it.requestMediaTypes)) {
49-
group.canCall = true;
50-
group.callables.push(it);
51-
}
52-
53-
group.requestMediaTypes.push(...it.requestMediaTypes);
54-
group.responseMediaTypes.push(it.responseMediaType);
55-
56-
group.all.push(it);
57-
});
58-
59-
return actionMap;
6014
}
6115
}

misk-admin-web-actions/src/web-actions/api/responseTypes.ts

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import { MediaTypes } from 'src/web-actions/api/MediaTypes';
2+
13
export interface MiskMetadataResponse {
24
all: {
35
'web-actions': {
@@ -28,19 +30,16 @@ export interface MiskFieldDefinition {
2830
annotations: any[];
2931
}
3032

31-
export interface ActionGroup {
33+
export interface MiskRoute {
3234
actionName: string;
3335
path: string;
3436
httpMethod: string;
35-
responseMediaTypes: string[];
36-
requestMediaTypes: string[];
37-
canCall: boolean;
38-
callables: MiskWebActionDefinition[];
37+
responseMediaTypes: MediaTypes;
38+
requestMediaTypes: MediaTypes;
3939
all: MiskWebActionDefinition[];
4040
types: MiskObjectTypes;
4141
requestType: string | null;
42+
callable?: boolean;
4243
}
4344

44-
export type MiskActions = Record<string, ActionGroup>;
45-
4645
export type MiskObjectTypes = Record<string, MiskObjectType>;

misk-admin-web-actions/src/web-actions/completion/CompletionProvider.ts

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,4 @@
1-
import {
2-
ActionGroup,
3-
MiskFieldDefinition,
4-
MiskWebActionDefinition,
5-
} from '@web-actions/api/responseTypes';
1+
import { MiskRoute, MiskFieldDefinition } from '@web-actions/api/responseTypes';
62
import { parseDocument } from '@web-actions/parsing/CommandParser';
73
import Obj from '@web-actions/parsing/ast/Obj';
84
import Field from '@web-actions/parsing/ast/Field';
@@ -24,7 +20,7 @@ interface CompletionArgs {
2420
}
2521

2622
export default class CompletionProvider {
27-
private selection: ActionGroup | null = null;
23+
private selection: MiskRoute | null = null;
2824

2925
private deleteTrailing(editor: Editor, curr: Position, values: string) {
3026
for (const c of values) {
@@ -212,7 +208,7 @@ export default class CompletionProvider {
212208
return [];
213209
}
214210

215-
setSelection(selection: ActionGroup | null) {
211+
setSelection(selection: MiskRoute | null) {
216212
this.selection = selection;
217213
}
218214
}

misk-admin-web-actions/src/web-actions/completion/__test__/CompletionTester.ts

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,8 @@
11
import FakeEditor from '@web-actions/completion/__test__/FakeEditor';
2-
import {
3-
MyAction,
4-
MyActionGroup,
5-
} from '@web-actions/completion/__test__/FakeMetadataClient';
2+
import { MyActionGroup } from '@web-actions/completion/__test__/FakeMetadataClient';
63
import Completion from '@web-actions/completion/Completion';
74
import { providerWithAction } from '@web-actions/completion/__test__/completion.spec';
8-
import {
9-
ActionGroup,
10-
MiskWebActionDefinition,
11-
} from '@web-actions/api/responseTypes';
5+
import { MiskRoute } from '@web-actions/api/responseTypes';
126

137
class CompletionTester {
148
private editor: FakeEditor;
@@ -54,7 +48,7 @@ class CompletionTester {
5448

5549
export function givenEditor(
5650
text: string,
57-
action?: ActionGroup,
51+
action?: MiskRoute,
5852
): CompletionTester {
5953
const editor = new FakeEditor();
6054
editor.completions = providerWithAction(action || MyActionGroup);

0 commit comments

Comments
 (0)