core-plugin-api: Remove deprecated get method from StorageApi
Signed-off-by: Johan Haals <johan.haals@gmail.com>
This commit is contained in:
@@ -0,0 +1,7 @@
|
||||
---
|
||||
'@backstage/core-app-api': minor
|
||||
'@backstage/core-plugin-api': minor
|
||||
'@backstage/test-utils': minor
|
||||
---
|
||||
|
||||
**BREAKING**: Removed the deprecated `get` method from `StorageAPI` and its implementations, this method has been replaced by the `snapshot` method. The return value from snapshot no longer includes `newValue` which has been replaced by `value`. For getting notified when a value changes, use `observe$`.
|
||||
@@ -0,0 +1,6 @@
|
||||
---
|
||||
'@backstage/core-components': patch
|
||||
'@backstage/plugin-catalog-react': patch
|
||||
---
|
||||
|
||||
Updated usage of `StorageApi` to use `snapshot` method instead of `get`
|
||||
@@ -33,12 +33,11 @@ describe('WebStorage Storage API', () => {
|
||||
it('should return undefined for values which are unset', async () => {
|
||||
const storage = createWebStorage();
|
||||
|
||||
expect(storage.get('myfakekey')).toBeUndefined();
|
||||
expect(storage.snapshot('myfakekey').value).toBeUndefined();
|
||||
expect(storage.snapshot('myfakekey')).toEqual({
|
||||
key: 'myfakekey',
|
||||
presence: 'absent',
|
||||
value: undefined,
|
||||
newValue: undefined,
|
||||
});
|
||||
});
|
||||
|
||||
@@ -48,26 +47,23 @@ describe('WebStorage Storage API', () => {
|
||||
await storage.set('myfakekey', 'helloimastring');
|
||||
await storage.set('mysecondfakekey', 1234);
|
||||
await storage.set('mythirdfakekey', true);
|
||||
expect(storage.get('myfakekey')).toBe('helloimastring');
|
||||
expect(storage.get('mysecondfakekey')).toBe(1234);
|
||||
expect(storage.get('mythirdfakekey')).toBe(true);
|
||||
expect(storage.snapshot('myfakekey').value).toBe('helloimastring');
|
||||
expect(storage.snapshot('mysecondfakekey').value).toBe(1234);
|
||||
expect(storage.snapshot('mythirdfakekey').value).toBe(true);
|
||||
expect(storage.snapshot('myfakekey')).toEqual({
|
||||
key: 'myfakekey',
|
||||
presence: 'present',
|
||||
value: 'helloimastring',
|
||||
newValue: 'helloimastring',
|
||||
});
|
||||
expect(storage.snapshot('mysecondfakekey')).toEqual({
|
||||
key: 'mysecondfakekey',
|
||||
presence: 'present',
|
||||
value: 1234,
|
||||
newValue: 1234,
|
||||
});
|
||||
expect(storage.snapshot('mythirdfakekey')).toEqual({
|
||||
key: 'mythirdfakekey',
|
||||
presence: 'present',
|
||||
value: true,
|
||||
newValue: true,
|
||||
});
|
||||
});
|
||||
|
||||
@@ -81,12 +77,11 @@ describe('WebStorage Storage API', () => {
|
||||
|
||||
await storage.set('myfakekey', mockData);
|
||||
|
||||
expect(storage.get('myfakekey')).toEqual(mockData);
|
||||
expect(storage.snapshot('myfakekey').value).toEqual(mockData);
|
||||
expect(storage.snapshot('myfakekey')).toEqual({
|
||||
key: 'myfakekey',
|
||||
presence: 'present',
|
||||
value: mockData,
|
||||
newValue: mockData,
|
||||
});
|
||||
});
|
||||
|
||||
@@ -118,7 +113,6 @@ describe('WebStorage Storage API', () => {
|
||||
key: 'correctKey',
|
||||
presence: 'present',
|
||||
value: mockData,
|
||||
newValue: mockData,
|
||||
});
|
||||
});
|
||||
|
||||
@@ -152,7 +146,6 @@ describe('WebStorage Storage API', () => {
|
||||
key: 'correctKey',
|
||||
presence: 'absent',
|
||||
value: undefined,
|
||||
newValue: undefined,
|
||||
});
|
||||
});
|
||||
|
||||
@@ -166,9 +159,11 @@ describe('WebStorage Storage API', () => {
|
||||
await firstStorage.set(keyName, 'boop');
|
||||
await secondStorage.set(keyName, 'deerp');
|
||||
|
||||
expect(firstStorage.get(keyName)).not.toBe(secondStorage.get(keyName));
|
||||
expect(firstStorage.get(keyName)).toBe('boop');
|
||||
expect(secondStorage.get(keyName)).toBe('deerp');
|
||||
expect(firstStorage.snapshot(keyName)).not.toBe(
|
||||
secondStorage.snapshot(keyName),
|
||||
);
|
||||
expect(firstStorage.snapshot(keyName).value).toBe('boop');
|
||||
expect(secondStorage.snapshot(keyName).value).toBe('deerp');
|
||||
expect(firstStorage.snapshot(keyName)).not.toEqual(
|
||||
secondStorage.snapshot(keyName),
|
||||
);
|
||||
@@ -176,13 +171,11 @@ describe('WebStorage Storage API', () => {
|
||||
key: keyName,
|
||||
presence: 'present',
|
||||
value: 'boop',
|
||||
newValue: 'boop',
|
||||
});
|
||||
expect(secondStorage.snapshot(keyName)).toEqual({
|
||||
key: keyName,
|
||||
presence: 'present',
|
||||
value: 'deerp',
|
||||
newValue: 'deerp',
|
||||
});
|
||||
});
|
||||
|
||||
@@ -217,7 +210,6 @@ describe('WebStorage Storage API', () => {
|
||||
key: 'key',
|
||||
presence: 'absent',
|
||||
value: undefined,
|
||||
newValue: undefined,
|
||||
});
|
||||
expect(mockErrorApi.post).toHaveBeenCalledWith(expect.any(Error));
|
||||
expect(mockErrorApi.post).toHaveBeenCalledWith(
|
||||
|
||||
@@ -65,7 +65,7 @@ export class WebStorage implements StorageApi {
|
||||
new Error(`Error when parsing JSON config from storage for: ${key}`),
|
||||
);
|
||||
}
|
||||
return { key, value, newValue: value, presence };
|
||||
return { key, value, presence };
|
||||
}
|
||||
|
||||
forBucket(name: string): WebStorage {
|
||||
|
||||
+1
-1
@@ -75,7 +75,7 @@ describe('<DismissableBanner />', () => {
|
||||
);
|
||||
fireEvent.click(button);
|
||||
const dismissedBanners =
|
||||
notifications?.get<string[]>('dismissedBanners') ?? [];
|
||||
notifications?.snapshot<string[]>('dismissedBanners').value ?? [];
|
||||
expect(
|
||||
dismissedBanners.includes('catalog_page_welcome_banner'),
|
||||
).toBeTruthy();
|
||||
|
||||
@@ -101,7 +101,7 @@ export const DismissableBanner = (props: Props) => {
|
||||
const storageApi = useApi(storageApiRef);
|
||||
const notificationsStore = storageApi.forBucket('notifications');
|
||||
const rawDismissedBanners =
|
||||
notificationsStore.get<string[]>('dismissedBanners') ?? [];
|
||||
notificationsStore.snapshot<string[]>('dismissedBanners').value ?? [];
|
||||
|
||||
const [dismissedBanners, setDismissedBanners] = useState(
|
||||
new Set(rawDismissedBanners),
|
||||
@@ -112,11 +112,11 @@ export const DismissableBanner = (props: Props) => {
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
if (observedItems?.newValue) {
|
||||
const currentValue = observedItems?.newValue ?? [];
|
||||
if (observedItems?.value) {
|
||||
const currentValue = observedItems?.value ?? [];
|
||||
setDismissedBanners(new Set(currentValue));
|
||||
}
|
||||
}, [observedItems?.newValue]);
|
||||
}, [observedItems?.value]);
|
||||
|
||||
const handleClick = () => {
|
||||
notificationsStore.set('dismissedBanners', [...dismissedBanners, id]);
|
||||
|
||||
@@ -678,8 +678,6 @@ export type SignInPageProps = {
|
||||
// @public
|
||||
export interface StorageApi {
|
||||
forBucket(name: string): StorageApi;
|
||||
// @deprecated
|
||||
get<T extends JsonValue>(key: string): T | undefined;
|
||||
observe$<T extends JsonValue>(
|
||||
key: string,
|
||||
): Observable<StorageValueSnapshot<T>>;
|
||||
@@ -691,23 +689,17 @@ export interface StorageApi {
|
||||
// @public
|
||||
export const storageApiRef: ApiRef<StorageApi>;
|
||||
|
||||
// @public @deprecated (undocumented)
|
||||
export type StorageValueChange<TValue extends JsonValue> =
|
||||
StorageValueSnapshot<TValue>;
|
||||
|
||||
// @public
|
||||
export type StorageValueSnapshot<TValue extends JsonValue> =
|
||||
| {
|
||||
key: string;
|
||||
presence: 'unknown' | 'absent';
|
||||
value?: undefined;
|
||||
newValue?: undefined;
|
||||
}
|
||||
| {
|
||||
key: string;
|
||||
presence: 'present';
|
||||
value: TValue;
|
||||
newValue?: TValue;
|
||||
};
|
||||
|
||||
// @public
|
||||
|
||||
@@ -27,24 +27,13 @@ export type StorageValueSnapshot<TValue extends JsonValue> =
|
||||
key: string;
|
||||
presence: 'unknown' | 'absent';
|
||||
value?: undefined;
|
||||
/** @deprecated Use `value` instead */
|
||||
newValue?: undefined;
|
||||
}
|
||||
| {
|
||||
key: string;
|
||||
presence: 'present';
|
||||
value: TValue;
|
||||
/** @deprecated Use `value` instead */
|
||||
newValue?: TValue;
|
||||
};
|
||||
|
||||
/**
|
||||
* @public
|
||||
* @deprecated Use StorageValueSnapshot instead
|
||||
*/
|
||||
export type StorageValueChange<TValue extends JsonValue> =
|
||||
StorageValueSnapshot<TValue>;
|
||||
|
||||
/**
|
||||
* Provides a key-value persistence API.
|
||||
*
|
||||
@@ -59,14 +48,6 @@ export interface StorageApi {
|
||||
*/
|
||||
forBucket(name: string): StorageApi;
|
||||
|
||||
/**
|
||||
* Get the current value for persistent data, use observe$ to be notified of updates.
|
||||
*
|
||||
* @deprecated Use `snapshot` instead.
|
||||
* @param key - Unique key associated with the data.
|
||||
*/
|
||||
get<T extends JsonValue>(key: string): T | undefined;
|
||||
|
||||
/**
|
||||
* Remove persistent data.
|
||||
*
|
||||
|
||||
@@ -164,8 +164,6 @@ export class MockStorageApi implements StorageApi {
|
||||
// (undocumented)
|
||||
forBucket(name: string): StorageApi;
|
||||
// (undocumented)
|
||||
get<T>(key: string): T | undefined;
|
||||
// (undocumented)
|
||||
observe$<T>(key: string): Observable<StorageValueSnapshot<T>>;
|
||||
// (undocumented)
|
||||
remove(key: string): Promise<void>;
|
||||
|
||||
@@ -24,7 +24,7 @@ describe('WebStorage Storage API', () => {
|
||||
it('should return undefined for values which are unset', async () => {
|
||||
const storage = createMockStorage();
|
||||
|
||||
expect(storage.get('myfakekey')).toBeUndefined();
|
||||
expect(storage.snapshot('myfakekey').value).toBeUndefined();
|
||||
expect(storage.snapshot('myfakekey')).toEqual({
|
||||
key: 'myfakekey',
|
||||
presence: 'absent',
|
||||
@@ -33,32 +33,29 @@ describe('WebStorage Storage API', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('should allow the setting and getting of the simple data structures', async () => {
|
||||
it('should allow the setting and snapshotting of the simple data structures', async () => {
|
||||
const storage = createMockStorage();
|
||||
|
||||
await storage.set('myfakekey', 'helloimastring');
|
||||
await storage.set('mysecondfakekey', 1234);
|
||||
await storage.set('mythirdfakekey', true);
|
||||
expect(storage.get('myfakekey')).toBe('helloimastring');
|
||||
expect(storage.get('mysecondfakekey')).toBe(1234);
|
||||
expect(storage.get('mythirdfakekey')).toBe(true);
|
||||
expect(storage.snapshot('myfakekey').value).toBe('helloimastring');
|
||||
expect(storage.snapshot('mysecondfakekey').value).toBe(1234);
|
||||
expect(storage.snapshot('mythirdfakekey').value).toBe(true);
|
||||
expect(storage.snapshot('myfakekey')).toEqual({
|
||||
key: 'myfakekey',
|
||||
presence: 'present',
|
||||
value: 'helloimastring',
|
||||
newValue: 'helloimastring',
|
||||
});
|
||||
expect(storage.snapshot('mysecondfakekey')).toEqual({
|
||||
key: 'mysecondfakekey',
|
||||
presence: 'present',
|
||||
value: 1234,
|
||||
newValue: 1234,
|
||||
});
|
||||
expect(storage.snapshot('mythirdfakekey')).toEqual({
|
||||
key: 'mythirdfakekey',
|
||||
presence: 'present',
|
||||
value: true,
|
||||
newValue: true,
|
||||
});
|
||||
});
|
||||
|
||||
@@ -72,12 +69,11 @@ describe('WebStorage Storage API', () => {
|
||||
|
||||
await storage.set('myfakekey', mockData);
|
||||
|
||||
expect(storage.get('myfakekey')).toEqual(mockData);
|
||||
expect(storage.snapshot('myfakekey').value).toEqual(mockData);
|
||||
expect(storage.snapshot('myfakekey')).toEqual({
|
||||
key: 'myfakekey',
|
||||
presence: 'present',
|
||||
value: mockData,
|
||||
newValue: mockData,
|
||||
});
|
||||
});
|
||||
|
||||
@@ -107,7 +103,6 @@ describe('WebStorage Storage API', () => {
|
||||
key: 'correctKey',
|
||||
presence: 'present',
|
||||
value: mockData,
|
||||
newValue: mockData,
|
||||
});
|
||||
});
|
||||
|
||||
@@ -153,9 +148,11 @@ describe('WebStorage Storage API', () => {
|
||||
await firstStorage.set(keyName, 'boop');
|
||||
await secondStorage.set(keyName, 'deerp');
|
||||
|
||||
expect(firstStorage.get(keyName)).not.toBe(secondStorage.get(keyName));
|
||||
expect(firstStorage.get(keyName)).toBe('boop');
|
||||
expect(secondStorage.get(keyName)).toBe('deerp');
|
||||
expect(firstStorage.snapshot(keyName)).not.toBe(
|
||||
secondStorage.snapshot(keyName),
|
||||
);
|
||||
expect(firstStorage.snapshot(keyName).value).toBe('boop');
|
||||
expect(secondStorage.snapshot(keyName).value).toBe('deerp');
|
||||
expect(firstStorage.snapshot(keyName)).not.toEqual(
|
||||
secondStorage.snapshot(keyName),
|
||||
);
|
||||
@@ -163,13 +160,11 @@ describe('WebStorage Storage API', () => {
|
||||
key: keyName,
|
||||
presence: 'present',
|
||||
value: 'boop',
|
||||
newValue: 'boop',
|
||||
});
|
||||
expect(secondStorage.snapshot(keyName)).toEqual({
|
||||
key: keyName,
|
||||
presence: 'present',
|
||||
value: 'deerp',
|
||||
newValue: 'deerp',
|
||||
});
|
||||
});
|
||||
|
||||
@@ -186,7 +181,7 @@ describe('WebStorage Storage API', () => {
|
||||
|
||||
await firstStorage.set('test2', { error: true });
|
||||
|
||||
expect(secondStorage.get('deep/test2')).toBe(undefined);
|
||||
expect(secondStorage.snapshot('deep/test2').value).toBe(undefined);
|
||||
expect(secondStorage.snapshot('deep/test2')).toMatchObject({
|
||||
presence: 'absent',
|
||||
});
|
||||
@@ -201,19 +196,17 @@ describe('WebStorage Storage API', () => {
|
||||
|
||||
await firstStorage.set('test2', true);
|
||||
|
||||
expect(firstStorage.get('test2')).toBe(true);
|
||||
expect(secondStorage.get('test2')).toBe(undefined);
|
||||
expect(firstStorage.snapshot('test2').value).toBe(true);
|
||||
expect(secondStorage.snapshot('test2').value).toBe(undefined);
|
||||
expect(firstStorage.snapshot('test2')).toEqual({
|
||||
key: 'test2',
|
||||
presence: 'present',
|
||||
value: true,
|
||||
newValue: true,
|
||||
});
|
||||
expect(secondStorage.snapshot('test2')).toEqual({
|
||||
key: 'test2',
|
||||
presence: 'absent',
|
||||
value: undefined,
|
||||
newValue: undefined,
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -61,10 +61,6 @@ export class MockStorageApi implements StorageApi {
|
||||
return this.bucketStorageApis.get(name)!;
|
||||
}
|
||||
|
||||
get<T>(key: string): T | undefined {
|
||||
return this.snapshot(key).value as T | undefined;
|
||||
}
|
||||
|
||||
snapshot<T extends JsonValue>(key: string): StorageValueSnapshot<T> {
|
||||
if (this.data.hasOwnProperty(this.getKeyName(key))) {
|
||||
const data = this.data[this.getKeyName(key)];
|
||||
@@ -72,14 +68,12 @@ export class MockStorageApi implements StorageApi {
|
||||
key,
|
||||
presence: 'present',
|
||||
value: data,
|
||||
newValue: data,
|
||||
};
|
||||
}
|
||||
return {
|
||||
key,
|
||||
presence: 'absent',
|
||||
value: undefined,
|
||||
newValue: undefined,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -95,7 +89,6 @@ export class MockStorageApi implements StorageApi {
|
||||
key,
|
||||
presence: 'present',
|
||||
value: serialized,
|
||||
newValue: serialized,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -105,7 +98,6 @@ export class MockStorageApi implements StorageApi {
|
||||
key,
|
||||
presence: 'absent',
|
||||
value: undefined,
|
||||
newValue: undefined,
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -36,12 +36,12 @@ export class DefaultStarredEntitiesApi implements StarredEntitiesApi {
|
||||
this.settingsStore = opts.storageApi.forBucket('starredEntities');
|
||||
|
||||
this.starredEntities = new Set(
|
||||
this.settingsStore.get<string[]>('entityRefs') ?? [],
|
||||
this.settingsStore.snapshot<string[]>('entityRefs').value ?? [],
|
||||
);
|
||||
|
||||
this.settingsStore.observe$<string[]>('entityRefs').subscribe({
|
||||
next: next => {
|
||||
this.starredEntities = new Set(next.newValue ?? []);
|
||||
this.starredEntities = new Set(next.value ?? []);
|
||||
this.notifyChanges();
|
||||
},
|
||||
});
|
||||
|
||||
@@ -41,19 +41,19 @@ describe('performMigrationToTheNewBucket', () => {
|
||||
'entity:Component:default:a',
|
||||
'entity:template:custom:b',
|
||||
]);
|
||||
expect(oldBucket.get('starredEntities')).not.toBeUndefined();
|
||||
expect(oldBucket.snapshot('starredEntities').value).not.toBeUndefined();
|
||||
|
||||
await performMigrationToTheNewBucket({ storageApi: mockStorage });
|
||||
|
||||
// read NEW bucket
|
||||
expect(await newBucket.get('entityRefs')).toEqual([
|
||||
expect(await newBucket.snapshot('entityRefs').value).toEqual([
|
||||
'component:default/c',
|
||||
'component:default/a',
|
||||
'template:custom/b',
|
||||
]);
|
||||
|
||||
// OLD bucket should be removed
|
||||
expect(oldBucket.get('starredEntities')).toBeUndefined();
|
||||
expect(oldBucket.snapshot('starredEntities').value).toBeUndefined();
|
||||
});
|
||||
|
||||
it('should ignore invalid entries', async () => {
|
||||
@@ -67,15 +67,17 @@ describe('performMigrationToTheNewBucket', () => {
|
||||
'entity:Component:a',
|
||||
'invalid',
|
||||
]);
|
||||
expect(oldBucket.get('starredEntities')).not.toBeUndefined();
|
||||
expect(oldBucket.snapshot('starredEntities')).not.toBeUndefined();
|
||||
|
||||
await performMigrationToTheNewBucket({ storageApi: mockStorage });
|
||||
|
||||
// read NEW bucket
|
||||
expect(await newBucket.get('entityRefs')).toEqual(['component:default/a']);
|
||||
expect(await newBucket.snapshot('entityRefs').value).toEqual([
|
||||
'component:default/a',
|
||||
]);
|
||||
|
||||
// OLD bucket should be removed
|
||||
expect(oldBucket.get('starredEntities')).toBeUndefined();
|
||||
expect(oldBucket.snapshot('starredEntities').value).toBeUndefined();
|
||||
});
|
||||
|
||||
it('should skip migration without old starred entities', async () => {
|
||||
@@ -88,7 +90,7 @@ describe('performMigrationToTheNewBucket', () => {
|
||||
await performMigrationToTheNewBucket({ storageApi: mockStorage });
|
||||
|
||||
// read NEW bucket
|
||||
expect(newBucket.get('entityRefs')).toEqual(expectedEntries);
|
||||
expect(newBucket.snapshot('entityRefs').value).toEqual(expectedEntries);
|
||||
});
|
||||
|
||||
it('should skip migration with non-array old starred entities', async () => {
|
||||
@@ -105,9 +107,9 @@ describe('performMigrationToTheNewBucket', () => {
|
||||
await performMigrationToTheNewBucket({ storageApi: mockStorage });
|
||||
|
||||
// read NEW bucket
|
||||
expect(newBucket.get('entityRefs')).toEqual(expectedEntries);
|
||||
expect(newBucket.snapshot('entityRefs').value).toEqual(expectedEntries);
|
||||
|
||||
// OLD bucket should be unchanged
|
||||
expect(oldBucket.get('starredEntities')).toBe('invalid');
|
||||
expect(oldBucket.snapshot('starredEntities').value).toBe('invalid');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -35,13 +35,15 @@ export async function performMigrationToTheNewBucket({
|
||||
const source = storageApi.forBucket('settings');
|
||||
const target = storageApi.forBucket('starredEntities');
|
||||
|
||||
const oldStarredEntities = source.get('starredEntities');
|
||||
const oldStarredEntities = source.snapshot('starredEntities').value;
|
||||
|
||||
if (!isArray(oldStarredEntities)) {
|
||||
// nothing to do
|
||||
return;
|
||||
}
|
||||
const targetEntities = new Set(target.get<string[]>('entityRefs') ?? []);
|
||||
const targetEntities = new Set(
|
||||
target.snapshot<string[]>('entityRefs').value ?? [],
|
||||
);
|
||||
|
||||
oldStarredEntities
|
||||
.filter(isString)
|
||||
|
||||
Reference in New Issue
Block a user