Skip to content

Commit

Permalink
feat(ucanto): upstream changes from w3 branch (#54)
Browse files Browse the repository at this point in the history
* feat(ucanto): add id to the client
* feat(ucanto): add link function to CAR codec
* chore: improve release config
  • Loading branch information
Gozala authored Jun 24, 2022
1 parent 4fa6876 commit 861e997
Show file tree
Hide file tree
Showing 8 changed files with 45 additions and 24 deletions.
6 changes: 3 additions & 3 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -97,9 +97,9 @@ jobs:
command: pr
upstream_owner: ${{ github.repository_owner }}
upstream_repo: ${{ github.event.repository.name }}
description: 'release master'
title: 'chore: release master'
message: 'chore: release master'
description: '🚢 release ucanto'
title: 'chore: release ucanto'
message: 'chore: release ucanto'
branch: release-please/branches/main
primary: main
force: true
Expand Down
1 change: 1 addition & 0 deletions packages/client/src/connection.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ class Connection {
* @param {API.ConnectionOptions<T>} options
*/
constructor(options) {
this.id = options.id
this.options = options
this.encoder = options.encoder
this.decoder = options.decoder
Expand Down
21 changes: 12 additions & 9 deletions packages/client/test/client.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,13 @@ import * as HTTP from '@ucanto/transport/http'
import * as CAR from '@ucanto/transport/car'
import * as CBOR from '@ucanto/transport/cbor'
import * as Service from './service.js'
import { alice, bob, mallory, service as web3Storage } from './fixtures.js'
import { alice, bob, mallory, service as w3 } from './fixtures.js'
import fetch from '@web-std/fetch'

test('encode inovocation', async () => {
/** @type {Client.ConnectionView<Service.Service>} */
const connection = Client.connect({
id: w3.authority,
channel: HTTP.open({ url: new URL('about:blank'), fetch }),
encoder: CAR,
decoder: CBOR,
Expand All @@ -21,7 +22,7 @@ test('encode inovocation', async () => {

const add = Client.invoke({
issuer: alice,
audience: web3Storage,
audience: w3,
capability: {
can: 'store/add',
with: alice.did(),
Expand All @@ -42,7 +43,7 @@ test('encode inovocation', async () => {
const [invocation] = request
assert.equal(request.length, 1)
assert.equal(invocation.issuer.did(), alice.did())
assert.equal(invocation.audience.did(), web3Storage.did())
assert.equal(invocation.audience.did(), w3.did())
assert.deepEqual(invocation.proofs, [])
assert.deepEqual(invocation.capabilities, [
{
Expand All @@ -61,6 +62,7 @@ test('encode delegated invocation', async () => {

/** @type {Client.ConnectionView<Service.Service>} */
const connection = Client.connect({
id: w3.authority,
channel: HTTP.open({ url: new URL('about:blank'), fetch }),
encoder: CAR,
decoder: CBOR,
Expand All @@ -79,7 +81,7 @@ test('encode delegated invocation', async () => {

const add = Client.invoke({
issuer: bob,
audience: web3Storage,
audience: w3,
capability: {
can: 'store/add',
with: alice.did(),
Expand All @@ -90,7 +92,7 @@ test('encode delegated invocation', async () => {

const remove = Client.invoke({
issuer: alice,
audience: web3Storage,
audience: w3,
capability: {
can: 'store/remove',
with: alice.did(),
Expand All @@ -105,7 +107,7 @@ test('encode delegated invocation', async () => {
assert.equal(request.length, 2)

assert.equal(add.issuer.did(), bob.did())
assert.equal(add.audience.did(), web3Storage.did())
assert.equal(add.audience.did(), w3.did())
assert.deepEqual(add.capabilities, [
{
can: 'store/add',
Expand All @@ -123,7 +125,7 @@ test('encode delegated invocation', async () => {
assert.deepEqual(delegation.capabilities, proof.capabilities)

assert.equal(remove.issuer.did(), alice.did())
assert.equal(remove.audience.did(), web3Storage.did())
assert.equal(remove.audience.did(), w3.did())
assert.deepEqual(remove.proofs, [])
assert.deepEqual(remove.capabilities, [
{
Expand All @@ -138,6 +140,7 @@ test('encode delegated invocation', async () => {
const service = Service.create()
/** @type {Client.ConnectionView<Service.Service>} */
const connection = Client.connect({
id: w3.authority,
channel: HTTP.open({
url: new URL('about:blank'),
fetch: async (url, input) => {
Expand Down Expand Up @@ -180,7 +183,7 @@ test('execute', async () => {

const add = Client.invoke({
issuer: alice,
audience: web3Storage,
audience: w3,
capability: {
can: 'store/add',
with: alice.did(),
Expand All @@ -191,7 +194,7 @@ test('execute', async () => {

const remove = Client.invoke({
issuer: alice,
audience: web3Storage,
audience: w3,
capability: {
can: 'store/remove',
with: alice.did(),
Expand Down
21 changes: 13 additions & 8 deletions packages/interface/src/lib.ts
Original file line number Diff line number Diff line change
Expand Up @@ -292,21 +292,24 @@ export interface HandlerExecutionError extends Failure {

export type API<T> = T[keyof T]

export interface ConnectionOptions<T> extends Transport.EncodeOptions {
export interface OutpboundTranpsortOptions {
readonly encoder: Transport.RequestEncoder
readonly decoder: Transport.ResponseDecoder
readonly channel: Transport.Channel<T>
}

export interface Connection<T> extends Phantom<T> {
readonly encoder: Transport.RequestEncoder
readonly decoder: Transport.ResponseDecoder
export interface ConnectionOptions<T>
extends Transport.EncodeOptions,
OutpboundTranpsortOptions {
readonly id: Identity
readonly channel: Transport.Channel<T>
}

export interface Connection<T> extends Phantom<T>, ConnectionOptions<T> {
readonly id: Identity
readonly hasher: MultihashHasher
}

export interface ConnectionView<T> extends Connection<T> {
id: Identity
execute<
C extends Capability,
I extends Transport.Tuple<ServiceInvocation<C, T>>
Expand All @@ -315,7 +318,7 @@ export interface ConnectionView<T> extends Connection<T> {
): Await<InferServiceInvocations<I, T>>
}

export interface TranpsortOptions {
export interface InboundTransportOptions {
/**
* Request decoder which is will be used by a server to decode HTTP Request
* into an invocation `Batch` that will be executed using a `service`.
Expand All @@ -341,7 +344,9 @@ export interface ValidatorOptions {
readonly resolve?: InvocationContext['resolve']
}

export interface ServerOptions extends TranpsortOptions, ValidatorOptions {
export interface ServerOptions
extends InboundTransportOptions,
ValidatorOptions {
/**
* Service DID which will be used to verify that received invocation
* audience matches it.
Expand Down
1 change: 1 addition & 0 deletions packages/server/test/handler.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ test('checks service id', async () => {
})

const client = Client.connect({
id: w3.authority,
encoder: CAR,
decoder: CBOR,
channel: server,
Expand Down
3 changes: 3 additions & 0 deletions packages/server/test/server.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ test('encode delegated invocation', async () => {
})

const connection = Client.connect({
id: w3.authority,
encoder: CAR,
decoder: CBOR,
channel: server,
Expand Down Expand Up @@ -166,6 +167,7 @@ test('unknown handler', async () => {
})

const connection = Client.connect({
id: w3.authority,
encoder: CAR,
decoder: CBOR,
channel: server,
Expand Down Expand Up @@ -233,6 +235,7 @@ test('execution error', async () => {
})

const connection = Client.connect({
id: w3.authority,
encoder: CAR,
decoder: CBOR,
channel: server,
Expand Down
13 changes: 9 additions & 4 deletions packages/transport/src/car/codec.js
Original file line number Diff line number Diff line change
Expand Up @@ -108,16 +108,21 @@ export const decode = async (bytes) => {
return { roots, blocks }
}

/**
* @param {Uint8Array} bytes
* @param {{hasher?: API.MultihashHasher }} [options]
*/
export const link = async (bytes, { hasher = sha256 } = {}) =>
/** @type {UCAN.Link<Model, typeof code, number> & import('multiformats').CID} */
(createLink(code, await hasher.digest(bytes)))

/**
* @param {Partial<Model>} data
* @param {{hasher?: API.MultihashHasher }} [options]
*/
export const write = async (data, { hasher = sha256 } = {}) => {
const bytes = encode(data)
const digest = await hasher.digest(bytes)
const cid = await link(bytes)

const cid =
/** @type {UCAN.Link<Model, typeof code, number> & import('multiformats').CID}*/
(createLink(code, digest))
return { bytes, cid }
}
3 changes: 3 additions & 0 deletions packages/transport/test/car.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,9 @@ test('codec', async () => {
const car = await CAR.codec.write({ roots: [root] })
assert.deepEqual(car.bytes, bytes)
assert.ok(asLink(car.cid) === car.cid)

const link = await CAR.codec.link(car.bytes)
assert.deepEqual(car.cid, link)
})

test('car writer', async () => {
Expand Down

0 comments on commit 861e997

Please sign in to comment.