diff --git a/.github/release-please-config.json b/.github/release-please-config.json index 4959779e8..13008170f 100644 --- a/.github/release-please-config.json +++ b/.github/release-please-config.json @@ -1,7 +1,7 @@ { "separate-pull-requests": true, "packages": { - "packages/access": {}, + "packages/access-client": {}, "packages/access-api": {}, "packages/upload-client": {}, "packages/wallet": {}, diff --git a/.github/release-please-manifest.json b/.github/release-please-manifest.json index 723a0c58c..cb5ce3e79 100644 --- a/.github/release-please-manifest.json +++ b/.github/release-please-manifest.json @@ -1,6 +1,6 @@ { "packages/wallet": "1.0.0", - "packages/access": "4.0.2", + "packages/access-client": "4.0.2", "packages/access-api": "3.0.0", "packages/store": "2.0.0" } diff --git a/.github/workflows/access.yml b/.github/workflows/access-client.yml similarity index 87% rename from .github/workflows/access.yml rename to .github/workflows/access-client.yml index ab4bb798c..3600ef4c4 100644 --- a/.github/workflows/access.yml +++ b/.github/workflows/access-client.yml @@ -1,4 +1,4 @@ -name: Access SDK +name: Access Client env: CI: true FORCE_COLOR: 1 @@ -7,12 +7,12 @@ on: branches: - main paths: - - 'packages/access/**' + - 'packages/access-client/**' - '.github/workflows/access.yml' - 'pnpm-lock.yaml' pull_request: paths: - - 'packages/access/**' + - 'packages/access-client/**' - '.github/workflows/access.yml' - 'pnpm-lock.yaml' jobs: diff --git a/.github/workflows/manual.yml b/.github/workflows/manual.yml index 6d99b4000..97e31e1b8 100644 --- a/.github/workflows/manual.yml +++ b/.github/workflows/manual.yml @@ -9,9 +9,10 @@ on: default: 'access-api' options: - access-api - - access - upload-client + - access-client - wallet + - docs environment: description: 'Environment to deploy' required: true @@ -52,9 +53,9 @@ jobs: with: environment: ${{ github.event.inputs.environment }} secrets: inherit - deploy-access: + deploy-access-client: runs-on: ubuntu-latest - if: github.event.inputs.package == 'access' + if: github.event.inputs.package == 'access-client' steps: - uses: actions/checkout@v3 - uses: pnpm/action-setup@v2.2.3 @@ -96,3 +97,28 @@ jobs: - run: pnpm -r --filter @web3-storage/upload-client publish --tag next --access public env: NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}} + deploy-docs: + runs-on: ubuntu-latest + if: github.event.inputs.package == 'docs' + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} + steps: + - uses: actions/checkout@v3 + - uses: pnpm/action-setup@v2.2.3 + with: + version: 7 + - uses: actions/setup-node@v3 + with: + node-version: 18 + registry-url: 'https://registry.npmjs.org' + cache: 'pnpm' + - run: pnpm install + - run: pnpm run docs + - uses: actions/configure-pages@v2 + - uses: actions/upload-pages-artifact@v1 + with: + path: './docs' + - name: Deploy to GitHub Pages + id: deployment + uses: actions/deploy-pages@v1 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 1c387c3ae..7619ca5b9 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -23,7 +23,7 @@ jobs: release-type: node publish-access: needs: release - if: contains(fromJson(needs.release.outputs.paths_released), 'packages/access') + if: contains(fromJson(needs.release.outputs.paths_released), 'packages/access-client') runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 diff --git a/package.json b/package.json index 5e9807050..b008182e2 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,5 @@ { - "name": "ucan-protocol", + "name": "w3-protocol", "version": "0.0.0", "private": true, "workspaces": [ @@ -11,14 +11,15 @@ "clean": "rm -rf docs node_modules pnpm-lock.yaml packages/*/{pnpm-lock.yaml,coverage,.nyc_output,dist,node_modules,.next}", "lint": "pnpm -r --if-present run lint", "test": "pnpm -r --if-present run test", - "check": "pnpm -r --if-present run check" + "check": "pnpm -r --if-present run check", + "docs": "typedoc --out docs" }, "devDependencies": { "lint-staged": "^13.0.3", "prettier": "2.7.1", "simple-git-hooks": "^2.8.1", - "typescript": "^4.8.4", - "wrangler": "^2.1.13" + "typescript": "4.8.4", + "wrangler": "^2.3.2" }, "simple-git-hooks": { "pre-commit": "npx lint-staged" @@ -35,5 +36,9 @@ }, "engines": { "node": ">=16" + }, + "dependencies": { + "typedoc": "^0.23.21", + "typedoc-plugin-missing-exports": "^1.0.0" } } diff --git a/packages/access-api/package.json b/packages/access-api/package.json index 5bdd516fd..5b464ac8f 100644 --- a/packages/access-api/package.json +++ b/packages/access-api/package.json @@ -11,25 +11,25 @@ "dev": "scripts/cli.js dev", "build": "scripts/cli.js build", "check": "tsc --build", - "test": "tsc --build && ava --timeout 10s" + "test": "pnpm build && tsc --build && ava --timeout 10s" }, "author": "Hugo Dias (hugodias.me)", "license": "(Apache-2.0 OR MIT)", "dependencies": { "@ipld/dag-ucan": "^2.0.1", - "@ucanto/client": "^3.0.1", - "@ucanto/core": "^3.0.1", - "@ucanto/interface": "^3.0.0", - "@ucanto/principal": "^3.0.0", - "@ucanto/server": "^3.0.1", - "@ucanto/transport": "^3.0.1", - "@ucanto/validator": "^3.0.1", + "@ucanto/client": "^3.0.2", + "@ucanto/core": "^3.0.2", + "@ucanto/interface": "^3.0.1", + "@ucanto/principal": "^3.0.1", + "@ucanto/server": "^3.0.4", + "@ucanto/transport": "^3.0.2", + "@ucanto/validator": "^3.0.4", "@web3-storage/access": "workspace:^", "@web3-storage/worker-utils": "0.4.3-dev", "multiformats": "^10.0.2", "nanoid": "^4.0.0", "p-retry": "^5.1.1", - "preact": "^10.11.2", + "preact": "^10.11.3", "preact-render-to-string": "^5.2.6", "qrcode": "^1.5.1", "toucan-js": "^2.7.0", @@ -39,28 +39,29 @@ "@cloudflare/workers-types": "^3.18.0", "@databases/escape-identifier": "^1.0.3", "@databases/sql": "^3.2.0", - "@sentry/cli": "^2.8.0", - "@sentry/webpack-plugin": "^1.19.1", + "@sentry/cli": "^2.9.0", + "@sentry/webpack-plugin": "^1.20.0", "@types/assert": "^1.5.6", "@types/git-rev-sync": "^2.0.0", - "@types/node": "^18.11.7", + "@types/node": "^18.11.9", "@types/qrcode": "^1.5.0", "assert": "^2.0.0", - "ava": "^5.0.1", + "ava": "^5.1.0", "better-sqlite3": "7.6.2", "buffer": "^6.0.3", "delay": "^5.0.0", "dotenv": "^16.0.3", - "esbuild": "^0.15.12", + "esbuild": "^0.15.14", "execa": "^6.1.0", - "git-rev-sync": "^3.0.1", + "git-rev-sync": "^3.0.2", "hd-scripts": "^3.0.2", - "miniflare": "^2.10.0", + "miniflare": "^2.11.0", + "p-wait-for": "^5.0.0", "process": "^0.11.10", - "readable-stream": "^4.1.0", - "sade": "^1.7.4", + "readable-stream": "^4.2.0", + "sade": "^1.8.1", "typescript": "4.8.4", - "wrangler": "^2.1.13" + "wrangler": "^2.3.2" }, "eslintConfig": { "extends": [ @@ -92,8 +93,6 @@ ], "ava": { "failFast": true, - "concurrency": 1, - "workerThreads": false, "files": [ "test/**/*.test.js" ], diff --git a/packages/access-api/sql/migrate.js b/packages/access-api/sql/migrate.js index 345775097..43bdc5b2b 100644 --- a/packages/access-api/sql/migrate.js +++ b/packages/access-api/sql/migrate.js @@ -28,7 +28,7 @@ export async function migrate(db) { } catch (error) { const err = /** @type {Error} */ (error) // eslint-disable-next-line no-console - console.log({ + console.error('D1 Error', { message: err.message, // @ts-ignore cause: err.cause?.message, diff --git a/packages/access-api/src/kvs/accounts.js b/packages/access-api/src/kvs/accounts.js index bf2c47020..466385a92 100644 --- a/packages/access-api/src/kvs/accounts.js +++ b/packages/access-api/src/kvs/accounts.js @@ -48,7 +48,7 @@ export class Accounts { tableName: 'accounts', fields: '*', where: { - conditions: 'did =?1', + conditions: 'did=?1', params: [did], }, }) @@ -68,10 +68,12 @@ export class Accounts { } /** - * @param {string} email + * Save account delegation per email + * + * @param {`mailto:${string}`} email * @param {Ucanto.Delegation} delegation */ - async saveAccount(email, delegation) { + async saveDelegation(email, delegation) { const accs = /** @type {string[] | undefined} */ ( await this.kv.get(email, { type: 'json', @@ -90,10 +92,27 @@ export class Accounts { } /** - * @param {string} email + * Check if we have delegations for an email + * + * @param {`mailto:${string}`} email */ - async hasAccounts(email) { + async hasDelegations(email) { const r = await this.kv.get(email) return Boolean(r) } + + /** + * @param {`mailto:${string}`} email + */ + async getDelegations(email) { + const r = await this.kv.get(email, { type: 'json' }) + + if (!r) { + return + } + + return /** @type {import('@web3-storage/access/types').EncodedDelegation<[import('@web3-storage/access/types').Any]>[]} */ ( + r + ) + } } diff --git a/packages/access-api/src/kvs/validations.js b/packages/access-api/src/kvs/validations.js index e9a9d7757..284255a15 100644 --- a/packages/access-api/src/kvs/validations.js +++ b/packages/access-api/src/kvs/validations.js @@ -13,11 +13,12 @@ export class Validations { } /** - * @param {string} ucan + * @template {import('@ucanto/interface').Capabilities} [T=import('@ucanto/interface').Capabilities] + * @param {import('@web3-storage/access/src/types').EncodedDelegation} ucan */ async put(ucan) { const delegation = - /** @type {import('@ucanto/interface').Delegation<[import('@web3-storage/access/capabilities/types').VoucherClaim]>} */ ( + /** @type {import('@ucanto/interface').Delegation} */ ( await stringToDelegation(ucan) ) diff --git a/packages/access-api/src/routes/validate-email.js b/packages/access-api/src/routes/validate-email.js index e0d826688..056659ebd 100644 --- a/packages/access-api/src/routes/validate-email.js +++ b/packages/access-api/src/routes/validate-email.js @@ -11,9 +11,16 @@ import { * @param {import('../bindings.js').RouteContext} env */ export async function validateEmail(req, env) { + if (req.query && req.query.ucan && req.query.mode === 'recover') { + return recover(req, env) + } if (req.query && req.query.ucan) { try { - const delegation = await env.kvs.validations.put(req.query.ucan) + const delegation = await env.kvs.validations.put( + /** @type {import('@web3-storage/access/src/types.js').EncodedDelegation<[import('@web3-storage/access/src/types.js').VoucherClaim]>} */ ( + req.query.ucan + ) + ) return new HtmlResponse( ( @@ -48,3 +55,44 @@ export async function validateEmail(req, env) { ) } + +/** + * @param {import('@web3-storage/worker-utils/router').ParsedRequest} req + * @param {import('../bindings.js').RouteContext} env + */ +async function recover(req, env) { + try { + const delegation = await env.kvs.validations.put( + /** @type {import('@web3-storage/access/src/types.js').EncodedDelegation<[import('@web3-storage/access/src/types.js').AccountRecover]>} */ ( + req.query.ucan + ) + ) + + return new HtmlResponse( + ( + + ) + ) + } catch (error) { + const err = /** @type {Error} */ (error) + + if (err.message.includes('Invalid expiration')) { + return new HtmlResponse( + + ) + } + + env.log.error(err) + return new HtmlResponse( + + ) + } +} diff --git a/packages/access-api/src/routes/validate-ws.js b/packages/access-api/src/routes/validate-ws.js index 031d620a5..024a049ae 100644 --- a/packages/access-api/src/routes/validate-ws.js +++ b/packages/access-api/src/routes/validate-ws.js @@ -3,7 +3,7 @@ import pRetry from 'p-retry' const run = async ( /** @type {import('../kvs/validations').Validations} */ kv, /** @type {WebSocket} */ server, - /** @type {any} */ did + /** @type {string} */ did ) => { const d = await kv.get(did) diff --git a/packages/access-api/src/service/index.js b/packages/access-api/src/service/index.js index b9eabcdf3..21f526316 100644 --- a/packages/access-api/src/service/index.js +++ b/packages/access-api/src/service/index.js @@ -4,7 +4,11 @@ import * as Account from '@web3-storage/access/capabilities/account' import { voucherClaimProvider } from './voucher-claim.js' import { voucherRedeemProvider } from './voucher-redeem.js' import * as DID from '@ipld/dag-ucan/did' -import { delegationToString } from '@web3-storage/access/encoding' +import { + delegationToString, + stringToDelegation, +} from '@web3-storage/access/encoding' +import { any } from '@web3-storage/access/capabilities/wildcard' /** * @param {import('../bindings').RouteContext} ctx @@ -18,13 +22,50 @@ export function service(ctx) { }, account: { - info: Server.provide(Account.info, async ({ capability }) => { + info: Server.provide(Account.info, async ({ capability, invocation }) => { const results = await ctx.kvs.accounts.get(capability.with) if (!results) { - throw new Failure('Account not found...') + return new Failure('Account not found.') } return results }), + recover: Server.provide( + Account.recover, + async ({ capability, invocation }) => { + if (capability.with !== ctx.signer.did()) { + return new Failure( + `Resource ${ + capability.with + } does not service did ${ctx.signer.did()}` + ) + } + + const encoded = await ctx.kvs.accounts.getDelegations( + capability.nb.identity + ) + if (!encoded) { + return new Failure( + `No delegations found for ${capability.nb.identity}` + ) + } + + const results = [] + for (const e of encoded) { + const proof = await stringToDelegation(e) + const del = await any.delegate({ + audience: invocation.issuer, + issuer: ctx.signer, + with: proof.capabilities[0].with, + expiration: Infinity, + proofs: [proof], + }) + + results.push(await delegationToString(del)) + } + + return results + } + ), 'recover-validation': Server.provide( Account.recoverValidation, @@ -33,9 +74,9 @@ export function service(ctx) { // if yes send email with account/login // if not error "no accounts for email X" - const email = capability.nb.email - if (!(await ctx.kvs.accounts.hasAccounts(email))) { - throw new Failure( + const email = capability.nb.identity + if (!(await ctx.kvs.accounts.hasDelegations(email))) { + return new Failure( `No accounts found for email: ${email.replace('mailto:', '')}.` ) } @@ -46,21 +87,29 @@ export function service(ctx) { audience: DID.parse(capability.with), with: ctx.signer.did(), lifetimeInSeconds: 60 * 10, + nb: { + identity: email, + }, proofs: [ await Account.recover.delegate({ audience: ctx.signer, issuer: ctx.signer, - lifetimeInSeconds: 60 * 1000, + expiration: Infinity, with: ctx.signer.did(), + nb: { + identity: 'mailto:*', + }, }), ], }) .delegate() const encoded = await delegationToString(inv) + const url = `${ctx.url.protocol}//${ctx.url.host}/validate-email?ucan=${encoded}&mode=recover` + // For testing if (ctx.config.ENV === 'test') { - return encoded + return url } } ), diff --git a/packages/access-api/src/service/voucher-claim.js b/packages/access-api/src/service/voucher-claim.js index 395c99e5c..2859c3ce1 100644 --- a/packages/access-api/src/service/voucher-claim.js +++ b/packages/access-api/src/service/voucher-claim.js @@ -40,9 +40,7 @@ export function voucherClaimProvider(ctx) { return encoded } - const url = `${ctx.url.protocol}//${ - ctx.url.host - }/validate-email?ucan=${encoded}&did=${invocation.issuer.did()}` + const url = `${ctx.url.protocol}//${ctx.url.host}/validate-email?ucan=${encoded}` await ctx.email.sendValidation({ to: capability.nb.identity.replace('mailto:', ''), diff --git a/packages/access-api/src/service/voucher-redeem.js b/packages/access-api/src/service/voucher-redeem.js index 54fe9a67c..d86eee05e 100644 --- a/packages/access-api/src/service/voucher-redeem.js +++ b/packages/access-api/src/service/voucher-redeem.js @@ -1,22 +1,28 @@ import * as Server from '@ucanto/server' import * as Voucher from '@web3-storage/access/capabilities/voucher' import { Delegation } from '@ucanto/core' +import { Failure } from '@ucanto/server' /** * @param {import('../bindings').RouteContext} ctx */ export function voucherRedeemProvider(ctx) { return Server.provide(Voucher.redeem, async ({ capability, invocation }) => { + if (capability.with !== ctx.signer.did()) { + return new Failure( + `Resource ${capability.with} does not service did ${ctx.signer.did()}` + ) + } // @ts-ignore - TODO fix this await ctx.kvs.accounts.create(capability, invocation) - // We should only save delegation for redeems + // We should only save delegation for email identities if (capability.nb.identity.startsWith('mailto:')) { for (const p of invocation.proofs) { if ( Delegation.isDelegation(p) && p.audience.did() === ctx.signer.did() ) { - await ctx.kvs.accounts.saveAccount(capability.nb.identity, p) + await ctx.kvs.accounts.saveDelegation(capability.nb.identity, p) } } } diff --git a/packages/access-api/src/utils/html.js b/packages/access-api/src/utils/html.js index 7cd1242a5..301a1d8e5 100644 --- a/packages/access-api/src/utils/html.js +++ b/packages/access-api/src/utils/html.js @@ -1,4 +1,6 @@ import { render } from 'preact-render-to-string' +// eslint-disable-next-line no-unused-vars +import * as Ucanto from '@ucanto/interface' /** * Build HTML document @@ -70,7 +72,7 @@ export class HtmlResponse extends Response { /** * * @param {object} param0 - * @param {import('@ucanto/interface').Delegation<[import('@web3-storage/access/capabilities/types').VoucherClaim]>} param0.delegation + * @param {Ucanto.Delegation<[import('@web3-storage/access/capabilities/types').VoucherClaim]> | Ucanto.Delegation<[import('@web3-storage/access/capabilities/types').AccountRecover]>} param0.delegation * @param {string} param0.ucan * @param {string} param0.qrcode */ diff --git a/packages/access-api/test/account-recover.test.js b/packages/access-api/test/account-recover.test.js index b8acfd48a..3b90b9680 100644 --- a/packages/access-api/test/account-recover.test.js +++ b/packages/access-api/test/account-recover.test.js @@ -1,10 +1,12 @@ import * as Account from '@web3-storage/access/capabilities/account' import { stringToDelegation } from '@web3-storage/access/encoding' +import pWaitFor from 'p-wait-for' import { context, test } from './helpers/context.js' +import { Validations } from '../src/kvs/validations.js' import { createAccount } from './helpers/utils.js' -test.before(async (t) => { +test.beforeEach(async (t) => { t.context = await context() }) @@ -17,25 +19,108 @@ test('should fail before registering account', async (t) => { audience: service, with: issuer.did(), nb: { - email: 'mailto:hello@dag.house', + identity: 'mailto:hello@dag.house', }, }) .execute(conn) if (inv?.error) { - t.deepEqual( - inv.message, - `service handler {can: "account/recover-validation"} error: No accounts found for email: hello@dag.house.` - ) + t.deepEqual(inv.message, `No accounts found for email: hello@dag.house.`) } else { return t.fail() } }) -test('should return account/login', async (t) => { - const { issuer, service, conn } = t.context +test('should return account/recover', async (t) => { + const { issuer, service, conn, mf } = t.context + + await createAccount(issuer, service, conn, 'account-recover@dag.house') + + const inv = await Account.recoverValidation + .invoke({ + issuer, + audience: service, + with: issuer.did(), + nb: { + identity: 'mailto:account-recover@dag.house', + }, + }) + .execute(conn) + + if (!inv || inv.error) { + return t.fail('failed to recover') + } + + const url = new URL(inv) + const encoded = + /** @type {import('@web3-storage/access/types').EncodedDelegation<[import('@web3-storage/access/capabilities/types').AccountRecover]>} */ ( + url.searchParams.get('ucan') + ) + + const del = await stringToDelegation(encoded) + + t.deepEqual(del.audience.did(), issuer.did()) + t.deepEqual(del.issuer.did(), service.did()) + t.deepEqual(del.capabilities[0].can, 'account/recover') + const rsp = await mf.dispatchFetch(url) + const html = await rsp.text() + + t.assert(html.includes(encoded)) + + const validations = new Validations(await mf.getKVNamespace('VALIDATIONS')) + const recoverEncoded = + /** @type {import('@web3-storage/access/types').EncodedDelegation<[import('@web3-storage/access/capabilities/types').AccountRecover]>} */ ( + await validations.get(issuer.did()) + ) + + t.truthy(recoverEncoded) + const recover = await stringToDelegation(recoverEncoded) + t.deepEqual(recover.audience.did(), issuer.did()) + t.deepEqual(recover.issuer.did(), service.did()) + t.deepEqual(recover.capabilities[0].can, 'account/recover') + + // ws + const res = await mf.dispatchFetch('http://localhost:8787/validate-ws', { + headers: { Upgrade: 'websocket' }, + }) + + const webSocket = res.webSocket + if (webSocket) { + let done = false + webSocket.accept() + webSocket.addEventListener('message', async (event) => { + // @ts-ignore + const data = JSON.parse(event.data) + + const encoded = + /** @type {import('@web3-storage/access/types').EncodedDelegation<[import('@web3-storage/access/capabilities/types').AccountRecover]>} */ ( + data.delegation + ) - await createAccount(issuer, service, conn, 'account-login@dag.house') + t.truthy(encoded) + const recover = await stringToDelegation(encoded) + t.deepEqual(recover.audience.did(), issuer.did()) + t.deepEqual(recover.issuer.did(), service.did()) + t.deepEqual(recover.capabilities[0].can, 'account/recover') + done = true + }) + + webSocket.send( + JSON.stringify({ + did: issuer.did(), + }) + ) + + await pWaitFor(() => done) + } else { + t.fail('should have ws') + } +}) + +test('should invoke account/recover and get account delegation', async (t) => { + const { issuer, service, conn } = t.context + const email = 'account-recover@dag.house' + const { account } = await createAccount(issuer, service, conn, email) const inv = await Account.recoverValidation .invoke({ @@ -43,7 +128,8 @@ test('should return account/login', async (t) => { audience: service, with: issuer.did(), nb: { - email: 'mailto:account-login@dag.house', + // @ts-ignore + identity: `mailto:${email}`, }, }) .execute(conn) @@ -52,13 +138,51 @@ test('should return account/login', async (t) => { return t.fail('failed to recover') } - const del = await stringToDelegation( - /** @type {import('@web3-storage/access/types').EncodedDelegation<[import('@web3-storage/access/capabilities/types').Any]>} */ ( - inv + const url = new URL(inv) + const encoded = + /** @type {import('@web3-storage/access/types').EncodedDelegation<[import('@web3-storage/access/capabilities/types').AccountRecover]>} */ ( + url.searchParams.get('ucan') ) - ) + + const del = await stringToDelegation(encoded) t.deepEqual(del.audience.did(), issuer.did()) t.deepEqual(del.issuer.did(), service.did()) t.deepEqual(del.capabilities[0].can, 'account/recover') + + const inv2 = await Account.recover + .invoke({ + issuer, + audience: service, + with: service.did(), + nb: { + identity: del.capabilities[0].nb.identity, + }, + proofs: [del], + }) + .execute(conn) + + if (!inv2 || inv2.error) { + return t.fail('failed to recover') + } + + const accountDelegation = await stringToDelegation(inv2[0]) + t.deepEqual(accountDelegation.audience.did(), issuer.did()) + t.deepEqual(accountDelegation.capabilities[0].can, '*') + t.deepEqual(accountDelegation.capabilities[0].with, account.did()) + + const accountInfo = await Account.info + .invoke({ + issuer, + audience: service, + with: account.did(), + proofs: [accountDelegation], + }) + .execute(conn) + + if (!accountInfo || accountInfo.error) { + return t.fail('failed to get account info') + } + + t.deepEqual(accountInfo.did, account.did()) }) diff --git a/packages/access-api/test/helpers/context.js b/packages/access-api/test/helpers/context.js index 6915afbd8..3f3a5bf5d 100644 --- a/packages/access-api/test/helpers/context.js +++ b/packages/access-api/test/helpers/context.js @@ -7,6 +7,7 @@ import { Miniflare } from 'miniflare' import path from 'path' import { fileURLToPath } from 'url' import { migrate } from '../../sql/migrate.js' +import { D1QB } from 'workers-qb' const __dirname = path.dirname(fileURLToPath(import.meta.url)) @@ -41,6 +42,7 @@ export async function context() { modules: true, bindings, d1Persist: undefined, + buildCommand: undefined, }) const binds = await mf.getBindings() @@ -57,6 +59,7 @@ export async function context() { ), service: Signer.parse(bindings.PRIVATE_KEY), issuer: principal, + db: new D1QB(db), } } diff --git a/packages/access-api/test/helpers/utils.js b/packages/access-api/test/helpers/utils.js index fbcd102f2..0618630eb 100644 --- a/packages/access-api/test/helpers/utils.js +++ b/packages/access-api/test/helpers/utils.js @@ -2,10 +2,10 @@ import * as UCAN from '@ipld/dag-ucan' // eslint-disable-next-line no-unused-vars import * as Types from '@ucanto/interface' -import { StoreMemory } from '@web3-storage/access/stores/store-memory' -import * as Any from '@web3-storage/access/capabilities/any' +import * as Any from '@web3-storage/access/capabilities/wildcard' import * as Voucher from '@web3-storage/access/capabilities/voucher' import { stringToDelegation } from '@web3-storage/access/encoding' +import { Signer } from '@ucanto/principal/ed25519' /** * @param {Types.UCAN.View} ucan @@ -27,8 +27,7 @@ export async function send(ucan, mf) { * @param {string} email */ export async function createAccount(issuer, service, conn, email) { - const store = new StoreMemory() - const account = await store.createAccount() + const account = await Signer.generate() const claim = await Voucher.claim .invoke({ issuer, @@ -83,4 +82,8 @@ export async function createAccount(issuer, service, conn, email) { console.log(redeem) throw new Error(redeem.message) } + + return { + account, + } } diff --git a/packages/access-api/test/voucher-claim.test.js b/packages/access-api/test/voucher-claim.test.js index d9b03d7e9..ea5364c31 100644 --- a/packages/access-api/test/voucher-claim.test.js +++ b/packages/access-api/test/voucher-claim.test.js @@ -3,7 +3,7 @@ import * as Voucher from '@web3-storage/access/capabilities/voucher' import { stringToDelegation } from '@web3-storage/access/encoding' import { context, test } from './helpers/context.js' -test.before(async (t) => { +test.beforeEach(async (t) => { t.context = await context() }) diff --git a/packages/access-api/test/voucher-redeem.test.js b/packages/access-api/test/voucher-redeem.test.js index afb12bff0..4a7687b1c 100644 --- a/packages/access-api/test/voucher-redeem.test.js +++ b/packages/access-api/test/voucher-redeem.test.js @@ -1,20 +1,20 @@ /* eslint-disable unicorn/prefer-number-properties */ -import * as Any from '@web3-storage/access/capabilities/any' +import * as Any from '@web3-storage/access/capabilities/wildcard' import * as Voucher from '@web3-storage/access/capabilities/voucher' import { stringToDelegation } from '@web3-storage/access/encoding' -import { StoreMemory } from '@web3-storage/access/stores/store-memory' import { context, test } from './helpers/context.js' import { createAccount } from './helpers/utils.js' +import { Accounts } from '../src/kvs/accounts.js' +import { Signer } from '@ucanto/principal/ed25519' -test.before(async (t) => { +test.beforeEach(async (t) => { t.context = await context() }) test('should return account/redeem', async (t) => { - const { issuer, service, conn, mf } = t.context + const { issuer, service, conn, mf, db } = t.context - const store = new StoreMemory() - const account = await store.createAccount() + const account = await Signer.generate() const claim = await Voucher.claim .invoke({ issuer, @@ -72,22 +72,24 @@ test('should return account/redeem', async (t) => { return t.fail() } - const accounts = await mf.getKVNamespace('ACCOUNTS') + const accounts = new Accounts(await mf.getKVNamespace('ACCOUNTS'), db) - const delEncoded = /** @type {string[]|undefined} */ ( - await accounts.get('mailto:email@dag.house', { - type: 'json', - }) - ) - if (!delEncoded) { + // check db for account + t.like(await accounts.get(account.did()), { + did: account.did(), + product: 'product:free', + email: 'email@dag.house', + agent: issuer.did(), + }) + + // check account delegations + const delegations = await accounts.getDelegations('mailto:email@dag.house') + + if (!delegations) { return t.fail('no delegation for email') } - const del = await stringToDelegation( - /** @type {import('@web3-storage/access/types').EncodedDelegation<[import('@web3-storage/access/capabilities/types').Any]>} */ ( - delEncoded[0] - ) - ) + const del = await stringToDelegation(delegations[0]) t.deepEqual(del.audience.did(), service.did()) t.deepEqual(del.capabilities[0].can, '*') @@ -124,3 +126,30 @@ test('should save multiple account delegation', async (t) => { // @ts-ignore t.assert(delEncoded.length === 2) }) + +test('should fail with wrong resource', async (t) => { + const { issuer, service, conn } = t.context + + const redeem = await Voucher.redeem + .invoke({ + issuer, + audience: service, + with: issuer.did(), + nb: { + account: issuer.did(), + identity: 'mailto:email@dag.house', + product: 'product:free', + }, + }) + .execute(conn) + + if (redeem.error) { + t.true(redeem.error) + t.deepEqual( + redeem.message, + `Resource ${issuer.did()} does not service did ${service.did()}` + ) + } else { + t.fail('should fail') + } +}) diff --git a/packages/access-api/tsconfig.json b/packages/access-api/tsconfig.json index 2fd4a2a4d..76ae2f9cf 100644 --- a/packages/access-api/tsconfig.json +++ b/packages/access-api/tsconfig.json @@ -8,5 +8,5 @@ }, "include": ["src", "scripts", "test", "package.json", "sql"], "exclude": ["**/node_modules/**"], - "references": [{ "path": "../access" }] + "references": [{ "path": "../access-client" }] } diff --git a/packages/access/CHANGELOG.md b/packages/access-client/CHANGELOG.md similarity index 100% rename from packages/access/CHANGELOG.md rename to packages/access-client/CHANGELOG.md diff --git a/packages/access/package.json b/packages/access-client/package.json similarity index 79% rename from packages/access/package.json rename to packages/access-client/package.json index c9ef88004..394ee1d67 100644 --- a/packages/access/package.json +++ b/packages/access-client/package.json @@ -1,12 +1,12 @@ { "name": "@web3-storage/access", "version": "4.0.2", - "description": "w3access SDK", - "homepage": "https://github.com/web3-storage/w3-protocol/tree/main/packages/access", + "description": "w3access client", + "homepage": "https://github.com/web3-storage/w3-protocol/tree/main/packages/access-client", "repository": { "type": "git", "url": "https://github.com/web3-storage/w3-protocol.git", - "directory": "packages/access" + "directory": "packages/access-client" }, "author": "Hugo Dias (hugodias.me)", "license": "(Apache-2.0 OR MIT)", @@ -29,15 +29,11 @@ ".": "./src/index.js", "./capabilities/*": "./src/capabilities/*.js", "./stores/*": "./src/stores/*.js", - "./connection": "./src/connection.js", "./types": "./src/types.js", "./encoding": "./src/encoding.js" }, "typesVersions": { "*": { - "connection": [ - "dist/src/connection" - ], "types": [ "dist/src/types" ], @@ -58,20 +54,19 @@ "dist/src/**/*.d.ts.map" ], "dependencies": { - "@ipld/car": "^5.0.0", + "@ipld/car": "^5.0.1", "@ipld/dag-ucan": "^2.0.1", "@noble/ed25519": "^1.7.1", - "@types/ws": "^8.5.3", - "@ucanto/client": "^3.0.1", - "@ucanto/core": "^3.0.1", - "@ucanto/interface": "^3.0.0", - "@ucanto/principal": "^3.0.0", - "@ucanto/server": "^3.0.1", - "@ucanto/transport": "^3.0.1", - "@ucanto/validator": "^3.0.1", + "@ucanto/client": "^3.0.2", + "@ucanto/core": "^3.0.2", + "@ucanto/interface": "^3.0.1", + "@ucanto/principal": "^3.0.1", + "@ucanto/server": "^3.0.4", + "@ucanto/transport": "^3.0.2", + "@ucanto/validator": "^3.0.4", "@web-std/fetch": "^4.1.0", "bigint-mod-arith": "^3.1.2", - "conf": "^10.1.2", + "conf": "^10.2.0", "inquirer": "^9.1.4", "isomorphic-ws": "^5.0.0", "multiformats": "^10.0.2", @@ -79,28 +74,29 @@ "one-webcrypto": "^1.0.3", "ora": "^6.1.2", "p-defer": "^4.0.0", - "p-queue": "^7.3.0", - "p-retry": "^5.1.1", "p-wait-for": "^5.0.0", + "streaming-iterables": "^7.1.0", + "type-fest": "^3.2.0", "uint8arrays": "^4.0.2", - "undici": "^5.12.0", - "ws": "^8.10.0", + "ws": "^8.11.0", "zod": "^3.19.1" }, "devDependencies": { "@types/assert": "^1.5.6", - "@types/inquirer": "^9.0.2", + "@types/inquirer": "^9.0.3", "@types/mocha": "^10.0.0", - "@types/node": "^18.11.7", + "@types/node": "^18.11.9", + "@types/ws": "^8.5.3", "@web-std/fetch": "^4.1.0", "assert": "^2.0.0", "delay": "^5.0.0", "dotenv": "^16.0.3", "hd-scripts": "^3.0.2", - "miniflare": "^2.9.0", + "miniflare": "^2.11.0", "mocha": "^10.1.0", + "p-queue": "^7.3.0", "playwright-test": "^8.1.1", - "sade": "^1.7.4", + "sade": "^1.8.1", "typescript": "4.8.4", "watch": "^1.0.2" }, @@ -115,7 +111,8 @@ } }, "rules": { - "unicorn/prefer-number-properties": "off" + "unicorn/prefer-number-properties": "off", + "unicorn/no-array-reduce": "off" }, "env": { "mocha": true diff --git a/packages/access-client/readme.md b/packages/access-client/readme.md new file mode 100644 index 000000000..e0cb77eb9 --- /dev/null +++ b/packages/access-client/readme.md @@ -0,0 +1 @@ +# Web3 Storage access client diff --git a/packages/access-client/src/agent.js b/packages/access-client/src/agent.js new file mode 100644 index 000000000..33d093121 --- /dev/null +++ b/packages/access-client/src/agent.js @@ -0,0 +1,496 @@ +/* eslint-disable max-depth */ +import * as DID from '@ipld/dag-ucan/did' +import * as Client from '@ucanto/client' +// @ts-ignore +// eslint-disable-next-line no-unused-vars +import * as Ucanto from '@ucanto/interface' +import * as CAR from '@ucanto/transport/car' +import * as CBOR from '@ucanto/transport/cbor' +import * as HTTP from '@ucanto/transport/http' +import { URI } from '@ucanto/validator' +import { Peer } from './awake/peer.js' +import * as Account from './capabilities/account.js' +import * as Voucher from './capabilities/voucher.js' +import { any as Any } from './capabilities/wildcard.js' +import { stringToDelegation } from './encoding.js' +import { Websocket, AbortError } from './utils/ws.js' +import { Signer } from '@ucanto/principal/ed25519' +import { invoke, delegate } from '@ucanto/core' +import { + isExpired, + isTooEarly, + validate, + canDelegateCapability, +} from './delegations.js' + +import { collect } from 'streaming-iterables' + +const HOST = 'https://access.web3.storage' + +/** + * @template {string} T + * @param {Ucanto.Principal} principal + * @param {typeof fetch} _fetch + * @param {URL} url + * @param {Ucanto.Transport.Channel} [channel] + * @returns {Promise>} + */ +export async function connection(principal, _fetch, url, channel) { + const _channel = + channel || + HTTP.open({ + url, + method: 'POST', + fetch: _fetch, + }) + const connection = Client.connect({ + id: principal, + encoder: CAR, + decoder: CBOR, + channel: _channel, + }) + + return connection +} + +/** + * @template {Ucanto.Signer} T + * Agent + */ +export class Agent { + /** @type {Ucanto.Principal|undefined} */ + #service + + /** @type {typeof fetch} */ + #fetch + + /** + * @param {import('./types').AgentOptions} opts + */ + constructor(opts) { + this.url = opts.url || new URL(HOST) + this.connection = opts.connection + this.issuer = opts.data.principal + this.store = opts.store + this.data = opts.data + + // private + this.#fetch = opts.fetch + this.#service = undefined + } + + /** + * @template {Ucanto.Signer} T + * @param {import('./types').AgentCreateOptions} opts + */ + static async create(opts) { + let _fetch = opts.fetch + const url = opts.url || new URL(HOST) + + // validate fetch implementation + if (!_fetch) { + if (typeof globalThis.fetch !== 'undefined') { + _fetch = globalThis.fetch.bind(globalThis) + } else { + throw new TypeError( + `Agent got undefined \`fetch\`. Try passing in a \`fetch\` implementation explicitly.` + ) + } + } + + if (!(await opts.store.exists())) { + throw new Error('Store is not initialized, run "Store.init()" first.') + } + const data = await opts.store.load() + return new Agent({ + connection: await connection(data.principal, _fetch, url, opts.channel), + fetch: _fetch, + url, + store: opts.store, + data, + }) + } + + async service() { + if (this.#service) { + return this.#service + } + const rsp = await this.#fetch(this.url + 'version') + const { did } = await rsp.json() + this.#service = DID.parse(did) + return this.#service + } + + did() { + return this.data.principal.did() + } + + /** + * + * @param {Ucanto.Delegation} delegation + */ + async addProof(delegation) { + validate(delegation, { + checkAudience: this.issuer, + checkIsExpired: true, + }) + + this.data.dels.set(delegation.cid.toString(), { + delegation, + }) + + await this.store.save(this.data) + } + + /** + * @param {import('@ucanto/interface').Capability[]} [caps] + */ + async *#delegations(caps) { + const _caps = new Set(caps) + for (const [key, value] of this.data.dels) { + // check expiration + if (!isExpired(value.delegation)) { + // check if delegation can be used + if (!isTooEarly(value.delegation)) { + // check if we need to filter for caps + if (caps) { + for (const cap of _caps) { + if (canDelegateCapability(value.delegation, cap)) { + _caps.delete(cap) + yield value + } + } + } else { + yield value + } + } + } else { + // delete any expired delegation + this.data.dels.delete(key) + } + } + + await this.store.save(this.data) + } + + /** + * @param {import('@ucanto/interface').Capability[]} [caps] + */ + async *proofs(caps) { + for await (const value of this.proofsWithMeta(caps)) { + yield value.delegation + } + } + + /** + * @param {import('@ucanto/interface').Capability[]} [caps] + */ + async *proofsWithMeta(caps) { + for await (const value of this.#delegations(caps)) { + if (value.delegation.audience.did() === this.issuer.did()) { + yield value + } + } + } + + /** + * @param {import('@ucanto/interface').Capability[]} [caps] + */ + async *delegations(caps) { + for await (const { delegation } of this.delegationsWithMeta(caps)) { + yield delegation + } + } + + /** + * @param {import('@ucanto/interface').Capability[]} [caps] + */ + async *delegationsWithMeta(caps) { + for await (const value of this.#delegations(caps)) { + if (value.delegation.audience.did() !== this.issuer.did()) { + yield value + } + } + } + + /** + * @param {string} name + */ + async createAccount(name) { + const signer = await Signer.generate() + const proof = await Any.delegate({ + issuer: signer, + audience: this.issuer, + with: signer.did(), + expiration: Infinity, + }) + + this.data.accs.set(signer.did(), { + name, + registered: false, + }) + + await this.addProof(proof) + + return { + did: signer.did(), + proof, + } + } + + /** + * + * @param {Ucanto.DID} account + */ + async setCurrentAccount(account) { + const proofs = await collect( + this.proofs([ + { + can: 'account/info', + with: account, + }, + ]) + ) + + if (proofs.length === 0) { + throw new Error(`Agent has no proofs for ${account}.`) + } + + this.data.currentAccount = account + await this.store.save(this.data) + + return account + } + + currentAccount() { + return this.data.currentAccount + } + + async currentAccountWithMeta() { + if (!this.data.currentAccount) { + return + } + + // TODO cache these + const proofs = await collect( + this.proofs([ + { + can: 'account/info', + with: this.data.currentAccount, + }, + ]) + ) + + const caps = new Set() + for (const p of proofs) { + for (const cap of p.capabilities) { + caps.add(cap.can) + } + } + + return { + did: this.data.currentAccount, + proofs, + capabilities: [...caps], + } + } + + /** + * @param {string} email + * @param {object} [opts] + * @param {AbortSignal} [opts.signal] + */ + async registerAccount(email, opts) { + const account = this.currentAccount() + const service = await this.service() + + if (!account) { + throw new Error('No account selected') + } + + const inv = await this.execute(Voucher.claim, { + nb: { + identity: URI.from(`mailto:${email}`), + product: 'product:free', + service: service.did(), + }, + }) + + if (inv && inv.error) { + throw new Error('Account creation failed', { cause: inv.error }) + } + + const voucherRedeem = await this.#waitForVoucherRedeem(opts) + const delegationToService = await this.delegate({ + abilities: ['*'], + audience: service, + audienceMeta: { + name: 'w3access', + type: 'service', + }, + }) + + const accInv = await this.execute(Voucher.redeem, { + with: URI.from(service.did()), + nb: { + account, + identity: voucherRedeem.capabilities[0].nb.identity, + product: voucherRedeem.capabilities[0].nb.product, + }, + proofs: [delegationToService], + }) + + if (accInv && accInv.error) { + throw new Error('Account registration failed', { cause: accInv }) + } + + await this.addProof(voucherRedeem) + } + + /** + * + * @param {object} [opts] + * @param {AbortSignal} [opts.signal] + */ + async #waitForVoucherRedeem(opts) { + const ws = new Websocket(this.url, 'validate-ws') + await ws.open() + + ws.send({ + did: this.did(), + }) + + try { + const msg = await ws.awaitMsg(opts) + + if (msg.type === 'timeout') { + await ws.close() + throw new Error('Email validation timed out.') + } + + if (msg.type === 'delegation') { + const delegation = await stringToDelegation( + /** @type {import('./types').EncodedDelegation<[import('./types').VoucherRedeem]>} */ ( + msg.delegation + ) + ) + ws.close() + return delegation + } + } catch (error) { + if (error instanceof AbortError) { + await ws.close() + throw new TypeError('Failed to get voucher/redeem', { cause: error }) + } + } + throw new TypeError('Failed to get voucher/redeem') + } + + /** + * + * @param {import('./types').DelegationOptions} options + */ + async delegate(options) { + const account = await this.currentAccountWithMeta() + if (!account) { + throw new Error('there no account selected.') + } + + const caps = /** @type {Ucanto.Capabilities} */ ( + options.abilities.map((a) => { + return { + with: account.did, + can: a, + } + }) + ) + + const delegation = await delegate({ + issuer: this.issuer, + capabilities: caps, + proofs: await collect(this.proofs(caps)), + ...options, + }) + + this.data.dels.set(delegation.cid.toString(), { + delegation, + meta: { + audience: options.audienceMeta, + }, + }) + await this.store.save(this.data) + return delegation + } + + /** + * @template {Ucanto.Ability} A + * @template {Ucanto.URI} R + * @template {Ucanto.TheCapabilityParser>} CAP + * @template {Ucanto.Caveats} [C={}] + * @param {CAP} cap + * @param {import('./types').ExecuteOptions} options + */ + async execute(cap, options) { + const _with = options.with || this.currentAccount() + if (!_with) { + throw new Error('there no account selected so you need pass a resource.') + } + + const proofs = await collect( + this.proofs([ + { + with: _with, + can: cap.can, + }, + ]) + ) + + if (proofs.length === 0) { + throw new Error( + `no proofs available for resource ${_with} and ability ${cap.can}` + ) + } + + const extraProofs = options.proofs || [] + const inv = invoke({ + audience: options.audience || (await this.service()), + // @ts-ignore + capability: cap.create({ + with: _with, + nb: options.nb, + }), + issuer: this.issuer, + proofs: [...proofs, ...extraProofs], + }) + + // @ts-ignore + const out = inv.execute(this.connection) + + return /** @type {Promise, import('./types').Service>>} */ ( + out + ) + } + + /** + * + * @param {import('../src/awake/types').Channel} channel + */ + peer(channel) { + return new Peer({ agent: this, channel }) + } + + /** + * @param {Ucanto.URI<"did:">} [account] + */ + async getAccountInfo(account) { + const inv = await this.execute(Account.info, { + with: account, + }) + + if (inv.error) { + throw inv + } + + return inv + } +} diff --git a/packages/access/src/awake/channel.js b/packages/access-client/src/awake/channel.js similarity index 99% rename from packages/access/src/awake/channel.js rename to packages/access-client/src/awake/channel.js index 677f5aeb7..82031bda3 100644 --- a/packages/access/src/awake/channel.js +++ b/packages/access-client/src/awake/channel.js @@ -324,7 +324,7 @@ export class Channel { } /** - * @type {ChannelType['sendMsg']} + * @type {ChannelType['sendFin']} */ async sendFin(did) { await this.sendMsg(did, { diff --git a/packages/access/src/awake/encoding.js b/packages/access-client/src/awake/encoding.js similarity index 100% rename from packages/access/src/awake/encoding.js rename to packages/access-client/src/awake/encoding.js diff --git a/packages/access/src/awake/messages.js b/packages/access-client/src/awake/messages.js similarity index 94% rename from packages/access/src/awake/messages.js rename to packages/access-client/src/awake/messages.js index a45c9d41d..948382c70 100644 --- a/packages/access/src/awake/messages.js +++ b/packages/access-client/src/awake/messages.js @@ -1,3 +1,8 @@ +/** + * @module awake-messages + * @packageDocumentation + * @ignore + */ import { z } from 'zod' export const MessageType = z.enum(['awake/init', 'awake/res', 'awake/msg']) diff --git a/packages/access/src/awake/peer.js b/packages/access-client/src/awake/peer.js similarity index 95% rename from packages/access/src/awake/peer.js rename to packages/access-client/src/awake/peer.js index 9c4fc149d..7f7153805 100644 --- a/packages/access/src/awake/peer.js +++ b/packages/access-client/src/awake/peer.js @@ -146,7 +146,7 @@ export class Peer { await this.channel.sendFin(this.nextdid) - await this.agent.addDelegation(delegations[0]) + await this.agent.addProof(delegations[0]) return { delegation: delegations[0], meta: capsRsp.msg.meta } } @@ -158,12 +158,12 @@ export class Peer { // request caps /** @type {import('./types').LinkRequest} */ const reqCap = await this.channel.awaitMsg(this.nextdid) - const d = await this.agent.delegate( - this.audience, - [{ with: this.agent.did(), can: reqCap.msg.caps[0].can }], - 8_600_000 - ) - + 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() }) diff --git a/packages/access/src/awake/readme.md b/packages/access-client/src/awake/readme.md similarity index 100% rename from packages/access/src/awake/readme.md rename to packages/access-client/src/awake/readme.md diff --git a/packages/access/src/awake/types.ts b/packages/access-client/src/awake/types.ts similarity index 100% rename from packages/access/src/awake/types.ts rename to packages/access-client/src/awake/types.ts diff --git a/packages/access/src/capabilities/account.js b/packages/access-client/src/capabilities/account.js similarity index 60% rename from packages/access/src/capabilities/account.js rename to packages/access-client/src/capabilities/account.js index 337e92bda..edaefe3d1 100644 --- a/packages/access/src/capabilities/account.js +++ b/packages/access-client/src/capabilities/account.js @@ -1,7 +1,18 @@ -import { capability, URI } from '@ucanto/server' -import { any } from './any.js' +/** + * Account Capabilities + * + * These can be imported directly with: + * ```js + * import * as Account from '@web3-storage/access/capabilities/account' + * ``` + * + * @module + */ + +import { any } from './wildcard.js' import { store } from './store.js' -import { equalWith } from './utils.js' +import { capability, URI } from '@ucanto/validator' +import { canDelegateURI, equalWith, fail } from './utils.js' export const account = any.derive({ to: capability({ @@ -33,7 +44,7 @@ export const recoverValidation = base.derive({ can: 'account/recover-validation', with: URI.match({ protocol: 'did:' }), nb: { - email: URI.match({ protocol: 'mailto:' }), + identity: URI.match({ protocol: 'mailto:' }), }, derives: equalWith, }), @@ -44,7 +55,16 @@ export const recover = base.derive({ to: capability({ can: 'account/recover', with: URI.match({ protocol: 'did:' }), - derives: equalWith, + nb: { + identity: URI.match({ protocol: 'mailto:' }), + }, + derives: (child, parent) => { + return ( + fail(equalWith(child, parent)) || + fail(canDelegateURI(child.nb.identity, parent.nb.identity)) || + true + ) + }, }), derives: equalWith, }) diff --git a/packages/access/src/capabilities/store.js b/packages/access-client/src/capabilities/store.js similarity index 91% rename from packages/access/src/capabilities/store.js rename to packages/access-client/src/capabilities/store.js index 0375072d8..237c5135b 100644 --- a/packages/access/src/capabilities/store.js +++ b/packages/access-client/src/capabilities/store.js @@ -1,6 +1,16 @@ +/** + * Store Capabilities + * + * These can be imported directly with: + * ```js + * import * as Account from '@web3-storage/access/capabilities/store' + * ``` + * + * @module + */ import { capability, Failure, Link, URI, Schema } from '@ucanto/validator' import { equalLink, equalWith } from './utils.js' -import { any } from './any.js' +import { any } from './wildcard.js' /** * all the `store/*` capabilities which can also be derived diff --git a/packages/access/src/capabilities/types.ts b/packages/access-client/src/capabilities/types.ts similarity index 76% rename from packages/access/src/capabilities/types.ts rename to packages/access-client/src/capabilities/types.ts index ce5d033eb..69683c759 100644 --- a/packages/access/src/capabilities/types.ts +++ b/packages/access-client/src/capabilities/types.ts @@ -1,6 +1,6 @@ import { InferInvokedCapability } from '@ucanto/interface' import { account, info, recover, recoverValidation } from './account.js' -import { any } from './any.js' +import { any } from './wildcard.js' import { add, list, remove } from './store.js' import * as UploadCaps from './upload.js' import { claim, redeem } from './voucher.js' @@ -26,3 +26,19 @@ export type StoreRemove = InferInvokedCapability export type StoreList = InferInvokedCapability // Any export type Any = InferInvokedCapability + +export type Abilities = + | Account['can'] + | AccountInfo['can'] + | AccountRecover['can'] + | AccountRecoverValidation['can'] + | VoucherClaim['can'] + | VoucherRedeem['can'] + | Upload['can'] + | UploadAdd['can'] + | UploadRemove['can'] + | UploadList['can'] + | StoreAdd['can'] + | StoreRemove['can'] + | StoreList['can'] + | Any['can'] diff --git a/packages/access/src/capabilities/upload.js b/packages/access-client/src/capabilities/upload.js similarity index 90% rename from packages/access/src/capabilities/upload.js rename to packages/access-client/src/capabilities/upload.js index e5a2ae1df..02aa32c5d 100644 --- a/packages/access/src/capabilities/upload.js +++ b/packages/access-client/src/capabilities/upload.js @@ -1,7 +1,17 @@ +/** + * Upload Capabilities + * + * These can be imported directly with: + * ```js + * import * as Account from '@web3-storage/access/capabilities/upload' + * ``` + * + * @module + */ import { capability, Link, URI } from '@ucanto/validator' import { codec } from '@ucanto/transport/car' import { equalWith, fail, equal } from './utils.js' -import { any } from './any.js' +import { any } from './wildcard.js' /** * All the `upload/*` capabilities which can also be derived diff --git a/packages/access/src/capabilities/utils.js b/packages/access-client/src/capabilities/utils.js similarity index 58% rename from packages/access/src/capabilities/utils.js rename to packages/access-client/src/capabilities/utils.js index 08fc34c1c..39f0a28ec 100644 --- a/packages/access/src/capabilities/utils.js +++ b/packages/access-client/src/capabilities/utils.js @@ -5,11 +5,14 @@ import * as Types from '@ucanto/interface' /** * Check URI can be delegated * - * @param {string} child - * @param {string} parent + * @param {string | undefined} child + * @param {string | undefined} parent */ export function canDelegateURI(child, parent) { - if (parent.endsWith('*')) { + if (parent === undefined) { + return true + } + if (child !== undefined && parent.endsWith('*')) { return child.startsWith(parent.slice(0, -1)) ? true : new Failure(`${child} does not match ${parent}`) @@ -85,3 +88,62 @@ export const equalLink = (claimed, delegated) => { export function fail(value) { return value === true ? undefined : value } + +/** + * + * @param {import('@ucanto/interface').Ability} ability + */ +function parseAbility(ability) { + switch (ability) { + case '*': { + return '*' + } + default: { + const [namespace, ...segments] = ability.split('/') + return { namespace, segments } + } + } +} + +/** + * + * TODO: needs to account for caps derived from diferent namespaces like 'account/info' can be derived from 'store/add' + * + * @param {import('@ucanto/interface').Ability} parent + * @param {import('@ucanto/interface').Ability} child + */ +export function canDelegateAbility(parent, child) { + const parsedParent = parseAbility(parent) + const parsedChild = parseAbility(child) + + // Parent is wildcard + if (parsedParent === '*') { + return true + } + + // Child is wild card so it can not be delegated from anything + if (parsedChild === '*') { + return false + } + + // namespaces dont match + if (parsedParent.namespace !== parsedChild.namespace) { + return false + } + + // given namespaces match and parent first segment is wildcard + if (parsedParent.segments[0] === '*') { + return true + } + + // Array equality + if (parsedParent.segments.length !== parsedChild.segments.length) { + return false + } + + // all segments must match + return parsedParent.segments.reduce( + (acc, v, i) => acc && parsedChild.segments[i] === v, + true + ) +} diff --git a/packages/access/src/capabilities/voucher.js b/packages/access-client/src/capabilities/voucher.js similarity index 89% rename from packages/access/src/capabilities/voucher.js rename to packages/access-client/src/capabilities/voucher.js index 50e172c7f..443a496bc 100644 --- a/packages/access/src/capabilities/voucher.js +++ b/packages/access-client/src/capabilities/voucher.js @@ -1,9 +1,19 @@ +/** + * Voucher Capabilities + * + * These can be imported directly with: + * ```js + * import * as Account from '@web3-storage/access/capabilities/voucher' + * ``` + * + * @module + */ import { capability, URI } from '@ucanto/validator' // @ts-ignore // eslint-disable-next-line no-unused-vars import * as Types from '@ucanto/interface' import { canDelegateURI, equalWith, fail } from './utils.js' -import { any } from './any.js' +import { any } from './wildcard.js' export const voucher = any.derive({ to: capability({ diff --git a/packages/access/src/capabilities/any.js b/packages/access-client/src/capabilities/wildcard.js similarity index 64% rename from packages/access/src/capabilities/any.js rename to packages/access-client/src/capabilities/wildcard.js index 3be16db3c..c25a59e7e 100644 --- a/packages/access/src/capabilities/any.js +++ b/packages/access-client/src/capabilities/wildcard.js @@ -1,3 +1,14 @@ +/** + * Wildcard Capabilities + * + * These can be imported directly with: + * ```js + * import * as Account from '@web3-storage/access/capabilities/wildcard' + * ``` + * + * @module + */ + import { capability, URI } from '@ucanto/validator' import { equalWith } from './utils.js' diff --git a/packages/access/src/cli/cmd-create-account.js b/packages/access-client/src/cli/cmd-create-account.js similarity index 96% rename from packages/access/src/cli/cmd-create-account.js rename to packages/access-client/src/cli/cmd-create-account.js index 0fa30d63a..e014d7d2f 100644 --- a/packages/access/src/cli/cmd-create-account.js +++ b/packages/access-client/src/cli/cmd-create-account.js @@ -29,7 +29,7 @@ export async function cmdCreateAccount(opts) { }) spinner.start('Waiting for email validation...') try { - await agent.createAccount(email) + await agent.registerAccount(email) spinner.succeed('Account has been created and register with the service.') } catch (error) { console.error(error) diff --git a/packages/access/src/cli/cmd-link.js b/packages/access-client/src/cli/cmd-link.js similarity index 100% rename from packages/access/src/cli/cmd-link.js rename to packages/access-client/src/cli/cmd-link.js diff --git a/packages/access/src/cli/cmd-setup.js b/packages/access-client/src/cli/cmd-setup.js similarity index 100% rename from packages/access/src/cli/cmd-setup.js rename to packages/access-client/src/cli/cmd-setup.js diff --git a/packages/access-client/src/cli/cmd-whoami.js b/packages/access-client/src/cli/cmd-whoami.js new file mode 100644 index 000000000..f3c5c3a14 --- /dev/null +++ b/packages/access-client/src/cli/cmd-whoami.js @@ -0,0 +1,31 @@ +/* eslint-disable no-console */ +// 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 }) + // if (await store.exists()) { + // const { delegations, meta, accounts, principal } = await store.load() + // console.log('Agent', principal.did(), meta) + // console.log('Accounts:') + // for (const acc of accounts) { + // console.log(acc.did()) + // } + // console.log('Delegations created:') + // for (const created of delegations.created) { + // console.log(created) + // } + // console.log('Delegations received:') + // for (const [key, value] of delegations.receivedByResource) { + // console.log( + // `Resource: ${key}`, + // value.map((cap) => cap.cap.can) + // ) + // } + // } else { + // console.error(`Run "${NAME} setup" first`) + // } +} diff --git a/packages/access/src/cli/config.js b/packages/access-client/src/cli/config.js similarity index 100% rename from packages/access/src/cli/config.js rename to packages/access-client/src/cli/config.js diff --git a/packages/access-client/src/cli/index.js b/packages/access-client/src/cli/index.js new file mode 100755 index 000000000..878c8db56 --- /dev/null +++ b/packages/access-client/src/cli/index.js @@ -0,0 +1,161 @@ +#!/usr/bin/env node +/* eslint-disable no-console */ +import fs from 'fs' +import sade from 'sade' +import { NAME, pkg } from './config.js' +import { getService } from './utils.js' +// @ts-ignore +// eslint-disable-next-line no-unused-vars +import { cmdCreateAccount } from './cmd-create-account.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 { stringToDelegation } from '../encoding.js' +// import inquirer from 'inquirer' +// import { Verifier } from '@ucanto/principal/ed25519' +// import { delegationToString, stringToDelegation } from '../encoding.js' + +const prog = sade(NAME) +prog + .version(pkg.version) + .option('-p, --profile', 'Select the config profile to use.', 'main') + .option('--env', 'Env', 'production') + +prog.command('link [channel]').describe('Link.').action(cmdLink) +prog + .command('setup') + .option('--reset', 'Reset current store.', false) + .describe('Print config file content.') + .action(cmdSetup) +prog.command('whoami').describe('Print config file content.').action(cmdWhoami) +prog + .command('create-account') + .describe('Create new account.') + .action(cmdCreateAccount) + +prog + .command('account') + .describe('Account info.') + .action(async (opts) => { + // const store = new StoreConf({ profile: opts.profile }) + // const { url } = await getService(opts.env) + // if (await store.exists()) { + // const agent = await Agent.create({ + // store, + // url, + // }) + // const choices = [] + // for (const [key, value] of agent.data.delegations.receivedByResource) { + // for (const d of value) { + // if (d.cap.can === 'account/info' || d.cap.can === 'account/*') { + // choices.push({ name: key }) + // } + // } + // } + // const { account } = await inquirer.prompt([ + // { + // type: 'list', + // name: 'account', + // default: 'device', + // choices, + // message: 'Select account:', + // }, + // ]) + // try { + // const result = await agent.getAccountInfo(account) + // console.log(result) + // } catch (error_) { + // const error = /** @type {Error} */ (error_) + // console.log(error.message) + // } + // } else { + // console.error(`Run "${NAME} setup" first`) + // } + }) + +prog + .command('delegate') + .describe('Delegation capabilities.') + .action(async (opts) => { + // const store = new StoreConf({ profile: opts.profile }) + // const { url } = await getService(opts.env) + // if (await store.exists()) { + // const agent = await Agent.create({ + // store, + // url, + // }) + // const accountDids = agent.data.accounts.map((acc) => { + // return { name: acc.did() } + // }) + // const { account } = await inquirer.prompt([ + // { + // type: 'list', + // name: 'account', + // choices: accountDids, + // message: 'Select account:', + // }, + // ]) + // const abilities = [] + // for (const [key, values] of agent.data.delegations.receivedByResource) { + // if (key === account) { + // for (const cap of values) { + // abilities.push({ name: cap.cap.can }) + // } + // } + // } + // const { ability } = await inquirer.prompt([ + // { + // type: 'list', + // name: 'ability', + // choices: abilities, + // message: 'Select ability:', + // }, + // ]) + // const { audience } = await inquirer.prompt([ + // { + // type: 'input', + // name: 'audience', + // choices: abilities, + // message: 'Input audience:', + // }, + // ]) + // console.log(account, ability) + // const delegation = await agent.delegate( + // Verifier.parse(audience), + // [ + // { + // can: ability, + // with: account, + // }, + // ], + // 800_000 + // ) + // console.log(await delegationToString(delegation)) + // } 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 { url } = await getService(opts.env) + if (await store.exists()) { + const agent = await Agent.create({ + store, + url, + }) + + const del = fs.readFileSync('./delegation', { encoding: 'utf8' }) + + await agent.addProof(await stringToDelegation(del)) + } else { + console.error(`Run "${NAME} setup" first`) + } + }) +prog.parse(process.argv) diff --git a/packages/access/src/cli/utils.js b/packages/access-client/src/cli/utils.js similarity index 89% rename from packages/access/src/cli/utils.js rename to packages/access-client/src/cli/utils.js index 329f6cb52..8f67174d1 100644 --- a/packages/access/src/cli/utils.js +++ b/packages/access-client/src/cli/utils.js @@ -1,4 +1,3 @@ -import undici from 'undici' import { Verifier } from '@ucanto/principal/ed25519' /** @type {Record} */ @@ -22,7 +21,7 @@ export async function getService(env) { if (audience) { return { url, did: audience } } else { - const rsp = await undici.fetch(url + 'version') + const rsp = await fetch(url + 'version') // @ts-ignore const { did } = await rsp.json() diff --git a/packages/access/src/crypto/aes-key.js b/packages/access-client/src/crypto/aes-key.js similarity index 100% rename from packages/access/src/crypto/aes-key.js rename to packages/access-client/src/crypto/aes-key.js diff --git a/packages/access/src/crypto/encoding.js b/packages/access-client/src/crypto/encoding.js similarity index 100% rename from packages/access/src/crypto/encoding.js rename to packages/access-client/src/crypto/encoding.js diff --git a/packages/access/src/crypto/p256-ecdh.js b/packages/access-client/src/crypto/p256-ecdh.js similarity index 100% rename from packages/access/src/crypto/p256-ecdh.js rename to packages/access-client/src/crypto/p256-ecdh.js diff --git a/packages/access/src/crypto/types.ts b/packages/access-client/src/crypto/types.ts similarity index 100% rename from packages/access/src/crypto/types.ts rename to packages/access-client/src/crypto/types.ts diff --git a/packages/access-client/src/delegations.js b/packages/access-client/src/delegations.js new file mode 100644 index 000000000..551d5cc63 --- /dev/null +++ b/packages/access-client/src/delegations.js @@ -0,0 +1,74 @@ +// @ts-ignore +// eslint-disable-next-line no-unused-vars +import * as Ucanto from '@ucanto/interface' +import { canDelegateAbility } from './capabilities/utils.js' + +/** + * + * @param {Ucanto.Delegation} delegation + */ +export function isExpired(delegation) { + if ( + delegation.expiration === undefined || + delegation.expiration <= Math.floor(Date.now() / 1000) + ) { + return true + } + return false +} + +/** + * + * @param {Ucanto.Delegation} delegation + */ +export function isTooEarly(delegation) { + if (!delegation.notBefore) { + return false + } + return delegation.notBefore > Math.floor(Date.now() / 1000) +} + +/** + * + * @param {Ucanto.Delegation} delegation + * @param {object} [opts] + * @param {Ucanto.Principal} [opts.checkAudience] + * @param {boolean} [opts.checkIsExpired] + * @param {boolean} [opts.checkIsTooEarly] + */ +export function validate(delegation, opts) { + const { + checkAudience, + checkIsExpired = true, + checkIsTooEarly = true, + } = opts ?? {} + + if (checkAudience && delegation.audience.did() !== checkAudience.did()) { + throw new Error(`Delegation audience does not match required DID.`) + } + + if (checkIsExpired && isExpired(delegation)) { + throw new Error(`Delegation expired.`) + } + + if (checkIsTooEarly && isTooEarly(delegation)) { + throw new Error(`Delegation is not active yet (too early).`) + } +} + +/** + * + * @param {import('@ucanto/interface').Delegation} delegation + * @param {import('@ucanto/interface').Capability} child + */ +export function canDelegateCapability(delegation, child) { + for (const parent of delegation.capabilities) { + if ( + parent.with === child.with && + canDelegateAbility(parent.can, child.can) + ) { + return true + } + } + return false +} diff --git a/packages/access/src/encoding.js b/packages/access-client/src/encoding.js similarity index 92% rename from packages/access/src/encoding.js rename to packages/access-client/src/encoding.js index fa8812525..84109c343 100644 --- a/packages/access/src/encoding.js +++ b/packages/access-client/src/encoding.js @@ -1,3 +1,17 @@ +/** + * Encoding utilities + * + * These can be imported directly with: + * ```js + * import * as Encoding from '@web3-storage/access/encoding' + * + * // or + * + * import { encodeDelegations } from '@web3-storage/access/encoding' + * ``` + * + * @module + */ /* eslint-disable unicorn/prefer-spread */ import { CarReader } from '@ipld/car/reader' import { CarWriter } from '@ipld/car/writer' diff --git a/packages/access-client/src/index.js b/packages/access-client/src/index.js new file mode 100644 index 000000000..56ee5b076 --- /dev/null +++ b/packages/access-client/src/index.js @@ -0,0 +1,12 @@ +/* eslint-disable jsdoc/check-tag-names */ +export * from './agent.js' + +// Workaround for typedoc until 0.24 support export maps +export * as Account from './capabilities/account.js' +export * as Wildcard from './capabilities/wildcard.js' +export * as Store from './capabilities/store.js' +export * as Upload from './capabilities/upload.js' +export * as Voucher from './capabilities/voucher.js' +export * as Encoding from './encoding.js' +export { StoreConf } from './stores/store-conf.js' +export { StoreIndexedDB } from './stores/store-indexeddb.js' diff --git a/packages/access-client/src/stores/store-conf.js b/packages/access-client/src/stores/store-conf.js new file mode 100644 index 000000000..f35b0d917 --- /dev/null +++ b/packages/access-client/src/stores/store-conf.js @@ -0,0 +1,132 @@ +/* eslint-disable jsdoc/check-indentation */ +import Conf from 'conf' +import { Signer } from '@ucanto/principal/ed25519' +import { delegationToString, stringToDelegation } from '../encoding.js' +// eslint-disable-next-line no-unused-vars +import * as Ucanto from '@ucanto/interface' + +/** + * @typedef {import('./types').StoreData} StoreData + * @typedef {import('./types').Store} Store + * @typedef {{ + * meta: import('../types.js').AgentMeta + * principal: string + * currentAccount?: Ucanto.DID + * accs: Array<[Ucanto.DID, import('./types').AccountMeta]> + * dels: Array<[import('./types').CIDString, { + * meta?: import('./types').DelegationMeta, + * delegation: import('../types.js').EncodedDelegation + * }]> + * }} Data + */ + +/** + * Store implementation with "conf" + * + * @implements {Store} + */ +export class StoreConf { + /** + * @type {Conf} + */ + #config + /** + * + * @param {{ + * profile: string + * }} opts + */ + constructor(opts) { + this.#config = new Conf({ + projectName: 'w3access', + projectSuffix: '', + configName: opts.profile, + }) + this.path = this.#config.path + } + + async open() { + return this + } + + async close() {} + + async reset() { + this.#config.clear() + } + + async exists() { + return this.#config.has('meta') && this.#config.has('principal') + } + + /** @type {Store['init']} */ + async init(data) { + const principal = data.principal || (await Signer.generate()) + + /** @type {StoreData} */ + const storeData = { + meta: data.meta || { name: 'agent', type: 'device' }, + accs: data.accs || new Map(), + dels: data.dels || new Map(), + principal, + currentAccount: data.currentAccount, + } + + await this.save(storeData) + return storeData + } + + /** + * + * @param {StoreData} data + */ + async save(data) { + /** @type {Data['dels']} */ + const dels = [] + + for (const [key, value] of data.dels) { + dels.push([ + key, + { + meta: value.meta, + delegation: await delegationToString(value.delegation), + }, + ]) + } + /** @type {Data} */ + const encodedData = { + currentAccount: data.currentAccount, + accs: [...data.accs.entries()], + meta: data.meta, + principal: Signer.format(data.principal), + dels, + } + + this.#config.set(encodedData) + + return this + } + + /** @type {Store['load']} */ + async load() { + const data = this.#config.store + + /** @type {StoreData['dels']} */ + const dels = new Map() + + for (const [key, value] of data.dels) { + dels.set(key, { + delegation: await stringToDelegation(value.delegation), + meta: value.meta, + }) + } + /** @type {StoreData} */ + return { + principal: Signer.parse(data.principal), + currentAccount: data.currentAccount, + meta: data.meta, + accs: new Map(data.accs), + dels, + } + } +} diff --git a/packages/access/src/stores/store-indexeddb.js b/packages/access-client/src/stores/store-indexeddb.js similarity index 82% rename from packages/access/src/stores/store-indexeddb.js rename to packages/access-client/src/stores/store-indexeddb.js index 0dff6ee04..fbd0e62f0 100644 --- a/packages/access/src/stores/store-indexeddb.js +++ b/packages/access-client/src/stores/store-indexeddb.js @@ -1,11 +1,10 @@ import { importDAG } from '@ucanto/core/delegation' import * as Signer from '@ucanto/principal/rsa' import defer from 'p-defer' -import { Delegations } from '../delegations.js' /** - * @typedef {import('./types').StoreDataKeyRSA} StoreData - * @typedef {import('./types').StoreKeyRSA} Store + * @typedef {import('./types').StoreData} StoreData + * @typedef {import('./types').Store} Store */ const STORE_NAME = 'AccessStore' @@ -112,14 +111,14 @@ export class StoreIndexedDB { /** @type {Store['init']} */ async init(data) { - const principal = - data.principal || (await Signer.generate({ extractable: false })) - const delegations = data.delegations || new Delegations({ principal }) + /** @type {StoreData} */ const storeData = { - accounts: data.accounts || [], meta: data.meta || { name: 'agent', type: 'device' }, - principal, - delegations, + principal: + data.principal || (await Signer.generate({ extractable: false })), + accs: data.accs || new Map(), + dels: data.dels || new Map(), + currentAccount: data.currentAccount, } await this.save(storeData) @@ -139,16 +138,24 @@ export class StoreIndexedDB { /** @type {import('p-defer').DeferredPromise} */ const { resolve, reject, promise } = defer() + const dels = [] + + for (const [key, value] of data.dels) { + dels.push([ + key, + { + meta: value.meta, + delegation: [...value.delegation.export()], + }, + ]) + } const putReq = store.put({ id: DATA_ID, - accounts: data.accounts.map((a) => a.toArchive()), - delegations: { - created: data.delegations.created.map((d) => [...d.export()]), - received: data.delegations.received.map((d) => [...d.export()]), - meta: [...data.delegations.meta.entries()], - }, meta: data.meta, principal: data.principal.toArchive(), + currentAccount: data.currentAccount, + accs: data.accs, + dels, }) putReq.addEventListener('success', () => resolve(this)) putReq.addEventListener('error', () => @@ -178,25 +185,27 @@ export class StoreIndexedDB { const getReq = store.get(DATA_ID) getReq.addEventListener('success', () => { try { - /** @type {import('./types').IDBStoreData} */ + /** @type {import('./types').StoreDataIDB} */ const raw = getReq.result if (!raw) throw new Error('Store is not initialized') - const principal = Signer.from(raw.principal) + /** @type {StoreData['dels']} */ + const dels = new Map() + + for (const [key, value] of raw.dels) { + dels.set(key, { + delegation: importDAG(value.delegation), + meta: value.meta, + }) + } + + /** @type {StoreData} */ const data = { - accounts: raw.accounts.map((a) => Signer.from(a)), - delegations: new Delegations({ - principal, - received: raw.delegations.received.map((blocks) => - importDAG(blocks) - ), - created: raw.delegations.created.map((blocks) => - importDAG(blocks) - ), - meta: new Map(raw.delegations.meta), - }), meta: raw.meta, - principal, + principal: Signer.from(raw.principal), + currentAccount: raw.currentAccount, + accs: raw.accs, + dels, } resolve(data) } catch (error) { diff --git a/packages/access/src/stores/store-memory.js b/packages/access-client/src/stores/store-memory.js similarity index 70% rename from packages/access/src/stores/store-memory.js rename to packages/access-client/src/stores/store-memory.js index e391dff9e..f5cace566 100644 --- a/packages/access/src/stores/store-memory.js +++ b/packages/access-client/src/stores/store-memory.js @@ -2,12 +2,10 @@ import { Signer } from '@ucanto/principal/ed25519' // @ts-ignore // eslint-disable-next-line no-unused-vars import * as Types from '@ucanto/interface' -import { Delegations } from '../delegations.js' /** - * @typedef {import('./types').DelegationsAsJSON} DelegationsAsJSON - * @typedef {import('./types').StoreDataKeyEd} StoreData - * @typedef {import('./types').StoreKeyEd} Store + * @typedef {import('./types').StoreData} StoreData + * @typedef {import('./types').Store} Store */ /** @@ -37,9 +35,13 @@ export class StoreMemory { return this.data.meta !== undefined && this.data.principal !== undefined } - static async create() { + /** + * + * @param {Partial} [data] + */ + static async create(data = {}) { const store = new StoreMemory() - await store.init({}) + await store.init(data) return store } @@ -47,17 +49,13 @@ export class StoreMemory { /** @type {Store['init']} */ async init(data) { const principal = data.principal || (await Signer.generate()) - const delegations = - data.delegations || - new Delegations({ - principal, - }) /** @type {StoreData} */ const storeData = { - accounts: data.accounts || [], meta: data.meta || { name: 'agent', type: 'device' }, principal, - delegations, + accs: data.accs || new Map(), + dels: data.dels || new Map(), + currentAccount: data.currentAccount, } await this.save(storeData) @@ -80,8 +78,4 @@ export class StoreMemory { /** @type {StoreData} */ return this.data } - - async createAccount() { - return await Signer.generate() - } } diff --git a/packages/access-client/src/stores/types.ts b/packages/access-client/src/stores/types.ts new file mode 100644 index 000000000..da3c92dab --- /dev/null +++ b/packages/access-client/src/stores/types.ts @@ -0,0 +1,48 @@ +import { AgentMeta } from '../types.js' +import { RSASigner } from '@ucanto/principal/rsa' +import { Delegation, SignerArchive, DID } from '@ucanto/interface' + +export type CIDString = string + +export interface DelegationMeta { + audience: AgentMeta +} + +export interface AccountMeta { + name: string + registered: boolean +} + +export interface StoreData { + meta: AgentMeta + principal: T + currentAccount?: DID + accs: Map + dels: Map +} + +export interface Store { + open: () => Promise> + close: () => Promise + exists: () => Promise + init: (data: Partial>) => Promise> + save: (data: StoreData) => Promise> + load: () => Promise> + reset: () => Promise +} + +// Store IDB +export interface StoreDataIDB { + id: number + meta: import('../types').AgentMeta + principal: SignerArchive + currentAccount?: DID + accs: Map + dels: Map< + CIDString, + { + meta?: DelegationMeta + delegation: Array + } + > +} diff --git a/packages/access-client/src/types.ts b/packages/access-client/src/types.ts new file mode 100644 index 000000000..e383f431b --- /dev/null +++ b/packages/access-client/src/types.ts @@ -0,0 +1,186 @@ +/* eslint-disable @typescript-eslint/indent */ +import type { + Capabilities, + ConnectionView, + Fact, + Failure, + Phantom, + Principal, + RequestEncoder, + Resource, + ResponseDecoder, + ServiceMethod, + UCAN, + URI, + InferInvokedCapability, + CapabilityParser, + Match, + Ability, + UnknownMatch, + Transport, + Delegation, +} from '@ucanto/interface' + +import type { + Abilities, + AccountInfo, + AccountRecover, + AccountRecoverValidation, + Any, +} from './capabilities/types' +import { VoucherClaim, VoucherRedeem } from './capabilities/types.js' +import { Store, StoreData } from './stores/types.js' +import type { SetRequired } from 'type-fest' + +// export capabilities types +export * from './capabilities/types.js' + +export interface ClientCodec extends RequestEncoder, ResponseDecoder {} + +export type EncodedDelegation = string & + Phantom + +export interface Service { + voucher: { + claim: ServiceMethod< + VoucherClaim, + EncodedDelegation<[VoucherRedeem]> | undefined, + Failure + > + redeem: ServiceMethod + } + account: { + info: ServiceMethod + 'recover-validation': ServiceMethod< + AccountRecoverValidation, + EncodedDelegation<[AccountRecover]> | undefined, + Failure + > + recover: ServiceMethod< + AccountRecover, + Array>, + Failure + > + } +} + +export interface Account { + did: UCAN.DID + agent: UCAN.DID + email: URI<'mailto:'> + product: URI<'product:'> + updated_at: string + inserted_at: string +} + +export interface AgentMeta { + name: string + description?: string + url?: URL + image?: URL + type: 'device' | 'app' | 'service' +} + +export interface AgentOptions { + store: Store + connection: ConnectionView + url?: URL + fetch: typeof fetch + data: StoreData +} + +export interface AgentCreateOptions { + channel?: Transport.Channel + store: Store + url?: URL + fetch?: typeof fetch +} + +export type ExecuteOptions< + A extends Ability, + R extends Resource, + CAP extends CapabilityParser< + Match<{ can: A; with: R; nb?: {} | undefined }, UnknownMatch> + > +> = UCANBasicOptions & + InferNb['nb']> & { + /** + * Resource for the capability, normally a Space DID + * Defaults to the current selected Space + */ + with?: R + + /** + * Extra proofs to be added to the invocation + */ + proofs?: Delegation[] + } + +export type DelegationOptions = SetRequired & { + /** + * Abilities to delegate + */ + abilities: Abilities[] + /** + * Metadata about the audience + */ + audienceMeta: AgentMeta +} + +export interface UCANBasicOptions { + /** + * Audience Principal (DID), + * Defaults to "Access service DID" + * + * @see {@link https://github.com/ucan-wg/spec#321-principals Spec} + */ + audience?: Principal + /** + * UCAN lifetime in seconds + */ + lifetimeInSeconds?: number + /** + * Unix timestamp when the UCAN is no longer valid + * + * Expiration overrides `lifetimeInSeconds` + * + * @see {@link https://github.com/ucan-wg/spec#322-time-bounds Spec} + */ + expiration?: number + /** + * Unix timestamp when the UCAN becomas valid + * + * @see {@link https://github.com/ucan-wg/spec#322-time-bounds Spec} + */ + notBefore?: number + /** + * Nonce, a randomly generated string, used to ensure the uniqueness of the UCAN. + * + * @see {@link https://github.com/ucan-wg/spec#323-nonce Spec} + */ + nonce?: string + /** + * Facts, an array of extra facts or information to attach to the UCAN + * + * @see {@link https://github.com/ucan-wg/spec#324-facts Spec} + */ + facts?: Fact[] +} + +/** + * Given an inferred capability infers if the nb field is optional or not + */ +export type InferNb = keyof C extends never + ? { + nb?: never + } + : { + /** + * Non-normative fields for the capability + * + * Check the capability definition for more details on the `nb` field. + * + * @see {@link https://github.com/ucan-wg/spec#241-nb-non-normative-fields Spec} + */ + nb: C + } diff --git a/packages/access/src/utils/ws.js b/packages/access-client/src/utils/ws.js similarity index 100% rename from packages/access/src/utils/ws.js rename to packages/access-client/src/utils/ws.js diff --git a/packages/access-client/test/agent.test.js b/packages/access-client/test/agent.test.js new file mode 100644 index 000000000..cef369eb1 --- /dev/null +++ b/packages/access-client/test/agent.test.js @@ -0,0 +1,195 @@ +import assert from 'assert' +import { URI } from '@ucanto/validator' +import { Agent } from '../src/index.js' +import { StoreMemory } from '../src/stores/store-memory.js' +import { collect } from 'streaming-iterables' +import * as Account from '../src/capabilities/account.js' +import { createServer } from './helpers/utils.js' +import * as fixtures from './helpers/fixtures.js' + +describe('Agent', function () { + it('should fail if store is not initialized', async function () { + const store = new StoreMemory() + + return assert.rejects( + Agent.create({ + store, + }), + { + name: 'Error', + message: 'Store is not initialized, run "Store.init()" first.', + } + ) + }) + + it('should return did', async function () { + const store = await StoreMemory.create() + const agent = await Agent.create({ + store, + }) + + assert.ok(agent.did()) + }) + + it('should create account', async function () { + const store = await StoreMemory.create() + const agent = await Agent.create({ + store, + }) + + const account = await agent.createAccount('test-create') + + assert(typeof account.did === 'string') + assert(account.proof) + }) + + it('should add proof when creating acccount', async function () { + const store = await StoreMemory.create() + const agent = await Agent.create({ + store, + }) + + const account = await agent.createAccount('test-add') + + const delegations = await collect(agent.proofsWithMeta()) + + assert.equal(account.proof.cid, delegations[0].delegation.cid) + assert(!delegations[0].meta) + }) + + it('should set current account', async function () { + const store = await StoreMemory.create() + const agent = await Agent.create({ + store, + }) + + const account = await agent.createAccount('test') + + await agent.setCurrentAccount(account.did) + + const accWithMeta = await agent.currentAccountWithMeta() + if (!accWithMeta) { + assert.fail('should have account') + } + assert.equal(accWithMeta.did, account.did) + assert(accWithMeta.proofs.length === 1) + assert.deepStrictEqual(accWithMeta.capabilities, ['*']) + }) + + it('fails set current account with no proofs', async function () { + const store = await StoreMemory.create() + const agent = await Agent.create({ + store, + }) + + await assert.rejects( + () => { + return agent.setCurrentAccount(fixtures.alice.did()) + }, + { + message: `Agent has no proofs for ${fixtures.alice.did()}.`, + } + ) + }) + + it('should execute', async function () { + const store = await StoreMemory.create() + const agent = await Agent.create({ + store, + channel: createServer(), + }) + + const account = await agent.createAccount('execute') + await agent.setCurrentAccount(account.did) + + const out = await agent.execute(Account.info, { + audience: fixtures.service, + }) + + assert.deepEqual(out, { + did: 'did:key:sss', + agent: 'did:key:agent', + email: 'mail@mail.com', + product: 'product:free', + updated_at: 'sss', + inserted_at: 'date', + }) + }) + + it('should fail execute with no proofs', async function () { + const store = await StoreMemory.create() + const agent = await Agent.create({ + store, + channel: createServer(), + }) + + await assert.rejects( + async () => { + await agent.execute(Account.info, { + audience: fixtures.service, + with: URI.from(fixtures.alice.did()), + }) + }, + { + name: 'Error', + message: `no proofs available for resource ${URI.from( + fixtures.alice.did() + )} and ability account/info`, + } + ) + }) + + it('should get account info', async function () { + const store = await StoreMemory.create() + const server = createServer() + const agent = await Agent.create({ + store, + channel: server, + }) + + // mock service + agent.service = async () => server.id + + const account = await agent.createAccount('execute') + await agent.setCurrentAccount(account.did) + + const out = await agent.getAccountInfo() + assert.deepEqual(out, { + did: 'did:key:sss', + agent: 'did:key:agent', + email: 'mail@mail.com', + product: 'product:free', + updated_at: 'sss', + inserted_at: 'date', + }) + }) + + it('should delegate', async function () { + const store = await StoreMemory.create() + const server = createServer() + const agent = await Agent.create({ + store, + channel: server, + }) + + const account = await agent.createAccount('execute') + await agent.setCurrentAccount(account.did) + + const out = await agent.delegate({ + abilities: ['*'], + audience: fixtures.alice, + audienceMeta: { + name: 'sss', + type: 'app', + }, + }) + + assert(out.audience.did() === fixtures.alice.did()) + assert.deepStrictEqual(out.capabilities, [ + { + can: '*', + with: account.did, + }, + ]) + }) +}) diff --git a/packages/access/test/awake-channel.node.test.js b/packages/access-client/test/awake-channel.node.test.js similarity index 100% rename from packages/access/test/awake-channel.node.test.js rename to packages/access-client/test/awake-channel.node.test.js diff --git a/packages/access/test/awake.node.test.js b/packages/access-client/test/awake.node.test.js similarity index 100% rename from packages/access/test/awake.node.test.js rename to packages/access-client/test/awake.node.test.js diff --git a/packages/access/test/capabilities.test.js b/packages/access-client/test/capabilities.test.js similarity index 100% rename from packages/access/test/capabilities.test.js rename to packages/access-client/test/capabilities.test.js diff --git a/packages/access/test/capabilities/store.test.js b/packages/access-client/test/capabilities/store.test.js similarity index 100% rename from packages/access/test/capabilities/store.test.js rename to packages/access-client/test/capabilities/store.test.js diff --git a/packages/access/test/capabilities/upload.test.js b/packages/access-client/test/capabilities/upload.test.js similarity index 100% rename from packages/access/test/capabilities/upload.test.js rename to packages/access-client/test/capabilities/upload.test.js diff --git a/packages/access/test/capabilities/voucher.test.js b/packages/access-client/test/capabilities/voucher.test.js similarity index 100% rename from packages/access/test/capabilities/voucher.test.js rename to packages/access-client/test/capabilities/voucher.test.js diff --git a/packages/access/test/helpers/fixtures.js b/packages/access-client/test/helpers/fixtures.js similarity index 100% rename from packages/access/test/helpers/fixtures.js rename to packages/access-client/test/helpers/fixtures.js diff --git a/packages/access/test/helpers/miniflare.js b/packages/access-client/test/helpers/miniflare.js similarity index 100% rename from packages/access/test/helpers/miniflare.js rename to packages/access-client/test/helpers/miniflare.js diff --git a/packages/access-client/test/helpers/utils.js b/packages/access-client/test/helpers/utils.js new file mode 100644 index 000000000..9b50d736b --- /dev/null +++ b/packages/access-client/test/helpers/utils.js @@ -0,0 +1,63 @@ +// eslint-disable-next-line no-unused-vars +import * as Ucanto from '@ucanto/interface' +import { parseLink } from '@ucanto/core' +import * as Server from '@ucanto/server' +// import { codec as CARCodec } from '@ucanto/transport/car' +// import { codec as CBOR } from '@ucanto/transport/cbor' +import * as Account from '../../src/capabilities/account.js' +import * as CAR from '@ucanto/transport/car' +import * as CBOR from '@ucanto/transport/cbor' +import { service } from './fixtures.js' + +/** + * @param {string} source + */ +export function parseCarLink(source) { + return /** @type {Ucanto.Link} */ (parseLink(source)) +} + +/** + * @param {any} data + */ +export async function createCborCid(data) { + const cbor = await CBOR.codec.write(data) + return cbor.cid +} + +/** + * @param {string} source + */ +export async function createCarCid(source) { + const cbor = await CBOR.codec.write({ hello: source }) + const shard = await CAR.codec.write({ roots: [cbor] }) + return shard.cid +} + +/** + * + * @returns {Ucanto.ServerView} + */ +export function createServer() { + const server = Server.create({ + id: service, + encoder: CBOR, + decoder: CAR, + service: { + account: { + info: Server.provide(Account.info, async ({ capability }) => { + return { + did: 'did:key:sss', + agent: 'did:key:agent', + email: 'mail@mail.com', + product: 'product:free', + updated_at: 'sss', + inserted_at: 'date', + } + }), + }, + }, + }) + + // @ts-ignore + return server +} diff --git a/packages/access/test/stores/store-indexeddb.browser.test.js b/packages/access-client/test/stores/store-indexeddb.browser.test.js similarity index 72% rename from packages/access/test/stores/store-indexeddb.browser.test.js rename to packages/access-client/test/stores/store-indexeddb.browser.test.js index 9120cd79a..985fe2218 100644 --- a/packages/access/test/stores/store-indexeddb.browser.test.js +++ b/packages/access-client/test/stores/store-indexeddb.browser.test.js @@ -14,31 +14,14 @@ describe('IndexedDB store', () => { assert.equal(archive.key.extractable, false) // no accounts or delegations yet - assert.equal(data.accounts.length, 0) - assert.equal(data.delegations.received.length, 0) - assert.equal(data.delegations.created.length, 0) + assert.equal(data.accs.size, 0) + assert.equal(data.dels.size, 0) // default meta assert.equal(data.meta.name, 'agent') assert.equal(data.meta.type, 'device') }) - it('should allow an account to be added', async () => { - const store = await StoreIndexedDB.create('test-access-db-' + Date.now()) - let data = await store.load() - assert(data) - - assert.equal(data.accounts.length, 0) - - const account = await store.createAccount() - data.accounts.push(account) - - await store.save(data) - data = await store.load() - - assert.equal(data.accounts.length, 1) - }) - it('should check existence', async () => { const store = new StoreIndexedDB('test-access-db-' + Date.now()) await store.open() diff --git a/packages/access-client/test/stores/store-memory.test.js b/packages/access-client/test/stores/store-memory.test.js new file mode 100644 index 000000000..b4ee7ff89 --- /dev/null +++ b/packages/access-client/test/stores/store-memory.test.js @@ -0,0 +1,10 @@ +import assert from 'assert/strict' +import { StoreMemory } from '../../src/stores/store-memory.js' + +describe('Store Memory', function () { + it('should not be initialized', async function () { + const store = new StoreMemory() + + assert.ok(!(await store.exists())) + }) +}) diff --git a/packages/access/tsconfig.json b/packages/access-client/tsconfig.json similarity index 100% rename from packages/access/tsconfig.json rename to packages/access-client/tsconfig.json diff --git a/packages/access-ws/package.json b/packages/access-ws/package.json index d650ecb96..5ed689492 100644 --- a/packages/access-ws/package.json +++ b/packages/access-ws/package.json @@ -22,31 +22,31 @@ "multiformats": "^10.0.2", "nanoid": "^4.0.0", "toucan-js": "^2.7.0", - "ws": "^8.10.0" + "ws": "^8.11.0" }, "devDependencies": { "@cloudflare/workers-types": "^3.18.0", - "@sentry/cli": "^2.8.0", - "@sentry/webpack-plugin": "^1.19.1", + "@sentry/cli": "^2.9.0", + "@sentry/webpack-plugin": "^1.20.0", "@types/assert": "^1.5.6", "@types/git-rev-sync": "^2.0.0", - "@types/node": "^18.11.7", + "@types/node": "^18.11.9", "assert": "^2.0.0", - "ava": "^5.0.1", + "ava": "^5.1.0", "buffer": "^6.0.3", "delay": "^5.0.0", "dotenv": "^16.0.3", - "esbuild": "^0.15.12", + "esbuild": "^0.15.14", "execa": "^6.1.0", - "git-rev-sync": "^3.0.1", + "git-rev-sync": "^3.0.2", "hd-scripts": "^3.0.2", - "miniflare": "^2.10.0", + "miniflare": "^2.11.0", "p-wait-for": "^5.0.0", "process": "^0.11.10", - "readable-stream": "^4.1.0", - "sade": "^1.7.4", + "readable-stream": "^4.2.0", + "sade": "^1.8.1", "typescript": "4.8.4", - "wrangler": "^2.1.13" + "wrangler": "^2.3.2" }, "eslintConfig": { "extends": [ diff --git a/packages/access-ws/tsconfig.json b/packages/access-ws/tsconfig.json index cedc9dcc8..3fbd527eb 100644 --- a/packages/access-ws/tsconfig.json +++ b/packages/access-ws/tsconfig.json @@ -7,5 +7,5 @@ }, "include": ["src", "scripts", "test", "package.json"], "exclude": ["**/node_modules/**"], - "references": [{ "path": "../access" }] + "references": [{ "path": "../access-client" }] } diff --git a/packages/access/src/agent.js b/packages/access/src/agent.js deleted file mode 100644 index ccd94b30a..000000000 --- a/packages/access/src/agent.js +++ /dev/null @@ -1,303 +0,0 @@ -import * as DID from '@ipld/dag-ucan/did' -import * as Client from '@ucanto/client' -// @ts-ignore -// eslint-disable-next-line no-unused-vars -import * as Ucanto from '@ucanto/interface' -import * as CAR from '@ucanto/transport/car' -import * as CBOR from '@ucanto/transport/cbor' -import * as HTTP from '@ucanto/transport/http' -import { URI } from '@ucanto/validator' -import { Peer } from './awake/peer.js' -import * as Account from './capabilities/account.js' -import * as Voucher from './capabilities/voucher.js' -import { any as Any } from './capabilities/any.js' -import { stringToDelegation } from './encoding.js' -import { Websocket, AbortError } from './utils/ws.js' - -/** - * @template T - * @typedef {{ - * store: import('./stores/types').Store - * connection: Ucanto.ConnectionView, - * url?: URL, - * fetch: typeof fetch - * data: import('./stores/types').StoreData - * }} AgentOptions - */ - -/** - * @template T - * @typedef {{ - * store: import('./stores/types').Store - * url?: URL, - * fetch?: typeof fetch - * }} AgentCreateOptions - */ - -const HOST = 'https://access.web3.storage' - -/** - * @template {string} T - * @param {Ucanto.Principal} principal - * @param {typeof fetch} _fetch - * @param {URL} url - * @returns { Promise>} - */ -export async function connection(principal, _fetch, url) { - const connection = Client.connect({ - id: principal, - encoder: CAR, - decoder: CBOR, - channel: HTTP.open({ - url, - method: 'POST', - fetch: _fetch, - }), - }) - - return connection -} - -/** - * @template {Ucanto.Signer} T - * Agent - */ -export class Agent { - /** @type {Ucanto.Principal|undefined} */ - #service - - /** @type {typeof fetch} */ - #fetch - - /** - * @param {AgentOptions} opts - */ - constructor(opts) { - this.url = opts.url || new URL(HOST) - this.connection = opts.connection - this.issuer = opts.data.principal - this.store = opts.store - this.data = opts.data - - // private - this.#fetch = opts.fetch - this.#service = undefined - } - - /** - * @template {Ucanto.Signer} T - * @param {AgentCreateOptions} opts - */ - static async create(opts) { - let _fetch = opts.fetch - const url = opts.url || new URL(HOST) - - // validate fetch implementation - if (!_fetch) { - if (typeof globalThis.fetch !== 'undefined') { - _fetch = globalThis.fetch.bind(globalThis) - } else { - throw new TypeError( - `Agent got undefined \`fetch\`. Try passing in a \`fetch\` implementation explicitly.` - ) - } - } - - const data = await opts.store.load() - return new Agent({ - connection: await connection(data.principal, _fetch, url), - fetch: _fetch, - url, - store: opts.store, - data, - }) - } - - async service() { - if (this.#service) { - return this.#service - } - const rsp = await this.#fetch(this.url + 'version') - const { did } = await rsp.json() - this.#service = DID.parse(did) - return this.#service - } - - did() { - return this.data.principal.did() - } - - /** - * @param {string} email - * @param {object} [opts] - * @param {AbortSignal} [opts.signal] - */ - async createAccount(email, opts) { - const account = await this.store.createAccount() - const service = await this.service() - const delegationToAgent = await Any.delegate({ - issuer: account, - audience: this.issuer, - with: account.did(), - expiration: Infinity, - }) - - const inv = await Voucher.claim - .invoke({ - issuer: this.issuer, - audience: service, - with: account.did(), - nb: { - identity: URI.from(`mailto:${email}`), - product: 'product:free', - service: service.did(), - }, - proofs: [delegationToAgent], - }) - .execute(this.connection) - - if (inv && inv.error) { - throw new Error('Account creation failed', { cause: inv.error }) - } - - const voucherRedeem = await this.#waitForVoucherRedeem(opts) - // TODO save this delegation so we can revoke later - const delegationToService = await Any.delegate({ - issuer: account, - audience: service, - with: account.did(), - expiration: Infinity, - }) - const accInv = await Voucher.redeem - .invoke({ - issuer: this.data.principal, - audience: service, - with: service.did(), - nb: { - account: account.did(), - identity: voucherRedeem.capabilities[0].nb.identity, - product: voucherRedeem.capabilities[0].nb.product, - }, - proofs: [voucherRedeem, delegationToService], - }) - - .execute(this.connection) - - if (accInv && accInv.error) { - throw new Error('Account registration failed', { cause: accInv }) - } - this.data.delegations.addMany([voucherRedeem, delegationToAgent]) - this.data.accounts.push(account) - this.store.save(this.data) - } - - /** - * - * @param {object} [opts] - * @param {AbortSignal} [opts.signal] - */ - async #waitForVoucherRedeem(opts) { - const ws = new Websocket(this.url, 'validate-ws') - await ws.open() - - ws.send({ - did: this.did(), - }) - - try { - const msg = await ws.awaitMsg(opts) - - if (msg.type === 'timeout') { - await ws.close() - throw new Error('Email validation timed out.') - } - - if (msg.type === 'delegation') { - const delegation = await stringToDelegation( - /** @type {import('./types').EncodedDelegation<[import('./types').VoucherRedeem]>} */ ( - msg.delegation - ) - ) - ws.close() - return delegation - } - } catch (error) { - if (error instanceof AbortError) { - await ws.close() - throw new TypeError('Failed to get voucher/redeem', { cause: error }) - } - } - throw new TypeError('Failed to get voucher/redeem') - } - - /** - * - * @param {Ucanto.Principal} audience - * @param {import('@ipld/dag-ucan').Capabilities} capabilities - * @param {number} [lifetimeInSeconds] - */ - async delegate(audience, capabilities, lifetimeInSeconds) { - const delegation = await this.data.delegations.delegate( - audience, - capabilities, - lifetimeInSeconds - ) - - await this.store.save(this.data) - return delegation - } - - /** - * - * @param {import('@ucanto/interface').Delegation} delegation - */ - async addDelegation(delegation) { - await this.data.delegations.add(delegation) - await this.store.save(this.data) - } - - /** - * - * @param {import('../src/awake/types').Channel} channel - */ - peer(channel) { - return new Peer({ agent: this, channel }) - } - - /** - * @param {Ucanto.URI<"did:">} account - */ - async getAccountInfo(account) { - const proofs = isEmpty(this.data.delegations.getByResource(account)) - if (!proofs) { - throw new TypeError('No proofs for "account/info".') - } - - const inv = await Account.info - .invoke({ - issuer: this.issuer, - audience: await this.service(), - with: account, - proofs, - }) - .execute(this.connection) - - if (inv.error) { - throw inv - } - - return inv - } -} - -/** - * @template T - * @param { Array | undefined} arr - */ -function isEmpty(arr) { - if (!Array.isArray(arr) || arr.length === 0) { - return - } - - return /** @type {T[]} */ (arr) -} diff --git a/packages/access/src/cli/cmd-whoami.js b/packages/access/src/cli/cmd-whoami.js deleted file mode 100644 index 2526a34c4..000000000 --- a/packages/access/src/cli/cmd-whoami.js +++ /dev/null @@ -1,33 +0,0 @@ -/* eslint-disable no-console */ -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 }) - if (await store.exists()) { - const { delegations, meta, accounts, principal } = await store.load() - - console.log('Agent', principal.did(), meta) - console.log('Accounts:') - for (const acc of accounts) { - console.log(acc.did()) - } - - console.log('Delegations created:') - for (const created of delegations.created) { - console.log(created) - } - console.log('Delegations received:') - for (const [key, value] of delegations.receivedByResource) { - console.log( - `Resource: ${key}`, - value.map((cap) => cap.cap.can) - ) - } - } else { - console.error(`Run "${NAME} setup" first`) - } -} diff --git a/packages/access/src/cli/index.js b/packages/access/src/cli/index.js deleted file mode 100755 index 68cddc656..000000000 --- a/packages/access/src/cli/index.js +++ /dev/null @@ -1,211 +0,0 @@ -#!/usr/bin/env node -/* eslint-disable no-console */ -import fs from 'fs' -import ora from 'ora' -import path from 'path' -import sade from 'sade' -import { Transform } from 'stream' -import undici from 'undici' -import { getConfig, NAME, pkg } from './config.js' -import { getService } from './utils.js' -// @ts-ignore -// eslint-disable-next-line no-unused-vars -import { cmdCreateAccount } from './cmd-create-account.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 inquirer from 'inquirer' -import { Verifier } from '@ucanto/principal/ed25519' -import { delegationToString, stringToDelegation } from '../encoding.js' - -const prog = sade(NAME) -prog - .version(pkg.version) - .option('-p, --profile', 'Select the config profile to use.', 'main') - .option('--env', 'Env', 'production') - -prog - .command('upload ') - .describe("Register with the service using config's keypair.") - .action(async (file, opts) => { - const config = getConfig(opts.profile) - const { url } = await getService(opts.env) - const spinner = ora('Registering with the service').start() - try { - if (!config.get('private-key')) { - spinner.fail( - `You dont have a private key saved yet, run "${NAME} init"` - ) - process.exit(1) - } - - const stream = fs.createReadStream(path.resolve(file)) - const checkStream = new Transform({ - transform(chunk, encoding, callback) { - console.log(chunk.length) - callback(undefined, chunk) - }, - }) - - const rsp = await undici.fetch(`${url}upload`, { - body: stream.pipe(checkStream), - method: 'POST', - }) - - console.log(await rsp.text()) - - spinner.succeed('Registration done.') - } catch (error) { - console.error(error) - // @ts-ignore - spinner.fail(error.message) - process.exit(1) - } - }) - -prog.command('link [channel]').describe('Link.').action(cmdLink) -prog - .command('setup') - .option('--reset', 'Reset current store.', false) - .describe('Print config file content.') - .action(cmdSetup) -prog.command('whoami').describe('Print config file content.').action(cmdWhoami) -prog - .command('create-account') - .describe('Create new account.') - .action(cmdCreateAccount) - -prog - .command('account') - .describe('Account info.') - .action(async (opts) => { - const store = new StoreConf({ profile: opts.profile }) - const { url } = await getService(opts.env) - if (await store.exists()) { - const agent = await Agent.create({ - store, - url, - }) - - const choices = [] - for (const [key, value] of agent.data.delegations.receivedByResource) { - for (const d of value) { - if (d.cap.can === 'account/info' || d.cap.can === 'account/*') { - choices.push({ name: key }) - } - } - } - - const { account } = await inquirer.prompt([ - { - type: 'list', - name: 'account', - default: 'device', - choices, - message: 'Select account:', - }, - ]) - try { - const result = await agent.getAccountInfo(account) - console.log(result) - } catch (error_) { - const error = /** @type {Error} */ (error_) - console.log(error.message) - } - } else { - console.error(`Run "${NAME} setup" first`) - } - }) - -prog - .command('delegate') - .describe('Delegation capabilities.') - .action(async (opts) => { - const store = new StoreConf({ profile: opts.profile }) - const { url } = await getService(opts.env) - if (await store.exists()) { - const agent = await Agent.create({ - store, - url, - }) - - const accountDids = agent.data.accounts.map((acc) => { - return { name: acc.did() } - }) - const { account } = await inquirer.prompt([ - { - type: 'list', - name: 'account', - choices: accountDids, - message: 'Select account:', - }, - ]) - - const abilities = [] - for (const [key, values] of agent.data.delegations.receivedByResource) { - if (key === account) { - for (const cap of values) { - abilities.push({ name: cap.cap.can }) - } - } - } - const { ability } = await inquirer.prompt([ - { - type: 'list', - name: 'ability', - choices: abilities, - message: 'Select ability:', - }, - ]) - - const { audience } = await inquirer.prompt([ - { - type: 'input', - name: 'audience', - choices: abilities, - message: 'Input audience:', - }, - ]) - - console.log(account, ability) - - const delegation = await agent.delegate( - Verifier.parse(audience), - [ - { - can: ability, - with: account, - }, - ], - 800_000 - ) - - console.log(await delegationToString(delegation)) - } 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 { url } = await getService(opts.env) - if (await store.exists()) { - const agent = await Agent.create({ - store, - url, - }) - - const del = fs.readFileSync('./delegation', { encoding: 'utf8' }) - - await agent.addDelegation(await stringToDelegation(del)) - } else { - console.error(`Run "${NAME} setup" first`) - } - }) -prog.parse(process.argv) diff --git a/packages/access/src/delegations.js b/packages/access/src/delegations.js deleted file mode 100644 index 526f898e1..000000000 --- a/packages/access/src/delegations.js +++ /dev/null @@ -1,103 +0,0 @@ -import { delegate } from '@ucanto/core' -// @ts-ignore -// eslint-disable-next-line no-unused-vars -import * as Ucanto from '@ucanto/interface' - -/** - * TODO: clear expired delegations - */ -export class Delegations { - /** - * @param {{ - * principal: Ucanto.Signer; - * received?: Ucanto.Delegation[] - * created?: Ucanto.Delegation[] - * meta?: import('./awake/types').MetaMap - * }} opts - */ - constructor(opts) { - this.principal = opts.principal - - /** @type {Ucanto.Delegation[]} */ - this.received = opts.received || [] - - /** @type {Ucanto.Delegation[]} */ - this.created = opts.created || [] - - /** @type {import('./awake/types').MetaMap} */ - this.meta = new Map() - - /** - * @type {Map} - */ - this.receivedByResource = new Map() - /** - * @type {Map} - */ - this.receivedMap = new Map() - } - - /** - * - * @param {Ucanto.Delegation} delegation - */ - async add(delegation) { - const cid = delegation.cid.toString() - - for (const cap of delegation.capabilities) { - const byResource = this.receivedByResource.get(cap.with) ?? [] - - byResource.push({ cid: delegation.cid.toString(), cap }) - this.receivedByResource.set(cap.with, byResource) - } - this.received.push(delegation) - - this.receivedMap.set(cid, delegation) - } - - /** - * @param {string} resource - */ - getByResource(resource) { - const byResource = this.receivedByResource.get(resource) - if (!byResource) { - return - } - - return byResource.map((r) => { - return this.receivedMap.get(r.cid) - }) - } - - /** - * Add multiple received delegations - * - * @param {Ucanto.Delegation[]} delegations - */ - async addMany(delegations) { - for (const d of delegations) { - this.add(d) - } - } - - /** - * - * @param {import('@ucanto/interface').Principal} audience - * @param {import('@ipld/dag-ucan').Capabilities} capabilities - * @param {number} [lifetimeInSeconds] - */ - async delegate(audience, capabilities, lifetimeInSeconds) { - const delegation = await delegate({ - issuer: this.principal, - // @ts-ignore - audience, - capabilities, - lifetimeInSeconds, - // be smarter about picking only the needs delegations - proofs: [...this.receivedMap.values()], - }) - - this.created.push(delegation) - return delegation - } -} diff --git a/packages/access/src/index.js b/packages/access/src/index.js deleted file mode 100644 index a858dcaa6..000000000 --- a/packages/access/src/index.js +++ /dev/null @@ -1 +0,0 @@ -export * from './agent.js' diff --git a/packages/access/src/stores/store-conf.js b/packages/access/src/stores/store-conf.js deleted file mode 100644 index 6782a0ef9..000000000 --- a/packages/access/src/stores/store-conf.js +++ /dev/null @@ -1,186 +0,0 @@ -import Conf from 'conf' -import { Signer } from '@ucanto/principal/ed25519' -import { Delegations } from '../delegations.js' -import { decodeDelegations, encodeDelegations } from '../encoding.js' - -/** - * @typedef {import('./types').DelegationsAsJSON} DelegationsAsJSON - * @typedef {import('./types').StoreDataKeyEd} StoreData - * @typedef {import('./types').StoreKeyEd} Store - */ - -/** - * Store implementation with "conf" - * - * @implements {Store} - */ -export class StoreConf { - #config - /** - * - * @param {{ - * profile: string - * }} opts - */ - constructor(opts) { - this.#config = new Conf({ - projectName: 'w3access', - projectSuffix: '', - configName: opts.profile, - }) - this.path = this.#config.path - } - - async open() { - return this - } - - async close() {} - - async reset() { - this.#config.clear() - } - - async exists() { - return this.#config.has('meta') && this.#config.has('principal') - } - - /** @type {Store['init']} */ - async init(data) { - const principal = data.principal || (await Signer.generate()) - const delegations = - data.delegations || - new Delegations({ - principal, - }) - /** @type {StoreData} */ - const storeData = { - accounts: data.accounts || [], - meta: data.meta || { name: 'agent', type: 'device' }, - principal, - delegations, - } - - await this.save(storeData) - return storeData - } - - /** - * - * @param {StoreData} data - */ - async save(data) { - this.setAccounts(data.accounts) - this.setDelegations(data.delegations) - this.setMeta(data.meta) - this.setPrincipal(data.principal) - return this - } - - /** @type {Store['load']} */ - async load() { - /** @type {StoreData} */ - return { - accounts: await this.getAccounts(), - meta: await this.getMeta(), - principal: await this.getPrincipal(), - delegations: await this.getDelegations(), - } - } - - async createAccount() { - return await Signer.generate() - } - - /** - * - * @param {import('../types').AgentMeta} meta - */ - async setMeta(meta) { - this.#config.set('meta', meta) - return meta - } - - /** - * @param {Signer.EdSigner} [principal] - */ - async setPrincipal(principal) { - let signer = principal - if (!signer) { - signer = await Signer.generate() - } - this.#config.set('principal', Signer.format(signer)) - return signer - } - - async getPrincipal() { - const raw = this.#config.get('principal') - return Signer.parse(/** @type {string} */ (raw)) - } - - async getMeta() { - const raw = this.#config.get('meta') - - return /** @type {import('../types').AgentMeta} */ (raw) - } - - /** - * @param {Delegations} delegations - */ - async setDelegations(delegations) { - const data = { - created: await encodeDelegations(delegations.created), - received: await encodeDelegations(delegations.received), - meta: [...delegations.meta.entries()], - } - - this.#config.set('delegations', data) - - return delegations - } - - async getDelegations() { - const data = /** @type {DelegationsAsJSON} */ ( - this.#config.get('delegations') - ) - const delegations = new Delegations({ - principal: await this.getPrincipal(), - created: await decodeDelegations(data.created || ''), - meta: new Map(data.meta), - }) - - await delegations.addMany(await decodeDelegations(data.received || '')) - - return delegations - } - - /** - * - * @param {Signer.EdSigner[]} accounts - */ - async setAccounts(accounts) { - const encoded = [] - for (const acc of accounts) { - encoded.push(Signer.format(acc)) - } - - this.#config.set('accounts', encoded) - - return accounts - } - - async getAccounts() { - const encoded = /** @type {string[]} */ (this.#config.get('accounts')) - /** @type {Signer.EdSigner[]} */ - const accounts = [] - - if (!Array.isArray(encoded)) { - return accounts - } - for (const acc of encoded) { - accounts.push(Signer.parse(acc)) - } - - return accounts - } -} diff --git a/packages/access/src/stores/types.ts b/packages/access/src/stores/types.ts deleted file mode 100644 index 757ed7e08..000000000 --- a/packages/access/src/stores/types.ts +++ /dev/null @@ -1,47 +0,0 @@ -import { AgentMeta } from '../types.js' -import { Delegations } from '../delegations.js' -import ed25519 from '@ucanto/principal/ed25519' -import { RSASigner } from '@ucanto/principal/rsa' -import { SignerArchive } from '@ucanto/interface' - -export interface DelegationsAsJSON { - created: string - received: string - meta: Array<[string, AgentMeta]> -} - -export interface StoreData { - accounts: T[] - meta: AgentMeta - principal: T - delegations: Delegations -} - -export interface Store { - open: () => Promise> - close: () => Promise - exists: () => Promise - init: (data: Partial>) => Promise> - save: (data: StoreData) => Promise> - load: () => Promise> - createAccount: () => Promise - reset: () => Promise -} - -export interface StoreKeyEd extends Store {} -export interface StoreDataKeyEd extends StoreData {} - -export interface StoreKeyRSA extends Store {} -export interface StoreDataKeyRSA extends StoreData {} - -export interface IDBStoreData { - id: number - accounts: Array> - delegations: { - created: Array> - received: Array> - meta: Array<[string, import('../awake/types').PeerMeta]> - } - meta: import('../types').AgentMeta - principal: SignerArchive -} diff --git a/packages/access/src/types.ts b/packages/access/src/types.ts deleted file mode 100644 index 23cbbb58e..000000000 --- a/packages/access/src/types.ts +++ /dev/null @@ -1,61 +0,0 @@ -/* eslint-disable @typescript-eslint/indent */ -import type { - Capabilities, - Failure, - Phantom, - RequestEncoder, - ResponseDecoder, - ServiceMethod, - UCAN, - URI, -} from '@ucanto/interface' - -import type { - AccountInfo, - AccountRecover, - AccountRecoverValidation, -} from './capabilities/types' -import { VoucherClaim, VoucherRedeem } from './capabilities/types.js' - -export * from './capabilities/types.js' - -export interface ClientCodec extends RequestEncoder, ResponseDecoder {} - -export type EncodedDelegation = string & - Phantom - -export interface Service { - voucher: { - claim: ServiceMethod< - VoucherClaim, - EncodedDelegation<[VoucherRedeem]> | undefined, - Failure - > - redeem: ServiceMethod - } - account: { - info: ServiceMethod - 'recover-validation': ServiceMethod< - AccountRecoverValidation, - EncodedDelegation<[AccountRecover]> | undefined, - Failure - > - } -} - -export interface Account { - did: UCAN.DID - agent: UCAN.DID - email: URI<'mailto:'> - product: URI<'product:'> - updated_at: string - inserted_at: string -} - -export interface AgentMeta { - name: string - description?: string - url?: URL - image?: URL - type: 'device' | 'app' | 'service' -} diff --git a/packages/access/test/helpers/utils.js b/packages/access/test/helpers/utils.js deleted file mode 100644 index 291f1a62d..000000000 --- a/packages/access/test/helpers/utils.js +++ /dev/null @@ -1,29 +0,0 @@ -// eslint-disable-next-line no-unused-vars -import * as Ucanto from '@ucanto/interface' -import { parseLink } from '@ucanto/core' -import { codec as CARCodec } from '@ucanto/transport/car' -import { codec as CBOR } from '@ucanto/transport/cbor' - -/** - * @param {string} source - */ -export function parseCarLink(source) { - return /** @type {Ucanto.Link} */ (parseLink(source)) -} - -/** - * @param {any} data - */ -export async function createCborCid(data) { - const cbor = await CBOR.write(data) - return cbor.cid -} - -/** - * @param {string} source - */ -export async function createCarCid(source) { - const cbor = await CBOR.write({ hello: source }) - const shard = await CARCodec.write({ roots: [cbor] }) - return shard.cid -} diff --git a/packages/store/package.json b/packages/store/package.json index e1cb19ef0..0e3b46bd3 100644 --- a/packages/store/package.json +++ b/packages/store/package.json @@ -26,27 +26,27 @@ "lintss": "tsc --build && eslint '**/*.{js,ts}' && prettier --check '**/*.{js,ts,yml,json}' --ignore-path ../../.gitignore" }, "dependencies": { - "@ucanto/client": "^3.0.1", - "@ucanto/core": "^3.0.1", - "@ucanto/interface": "^3.0.0", - "@ucanto/principal": "^3.0.0", - "@ucanto/server": "^3.0.1", - "@ucanto/transport": "^3.0.1", - "@ucanto/validator": "^3.0.1", + "@ucanto/client": "^3.0.2", + "@ucanto/core": "^3.0.2", + "@ucanto/interface": "^3.0.1", + "@ucanto/principal": "^3.0.1", + "@ucanto/server": "^3.0.4", + "@ucanto/transport": "^3.0.2", + "@ucanto/validator": "^3.0.4", "@web-std/fetch": "^4.1.0", - "@web3-storage/sigv4": "^1.0.0", + "@web3-storage/sigv4": "^1.0.2", "multiformats": "^10.0.2" }, "devDependencies": { - "@types/chai": "^4.3.0", + "@types/chai": "^4.3.4", "@types/chai-subset": "^1.3.3", "@types/mocha": "^10.0.0", - "chai": "^4.3.6", + "chai": "^4.3.7", "chai-subset": "^1.6.0", "hd-scripts": "^3.0.2", "mocha": "^10.1.0", "playwright-test": "^8.1.1", - "typescript": "^4.8.4" + "typescript": "4.8.4" }, "exports": { ".": { diff --git a/packages/upload-client/package.json b/packages/upload-client/package.json index de4b4af80..afb70cb78 100644 --- a/packages/upload-client/package.json +++ b/packages/upload-client/package.json @@ -43,7 +43,7 @@ "hd-scripts": "^3.0.2", "mocha": "^10.1.0", "playwright-test": "^8.1.1", - "typescript": "^4.8.4" + "typescript": "4.8.4" }, "eslintConfig": { "extends": [ diff --git a/packages/wallet/package.json b/packages/wallet/package.json index a90abb750..906a57c18 100644 --- a/packages/wallet/package.json +++ b/packages/wallet/package.json @@ -11,18 +11,18 @@ "check": "tsc" }, "dependencies": { - "next": "12.3.1", + "next": "13.0.3", "react": "18.2.0", "react-dom": "18.2.0" }, "devDependencies": { - "@types/node": "^18.11.7", - "@types/react": "^18.0.24", - "eslint": "^8.26.0", - "eslint-config-next": "12.3.1", + "@types/node": "^18.11.9", + "@types/react": "^18.0.25", + "eslint": "^8.27.0", + "eslint-config-next": "13.0.3", "hd-scripts": "^3.0.2", "typescript": "4.8.4", - "wrangler": "^2.1.13" + "wrangler": "^2.3.2" }, "eslintConfig": { "extends": [ diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index defdcdc0c..de3340083 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -7,103 +7,19 @@ importers: lint-staged: ^13.0.3 prettier: 2.7.1 simple-git-hooks: ^2.8.1 - typescript: ^4.8.4 - wrangler: ^2.1.13 + typedoc: ^0.23.21 + typedoc-plugin-missing-exports: ^1.0.0 + typescript: 4.8.4 + wrangler: ^2.3.2 + dependencies: + typedoc: 0.23.21_typescript@4.8.4 + typedoc-plugin-missing-exports: 1.0.0_typedoc@0.23.21 devDependencies: lint-staged: 13.0.3 prettier: 2.7.1 simple-git-hooks: 2.8.1 typescript: 4.8.4 - wrangler: 2.1.15 - - packages/access: - specifiers: - '@ipld/car': ^5.0.0 - '@ipld/dag-ucan': ^2.0.1 - '@noble/ed25519': ^1.7.1 - '@types/assert': ^1.5.6 - '@types/inquirer': ^9.0.2 - '@types/mocha': ^10.0.0 - '@types/node': ^18.11.7 - '@types/ws': ^8.5.3 - '@ucanto/client': ^3.0.1 - '@ucanto/core': ^3.0.1 - '@ucanto/interface': ^3.0.0 - '@ucanto/principal': ^3.0.0 - '@ucanto/server': ^3.0.1 - '@ucanto/transport': ^3.0.1 - '@ucanto/validator': ^3.0.1 - '@web-std/fetch': ^4.1.0 - assert: ^2.0.0 - bigint-mod-arith: ^3.1.2 - conf: ^10.1.2 - delay: ^5.0.0 - dotenv: ^16.0.3 - hd-scripts: ^3.0.2 - inquirer: ^9.1.4 - isomorphic-ws: ^5.0.0 - miniflare: ^2.9.0 - mocha: ^10.1.0 - multiformats: ^10.0.2 - nanoid: ^4.0.0 - one-webcrypto: ^1.0.3 - ora: ^6.1.2 - p-defer: ^4.0.0 - p-queue: ^7.3.0 - p-retry: ^5.1.1 - p-wait-for: ^5.0.0 - playwright-test: ^8.1.1 - sade: ^1.7.4 - typescript: 4.8.4 - uint8arrays: ^4.0.2 - undici: ^5.12.0 - watch: ^1.0.2 - ws: ^8.10.0 - zod: ^3.19.1 - dependencies: - '@ipld/car': 5.0.0 - '@ipld/dag-ucan': 2.0.1 - '@noble/ed25519': 1.7.1 - '@types/ws': 8.5.3 - '@ucanto/client': 3.0.1 - '@ucanto/core': 3.0.1 - '@ucanto/interface': 3.0.0 - '@ucanto/principal': 3.0.0 - '@ucanto/server': 3.0.1 - '@ucanto/transport': 3.0.1 - '@ucanto/validator': 3.0.1 - '@web-std/fetch': 4.1.0 - bigint-mod-arith: 3.1.2 - conf: 10.2.0 - inquirer: 9.1.4 - isomorphic-ws: 5.0.0_ws@8.10.0 - multiformats: 10.0.2 - nanoid: 4.0.0 - one-webcrypto: 1.0.3 - ora: 6.1.2 - p-defer: 4.0.0 - p-queue: 7.3.0 - p-retry: 5.1.1 - p-wait-for: 5.0.0 - uint8arrays: 4.0.2 - undici: 5.12.0 - ws: 8.10.0 - zod: 3.19.1 - devDependencies: - '@types/assert': 1.5.6 - '@types/inquirer': 9.0.2 - '@types/mocha': 10.0.0 - '@types/node': 18.11.9 - assert: 2.0.0 - delay: 5.0.0 - dotenv: 16.0.3 - hd-scripts: 3.0.2 - miniflare: 2.11.0 - mocha: 10.1.0 - playwright-test: 8.1.1 - sade: 1.8.1 - typescript: 4.8.4 - watch: 1.0.2 + wrangler: 2.3.2 packages/access-api: specifiers: @@ -111,61 +27,62 @@ importers: '@databases/escape-identifier': ^1.0.3 '@databases/sql': ^3.2.0 '@ipld/dag-ucan': ^2.0.1 - '@sentry/cli': ^2.8.0 - '@sentry/webpack-plugin': ^1.19.1 + '@sentry/cli': ^2.9.0 + '@sentry/webpack-plugin': ^1.20.0 '@types/assert': ^1.5.6 '@types/git-rev-sync': ^2.0.0 - '@types/node': ^18.11.7 + '@types/node': ^18.11.9 '@types/qrcode': ^1.5.0 - '@ucanto/client': ^3.0.1 - '@ucanto/core': ^3.0.1 - '@ucanto/interface': ^3.0.0 - '@ucanto/principal': ^3.0.0 - '@ucanto/server': ^3.0.1 - '@ucanto/transport': ^3.0.1 - '@ucanto/validator': ^3.0.1 + '@ucanto/client': ^3.0.2 + '@ucanto/core': ^3.0.2 + '@ucanto/interface': ^3.0.1 + '@ucanto/principal': ^3.0.1 + '@ucanto/server': ^3.0.4 + '@ucanto/transport': ^3.0.2 + '@ucanto/validator': ^3.0.4 '@web3-storage/access': workspace:^ '@web3-storage/worker-utils': 0.4.3-dev assert: ^2.0.0 - ava: ^5.0.1 + ava: ^5.1.0 better-sqlite3: 7.6.2 buffer: ^6.0.3 delay: ^5.0.0 dotenv: ^16.0.3 - esbuild: ^0.15.12 + esbuild: ^0.15.14 execa: ^6.1.0 - git-rev-sync: ^3.0.1 + git-rev-sync: ^3.0.2 hd-scripts: ^3.0.2 - miniflare: ^2.10.0 + miniflare: ^2.11.0 multiformats: ^10.0.2 nanoid: ^4.0.0 p-retry: ^5.1.1 - preact: ^10.11.2 + p-wait-for: ^5.0.0 + preact: ^10.11.3 preact-render-to-string: ^5.2.6 process: ^0.11.10 qrcode: ^1.5.1 - readable-stream: ^4.1.0 - sade: ^1.7.4 + readable-stream: ^4.2.0 + sade: ^1.8.1 toucan-js: ^2.7.0 typescript: 4.8.4 workers-qb: ^0.1.2 - wrangler: ^2.1.13 + wrangler: ^2.3.2 dependencies: '@ipld/dag-ucan': 2.0.1 - '@ucanto/client': 3.0.1 - '@ucanto/core': 3.0.1 - '@ucanto/interface': 3.0.0 - '@ucanto/principal': 3.0.0 - '@ucanto/server': 3.0.1 - '@ucanto/transport': 3.0.1 - '@ucanto/validator': 3.0.1 - '@web3-storage/access': link:../access + '@ucanto/client': 3.0.2 + '@ucanto/core': 3.0.2 + '@ucanto/interface': 3.0.1 + '@ucanto/principal': 3.0.1 + '@ucanto/server': 3.0.4 + '@ucanto/transport': 3.0.2 + '@ucanto/validator': 3.0.4 + '@web3-storage/access': link:../access-client '@web3-storage/worker-utils': 0.4.3-dev multiformats: 10.0.2 nanoid: 4.0.0 p-retry: 5.1.1 - preact: 10.11.2 - preact-render-to-string: 5.2.6_preact@10.11.2 + preact: 10.11.3 + preact-render-to-string: 5.2.6_preact@10.11.3 qrcode: 1.5.1 toucan-js: 2.7.0 workers-qb: 0.1.2 @@ -173,81 +90,171 @@ importers: '@cloudflare/workers-types': 3.18.0 '@databases/escape-identifier': 1.0.3 '@databases/sql': 3.2.0 - '@sentry/cli': 2.8.1 + '@sentry/cli': 2.9.0 '@sentry/webpack-plugin': 1.20.0 '@types/assert': 1.5.6 '@types/git-rev-sync': 2.0.0 '@types/node': 18.11.9 '@types/qrcode': 1.5.0 assert: 2.0.0 - ava: 5.0.1 + ava: 5.1.0 better-sqlite3: 7.6.2 buffer: 6.0.3 delay: 5.0.0 dotenv: 16.0.3 - esbuild: 0.15.13 + esbuild: 0.15.14 execa: 6.1.0 git-rev-sync: 3.0.2 hd-scripts: 3.0.2 miniflare: 2.11.0 + p-wait-for: 5.0.0 process: 0.11.10 readable-stream: 4.2.0 sade: 1.8.1 typescript: 4.8.4 - wrangler: 2.1.15 + wrangler: 2.3.2 + + packages/access-client: + specifiers: + '@ipld/car': ^5.0.1 + '@ipld/dag-ucan': ^2.0.1 + '@noble/ed25519': ^1.7.1 + '@types/assert': ^1.5.6 + '@types/inquirer': ^9.0.3 + '@types/mocha': ^10.0.0 + '@types/node': ^18.11.9 + '@types/ws': ^8.5.3 + '@ucanto/client': ^3.0.2 + '@ucanto/core': ^3.0.2 + '@ucanto/interface': ^3.0.1 + '@ucanto/principal': ^3.0.1 + '@ucanto/server': ^3.0.4 + '@ucanto/transport': ^3.0.2 + '@ucanto/validator': ^3.0.4 + '@web-std/fetch': ^4.1.0 + assert: ^2.0.0 + bigint-mod-arith: ^3.1.2 + conf: ^10.2.0 + delay: ^5.0.0 + dotenv: ^16.0.3 + hd-scripts: ^3.0.2 + inquirer: ^9.1.4 + isomorphic-ws: ^5.0.0 + miniflare: ^2.11.0 + mocha: ^10.1.0 + multiformats: ^10.0.2 + nanoid: ^4.0.0 + one-webcrypto: ^1.0.3 + ora: ^6.1.2 + p-defer: ^4.0.0 + p-queue: ^7.3.0 + p-wait-for: ^5.0.0 + playwright-test: ^8.1.1 + sade: ^1.8.1 + streaming-iterables: ^7.1.0 + type-fest: ^3.2.0 + typescript: 4.8.4 + uint8arrays: ^4.0.2 + watch: ^1.0.2 + ws: ^8.11.0 + zod: ^3.19.1 + dependencies: + '@ipld/car': 5.0.1 + '@ipld/dag-ucan': 2.0.1 + '@noble/ed25519': 1.7.1 + '@ucanto/client': 3.0.2 + '@ucanto/core': 3.0.2 + '@ucanto/interface': 3.0.1 + '@ucanto/principal': 3.0.1 + '@ucanto/server': 3.0.4 + '@ucanto/transport': 3.0.2 + '@ucanto/validator': 3.0.4 + '@web-std/fetch': 4.1.0 + bigint-mod-arith: 3.1.2 + conf: 10.2.0 + inquirer: 9.1.4 + isomorphic-ws: 5.0.0_ws@8.11.0 + multiformats: 10.0.2 + nanoid: 4.0.0 + one-webcrypto: 1.0.3 + ora: 6.1.2 + p-defer: 4.0.0 + p-wait-for: 5.0.0 + streaming-iterables: 7.1.0 + type-fest: 3.2.0 + uint8arrays: 4.0.2 + ws: 8.11.0 + zod: 3.19.1 + devDependencies: + '@types/assert': 1.5.6 + '@types/inquirer': 9.0.3 + '@types/mocha': 10.0.0 + '@types/node': 18.11.9 + '@types/ws': 8.5.3 + assert: 2.0.0 + delay: 5.0.0 + dotenv: 16.0.3 + hd-scripts: 3.0.2 + miniflare: 2.11.0 + mocha: 10.1.0 + p-queue: 7.3.0 + playwright-test: 8.1.1 + sade: 1.8.1 + typescript: 4.8.4 + watch: 1.0.2 packages/access-ws: specifiers: '@cloudflare/workers-types': ^3.18.0 - '@sentry/cli': ^2.8.0 - '@sentry/webpack-plugin': ^1.19.1 + '@sentry/cli': ^2.9.0 + '@sentry/webpack-plugin': ^1.20.0 '@types/assert': ^1.5.6 '@types/git-rev-sync': ^2.0.0 - '@types/node': ^18.11.7 + '@types/node': ^18.11.9 '@types/ws': ^8.5.3 '@web3-storage/worker-utils': 0.4.3-dev assert: ^2.0.0 - ava: ^5.0.1 + ava: ^5.1.0 buffer: ^6.0.3 delay: ^5.0.0 dotenv: ^16.0.3 - esbuild: ^0.15.12 + esbuild: ^0.15.14 execa: ^6.1.0 - git-rev-sync: ^3.0.1 + git-rev-sync: ^3.0.2 hd-scripts: ^3.0.2 isomorphic-ws: ^5.0.0 - miniflare: ^2.10.0 + miniflare: ^2.11.0 multiformats: ^10.0.2 nanoid: ^4.0.0 p-wait-for: ^5.0.0 process: ^0.11.10 - readable-stream: ^4.1.0 - sade: ^1.7.4 + readable-stream: ^4.2.0 + sade: ^1.8.1 toucan-js: ^2.7.0 typescript: 4.8.4 - wrangler: ^2.1.13 - ws: ^8.10.0 + wrangler: ^2.3.2 + ws: ^8.11.0 dependencies: '@types/ws': 8.5.3 '@web3-storage/worker-utils': 0.4.3-dev - isomorphic-ws: 5.0.0_ws@8.10.0 + isomorphic-ws: 5.0.0_ws@8.11.0 multiformats: 10.0.2 nanoid: 4.0.0 toucan-js: 2.7.0 - ws: 8.10.0 + ws: 8.11.0 devDependencies: '@cloudflare/workers-types': 3.18.0 - '@sentry/cli': 2.8.1 + '@sentry/cli': 2.9.0 '@sentry/webpack-plugin': 1.20.0 '@types/assert': 1.5.6 '@types/git-rev-sync': 2.0.0 '@types/node': 18.11.9 assert: 2.0.0 - ava: 5.0.1 + ava: 5.1.0 buffer: 6.0.3 delay: 5.0.0 dotenv: 16.0.3 - esbuild: 0.15.13 + esbuild: 0.15.14 execa: 6.1.0 git-rev-sync: 3.0.2 hd-scripts: 3.0.2 @@ -257,64 +264,64 @@ importers: readable-stream: 4.2.0 sade: 1.8.1 typescript: 4.8.4 - wrangler: 2.1.15 + wrangler: 2.3.2 - packages/upload-client: + packages/store: specifiers: - '@types/assert': ^1.5.6 + '@types/chai': ^4.3.4 + '@types/chai-subset': ^1.3.3 '@types/mocha': ^10.0.0 - assert: ^2.0.0 + '@ucanto/client': ^3.0.2 + '@ucanto/core': ^3.0.2 + '@ucanto/interface': ^3.0.1 + '@ucanto/principal': ^3.0.1 + '@ucanto/server': ^3.0.4 + '@ucanto/transport': ^3.0.2 + '@ucanto/validator': ^3.0.4 + '@web-std/fetch': ^4.1.0 + '@web3-storage/sigv4': ^1.0.2 + chai: ^4.3.7 + chai-subset: ^1.6.0 hd-scripts: ^3.0.2 mocha: ^10.1.0 + multiformats: ^10.0.2 playwright-test: ^8.1.1 - typescript: ^4.8.4 + typescript: 4.8.4 + dependencies: + '@ucanto/client': 3.0.2 + '@ucanto/core': 3.0.2 + '@ucanto/interface': 3.0.1 + '@ucanto/principal': 3.0.1 + '@ucanto/server': 3.0.4 + '@ucanto/transport': 3.0.2 + '@ucanto/validator': 3.0.4 + '@web-std/fetch': 4.1.0 + '@web3-storage/sigv4': 1.0.2 + multiformats: 10.0.2 devDependencies: - '@types/assert': 1.5.6 + '@types/chai': 4.3.4 + '@types/chai-subset': 1.3.3 '@types/mocha': 10.0.0 - assert: 2.0.0 + chai: 4.3.7 + chai-subset: 1.6.0 hd-scripts: 3.0.2 mocha: 10.1.0 playwright-test: 8.1.1 typescript: 4.8.4 - packages/store: + packages/upload-client: specifiers: - '@types/chai': ^4.3.0 - '@types/chai-subset': ^1.3.3 + '@types/assert': ^1.5.6 '@types/mocha': ^10.0.0 - '@ucanto/client': ^3.0.1 - '@ucanto/core': ^3.0.1 - '@ucanto/interface': ^3.0.0 - '@ucanto/principal': ^3.0.0 - '@ucanto/server': ^3.0.1 - '@ucanto/transport': ^3.0.1 - '@ucanto/validator': ^3.0.1 - '@web-std/fetch': ^4.1.0 - '@web3-storage/sigv4': ^1.0.0 - chai: ^4.3.6 - chai-subset: ^1.6.0 + assert: ^2.0.0 hd-scripts: ^3.0.2 mocha: ^10.1.0 - multiformats: ^10.0.2 playwright-test: ^8.1.1 - typescript: ^4.8.4 - dependencies: - '@ucanto/client': 3.0.1 - '@ucanto/core': 3.0.1 - '@ucanto/interface': 3.0.0 - '@ucanto/principal': 3.0.0 - '@ucanto/server': 3.0.1 - '@ucanto/transport': 3.0.1 - '@ucanto/validator': 3.0.1 - '@web-std/fetch': 4.1.0 - '@web3-storage/sigv4': 1.0.2 - multiformats: 10.0.2 + typescript: 4.8.4 devDependencies: - '@types/chai': 4.3.3 - '@types/chai-subset': 1.3.3 + '@types/assert': 1.5.6 '@types/mocha': 10.0.0 - chai: 4.3.6 - chai-subset: 1.6.0 + assert: 2.0.0 hd-scripts: 3.0.2 mocha: 10.1.0 playwright-test: 8.1.1 @@ -322,28 +329,28 @@ importers: packages/wallet: specifiers: - '@types/node': ^18.11.7 - '@types/react': ^18.0.24 - eslint: ^8.26.0 - eslint-config-next: 12.3.1 + '@types/node': ^18.11.9 + '@types/react': ^18.0.25 + eslint: ^8.27.0 + eslint-config-next: 13.0.3 hd-scripts: ^3.0.2 - next: 12.3.1 + next: 13.0.3 react: 18.2.0 react-dom: 18.2.0 typescript: 4.8.4 - wrangler: ^2.1.13 + wrangler: ^2.3.2 dependencies: - next: 12.3.1_biqbaboplfbrettd7655fr4n2y + next: 13.0.3_biqbaboplfbrettd7655fr4n2y react: 18.2.0 react-dom: 18.2.0_react@18.2.0 devDependencies: '@types/node': 18.11.9 - '@types/react': 18.0.24 - eslint: 8.26.0 - eslint-config-next: 12.3.1_wyqvi574yv7oiwfeinomdzmc3m + '@types/react': 18.0.25 + eslint: 8.27.0 + eslint-config-next: 13.0.3_rmayb2veg2btbq6mbmnyivgasy hd-scripts: 3.0.2 typescript: 4.8.4 - wrangler: 2.1.15 + wrangler: 2.3.2 packages: @@ -377,7 +384,7 @@ packages: resolution: {integrity: sha512-CGulbEDcg/ND1Im7fUNRZdGXmX2MTWVVZacQi/6DiKE5HNwZ3aVTm5PV4lO8HHz0B2h8WQyvKKjbX5XgTtydsg==} engines: {node: '>=6.9.0'} dependencies: - core-js-pure: 3.26.0 + core-js-pure: 3.26.1 regenerator-runtime: 0.13.10 dev: true @@ -439,8 +446,8 @@ packages: rollup-plugin-node-polyfills: 0.2.1 dev: true - /@esbuild/android-arm/0.15.13: - resolution: {integrity: sha512-RY2fVI8O0iFUNvZirXaQ1vMvK0xhCcl0gqRj74Z6yEiO1zAUa7hbsdwZM1kzqbxHK7LFyMizipfXT3JME+12Hw==} + /@esbuild/android-arm/0.15.14: + resolution: {integrity: sha512-+Rb20XXxRGisNu2WmNKk+scpanb7nL5yhuI1KR9wQFiC43ddPj/V1fmNyzlFC9bKiG4mYzxW7egtoHVcynr+OA==} engines: {node: '>=12'} cpu: [arm] os: [android] @@ -448,8 +455,8 @@ packages: dev: true optional: true - /@esbuild/linux-loong64/0.15.13: - resolution: {integrity: sha512-+BoyIm4I8uJmH/QDIH0fu7MG0AEx9OXEDXnqptXCwKOlOqZiS4iraH1Nr7/ObLMokW3sOCeBNyD68ATcV9b9Ag==} + /@esbuild/linux-loong64/0.15.14: + resolution: {integrity: sha512-eQi9rosGNVQFJyJWV0HCA5WZae/qWIQME7s8/j8DMvnylfBv62Pbu+zJ2eUDqNf2O4u3WB+OEXyfkpBoe194sg==} engines: {node: '>=12'} cpu: [loong64] os: [linux] @@ -463,7 +470,7 @@ packages: dependencies: ajv: 6.12.6 debug: 4.3.4 - espree: 9.4.0 + espree: 9.4.1 globals: 13.17.0 ignore: 5.2.0 import-fresh: 3.3.0 @@ -498,12 +505,12 @@ packages: resolution: {integrity: sha512-trnsAYxU3xnS1gPHPyU961coFyLkh4gAD/0zQ5mymY4yOZ+CYvsPqUbOFSw0aDM4y0tV7tiFxL/1XfXPNC6IPg==} dev: true - /@ipld/car/5.0.0: - resolution: {integrity: sha512-JyJ5vGEIyheqxmJKa81eQdd9tScOKpkO1wcGQPsm/DbV87n0wT7KvzaFOLSZCcPoq23+C5u+GIwFV+CBUVBGOw==} + /@ipld/car/5.0.1: + resolution: {integrity: sha512-YPXr1TztVmTPE4MerjKpFMuIll73MqvEakzWDMqj4uGJnwkY+tE0SlBGmqkMSofOgVMQAxZ6JtuRA93WlTzb8w==} engines: {node: '>=16.0.0', npm: '>=7.0.0'} dependencies: '@ipld/dag-cbor': 8.0.0 - cborg: 1.9.5 + cborg: 1.9.6 multiformats: 10.0.2 varint: 6.0.0 dev: false @@ -512,7 +519,7 @@ packages: resolution: {integrity: sha512-VfedC21yAD/ZIahcrHTeMcc17kEVRlCmHQl0JY9/Rwbd102v0QcuXtBN8KGH8alNO82S89+H6MM/hxP85P4Veg==} engines: {node: '>=16.0.0', npm: '>=7.0.0'} dependencies: - cborg: 1.9.5 + cborg: 1.9.6 multiformats: 10.0.2 dev: false @@ -520,7 +527,7 @@ packages: resolution: {integrity: sha512-dL5Xhrk0XXoq3lSsY2LNNraH2Nxx4nlgQwSarl2J3oir2jBDQEiBDW8bjgr30ni8/epdWDhXm5mdxat8dFWwGQ==} engines: {node: '>=16.0.0', npm: '>=7.0.0'} dependencies: - cborg: 1.9.5 + cborg: 1.9.6 multiformats: 10.0.2 dev: false @@ -687,7 +694,7 @@ packages: kleur: 4.1.5 selfsigned: 2.1.1 undici: 5.9.1 - ws: 8.10.0 + ws: 8.11.0 youch: 2.2.2 transitivePeerDependencies: - bufferutil @@ -704,7 +711,7 @@ packages: kleur: 4.1.5 selfsigned: 2.1.1 undici: 5.9.1 - ws: 8.10.0 + ws: 8.11.0 youch: 2.2.2 transitivePeerDependencies: - bufferutil @@ -876,7 +883,7 @@ packages: '@miniflare/core': 2.10.0 '@miniflare/shared': 2.10.0 undici: 5.9.1 - ws: 8.10.0 + ws: 8.11.0 transitivePeerDependencies: - bufferutil - utf-8-validate @@ -889,24 +896,24 @@ packages: '@miniflare/core': 2.11.0 '@miniflare/shared': 2.11.0 undici: 5.9.1 - ws: 8.10.0 + ws: 8.11.0 transitivePeerDependencies: - bufferutil - utf-8-validate dev: true - /@next/env/12.3.1: - resolution: {integrity: sha512-9P9THmRFVKGKt9DYqeC2aKIxm8rlvkK38V1P1sRE7qyoPBIs8l9oo79QoSdPtOWfzkbDAVUqvbQGgTMsb8BtJg==} + /@next/env/13.0.3: + resolution: {integrity: sha512-/4WzeG61Ot/PxsghXkSqQJ6UohFfwXoZ3dtsypmR9EBP+OIax9JRq0trq8Z/LCT9Aq4JbihVkaazRWguORjTAw==} dev: false - /@next/eslint-plugin-next/12.3.1: - resolution: {integrity: sha512-sw+lTf6r6P0j+g/n9y4qdWWI2syPqZx+uc0+B/fRENqfR3KpSid6MIKqc9gNwGhJASazEQ5b3w8h4cAET213jw==} + /@next/eslint-plugin-next/13.0.3: + resolution: {integrity: sha512-slmTAHNKDyc7jhx4VF8lFbmOPWJ3PShtUUWpb6x9+ga59CyOxgP6AdcDhxfapnWYACKe/TwYiaveufu7LqXgZg==} dependencies: glob: 7.1.7 dev: true - /@next/swc-android-arm-eabi/12.3.1: - resolution: {integrity: sha512-i+BvKA8tB//srVPPQxIQN5lvfROcfv4OB23/L1nXznP+N/TyKL8lql3l7oo2LNhnH66zWhfoemg3Q4VJZSruzQ==} + /@next/swc-android-arm-eabi/13.0.3: + resolution: {integrity: sha512-uxfUoj65CdFc1gX2q7GtBX3DhKv9Kn343LMqGNvXyuTpYTGMmIiVY7b9yF8oLWRV0gVKqhZBZifUmoPE8SJU6Q==} engines: {node: '>= 10'} cpu: [arm] os: [android] @@ -914,8 +921,8 @@ packages: dev: false optional: true - /@next/swc-android-arm64/12.3.1: - resolution: {integrity: sha512-CmgU2ZNyBP0rkugOOqLnjl3+eRpXBzB/I2sjwcGZ7/Z6RcUJXK5Evz+N0ucOxqE4cZ3gkTeXtSzRrMK2mGYV8Q==} + /@next/swc-android-arm64/13.0.3: + resolution: {integrity: sha512-t2k+WDfg7Cq2z/EnalKGsd/9E5F4Hdo1xu+UzZXYDpKUI9zgE6Bz8ajQb8m8txv3qOaWdKuDa5j5ziq9Acd1Xw==} engines: {node: '>= 10'} cpu: [arm64] os: [android] @@ -923,8 +930,8 @@ packages: dev: false optional: true - /@next/swc-darwin-arm64/12.3.1: - resolution: {integrity: sha512-hT/EBGNcu0ITiuWDYU9ur57Oa4LybD5DOQp4f22T6zLfpoBMfBibPtR8XktXmOyFHrL/6FC2p9ojdLZhWhvBHg==} + /@next/swc-darwin-arm64/13.0.3: + resolution: {integrity: sha512-wV6j6SZ1bc/YHOLCLk9JVqaZTCCey6HBV7inl2DriHsHqIcO6F3+QiYf0KXwRP9BE0GSZZrYd5mZQm2JPTHdJA==} engines: {node: '>= 10'} cpu: [arm64] os: [darwin] @@ -932,8 +939,8 @@ packages: dev: false optional: true - /@next/swc-darwin-x64/12.3.1: - resolution: {integrity: sha512-9S6EVueCVCyGf2vuiLiGEHZCJcPAxglyckTZcEwLdJwozLqN0gtS0Eq0bQlGS3dH49Py/rQYpZ3KVWZ9BUf/WA==} + /@next/swc-darwin-x64/13.0.3: + resolution: {integrity: sha512-jaI2CMuYWvUtRixV3AIjUhnxUDU1FKOR+8hADMhYt3Yz+pCKuj4RZ0n0nY5qUf3qT1AtvnJXEgyatSFJhSp/wQ==} engines: {node: '>= 10'} cpu: [x64] os: [darwin] @@ -941,8 +948,8 @@ packages: dev: false optional: true - /@next/swc-freebsd-x64/12.3.1: - resolution: {integrity: sha512-qcuUQkaBZWqzM0F1N4AkAh88lLzzpfE6ImOcI1P6YeyJSsBmpBIV8o70zV+Wxpc26yV9vpzb+e5gCyxNjKJg5Q==} + /@next/swc-freebsd-x64/13.0.3: + resolution: {integrity: sha512-nbyT0toBTJrcj5TCB9pVnQpGJ3utGyQj4CWegZs1ulaeUQ5Z7CS/qt8nRyYyOKYHtOdSCJ9Nw5F/RgKNkdpOdw==} engines: {node: '>= 10'} cpu: [x64] os: [freebsd] @@ -950,8 +957,8 @@ packages: dev: false optional: true - /@next/swc-linux-arm-gnueabihf/12.3.1: - resolution: {integrity: sha512-diL9MSYrEI5nY2wc/h/DBewEDUzr/DqBjIgHJ3RUNtETAOB3spMNHvJk2XKUDjnQuluLmFMloet9tpEqU2TT9w==} + /@next/swc-linux-arm-gnueabihf/13.0.3: + resolution: {integrity: sha512-1naLxYvRUQCoFCU1nMkcQueRc0Iux9xBv1L5pzH2ejtIWFg8BrSgyuluJG4nyAhFCx4WG863IEIkAaefOowVdA==} engines: {node: '>= 10'} cpu: [arm] os: [linux] @@ -959,8 +966,8 @@ packages: dev: false optional: true - /@next/swc-linux-arm64-gnu/12.3.1: - resolution: {integrity: sha512-o/xB2nztoaC7jnXU3Q36vGgOolJpsGG8ETNjxM1VAPxRwM7FyGCPHOMk1XavG88QZSQf+1r+POBW0tLxQOJ9DQ==} + /@next/swc-linux-arm64-gnu/13.0.3: + resolution: {integrity: sha512-3Z4A8JkuGWpMVbUhUPQInK/SLY+kijTT78Q/NZCrhLlyvwrVxaQALJNlXzxDLraUgv4oVH0Wz/FIw1W9PUUhxA==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] @@ -968,8 +975,8 @@ packages: dev: false optional: true - /@next/swc-linux-arm64-musl/12.3.1: - resolution: {integrity: sha512-2WEasRxJzgAmP43glFNhADpe8zB7kJofhEAVNbDJZANp+H4+wq+/cW1CdDi8DqjkShPEA6/ejJw+xnEyDID2jg==} + /@next/swc-linux-arm64-musl/13.0.3: + resolution: {integrity: sha512-MoYe9SM40UaunTjC+01c9OILLH3uSoeri58kDMu3KF/EFEvn1LZ6ODeDj+SLGlAc95wn46hrRJS2BPmDDE+jFQ==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] @@ -977,8 +984,8 @@ packages: dev: false optional: true - /@next/swc-linux-x64-gnu/12.3.1: - resolution: {integrity: sha512-JWEaMyvNrXuM3dyy9Pp5cFPuSSvG82+yABqsWugjWlvfmnlnx9HOQZY23bFq3cNghy5V/t0iPb6cffzRWylgsA==} + /@next/swc-linux-x64-gnu/13.0.3: + resolution: {integrity: sha512-z22T5WGnRanjLMXdF0NaNjSpBlEzzY43t5Ysp3nW1oI6gOkub6WdQNZeHIY7A2JwkgSWZmtjLtf+Fzzz38LHeQ==} engines: {node: '>= 10'} cpu: [x64] os: [linux] @@ -986,8 +993,8 @@ packages: dev: false optional: true - /@next/swc-linux-x64-musl/12.3.1: - resolution: {integrity: sha512-xoEWQQ71waWc4BZcOjmatuvPUXKTv6MbIFzpm4LFeCHsg2iwai0ILmNXf81rJR+L1Wb9ifEke2sQpZSPNz1Iyg==} + /@next/swc-linux-x64-musl/13.0.3: + resolution: {integrity: sha512-ZOMT7zjBFmkusAtr47k8xs/oTLsNlTH6xvYb+iux7yly2hZGwhfBLzPGBsbeMZukZ96IphJTagT+C033s6LNVA==} engines: {node: '>= 10'} cpu: [x64] os: [linux] @@ -995,8 +1002,8 @@ packages: dev: false optional: true - /@next/swc-win32-arm64-msvc/12.3.1: - resolution: {integrity: sha512-hswVFYQYIeGHE2JYaBVtvqmBQ1CppplQbZJS/JgrVI3x2CurNhEkmds/yqvDONfwfbttTtH4+q9Dzf/WVl3Opw==} + /@next/swc-win32-arm64-msvc/13.0.3: + resolution: {integrity: sha512-Q4BM16Djl+Oah9UdGrvjFYgoftYB2jNd+rtRGPX5Mmxo09Ry/KiLbOZnoUyoIxKc1xPyfqMXuaVsAFQLYs0KEQ==} engines: {node: '>= 10'} cpu: [arm64] os: [win32] @@ -1004,8 +1011,8 @@ packages: dev: false optional: true - /@next/swc-win32-ia32-msvc/12.3.1: - resolution: {integrity: sha512-Kny5JBehkTbKPmqulr5i+iKntO5YMP+bVM8Hf8UAmjSMVo3wehyLVc9IZkNmcbxi+vwETnQvJaT5ynYBkJ9dWA==} + /@next/swc-win32-ia32-msvc/13.0.3: + resolution: {integrity: sha512-Sa8yGkNeRUsic8Qjf7MLIAfP0p0+einK/wIqJ8UO1y76j+8rRQu42AMs5H4Ax1fm9GEYq6I8njHtY59TVpTtGQ==} engines: {node: '>= 10'} cpu: [ia32] os: [win32] @@ -1013,8 +1020,8 @@ packages: dev: false optional: true - /@next/swc-win32-x64-msvc/12.3.1: - resolution: {integrity: sha512-W1ijvzzg+kPEX6LAc+50EYYSEo0FVu7dmTE+t+DM4iOLqgGHoW9uYSz9wCVdkXOEEMP9xhXfGpcSxsfDucyPkA==} + /@next/swc-win32-x64-msvc/13.0.3: + resolution: {integrity: sha512-IAptmSqA7k4tQzaw2NAkoEjj3+Dz9ceuvlEHwYh770MMDL4V0ku2m+UHrmn5HUCEDHhgwwjg2nyf6728q2jr1w==} engines: {node: '>= 10'} cpu: [x64] os: [win32] @@ -1090,15 +1097,14 @@ packages: - supports-color dev: true - /@sentry/cli/2.8.1: - resolution: {integrity: sha512-V/Mzy/ooZaICBFC8OvSrhUg3Anw1vlEzQQKwUtXEH0EQmcKDJMGkgfo2hXlpoR6lybODjkXDlMkajKcspdF4RA==} - engines: {node: '>= 12'} + /@sentry/cli/2.9.0: + resolution: {integrity: sha512-0qq3aP5shbm/V5GQSyeGEXlDNPQlWKngwNu+h5zaaaDrCfG2gJeoRHybOq4of+raKFZTvx4kjVmwwWAUvHfTYg==} + engines: {node: '>= 10'} hasBin: true requiresBuild: true dependencies: https-proxy-agent: 5.0.1 node-fetch: 2.6.7 - npmlog: 6.0.2 progress: 2.0.3 proxy-from-env: 1.1.0 which: 2.0.2 @@ -1179,11 +1185,11 @@ packages: /@types/chai-subset/1.3.3: resolution: {integrity: sha512-frBecisrNGz+F4T6bcc+NLeolfiojh5FxW2klu669+8BARtyQv2C/GkNW6FUodVe4BroGMP/wER/YDGc7rEllw==} dependencies: - '@types/chai': 4.3.3 + '@types/chai': 4.3.4 dev: true - /@types/chai/4.3.3: - resolution: {integrity: sha512-hC7OMnszpxhZPduX+m+nrx+uFoLkWOMiR4oa/AZF3MuSETYTZmFfJAHqZEM8MVlvfG7BEUcgvtwoCTxBp6hm3g==} + /@types/chai/4.3.4: + resolution: {integrity: sha512-KnRanxnpfpjUTqTCXslZSEdLfXExwgNxYPdiO2WGUj8+HDjFi8R3k5RVKPeSCzLjCcshCAtVO2QBbVuAV4kTnw==} dev: true /@types/cookie/0.5.0: @@ -1194,8 +1200,8 @@ packages: resolution: {integrity: sha512-qGYApbb0m8Ofy3pwYks+kYVIZQAN/cqNucJGbl5O5GpLw9JSzp74rkTWDhPv3brrJfJb5/ixtimLJpo4tfh2QA==} dev: true - /@types/inquirer/9.0.2: - resolution: {integrity: sha512-MQc3adiIh/rDxLkjnvL03rSvuHg+/dKif4dn/MRsnE+oU1bAdyuDbW0w+ewR1M/M/u/Z0YAbw7NZYCpgQ5SW8A==} + /@types/inquirer/9.0.3: + resolution: {integrity: sha512-CzNkWqQftcmk2jaCWdBTf9Sm7xSw4rkI1zpU/Udw3HX5//adEZUIm9STtoRP1qgWj0CWQtJ9UTvqmO2NNjhMJw==} dependencies: '@types/through': 0.0.30 rxjs: 7.5.7 @@ -1234,8 +1240,8 @@ packages: '@types/node': 18.11.9 dev: true - /@types/react/18.0.24: - resolution: {integrity: sha512-wRJWT6ouziGUy+9uX0aW4YOJxAY0bG6/AOk5AW5QSvZqI7dk6VBIbXvcVgIw/W5Jrl24f77df98GEKTJGOLx7Q==} + /@types/react/18.0.25: + resolution: {integrity: sha512-xD6c0KDT4m7n9uD4ZHi02lzskaiqcBxf4zi+tXZY98a04wvc0hi/TcCPC2FOESZi51Nd7tlUeOJY8RofL799/g==} dependencies: '@types/prop-types': 15.7.5 '@types/scheduler': 0.16.2 @@ -1268,7 +1274,6 @@ packages: resolution: {integrity: sha512-6YOoWjruKj1uLf3INHH7D3qTXwFfEsg1kf3c0uDdSBJwfa/llkwIjrAGV7j7mVgGNbzTQ3HiHKKDXl6bJPD97w==} dependencies: '@types/node': 18.11.9 - dev: false /@types/yargs-parser/21.0.0: resolution: {integrity: sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==} @@ -1280,8 +1285,8 @@ packages: '@types/yargs-parser': 21.0.0 dev: true - /@typescript-eslint/eslint-plugin/5.42.0_6xw5wg2354iw4zujk2f3vyfrzu: - resolution: {integrity: sha512-5TJh2AgL6+wpL8H/GTSjNb4WrjKoR2rqvFxR/DDTqYNk6uXn8BJMEcncLSpMbf/XV1aS0jAjYwn98uvVCiAywQ==} + /@typescript-eslint/eslint-plugin/5.43.0_yy4vf4gcvxiubmg7fqa55dqe2i: + resolution: {integrity: sha512-wNPzG+eDR6+hhW4yobEmpR36jrqqQv1vxBq5LJO3fBAktjkvekfr4BRl+3Fn1CM/A+s8/EiGUbOMDoYqWdbtXA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: '@typescript-eslint/parser': ^5.0.0 @@ -1291,12 +1296,12 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/parser': 5.42.0_wyqvi574yv7oiwfeinomdzmc3m - '@typescript-eslint/scope-manager': 5.42.0 - '@typescript-eslint/type-utils': 5.42.0_wyqvi574yv7oiwfeinomdzmc3m - '@typescript-eslint/utils': 5.42.0_wyqvi574yv7oiwfeinomdzmc3m + '@typescript-eslint/parser': 5.43.0_rmayb2veg2btbq6mbmnyivgasy + '@typescript-eslint/scope-manager': 5.43.0 + '@typescript-eslint/type-utils': 5.43.0_rmayb2veg2btbq6mbmnyivgasy + '@typescript-eslint/utils': 5.43.0_rmayb2veg2btbq6mbmnyivgasy debug: 4.3.4 - eslint: 8.26.0 + eslint: 8.27.0 ignore: 5.2.0 natural-compare-lite: 1.4.0 regexpp: 3.2.0 @@ -1307,21 +1312,21 @@ packages: - supports-color dev: true - /@typescript-eslint/experimental-utils/5.42.0_wyqvi574yv7oiwfeinomdzmc3m: - resolution: {integrity: sha512-B51HySW9wWIwLantEMqJi0FXVp1IMKRAyNASrYhJV3/nl4r6aEz6FJTJtscgu7YrGWigs7OypQExmcVqGQoDFQ==} + /@typescript-eslint/experimental-utils/5.43.0_rmayb2veg2btbq6mbmnyivgasy: + resolution: {integrity: sha512-WkT637CumTJbm/hRbFfnHBMgfUYTKr08LitVsD7gQId7bi6rnkx3pu3jac67lmp5ObW4MpJ9SNFZAIOUB/Qbsw==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 dependencies: - '@typescript-eslint/utils': 5.42.0_wyqvi574yv7oiwfeinomdzmc3m - eslint: 8.26.0 + '@typescript-eslint/utils': 5.43.0_rmayb2veg2btbq6mbmnyivgasy + eslint: 8.27.0 transitivePeerDependencies: - supports-color - typescript dev: true - /@typescript-eslint/parser/5.42.0_wyqvi574yv7oiwfeinomdzmc3m: - resolution: {integrity: sha512-Ixh9qrOTDRctFg3yIwrLkgf33AHyEIn6lhyf5cCfwwiGtkWhNpVKlEZApi3inGQR/barWnY7qY8FbGKBO7p3JA==} + /@typescript-eslint/parser/5.43.0_rmayb2veg2btbq6mbmnyivgasy: + resolution: {integrity: sha512-2iHUK2Lh7PwNUlhFxxLI2haSDNyXvebBO9izhjhMoDC+S3XI9qt2DGFUsiJ89m2k7gGYch2aEpYqV5F/+nwZug==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 @@ -1330,26 +1335,26 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/scope-manager': 5.42.0 - '@typescript-eslint/types': 5.42.0 - '@typescript-eslint/typescript-estree': 5.42.0_typescript@4.8.4 + '@typescript-eslint/scope-manager': 5.43.0 + '@typescript-eslint/types': 5.43.0 + '@typescript-eslint/typescript-estree': 5.43.0_typescript@4.8.4 debug: 4.3.4 - eslint: 8.26.0 + eslint: 8.27.0 typescript: 4.8.4 transitivePeerDependencies: - supports-color dev: true - /@typescript-eslint/scope-manager/5.42.0: - resolution: {integrity: sha512-l5/3IBHLH0Bv04y+H+zlcLiEMEMjWGaCX6WyHE5Uk2YkSGAMlgdUPsT/ywTSKgu9D1dmmKMYgYZijObfA39Wow==} + /@typescript-eslint/scope-manager/5.43.0: + resolution: {integrity: sha512-XNWnGaqAtTJsUiZaoiGIrdJYHsUOd3BZ3Qj5zKp9w6km6HsrjPk/TGZv0qMTWyWj0+1QOqpHQ2gZOLXaGA9Ekw==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dependencies: - '@typescript-eslint/types': 5.42.0 - '@typescript-eslint/visitor-keys': 5.42.0 + '@typescript-eslint/types': 5.43.0 + '@typescript-eslint/visitor-keys': 5.43.0 dev: true - /@typescript-eslint/type-utils/5.42.0_wyqvi574yv7oiwfeinomdzmc3m: - resolution: {integrity: sha512-HW14TXC45dFVZxnVW8rnUGnvYyRC0E/vxXShFCthcC9VhVTmjqOmtqj6H5rm9Zxv+ORxKA/1aLGD7vmlLsdlOg==} + /@typescript-eslint/type-utils/5.43.0_rmayb2veg2btbq6mbmnyivgasy: + resolution: {integrity: sha512-K21f+KY2/VvYggLf5Pk4tgBOPs2otTaIHy2zjclo7UZGLyFH86VfUOm5iq+OtDtxq/Zwu2I3ujDBykVW4Xtmtg==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: eslint: '*' @@ -1358,23 +1363,23 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/typescript-estree': 5.42.0_typescript@4.8.4 - '@typescript-eslint/utils': 5.42.0_wyqvi574yv7oiwfeinomdzmc3m + '@typescript-eslint/typescript-estree': 5.43.0_typescript@4.8.4 + '@typescript-eslint/utils': 5.43.0_rmayb2veg2btbq6mbmnyivgasy debug: 4.3.4 - eslint: 8.26.0 + eslint: 8.27.0 tsutils: 3.21.0_typescript@4.8.4 typescript: 4.8.4 transitivePeerDependencies: - supports-color dev: true - /@typescript-eslint/types/5.42.0: - resolution: {integrity: sha512-t4lzO9ZOAUcHY6bXQYRuu+3SSYdD9TS8ooApZft4WARt4/f2Cj/YpvbTe8A4GuhT4bNW72goDMOy7SW71mZwGw==} + /@typescript-eslint/types/5.43.0: + resolution: {integrity: sha512-jpsbcD0x6AUvV7tyOlyvon0aUsQpF8W+7TpJntfCUWU1qaIKu2K34pMwQKSzQH8ORgUrGYY6pVIh1Pi8TNeteg==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dev: true - /@typescript-eslint/typescript-estree/5.42.0_typescript@4.8.4: - resolution: {integrity: sha512-2O3vSq794x3kZGtV7i4SCWZWCwjEtkWfVqX4m5fbUBomOsEOyd6OAD1qU2lbvV5S8tgy/luJnOYluNyYVeOTTg==} + /@typescript-eslint/typescript-estree/5.43.0_typescript@4.8.4: + resolution: {integrity: sha512-BZ1WVe+QQ+igWal2tDbNg1j2HWUkAa+CVqdU79L4HP9izQY6CNhXfkNwd1SS4+sSZAP/EthI1uiCSY/+H0pROg==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: typescript: '*' @@ -1382,8 +1387,8 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/types': 5.42.0 - '@typescript-eslint/visitor-keys': 5.42.0 + '@typescript-eslint/types': 5.43.0 + '@typescript-eslint/visitor-keys': 5.43.0 debug: 4.3.4 globby: 11.1.0 is-glob: 4.0.3 @@ -1394,93 +1399,93 @@ packages: - supports-color dev: true - /@typescript-eslint/utils/5.42.0_wyqvi574yv7oiwfeinomdzmc3m: - resolution: {integrity: sha512-JZ++3+h1vbeG1NUECXQZE3hg0kias9kOtcQr3+JVQ3whnjvKuMyktJAAIj6743OeNPnGBmjj7KEmiDL7qsdnCQ==} + /@typescript-eslint/utils/5.43.0_rmayb2veg2btbq6mbmnyivgasy: + resolution: {integrity: sha512-8nVpA6yX0sCjf7v/NDfeaOlyaIIqL7OaIGOWSPFqUKK59Gnumd3Wa+2l8oAaYO2lk0sO+SbWFWRSvhu8gLGv4A==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 dependencies: '@types/json-schema': 7.0.11 '@types/semver': 7.3.13 - '@typescript-eslint/scope-manager': 5.42.0 - '@typescript-eslint/types': 5.42.0 - '@typescript-eslint/typescript-estree': 5.42.0_typescript@4.8.4 - eslint: 8.26.0 + '@typescript-eslint/scope-manager': 5.43.0 + '@typescript-eslint/types': 5.43.0 + '@typescript-eslint/typescript-estree': 5.43.0_typescript@4.8.4 + eslint: 8.27.0 eslint-scope: 5.1.1 - eslint-utils: 3.0.0_eslint@8.26.0 + eslint-utils: 3.0.0_eslint@8.27.0 semver: 7.3.8 transitivePeerDependencies: - supports-color - typescript dev: true - /@typescript-eslint/visitor-keys/5.42.0: - resolution: {integrity: sha512-QHbu5Hf/2lOEOwy+IUw0GoSCuAzByTAWWrOTKzTzsotiUnWFpuKnXcAhC9YztAf2EElQ0VvIK+pHJUPkM0q7jg==} + /@typescript-eslint/visitor-keys/5.43.0: + resolution: {integrity: sha512-icl1jNH/d18OVHLfcwdL3bWUKsBeIiKYTGxMJCoGe7xFht+E4QgzOqoWYrU8XSLJWhVw8nTacbm03v23J/hFTg==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dependencies: - '@typescript-eslint/types': 5.42.0 + '@typescript-eslint/types': 5.43.0 eslint-visitor-keys: 3.3.0 dev: true - /@ucanto/client/3.0.1: - resolution: {integrity: sha512-rK0M3kqLHlvLTp6P9jyqjSOdzGbulawxzfFOh0cV4D6FLLjpHwNq5NpXZ7n6AbQ7H1EQeWla/gNgLKVGWXKrMQ==} + /@ucanto/client/3.0.2: + resolution: {integrity: sha512-viYv/fLPvH/POFIfVoIaK4B8KSYIBLNZeVFCdnhSbS4/m6t3h4G0Z7GMjNyP1mZG/CGjAOmHxeNvMUr0sNCyVQ==} dependencies: - '@ucanto/interface': 3.0.0 + '@ucanto/interface': 3.0.1 multiformats: 10.0.2 dev: false - /@ucanto/core/3.0.1: - resolution: {integrity: sha512-DoCIfczxo6bikOUFA/5RS6QTC52Xz2Dfija5rsWmRj+vP8LIvuuuNhHZbgDEmXtSRVyvoVQeAxxxHmWWrVtoAQ==} + /@ucanto/core/3.0.2: + resolution: {integrity: sha512-TEVCqAM/3v4fXLuZcIBgQZrPwD53yqoXqwmSChhd420FikFGkkAeWvj6JT6oR4VmCuiIPK5FnukaE2LL5h0Ekg==} dependencies: - '@ipld/car': 5.0.0 + '@ipld/car': 5.0.1 '@ipld/dag-cbor': 8.0.0 '@ipld/dag-ucan': 2.0.1 - '@ucanto/interface': 3.0.0 + '@ucanto/interface': 3.0.1 multiformats: 10.0.2 dev: false - /@ucanto/interface/3.0.0: - resolution: {integrity: sha512-CZ+wPD9Zxv3UL/0s3+d1Zf0LPktbkMLGtpdt08+/gKLVU95qxvHzEcpBp9toDYvbKNYBIKQtEc2VbOvwUlMLZA==} + /@ucanto/interface/3.0.1: + resolution: {integrity: sha512-1UlyLMjJwgzAmhlqu/V1gz0xrE9MUiI3gdzxOJbIXwrS7zAWsbtUZqIS/SPpr1+PYnNO8PHSGyGekb+N0dqtWQ==} dependencies: '@ipld/dag-ucan': 2.0.1 multiformats: 10.0.2 dev: false - /@ucanto/principal/3.0.0: - resolution: {integrity: sha512-7CwVbYQc+CdWta+lNuI6vRjVT+GkPwf2VQVXFBm8i4fQomFOTmOq8I/Be3TBS9N2OaIbL7b/eKy1WBdMMzfz5g==} + /@ucanto/principal/3.0.1: + resolution: {integrity: sha512-0U0EF2ddfR55LKKc7FkzTkH8OFvjZvEeRqMkyV5FyeSsFEF7lXhgEXZrNgggK2zlriXjYC9VVCpPhsGb4cI72g==} dependencies: '@ipld/dag-ucan': 2.0.1 '@noble/ed25519': 1.7.1 - '@ucanto/interface': 3.0.0 + '@ucanto/interface': 3.0.1 multiformats: 10.0.2 one-webcrypto: 1.0.3 dev: false - /@ucanto/server/3.0.1: - resolution: {integrity: sha512-PMBb9gPk+5+qKl7bANusPq9xCm2S0dVNIT33EmmtNhXWQSj8nLvWLInnxXYGc+ziyQonPZtDPgKi02uREFEdXw==} + /@ucanto/server/3.0.4: + resolution: {integrity: sha512-4a5ou5HZ8ymw39EeZ0024nu0JD916xTMpYsS4eXMxpnoWlOjgmoeWZ5e01dEiw5AlfnSa8e9+a0b1dzvSISQxQ==} dependencies: - '@ucanto/core': 3.0.1 - '@ucanto/interface': 3.0.0 - '@ucanto/validator': 3.0.1 + '@ucanto/core': 3.0.2 + '@ucanto/interface': 3.0.1 + '@ucanto/validator': 3.0.4 dev: false - /@ucanto/transport/3.0.1: - resolution: {integrity: sha512-stUryA8e6Npkt8RVcxko61gE11+c2Gta+eGzv1XOrWGCk5WqdzequWs/zLxgHxq52EqCWZhLYKQpY5nkrz5UAA==} + /@ucanto/transport/3.0.2: + resolution: {integrity: sha512-IyfI26VWPxCL2jnGiGP1i6mZblk8QORHzEVt5t+7Pic2k7pANQHoqbveQveRb9a8z6D/UdFogSPQxWYYtKaxWQ==} dependencies: - '@ipld/car': 5.0.0 + '@ipld/car': 5.0.1 '@ipld/dag-cbor': 8.0.0 - '@ucanto/core': 3.0.1 - '@ucanto/interface': 3.0.0 + '@ucanto/core': 3.0.2 + '@ucanto/interface': 3.0.1 multiformats: 10.0.2 dev: false - /@ucanto/validator/3.0.1: - resolution: {integrity: sha512-LVirhuwMPOwATIDwlhGZt7C1BtrKp2+HJ7pALQcbC4+eHYyminniZEAzYjf0/EnjXtDj0SL3jnnBBvmpIJiWDQ==} + /@ucanto/validator/3.0.4: + resolution: {integrity: sha512-JG6y6yWPDUBoJuWP7auwMTZf9SJN9d2e7y/ZbVvluQBZC+WvhLq1Z2cjWCjA21Y2FJxWeI27leBjWzyIsHtYUA==} dependencies: - '@ipld/car': 5.0.0 + '@ipld/car': 5.0.1 '@ipld/dag-cbor': 8.0.0 - '@ucanto/core': 3.0.1 - '@ucanto/interface': 3.0.0 + '@ucanto/core': 3.0.2 + '@ucanto/interface': 3.0.1 multiformats: 10.0.2 dev: false @@ -1602,7 +1607,7 @@ packages: ajv: optional: true dependencies: - ajv: 8.11.0 + ajv: 8.11.2 dev: false /ajv/6.12.6: @@ -1614,8 +1619,8 @@ packages: uri-js: 4.4.1 dev: true - /ajv/8.11.0: - resolution: {integrity: sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==} + /ajv/8.11.2: + resolution: {integrity: sha512-E4bfmKAhGiSTvMfL1Myyycaub+cUEU2/IvpylXkUu7CHBkBj1f/ikdzbD7YQ6FKUbixDxeYvB/xY4fvyroDlQg==} dependencies: fast-deep-equal: 3.1.3 json-schema-traverse: 1.0.0 @@ -1639,7 +1644,7 @@ packages: resolution: {integrity: sha512-IG23inYII3dWlU2EyiAiGj6Bwal5GzsgPMwjYGvc1HPE2dgbj4ZB5ToWBKSquKw74nB3TIuOwaI6/jSULzfgrw==} engines: {node: '>=14.16'} dependencies: - type-fest: 3.1.0 + type-fest: 3.2.0 dev: false /ansi-regex/2.1.1: @@ -1684,10 +1689,6 @@ packages: resolution: {integrity: sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==} dev: true - /aproba/2.0.0: - resolution: {integrity: sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==} - dev: true - /are-we-there-yet/1.1.7: resolution: {integrity: sha512-nxwy40TuMiUGqMyRHgCSWZ9FM4VAoRP4xUYSTv5ImRog+h9yISPbVH7H8fASCIzYn9wlEv4zvFL7uKDMCFQm3g==} dependencies: @@ -1695,14 +1696,6 @@ packages: readable-stream: 2.3.7 dev: true - /are-we-there-yet/3.0.1: - resolution: {integrity: sha512-QZW4EDmGwlYur0Yyf/b2uGucHQMa8aFUP7eu9ddR73vvhFyt4V0Vl3QHPcTNJ8l6qYOBdxgXdnBXQrHilfRQBg==} - engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} - dependencies: - delegates: 1.0.0 - readable-stream: 3.6.0 - dev: true - /argparse/1.0.10: resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==} dependencies: @@ -1726,8 +1719,8 @@ packages: engines: {node: '>=0.10.0'} dev: true - /array-includes/3.1.5: - resolution: {integrity: sha512-iSDYZMMyTPkiFasVqfuAQnWAYcvO/SeBSCGKePoEthjp4LEMTe4uLc7b025o4jAZpHhihh8xPo99TNWUWWkGDQ==} + /array-includes/3.1.6: + resolution: {integrity: sha512-sgTbLvL6cNnw24FnbaDyjmvddQ2ML8arZsgaJhoABMoplz/4QRhtrYS+alr1BUM1Bwp6dhx8vVCBSLG+StwOFw==} engines: {node: '>= 0.4'} dependencies: call-bind: 1.0.2 @@ -1809,8 +1802,8 @@ packages: engines: {node: '>=10.12.0'} dev: false - /ava/5.0.1: - resolution: {integrity: sha512-nS1eK3HhWaC+eGHtteF5j4yZMjaIE+q2o+oyqD75xsmS87R5sGlxADYWkFIGyB28jrDmAATZAAx+s3JhYsnhNw==} + /ava/5.1.0: + resolution: {integrity: sha512-e5VFrSQ0WBPyZJWRXVrO7RFOizFeNM0t2PORwrPvWtApgkORI6cvGnY3GX1G+lzpd0HjqNx5Jus22AhxVnUMNA==} engines: {node: '>=14.19 <15 || >=16.15 <17 || >=18'} hasBin: true peerDependencies: @@ -1829,7 +1822,7 @@ packages: chalk: 5.1.2 chokidar: 3.5.3 chunkd: 2.0.1 - ci-info: 3.5.0 + ci-info: 3.6.1 ci-parallel-vars: 1.0.1 clean-yaml-object: 0.1.0 cli-truncate: 3.1.0 @@ -1839,7 +1832,7 @@ packages: currently-unhandled: 0.4.1 debug: 4.3.4 del: 7.0.0 - emittery: 1.0.0 + emittery: 1.0.1 figures: 5.0.0 globby: 13.1.2 ignore-by-default: 2.1.0 @@ -1858,11 +1851,11 @@ packages: pretty-ms: 8.0.0 resolve-cwd: 3.0.0 slash: 3.0.0 - stack-utils: 2.0.5 + stack-utils: 2.0.6 strip-ansi: 7.0.1 supertap: 3.0.1 - temp-dir: 2.0.0 - write-file-atomic: 4.0.2 + temp-dir: 3.0.0 + write-file-atomic: 5.0.0 yargs: 17.6.2 transitivePeerDependencies: - supports-color @@ -1872,8 +1865,8 @@ packages: resolution: {integrity: sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==} engines: {node: '>= 0.4'} - /axe-core/4.5.1: - resolution: {integrity: sha512-1exVbW0X1O/HSr/WMwnaweyqcWOgZgLiVxdLG34pvSQk4NlYQr9OUy0JLwuhFfuVNQzzqgH57eYzkFBCb3bIsQ==} + /axe-core/4.5.2: + resolution: {integrity: sha512-u2MVsXfew5HBvjsczCv+xlwdNnB1oQR9HlAcsejZttNjKKSkeDNVwB1vMThIUIFI9GoT57Vtk8iQLwqOfAkboA==} engines: {node: '>=4'} dev: true @@ -1883,7 +1876,6 @@ packages: /balanced-match/1.0.2: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} - dev: true /base64-js/1.5.1: resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} @@ -1946,7 +1938,6 @@ packages: resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} dependencies: balanced-match: 1.0.2 - dev: true /braces/3.0.2: resolution: {integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==} @@ -1992,6 +1983,7 @@ packages: engines: {node: '>=10.16.0'} dependencies: streamsearch: 1.1.0 + dev: true /call-bind/1.0.2: resolution: {integrity: sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==} @@ -2019,8 +2011,8 @@ packages: engines: {node: '>=10'} dev: true - /caniuse-lite/1.0.30001429: - resolution: {integrity: sha512-511ThLu1hF+5RRRt0zYCf2U2yRr9GPF6m5y90SBCWsvSoYoW7yAGlv/elyPaNfvGCkp6kj/KFZWU0BMA69Prsg==} + /caniuse-lite/1.0.30001431: + resolution: {integrity: sha512-zBUoFU0ZcxpvSt9IU66dXVT/3ctO1cy4y9cscs1szkPlcWb6pasYM144GqrUygUbT+k7cmUCW61cvskjcv0enQ==} dev: false /cbor/8.1.0: @@ -2030,8 +2022,8 @@ packages: nofilter: 3.1.0 dev: true - /cborg/1.9.5: - resolution: {integrity: sha512-fLBv8wmqtlXqy1Yu+pHzevAIkW6k2K0ZtMujNzWphLsA34vzzg9BHn+5GmZqOJkSA9V7EMKsWrf6K976c1QMjQ==} + /cborg/1.9.6: + resolution: {integrity: sha512-XmiD+NWTk9xg31d8MdXgW46bSZd95ELllxjbjdWGyHAtpTw+cf8iG3NibWgTWRnfWfxtcihVa5Pm0gchHiO3JQ==} hasBin: true dev: false @@ -2040,15 +2032,15 @@ packages: engines: {node: '>=4'} dev: true - /chai/4.3.6: - resolution: {integrity: sha512-bbcp3YfHCUzMOvKqsztczerVgBKSsEijCySNlHHbX3VG1nskvqjz5Rfso1gGwD6w6oOV3eI60pKuMOV5MV7p3Q==} + /chai/4.3.7: + resolution: {integrity: sha512-HLnAzZ2iupm25PlN0xFreAlBA5zaBSv3og0DdeGA4Ar6h6rJ3A0rolRUKJhSF2V10GZKDgWF/VmAEsNWjCRB+A==} engines: {node: '>=4'} dependencies: assertion-error: 1.1.0 check-error: 1.0.2 - deep-eql: 3.0.1 + deep-eql: 4.1.2 get-func-name: 2.0.0 - loupe: 2.3.4 + loupe: 2.3.6 pathval: 1.1.1 type-detect: 4.0.8 dev: true @@ -2105,8 +2097,9 @@ packages: resolution: {integrity: sha512-7d58XsFmOq0j6el67Ug9mHf9ELUXsQXYJBkyxhH/k+6Ke0qXRnv0kbemx+Twc6fRJ07C49lcbdgm9FL1Ei/6SQ==} dev: true - /ci-info/3.5.0: - resolution: {integrity: sha512-yH4RezKOGlOhxkmhbeNuC4eYZKAUsEaGtBuBzDDP1eFUKiccDWzBABxBfOx31IDwDIXMTxWuwAxUGModvkbuVw==} + /ci-info/3.6.1: + resolution: {integrity: sha512-up5ggbaDqOqJ4UqLKZ2naVkyqSJQgJi5lwD6b6mM748ysrghDBX0bx/qJTUHzw7zu6Mq4gycviSF5hJnwceD8w==} + engines: {node: '>=8'} dev: true /ci-parallel-vars/1.0.1: @@ -2175,6 +2168,10 @@ packages: engines: {node: '>= 12'} dev: false + /client-only/0.0.1: + resolution: {integrity: sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==} + dev: false + /cliui/6.0.0: resolution: {integrity: sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==} dependencies: @@ -2235,11 +2232,6 @@ packages: /color-name/1.1.4: resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} - /color-support/1.1.3: - resolution: {integrity: sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==} - hasBin: true - dev: true - /colorette/2.0.19: resolution: {integrity: sha512-3tlv/dIP7FWvj3BsbHrGLJ6l/oKh1O3TcgBqMn+yyCagOxc23fyzDS6HypQbgxWbkpDnf52p1LuR4eWDQ/K9WQ==} dev: true @@ -2280,7 +2272,7 @@ packages: resolution: {integrity: sha512-8fLl9F04EJqjSqH+QjITQfJF8BrOVaYr1jewVgSRAEWePfxT0sku4w2hrGQ60BC/TNLGQ2pgxNlTbWQmMPFvXg==} engines: {node: '>=12'} dependencies: - ajv: 8.11.0 + ajv: 8.11.2 ajv-formats: 2.1.1 atomically: 1.7.0 debounce-fn: 4.0.0 @@ -2315,8 +2307,8 @@ packages: engines: {node: '>= 0.6'} dev: false - /core-js-pure/3.26.0: - resolution: {integrity: sha512-LiN6fylpVBVwT8twhhluD9TzXmZQQsr2I2eIKtWNbZI1XMfBT7CV18itaN6RA7EtQd/SDdRx/wzvAShX2HvhQA==} + /core-js-pure/3.26.1: + resolution: {integrity: sha512-VVXcDpp/xJ21KdULRq/lXdLzQAtX7+37LzpyfFM973il0tWSsDEoyzG38G14AjTpK9VTfiNM9jnFauq/CpaWGQ==} requiresBuild: true dev: true @@ -2466,9 +2458,9 @@ packages: mimic-response: 3.1.0 dev: true - /deep-eql/3.0.1: - resolution: {integrity: sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==} - engines: {node: '>=0.12'} + /deep-eql/4.1.2: + resolution: {integrity: sha512-gT18+YW4CcW/DBNTwAmqTtkJh7f9qqScu2qFVlx7kCoeY9tlBu9cUcr7+I+Z/noG8INehS3xQgLpTtd/QUTn4w==} + engines: {node: '>=6'} dependencies: type-detect: 4.0.8 dev: true @@ -2604,8 +2596,8 @@ packages: /eastasianwidth/0.2.0: resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} - /emittery/1.0.0: - resolution: {integrity: sha512-TD/u5aAn5W2HI2OukSIReNYXf/cH7U0QZHPxM4aIVYy0CmtrLCvf+7E8MuV2BbO02l6wq4sAKuFA8H16l6AHMA==} + /emittery/1.0.1: + resolution: {integrity: sha512-2ID6FdrMD9KDLldGesP6317G78K7km/kMcwItRtVFva7I/cSEOIaLpewaUb+YLXVwdAp3Ctfxh/V5zIl1sj7dQ==} engines: {node: '>=14.16'} dev: true @@ -2667,8 +2659,8 @@ packages: object.assign: 4.1.4 regexp.prototype.flags: 1.4.3 safe-regex-test: 1.0.0 - string.prototype.trimend: 1.0.5 - string.prototype.trimstart: 1.0.5 + string.prototype.trimend: 1.0.6 + string.prototype.trimstart: 1.0.6 unbox-primitive: 1.0.2 dev: true @@ -2722,8 +2714,8 @@ packages: dev: true optional: true - /esbuild-android-64/0.15.13: - resolution: {integrity: sha512-yRorukXBlokwTip+Sy4MYskLhJsO0Kn0/Fj43s1krVblfwP+hMD37a4Wmg139GEsMLl+vh8WXp2mq/cTA9J97g==} + /esbuild-android-64/0.15.14: + resolution: {integrity: sha512-HuilVIb4rk9abT4U6bcFdU35UHOzcWVGLSjEmC58OVr96q5UiRqzDtWjPlCMugjhgUGKEs8Zf4ueIvYbOStbIg==} engines: {node: '>=12'} cpu: [x64] os: [android] @@ -2749,8 +2741,8 @@ packages: dev: true optional: true - /esbuild-android-arm64/0.15.13: - resolution: {integrity: sha512-TKzyymLD6PiVeyYa4c5wdPw87BeAiTXNtK6amWUcXZxkV51gOk5u5qzmDaYSwiWeecSNHamFsaFjLoi32QR5/w==} + /esbuild-android-arm64/0.15.14: + resolution: {integrity: sha512-/QnxRVxsR2Vtf3XottAHj7hENAMW2wCs6S+OZcAbc/8nlhbAL/bCQRCVD78VtI5mdwqWkVi3wMqM94kScQCgqg==} engines: {node: '>=12'} cpu: [arm64] os: [android] @@ -2776,8 +2768,8 @@ packages: dev: true optional: true - /esbuild-darwin-64/0.15.13: - resolution: {integrity: sha512-WAx7c2DaOS6CrRcoYCgXgkXDliLnFv3pQLV6GeW1YcGEZq2Gnl8s9Pg7ahValZkpOa0iE/ojRVQ87sbUhF1Cbg==} + /esbuild-darwin-64/0.15.14: + resolution: {integrity: sha512-ToNuf1uifu8hhwWvoZJGCdLIX/1zpo8cOGnT0XAhDQXiKOKYaotVNx7pOVB1f+wHoWwTLInrOmh3EmA7Fd+8Vg==} engines: {node: '>=12'} cpu: [x64] os: [darwin] @@ -2803,8 +2795,8 @@ packages: dev: true optional: true - /esbuild-darwin-arm64/0.15.13: - resolution: {integrity: sha512-U6jFsPfSSxC3V1CLiQqwvDuj3GGrtQNB3P3nNC3+q99EKf94UGpsG9l4CQ83zBs1NHrk1rtCSYT0+KfK5LsD8A==} + /esbuild-darwin-arm64/0.15.14: + resolution: {integrity: sha512-KgGP+y77GszfYJgceO0Wi/PiRtYo5y2Xo9rhBUpxTPaBgWDJ14gqYN0+NMbu+qC2fykxXaipHxN4Scaj9tUS1A==} engines: {node: '>=12'} cpu: [arm64] os: [darwin] @@ -2830,8 +2822,8 @@ packages: dev: true optional: true - /esbuild-freebsd-64/0.15.13: - resolution: {integrity: sha512-whItJgDiOXaDG/idy75qqevIpZjnReZkMGCgQaBWZuKHoElDJC1rh7MpoUgupMcdfOd+PgdEwNQW9DAE6i8wyA==} + /esbuild-freebsd-64/0.15.14: + resolution: {integrity: sha512-xr0E2n5lyWw3uFSwwUXHc0EcaBDtsal/iIfLioflHdhAe10KSctV978Te7YsfnsMKzcoGeS366+tqbCXdqDHQA==} engines: {node: '>=12'} cpu: [x64] os: [freebsd] @@ -2857,8 +2849,8 @@ packages: dev: true optional: true - /esbuild-freebsd-arm64/0.15.13: - resolution: {integrity: sha512-6pCSWt8mLUbPtygv7cufV0sZLeylaMwS5Fznj6Rsx9G2AJJsAjQ9ifA+0rQEIg7DwJmi9it+WjzNTEAzzdoM3Q==} + /esbuild-freebsd-arm64/0.15.14: + resolution: {integrity: sha512-8XH96sOQ4b1LhMlO10eEWOjEngmZ2oyw3pW4o8kvBcpF6pULr56eeYVP5radtgw54g3T8nKHDHYEI5AItvskZg==} engines: {node: '>=12'} cpu: [arm64] os: [freebsd] @@ -2884,8 +2876,8 @@ packages: dev: true optional: true - /esbuild-linux-32/0.15.13: - resolution: {integrity: sha512-VbZdWOEdrJiYApm2kkxoTOgsoCO1krBZ3quHdYk3g3ivWaMwNIVPIfEE0f0XQQ0u5pJtBsnk2/7OPiCFIPOe/w==} + /esbuild-linux-32/0.15.14: + resolution: {integrity: sha512-6ssnvwaTAi8AzKN8By2V0nS+WF5jTP7SfuK6sStGnDP7MCJo/4zHgM9oE1eQTS2jPmo3D673rckuCzRlig+HMA==} engines: {node: '>=12'} cpu: [ia32] os: [linux] @@ -2911,8 +2903,8 @@ packages: dev: true optional: true - /esbuild-linux-64/0.15.13: - resolution: {integrity: sha512-rXmnArVNio6yANSqDQlIO4WiP+Cv7+9EuAHNnag7rByAqFVuRusLbGi2697A5dFPNXoO//IiogVwi3AdcfPC6A==} + /esbuild-linux-64/0.15.14: + resolution: {integrity: sha512-ONySx3U0wAJOJuxGUlXBWxVKFVpWv88JEv0NZ6NlHknmDd1yCbf4AEdClSgLrqKQDXYywmw4gYDvdLsS6z0hcw==} engines: {node: '>=12'} cpu: [x64] os: [linux] @@ -2938,8 +2930,8 @@ packages: dev: true optional: true - /esbuild-linux-arm/0.15.13: - resolution: {integrity: sha512-Ac6LpfmJO8WhCMQmO253xX2IU2B3wPDbl4IvR0hnqcPrdfCaUa2j/lLMGTjmQ4W5JsJIdHEdW12dG8lFS0MbxQ==} + /esbuild-linux-arm/0.15.14: + resolution: {integrity: sha512-D2LImAIV3QzL7lHURyCHBkycVFbKwkDb1XEUWan+2fb4qfW7qAeUtul7ZIcIwFKZgPcl+6gKZmvLgPSj26RQ2Q==} engines: {node: '>=12'} cpu: [arm] os: [linux] @@ -2965,8 +2957,8 @@ packages: dev: true optional: true - /esbuild-linux-arm64/0.15.13: - resolution: {integrity: sha512-alEMGU4Z+d17U7KQQw2IV8tQycO6T+rOrgW8OS22Ua25x6kHxoG6Ngry6Aq6uranC+pNWNMB6aHFPh7aTQdORQ==} + /esbuild-linux-arm64/0.15.14: + resolution: {integrity: sha512-kle2Ov6a1e5AjlHlMQl1e+c4myGTeggrRzArQFmWp6O6JoqqB9hT+B28EW4tjFWgV/NxUq46pWYpgaWXsXRPAg==} engines: {node: '>=12'} cpu: [arm64] os: [linux] @@ -2992,8 +2984,8 @@ packages: dev: true optional: true - /esbuild-linux-mips64le/0.15.13: - resolution: {integrity: sha512-47PgmyYEu+yN5rD/MbwS6DxP2FSGPo4Uxg5LwIdxTiyGC2XKwHhHyW7YYEDlSuXLQXEdTO7mYe8zQ74czP7W8A==} + /esbuild-linux-mips64le/0.15.14: + resolution: {integrity: sha512-FVdMYIzOLXUq+OE7XYKesuEAqZhmAIV6qOoYahvUp93oXy0MOVTP370ECbPfGXXUdlvc0TNgkJa3YhEwyZ6MRA==} engines: {node: '>=12'} cpu: [mips64el] os: [linux] @@ -3019,8 +3011,8 @@ packages: dev: true optional: true - /esbuild-linux-ppc64le/0.15.13: - resolution: {integrity: sha512-z6n28h2+PC1Ayle9DjKoBRcx/4cxHoOa2e689e2aDJSaKug3jXcQw7mM+GLg+9ydYoNzj8QxNL8ihOv/OnezhA==} + /esbuild-linux-ppc64le/0.15.14: + resolution: {integrity: sha512-2NzH+iuzMDA+jjtPjuIz/OhRDf8tzbQ1tRZJI//aT25o1HKc0reMMXxKIYq/8nSHXiJSnYV4ODzTiv45s+h73w==} engines: {node: '>=12'} cpu: [ppc64] os: [linux] @@ -3046,8 +3038,8 @@ packages: dev: true optional: true - /esbuild-linux-riscv64/0.15.13: - resolution: {integrity: sha512-+Lu4zuuXuQhgLUGyZloWCqTslcCAjMZH1k3Xc9MSEJEpEFdpsSU0sRDXAnk18FKOfEjhu4YMGaykx9xjtpA6ow==} + /esbuild-linux-riscv64/0.15.14: + resolution: {integrity: sha512-VqxvutZNlQxmUNS7Ac+aczttLEoHBJ9e3OYGqnULrfipRvG97qLrAv9EUY9iSrRKBqeEbSvS9bSfstZqwz0T4Q==} engines: {node: '>=12'} cpu: [riscv64] os: [linux] @@ -3073,8 +3065,8 @@ packages: dev: true optional: true - /esbuild-linux-s390x/0.15.13: - resolution: {integrity: sha512-BMeXRljruf7J0TMxD5CIXS65y7puiZkAh+s4XFV9qy16SxOuMhxhVIXYLnbdfLrsYGFzx7U9mcdpFWkkvy/Uag==} + /esbuild-linux-s390x/0.15.14: + resolution: {integrity: sha512-+KVHEUshX5n6VP6Vp/AKv9fZIl5kr2ph8EUFmQUJnDpHwcfTSn2AQgYYm0HTBR2Mr4d0Wlr0FxF/Cs5pbFgiOw==} engines: {node: '>=12'} cpu: [s390x] os: [linux] @@ -3100,8 +3092,8 @@ packages: dev: true optional: true - /esbuild-netbsd-64/0.15.13: - resolution: {integrity: sha512-EHj9QZOTel581JPj7UO3xYbltFTYnHy+SIqJVq6yd3KkCrsHRbapiPb0Lx3EOOtybBEE9EyqbmfW1NlSDsSzvQ==} + /esbuild-netbsd-64/0.15.14: + resolution: {integrity: sha512-6D/dr17piEgevIm1xJfZP2SjB9Z+g8ERhNnBdlZPBWZl+KSPUKLGF13AbvC+nzGh8IxOH2TyTIdRMvKMP0nEzQ==} engines: {node: '>=12'} cpu: [x64] os: [netbsd] @@ -3127,8 +3119,8 @@ packages: dev: true optional: true - /esbuild-openbsd-64/0.15.13: - resolution: {integrity: sha512-nkuDlIjF/sfUhfx8SKq0+U+Fgx5K9JcPq1mUodnxI0x4kBdCv46rOGWbuJ6eof2n3wdoCLccOoJAbg9ba/bT2w==} + /esbuild-openbsd-64/0.15.14: + resolution: {integrity: sha512-rREQBIlMibBetgr2E9Lywt2Qxv2ZdpmYahR4IUlAQ1Efv/A5gYdO0/VIN3iowDbCNTLxp0bb57Vf0LFcffD6kA==} engines: {node: '>=12'} cpu: [x64] os: [openbsd] @@ -3154,8 +3146,8 @@ packages: dev: true optional: true - /esbuild-sunos-64/0.15.13: - resolution: {integrity: sha512-jVeu2GfxZQ++6lRdY43CS0Tm/r4WuQQ0Pdsrxbw+aOrHQPHV0+LNOLnvbN28M7BSUGnJnHkHm2HozGgNGyeIRw==} + /esbuild-sunos-64/0.15.14: + resolution: {integrity: sha512-DNVjSp/BY4IfwtdUAvWGIDaIjJXY5KI4uD82+15v6k/w7px9dnaDaJJ2R6Mu+KCgr5oklmFc0KjBjh311Gxl9Q==} engines: {node: '>=12'} cpu: [x64] os: [sunos] @@ -3181,8 +3173,8 @@ packages: dev: true optional: true - /esbuild-windows-32/0.15.13: - resolution: {integrity: sha512-XoF2iBf0wnqo16SDq+aDGi/+QbaLFpkiRarPVssMh9KYbFNCqPLlGAWwDvxEVz+ywX6Si37J2AKm+AXq1kC0JA==} + /esbuild-windows-32/0.15.14: + resolution: {integrity: sha512-pHBWrcA+/oLgvViuG9FO3kNPO635gkoVrRQwe6ZY1S0jdET07xe2toUvQoJQ8KT3/OkxqUasIty5hpuKFLD+eg==} engines: {node: '>=12'} cpu: [ia32] os: [win32] @@ -3208,8 +3200,8 @@ packages: dev: true optional: true - /esbuild-windows-64/0.15.13: - resolution: {integrity: sha512-Et6htEfGycjDrtqb2ng6nT+baesZPYQIW+HUEHK4D1ncggNrDNk3yoboYQ5KtiVrw/JaDMNttz8rrPubV/fvPQ==} + /esbuild-windows-64/0.15.14: + resolution: {integrity: sha512-CszIGQVk/P8FOS5UgAH4hKc9zOaFo69fe+k1rqgBHx3CSK3Opyk5lwYriIamaWOVjBt7IwEP6NALz+tkVWdFog==} engines: {node: '>=12'} cpu: [x64] os: [win32] @@ -3235,8 +3227,8 @@ packages: dev: true optional: true - /esbuild-windows-arm64/0.15.13: - resolution: {integrity: sha512-3bv7tqntThQC9SWLRouMDmZnlOukBhOCTlkzNqzGCmrkCJI7io5LLjwJBOVY6kOUlIvdxbooNZwjtBvj+7uuVg==} + /esbuild-windows-arm64/0.15.14: + resolution: {integrity: sha512-KW9W4psdZceaS9A7Jsgl4WialOznSURvqX/oHZk3gOP7KbjtHLSsnmSvNdzagGJfxbAe30UVGXRe8q8nDsOSQw==} engines: {node: '>=12'} cpu: [arm64] os: [win32] @@ -3300,34 +3292,34 @@ packages: esbuild-windows-arm64: 0.14.51 dev: true - /esbuild/0.15.13: - resolution: {integrity: sha512-Cu3SC84oyzzhrK/YyN4iEVy2jZu5t2fz66HEOShHURcjSkOSAVL8C/gfUT+lDJxkVHpg8GZ10DD0rMHRPqMFaQ==} + /esbuild/0.15.14: + resolution: {integrity: sha512-pJN8j42fvWLFWwSMG4luuupl2Me7mxciUOsMegKvwCmhEbJ2covUdFnihxm0FMIBV+cbwbtMoHgMCCI+pj1btQ==} engines: {node: '>=12'} hasBin: true requiresBuild: true optionalDependencies: - '@esbuild/android-arm': 0.15.13 - '@esbuild/linux-loong64': 0.15.13 - esbuild-android-64: 0.15.13 - esbuild-android-arm64: 0.15.13 - esbuild-darwin-64: 0.15.13 - esbuild-darwin-arm64: 0.15.13 - esbuild-freebsd-64: 0.15.13 - esbuild-freebsd-arm64: 0.15.13 - esbuild-linux-32: 0.15.13 - esbuild-linux-64: 0.15.13 - esbuild-linux-arm: 0.15.13 - esbuild-linux-arm64: 0.15.13 - esbuild-linux-mips64le: 0.15.13 - esbuild-linux-ppc64le: 0.15.13 - esbuild-linux-riscv64: 0.15.13 - esbuild-linux-s390x: 0.15.13 - esbuild-netbsd-64: 0.15.13 - esbuild-openbsd-64: 0.15.13 - esbuild-sunos-64: 0.15.13 - esbuild-windows-32: 0.15.13 - esbuild-windows-64: 0.15.13 - esbuild-windows-arm64: 0.15.13 + '@esbuild/android-arm': 0.15.14 + '@esbuild/linux-loong64': 0.15.14 + esbuild-android-64: 0.15.14 + esbuild-android-arm64: 0.15.14 + esbuild-darwin-64: 0.15.14 + esbuild-darwin-arm64: 0.15.14 + esbuild-freebsd-64: 0.15.14 + esbuild-freebsd-arm64: 0.15.14 + esbuild-linux-32: 0.15.14 + esbuild-linux-64: 0.15.14 + esbuild-linux-arm: 0.15.14 + esbuild-linux-arm64: 0.15.14 + esbuild-linux-mips64le: 0.15.14 + esbuild-linux-ppc64le: 0.15.14 + esbuild-linux-riscv64: 0.15.14 + esbuild-linux-s390x: 0.15.14 + esbuild-netbsd-64: 0.15.14 + esbuild-openbsd-64: 0.15.14 + esbuild-sunos-64: 0.15.14 + esbuild-windows-32: 0.15.14 + esbuild-windows-64: 0.15.14 + esbuild-windows-arm64: 0.15.14 dev: true /escalade/3.1.1: @@ -3354,8 +3346,8 @@ packages: resolution: {integrity: sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==} engines: {node: '>=12'} - /eslint-config-next/12.3.1_wyqvi574yv7oiwfeinomdzmc3m: - resolution: {integrity: sha512-EN/xwKPU6jz1G0Qi6Bd/BqMnHLyRAL0VsaQaWA7F3KkjAgZHi4f1uL1JKGWNxdQpHTW/sdGONBd0bzxUka/DJg==} + /eslint-config-next/13.0.3_rmayb2veg2btbq6mbmnyivgasy: + resolution: {integrity: sha512-i2JoQP8gGv303GjXTonA27fm1ckRRkRoAP1WYEQgN0D2DDoFeBPqlJgHlMHnXKWjmNct/sW8jQEvy9am2juc8g==} peerDependencies: eslint: ^7.23.0 || ^8.0.0 typescript: '>=3.3.1' @@ -3363,32 +3355,32 @@ packages: typescript: optional: true dependencies: - '@next/eslint-plugin-next': 12.3.1 + '@next/eslint-plugin-next': 13.0.3 '@rushstack/eslint-patch': 1.2.0 - '@typescript-eslint/parser': 5.42.0_wyqvi574yv7oiwfeinomdzmc3m - eslint: 8.26.0 + '@typescript-eslint/parser': 5.43.0_rmayb2veg2btbq6mbmnyivgasy + eslint: 8.27.0 eslint-import-resolver-node: 0.3.6 - eslint-import-resolver-typescript: 2.7.1_mynvxvmq5qtyojffiqgev4x7mm - eslint-plugin-import: 2.26.0_f352m6qpd5jz6qrf3l36ifh65y - eslint-plugin-jsx-a11y: 6.6.1_eslint@8.26.0 - eslint-plugin-react: 7.31.10_eslint@8.26.0 - eslint-plugin-react-hooks: 4.6.0_eslint@8.26.0 + eslint-import-resolver-typescript: 2.7.1_dcpv4nbdr5ks2h5677xdltrk6e + eslint-plugin-import: 2.26.0_ttnp75sbivpcvanbhjbkcsh3ly + eslint-plugin-jsx-a11y: 6.6.1_eslint@8.27.0 + eslint-plugin-react: 7.31.10_eslint@8.27.0 + eslint-plugin-react-hooks: 4.6.0_eslint@8.27.0 typescript: 4.8.4 transitivePeerDependencies: - eslint-import-resolver-webpack - supports-color dev: true - /eslint-config-prettier/8.5.0_eslint@8.26.0: + /eslint-config-prettier/8.5.0_eslint@8.27.0: resolution: {integrity: sha512-obmWKLUNCnhtQRKc+tmnYuQl0pFU1ibYJQ5BGhTVB08bHe9wC8qUeG7c08dj9XX+AuPj1YSGSQIHl1pnDHZR0Q==} hasBin: true peerDependencies: eslint: '>=7.0.0' dependencies: - eslint: 8.26.0 + eslint: 8.27.0 dev: true - /eslint-config-standard-with-typescript/23.0.0_cuhm7w6dppd435hmbz5wtjkgum: + /eslint-config-standard-with-typescript/23.0.0_iajcbk7iadsd3pvvaviyatln7y: resolution: {integrity: sha512-iaaWifImn37Z1OXbNW1es7KI+S7D408F9ys0bpaQf2temeBWlvb0Nc5qHkOgYaRb5QxTZT32GGeN1gtswASOXA==} peerDependencies: '@typescript-eslint/eslint-plugin': ^5.0.0 @@ -3398,19 +3390,19 @@ packages: eslint-plugin-promise: ^6.0.0 typescript: '*' dependencies: - '@typescript-eslint/eslint-plugin': 5.42.0_6xw5wg2354iw4zujk2f3vyfrzu - '@typescript-eslint/parser': 5.42.0_wyqvi574yv7oiwfeinomdzmc3m - eslint: 8.26.0 - eslint-config-standard: 17.0.0_pxgizx7scytnzv6tfhdgsab7u4 - eslint-plugin-import: 2.26.0_5aea5dp4n23mfv4y2mmjxole3e - eslint-plugin-n: 15.4.0_eslint@8.26.0 - eslint-plugin-promise: 6.1.1_eslint@8.26.0 + '@typescript-eslint/eslint-plugin': 5.43.0_yy4vf4gcvxiubmg7fqa55dqe2i + '@typescript-eslint/parser': 5.43.0_rmayb2veg2btbq6mbmnyivgasy + eslint: 8.27.0 + eslint-config-standard: 17.0.0_qmmcbu32ybj7ict4ieqqyvwr3m + eslint-plugin-import: 2.26.0_wbsj7pk5g7hogwvhsif6xntns4 + eslint-plugin-n: 15.5.1_eslint@8.27.0 + eslint-plugin-promise: 6.1.1_eslint@8.27.0 typescript: 4.8.4 transitivePeerDependencies: - supports-color dev: true - /eslint-config-standard/17.0.0_pxgizx7scytnzv6tfhdgsab7u4: + /eslint-config-standard/17.0.0_qmmcbu32ybj7ict4ieqqyvwr3m: resolution: {integrity: sha512-/2ks1GKyqSOkH7JFvXJicu0iMpoojkwB+f5Du/1SC0PtBL+s8v30k9njRZ21pm2drKYm2342jFnGWzttxPmZVg==} peerDependencies: eslint: ^8.0.1 @@ -3418,20 +3410,20 @@ packages: eslint-plugin-n: ^15.0.0 eslint-plugin-promise: ^6.0.0 dependencies: - eslint: 8.26.0 - eslint-plugin-import: 2.26.0_5aea5dp4n23mfv4y2mmjxole3e - eslint-plugin-n: 15.4.0_eslint@8.26.0 - eslint-plugin-promise: 6.1.1_eslint@8.26.0 + eslint: 8.27.0 + eslint-plugin-import: 2.26.0_wbsj7pk5g7hogwvhsif6xntns4 + eslint-plugin-n: 15.5.1_eslint@8.27.0 + eslint-plugin-promise: 6.1.1_eslint@8.27.0 dev: true - /eslint-etc/5.2.0_wyqvi574yv7oiwfeinomdzmc3m: + /eslint-etc/5.2.0_rmayb2veg2btbq6mbmnyivgasy: resolution: {integrity: sha512-Gcm/NMa349FOXb1PEEfNMMyIANuorIc2/mI5Vfu1zENNsz+FBVhF62uY6gPUCigm/xDOc8JOnl+71WGnlzlDag==} peerDependencies: eslint: ^8.0.0 typescript: ^4.0.0 dependencies: - '@typescript-eslint/experimental-utils': 5.42.0_wyqvi574yv7oiwfeinomdzmc3m - eslint: 8.26.0 + '@typescript-eslint/experimental-utils': 5.43.0_rmayb2veg2btbq6mbmnyivgasy + eslint: 8.27.0 tsutils: 3.21.0_typescript@4.8.4 tsutils-etc: 1.4.1_mhfzdf4crgayux52p57kxjyixi typescript: 4.8.4 @@ -3448,7 +3440,7 @@ packages: - supports-color dev: true - /eslint-import-resolver-typescript/2.7.1_mynvxvmq5qtyojffiqgev4x7mm: + /eslint-import-resolver-typescript/2.7.1_dcpv4nbdr5ks2h5677xdltrk6e: resolution: {integrity: sha512-00UbgGwV8bSgUv34igBDbTOtKhqoRMy9bFjNehT40bXg6585PNIct8HhXZ0SybqB9rWtXj9crcku8ndDn/gIqQ==} engines: {node: '>=4'} peerDependencies: @@ -3456,8 +3448,8 @@ packages: eslint-plugin-import: '*' dependencies: debug: 4.3.4 - eslint: 8.26.0 - eslint-plugin-import: 2.26.0_f352m6qpd5jz6qrf3l36ifh65y + eslint: 8.27.0 + eslint-plugin-import: 2.26.0_ttnp75sbivpcvanbhjbkcsh3ly glob: 7.2.3 is-glob: 4.0.3 resolve: 1.22.1 @@ -3466,7 +3458,7 @@ packages: - supports-color dev: true - /eslint-module-utils/2.7.4_5wizbv6at2kperuxlviadd4ace: + /eslint-module-utils/2.7.4_7n62batgpjg7oa6ssbsyzoyo34: resolution: {integrity: sha512-j4GT+rqzCoRKHwURX7pddtIPGySnX9Si/cgMI5ztrcqOPtk5dDEeZ34CQVPphnqkJytlc97Vuk05Um2mJ3gEQA==} engines: {node: '>=4'} peerDependencies: @@ -3487,16 +3479,15 @@ packages: eslint-import-resolver-webpack: optional: true dependencies: - '@typescript-eslint/parser': 5.42.0_wyqvi574yv7oiwfeinomdzmc3m + '@typescript-eslint/parser': 5.43.0_rmayb2veg2btbq6mbmnyivgasy debug: 3.2.7 - eslint: 8.26.0 + eslint: 8.27.0 eslint-import-resolver-node: 0.3.6 - eslint-import-resolver-typescript: 2.7.1_mynvxvmq5qtyojffiqgev4x7mm transitivePeerDependencies: - supports-color dev: true - /eslint-module-utils/2.7.4_yytd4qhylm3dyr3j4r4rwmq2vy: + /eslint-module-utils/2.7.4_xrelmojid5azn576bwxzifnii4: resolution: {integrity: sha512-j4GT+rqzCoRKHwURX7pddtIPGySnX9Si/cgMI5ztrcqOPtk5dDEeZ34CQVPphnqkJytlc97Vuk05Um2mJ3gEQA==} engines: {node: '>=4'} peerDependencies: @@ -3517,35 +3508,36 @@ packages: eslint-import-resolver-webpack: optional: true dependencies: - '@typescript-eslint/parser': 5.42.0_wyqvi574yv7oiwfeinomdzmc3m + '@typescript-eslint/parser': 5.43.0_rmayb2veg2btbq6mbmnyivgasy debug: 3.2.7 - eslint: 8.26.0 + eslint: 8.27.0 eslint-import-resolver-node: 0.3.6 + eslint-import-resolver-typescript: 2.7.1_dcpv4nbdr5ks2h5677xdltrk6e transitivePeerDependencies: - supports-color dev: true - /eslint-plugin-es/4.1.0_eslint@8.26.0: + /eslint-plugin-es/4.1.0_eslint@8.27.0: resolution: {integrity: sha512-GILhQTnjYE2WorX5Jyi5i4dz5ALWxBIdQECVQavL6s7cI76IZTDWleTHkxz/QT3kvcs2QlGHvKLYsSlPOlPXnQ==} engines: {node: '>=8.10.0'} peerDependencies: eslint: '>=4.19.1' dependencies: - eslint: 8.26.0 + eslint: 8.27.0 eslint-utils: 2.1.0 regexpp: 3.2.0 dev: true - /eslint-plugin-etc/2.0.2_wyqvi574yv7oiwfeinomdzmc3m: + /eslint-plugin-etc/2.0.2_rmayb2veg2btbq6mbmnyivgasy: resolution: {integrity: sha512-g3b95LCdTCwZA8On9EICYL8m1NMWaiGfmNUd/ftZTeGZDXrwujKXUr+unYzqKjKFo1EbqJ31vt+Dqzrdm/sUcw==} peerDependencies: eslint: ^8.0.0 typescript: ^4.0.0 dependencies: '@phenomnomnominal/tsquery': 4.2.0_typescript@4.8.4 - '@typescript-eslint/experimental-utils': 5.42.0_wyqvi574yv7oiwfeinomdzmc3m - eslint: 8.26.0 - eslint-etc: 5.2.0_wyqvi574yv7oiwfeinomdzmc3m + '@typescript-eslint/experimental-utils': 5.43.0_rmayb2veg2btbq6mbmnyivgasy + eslint: 8.27.0 + eslint-etc: 5.2.0_rmayb2veg2btbq6mbmnyivgasy requireindex: 1.2.0 tslib: 2.4.1 tsutils: 3.21.0_typescript@4.8.4 @@ -3554,7 +3546,7 @@ packages: - supports-color dev: true - /eslint-plugin-import/2.26.0_5aea5dp4n23mfv4y2mmjxole3e: + /eslint-plugin-import/2.26.0_ttnp75sbivpcvanbhjbkcsh3ly: resolution: {integrity: sha512-hYfi3FXaM8WPLf4S1cikh/r4IxnO6zrhZbEGz2b660EJRbuxgpDS5gkCuYgGWg2xxh2rBuIr4Pvhve/7c31koA==} engines: {node: '>=4'} peerDependencies: @@ -3564,19 +3556,19 @@ packages: '@typescript-eslint/parser': optional: true dependencies: - '@typescript-eslint/parser': 5.42.0_wyqvi574yv7oiwfeinomdzmc3m - array-includes: 3.1.5 + '@typescript-eslint/parser': 5.43.0_rmayb2veg2btbq6mbmnyivgasy + array-includes: 3.1.6 array.prototype.flat: 1.3.1 debug: 2.6.9 doctrine: 2.1.0 - eslint: 8.26.0 + eslint: 8.27.0 eslint-import-resolver-node: 0.3.6 - eslint-module-utils: 2.7.4_yytd4qhylm3dyr3j4r4rwmq2vy + eslint-module-utils: 2.7.4_xrelmojid5azn576bwxzifnii4 has: 1.0.3 is-core-module: 2.11.0 is-glob: 4.0.3 minimatch: 3.1.2 - object.values: 1.1.5 + object.values: 1.1.6 resolve: 1.22.1 tsconfig-paths: 3.14.1 transitivePeerDependencies: @@ -3585,7 +3577,7 @@ packages: - supports-color dev: true - /eslint-plugin-import/2.26.0_f352m6qpd5jz6qrf3l36ifh65y: + /eslint-plugin-import/2.26.0_wbsj7pk5g7hogwvhsif6xntns4: resolution: {integrity: sha512-hYfi3FXaM8WPLf4S1cikh/r4IxnO6zrhZbEGz2b660EJRbuxgpDS5gkCuYgGWg2xxh2rBuIr4Pvhve/7c31koA==} engines: {node: '>=4'} peerDependencies: @@ -3595,19 +3587,19 @@ packages: '@typescript-eslint/parser': optional: true dependencies: - '@typescript-eslint/parser': 5.42.0_wyqvi574yv7oiwfeinomdzmc3m - array-includes: 3.1.5 + '@typescript-eslint/parser': 5.43.0_rmayb2veg2btbq6mbmnyivgasy + array-includes: 3.1.6 array.prototype.flat: 1.3.1 debug: 2.6.9 doctrine: 2.1.0 - eslint: 8.26.0 + eslint: 8.27.0 eslint-import-resolver-node: 0.3.6 - eslint-module-utils: 2.7.4_5wizbv6at2kperuxlviadd4ace + eslint-module-utils: 2.7.4_7n62batgpjg7oa6ssbsyzoyo34 has: 1.0.3 is-core-module: 2.11.0 is-glob: 4.0.3 minimatch: 3.1.2 - object.values: 1.1.5 + object.values: 1.1.6 resolve: 1.22.1 tsconfig-paths: 3.14.1 transitivePeerDependencies: @@ -3616,7 +3608,7 @@ packages: - supports-color dev: true - /eslint-plugin-jsdoc/39.6.2_eslint@8.26.0: + /eslint-plugin-jsdoc/39.6.2_eslint@8.27.0: resolution: {integrity: sha512-dvgY/W7eUFoAIIiaWHERIMI61ZWqcz9YFjEeyTzdPlrZc3TY/3aZm5aB91NUoTLWYZmO/vFlYSuQi15tF7uE5A==} engines: {node: ^14 || ^16 || ^17 || ^18 || ^19} peerDependencies: @@ -3626,7 +3618,7 @@ packages: comment-parser: 1.3.1 debug: 4.3.4 escape-string-regexp: 4.0.0 - eslint: 8.26.0 + eslint: 8.27.0 esquery: 1.4.0 semver: 7.3.8 spdx-expression-parse: 3.0.1 @@ -3634,7 +3626,7 @@ packages: - supports-color dev: true - /eslint-plugin-jsx-a11y/6.6.1_eslint@8.26.0: + /eslint-plugin-jsx-a11y/6.6.1_eslint@8.27.0: resolution: {integrity: sha512-sXgFVNHiWffBq23uiS/JaP6eVR622DqwB4yTzKvGZGcPq6/yZ3WmOZfuBks/vHWo9GaFOqC2ZK4i6+C35knx7Q==} engines: {node: '>=4.0'} peerDependencies: @@ -3642,13 +3634,13 @@ packages: dependencies: '@babel/runtime': 7.20.1 aria-query: 4.2.2 - array-includes: 3.1.5 + array-includes: 3.1.6 ast-types-flow: 0.0.7 - axe-core: 4.5.1 + axe-core: 4.5.2 axobject-query: 2.2.0 damerau-levenshtein: 1.0.8 emoji-regex: 9.2.2 - eslint: 8.26.0 + eslint: 8.27.0 has: 1.0.3 jsx-ast-utils: 3.3.3 language-tags: 1.0.5 @@ -3656,16 +3648,16 @@ packages: semver: 6.3.0 dev: true - /eslint-plugin-n/15.4.0_eslint@8.26.0: - resolution: {integrity: sha512-MkoKy9/lfd52TAXK4fkABgCp0aglk82Q3viy2UOWIEpTVE/Cem5P/UAxMBA4vSw7Gy+2egPqImE9euitLGp5aw==} + /eslint-plugin-n/15.5.1_eslint@8.27.0: + resolution: {integrity: sha512-kAd+xhZm7brHoFLzKLB7/FGRFJNg/srmv67mqb7tto22rpr4wv/LV6RuXzAfv3jbab7+k1wi42PsIhGviywaaw==} engines: {node: '>=12.22.0'} peerDependencies: eslint: '>=7.0.0' dependencies: builtins: 5.0.1 - eslint: 8.26.0 - eslint-plugin-es: 4.1.0_eslint@8.26.0 - eslint-utils: 3.0.0_eslint@8.26.0 + eslint: 8.27.0 + eslint-plugin-es: 4.1.0_eslint@8.27.0 + eslint-utils: 3.0.0_eslint@8.27.0 ignore: 5.2.0 is-core-module: 2.11.0 minimatch: 3.1.2 @@ -3678,58 +3670,58 @@ packages: engines: {node: '>=5.0.0'} dev: true - /eslint-plugin-promise/6.1.1_eslint@8.26.0: + /eslint-plugin-promise/6.1.1_eslint@8.27.0: resolution: {integrity: sha512-tjqWDwVZQo7UIPMeDReOpUgHCmCiH+ePnVT+5zVapL0uuHnegBUs2smM13CzOs2Xb5+MHMRFTs9v24yjba4Oig==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: eslint: ^7.0.0 || ^8.0.0 dependencies: - eslint: 8.26.0 + eslint: 8.27.0 dev: true - /eslint-plugin-react-hooks/4.6.0_eslint@8.26.0: + /eslint-plugin-react-hooks/4.6.0_eslint@8.27.0: resolution: {integrity: sha512-oFc7Itz9Qxh2x4gNHStv3BqJq54ExXmfC+a1NjAta66IAN87Wu0R/QArgIS9qKzX3dXKPI9H5crl9QchNMY9+g==} engines: {node: '>=10'} peerDependencies: eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 dependencies: - eslint: 8.26.0 + eslint: 8.27.0 dev: true - /eslint-plugin-react/7.31.10_eslint@8.26.0: + /eslint-plugin-react/7.31.10_eslint@8.27.0: resolution: {integrity: sha512-e4N/nc6AAlg4UKW/mXeYWd3R++qUano5/o+t+wnWxIf+bLsOaH3a4q74kX3nDjYym3VBN4HyO9nEn1GcAqgQOA==} engines: {node: '>=4'} peerDependencies: eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 dependencies: - array-includes: 3.1.5 + array-includes: 3.1.6 array.prototype.flatmap: 1.3.1 doctrine: 2.1.0 - eslint: 8.26.0 + eslint: 8.27.0 estraverse: 5.3.0 jsx-ast-utils: 3.3.3 minimatch: 3.1.2 - object.entries: 1.1.5 - object.fromentries: 2.0.5 - object.hasown: 1.1.1 - object.values: 1.1.5 + object.entries: 1.1.6 + object.fromentries: 2.0.6 + object.hasown: 1.1.2 + object.values: 1.1.6 prop-types: 15.8.1 resolve: 2.0.0-next.4 semver: 6.3.0 - string.prototype.matchall: 4.0.7 + string.prototype.matchall: 4.0.8 dev: true - /eslint-plugin-unicorn/44.0.2_eslint@8.26.0: + /eslint-plugin-unicorn/44.0.2_eslint@8.27.0: resolution: {integrity: sha512-GLIDX1wmeEqpGaKcnMcqRvMVsoabeF0Ton0EX4Th5u6Kmf7RM9WBl705AXFEsns56ESkEs0uyelLuUTvz9Tr0w==} engines: {node: '>=14.18'} peerDependencies: eslint: '>=8.23.1' dependencies: '@babel/helper-validator-identifier': 7.19.1 - ci-info: 3.5.0 + ci-info: 3.6.1 clean-regexp: 1.0.0 - eslint: 8.26.0 - eslint-utils: 3.0.0_eslint@8.26.0 + eslint: 8.27.0 + eslint-utils: 3.0.0_eslint@8.27.0 esquery: 1.4.0 indent-string: 4.0.0 is-builtin-module: 3.2.0 @@ -3765,13 +3757,13 @@ packages: eslint-visitor-keys: 1.3.0 dev: true - /eslint-utils/3.0.0_eslint@8.26.0: + /eslint-utils/3.0.0_eslint@8.27.0: resolution: {integrity: sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==} engines: {node: ^10.0.0 || ^12.0.0 || >= 14.0.0} peerDependencies: eslint: '>=5' dependencies: - eslint: 8.26.0 + eslint: 8.27.0 eslint-visitor-keys: 2.1.0 dev: true @@ -3790,8 +3782,8 @@ packages: engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dev: true - /eslint/8.26.0: - resolution: {integrity: sha512-kzJkpaw1Bfwheq4VXUezFriD1GxszX6dUekM7Z3aC2o4hju+tsR/XyTC3RcoSD7jmy9VkPU3+N6YjVU2e96Oyg==} + /eslint/8.27.0: + resolution: {integrity: sha512-0y1bfG2ho7mty+SiILVf9PfuRA49ek4Nc60Wmmu62QlobNR+CeXa4xXIJgcuwSQgZiWaPH+5BDsctpIW0PR/wQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} hasBin: true dependencies: @@ -3806,9 +3798,9 @@ packages: doctrine: 3.0.0 escape-string-regexp: 4.0.0 eslint-scope: 7.1.1 - eslint-utils: 3.0.0_eslint@8.26.0 + eslint-utils: 3.0.0_eslint@8.27.0 eslint-visitor-keys: 3.3.0 - espree: 9.4.0 + espree: 9.4.1 esquery: 1.4.0 esutils: 2.0.3 fast-deep-equal: 3.1.3 @@ -3838,8 +3830,8 @@ packages: - supports-color dev: true - /espree/9.4.0: - resolution: {integrity: sha512-DQmnRpLj7f6TgN/NYb0MTzJXL+vJF9h3pHy4JhCIs3zwcgez8xmGg3sXHcEO97BrmO2OSvCwMdfdlyl+E9KjOw==} + /espree/9.4.1: + resolution: {integrity: sha512-XwctdmTO6SIvCzd9810yyNzIrOrqNYV9Koizx4C/mRhf9uq0o4yHoCEU/670pOxOL/MSraektvSAji79kX90Vg==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dependencies: acorn: 8.8.1 @@ -3893,7 +3885,7 @@ packages: /eventemitter3/4.0.7: resolution: {integrity: sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==} - dev: false + dev: true /events/3.3.0: resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==} @@ -4090,20 +4082,6 @@ packages: wide-align: 1.1.5 dev: true - /gauge/4.0.4: - resolution: {integrity: sha512-f9m+BEN5jkg6a0fZjleidjN51VE1X+mPFQ2DJ0uv1V39oCLCbsGe6yjbBnp7eK7z/+GAon99a3nHuqbuuthyPg==} - engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} - dependencies: - aproba: 2.0.0 - color-support: 1.1.3 - console-control-strings: 1.1.0 - has-unicode: 2.0.1 - signal-exit: 3.0.7 - string-width: 4.2.3 - strip-ansi: 6.0.1 - wide-align: 1.1.5 - dev: true - /get-caller-file/2.0.5: resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} engines: {node: 6.* || 8.* || >= 10.*} @@ -4294,21 +4272,21 @@ packages: resolution: {integrity: sha512-Pg7yAvasl8QRsymK/m0S184fDPiz03/VOAdbRbHdsaFcp41drGh9NdzG2jLJHpRuNoWxL/bH0R4kSULT6DvpSw==} engines: {node: '>=14'} dependencies: - '@typescript-eslint/eslint-plugin': 5.42.0_6xw5wg2354iw4zujk2f3vyfrzu - '@typescript-eslint/parser': 5.42.0_wyqvi574yv7oiwfeinomdzmc3m - eslint: 8.26.0 - eslint-config-prettier: 8.5.0_eslint@8.26.0 - eslint-config-standard: 17.0.0_pxgizx7scytnzv6tfhdgsab7u4 - eslint-config-standard-with-typescript: 23.0.0_cuhm7w6dppd435hmbz5wtjkgum - eslint-plugin-etc: 2.0.2_wyqvi574yv7oiwfeinomdzmc3m - eslint-plugin-import: 2.26.0_5aea5dp4n23mfv4y2mmjxole3e - eslint-plugin-jsdoc: 39.6.2_eslint@8.26.0 - eslint-plugin-n: 15.4.0_eslint@8.26.0 + '@typescript-eslint/eslint-plugin': 5.43.0_yy4vf4gcvxiubmg7fqa55dqe2i + '@typescript-eslint/parser': 5.43.0_rmayb2veg2btbq6mbmnyivgasy + eslint: 8.27.0 + eslint-config-prettier: 8.5.0_eslint@8.27.0 + eslint-config-standard: 17.0.0_qmmcbu32ybj7ict4ieqqyvwr3m + eslint-config-standard-with-typescript: 23.0.0_iajcbk7iadsd3pvvaviyatln7y + eslint-plugin-etc: 2.0.2_rmayb2veg2btbq6mbmnyivgasy + eslint-plugin-import: 2.26.0_wbsj7pk5g7hogwvhsif6xntns4 + eslint-plugin-jsdoc: 39.6.2_eslint@8.27.0 + eslint-plugin-n: 15.5.1_eslint@8.27.0 eslint-plugin-no-only-tests: 3.1.0 - eslint-plugin-promise: 6.1.1_eslint@8.26.0 - eslint-plugin-react: 7.31.10_eslint@8.26.0 - eslint-plugin-react-hooks: 4.6.0_eslint@8.26.0 - eslint-plugin-unicorn: 44.0.2_eslint@8.26.0 + eslint-plugin-promise: 6.1.1_eslint@8.27.0 + eslint-plugin-react: 7.31.10_eslint@8.27.0 + eslint-plugin-react-hooks: 4.6.0_eslint@8.27.0 + eslint-plugin-unicorn: 44.0.2_eslint@8.27.0 lint-staged: 13.0.3 prettier: 2.7.1 simple-git-hooks: 2.8.1 @@ -4695,12 +4673,12 @@ packages: resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} dev: true - /isomorphic-ws/5.0.0_ws@8.10.0: + /isomorphic-ws/5.0.0_ws@8.11.0: resolution: {integrity: sha512-muId7Zzn9ywDsyXgTIafTry2sV3nySZeUDe6YedVd1Hvuuep5AsIlqK+XefWpYTyJG5e503F2xIuT2lcU6rCSw==} peerDependencies: ws: '*' dependencies: - ws: 8.10.0 + ws: 8.11.0 dev: false /js-sdsl/4.1.5: @@ -4762,11 +4740,15 @@ packages: minimist: 1.2.7 dev: true + /jsonc-parser/3.2.0: + resolution: {integrity: sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==} + dev: false + /jsx-ast-utils/3.3.3: resolution: {integrity: sha512-fYQHZTZ8jSfmWZ0iyzfwiU4WDX4HpHbMCZ3gPlWYiCl3BoeOTsqKBqnTVfH2rYT7eP5c3sVbeSPHnnJOaTrWiw==} engines: {node: '>=4.0'} dependencies: - array-includes: 3.1.5 + array-includes: 3.1.6 object.assign: 4.1.4 dev: true @@ -4925,8 +4907,8 @@ packages: dependencies: js-tokens: 4.0.0 - /loupe/2.3.4: - resolution: {integrity: sha512-OvKfgCC2Ndby6aSTREl5aCCPTNIzlDfQZvZxNUrBrihDhL3xcrYegTblhmEiCrg2kKQz4XsFIaemE5BF4ybSaQ==} + /loupe/2.3.6: + resolution: {integrity: sha512-RaPMZKiMy8/JruncMU5Bt6na1eftNoo++R4Y+N2FrxkDVTrGvcyzFTsaGif4QTeKESheMGegbhw6iUAq+5A8zA==} dependencies: get-func-name: 2.0.0 dev: true @@ -4937,6 +4919,10 @@ packages: dependencies: yallist: 4.0.0 + /lunr/2.3.9: + resolution: {integrity: sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow==} + dev: false + /magic-string/0.25.9: resolution: {integrity: sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==} dependencies: @@ -4957,6 +4943,12 @@ packages: p-defer: 1.0.0 dev: true + /marked/4.2.2: + resolution: {integrity: sha512-JjBTFTAvuTgANXx82a5vzK9JLSMoV6V3LBVn4Uhdso6t7vXrGx7g1Cd2r6NYSsxrYbQGFCMqBDhFHyK5q2UvcQ==} + engines: {node: '>= 12'} + hasBin: true + dev: false + /matcher/5.0.0: resolution: {integrity: sha512-s2EMBOWtXFc8dgqvoAzKJXxNHibcdJMV0gwqKUaw9E2JBJuGUK7DrNKrA6g/i+v72TT16+6sVm5mS3thaMLQUw==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} @@ -5141,6 +5133,13 @@ packages: brace-expansion: 2.0.1 dev: true + /minimatch/5.1.0: + resolution: {integrity: sha512-9TPBGGak4nHfGZsPBohm9AWg6NoT7QTCehS3BIJABslyZbzxfV78QM2Y6+i741OPZIafFAaiiEMh5OyIrJPgtg==} + engines: {node: '>=10'} + dependencies: + brace-expansion: 2.0.1 + dev: false + /minimist/1.2.7: resolution: {integrity: sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g==} dev: true @@ -5252,15 +5251,15 @@ packages: resolution: {integrity: sha512-9iN1ka/9zmX1ZvLV9ewJYEk9h7RyRRtqdK0woXcqohu8EWIerfPUjYJPg0ULy0UqP7cslmdGc8xKDJcojlKiaw==} dev: true - /next/12.3.1_biqbaboplfbrettd7655fr4n2y: - resolution: {integrity: sha512-l7bvmSeIwX5lp07WtIiP9u2ytZMv7jIeB8iacR28PuUEFG5j0HGAPnMqyG5kbZNBG2H7tRsrQ4HCjuMOPnANZw==} - engines: {node: '>=12.22.0'} + /next/13.0.3_biqbaboplfbrettd7655fr4n2y: + resolution: {integrity: sha512-rFQeepcenRxKzeKlh1CsmEnxsJwhIERtbUjmYnKZyDInZsU06lvaGw5DT44rlNp1Rv2MT/e9vffZ8vK+ytwXHA==} + engines: {node: '>=14.6.0'} hasBin: true peerDependencies: fibers: '>= 3.1.0' node-sass: ^6.0.0 || ^7.0.0 - react: ^17.0.2 || ^18.0.0-0 - react-dom: ^17.0.2 || ^18.0.0-0 + react: ^18.2.0 + react-dom: ^18.2.0 sass: ^1.3.0 peerDependenciesMeta: fibers: @@ -5270,28 +5269,28 @@ packages: sass: optional: true dependencies: - '@next/env': 12.3.1 + '@next/env': 13.0.3 '@swc/helpers': 0.4.11 - caniuse-lite: 1.0.30001429 + caniuse-lite: 1.0.30001431 postcss: 8.4.14 react: 18.2.0 react-dom: 18.2.0_react@18.2.0 - styled-jsx: 5.0.7_react@18.2.0 + styled-jsx: 5.1.0_react@18.2.0 use-sync-external-store: 1.2.0_react@18.2.0 optionalDependencies: - '@next/swc-android-arm-eabi': 12.3.1 - '@next/swc-android-arm64': 12.3.1 - '@next/swc-darwin-arm64': 12.3.1 - '@next/swc-darwin-x64': 12.3.1 - '@next/swc-freebsd-x64': 12.3.1 - '@next/swc-linux-arm-gnueabihf': 12.3.1 - '@next/swc-linux-arm64-gnu': 12.3.1 - '@next/swc-linux-arm64-musl': 12.3.1 - '@next/swc-linux-x64-gnu': 12.3.1 - '@next/swc-linux-x64-musl': 12.3.1 - '@next/swc-win32-arm64-msvc': 12.3.1 - '@next/swc-win32-ia32-msvc': 12.3.1 - '@next/swc-win32-x64-msvc': 12.3.1 + '@next/swc-android-arm-eabi': 13.0.3 + '@next/swc-android-arm64': 13.0.3 + '@next/swc-darwin-arm64': 13.0.3 + '@next/swc-darwin-x64': 13.0.3 + '@next/swc-freebsd-x64': 13.0.3 + '@next/swc-linux-arm-gnueabihf': 13.0.3 + '@next/swc-linux-arm64-gnu': 13.0.3 + '@next/swc-linux-arm64-musl': 13.0.3 + '@next/swc-linux-x64-gnu': 13.0.3 + '@next/swc-linux-x64-musl': 13.0.3 + '@next/swc-win32-arm64-msvc': 13.0.3 + '@next/swc-win32-ia32-msvc': 13.0.3 + '@next/swc-win32-x64-msvc': 13.0.3 transitivePeerDependencies: - '@babel/core' - babel-plugin-macros @@ -5356,16 +5355,6 @@ packages: set-blocking: 2.0.0 dev: true - /npmlog/6.0.2: - resolution: {integrity: sha512-/vBvz5Jfr9dT/aFWd0FIRf+T/Q2WBsLENygUaFUqstqsycmZAP/t5BvFJTK0viFmSUxiUKTUplWy5vt+rvKIxg==} - engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} - dependencies: - are-we-there-yet: 3.0.1 - console-control-strings: 1.1.0 - gauge: 4.0.4 - set-blocking: 2.0.0 - dev: true - /npx-import/1.1.4: resolution: {integrity: sha512-3ShymTWOgqGyNlh5lMJAejLuIv3W1K3fbI5Ewc6YErZU3Sp0PqsNs8UIU1O8z5+KVl/Du5ag56Gza9vdorGEoA==} dependencies: @@ -5412,8 +5401,8 @@ packages: object-keys: 1.1.1 dev: true - /object.entries/1.1.5: - resolution: {integrity: sha512-TyxmjUoZggd4OrrU1W66FMDG6CuqJxsFvymeyXI51+vQLN67zYfZseptRge703kKQdo4uccgAKebXFcRCzk4+g==} + /object.entries/1.1.6: + resolution: {integrity: sha512-leTPzo4Zvg3pmbQ3rDK69Rl8GQvIqMWubrkxONG9/ojtFE2rD9fjMKfSI5BxW3osRH1m6VdzmqK8oAY9aT4x5w==} engines: {node: '>= 0.4'} dependencies: call-bind: 1.0.2 @@ -5421,8 +5410,8 @@ packages: es-abstract: 1.20.4 dev: true - /object.fromentries/2.0.5: - resolution: {integrity: sha512-CAyG5mWQRRiBU57Re4FKoTBjXfDoNwdFVH2Y1tS9PqCsfUTymAohOkEMSG3aRNKmv4lV3O7p1et7c187q6bynw==} + /object.fromentries/2.0.6: + resolution: {integrity: sha512-VciD13dswC4j1Xt5394WR4MzmAQmlgN72phd/riNp9vtD7tp4QQWJ0R4wvclXcafgcYK8veHRed2W6XeGBvcfg==} engines: {node: '>= 0.4'} dependencies: call-bind: 1.0.2 @@ -5430,15 +5419,15 @@ packages: es-abstract: 1.20.4 dev: true - /object.hasown/1.1.1: - resolution: {integrity: sha512-LYLe4tivNQzq4JdaWW6WO3HMZZJWzkkH8fnI6EebWl0VZth2wL2Lovm74ep2/gZzlaTdV62JZHEqHQ2yVn8Q/A==} + /object.hasown/1.1.2: + resolution: {integrity: sha512-B5UIT3J1W+WuWIU55h0mjlwaqxiE5vYENJXIXZ4VFe05pNYrkKuK0U/6aFcb0pKywYJh7IhfoqUfKVmrJJHZHw==} dependencies: define-properties: 1.1.4 es-abstract: 1.20.4 dev: true - /object.values/1.1.5: - resolution: {integrity: sha512-QUZRW0ilQ3PnPpbNtgdNV1PDbEqLIiSFB3l+EnGtBQ/8SUTLj1PZwtQHABZtLgwpJZTSZhuGLOGk57Drx2IvYg==} + /object.values/1.1.6: + resolution: {integrity: sha512-FVVTkD1vENCsAcwNs9k6jea2uHC/X0+JcjG8YA60FN5CMaJmG95wT9jek/xX9nornqGRrBkKtzuAu2wuHpKqvw==} engines: {node: '>= 0.4'} dependencies: call-bind: 1.0.2 @@ -5603,7 +5592,7 @@ packages: dependencies: eventemitter3: 4.0.7 p-timeout: 5.1.0 - dev: false + dev: true /p-retry/5.1.1: resolution: {integrity: sha512-i69WkEU5ZAL8mrmdmVviWwU+DN+IUF8f4sSJThoJ3z5A7Nn5iuO5ROX3Boye0u+uYQLOSfgFl7SuFZCjlAVbQA==} @@ -5623,6 +5612,7 @@ packages: /p-timeout/5.1.0: resolution: {integrity: sha512-auFDyzzzGZZZdHz3BtET9VEz0SE/uMEAx7uWfGPucfzEwwe/xH0iVeZibQmANYE/hp9T2+UUZT5m+BKyrDp3Ew==} engines: {node: '>=12'} + dev: true /p-timeout/6.0.0: resolution: {integrity: sha512-5iS61MOdUMemWH9CORQRxVXTp9g5K8rPnI9uQpo97aWgsH3vVXKjkIhDi+OgIDmN3Ly9+AZ2fZV01Wut1yzfKA==} @@ -5825,17 +5815,17 @@ packages: source-map-js: 1.0.2 dev: false - /preact-render-to-string/5.2.6_preact@10.11.2: + /preact-render-to-string/5.2.6_preact@10.11.3: resolution: {integrity: sha512-JyhErpYOvBV1hEPwIxc/fHWXPfnEGdRKxc8gFdAZ7XV4tlzyzG847XAyEZqoDnynP88akM4eaHcSOzNcLWFguw==} peerDependencies: preact: '>=10' dependencies: - preact: 10.11.2 + preact: 10.11.3 pretty-format: 3.8.0 dev: false - /preact/10.11.2: - resolution: {integrity: sha512-skAwGDFmgxhq1DCBHke/9e12ewkhc7WYwjuhHB8HHS8zkdtITXLRmUMTeol2ldxvLwYtwbFeifZ9uDDWuyL4Iw==} + /preact/10.11.3: + resolution: {integrity: sha512-eY93IVpod/zG3uMF22Unl8h9KkrcKIRs2EGar8hwLZZDU1lkjph303V9HZBwufh2s736U6VXuhD109LYqPoffg==} dev: false /prebuild-install/7.1.1: @@ -6301,6 +6291,14 @@ packages: rechoir: 0.6.2 dev: true + /shiki/0.11.1: + resolution: {integrity: sha512-EugY9VASFuDqOexOgXR18ZV+TbFrQHeCpEYaXamO+SZlsnT/2LxuLBX25GGtIrwaEVFXUAbUQ601SWE2rMwWHA==} + dependencies: + jsonc-parser: 3.2.0 + vscode-oniguruma: 1.6.2 + vscode-textmate: 6.0.0 + dev: false + /side-channel/1.0.4: resolution: {integrity: sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==} dependencies: @@ -6442,8 +6440,8 @@ packages: resolution: {integrity: sha512-KGzahc7puUKkzyMt+IqAep+TVNbKP+k2Lmwhub39m1AsTSkaDutx56aDCo+HLDzf/D26BIHTJWNiTG1KAJiQCg==} dev: true - /stack-utils/2.0.5: - resolution: {integrity: sha512-xrQcmYhOsn/1kX+Vraq+7j4oE2j/6BFscZ0etmYg81xuM8Gq0022Pxb8+IqgOFUIaxHs0KaSb7T1+OegiNrNFA==} + /stack-utils/2.0.6: + resolution: {integrity: sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==} engines: {node: '>=10'} dependencies: escape-string-regexp: 2.0.0 @@ -6475,9 +6473,15 @@ packages: readable-stream: 3.6.0 dev: true + /streaming-iterables/7.1.0: + resolution: {integrity: sha512-t2KmiLVhqafTRqGefD98s5XAMskfkfprr/BTzPIZz0kWB23iyR7XUkY03yjUf4aZpAuuV2/2SUOVri3LgKuOKw==} + engines: {node: '>=14'} + dev: false + /streamsearch/1.1.0: resolution: {integrity: sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==} engines: {node: '>=10.0.0'} + dev: true /string-argv/0.3.1: resolution: {integrity: sha512-a1uQGz7IyVy9YwhqjZIZu1c8JO8dNIe20xBmSS6qu9kv++k3JGzCVmprbNN5Kn+BgzD5E7YYwg1CcjuJMRNsvg==} @@ -6509,8 +6513,8 @@ packages: emoji-regex: 9.2.2 strip-ansi: 7.0.1 - /string.prototype.matchall/4.0.7: - resolution: {integrity: sha512-f48okCX7JiwVi1NXCVWcFnZgADDC/n2vePlQ/KUCNqCikLLilQvwjMO8+BHVKvgzH0JB0J9LEPgxOGT02RoETg==} + /string.prototype.matchall/4.0.8: + resolution: {integrity: sha512-6zOCOcJ+RJAQshcTvXPHoxoQGONa3e/Lqx90wUA+wEzX78sg5Bo+1tQo4N0pohS0erG9qtCqJDjNCQBjeWVxyg==} dependencies: call-bind: 1.0.2 define-properties: 1.1.4 @@ -6522,8 +6526,8 @@ packages: side-channel: 1.0.4 dev: true - /string.prototype.trim/1.2.6: - resolution: {integrity: sha512-8lMR2m+U0VJTPp6JjvJTtGyc4FIGq9CdRt7O9p6T0e6K4vjU+OP+SQJpbe/SBmRcCUIvNUnjsbmY6lnMp8MhsQ==} + /string.prototype.trim/1.2.7: + resolution: {integrity: sha512-p6TmeT1T3411M8Cgg9wBTMRtY2q9+PNy9EV1i2lIXUN/btt763oIfxwN3RR8VU6wHX8j/1CFy0L+YuThm6bgOg==} engines: {node: '>= 0.4'} dependencies: call-bind: 1.0.2 @@ -6531,16 +6535,16 @@ packages: es-abstract: 1.20.4 dev: true - /string.prototype.trimend/1.0.5: - resolution: {integrity: sha512-I7RGvmjV4pJ7O3kdf+LXFpVfdNOxtCW/2C8f6jNiW4+PQchwxkCDzlk1/7p+Wl4bqFIZeF47qAHXLuHHWKAxog==} + /string.prototype.trimend/1.0.6: + resolution: {integrity: sha512-JySq+4mrPf9EsDBEDYMOb/lM7XQLulwg5R/m1r0PXEFqrV0qHvl58sdTilSXtKOflCsK2E8jxf+GKC0T07RWwQ==} dependencies: call-bind: 1.0.2 define-properties: 1.1.4 es-abstract: 1.20.4 dev: true - /string.prototype.trimstart/1.0.5: - resolution: {integrity: sha512-THx16TJCGlsN0o6dl2o6ncWUsdgnLRSA23rRE5pyGBw/mLr3Ej/R2LaqCtgP8VNMGZsvMWnf9ooZPyY2bHvUFg==} + /string.prototype.trimstart/1.0.6: + resolution: {integrity: sha512-omqjMDaY92pbn5HOX7f9IccLA+U1tA9GvtU4JrodiXFfYB7jPzzHpRzpglLAjtUV6bB557zwClJezTqnAiYnQA==} dependencies: call-bind: 1.0.2 define-properties: 1.1.4 @@ -6604,8 +6608,8 @@ packages: engines: {node: '>=8'} dev: true - /styled-jsx/5.0.7_react@18.2.0: - resolution: {integrity: sha512-b3sUzamS086YLRuvnaDigdAewz1/EFYlHpYBP5mZovKEdQQOIIYq8lApylub3HHZ6xFjV051kkGU7cudJmrXEA==} + /styled-jsx/5.1.0_react@18.2.0: + resolution: {integrity: sha512-/iHaRJt9U7T+5tp6TRelLnqBqiaIT0HsO0+vgyj8hK2KUk7aejFqRrumqPUlAqDwAj8IbS/1hk3IhBAAK/FCUQ==} engines: {node: '>= 12.0.0'} peerDependencies: '@babel/core': '*' @@ -6617,6 +6621,7 @@ packages: babel-plugin-macros: optional: true dependencies: + client-only: 0.0.1 react: 18.2.0 dev: false @@ -6679,7 +6684,7 @@ packages: object.assign: 4.1.4 resolve: 2.0.0-next.4 resumer: 0.0.0 - string.prototype.trim: 1.2.6 + string.prototype.trim: 1.2.7 through: 2.3.8 dev: true @@ -6708,6 +6713,11 @@ packages: engines: {node: '>=8'} dev: true + /temp-dir/3.0.0: + resolution: {integrity: sha512-nHc6S/bwIilKHNRgK/3jlhDoIHcp45YgyiwcAk46Tr0LfEqGBVpmiAyuiuxeVE44m3mXnEeVhaipLOEWmH+Njw==} + engines: {node: '>=14.16'} + dev: true + /tempy/3.0.0: resolution: {integrity: sha512-B2I9X7+o2wOaW4r/CWMkpOO9mdiTRCxXNgob6iGvPmfPWgH/KyUD6Uy5crtWBxIBe3YrNZKR2lSzv1JJKWD4vA==} engines: {node: '>=14.16'} @@ -6872,16 +6882,37 @@ packages: engines: {node: '>=12.20'} dev: true - /type-fest/3.1.0: - resolution: {integrity: sha512-StmrZmK3eD9mDF9Vt7UhqthrDSk66O9iYl5t5a0TSoVkHjl0XZx/xuc/BRz4urAXXGHOY5OLsE0RdJFIApSFmw==} + /type-fest/3.2.0: + resolution: {integrity: sha512-Il3wdLRzWvbAEtocgxGQA9YOoRVeVUGOMBtel5LdEpNeEAol6GJTLw8GbX6Z8EIMfvfhoOXs2bwOijtAZdK5og==} engines: {node: '>=14.16'} dev: false + /typedoc-plugin-missing-exports/1.0.0_typedoc@0.23.21: + resolution: {integrity: sha512-7s6znXnuAj1eD9KYPyzVzR1lBF5nwAY8IKccP5sdoO9crG4lpd16RoFpLsh2PccJM+I2NASpr0+/NMka6ThwVA==} + peerDependencies: + typedoc: 0.22.x || 0.23.x + dependencies: + typedoc: 0.23.21_typescript@4.8.4 + dev: false + + /typedoc/0.23.21_typescript@4.8.4: + resolution: {integrity: sha512-VNE9Jv7BgclvyH9moi2mluneSviD43dCE9pY8RWkO88/DrEgJZk9KpUk7WO468c9WWs/+aG6dOnoH7ccjnErhg==} + engines: {node: '>= 14.14'} + hasBin: true + peerDependencies: + typescript: 4.6.x || 4.7.x || 4.8.x || 4.9.x + dependencies: + lunr: 2.3.9 + marked: 4.2.2 + minimatch: 5.1.0 + shiki: 0.11.1 + typescript: 4.8.4 + dev: false + /typescript/4.8.4: resolution: {integrity: sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ==} engines: {node: '>=4.2.0'} hasBin: true - dev: true /uint8arrays/4.0.2: resolution: {integrity: sha512-8CWXXZdOvVrIL4SeY/Gnp+idxxiGK4XFkP4FY26Sx/fpTz/b6vv4BVWELMDzQweSyyhdcuAcU14H6izzB6k1Cw==} @@ -6899,13 +6930,6 @@ packages: which-boxed-primitive: 1.0.2 dev: true - /undici/5.12.0: - resolution: {integrity: sha512-zMLamCG62PGjd9HHMpo05bSLvvwWOZgGeiWlN/vlqu3+lRo3elxktVGEyLMX+IO7c2eflLjcW74AlkhEZm15mg==} - engines: {node: '>=12.18'} - dependencies: - busboy: 1.6.0 - dev: false - /undici/5.9.1: resolution: {integrity: sha512-6fB3a+SNnWEm4CJbgo0/CWR8RGcOCQP68SF4X0mxtYTq2VNN8T88NYrWVBAeSX+zb7bny2dx2iYhP3XHi00omg==} engines: {node: '>=12.18'} @@ -6974,6 +6998,14 @@ packages: resolution: {integrity: sha512-cXEIW6cfr15lFv563k4GuVuW/fiwjknytD37jIOLSdSWuOI6WnO/oKwmP2FQTU2l01LP8/M5TSAJpzUaGe3uWg==} dev: false + /vscode-oniguruma/1.6.2: + resolution: {integrity: sha512-KH8+KKov5eS/9WhofZR8M8dMHWN2gTxjMsG4jd04YhpbPR91fUj7rYQ2/XjeHCJWbg7X++ApRIU9NUwM2vTvLA==} + dev: false + + /vscode-textmate/6.0.0: + resolution: {integrity: sha512-gu73tuZfJgu+mvCSy4UZwd2JXykjK9zAZsfmDeut5dx/1a7FeTk0XwJsSuqQn+cuMCGVbIBfl+s53X4T19DnzQ==} + dev: false + /watch/1.0.2: resolution: {integrity: sha512-1u+Z5n9Jc1E2c7qDO8SinPoZuHj7FgbgU1olSFoyaklduDvvtX7GMMtlE6OC9FTXq4KvNAOfj6Zu4vI1e9bAKA==} engines: {node: '>=0.1.95'} @@ -7067,7 +7099,7 @@ packages: /wide-align/1.1.5: resolution: {integrity: sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==} dependencies: - string-width: 4.2.3 + string-width: 1.0.2 dev: true /word-wrap/1.2.3: @@ -7083,8 +7115,8 @@ packages: resolution: {integrity: sha512-y38RiVOEJPmqSSQniVPKQrWE8XocqeRWO9TwgfXTMARzQa3aGwsaBwUdOBn5MJukZwIkGOYsljK76kMGLu5aOA==} dev: false - /wrangler/2.1.15: - resolution: {integrity: sha512-5iqtFNo+zbu1FTnQQU/1Y+WWxIEuPIy71fe0uvqqFl0pSlkAtZJ+ufw8UYVxf2Mprw4ia4mSDdhV+hHpZO1sLQ==} + /wrangler/2.3.2: + resolution: {integrity: sha512-PWqNJclB7SGIRpuJSrF9zuTfLAqrS1VPembhf6HPGJC6zL96hx3XcHC01VjChC0lsadUqGRa7/iEvWtwdUy6kw==} engines: {node: '>=16.13.0'} hasBin: true dependencies: @@ -7143,16 +7175,16 @@ packages: resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} dev: true - /write-file-atomic/4.0.2: - resolution: {integrity: sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==} - engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + /write-file-atomic/5.0.0: + resolution: {integrity: sha512-R7NYMnHSlV42K54lwY9lvW6MnSm1HSJqZL3xiSgi9E7//FYaI74r2G0rd+/X6VAMkHEdzxQaU5HUOXWUz5kA/w==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} dependencies: imurmurhash: 0.1.4 signal-exit: 3.0.7 dev: true - /ws/8.10.0: - resolution: {integrity: sha512-+s49uSmZpvtAsd2h37vIPy1RBusaLawVe8of+GyEPsaJTCMpj/2v8NpeK1SHXjBlQ95lQTmQofOJnFiLoaN3yw==} + /ws/8.11.0: + resolution: {integrity: sha512-HPG3wQd9sNQoT9xHyNCXoDUa+Xw/VevmY9FoHyQ+g+rrMn4j6FB4np7Z0OhdTgjx6MgQLK7jwSy1YecU1+4Asg==} engines: {node: '>=10.0.0'} peerDependencies: bufferutil: ^4.0.1 diff --git a/tsconfig.json b/tsconfig.json index 610b3e99b..15524ac91 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -32,5 +32,14 @@ "skipLibCheck": true, "stripInternal": true, "resolveJsonModule": true + }, + "typedocOptions": { + "entryPointStrategy": "packages", + "entryPoints": ["packages/access-client", "packages/upload-client"], + "excludeExternals": true, + "darkHighlightTheme": "github-dark", + "navigationLinks": { + "Github": "https://github.com/web3-storage/w3protocol" + } } }