Skip to content

Commit 54fa1e0

Browse files
committed
fixes sonarqube issues
1 parent f6b50bc commit 54fa1e0

4 files changed

Lines changed: 134 additions & 105 deletions

File tree

packages/react-native/src/lib/user/update-queue.ts

Lines changed: 89 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,74 @@ export class UpdateQueue {
6565
return !this.updates;
6666
}
6767

68+
private handleLanguageWithoutUserId(
69+
currentUpdates: Partial<TUpdates> & { attributes?: TAttributes },
70+
config: RNConfig
71+
): Partial<TUpdates> & { attributes?: TAttributes } {
72+
if (!currentUpdates.attributes?.language) {
73+
return currentUpdates;
74+
}
75+
76+
// Update language in local config
77+
config.update({
78+
...config.get(),
79+
user: {
80+
...config.get().user,
81+
data: {
82+
...config.get().user.data,
83+
language: currentUpdates.attributes.language,
84+
},
85+
},
86+
});
87+
88+
logger.debug("Updated language successfully");
89+
90+
// Remove language from attributes
91+
const { language: _, ...remainingAttributes } = currentUpdates.attributes;
92+
return {
93+
...currentUpdates,
94+
attributes: remainingAttributes,
95+
};
96+
}
97+
98+
private validateAttributesWithUserId(
99+
currentUpdates: Partial<TUpdates> & { attributes?: TAttributes },
100+
effectiveUserId: string | null | undefined
101+
): void {
102+
const hasAttributes =
103+
Object.keys(currentUpdates.attributes ?? {}).length > 0;
104+
105+
if (hasAttributes && !effectiveUserId) {
106+
const errorMessage =
107+
"Formbricks can't set attributes without a userId! Please set a userId first with the setUserId function";
108+
logger.error(errorMessage);
109+
this.clearUpdates();
110+
throw new Error(errorMessage);
111+
}
112+
}
113+
114+
private async sendUpdatesIfNeeded(
115+
effectiveUserId: string | null | undefined,
116+
currentUpdates: Partial<TUpdates> & { attributes?: TAttributes }
117+
): Promise<void> {
118+
if (!effectiveUserId) {
119+
return;
120+
}
121+
122+
const result = await sendUpdates({
123+
updates: {
124+
userId: effectiveUserId,
125+
attributes: currentUpdates.attributes ?? {},
126+
},
127+
});
128+
129+
if (result.ok) {
130+
logger.debug("Updates sent successfully");
131+
} else {
132+
logger.error("Failed to send updates");
133+
}
134+
}
135+
68136
public async processUpdates(): Promise<void> {
69137
if (!this.updates) {
70138
return;
@@ -80,66 +148,29 @@ export class UpdateQueue {
80148
let currentUpdates = { ...this.updates };
81149
const config = await RNConfig.getInstance();
82150

83-
if (Object.keys(currentUpdates).length > 0) {
84-
// Get userId from either updates or config
85-
const effectiveUserId =
86-
currentUpdates.userId ?? config.get().user.data.userId;
87-
const isLanguageInUpdates = currentUpdates.attributes?.language;
88-
89-
if (!effectiveUserId && isLanguageInUpdates) {
90-
// no user id set but the updates contain a language
91-
// we need to set this language in the local config:
92-
config.update({
93-
...config.get(),
94-
user: {
95-
...config.get().user,
96-
data: {
97-
...config.get().user.data,
98-
language: currentUpdates.attributes?.language,
99-
},
100-
},
101-
});
102-
103-
logger.debug("Updated language successfully");
104-
105-
const { language: _, ...remainingAttributes } =
106-
currentUpdates.attributes ?? {};
107-
108-
// remove language from attributes
109-
currentUpdates = {
110-
...currentUpdates,
111-
attributes: remainingAttributes,
112-
};
113-
}
114-
115-
if (
116-
Object.keys(currentUpdates.attributes ?? {}).length > 0 &&
117-
!effectiveUserId
118-
) {
119-
const errorMessage =
120-
"Formbricks can't set attributes without a userId! Please set a userId first with the setUserId function";
121-
logger.error(errorMessage);
122-
this.clearUpdates();
123-
throw new Error(errorMessage);
124-
}
125-
126-
// Only send updates if we have a userId (either from updates or local storage)
127-
if (effectiveUserId) {
128-
const result = await sendUpdates({
129-
updates: {
130-
userId: effectiveUserId,
131-
attributes: currentUpdates.attributes ?? {},
132-
},
133-
});
134-
135-
if (result.ok) {
136-
logger.debug("Updates sent successfully");
137-
} else {
138-
logger.error("Failed to send updates");
139-
}
140-
}
151+
if (Object.keys(currentUpdates).length === 0) {
152+
this.clearUpdates();
153+
resolve();
154+
return;
155+
}
156+
157+
const effectiveUserId =
158+
currentUpdates.userId ?? config.get().user.data.userId;
159+
160+
// Handle language updates without userId
161+
if (!effectiveUserId) {
162+
currentUpdates = this.handleLanguageWithoutUserId(
163+
currentUpdates,
164+
config
165+
);
141166
}
142167

168+
// Validate attributes require userId
169+
this.validateAttributesWithUserId(currentUpdates, effectiveUserId);
170+
171+
// Send updates if we have a userId
172+
await this.sendUpdatesIfNeeded(effectiveUserId, currentUpdates);
173+
143174
this.clearUpdates();
144175
resolve();
145176
} catch (error: unknown) {

packages/react-native/src/types/project.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import type { TBaseStyling } from "./survey";
1+
import type { TBaseStyling } from "./styling";
22

33
export type TProject = {
44
id: string;
@@ -27,7 +27,6 @@ export type TProject = {
2727
} | null;
2828
};
2929

30-
3130
export interface TProjectStyling extends TBaseStyling {
3231
allowStyleOverwrite: boolean;
3332
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
export interface TStylingColor {
2+
light: string;
3+
dark?: string | null;
4+
}
5+
6+
export interface TBaseStyling {
7+
brandColor?: TStylingColor | null;
8+
questionColor?: TStylingColor | null;
9+
inputColor?: TStylingColor | null;
10+
inputBorderColor?: TStylingColor | null;
11+
cardBackgroundColor?: TStylingColor | null;
12+
cardBorderColor?: TStylingColor | null;
13+
cardShadowColor?: TStylingColor | null;
14+
highlightBorderColor?: TStylingColor | null;
15+
isDarkModeEnabled?: boolean | null;
16+
roundness?: number | null;
17+
cardArrangement?: {
18+
linkSurveys: "casual" | "straight" | "simple";
19+
appSurveys: "casual" | "straight" | "simple";
20+
} | null;
21+
background?: {
22+
bg?: string | null;
23+
bgType?: "animation" | "color" | "image" | "upload" | null;
24+
brightness?: number | null;
25+
} | null;
26+
hideProgressBar?: boolean | null;
27+
isLogoHidden?: boolean | null;
28+
}

packages/react-native/src/types/survey.ts

Lines changed: 16 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -219,10 +219,10 @@ export type TSurvey = {
219219
recontactDays: number | null;
220220
displayLimit: number | null;
221221
displayOption:
222-
| "displayOnce"
223-
| "displayMultiple"
224-
| "respondMultiple"
225-
| "displaySome";
222+
| "displayOnce"
223+
| "displayMultiple"
224+
| "respondMultiple"
225+
| "displaySome";
226226
hiddenFields: {
227227
enabled: boolean;
228228
fieldIds?: string[];
@@ -232,12 +232,12 @@ export type TSurvey = {
232232
brandColor?: string | null;
233233
highlightBorderColor?: string | null;
234234
placement?:
235-
| "topLeft"
236-
| "topRight"
237-
| "bottomLeft"
238-
| "bottomRight"
239-
| "center"
240-
| null;
235+
| "topLeft"
236+
| "topRight"
237+
| "bottomLeft"
238+
| "bottomRight"
239+
| "center"
240+
| null;
241241
clickOutsideClose?: boolean | null;
242242
darkOverlay?: boolean | null;
243243
} | null;
@@ -267,12 +267,12 @@ export type TSurvey = {
267267
urlFilters: {
268268
value: string;
269269
rule:
270-
| "exactMatch"
271-
| "contains"
272-
| "startsWith"
273-
| "endsWith"
274-
| "notMatch"
275-
| "notContains";
270+
| "exactMatch"
271+
| "contains"
272+
| "startsWith"
273+
| "endsWith"
274+
| "notMatch"
275+
| "notContains";
276276
}[];
277277
elementSelector?: {
278278
cssSelector?: string;
@@ -318,32 +318,3 @@ export type TSurvey = {
318318
overwriteThemeStyling?: boolean | null;
319319
};
320320
};
321-
322-
export interface TStylingColor {
323-
light: string;
324-
dark?: string | null;
325-
}
326-
327-
export interface TBaseStyling {
328-
brandColor?: TStylingColor | null;
329-
questionColor?: TStylingColor | null;
330-
inputColor?: TStylingColor | null;
331-
inputBorderColor?: TStylingColor | null;
332-
cardBackgroundColor?: TStylingColor | null;
333-
cardBorderColor?: TStylingColor | null;
334-
cardShadowColor?: TStylingColor | null;
335-
highlightBorderColor?: TStylingColor | null;
336-
isDarkModeEnabled?: boolean | null;
337-
roundness?: number | null;
338-
cardArrangement?: {
339-
linkSurveys: "casual" | "straight" | "simple";
340-
appSurveys: "casual" | "straight" | "simple";
341-
} | null;
342-
background?: {
343-
bg?: string | null;
344-
bgType?: "animation" | "color" | "image" | "upload" | null;
345-
brightness?: number | null;
346-
} | null;
347-
hideProgressBar?: boolean | null;
348-
isLogoHidden?: boolean | null;
349-
}

0 commit comments

Comments
 (0)