Skip to content

Commit d6e09e6

Browse files
authored
Merge pull request #52 from lemoncloud-io/feature/louis-update-case
feat(storage): support camelCase and snake_case keys
2 parents 1a772e5 + 5f37c2e commit d6e09e6

File tree

4 files changed

+67
-25
lines changed

4 files changed

+67
-25
lines changed

src/token-storage/aws-storage.service.ts

Lines changed: 26 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,17 @@ export class AWSStorageService extends TokenStorageService {
2626
];
2727

2828
/**
29-
* Gets the storage key (always snake_case).
29+
* Gets whether to use snake_case based on configuration.
30+
*/
31+
private get useSnakeCase(): boolean {
32+
return this.config.defaultCaseStyle !== 'camelCase';
33+
}
34+
35+
/**
36+
* Gets the storage key in the configured default case style.
3037
*/
3138
private getKey(key: string): string {
32-
return getStorageKey(this.prefix, key);
39+
return getStorageKey(this.prefix, key, this.useSnakeCase);
3340
}
3441

3542
/**
@@ -40,21 +47,29 @@ export class AWSStorageService extends TokenStorageService {
4047
}
4148

4249
/**
43-
* Migrates camelCase keys to snake_case if needed.
50+
* Migrates keys to the configured default case style if needed.
4451
*/
4552
private async migrateKey(key: string): Promise<void> {
4653
const { snakeKey, camelKey } = getStorageKeyVariants(this.prefix, key);
4754
const snakeValue = await this.storage.getItem(snakeKey);
4855
const camelValue = await this.storage.getItem(camelKey);
4956

50-
// If both exist, prefer snake_case and remove camelCase
51-
if (snakeValue && camelValue) {
52-
await this.storage.removeItem(camelKey);
53-
}
54-
// If only camelCase exists, migrate it to snake_case
55-
else if (!snakeValue && camelValue) {
56-
await this.storage.setItem(snakeKey, camelValue);
57-
await this.storage.removeItem(camelKey);
57+
if (this.useSnakeCase) {
58+
// Prefer snake_case: migrate camelCase to snake_case if needed
59+
if (snakeValue && camelValue) {
60+
await this.storage.removeItem(camelKey);
61+
} else if (!snakeValue && camelValue) {
62+
await this.storage.setItem(snakeKey, camelValue);
63+
await this.storage.removeItem(camelKey);
64+
}
65+
} else {
66+
// Prefer camelCase: migrate snake_case to camelCase if needed
67+
if (snakeValue && camelValue) {
68+
await this.storage.removeItem(snakeKey);
69+
} else if (snakeValue && !camelValue) {
70+
await this.storage.setItem(camelKey, snakeValue);
71+
await this.storage.removeItem(snakeKey);
72+
}
5873
}
5974
}
6075

src/token-storage/azure-storage.service.ts

Lines changed: 26 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,17 @@ export class AzureStorageService extends TokenStorageService {
2222
];
2323

2424
/**
25-
* Gets the storage key (always snake_case).
25+
* Gets whether to use snake_case based on configuration.
26+
*/
27+
private get useSnakeCase(): boolean {
28+
return this.config.defaultCaseStyle !== 'camelCase';
29+
}
30+
31+
/**
32+
* Gets the storage key in the configured default case style.
2633
*/
2734
private getKey(key: string): string {
28-
return getStorageKey(this.prefix, key);
35+
return getStorageKey(this.prefix, key, this.useSnakeCase);
2936
}
3037

3138
/**
@@ -36,21 +43,29 @@ export class AzureStorageService extends TokenStorageService {
3643
}
3744

3845
/**
39-
* Migrates camelCase keys to snake_case if needed.
46+
* Migrates keys to the configured default case style if needed.
4047
*/
4148
private async migrateKey(key: string): Promise<void> {
4249
const { snakeKey, camelKey } = getStorageKeyVariants(this.prefix, key);
4350
const snakeValue = await this.storage.getItem(snakeKey);
4451
const camelValue = await this.storage.getItem(camelKey);
4552

46-
// If both exist, prefer snake_case and remove camelCase
47-
if (snakeValue && camelValue) {
48-
await this.storage.removeItem(camelKey);
49-
}
50-
// If only camelCase exists, migrate it to snake_case
51-
else if (!snakeValue && camelValue) {
52-
await this.storage.setItem(snakeKey, camelValue);
53-
await this.storage.removeItem(camelKey);
53+
if (this.useSnakeCase) {
54+
// Prefer snake_case: migrate camelCase to snake_case if needed
55+
if (snakeValue && camelValue) {
56+
await this.storage.removeItem(camelKey);
57+
} else if (!snakeValue && camelValue) {
58+
await this.storage.setItem(snakeKey, camelValue);
59+
await this.storage.removeItem(camelKey);
60+
}
61+
} else {
62+
// Prefer camelCase: migrate snake_case to camelCase if needed
63+
if (snakeValue && camelValue) {
64+
await this.storage.removeItem(snakeKey);
65+
} else if (snakeValue && !camelValue) {
66+
await this.storage.setItem(camelKey, snakeValue);
67+
await this.storage.removeItem(snakeKey);
68+
}
5469
}
5570
}
5671

src/types/core.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,11 @@ export type WebCoreServiceMap = {
5656
*/
5757
export type CloudProvider = keyof WebCoreServiceMap;
5858

59+
/**
60+
* Type representing the case style for localStorage keys.
61+
*/
62+
export type CaseStyle = 'snake_case' | 'camelCase';
63+
5964
/**
6065
* Type representing the configuration for the web core.
6166
* @template T - The cloud provider type.
@@ -66,6 +71,13 @@ export type WebCoreConfig<T extends CloudProvider> = {
6671
oAuthEndpoint: string;
6772
region?: string;
6873
storage?: Storage;
74+
/**
75+
* Default case style for new localStorage keys.
76+
* - 'snake_case': Use snake_case format (e.g., access_key_id)
77+
* - 'camelCase': Use camelCase format (e.g., accessKeyId)
78+
* @default 'snake_case'
79+
*/
80+
defaultCaseStyle?: CaseStyle;
6981
};
7082

7183
/**

src/utils/utils.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -75,9 +75,9 @@ export const convertSnakeCaseFromCamel = (key: string) => {
7575
return key.replace(/[A-Z]/g, letter => `_${letter.toLowerCase()}`);
7676
};
7777

78-
export const getStorageKey = (prefix: string, key: string) => {
79-
// Always use snake_case for new storage keys
80-
return `${prefix}.${key}`;
78+
export const getStorageKey = (prefix: string, key: string, useSnakeCase: boolean = true) => {
79+
const storageKey = useSnakeCase ? key : convertCamelCaseFromSnake(key);
80+
return `${prefix}.${storageKey}`;
8181
};
8282

8383
export const getStorageKeyVariants = (prefix: string, key: string) => {

0 commit comments

Comments
 (0)