Skip to content

Commit 01ef667

Browse files
authored
Merge pull request #376 from brionmario/refactor-thunder-flows
Fix some design related issues for AsgardeoV2 (Thunder)
2 parents f67e659 + bc2a8ac commit 01ef667

File tree

62 files changed

+1261
-217
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

62 files changed

+1261
-217
lines changed

.changeset/witty-forks-feel.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
'@asgardeo/javascript': patch
3+
'@asgardeo/react': patch
4+
---
5+
6+
Fix some issues related to design in AsgardeoV2

package.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,11 @@
7676
"@wso2/eslint-plugin>@typescript-eslint/parser": "6.21.0",
7777
"@wso2/eslint-plugin>@typescript-eslint/type-utils": "6.21.0",
7878
"@wso2/eslint-plugin>@typescript-eslint/utils": "6.21.0"
79+
},
80+
"auditConfig": {
81+
"ignoreCves": [
82+
"CVE-2026-26996"
83+
]
7984
}
8085
},
8186
"publishConfig": {

packages/javascript/src/__legacy__/client.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ import {Storage, TemporaryStore} from '../models/store';
3232
import {TokenResponse, IdToken, TokenExchangeRequestConfig} from '../models/token';
3333
import {User} from '../models/user';
3434
import StorageManager from '../StorageManager';
35+
import deepMerge from '../utils/deepMerge';
3536
import extractPkceStorageKeyFromState from '../utils/extractPkceStorageKeyFromState';
3637
import generatePkceStorageKey from '../utils/generatePkceStorageKey';
3738
import getAuthorizeRequestUrlParams from '../utils/getAuthorizeRequestUrlParams';
@@ -1138,7 +1139,10 @@ export class AsgardeoAuthClient<T> {
11381139
* @preserve
11391140
*/
11401141
public async reInitialize(config: Partial<AuthClientConfig<T>>): Promise<void> {
1141-
await this.storageManager.setConfigData(config);
1142+
const currentConfig: AuthClientConfig<T> = this.storageManager.getConfigData() as unknown as AuthClientConfig<T>;
1143+
const newConfig: AuthClientConfig<T> = deepMerge(currentConfig, config);
1144+
1145+
await this.storageManager.setConfigData(newConfig);
11421146
await this.loadOpenIDProviderConfiguration(true);
11431147
}
11441148

packages/javascript/src/index.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,8 @@ export {Storage, TemporaryStore} from './models/store';
161161
export {User, UserProfile} from './models/user';
162162
export {SessionData} from './models/session';
163163
export {Organization} from './models/organization';
164+
export {TranslationFn} from './models/v2/translation';
165+
export {ResolveVarsOptions} from './models/v2/vars';
164166
export {
165167
BrandingPreference,
166168
BrandingPreferenceConfig,
@@ -204,6 +206,8 @@ export {default as get} from './utils/get';
204206
export {default as removeTrailingSlash} from './utils/removeTrailingSlash';
205207
export {default as resolveFieldType} from './utils/resolveFieldType';
206208
export {default as resolveFieldName} from './utils/resolveFieldName';
209+
export {default as resolveMeta} from './utils/v2/resolveMeta';
210+
export {default as resolveVars} from './utils/v2/resolveVars';
207211
export {default as processOpenIDScopes} from './utils/processOpenIDScopes';
208212
export {default as withVendorCSSClassPrefix} from './utils/withVendorCSSClassPrefix';
209213
export {default as transformBrandingPreferenceToTheme} from './utils/transformBrandingPreferenceToTheme';

packages/javascript/src/models/v2/embedded-flow-v2.ts

Lines changed: 85 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,12 @@ export enum EmbeddedFlowComponentType {
5050
/** Email input field with validation for email addresses. */
5151
EmailInput = 'EMAIL_INPUT',
5252

53+
/** Icon display component for rendering named vector icons */
54+
Icon = 'ICON',
55+
56+
/** Image display component for logos and illustrations */
57+
Image = 'IMAGE',
58+
5359
/** One-time password input field for multi-factor authentication */
5460
OtpInput = 'OTP_INPUT',
5561

@@ -59,9 +65,15 @@ export enum EmbeddedFlowComponentType {
5965
/** Phone number input field with country code support */
6066
PhoneInput = 'PHONE_INPUT',
6167

68+
/** Rich text display component that renders formatted HTML content */
69+
RichText = 'RICH_TEXT',
70+
6271
/** Select/dropdown input component for single choice selection */
6372
Select = 'SELECT',
6473

74+
/** Stack layout component for arranging children in a row or column */
75+
Stack = 'STACK',
76+
6577
/** Text display component for labels, headings, and messages */
6678
Text = 'TEXT',
6779

@@ -199,27 +211,78 @@ export enum EmbeddedFlowEventType {
199211
*/
200212
export interface EmbeddedFlowComponent {
201213
/**
202-
* Nested child components for container components like Block.
214+
* Alignment of children along the cross axis (for Stack components).
215+
*/
216+
align?: string;
217+
218+
/**
219+
* Alternative text for Image components.
220+
*/
221+
alt?: string;
222+
223+
/**
224+
* Icon color, CSS color value (for Icon components).
225+
*/
226+
color?: string;
227+
228+
/**
229+
* Nested child components for container components like Block and Stack.
203230
*/
204231
components?: EmbeddedFlowComponent[];
205232

233+
/**
234+
* Layout direction for Stack components ('row' | 'column').
235+
*/
236+
direction?: string;
237+
238+
/**
239+
* Icon to render at the end of an Action button (URL string).
240+
*/
241+
endIcon?: string;
242+
206243
/**
207244
* Event type for action components that defines the interaction behavior.
208245
* Only relevant for Action components.
209246
*/
210247
eventType?: EmbeddedFlowEventType | string;
211248

249+
/**
250+
* Gap between children in Stack components (number, maps to spacing units).
251+
*/
252+
gap?: number;
253+
254+
/**
255+
* Height of the component (for Image components, can be string with units or number for pixels).
256+
* The value depends on the component type (e.g., for Image components).
257+
*/
258+
height?: string | number;
259+
212260
/**
213261
* Unique identifier for the component
214262
*/
215263
id: string;
216264

265+
/**
266+
* Number of items across the main axis (for Stack grid-like layouts).
267+
*/
268+
items?: string | number;
269+
270+
/**
271+
* Justification of children along the main axis (for Stack components).
272+
*/
273+
justify?: string;
274+
217275
/**
218276
* Display label for the component (e.g., field label, button text).
219277
* Supports internationalization and may contain template strings.
220278
*/
221279
label?: string;
222280

281+
/**
282+
* Icon name for Icon components (e.g., lucide-react icon names like 'ArrowLeftRight').
283+
*/
284+
name?: string;
285+
223286
/**
224287
* Options for SELECT components.
225288
* Each option can be a string value or an object with value and label.
@@ -243,6 +306,21 @@ export interface EmbeddedFlowComponent {
243306
*/
244307
required?: boolean;
245308

309+
/**
310+
* Icon size in pixels (for Icon components).
311+
*/
312+
size?: number;
313+
314+
/**
315+
* Image source URL (for Image components).
316+
*/
317+
src?: string;
318+
319+
/**
320+
* Icon to render at the start of an Action button (URL string).
321+
*/
322+
startIcon?: string;
323+
246324
/**
247325
* Component type that determines rendering behavior
248326
*/
@@ -253,6 +331,12 @@ export interface EmbeddedFlowComponent {
253331
* The value depends on the component type (e.g., button variants, text variants).
254332
*/
255333
variant?: EmbeddedFlowActionVariant | EmbeddedFlowTextVariant | string;
334+
335+
/**
336+
* Width of the component (for Image components, can be string with units or number for pixels).
337+
* The value depends on the component type (e.g., for Image components).
338+
*/
339+
width?: string | number;
256340
}
257341

258342
/**

packages/javascript/src/models/v2/flow-meta-v2.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,7 @@ export interface FlowMetaThemeColors {
165165
*/
166166
export interface FlowMetaThemeColorScheme {
167167
/** All colors defined for this color scheme (light or dark) */
168-
colors: FlowMetaThemeColors;
168+
palette: FlowMetaThemeColors;
169169
}
170170

171171
/**
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
/**
2+
* Copyright (c) 2026, WSO2 LLC. (https://www.wso2.com).
3+
*
4+
* WSO2 LLC. licenses this file to you under the Apache License,
5+
* Version 2.0 (the "License"); you may not use this file except
6+
* in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing,
12+
* software distributed under the License is distributed on an
13+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14+
* KIND, either express or implied. See the License for the
15+
* specific language governing permissions and limitations
16+
* under the License.
17+
*/
18+
19+
/**
20+
* Generic translation function type.
21+
*
22+
* The default parameter type (`Record<string, string | number>`) matches the
23+
* common i18n signature used throughout the SDK. Consumers can supply a more
24+
* specific type when integrating with third-party i18n libraries.
25+
*
26+
* @template TParams - The type of the optional interpolation parameters object.
27+
*
28+
* @example
29+
* // Using the default (SDK-native) signature
30+
* const t: TranslationFn = (key, params) => i18n.t(key, params);
31+
*
32+
* // Using react-i18next's TFunction as TParams
33+
* const t: TranslationFn<Record<string, unknown>> = i18nextT;
34+
*/
35+
export type TranslationFn<TParams = Record<string, string | number>> = (key: string, params?: TParams) => string;
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
/**
2+
* Copyright (c) 2026, WSO2 LLC. (https://www.wso2.com).
3+
*
4+
* WSO2 LLC. licenses this file to you under the Apache License,
5+
* Version 2.0 (the "License"); you may not use this file except
6+
* in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing,
12+
* software distributed under the License is distributed on an
13+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14+
* KIND, either express or implied. See the License for the
15+
* specific language governing permissions and limitations
16+
* under the License.
17+
*/
18+
19+
import {FlowMetadataResponse} from './flow-meta-v2';
20+
import {TranslationFn} from './translation';
21+
22+
/**
23+
* Options for the resolveVars function.
24+
*
25+
* @template TFn - The concrete translation function type.
26+
* Defaults to the SDK-native {@link TranslationFn} signature.
27+
*/
28+
export interface ResolveVarsOptions<TFn extends TranslationFn = TranslationFn> {
29+
/**
30+
* Optional flow metadata for resolving `{{ meta(path) }}` expressions.
31+
*/
32+
meta?: FlowMetadataResponse | null;
33+
/**
34+
* i18n translation function for resolving `{{ t(key) }}` expressions.
35+
*/
36+
t: TFn;
37+
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
/**
2+
* Copyright (c) 2026, WSO2 LLC. (https://www.wso2.com).
3+
*
4+
* WSO2 LLC. licenses this file to you under the Apache License,
5+
* Version 2.0 (the "License"); you may not use this file except
6+
* in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing,
12+
* software distributed under the License is distributed on an
13+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14+
* KIND, either express or implied. See the License for the
15+
* specific language governing permissions and limitations
16+
* under the License.
17+
*/
18+
19+
import {FlowMetadataResponse} from '../../models/v2/flow-meta-v2';
20+
21+
/**
22+
* Resolves a dot-path expression against a FlowMetadataResponse object.
23+
*
24+
* Supports both camelCase paths (e.g. `logoUrl`) and snake_case API responses
25+
* (e.g. `logo_url`). When a camelCase segment is not found directly, the
26+
* function falls back to its snake_case equivalent.
27+
*
28+
* @example
29+
* resolveMeta('application.name', meta) // → 'My App'
30+
* resolveMeta('ou.name', meta) // → 'My Org'
31+
*
32+
* @param path - Dot-separated path into the meta object (e.g. 'application.name')
33+
* @param meta - The FlowMetadataResponse to look up
34+
* @returns The resolved string value, or empty string if not found
35+
*/
36+
export default function resolveMeta(path: string, meta: FlowMetadataResponse): string {
37+
const value: unknown = path.split('.').reduce<unknown>((current: unknown, part: string) => {
38+
if (current == null || typeof current !== 'object') {
39+
return undefined;
40+
}
41+
42+
const obj: Record<string, unknown> = current as Record<string, unknown>;
43+
const snakePart: string = part.replace(/[A-Z]/g, (c: string) => `_${c.toLowerCase()}`);
44+
45+
return part in obj ? obj[part] : obj[snakePart];
46+
}, meta);
47+
48+
return value != null ? String(value) : '';
49+
}

0 commit comments

Comments
 (0)