Skip to content

Commit

Permalink
chore: address review
Browse files Browse the repository at this point in the history
  • Loading branch information
vasco-santos committed Apr 5, 2024
1 parent 7f0c84e commit 0668957
Show file tree
Hide file tree
Showing 18 changed files with 476 additions and 490 deletions.
4 changes: 4 additions & 0 deletions packages/capabilities/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,10 @@
"types": "./dist/src/filecoin/dealer.d.ts",
"import": "./src/filecoin/dealer.js"
},
"./web3.storage/blob": {
"types": "./dist/src/web3.storage/blob.d.ts",
"import": "./src/web3.storage/blob.js"
},
"./types": {
"types": "./dist/src/types.d.ts",
"import": "./src/types.js"
Expand Down
200 changes: 3 additions & 197 deletions packages/capabilities/src/blob.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,8 @@
*
* @module
*/
import { capability, Link, Schema, ok, fail } from '@ucanto/validator'
import {
equal,
equalBlob,
equalContent,
equalWith,
checkLink,
SpaceDID,
and,
} from './utils.js'
import { capability, Schema } from '@ucanto/validator'
import { equalBlob, equalWith, SpaceDID } from './utils.js'

/**
* Agent capabilities for Blob protocol
Expand Down Expand Up @@ -79,192 +71,6 @@ export const add = capability({
derives: equalBlob,
})

/**
* `blob/remove` capability can be used to remove the stored Blob from the (memory)
* space identified by `with` field.
*/
export const remove = capability({
can: 'blob/remove',
/**
* DID of the (memory) space where Blob is intended to
* be stored.
*/
with: SpaceDID,
nb: Schema.struct({
/**
* A multihash digest of the blob payload bytes, uniquely identifying blob.
*/
content: Schema.bytes(),
}),
derives: equalContent,
})

/**
* `blob/list` capability can be invoked to request a list of stored Blobs in the
* (memory) space identified by `with` field.
*/
export const list = capability({
can: 'blob/list',
/**
* DID of the (memory) space where Blob is intended to
* be stored.
*/
with: SpaceDID,
nb: Schema.struct({
/**
* A pointer that can be moved back and forth on the list.
* It can be used to paginate a list for instance.
*/
cursor: Schema.string().optional(),
/**
* Maximum number of items per page.
*/
size: Schema.integer().optional(),
/**
* If true, return page of results preceding cursor. Defaults to false.
*/
pre: Schema.boolean().optional(),
}),
derives: (claimed, delegated) => {
if (claimed.with !== delegated.with) {
return fail(
`Expected 'with: "${delegated.with}"' instead got '${claimed.with}'`
)
}
return ok({})
},
})

/**
* Service capabilities for Blob protocol
*/
/**
* Capability can only be delegated (but not invoked) allowing audience to
* derived any `web3.storage/blob/` prefixed capability for the (memory) space identified
* by DID in the `with` field.
*/
export const serviceBlob = capability({
can: 'web3.storage/blob/*',
/**
* DID of the (memory) space where Blob is intended to
* be stored.
*/
with: SpaceDID,
derives: equalWith,
})

/**
* `web3.storage/blob//allocate` capability can be invoked to create a memory
* address where blob content can be written via HTTP PUT request.
*/
export const allocate = capability({
can: 'web3.storage/blob/allocate',
/**
* Provider DID.
*/
with: Schema.did(),
nb: Schema.struct({
/**
* Blob to allocate on the space.
*/
blob: blobStruct,
/**
* The Link for an Add Blob task, that caused an allocation
*/
cause: Link,
/**
* DID of the user space where allocation takes place
*/
space: SpaceDID,
}),
derives: (claim, from) => {
return (
and(equalWith(claim, from)) ||
and(equalBlob(claim, from)) ||
and(checkLink(claim.nb.cause, from.nb.cause, 'cause')) ||
and(equal(claim.nb.space, from.nb.space, 'space')) ||
ok({})
)
},
})

/**
* `http/put` capability invocation MAY be performed by any agent on behalf of the subject.
* The `blob/add` provider MUST add `/http/put` effect and capture private key of the
* `subject` in the `meta` field so that any agent could perform it.
*/
export const put = capability({
can: 'http/put',
/**
* DID of the (memory) space where Blob is intended to
* be stored.
*/
with: SpaceDID,
nb: Schema.struct({
/**
* Blob to allocate on the space.
*/
blob: blobStruct,
/**
* Blob to accept.
*/
address: Schema.struct({
/**
* HTTP(S) location that can receive blob content via HTTP PUT request.
*/
url: Schema.string(),
/**
* HTTP headers.
*/
headers: Schema.unknown(),
}).optional(),
}),
derives: (claim, from) => {
return (
and(equalWith(claim, from)) ||
and(equalBlob(claim, from)) ||
and(equal(claim.nb.address?.url, from.nb.address, 'url')) ||
and(equal(claim.nb.address?.headers, from.nb.address, 'headers')) ||
ok({})
)
},
})

/**
* `blob/accept` capability invocation should either succeed when content is
* delivered on allocated address or fail if no content is allocation expires
* without content being delivered.
*/
export const accept = capability({
can: 'web3.storage/blob/accept',
/**
* Provider DID.
*/
with: Schema.did(),
nb: Schema.struct({
/**
* Blob to accept.
*/
blob: blobStruct,
/**
* Expiration..
*/
exp: Schema.integer(),
}),
derives: (claim, from) => {
const result = equalBlob(claim, from)
if (result.error) {
return result
} else if (claim.nb.exp !== undefined && from.nb.exp !== undefined) {
return claim.nb.exp > from.nb.exp
? fail(`exp constraint violation: ${claim.nb.exp} > ${from.nb.exp}`)
: ok({})
} else {
return ok({})
}
},
})

// ⚠️ We export imports here so they are not omitted in generated typedes
// @see https://github.com/microsoft/TypeScript/issues/51548
export { Schema, Link }
export { Schema }
55 changes: 55 additions & 0 deletions packages/capabilities/src/http.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/**
* HTTP Capabilities.
*
* These can be imported directly with:
* ```js
* import * as HTTP from '@web3-storage/capabilities/http'
* ```
*
* @module
*/
import { capability, Schema, ok } from '@ucanto/validator'
import { blobStruct } from './blob.js'
import { equal, equalBlob, equalWith, SpaceDID, and } from './utils.js'

/**
* `http/put` capability invocation MAY be performed by any agent on behalf of the subject.
* The `blob/add` provider MUST add `/http/put` effect and capture private key of the
* `subject` in the `meta` field so that any agent could perform it.
*/
export const put = capability({
can: 'http/put',
/**
* DID of the (memory) space where Blob is intended to
* be stored.
*/
with: SpaceDID,
nb: Schema.struct({
/**
* Blob to allocate on the space.
*/
blob: blobStruct,
/**
* Blob to accept.
*/
address: Schema.struct({
/**
* HTTP(S) location that can receive blob content via HTTP PUT request.
*/
url: Schema.string(),
/**
* HTTP headers.
*/
headers: Schema.unknown(),
}).optional(),
}),
derives: (claim, from) => {
return (
and(equalWith(claim, from)) ||
and(equalBlob(claim, from)) ||
and(equal(claim.nb.address?.url, from.nb.address, 'url')) ||
and(equal(claim.nb.address?.headers, from.nb.address, 'headers')) ||
ok({})
)
},
})
12 changes: 6 additions & 6 deletions packages/capabilities/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ import * as UCAN from './ucan.js'
import * as Plan from './plan.js'
import * as Usage from './usage.js'
import * as Blob from './blob.js'
import * as W3sBlob from './web3.storage/blob.js'
import * as HTTP from './http.js'

export {
Access,
Expand Down Expand Up @@ -90,10 +92,8 @@ export const abilitiesAsStrings = [
Usage.report.can,
Blob.blob.can,
Blob.add.can,
Blob.remove.can,
Blob.list.can,
Blob.serviceBlob.can,
Blob.put.can,
Blob.allocate.can,
Blob.accept.can,
W3sBlob.blob.can,
W3sBlob.allocate.can,
W3sBlob.accept.can,
HTTP.put.can,
]
Loading

0 comments on commit 0668957

Please sign in to comment.