Skip to content

Commit 482fa5d

Browse files
feat(store): preserve the event name case with createActionGroup (#3832)
BREAKING CHANGES: The event name case is preserved when converting to the action name by using the `createActionGroup` function. BEFORE: All letters of the event name will be lowercase, except for the initial letters of words starting from the second word, which will be uppercase. ```ts const authApiActions = createActionGroup({ source: 'Auth API', events: { 'LogIn Success': emptyProps(), 'login failure': emptyProps(), 'Logout Success': emptyProps(), logoutFailure: emptyProps(), }, }); // generated actions: const { loginSuccess, loginFailure, logoutSuccess, logoutfailure, } = authApiActions; ``` AFTER: The initial letter of the first word of the event name will be lowercase, and the initial letters of the other words will be uppercase. The case of other letters in the event name will remain the same. ```ts const { logInSuccess, loginFailure, logoutSuccess, logoutFailure, } = authApiActions; ```
1 parent 73eb55c commit 482fa5d

File tree

6 files changed

+40
-11
lines changed

6 files changed

+40
-11
lines changed

modules/store/spec/action_group_creator.spec.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,17 +14,22 @@ describe('createActionGroup', () => {
1414
source: 'Books API',
1515
events: {
1616
' Load BOOKS suCCess ': emptyProps(),
17+
loadBooksFailure: emptyProps(),
1718
},
1819
});
1920

2021
it('should create action name by camel casing the event name', () => {
21-
expect(booksApiActions.loadBooksSuccess).toBeDefined();
22+
expect(booksApiActions.loadBOOKSSuCCess).toBeDefined();
23+
expect(booksApiActions.loadBooksFailure).toBeDefined();
2224
});
2325

2426
it('should create action type using the "[Source] Event" pattern', () => {
25-
expect(booksApiActions.loadBooksSuccess().type).toBe(
27+
expect(booksApiActions.loadBOOKSSuCCess().type).toBe(
2628
'[Books API] Load BOOKS suCCess '
2729
);
30+
expect(booksApiActions.loadBooksFailure().type).toBe(
31+
'[Books API] loadBooksFailure'
32+
);
2833
});
2934

3035
it('should create action with props', () => {

modules/store/spec/helpers.spec.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { capitalize } from '../src/helpers';
1+
import { capitalize, uncapitalize } from '../src/helpers';
22

33
describe('helpers', () => {
44
describe('capitalize', () => {
@@ -10,4 +10,14 @@ describe('helpers', () => {
1010
expect(capitalize('')).toEqual('');
1111
});
1212
});
13+
14+
describe('uncapitalize', () => {
15+
it('should uncapitalize the text', () => {
16+
expect(uncapitalize('NGRX')).toEqual('nGRX');
17+
});
18+
19+
it('should return an empty string when the text is an empty string', () => {
20+
expect(uncapitalize('')).toEqual('');
21+
});
22+
});
1323
});

modules/store/spec/types/action_group_creator.spec.ts

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -98,22 +98,33 @@ describe('createActionGroup', () => {
9898

9999
describe('event name', () => {
100100
it('should create action name by camel casing the event name', () => {
101-
expectSnippet(`
101+
const snippet = expectSnippet(`
102102
const booksApiActions = createActionGroup({
103103
source: 'Books API',
104104
events: {
105105
' Load BOOKS suCCess ': emptyProps(),
106+
loadBooksFailure: emptyProps(),
106107
},
107108
});
108109
109-
let loadBooksSuccess: typeof booksApiActions.loadBooksSuccess;
110-
`).toInfer(
110+
let loadBooksSuccess: typeof booksApiActions.loadBOOKSSuCCess;
111+
let loadBooksFailure: typeof booksApiActions.loadBooksFailure;
112+
`);
113+
114+
snippet.toInfer(
111115
'loadBooksSuccess',
112116
`ActionCreator<
113117
"[Books API] Load BOOKS suCCess ",
114118
() => TypedAction<"[Books API] Load BOOKS suCCess ">
115119
>`
116120
);
121+
snippet.toInfer(
122+
'loadBooksFailure',
123+
`ActionCreator<
124+
"[Books API] loadBooksFailure",
125+
() => TypedAction<"[Books API] loadBooksFailure">
126+
>`
127+
);
117128
});
118129

119130
it('should fail when event name is an empty string', () => {
@@ -222,7 +233,7 @@ describe('createActionGroup', () => {
222233
const booksApiActions = createActionGroup({
223234
source: 'Books API',
224235
events: {
225-
' Load BOOks success ': emptyProps(),
236+
' Load Books success ': emptyProps(),
226237
'load Books Success': props<{ books: string[] }>(),
227238
}
228239
});

modules/store/src/action_group_creator.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { createAction, props } from './action_creator';
22
import { ActionCreatorProps, Creator } from './models';
3-
import { capitalize } from './helpers';
3+
import { capitalize, uncapitalize } from './helpers';
44
import {
55
ActionGroup,
66
ActionGroupConfig,
@@ -75,9 +75,8 @@ function toActionName<EventName extends string>(
7575
): ActionName<EventName> {
7676
return eventName
7777
.trim()
78-
.toLowerCase()
7978
.split(' ')
80-
.map((word, i) => (i === 0 ? word : capitalize(word)))
79+
.map((word, i) => (i === 0 ? uncapitalize(word) : capitalize(word)))
8180
.join('') as ActionName<EventName>;
8281
}
8382

modules/store/src/action_group_creator_models.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ type EventCreator<
9595
: never;
9696

9797
export type ActionName<EventName extends string> = Uncapitalize<
98-
Join<TitleCase<Lowercase<Trim<EventName>>>>
98+
Join<TitleCase<EventName>>
9999
>;
100100

101101
export interface ActionGroupConfig<

modules/store/src/helpers.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
11
export function capitalize<T extends string>(text: T): Capitalize<T> {
22
return (text.charAt(0).toUpperCase() + text.substring(1)) as Capitalize<T>;
33
}
4+
5+
export function uncapitalize<T extends string>(text: T): Uncapitalize<T> {
6+
return (text.charAt(0).toLowerCase() + text.substring(1)) as Uncapitalize<T>;
7+
}

0 commit comments

Comments
 (0)