Skip to content

Commit

Permalink
Add isSnapId utility function (#2808)
Browse files Browse the repository at this point in the history
This adds a `isSnapId` function which accepts any value, and returns a
boolean if the input is a valid Snap ID or not.

This is extracted from #2634.
  • Loading branch information
Mrtenz authored Oct 8, 2024
1 parent e5aeb16 commit a80db22
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 6 deletions.
4 changes: 2 additions & 2 deletions packages/snaps-utils/coverage.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"branches": 99.74,
"functions": 98.91,
"functions": 98.92,
"lines": 99.45,
"statements": 96.3
"statements": 96.31
}
36 changes: 32 additions & 4 deletions packages/snaps-utils/src/snaps.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,37 @@ import {
assertIsValidSnapId,
verifyRequestedSnapPermissions,
stripSnapPrefix,
isSnapId,
} from './snaps';
import { MOCK_SNAP_ID } from './test-utils';
import { uri, WALLET_SNAP_PERMISSION_KEY } from './types';

describe('isSnapId', () => {
it.each(['npm:@metamask/test-snap-bip44', 'local:http://localhost:8000'])(
'returns `true` for "%s"',
(value) => {
expect(isSnapId(value)).toBe(true);
},
);

it.each([
undefined,
{},
null,
true,
2,
'foo:bar',
' local:http://localhost:8000',
'local:http://localhost:8000 ',
'local:http://localhost:8000\n',
'local:http://localhost:8000\r',
'local:😎',
'local:␡',
])('returns `false` for "%s"', (value) => {
expect(isSnapId(value)).toBe(false);
});
});

describe('assertIsValidSnapId', () => {
it.each([undefined, {}, null, true, 2])(
'throws for non-strings (#%#)',
Expand Down Expand Up @@ -239,7 +267,7 @@ describe('isSnapPermitted', () => {
{
type: 'snapIds',
value: {
foo: {},
[MOCK_SNAP_ID]: {},
},
},
],
Expand Down Expand Up @@ -273,9 +301,9 @@ describe('isSnapPermitted', () => {
},
};

expect(isSnapPermitted(validPermissions, 'foo')).toBe(true);
expect(isSnapPermitted(invalidPermissions1, 'foo')).toBe(false);
expect(isSnapPermitted(invalidPermissions2, 'foo')).toBe(false);
expect(isSnapPermitted(validPermissions, MOCK_SNAP_ID)).toBe(true);
expect(isSnapPermitted(invalidPermissions1, MOCK_SNAP_ID)).toBe(false);
expect(isSnapPermitted(invalidPermissions2, MOCK_SNAP_ID)).toBe(false);
});

describe('verifyRequestedSnapPermissions', () => {
Expand Down
12 changes: 12 additions & 0 deletions packages/snaps-utils/src/snaps.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import type { BlockReason } from '@metamask/snaps-registry';
import type { SnapId, Snap as TruncatedSnap } from '@metamask/snaps-sdk';
import type { Struct } from '@metamask/superstruct';
import {
is,
empty,
enums,
intersection,
Expand Down Expand Up @@ -311,6 +312,17 @@ export function stripSnapPrefix(snapId: string): string {
return snapId.replace(getSnapPrefix(snapId), '');
}

/**
* Check if the given value is a valid snap ID. This function is a type guard,
* and will narrow the type of the value to `SnapId` if it returns `true`.
*
* @param value - The value to check.
* @returns `true` if the value is a valid snap ID, and `false` otherwise.
*/
export function isSnapId(value: unknown): value is SnapId {
return is(value, SnapIdStruct);
}

/**
* Assert that the given value is a valid snap ID.
*
Expand Down

0 comments on commit a80db22

Please sign in to comment.