Skip to content

Commit 2900550

Browse files
authored
fix(OS response): Fixed issue with http response format on different OS (#57)
1 parent f5eab50 commit 2900550

File tree

2 files changed

+88
-42
lines changed

2 files changed

+88
-42
lines changed

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
IMAGE?=localstack/localstack-docker-desktop
2-
TAG?=0.5.4
2+
TAG?=0.5.5
33

44
BUILDER=buildx-multi-arch
55

ui/src/services/hooks/api.ts

Lines changed: 87 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,53 @@
11
import useSWR from 'swr';
2-
import { STORAGE_KEY_ENVVARS, STORAGE_KEY_LOCALSTACK, STORAGE_KEY_MOUNT } from '../../constants';
3-
import { ConfigData, DockerContainer, mountPointData, RunConfig } from '../../types';
2+
import {
3+
STORAGE_KEY_ENVVARS,
4+
STORAGE_KEY_LOCALSTACK,
5+
STORAGE_KEY_MOUNT,
6+
} from '../../constants';
7+
import {
8+
ConfigData,
9+
DockerContainer,
10+
mountPointData,
11+
RunConfig,
12+
} from '../../types';
413
import { isALocalStackContainer, isJson } from '../util';
514
import { useDDClient } from './utils';
615

716
interface useRunConfigsReturn {
8-
configData: ConfigData,
9-
isLoading: boolean,
17+
configData: ConfigData;
18+
isLoading: boolean;
1019
setRunningConfig: (data: string) => unknown;
1120
createConfig: (data: RunConfig) => unknown;
1221
updateConfig: (data: RunConfig) => unknown;
1322
deleteConfig: (data: string) => unknown;
1423
}
1524

16-
interface HTTPMessage {
17-
data: {
18-
Message: string,
19-
},
20-
}
25+
// This is what backend calls send in MacOS
26+
type BaseMessage = {
27+
Message: string;
28+
};
29+
30+
// This is what backend calls send on Linux
31+
type LinuxMessage = {
32+
data: BaseMessage;
33+
};
34+
35+
type HTTPMessage = LinuxMessage | BaseMessage;
36+
37+
const isBaseMessage = (msg: HTTPMessage): msg is BaseMessage => (msg as BaseMessage).Message !== undefined;
38+
39+
const resolveOSMessage = (message: HTTPMessage | undefined): BaseMessage | undefined => {
40+
if (!message) return undefined;
41+
if (isBaseMessage(message)) return message;
42+
return message.data;
43+
};
2144

2245
const adaptVersionData = (message: HTTPMessage, error: Error) => {
23-
const newData = (!message || !message.data?.Message || error) ?
24-
{ configs: [], runningConfig: null }
25-
:
26-
JSON.parse(message.data?.Message);
46+
const data = resolveOSMessage(message);
47+
const newData =
48+
!data || !data?.Message || error
49+
? { configs: [], runningConfig: null }
50+
: JSON.parse(data?.Message);
2751
if (Array.isArray(newData)) {
2852
return { configs: newData, runningConfig: newData.at(0).id ?? null };
2953
}
@@ -35,21 +59,27 @@ export const useRunConfigs = (): useRunConfigsReturn => {
3559
const { client: ddClient } = useDDClient();
3660
const { data, mutate, isValidating, error } = useSWR(
3761
cacheKey,
38-
() => (ddClient.extension.vm.service.get('/configs') as Promise<HTTPMessage>),
62+
() => ddClient.extension.vm.service.get('/configs') as Promise<HTTPMessage>,
3963
);
4064

4165
const updateConfig = async (newData: RunConfig) => {
42-
await ddClient.extension.vm.service.put('/configs', { Data: JSON.stringify(newData) });
66+
await ddClient.extension.vm.service.put('/configs', {
67+
Data: JSON.stringify(newData),
68+
});
4369
mutate();
4470
};
4571

4672
const setRunningConfig = async (configId: string) => {
47-
await ddClient.extension.vm.service.put('/configs/running', { Data: JSON.stringify(configId) });
73+
await ddClient.extension.vm.service.put('/configs/running', {
74+
Data: JSON.stringify(configId),
75+
});
4876
mutate();
4977
};
5078

5179
const createConfig = async (newData: RunConfig) => {
52-
await ddClient.extension.vm.service.post('/configs', { Data: JSON.stringify(newData) });
80+
await ddClient.extension.vm.service.post('/configs', {
81+
Data: JSON.stringify(newData),
82+
});
5383
mutate();
5484
};
5585

@@ -58,7 +88,6 @@ export const useRunConfigs = (): useRunConfigsReturn => {
5888
mutate();
5989
};
6090

61-
6291
return {
6392
configData: adaptVersionData(data, error),
6493
isLoading: isValidating || (!error && !data),
@@ -70,12 +99,12 @@ export const useRunConfigs = (): useRunConfigsReturn => {
7099
};
71100

72101
interface useMountPointReturn {
73-
user: string | null,
74-
os: string | null,
75-
showForm: boolean,
76-
showSetupWarning: boolean,
77-
hasSkippedConfiguration: boolean,
78-
isLoading: boolean,
102+
user: string | null;
103+
os: string | null;
104+
showForm: boolean;
105+
showSetupWarning: boolean;
106+
hasSkippedConfiguration: boolean;
107+
isLoading: boolean;
79108
setMountPointData: (data: mountPointData) => void;
80109
}
81110

@@ -85,30 +114,41 @@ export const useMountPoint = (): useMountPointReturn => {
85114

86115
const { data, mutate, isValidating, error } = useSWR(
87116
cacheKey,
88-
async () => (ddClient.extension.vm.service.get('/mount') as Promise<HTTPMessage>),
117+
async () =>
118+
ddClient.extension.vm.service.get('/mount') as Promise<HTTPMessage>,
89119
);
90120

91121
const setMountPointData = async (data: mountPointData) => {
92-
await ddClient.extension.vm.service.post('/mount', { Data: JSON.stringify(data) });
122+
await ddClient.extension.vm.service.post('/mount', {
123+
Data: JSON.stringify(data),
124+
});
93125
mutate();
94126
};
95127

96-
const fileContent = (!error && data) ? data.data.Message : null;
97-
const mountPointData = isJson(fileContent) ? JSON.parse(fileContent) as mountPointData : null;
128+
const adaptedData = resolveOSMessage(data);
129+
130+
const fileContent = !error && adaptedData ? adaptedData.Message : null;
131+
const mountPointData = isJson(fileContent)
132+
? (JSON.parse(fileContent) as mountPointData)
133+
: null;
98134

99135
return {
100136
user: mountPointData?.user,
101137
os: mountPointData?.os,
102-
showForm: mountPointData?.showForm == null ? true : mountPointData?.showForm,
103-
showSetupWarning: mountPointData?.showSetupWarning == null ? true : mountPointData?.showSetupWarning,
138+
showForm:
139+
mountPointData?.showForm == null ? true : mountPointData?.showForm,
140+
showSetupWarning:
141+
mountPointData?.showSetupWarning == null
142+
? true
143+
: mountPointData?.showSetupWarning,
104144
hasSkippedConfiguration: mountPointData?.hasSkippedConfiguration || false,
105-
isLoading: isValidating || (!error && !data),
145+
isLoading: isValidating || (!error && !adaptedData),
106146
setMountPointData,
107147
};
108148
};
109149

110150
interface useLocalStackReturn {
111-
data: DockerContainer | null,
151+
data: DockerContainer | null;
112152
mutate: () => void;
113153
}
114154

@@ -118,15 +158,21 @@ export const useLocalStack = (): useLocalStackReturn => {
118158

119159
const { data, mutate } = useSWR(
120160
cacheKey,
121-
async () => (await ddClient.docker.listContainers() as [DockerContainer])
122-
.find(container =>
123-
isALocalStackContainer(container) && container.Command !== 'bin/localstack update docker-images',
124-
), {
125-
refreshInterval: 2000, compare:
126-
/*
127-
* compares whether the old (b) status aligns with that of new (a) status
128-
*/
129-
(a, b) => a?.Id === b?.Id && a?.Status.includes('unhealthy') === b?.Status.includes('unhealthy'),
161+
async () =>
162+
((await ddClient.docker.listContainers()) as [DockerContainer]).find(
163+
(container) =>
164+
isALocalStackContainer(container) &&
165+
container.Command !== 'bin/localstack update docker-images',
166+
),
167+
{
168+
refreshInterval: 2000,
169+
compare:
170+
/*
171+
* compares whether the old (b) status aligns with that of new (a) status
172+
*/
173+
(a, b) =>
174+
a?.Id === b?.Id &&
175+
a?.Status.includes('unhealthy') === b?.Status.includes('unhealthy'),
130176
},
131177
);
132178

0 commit comments

Comments
 (0)