Skip to content

Commit

Permalink
feat: add a function to verify and return Abilities. (#1252)
Browse files Browse the repository at this point in the history
Given a list of strings representing capability names (`ServiceAbility`s),
verify that all the strings are valid `ServiceAbility`s and return
`ServiceAbility[]`.

`ServiceAbility[]` is still just a list of strings, but this helps us play
nice with Typescript.

Inspired by #1250
  • Loading branch information
travis committed Jan 11, 2024
1 parent 80037f9 commit 2f026a2
Show file tree
Hide file tree
Showing 4 changed files with 66 additions and 2 deletions.
14 changes: 12 additions & 2 deletions packages/capabilities/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -633,9 +633,9 @@ export type PlanGetFailure = PlanNotFound
// Top
export type Top = InferInvokedCapability<typeof top>

export type Abilities = TupleToUnion<AbilitiesArray>
export type ServiceAbility = TupleToUnion<ServiceAbilityArray>

export type AbilitiesArray = [
export type ServiceAbilityArray = [
Top['can'],
ProviderAdd['can'],
Space['can'],
Expand Down Expand Up @@ -677,3 +677,13 @@ export type AbilitiesArray = [
Usage['can'],
UsageReport['can']
]

/**
* @deprecated use ServiceAbility
*/
export type Abilities = ServiceAbility

/**
* @deprecated use ServiceAbilityArray
*/
export type AbilitiesArray = ServiceAbilityArray
32 changes: 32 additions & 0 deletions packages/w3up-client/src/ability.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { abilitiesAsStrings } from '@web3-storage/capabilities'

const setOfAbilities = new Set(abilitiesAsStrings)

/**
* Verify and return Abilities.
*
* Given a list of strings representing capability names (Abilities),
* verify that all the strings are valid Abilities and return Abilities[].
*
* Abilities[] is still just a list of strings, but this helps us play
* nice with Typescript.
*
* @param {string[]} abilities
* @returns {import('@web3-storage/capabilities/types').ServiceAbility[]}
*/
export function asAbilities(abilities) {
for (const ability of abilities) {
if (
!setOfAbilities.has(
/** @type {import('@web3-storage/capabilities/types').ServiceAbility} */ (
ability
)
)
) {
throw new Error(`${ability} is not a supported capability`)
}
}
return /** @type {import('@web3-storage/capabilities/types').ServiceAbility[]} */ (
abilities
)
}
1 change: 1 addition & 0 deletions packages/w3up-client/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { generate } from '@ucanto/principal/rsa'
import { Client } from './client.js'
export * as Result from './result.js'
export * as Account from './account.js'
export * from './ability.js'

/**
* Create a new w3up client.
Expand Down
21 changes: 21 additions & 0 deletions packages/w3up-client/test/ability.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import assert from 'assert'
import { asAbilities } from '../src/ability.js'

describe('abilities', () => {
it('should return the passed argument if all abilities are valid', async () => {
const abilities = ['store/add', 'upload/add']
assert.equal(asAbilities(abilities), abilities)
})

it('should throw an error if one of the abilities is not supported', async () => {
assert.throws(
() => {
asAbilities(['foo/bar'])
},
{
name: 'Error',
message: 'foo/bar is not a supported capability',
}
)
})
})

0 comments on commit 2f026a2

Please sign in to comment.