From 77bf7ea8c67c5bb1bbce9b298fd72919dad7bd43 Mon Sep 17 00:00:00 2001 From: Travis Vachon Date: Tue, 10 Oct 2023 15:26:18 +0100 Subject: [PATCH 1/3] fix!: remove websocket support (#966) when you try to use `@web3-storage/access` in a new next.js repository you get errors like this: ``` Import trace for requested module: ./node_modules/ipfs-utils/src/http/fetch.js ./node_modules/@web3-storage/upload-client/src/store.js ./node_modules/@web3-storage/upload-client/src/index.js ./node_modules/@web3-storage/w3up-client/src/client.js ./node_modules/@web3-storage/w3up-client/src/index.node.js ./app/utils/utils.ts ./app/page.tsx ./node_modules/ws/lib/buffer-util.js Module not found: Can't resolve 'bufferutil' in '/Users/travis/dev/pl/sample-w3/node_modules/ws/lib' Import trace for requested module: ./node_modules/ws/lib/buffer-util.js ./node_modules/ws/lib/websocket.js ./node_modules/ws/index.js ./node_modules/isomorphic-ws/node.js ./node_modules/@web3-storage/access/src/utils/ws.js ./node_modules/@web3-storage/access/src/agent-use-cases.js ./node_modules/@web3-storage/access/src/agent.js ./node_modules/@web3-storage/w3up-client/src/index.node.js ./app/utils/utils.ts ./app/page.tsx ./node_modules/ws/lib/validation.js Module not found: Can't resolve 'utf-8-validate' in '/Users/travis/dev/pl/sample-w3/node_modules/ws/lib' Import trace for requested module: ./node_modules/ws/lib/validation.js ./node_modules/ws/lib/receiver.js ./node_modules/ws/index.js ./node_modules/isomorphic-ws/node.js ./node_modules/@web3-storage/access/src/utils/ws.js ./node_modules/@web3-storage/access/src/agent-use-cases.js ./node_modules/@web3-storage/access/src/agent.js ./node_modules/@web3-storage/w3up-client/src/index.node.js ./app/utils/utils.ts ./app/page.tsx ``` Which looks like the same thing as https://github.com/netlify/netlify-lambda/issues/179 and shows up a few other times in similar repos. While we could instruct our users to add some build configuration to go away, we don't use websockets in production in any of our flows and imho we should just remove this dependency. The easiest way to do this is to remove the cli as well, and since we don't use that anywhere that also seems like a good idea. --- .vscode/settings.json | 5 + packages/access-client/package.json | 13 +- packages/access-client/src/agent-use-cases.js | 71 +--- packages/access-client/src/agent.js | 9 - packages/access-client/src/awake/channel.js | 336 ------------------ packages/access-client/src/awake/encoding.js | 14 - packages/access-client/src/awake/messages.js | 56 --- packages/access-client/src/awake/peer.js | 206 ----------- packages/access-client/src/awake/readme.md | 22 -- packages/access-client/src/awake/types.ts | 133 ------- .../access-client/src/cli/cmd-create-space.js | 52 --- packages/access-client/src/cli/cmd-link.js | 79 ---- packages/access-client/src/cli/cmd-setup.js | 49 --- packages/access-client/src/cli/cmd-whoami.js | 53 --- packages/access-client/src/cli/config.js | 22 -- packages/access-client/src/cli/index.js | 156 -------- packages/access-client/src/cli/utils.js | 70 ---- packages/access-client/src/types.ts | 32 -- packages/access-client/src/utils/ws.js | 229 ------------ pnpm-lock.yaml | 241 ++----------- 20 files changed, 30 insertions(+), 1818 deletions(-) create mode 100644 .vscode/settings.json delete mode 100644 packages/access-client/src/awake/channel.js delete mode 100644 packages/access-client/src/awake/encoding.js delete mode 100644 packages/access-client/src/awake/messages.js delete mode 100644 packages/access-client/src/awake/peer.js delete mode 100644 packages/access-client/src/awake/readme.md delete mode 100644 packages/access-client/src/awake/types.ts delete mode 100644 packages/access-client/src/cli/cmd-create-space.js delete mode 100644 packages/access-client/src/cli/cmd-link.js delete mode 100644 packages/access-client/src/cli/cmd-setup.js delete mode 100644 packages/access-client/src/cli/cmd-whoami.js delete mode 100644 packages/access-client/src/cli/config.js delete mode 100755 packages/access-client/src/cli/index.js delete mode 100644 packages/access-client/src/cli/utils.js delete mode 100644 packages/access-client/src/utils/ws.js diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 000000000..43734c896 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,5 @@ +{ + "javascript.format.insertSpaceBeforeFunctionParenthesis": false, + "typescript.format.insertSpaceBeforeFunctionParenthesis": false, + "typescript.tsdk": "node_modules/typescript/lib" +} diff --git a/packages/access-client/package.json b/packages/access-client/package.json index 8fbd00ded..3c34a012a 100644 --- a/packages/access-client/package.json +++ b/packages/access-client/package.json @@ -13,9 +13,6 @@ "type": "module", "types": "dist/src/index.d.ts", "main": "src/index.js", - "bin": { - "w3access": "./src/cli/index.js" - }, "scripts": { "lint": "tsc --build && eslint '**/*.{js,ts}' && prettier --check '**/*.{js,ts,yml,json}' --ignore-path ../../.gitignore", "build": "tsc --build", @@ -71,18 +68,11 @@ "@web3-storage/did-mailto": "workspace:^", "bigint-mod-arith": "^3.1.2", "conf": "10.2.0", - "inquirer": "^9.1.4", - "isomorphic-ws": "^5.0.0", - "kysely": "^0.23.4", "multiformats": "^12.1.2", "one-webcrypto": "^1.0.3", - "ora": "^6.1.2", "p-defer": "^4.0.0", - "p-wait-for": "^5.0.0", "type-fest": "^3.3.0", - "uint8arrays": "^4.0.6", - "ws": "^8.12.0", - "zod": "^3.20.2" + "uint8arrays": "^4.0.6" }, "devDependencies": { "@types/assert": "^1.5.6", @@ -97,7 +87,6 @@ "hd-scripts": "^4.0.0", "mocha": "^10.2.0", "playwright-test": "^12.3.4", - "sade": "^1.8.1", "sinon": "^15.0.3", "typescript": "5.2.2", "watch": "^1.0.2" diff --git a/packages/access-client/src/agent-use-cases.js b/packages/access-client/src/agent-use-cases.js index d46fa7155..30e45dc4b 100644 --- a/packages/access-client/src/agent-use-cases.js +++ b/packages/access-client/src/agent-use-cases.js @@ -1,10 +1,9 @@ import { addSpacesFromDelegations, Agent as AccessAgent } from './agent.js' import * as Ucanto from '@ucanto/interface' import * as Access from '@web3-storage/capabilities/access' -import { bytesToDelegations, stringToDelegation } from './encoding.js' +import { bytesToDelegations } from './encoding.js' import { Provider } from '@web3-storage/capabilities' import * as w3caps from '@web3-storage/capabilities' -import { Websocket, AbortError } from './utils/ws.js' import { AgentData, isSessionProof } from './agent-data.js' import * as ucanto from '@ucanto/core' import { DID as DIDValidator } from '@ucanto/validator' @@ -130,43 +129,6 @@ export async function pollAccessClaimUntil( } } -/** - * @param {AccessAgent} access - * @param {object} [opts] - * @param {AbortSignal} [opts.signal] - * @deprecated - use waitForAuthorizationOnSocket - */ -export async function waitForDelegationOnSocket(access, opts) { - const ws = new Websocket(access.url, 'validate-ws') - await ws.open(opts) - - ws.send({ - did: access.did(), - }) - - try { - const msg = await ws.awaitMsg(opts) - - if (msg.type === 'timeout') { - await ws.close(1000, 'agent got timeout waiting for validation') - throw new Error('Email validation timed out.') - } - - if (msg.type === 'delegation') { - const delegation = stringToDelegation(msg.delegation) - await ws.close(1000, 'received delegation, agent is done with ws') - return delegation - } - } catch (error) { - if (error instanceof AbortError) { - await ws.close(1000, 'AbortError: agent failed to get delegation') - throw new TypeError('Failed to get delegation', { cause: error }) - } - throw error - } - throw new TypeError('Failed to get delegation') -} - /** * @template [T={}] * @typedef {{ signal?: AbortSignal } & T} AuthorizationWaiterOpts @@ -176,19 +138,6 @@ export async function waitForDelegationOnSocket(access, opts) { * @typedef {(accessAgent: AccessAgent, opts: AuthorizationWaiterOpts) => Promise>} AuthorizationWaiter */ -/** - * Wait for the authorization process to complete by waiting on a - * well-known websocket endpoint for the access-api server to - * receive and forward a session delegation from the authorization - * email flow. - * - * @type AuthorizationWaiter - */ -export async function waitForAuthorizationOnSocket(access, opts = {}) { - const delegation = await waitForDelegationOnSocket(access, opts) - return [delegation] -} - /** * Wait for authorization process to complete by polling executions of the * `access/claim` capability and waiting for the result to include @@ -260,24 +209,6 @@ export async function authorizeWaitAndClaim(accessAgent, email, opts) { }) } -/** - * Request authorization of a session allowing this agent to issue UCANs - * signed by the passed email address. - * - * @param {AccessAgent} access - * @param {`${string}@${string}`} email - * @param {object} [opts] - * @param {AbortSignal} [opts.signal] - * @param {Iterable<{ can: Ucanto.Ability }>} [opts.capabilities] - * @deprecated use authorizeWaitAndClaim directly going forward, passing it the expectAuthorization: waitForAuthorizationOnSocket to replicate this function's behavior - */ -export async function authorizeWithSocket(access, email, opts) { - return authorizeWaitAndClaim(access, email, { - ...opts, - expectAuthorization: waitForAuthorizationOnSocket, - }) -} - /** * Invokes voucher/redeem for the free tier, wait on the websocket for the voucher/claim and invokes it * diff --git a/packages/access-client/src/agent.js b/packages/access-client/src/agent.js index 6f2dbbfef..157eca854 100644 --- a/packages/access-client/src/agent.js +++ b/packages/access-client/src/agent.js @@ -6,7 +6,6 @@ import * as Ucanto from '@ucanto/interface' import * as CAR from '@ucanto/transport/car' import * as HTTP from '@ucanto/transport/http' import * as ucanto from '@ucanto/core' -import { Peer } from './awake/peer.js' import * as Space from '@web3-storage/capabilities/space' import * as Access from '@web3-storage/capabilities/access' @@ -562,14 +561,6 @@ export class Agent { ) } - /** - * - * @param {import('../src/awake/types').Channel} channel - */ - peer(channel) { - return new Peer({ agent: this, channel }) - } - /** * Get Space information from Access service * diff --git a/packages/access-client/src/awake/channel.js b/packages/access-client/src/awake/channel.js deleted file mode 100644 index 82031bda3..000000000 --- a/packages/access-client/src/awake/channel.js +++ /dev/null @@ -1,336 +0,0 @@ -/* eslint-disable no-console */ -import * as UCAN from '@ipld/dag-ucan' -import * as DID from '@ipld/dag-ucan/did' -import WS from 'isomorphic-ws' -import pWaitFor from 'p-wait-for' -import { concatEncode } from './encoding.js' -import * as Messages from './messages.js' - -const AWAKE_VERSION = '0.1.0' - -/** - * @template [T=unknown] - * @typedef {(event: T) => void} Handler - */ - -/** - * @template [T=unknown] - * @typedef {Array> } EventHandlerList - */ - -/** - * @template {Record} [Events=Record] - * @typedef {Map>} EventHandlerMap - */ - -/** - * @typedef {import('./types').Channel} ChannelType - * @implements {ChannelType} - */ -export class Channel { - /** @type {EventHandlerMap} */ - #subs - - /** - * @param {string | URL} host - * @param {string} topic - * @param {import('../crypto/types').KeyExchangeKeypair} keypair - */ - constructor(host, topic, keypair) { - this.url = new URL('connect/' + topic, host) - this.ws = undefined - this.keypair = keypair - this.#subs = new Map() - this.onMessage = undefined - this.attemps = 0 - /** - * @type {string | number | NodeJS.Timeout | undefined} - */ - this.timeout = undefined - this.forceClose = false - } - - async open() { - this.ws = this.connect() - await pWaitFor(() => this.ws?.readyState === 1) - return this - } - - connect() { - if (this.attemps > 10) { - return - } - - const ws = new WS(this.url) - this.ws = ws - - ws.addEventListener('close', (event) => { - if (!this.forceClose && !this.timeout) { - this.timeout = setTimeout(() => { - this.attemps++ - this.connect() - }, 1000) - console.log('WebSocket closed, reconnecting:', event.code, event.reason) - } else { - clearTimeout(this.timeout) - this.timeout = undefined - // console.log('WebSocket closed:', event.code, event.reason) - } - }) - ws.addEventListener('error', (event) => { - // console.log('WebSocket error', event) - }) - ws.addEventListener('open', (event) => { - // console.log('WebSocket open') - clearTimeout(this.timeout) - this.timeout = undefined - }) - ws.addEventListener('message', (event) => { - // @ts-ignore - const data = JSON.parse(event.data) - if (data.error) { - console.error(data.error) - } - - if (data.type) { - this.publish(data) - } - - if (this.onMessage !== undefined && data.type) { - this.onMessage(data) - } - }) - - return ws - } - - /** - * @param {number} [code] - * @param {string | Buffer } [reason] - */ - async close(code, reason) { - if (this.ws) { - this.forceClose = true - this.ws.close(code, reason) - await pWaitFor(() => this.ws?.readyState === 3) - } - return this - } - - /** - * @param {any} data - */ - send(data) { - if (this.ws?.readyState !== 1) { - throw new Error('Websocket is not active.') - } - - this.ws.send(JSON.stringify(data)) - } - - /** - * @param {import('./types').MessageType} type - * @param { Handler } fn - * @param {boolean} [once] - */ - subscribe(type, fn, once) { - let handlers = this.#subs.get(type) - let handler = fn - - if (once) { - handler = (data) => { - handlers?.splice(handlers.indexOf(handler) >>> 0, 1) - Reflect.apply(fn, this, [data]) - } - } - - if (handlers) { - handlers.push(handler) - } else { - handlers = [handler] - this.#subs.set(type, handlers) - } - - return () => { - handlers?.splice(handlers.indexOf(handler) >>> 0, 1) - } - } - - /** - * @param {import('./types').MessageType} type - * @param { Handler } fn - */ - unsubscribe(type, fn) { - const handlers = this.#subs.get(type) - if (handlers) { - if (fn) { - handlers.splice(handlers.indexOf(fn) >>> 0, 1) - } else { - this.#subs.set(type, []) - } - } - } - - /** - * @private - * @param {import('./types').AwakeMessage} data - */ - publish(data) { - const { type } = data - - const handlers = this.#subs.get(type)?.slice() - if (handlers) { - for (const h of handlers) { - h(data) - } - } - } - - /** - * @type {ChannelType['awaitInit']} - */ - awaitInit() { - return new Promise((resolve, reject) => { - this.onMessage = (/** @type {import('./types').AwakeMessage} */ msg) => { - try { - if (msg.type === 'awake/init') { - this.onMessage = undefined - console.log('receive', msg.type) - - const data = Messages.InitResponse.parse(msg) - resolve({ - awv: data.awv, - type: data.type, - did: DID.parse(data.did), - caps: /** @type {UCAN.Capabilities} */ (data.caps), - }) - } - } catch (error) { - reject(error) - } - } - }) - } - - /** - * @type {ChannelType['awaitRes']} - */ - awaitRes() { - return new Promise((resolve, reject) => { - this.onMessage = async ( - /** @type {import('./types').AwakeMessage} */ msg - ) => { - try { - if (msg.type === 'awake/res') { - this.onMessage = undefined - console.log('receive', msg.type) - - const data = Messages.ResResponse.parse(msg) - const iss = DID.parse(data.iss) - const decryptedMsg = await this.keypair.decryptFromDid( - data.msg, - iss.did() - ) - resolve({ - awv: data.awv, - type: data.type, - iss, - aud: DID.parse(data.aud), - ucan: UCAN.parse(decryptedMsg), - }) - } - } catch (error) { - reject(error) - } - } - }) - } - - /** - * - * @type {ChannelType['awaitMsg']} - */ - awaitMsg(did) { - return new Promise((resolve, reject) => { - this.onMessage = async ( - /** @type {import('./types').AwakeMsg} */ msg - ) => { - try { - if ( - msg.type === 'awake/msg' && - msg.msg && - typeof msg.msg === 'string' - ) { - this.onMessage = undefined - - msg.msg = JSON.parse( - await this.keypair.decryptFromDid(msg.msg, did.did()) - ) - console.log('receive', msg.type) - resolve(msg) - } - } catch (error) { - reject(error) - } - } - }) - } - - /** - * @type {ChannelType['sendInit']} - */ - async sendInit(caps) { - console.log('send awake/init') - this.send({ - awv: AWAKE_VERSION, - type: 'awake/init', - did: this.keypair.did, - caps, - }) - } - - /** - * @type {ChannelType['sendRes']} - */ - async sendRes(aud, ucan) { - console.log('send awake/res') - - const msg = await this.keypair.encryptForDid(UCAN.format(ucan), aud.did()) - this.send({ - awv: AWAKE_VERSION, - type: 'awake/res', - iss: this.keypair.did, - aud: aud.did(), - msg, - }) - } - - /** - * @type {ChannelType['sendMsg']} - */ - async sendMsg(did, msg) { - console.log('send awake/msg') - const id = await concatEncode([ - await this.keypair.pubkey(), - DID.encode(did), - ]) - - this.send({ - awv: AWAKE_VERSION, - type: 'awake/msg', - id, - msg: await this.keypair.encryptForDid(JSON.stringify(msg), did.did()), - }) - } - - /** - * @type {ChannelType['sendFin']} - */ - async sendFin(did) { - await this.sendMsg(did, { - 'awake/fin': 'disconnect', - }) - - await this.close() - } -} diff --git a/packages/access-client/src/awake/encoding.js b/packages/access-client/src/awake/encoding.js deleted file mode 100644 index 284bca966..000000000 --- a/packages/access-client/src/awake/encoding.js +++ /dev/null @@ -1,14 +0,0 @@ -/* eslint-disable unicorn/prefer-spread */ -import * as u8 from 'uint8arrays' -import { sha256 } from 'multiformats/hashes/sha2' - -/** - * - * @param {ArrayLike[]} buffers - * @param {import('uint8arrays/to-string').SupportedEncodings} [encoding] - */ -export async function concatEncode(buffers, encoding = 'base64') { - const out = await sha256.encode(u8.concat(buffers)) - - return u8.toString(out, encoding) -} diff --git a/packages/access-client/src/awake/messages.js b/packages/access-client/src/awake/messages.js deleted file mode 100644 index 948382c70..000000000 --- a/packages/access-client/src/awake/messages.js +++ /dev/null @@ -1,56 +0,0 @@ -/** - * @module awake-messages - * @packageDocumentation - * @ignore - */ -import { z } from 'zod' - -export const MessageType = z.enum(['awake/init', 'awake/res', 'awake/msg']) - -export const AwakeMessage = z.object({ - awv: z.literal('0.1.0'), - type: MessageType, -}) - -export const PinChallengeMessage = z - .object({ - did: z - .string() - .startsWith('did:', { message: 'should be a DID `did:key:z...`' }), - sig: z.string(), - }) - .strict() - -export const AckMessage = z - .object({ - 'awake/ack': z - .string() - .startsWith('did:', { message: 'should be a DID `did:key:z...`' }), - }) - .strict() - -export const InitResponse = AwakeMessage.extend({ - type: z.literal('awake/init'), - did: z - .string() - .startsWith('did:', { message: 'should be a DID `did:key:z...`' }), - caps: z - .array( - z.object({ - with: z.string(), - can: z.string(), - }) - ) - .nonempty(), -}).strict() - -export const DID = z - .string() - .startsWith('did:', { message: 'should be a DID `did:key:z...`' }) - -export const ResResponse = AwakeMessage.extend({ - type: z.literal('awake/res'), - iss: DID, - aud: DID, - msg: z.string().min(1), -}).strict() diff --git a/packages/access-client/src/awake/peer.js b/packages/access-client/src/awake/peer.js deleted file mode 100644 index c96ff7016..000000000 --- a/packages/access-client/src/awake/peer.js +++ /dev/null @@ -1,206 +0,0 @@ -import * as UCAN from '@ipld/dag-ucan' -import * as DID from '@ipld/dag-ucan/did' -import * as Signature from '@ipld/dag-ucan/signature' -import { Verifier } from '@ucanto/principal/ed25519' -import { sha256 } from 'multiformats/hashes/sha2' -import * as u8 from 'uint8arrays' -import { stringToDelegations, delegationsToString } from '../encoding.js' -import * as Messages from './messages.js' - -export class Peer { - /** - * @param {{ - * channel: import('./types').Channel - * agent: import('../agent').Agent - * }} opts - */ - constructor(opts) { - this.channel = opts.channel - this.agent = opts.agent - this.did = opts.agent.did() - this.challenge = undefined - this.nextdid = undefined - this.audience = undefined - this.pin = Math.floor(Math.random() * 1_000_000) - } - - /** - * Bootstrap `awake/init`, receive `awake/res` and send challenge to Responder - * - * @param {import('@ipld/dag-ucan').Capabilities} caps - */ - async bootstrap(caps) { - // step 2 - awake/init send - this.channel.sendInit(caps) - - // step 3 - awake/res receive - const { ucan } = await this.channel.awaitRes() - - // step 4 - awake/msg send - // TODO: verify ucan, and check if proof includes caps sent previously - - const challenge = findKey(ucan.facts, 'awake/challenge') - this.nextdid = DID.parse(findKey(ucan.facts, 'awake/nextdid')) - - if (challenge === 'oob-pin') { - await this.sendPinSignature() - return this.pin.toString() - } - - // TODO: fail on unknown challenge with unknown-challenge message https://github.com/ucan-wg/awake#62-unknown-challenge-error - } - - async awaitBootstrap() { - // step 2 - awake/init receive - const msg = await this.channel.awaitInit() - this.nextdid = msg.did - - // step3 - awake/res send - const ucan = await UCAN.issue({ - issuer: this.agent.issuer, - audience: this.nextdid, - capabilities: [{ with: 'awake:', can: '*' }], - facts: [ - { 'awake/challenge': 'oob-pin' }, - // TODO: this should be rotated for the next step - { 'awake/nextdid': this.channel.keypair.did }, - ], - // TODO: proof for caps requested - }) - - await this.channel.sendRes(this.nextdid, ucan) - - // step 4 - awake/msg receive - const challengeMsg = await this.channel.awaitMsg(this.nextdid) - const { did, sig } = Messages.PinChallengeMessage.parse(challengeMsg.msg) - this.audience = DID.parse(did) - this.challenge = sig - } - - /** - * Acknowledgment for the PIN challenge - * - * @param {string} pin - */ - async ack(pin) { - if (!this.challenge || !this.nextdid || !this.audience) { - throw new Error('No challenge active.') - } - - // step 5 - awake/ack challenge confirmation and send - const sig = u8.fromString(this.challenge, 'base64') - const verifier = Verifier.parse(this.audience.did()) - const payload = u8.fromString(this.channel.keypair.did + pin) - const payloadHash = await sha256.encode(payload) - - // @ts-ignore - if (!(await verifier.verify(payloadHash, Signature.decode(sig)))) { - throw new Error( - `Challenge failed: ${pin} is not valid for the current challenge.` - ) - } - - // challenge response - await this.channel.sendMsg(this.nextdid, { - 'awake/ack': this.did, - }) - } - - async awaitAck() { - if (!this.nextdid) { - throw new Error('No session is active. await ack') - } - - const awakeMsgAck = await this.channel.awaitMsg(this.nextdid) - - const ack = Messages.AckMessage.parse(awakeMsgAck.msg) - - this.audience = DID.parse(ack['awake/ack']) - } - - /** - * - * @param {{ - * caps: import('./types').LinkRequest['msg']['caps'] - * meta: import('./types').PeerMeta - * }} opts - */ - async link(opts) { - if (!this.nextdid || !this.audience) { - throw new Error('No session is active. request link') - } - - const msg = { - type: 'link', - meta: opts.meta, - caps: opts.caps, - } - this.channel.sendMsg(this.nextdid, msg) - - /** @type {import('./types').LinkResponse} */ - const capsRsp = await this.channel.awaitMsg(this.nextdid) - const delegations = stringToDelegations(capsRsp.msg.delegation) - - await this.channel.sendFin(this.nextdid) - - await this.agent.addProof(delegations[0]) - - return { delegation: delegations[0], meta: capsRsp.msg.meta } - } - - async awaitLink() { - if (!this.nextdid || !this.audience) { - throw new Error('No challenge active.') - } - // request caps - /** @type {import('./types').LinkRequest} */ - const reqCap = await this.channel.awaitMsg(this.nextdid) - const d = await this.agent.delegate({ - abilities: ['*'], // TODO should be derived from reqCap - audience: this.audience, - expiration: Infinity, - audienceMeta: reqCap.msg.meta, - }) - this.channel.subscribe('awake/msg', (msg) => { - this.channel.close() - }) - this.channel.sendMsg(this.nextdid, { - meta: { - name: this.agent.did(), - type: 'device', - }, - delegation: delegationsToString([d]), - }) - } - - /** - * Build pin signature and send it - * - * @private - */ - async sendPinSignature() { - if (!this.nextdid) { - throw new Error('No session is active.') - } - - // Pin signature - const bytes = u8.fromString(this.nextdid.did() + this.pin.toString()) - const signed = await this.agent.issuer.sign(await sha256.encode(bytes)) - this.channel.sendMsg(this.nextdid, { - did: this.did, - sig: u8.toString(signed, 'base64'), - }) - } -} - -/** - * @param {any} arr - * @param {string} key - */ -function findKey(arr, key) { - for (const i of arr) { - if (i[key]) { - return i[key] - } - } -} diff --git a/packages/access-client/src/awake/readme.md b/packages/access-client/src/awake/readme.md deleted file mode 100644 index 98156f8dc..000000000 --- a/packages/access-client/src/awake/readme.md +++ /dev/null @@ -1,22 +0,0 @@ -# Awake - -## TODO - -- [ ] concurrent sessions -- [ ] ucan store class -- [ ] validate ucan https://github.com/ucan-wg/awake#331-validation-ucan in awake/res -- [ ] timeout on messages sent -- [ ] rotate chain keys - Double Ratchet -- [ ] error over channel and disconnect during bad handshake -- [ ] update according to latest spec - -## Notes - -- HKDF: HMAC-based Extract-and-Expand Key Derivation Function -- KDF: Key Derivation Function -- OKM: Output Key Material -- Double Ratchet Algorithm: https://signal.org/docs/specifications/doubleratchet/ - -### Session setup - -The Requestor SHOULD accept multiple concurrent connection attempts on this request DID, at least until the handshake is complete. diff --git a/packages/access-client/src/awake/types.ts b/packages/access-client/src/awake/types.ts deleted file mode 100644 index 24d0f807c..000000000 --- a/packages/access-client/src/awake/types.ts +++ /dev/null @@ -1,133 +0,0 @@ -import * as UCAN from '@ipld/dag-ucan' -import { Ability, Resource } from '@ipld/dag-ucan' -import WS from 'isomorphic-ws' -import { z } from 'zod' -import { KeyExchangeKeypair } from '../crypto/types.js' -import { Handler } from './channel.js' -import * as Messages from './messages.js' - -export interface Channel { - keypair: KeyExchangeKeypair - - ws?: WebSocket | WS - /** - * Sends a data as a message - * Data should run through JSON.stringify - */ - send: (data: unknown) => void - open: () => Promise - close: (code?: number, reason?: string) => Promise - subscribe: (type: MessageType, fn: Handler, once?: boolean) => () => void - - /** - * Send awake init message to responder - * did - The Requestor's initial (temp) ECDH P-256 - * - * @param caps - Capabilities that the Responder MUST provide - */ - sendInit: (caps: AwakeInit['caps']) => Promise - - awaitInit: () => Promise - - /** - * Send awake res message to requestor - * - * @param aud - The ECDH P-256 DID signalled by the Requestor in previous awake/init - * @param ucan - Validation UCAN to be AES-GCM-encrypted - */ - sendRes: (aud: UCAN.Principal, msg: UCAN.View) => Promise - - /** - * Awaits for awake/res msg and decrypts ucan payload from send DID - */ - awaitRes: () => Promise - - /** - * Send generic awake/msg with encrypted payload and message id - * - * @param did - DID to encrypt for - * @param msg - Message to be encrypted and sent - */ - sendMsg: (did: UCAN.Principal, msg: unknown) => Promise - - /** - * Awaits for a awake/msg and decrypts payload from sender DID - */ - awaitMsg: ( - did: UCAN.Principal - ) => Promise - - sendFin: (did: UCAN.Principal) => Promise -} - -export type MessageType = z.infer<(typeof Messages)['MessageType']> - -export type AwakeMessage = z.infer<(typeof Messages)['AwakeMessage']> - -export interface AwakeInit extends AwakeMessage { - did: UCAN.Principal - caps: UCAN.Capabilities -} - -export interface AwakeRes extends AwakeMessage { - iss: UCAN.Principal - aud: UCAN.Principal - ucan: UCAN.View -} - -/** - * Awake message with encrypted payload - */ -export interface AwakeMsg extends AwakeMessage { - id: string - msg: string -} - -/** - * Awake message with decrypted payload - */ -export interface AwakeMsgDecrypted extends AwakeMessage { - id: string - msg: any -} - -export type PinChallengeMessage = z.infer< - (typeof Messages)['PinChallengeMessage'] -> & { - did: `did:${string}` -} - -declare const Marker: unique symbol -export interface Phantom { - [Marker]?: T -} - -export type Encrypted = Out & Phantom - -export interface PeerMeta { - name: string - description?: string - url?: URL - image?: URL - type: 'device' | 'app' | 'service' -} - -export interface LinkRequest extends AwakeMsgDecrypted { - msg: { - type: 'link' - meta: PeerMeta - caps: Array<{ - can: Ability - with?: Resource - }> - } -} - -export interface LinkResponse extends AwakeMsgDecrypted { - msg: { - meta: PeerMeta - delegation: string - } -} - -export type MetaMap = Map diff --git a/packages/access-client/src/cli/cmd-create-space.js b/packages/access-client/src/cli/cmd-create-space.js deleted file mode 100644 index 8fb3243f9..000000000 --- a/packages/access-client/src/cli/cmd-create-space.js +++ /dev/null @@ -1,52 +0,0 @@ -/* eslint-disable unicorn/no-process-exit */ -/* eslint-disable no-console */ -import inquirer from 'inquirer' -import ora from 'ora' -import { Agent } from '../agent.js' -import { StoreConf } from '../stores/store-conf.js' -import { getService } from './utils.js' - -/** - * @param {{ profile: any; env: string }} opts - */ -export async function cmdCreateSpace(opts) { - const { url, servicePrincipal } = await getService(opts.env) - const store = new StoreConf({ profile: opts.profile }) - const data = await store.load() - - if (data) { - const spinner = ora('Registering with the service').start() - const agent = Agent.from(data, { store, url, servicePrincipal }) - - spinner.stopAndPersist() - const { email, name } = await inquirer.prompt([ - { - type: 'input', - name: 'name', - message: 'Input your a name for the new space:', - }, - { - type: 'input', - name: 'email', - default: 'hugomrdias@gmail.com', - message: 'Input your email to validate:', - }, - ]) - try { - spinner.start('Waiting for email validation...') - const space = await agent.createSpace(name) - - await agent.setCurrentSpace(space.did) - await agent.registerSpace(email) - spinner.succeed('Space has been created and register with the service.') - } catch (error) { - console.error(error) - // @ts-ignore - spinner.fail(error.message) - process.exit(1) - } - } else { - console.error('run setup command first.') - process.exit(1) - } -} diff --git a/packages/access-client/src/cli/cmd-link.js b/packages/access-client/src/cli/cmd-link.js deleted file mode 100644 index f5b541749..000000000 --- a/packages/access-client/src/cli/cmd-link.js +++ /dev/null @@ -1,79 +0,0 @@ -/* eslint-disable unicorn/no-process-exit */ -/* eslint-disable no-console */ -// @ts-ignore -// eslint-disable-next-line no-unused-vars -import inquirer from 'inquirer' -import pWaitFor from 'p-wait-for' -import { Agent } from '../agent.js' -import { Channel } from '../awake/channel.js' -import { EcdhKeypair } from '../crypto/p256-ecdh.js' -import { StoreConf } from '../stores/store-conf.js' -import { getService } from './utils.js' - -/** - * @param {string} channel - * @param {{ profile: string; env: string }} opts - */ -export async function cmdLink(channel, opts) { - const { url } = await getService(opts.env) - const store = new StoreConf({ profile: opts.profile }) - const data = await store.load() - - if (!data) { - console.error('run setup first') - process.exit(1) - } - - const agent = Agent.from(data, { store, url }) - - console.log('DID:', agent.did()) - let done = false - const host = new URL('ws://127.0.0.1:8788/connect') - if (channel) { - const ws = await new Channel( - host, - channel, - await EcdhKeypair.create() - ).open() - const requestor = agent.peer(ws) - const pin = await requestor.bootstrap([ - // @ts-ignore - { with: channel, can: 'identity/*' }, - ]) - - console.log(pin) - await requestor.awaitAck() - const link = await requestor.link({ - caps: [{ can: 'identity/*' }], - meta: { - name: agent.did(), - type: 'device', - }, - }) - - console.log(link) - - done = true - } else { - const ws = await new Channel( - host, - agent.did(), - await EcdhKeypair.create() - ).open() - - const responder = agent.peer(ws) - await responder.awaitBootstrap() - const { pin } = await inquirer.prompt({ - type: 'input', - name: 'pin', - message: 'Input your pin:', - }) - - await responder.ack(pin) - await responder.awaitLink() - - done = true - } - - await pWaitFor(() => done) -} diff --git a/packages/access-client/src/cli/cmd-setup.js b/packages/access-client/src/cli/cmd-setup.js deleted file mode 100644 index 8d40d6f5e..000000000 --- a/packages/access-client/src/cli/cmd-setup.js +++ /dev/null @@ -1,49 +0,0 @@ -/* eslint-disable no-console */ -import inquirer from 'inquirer' -import { AgentData } from '../agent-data.js' -import { StoreConf } from '../stores/store-conf.js' - -/** - * @param {{ profile: string, force: boolean }} opts - */ -export async function cmdSetup(opts) { - const store = new StoreConf({ profile: opts.profile }) - console.log('Path:', store.path) - - if (opts.force) { - await store.reset() - } - - const data = await store.load() - - if (data) { - console.log('Agent is already setup.') - } else { - const { name, type } = await inquirer.prompt([ - { - type: 'input', - name: 'name', - default: 'cli', - message: 'Input the name for this device:', - }, - { - type: 'list', - name: 'type', - default: 'device', - choices: [{ name: 'device' }, { name: 'app' }, { name: 'service' }], - message: 'Select this agent type:', - }, - ]) - await AgentData.create( - { - meta: { - name, - type, - }, - }, - { store } - ) - - console.log('Agent is ready to use.') - } -} diff --git a/packages/access-client/src/cli/cmd-whoami.js b/packages/access-client/src/cli/cmd-whoami.js deleted file mode 100644 index 94d8d46bf..000000000 --- a/packages/access-client/src/cli/cmd-whoami.js +++ /dev/null @@ -1,53 +0,0 @@ -/* eslint-disable no-console */ -import { Agent } from '../agent.js' -import { expirationToDate } from '../encoding.js' -import { StoreConf } from '../stores/store-conf.js' -import { NAME } from './config.js' - -/** - * @param {{ profile: any; env : string }} opts - */ -export async function cmdWhoami(opts) { - const store = new StoreConf({ profile: opts.profile }) - const data = await store.load() - if (data) { - const agent = Agent.from(data, { store }) - console.log('Agent', agent.issuer.did(), agent.meta) - console.log('Current Space', agent.currentSpaceWithMeta()) - console.log('\nSpaces:') - for (const space of agent.spaces) { - console.log( - `Name: ${space[1].name ?? 'none'} DID: ${space[0]} Registered: ${ - space[1].isRegistered - }` - ) - } - console.log('\nProofs:') - for (const proof of agent.proofs()) { - for (const cap of proof.capabilities) { - console.log( - `With resource: ${cap.with} can "${cap.can}" expires at ${proof.expiration}` - ) - } - } - - console.log('\nDelegations:') - for (const { meta, delegation } of agent.delegationsWithMeta()) { - console.log( - `Audience ${meta.audience?.name ?? 'unknown'} (${ - meta.audience?.type ?? 'unknown' - }):` - ) - for (const cap of delegation.capabilities) { - const expires = expirationToDate(delegation.expiration) - console.log( - `With resource: ${cap.with} can "${cap.can}" expires at ${ - expires ? expires.toISOString() : 'never' - }` - ) - } - } - } else { - console.error(`Run "${NAME} setup" first`) - } -} diff --git a/packages/access-client/src/cli/config.js b/packages/access-client/src/cli/config.js deleted file mode 100644 index c399f5615..000000000 --- a/packages/access-client/src/cli/config.js +++ /dev/null @@ -1,22 +0,0 @@ -import fs from 'fs' -import Conf from 'conf' - -export const NAME = 'w3access' -export const pkg = JSON.parse( - // eslint-disable-next-line unicorn/prefer-json-parse-buffer - fs.readFileSync(new URL('../../package.json', import.meta.url), { - encoding: 'utf8', - }) -) - -/** - * @param {string} profile - */ -export function getConfig(profile = 'main') { - const config = new Conf({ - projectName: NAME, - projectSuffix: '', - configName: profile, - }) - return config -} diff --git a/packages/access-client/src/cli/index.js b/packages/access-client/src/cli/index.js deleted file mode 100755 index 13e8d86c0..000000000 --- a/packages/access-client/src/cli/index.js +++ /dev/null @@ -1,156 +0,0 @@ -#!/usr/bin/env node -/* eslint-disable no-console */ -import fs from 'fs' -import sade from 'sade' -import { NAME, pkg } from './config.js' -import { getService, selectSpace } from './utils.js' -// @ts-ignore -// eslint-disable-next-line no-unused-vars -import { cmdCreateSpace } from './cmd-create-space.js' -import { cmdLink } from './cmd-link.js' -import { cmdSetup } from './cmd-setup.js' -import { cmdWhoami } from './cmd-whoami.js' -import { StoreConf } from '../stores/store-conf.js' -import { Agent } from '../agent.js' -import { abilitiesAsStrings } from '@web3-storage/capabilities' -import { delegationToString, stringToDelegation } from '../encoding.js' -import inquirer from 'inquirer' -import { Verifier } from '@ucanto/principal' -import path from 'path' - -const prog = sade(NAME) -prog - .version(pkg.version) - .option('-p, --profile', 'Select the config profile to use.', 'main') - .option( - '--env', - 'Environment "production", "staging", "dev" or "local"', - 'production' - ) - -prog.command('link [channel]').describe('Link.').action(cmdLink) -prog - .command('setup') - .option('--reset', 'Reset current store.', false) - .describe('Setup agent keypair.') - .action(cmdSetup) -prog.command('whoami').describe('Print config file content.').action(cmdWhoami) -prog - .command('create-space') - .describe('Create new space and register with the service.') - .action(cmdCreateSpace) - -prog - .command('space') - .describe('Space info.') - .action(async (opts) => { - const store = new StoreConf({ profile: opts.profile }) - const data = await store.load() - const { url, servicePrincipal } = await getService(opts.env) - if (data) { - const agent = Agent.from(data, { store, url, servicePrincipal }) - const space = await selectSpace(agent) - try { - const result = await agent.getSpaceInfo(space) - console.log(result) - } catch (error_) { - const error = /** @type {Error} */ (error_) - console.log('Error', error.message) - } - } else { - console.error(`Run "${NAME} setup" first`) - } - }) - -prog - .command('delegate') - .describe('Delegation capabilities.') - .option('--file', 'File to write the delegation into.') - .action(async (opts) => { - const store = new StoreConf({ profile: opts.profile }) - const data = await store.load() - const { url, servicePrincipal } = await getService(opts.env) - if (data) { - const agent = Agent.from(data, { store, url, servicePrincipal }) - const space = await selectSpace(agent) - - await agent.setCurrentSpace(space) - - const { audience, expiration, name, type, abilities } = - await inquirer.prompt([ - { - type: 'input', - name: 'audience', - message: 'Input audience DID:', - }, - { - type: 'input', - name: 'name', - message: 'Input audience name:', - }, - { - type: 'list', - name: 'type', - default: 'device', - choices: ['device', 'app', 'service'], - message: 'Input audience type:', - }, - { - type: 'number', - name: 'expiration', - message: 'Input expiration in seconds:', - }, - { - type: 'checkbox', - name: 'abilities', - message: 'Input abilities to delegate:', - choices: abilitiesAsStrings, - }, - ]) - - const delegation = await agent.delegate({ - audience: Verifier.parse(audience), - audienceMeta: { - name, - type, - }, - lifetimeInSeconds: isNaN(expiration) ? Infinity : expiration, - abilities, - }) - - const delString = delegationToString(delegation) - - if (opts.file) { - fs.writeFileSync(path.join(process.cwd(), opts.file), delString, { - encoding: 'utf8', - }) - } else { - console.log(delString) - } - } else { - console.error(`Run "${NAME} setup" first`) - } - }) - -prog - .command('import') - .describe('Import delegation.') - .option('--delegation') - .action(async (opts) => { - const store = new StoreConf({ profile: opts.profile }) - const data = await store.load() - const { url, servicePrincipal } = await getService(opts.env) - if (data) { - const agent = Agent.from(data, { store, url, servicePrincipal }) - - const del = fs.readFileSync(path.resolve(opts.delegation), { - encoding: 'utf8', - }) - - await agent.importSpaceFromDelegation(stringToDelegation(del)) - } else { - console.error(`Run "${NAME} setup" first`) - } - }) - -prog.parse(process.argv) diff --git a/packages/access-client/src/cli/utils.js b/packages/access-client/src/cli/utils.js deleted file mode 100644 index 8d079d00e..000000000 --- a/packages/access-client/src/cli/utils.js +++ /dev/null @@ -1,70 +0,0 @@ -// @ts-ignore -// eslint-disable-next-line no-unused-vars -import * as Ucanto from '@ucanto/interface' -import { DID } from '@ucanto/core' -import inquirer from 'inquirer' - -/** @type {Record} */ -const envs = { - production: 'https://up.web3.storage', - staging: 'https://staging.up.web3.storage', - dev: 'https://dev.up.web3.storage', - local: 'http://127.0.0.1:8787', -} - -/** @type {Record} */ -const dids = { - production: 'did:web:web3.storage', - staging: 'did:web:staging.web3.storage', - dev: 'did:web:dev.web3.storage', -} - -/** - * @type {import("@ucanto/interface").Principal} - */ -let audience - -/** - * @param {string} env - */ -export async function getService(env) { - const url = new URL(envs[env]) - let did - - if (audience) { - return { url, servicePrincipal: audience } - } else { - if (env === 'local') { - const rsp = await fetch(url + 'version') - const data = await rsp.json() - did = data.did - } else { - did = dids[env] - } - - // @ts-ignore - audience = DID.parse(did) - return { url, servicePrincipal: audience } - } -} - -/** - * @template {Ucanto.Signer} T - * @param {import('../agent').Agent} agent - */ -export async function selectSpace(agent) { - const choices = [] - for (const [key, value] of agent.spaces) { - choices.push({ name: value.name, value: key }) - } - const { space } = await inquirer.prompt([ - { - type: 'list', - name: 'space', - choices, - message: 'Select space:', - }, - ]) - - return space -} diff --git a/packages/access-client/src/types.ts b/packages/access-client/src/types.ts index d365a57f1..e4d2dd8c5 100644 --- a/packages/access-client/src/types.ts +++ b/packages/access-client/src/types.ts @@ -10,7 +10,6 @@ import type { Resource, ResponseDecoder, ServiceMethod, - URI, InferInvokedCapability, CapabilityParser, Match, @@ -18,7 +17,6 @@ import type { UnknownMatch, Delegation, DID, - DIDKey, Signer, SignerArchive, SigAlg, @@ -46,47 +44,17 @@ import type { import type { SetRequired } from 'type-fest' import { Driver } from './drivers/types.js' import { SpaceUnknown } from './errors.js' -import type { ColumnType, Generated, Selectable } from 'kysely' // export other types export * from '@web3-storage/capabilities/types' export * from './errors.js' -/** - * D1 Types - */ - -export interface SpaceTable { - did: DIDKey - agent: DID - email: string - product: URI - inserted_at: Generated - updated_at: ColumnType - metadata: SpaceTableMetadata | null - invocation: string - delegation: string | null -} -export type SpaceRecord = Selectable - export interface SpaceInfoResult { // space did did: DID<'key'> providers: Array> } -export interface AccountTable { - did: DID<'mailto'> - inserted_at: Generated - updated_at: ColumnType -} -export type AccountRecord = Selectable - -export interface SpaceTableMetadata { - space: SpaceMeta - agent: AgentMeta -} - /** * Access api service definition type */ diff --git a/packages/access-client/src/utils/ws.js b/packages/access-client/src/utils/ws.js deleted file mode 100644 index 7658cc0cb..000000000 --- a/packages/access-client/src/utils/ws.js +++ /dev/null @@ -1,229 +0,0 @@ -/* eslint-disable no-console */ -import WS from 'isomorphic-ws' -import pWaitFor from 'p-wait-for' - -/** - * @template [T=unknown] - * @typedef {(event: T) => void} Handler - */ - -/** - * @template [T=unknown] - * @typedef {Array> } EventHandlerList - */ - -/** - * @template {Record} [Events=Record] - * @typedef {Map>} EventHandlerMap - */ - -export class Websocket { - /** @type {EventHandlerMap} */ - #subs - - /** - * @param {URL} host - * @param {string} topic - */ - constructor(host, topic) { - this.url = new URL(topic, host) - if (host.protocol === 'http:') { - this.url.protocol = 'ws:' - } - if (host.protocol === 'https:') { - this.url.protocol = 'wss:' - } - this.ws = undefined - this.#subs = new Map() - this.attemps = 0 - this.onMessage = undefined - /** - * @type {string | number | NodeJS.Timeout | undefined} - */ - this.timeout = undefined - this.forceClose = false - } - - /** - * @param {object} [opts] - * @param {AbortSignal} [opts.signal] - */ - async open(opts) { - this.ws = this.connect() - await pWaitFor(() => opts?.signal?.aborted || this.ws?.readyState === 1) - return this - } - - connect() { - if (this.attemps > 10) { - return - } - - const ws = new WS(this.url) - this.ws = ws - - ws.addEventListener('close', (event) => { - if (!this.forceClose && !this.timeout) { - this.timeout = setTimeout(() => { - this.attemps++ - this.connect() - }, 1000) - console.log('WebSocket closed, reconnecting:', event.code, event.reason) - } else { - clearTimeout(this.timeout) - this.timeout = undefined - // console.log('WebSocket closed:', event.code, event.reason) - } - }) - ws.addEventListener('error', (event) => { - // console.log('WebSocket error', event) - }) - ws.addEventListener('open', (event) => { - // console.log('WebSocket open') - clearTimeout(this.timeout) - this.timeout = undefined - }) - ws.addEventListener('message', (event) => { - // @ts-ignore - const data = JSON.parse(event.data) - if (data.error) { - console.error(data.error) - } - - if (data.type) { - this.publish(data) - } - - if (this.onMessage !== undefined && data.type) { - this.onMessage(data) - } - }) - - return ws - } - - /** - * @param {number} [code] - * @param {string | Buffer } [reason] - */ - async close(code, reason) { - if (this.ws) { - this.forceClose = true - this.ws.close(code, reason) - await pWaitFor(() => this.ws?.readyState === 3) - } - return this - } - - /** - * @param {any} data - */ - send(data) { - if (this.ws?.readyState !== 1) { - throw new Error('Websocket is not active.') - } - - this.ws.send(JSON.stringify(data)) - } - - /** - * @param {string} type - * @param { Handler } fn - * @param {boolean} [once] - */ - subscribe(type, fn, once) { - let handlers = this.#subs.get(type) - let handler = fn - - if (once) { - handler = (data) => { - handlers?.splice(handlers.indexOf(handler) >>> 0, 1) - Reflect.apply(fn, this, [data]) - } - } - - if (handlers) { - handlers.push(handler) - } else { - handlers = [handler] - this.#subs.set(type, handlers) - } - - return () => { - handlers?.splice(handlers.indexOf(handler) >>> 0, 1) - } - } - - /** - * @param {string} type - * @param { Handler } fn - */ - unsubscribe(type, fn) { - const handlers = this.#subs.get(type) - if (handlers) { - if (fn) { - handlers.splice(handlers.indexOf(fn) >>> 0, 1) - } else { - this.#subs.set(type, []) - } - } - } - - /** - * - * @param {unknown} data - */ - publish(data) { - // @ts-ignore - const { type } = data - - const handlers = this.#subs.get(type)?.slice() - if (handlers) { - for (const h of handlers) { - h(data) - } - } - } - - /** - * - * @param {object} [opts] - * @param {AbortSignal} [opts.signal] - */ - awaitMsg(opts) { - return new Promise((resolve, reject) => { - if (opts?.signal) { - opts.signal.addEventListener('abort', () => { - this.onMessage = undefined - reject( - new AbortError('Await message cancelled.', { - cause: opts.signal?.reason, - }) - ) - }) - } - this.onMessage = (/** @type {{ type: string; }} */ msg) => { - try { - this.onMessage = undefined - resolve(msg) - } catch (error) { - reject(error) - } - } - }) - } -} - -export class AbortError extends Error { - /** - * @param {string} message - * @param {ErrorOptions} [opts] - */ - constructor(message, opts) { - super(message, opts) - this.name = 'AbortError' - this.message = message - this.code = AbortError.code - } -} -AbortError.code = 'ERR_AWAIT_MSG_CANCEL' diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index af6efb30e..075ae8ef5 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -75,42 +75,21 @@ importers: conf: specifier: 10.2.0 version: 10.2.0 - inquirer: - specifier: ^9.1.4 - version: 9.2.11 - isomorphic-ws: - specifier: ^5.0.0 - version: 5.0.0(ws@8.14.2) - kysely: - specifier: ^0.23.4 - version: 0.23.5 multiformats: specifier: ^12.1.2 version: 12.1.2 one-webcrypto: specifier: ^1.0.3 version: 1.0.3 - ora: - specifier: ^6.1.2 - version: 6.3.1 p-defer: specifier: ^4.0.0 version: 4.0.0 - p-wait-for: - specifier: ^5.0.0 - version: 5.0.2 type-fest: specifier: ^3.3.0 version: 3.13.1 uint8arrays: specifier: ^4.0.6 version: 4.0.6 - ws: - specifier: ^8.12.0 - version: 8.14.2 - zod: - specifier: ^3.20.2 - version: 3.22.4 devDependencies: '@types/assert': specifier: ^1.5.6 @@ -148,9 +127,6 @@ importers: playwright-test: specifier: ^12.3.4 version: 12.3.8 - sade: - specifier: ^1.8.1 - version: 1.8.1 sinon: specifier: ^15.0.3 version: 15.2.0 @@ -2661,11 +2637,6 @@ packages: resolution: {integrity: sha512-Hcv+nVC0kZnQ3tD9GVu5xSMR4VVYOteQIr/hwFPVEvPdlXqgGEuRjiheChHgdM+JyqdgNcmzZOX/tnl0JOiI7A==} dev: true - /@ljharb/through@2.3.9: - resolution: {integrity: sha512-yN599ZBuMPPK4tdoToLlvgJB4CLK8fGl7ntfy0Wn7U6ttNvHYurd81bfUiK/6sMkiIwm65R6ck4L6+Y3DfVbNQ==} - engines: {node: '>= 0.4'} - dev: false - /@mdx-js/mdx@1.6.22: resolution: {integrity: sha512-AMxuLxPz2j5/6TpF/XSdKpQP1NlG0z11dFOlq+2IP/lSgl11GY8ji6S/rgsViN/L0BDvHvUMruRb7ub+24LUYA==} dependencies: @@ -3926,13 +3897,6 @@ packages: engines: {node: '>=6'} dev: true - /ansi-escapes@4.3.2: - resolution: {integrity: sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==} - engines: {node: '>=8'} - dependencies: - type-fest: 0.21.3 - dev: false - /ansi-escapes@5.0.0: resolution: {integrity: sha512-5GFMVX8HqE/TB+FuBJGuO5XG0WrsA6ptUqoODaT/n9mmUaZFkqnBueB4leqGBCmrUHnCnC4PCZTCd0E7QQ83bA==} engines: {node: '>=12'} @@ -3953,6 +3917,7 @@ packages: /ansi-regex@6.0.1: resolution: {integrity: sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==} engines: {node: '>=12'} + dev: true /ansi-sequence-parser@1.1.1: resolution: {integrity: sha512-vJXt3yiaUL4UU546s3rPXlsry/RnM730G1+HkpKE012AN0sx1eOrxSu95oKDIonskeLTijMgqWZ3uDEe3NFvyg==} @@ -4250,20 +4215,13 @@ packages: engines: {node: '>=8'} dev: true - /bl@4.1.0: - resolution: {integrity: sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==} - dependencies: - buffer: 5.7.1 - inherits: 2.0.4 - readable-stream: 3.6.2 - dev: false - /bl@5.1.0: resolution: {integrity: sha512-tv1ZJHLfTDnXE6tMHv73YgSJaWR2AFuPwMntBe7XL/GBFHnT0CLnsHMogfk5+GzCDC5ZWarSCYaIGATZt9dNsQ==} dependencies: buffer: 6.0.3 inherits: 2.0.4 readable-stream: 3.6.2 + dev: true /blockstore-core@3.0.0: resolution: {integrity: sha512-5ZZB5nh6kErcjZ/CTK6lCwTIGlPdkTXbD8+2xLC4Fm0WGh7g2e2lW2bfURw7mvnPtSX1xV+sN4V2ndowSgIiHQ==} @@ -4380,13 +4338,6 @@ packages: resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} dev: true - /buffer@5.7.1: - resolution: {integrity: sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==} - dependencies: - base64-js: 1.5.1 - ieee754: 1.2.1 - dev: false - /buffer@6.0.3: resolution: {integrity: sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==} dependencies: @@ -4536,10 +4487,12 @@ packages: dependencies: ansi-styles: 4.3.0 supports-color: 7.2.0 + dev: true /chalk@5.3.0: resolution: {integrity: sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==} engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} + dev: true /character-entities-legacy@1.1.4: resolution: {integrity: sha512-3Xnr+7ZFS1uxeiUDvV02wQ+QDbc55o97tIV5zHScSPJpcLm/r0DFPcoY3tYRp+VZukxuMeKgXYmsXQHO05zQeA==} @@ -4553,10 +4506,6 @@ packages: resolution: {integrity: sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg==} dev: true - /chardet@0.7.0: - resolution: {integrity: sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==} - dev: false - /chokidar@3.5.3: resolution: {integrity: sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==} engines: {node: '>= 8.10.0'} @@ -4622,22 +4571,17 @@ packages: engines: {node: '>=10'} dev: true - /cli-cursor@3.1.0: - resolution: {integrity: sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==} - engines: {node: '>=8'} - dependencies: - restore-cursor: 3.1.0 - dev: false - /cli-cursor@4.0.0: resolution: {integrity: sha512-VGtlMu3x/4DOtIUwEkRezxUZ2lBacNJCHash0N0WeZDBS+7Ux1dm3XWAgWYxLJFMMdOeXMHXorshEFhbMSGelg==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} dependencies: restore-cursor: 4.0.0 + dev: true /cli-spinners@2.9.1: resolution: {integrity: sha512-jHgecW0pxkonBJdrKsqxgRX9AcG+u/5k0Q7WPDfi8AogLAdwxEkyYYNWwZ5GvVFoFx2uiY1eNcSK00fh+1+FyQ==} engines: {node: '>=6'} + dev: true /cli-table3@0.6.3: resolution: {integrity: sha512-w5Jac5SykAeZJKntOxJCrm63Eg5/4dhMWIcuTbo9rpE+brgaSZo0RuNJZeOyMgsUdhDeojvgyQLmjI+K50ZGyg==} @@ -4656,11 +4600,6 @@ packages: string-width: 5.1.2 dev: true - /cli-width@4.1.0: - resolution: {integrity: sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==} - engines: {node: '>= 12'} - dev: false - /cliui@7.0.4: resolution: {integrity: sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==} dependencies: @@ -4692,11 +4631,6 @@ packages: mimic-response: 1.0.1 dev: true - /clone@1.0.4: - resolution: {integrity: sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==} - engines: {node: '>=0.8'} - dev: false - /collapse-white-space@1.0.6: resolution: {integrity: sha512-jEovNnrhMuqyCcjfEJA56v0Xq8SkIoPKDyaHahwo3POf4qcSXqMYuwNcOTzp74vTsR9Tn08z4MxWqAhcekogkQ==} dev: true @@ -5240,12 +5174,6 @@ packages: execa: 5.1.1 dev: true - /defaults@1.0.4: - resolution: {integrity: sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==} - dependencies: - clone: 1.0.4 - dev: false - /defer-to-connect@1.1.3: resolution: {integrity: sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ==} dev: true @@ -5726,6 +5654,7 @@ packages: /escape-string-regexp@5.0.0: resolution: {integrity: sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==} engines: {node: '>=12'} + dev: true /eslint-config-prettier@8.10.0(eslint@8.50.0): resolution: {integrity: sha512-SM8AMJdeQqRYT9O9zguiruQZaN7+z+E4eAP9oiLNGKMtomwaB1E9dcgUD6ZAn/eQAb52USbvezbiljfZUhbJcg==} @@ -6550,15 +6479,6 @@ packages: resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==} dev: true - /external-editor@3.1.0: - resolution: {integrity: sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==} - engines: {node: '>=4'} - dependencies: - chardet: 0.7.0 - iconv-lite: 0.4.24 - tmp: 0.0.33 - dev: false - /fast-deep-equal@3.1.3: resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} @@ -6604,14 +6524,6 @@ packages: websocket-driver: 0.7.4 dev: true - /figures@5.0.0: - resolution: {integrity: sha512-ej8ksPF4x6e5wvK9yevct0UCXh8TTFlWGVLlgjZuoBH1HwjIfKE/IdL5mq89sFA7zELi1VhKpmtDnrs7zWyeyg==} - engines: {node: '>=14'} - dependencies: - escape-string-regexp: 5.0.0 - is-unicode-supported: 1.3.0 - dev: false - /file-entry-cache@6.0.1: resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==} engines: {node: ^10.12.0 || >=12.0.0} @@ -7460,6 +7372,7 @@ packages: engines: {node: '>=0.10.0'} dependencies: safer-buffer: 2.1.2 + dev: true /iconv-lite@0.6.3: resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==} @@ -7549,27 +7462,6 @@ packages: resolution: {integrity: sha512-7NXolsK4CAS5+xvdj5OMMbI962hU/wvwoxk+LWR9Ek9bVtyuuYScDN6eS0rUm6TxApFpw7CX1o4uJzcd4AyD3Q==} dev: true - /inquirer@9.2.11: - resolution: {integrity: sha512-B2LafrnnhbRzCWfAdOXisUzL89Kg8cVJlYmhqoi3flSiV/TveO+nsXwgKr9h9PIo+J1hz7nBSk6gegRIMBBf7g==} - engines: {node: '>=14.18.0'} - dependencies: - '@ljharb/through': 2.3.9 - ansi-escapes: 4.3.2 - chalk: 5.3.0 - cli-cursor: 3.1.0 - cli-width: 4.1.0 - external-editor: 3.1.0 - figures: 5.0.0 - lodash: 4.17.21 - mute-stream: 1.0.0 - ora: 5.4.1 - run-async: 3.0.0 - rxjs: 7.8.1 - string-width: 4.2.3 - strip-ansi: 6.0.1 - wrap-ansi: 6.2.0 - dev: false - /interface-blockstore@4.0.1: resolution: {integrity: sha512-ROWKGJls7vLeFaQtI3hZVCJOkUoZ05xAi2t2qysM4d7dwVKrfm5jUOqWh8JgLL7Iup3XqJ0mKXXZuwJ3s03RSw==} engines: {node: '>=16.0.0', npm: '>=7.0.0'} @@ -7823,14 +7715,10 @@ packages: is-path-inside: 3.0.3 dev: true - /is-interactive@1.0.0: - resolution: {integrity: sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==} - engines: {node: '>=8'} - dev: false - /is-interactive@2.0.0: resolution: {integrity: sha512-qP1vozQRI+BMOPcjFzrjXuQvdak2pHNUMZoeG2eRbiSqyvbEf/wQtEOTOX1guk6E3t36RkaqiSt8A/6YElNxLQ==} engines: {node: '>=12'} + dev: true /is-map@2.0.2: resolution: {integrity: sha512-cOZFQQozTha1f4MxLFzlgKYPTyj26picdZTx82hbc/Xf4K/tZOOXSCkMvU4pKioRXGDLJRn0GM7Upe7kR721yg==} @@ -7975,10 +7863,12 @@ packages: /is-unicode-supported@0.1.0: resolution: {integrity: sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==} engines: {node: '>=10'} + dev: true /is-unicode-supported@1.3.0: resolution: {integrity: sha512-43r2mRvz+8JRIKnWJ+3j8JtjRKZ6GmjzfaE/qiBJnikNnYv/6bagRJ1kUhNk8R5EX/GkobD+r+sfxCPJsiKBLQ==} engines: {node: '>=12'} + dev: true /is-weakmap@2.0.1: resolution: {integrity: sha512-NSBR4kH5oVj1Uwvv970ruUkCV7O1mzgVFO4/rev2cLRda9Tm9HrL70ZPut4rOHgY0FNrUu9BCbXA2sdQ+x0chA==} @@ -8046,14 +7936,6 @@ packages: engines: {node: '>=0.10.0'} dev: true - /isomorphic-ws@5.0.0(ws@8.14.2): - resolution: {integrity: sha512-muId7Zzn9ywDsyXgTIafTry2sV3nySZeUDe6YedVd1Hvuuep5AsIlqK+XefWpYTyJG5e503F2xIuT2lcU6rCSw==} - peerDependencies: - ws: '*' - dependencies: - ws: 8.14.2 - dev: false - /istanbul-lib-coverage@3.2.0: resolution: {integrity: sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==} engines: {node: '>=8'} @@ -8360,11 +8242,6 @@ packages: engines: {node: '>=6'} dev: true - /kysely@0.23.5: - resolution: {integrity: sha512-TH+b56pVXQq0tsyooYLeNfV11j6ih7D50dyN8tkM0e7ndiUH28Nziojiog3qRFlmEj9XePYdZUrNJ2079Qjdow==} - engines: {node: '>=14.0.0'} - dev: false - /latest-version@5.1.0: resolution: {integrity: sha512-weT+r0kTkRQdCdYCNtkMwWXQTMEswKrFBkm4ckQOMVhhqhIMI1UT2hMj+1iigIhgSZm5gTmrRXBNoGUgaTY1xA==} engines: {node: '>=8'} @@ -8547,6 +8424,7 @@ packages: dependencies: chalk: 4.1.2 is-unicode-supported: 0.1.0 + dev: true /log-symbols@5.1.0: resolution: {integrity: sha512-l0x2DvrW294C9uDCoQe1VSU4gf529FkSZ6leBl4TiqZH/e+0R7hSfHQBNut2mNygDgHwvYHfFLn6Oxb3VWj2rA==} @@ -8554,6 +8432,7 @@ packages: dependencies: chalk: 5.3.0 is-unicode-supported: 1.3.0 + dev: true /log-update@5.0.1: resolution: {integrity: sha512-5UtUDQ/6edw4ofyljDNcOVJQ4c7OjDro4h3y8e1GQL5iYElYclVHJ3zeWchylvMaKnDbDilC8irOVyexnA/Slw==} @@ -8903,11 +8782,6 @@ packages: resolution: {integrity: sha512-/sF3ee6zvScXMb1XFJ8gDsSnY+X8PbOyjIuBhtgis10W2Jx4ZjIhikUCIF9c4gpJxVnQIsPAFrSwTCuAjicP6g==} engines: {node: '>=8.0.0'} - /mute-stream@1.0.0: - resolution: {integrity: sha512-avsJQhyd+680gKXyG/sQc0nXaC6rBkPOfyHYcFb9+hdkqQkR9bdnkJ0AMZhke0oesPqIO+mFFJ+IdBc7mst4IA==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} - dev: false - /nanoid@3.3.3: resolution: {integrity: sha512-p1sjXuopFs0xg+fPASzQ28agW1oHD7xDsd9Xkf3T15H3c/cifrFHVwrh74PdoklAPi+i7MdRsE47vm2r6JoB+w==} engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} @@ -9206,36 +9080,6 @@ packages: type-check: 0.4.0 dev: true - /ora@5.4.1: - resolution: {integrity: sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==} - engines: {node: '>=10'} - dependencies: - bl: 4.1.0 - chalk: 4.1.2 - cli-cursor: 3.1.0 - cli-spinners: 2.9.1 - is-interactive: 1.0.0 - is-unicode-supported: 0.1.0 - log-symbols: 4.1.0 - strip-ansi: 6.0.1 - wcwidth: 1.0.1 - dev: false - - /ora@6.3.1: - resolution: {integrity: sha512-ERAyNnZOfqM+Ao3RAvIXkYh5joP220yf59gVe2X/cI6SiCxIdi4c9HZKZD8R6q/RDXEje1THBju6iExiSsgJaQ==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - dependencies: - chalk: 5.3.0 - cli-cursor: 4.0.0 - cli-spinners: 2.9.1 - is-interactive: 2.0.0 - is-unicode-supported: 1.3.0 - log-symbols: 5.1.0 - stdin-discarder: 0.1.0 - strip-ansi: 7.1.0 - wcwidth: 1.0.1 - dev: false - /ora@7.0.1: resolution: {integrity: sha512-0TUxTiFJWv+JnjWm4o9yvuskpEJLXTcng8MJuKd+SzAzp2o+OP3HWqNhB4OdJRt1Vsd9/mR0oyaEYlOnL7XIRw==} engines: {node: '>=16'} @@ -9251,11 +9095,6 @@ packages: strip-ansi: 7.1.0 dev: true - /os-tmpdir@1.0.2: - resolution: {integrity: sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==} - engines: {node: '>=0.10.0'} - dev: false - /p-cancelable@1.1.0: resolution: {integrity: sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==} engines: {node: '>=6'} @@ -9375,6 +9214,7 @@ packages: /p-timeout@6.1.2: resolution: {integrity: sha512-UbD77BuZ9Bc9aABo74gfXhNvzC9Tx7SxtHSh1fxvx3jTLLYvmVhiQZZrJzqqU0jKbN32kb5VOKiLEQI/3bIjgQ==} engines: {node: '>=14.16'} + dev: true /p-try@2.2.0: resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} @@ -9385,6 +9225,7 @@ packages: engines: {node: '>=12'} dependencies: p-timeout: 6.1.2 + dev: true /package-json@6.5.0: resolution: {integrity: sha512-k3bdm2n25tkyxcjSKzB5x8kfVxlMdgsbPr0GkZcwHsLpba6cBjqCt1KlcChKEvxHIcTB1FVMuwoijZ26xex5MQ==} @@ -10666,20 +10507,13 @@ packages: lowercase-keys: 1.0.1 dev: true - /restore-cursor@3.1.0: - resolution: {integrity: sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==} - engines: {node: '>=8'} - dependencies: - onetime: 5.1.2 - signal-exit: 3.0.7 - dev: false - /restore-cursor@4.0.0: resolution: {integrity: sha512-I9fPXU9geO9bHOt9pHHOhOkYerIMsmVaWB0rA2AI9ERh/+x/i7MV5HKBNrg+ljO5eoPVgCcnFuRjJ9uH6I/3eg==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} dependencies: onetime: 5.1.2 signal-exit: 3.0.7 + dev: true /retry@0.13.1: resolution: {integrity: sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==} @@ -10705,11 +10539,6 @@ packages: resolution: {integrity: sha512-EBR4I2VDSSYr7PkBmFy04uhycIpDKp+21p/jARYXlCSjQksTBQcJ0HFUPOO79EPPH5JS6VAhiIQbycf0O3JAxQ==} dev: true - /run-async@3.0.0: - resolution: {integrity: sha512-540WwVDOMxA6dN6We19EcT9sc3hkXPw5mzRNGM3FkdN/vtE9NFvj5lFAPNwUDmJjXidm3v7TC1cTE7t17Ulm1Q==} - engines: {node: '>=0.12.0'} - dev: false - /run-parallel@1.2.0: resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} dependencies: @@ -10720,6 +10549,7 @@ packages: resolution: {integrity: sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==} dependencies: tslib: 2.6.2 + dev: true /sade@1.8.1: resolution: {integrity: sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==} @@ -11003,6 +10833,7 @@ packages: /signal-exit@3.0.7: resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} + dev: true /signal-exit@4.1.0: resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} @@ -11209,6 +11040,7 @@ packages: engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} dependencies: bl: 5.1.0 + dev: true /stream-browserify@3.0.0: resolution: {integrity: sha512-H73RAHsVBapbim0tU2JwwOiXUj+fikfiaoYAKHF3VJfA0pe2BCzkhAHBlLG6REzE+2WNZcxOXjK7lkso+9euLA==} @@ -11333,6 +11165,7 @@ packages: engines: {node: '>=12'} dependencies: ansi-regex: 6.0.1 + dev: true /strip-bom-string@1.0.0: resolution: {integrity: sha512-uCC2VHvQRYu+lMh4My/sFNmF2klFymLX1wHJeXnbEJERpV/ZsVuonzerjfrGpIGF7LBVa1O7i9kjiWvJiFck8g==} @@ -11399,6 +11232,7 @@ packages: engines: {node: '>=8'} dependencies: has-flag: 4.0.0 + dev: true /supports-color@8.1.1: resolution: {integrity: sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==} @@ -11518,13 +11352,6 @@ packages: resolution: {integrity: sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==} dev: true - /tmp@0.0.33: - resolution: {integrity: sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==} - engines: {node: '>=0.6.0'} - dependencies: - os-tmpdir: 1.0.2 - dev: false - /to-fast-properties@2.0.0: resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==} engines: {node: '>=4'} @@ -11589,6 +11416,7 @@ packages: /tslib@2.6.2: resolution: {integrity: sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==} + dev: true /tsutils-etc@1.4.2(tsutils@3.21.0)(typescript@4.9.5): resolution: {integrity: sha512-2Dn5SxTDOu6YWDNKcx1xu2YUy6PUeKrWZB/x2cQ8vY2+iz3JRembKn/iZ0JLT1ZudGNwQQvtFX9AwvRHbXuPUg==} @@ -11640,11 +11468,6 @@ packages: engines: {node: '>=10'} dev: true - /type-fest@0.21.3: - resolution: {integrity: sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==} - engines: {node: '>=10'} - dev: false - /type-fest@0.3.1: resolution: {integrity: sha512-cUGJnCdr4STbePCgqNFbpVNCepa+kAVohJs1sLhxzdH+gnEoOd8VhbYa7pD3zZYGiURWM2xzEII3fQcRizDkYQ==} engines: {node: '>=6'} @@ -12101,12 +11924,6 @@ packages: minimalistic-assert: 1.0.1 dev: true - /wcwidth@1.0.1: - resolution: {integrity: sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==} - dependencies: - defaults: 1.0.4 - dev: false - /web-encoding@1.1.5: resolution: {integrity: sha512-HYLeVCdJ0+lBYV2FvNZmv3HJ2Nt0QYXqZojk3d9FJOLkwnuhzM9tmamh8d7HPM8QqjKH8DeHkFTx+CFlWpZZDA==} dependencies: @@ -12394,15 +12211,6 @@ packages: resolution: {integrity: sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw==} dev: true - /wrap-ansi@6.2.0: - resolution: {integrity: sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==} - engines: {node: '>=8'} - dependencies: - ansi-styles: 4.3.0 - string-width: 4.2.3 - strip-ansi: 6.0.1 - dev: false - /wrap-ansi@7.0.0: resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} engines: {node: '>=10'} @@ -12457,6 +12265,7 @@ packages: optional: true utf-8-validate: optional: true + dev: true /xdg-basedir@4.0.0: resolution: {integrity: sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q==} @@ -12542,10 +12351,6 @@ packages: engines: {node: '>=10'} dev: true - /zod@3.22.4: - resolution: {integrity: sha512-iC+8Io04lddc+mVqQ9AZ7OQ2MrUKGN+oIQyq1vemgt46jwCwLfhq7/pwnBnNXXXZb8VTVLKwp9EDkx+ryxIWmg==} - dev: false - /zwitch@1.0.5: resolution: {integrity: sha512-V50KMwwzqJV0NpZIZFwfOD5/lyny3WlSzRiXgA0G7VUnRlqttta1L6UQIHzd6EuBY/cHGfwTIck7w1yH6Q5zUw==} dev: true From 54c48a4fb6ef0903ae7bdbc68537ca85046c0d32 Mon Sep 17 00:00:00 2001 From: DAG House <111574116+it-dag-house@users.noreply.github.com> Date: Tue, 10 Oct 2023 16:33:00 +0200 Subject: [PATCH 2/3] chore(main): release capabilities 9.5.0 (#965) :robot: I have created a release *beep* *boop* --- ## [9.5.0](https://github.com/web3-storage/w3up/compare/capabilities-v9.4.0...capabilities-v9.5.0) (2023-10-10) ### Features * revocation handler ([#960](https://github.com/web3-storage/w3up/issues/960)) ([91f52c6](https://github.com/web3-storage/w3up/commit/91f52c6d35e4aea2a98c75d8b95ff61cdffac452)) ### Bug Fixes * upgrade to latest ts ([#962](https://github.com/web3-storage/w3up/issues/962)) ([711e3f7](https://github.com/web3-storage/w3up/commit/711e3f73f6905fde0d929952fff70be845a55fa1)) --- This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please). --- .github/release-please-manifest.json | 2 +- packages/capabilities/CHANGELOG.md | 12 ++++++++++++ packages/capabilities/package.json | 2 +- 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/.github/release-please-manifest.json b/.github/release-please-manifest.json index fe4bbba6b..b5bd0ccb2 100644 --- a/.github/release-please-manifest.json +++ b/.github/release-please-manifest.json @@ -2,7 +2,7 @@ "packages/access-client": "15.3.0", "packages/filecoin-api": "1.4.4", "packages/filecoin-client": "1.3.0", - "packages/capabilities": "9.4.0", + "packages/capabilities": "9.5.0", "packages/upload-api": "5.8.0", "packages/upload-client": "9.4.1", "packages/w3up-client": "8.0.3", diff --git a/packages/capabilities/CHANGELOG.md b/packages/capabilities/CHANGELOG.md index 8e987e416..227a1ba80 100644 --- a/packages/capabilities/CHANGELOG.md +++ b/packages/capabilities/CHANGELOG.md @@ -1,5 +1,17 @@ # Changelog +## [9.5.0](https://github.com/web3-storage/w3up/compare/capabilities-v9.4.0...capabilities-v9.5.0) (2023-10-10) + + +### Features + +* revocation handler ([#960](https://github.com/web3-storage/w3up/issues/960)) ([91f52c6](https://github.com/web3-storage/w3up/commit/91f52c6d35e4aea2a98c75d8b95ff61cdffac452)) + + +### Bug Fixes + +* upgrade to latest ts ([#962](https://github.com/web3-storage/w3up/issues/962)) ([711e3f7](https://github.com/web3-storage/w3up/commit/711e3f73f6905fde0d929952fff70be845a55fa1)) + ## [9.4.0](https://github.com/web3-storage/w3up/compare/capabilities-v9.3.0...capabilities-v9.4.0) (2023-10-10) diff --git a/packages/capabilities/package.json b/packages/capabilities/package.json index d26566e83..b926bbe89 100644 --- a/packages/capabilities/package.json +++ b/packages/capabilities/package.json @@ -1,6 +1,6 @@ { "name": "@web3-storage/capabilities", - "version": "9.4.0", + "version": "9.5.0", "description": "Capabilities provided by web3.storage", "homepage": "https://github.com/web3-storage/w3protocol/tree/main/packages/capabilities", "repository": { From 81abb0589c8d5bb4e8fdf6b262ce9bf58e294fa9 Mon Sep 17 00:00:00 2001 From: Travis Vachon Date: Tue, 10 Oct 2023 15:52:28 +0100 Subject: [PATCH 3/3] chore: back out settings.json (#968) realllllly thought I removed this --- .vscode/settings.json | 5 ----- 1 file changed, 5 deletions(-) delete mode 100644 .vscode/settings.json diff --git a/.vscode/settings.json b/.vscode/settings.json deleted file mode 100644 index 43734c896..000000000 --- a/.vscode/settings.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "javascript.format.insertSpaceBeforeFunctionParenthesis": false, - "typescript.format.insertSpaceBeforeFunctionParenthesis": false, - "typescript.tsdk": "node_modules/typescript/lib" -}