Skip to content

Commit

Permalink
fix: make d1 spaces.metadata nullable and change to kysely
Browse files Browse the repository at this point in the history
- d1 tables are now typed
  • Loading branch information
hugomrdias committed Dec 12, 2022
1 parent a4f20a9 commit 834ac15
Show file tree
Hide file tree
Showing 19 changed files with 412 additions and 207 deletions.
44 changes: 44 additions & 0 deletions packages/access-api/migrations/0003_space.metadata_can_be_null.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
-- Migration number: 0003 2022-12-12T18:58:30.339Z
ALTER TABLE spaces
RENAME TO _spaces_old;

CREATE TABLE
spaces (
did TEXT NOT NULL PRIMARY KEY,
product TEXT NOT NULL,
email TEXT NOT NULL,
agent TEXT NOT NULL,
inserted_at TEXT NOT NULL DEFAULT (strftime ('%Y-%m-%dT%H:%M:%fZ', 'now')),
updated_at TEXT NOT NULL DEFAULT (strftime ('%Y-%m-%dT%H:%M:%fZ', 'now')),
metadata JSON DEFAULT EMPTY,
invocation TEXT NOT NULL DEFAULT EMPTY,
delegation TEXT DEFAULT NULL,
UNIQUE (did)
);

INSERT INTO
spaces (
did,
product,
email,
agent,
inserted_at,
updated_at,
metadata,
invocation,
delegation
)
SELECT
did,
product,
email,
agent,
inserted_at,
updated_at,
metadata,
invocation,
delegation
FROM
_spaces_old;

DROP TABLE "_spaces_old";
5 changes: 3 additions & 2 deletions packages/access-api/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,13 @@
"@web3-storage/access": "workspace:^",
"@web3-storage/capabilities": "workspace:^",
"@web3-storage/worker-utils": "0.4.3-dev",
"kysely": "^0.22.0",
"kysely-d1": "^0.0.6",
"p-retry": "^5.1.2",
"preact": "^10.11.3",
"preact-render-to-string": "^5.2.6",
"qrcode": "^1.5.1",
"toucan-js": "^2.7.0",
"workers-qb": "^0.1.2"
"toucan-js": "^2.7.0"
},
"devDependencies": {
"@cloudflare/workers-types": "^3.18.0",
Expand Down
16 changes: 10 additions & 6 deletions packages/access-api/src/bindings.d.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import type { Logging } from '@web3-storage/worker-utils/logging'
import type { SpaceTable } from '@web3-storage/access/types'
import type { Handler as _Handler } from '@web3-storage/worker-utils/router'
import type { Signer } from '@ucanto/interface'
import { Email } from './utils/email.js'
import { Spaces } from './kvs/spaces.js'
import { Validations } from './kvs/validations.js'
import { D1QB } from 'workers-qb'
import { Spaces } from './models/spaces.js'
import { Validations } from './models/validations.js'
import { loadConfig } from './config.js'

export {}
Expand Down Expand Up @@ -42,11 +41,10 @@ export interface RouteContext {
config: ReturnType<typeof loadConfig>
url: URL
email: Email
kvs: {
models: {
spaces: Spaces
validations: Validations
}
db: D1QB
}

export type Handler = _Handler<RouteContext>
Expand Down Expand Up @@ -79,6 +77,12 @@ export interface ModuleWorker {
scheduled?: ModuleWorker.CronHandler<Env>
}

// D1 types

export interface D1ErrorRaw extends Error {
cause: Error & { code: string }
}

export interface D1Schema {
spaces: SpaceTable
}
148 changes: 0 additions & 148 deletions packages/access-api/src/kvs/spaces.js

This file was deleted.

97 changes: 97 additions & 0 deletions packages/access-api/src/models/spaces.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
// @ts-ignore
// eslint-disable-next-line no-unused-vars
import * as Ucanto from '@ucanto/interface'
import { delegationToString } from '@web3-storage/access/encoding'
import { Kysely } from 'kysely'
import { D1Dialect } from 'kysely-d1'
import { D1Error, SpacePlugin } from '../utils/d1.js'

const spacePlugin = new SpacePlugin()

/**
* Spaces
*/
export class Spaces {
/**
*
* @param {D1Database} d1
*/
constructor(d1) {
this.d1 = /** @type {Kysely<import('../bindings').D1Schema>} */ (
new Kysely({ dialect: new D1Dialect({ database: d1 }) })
)
}

/**
* @param {import('@web3-storage/capabilities/types').VoucherRedeem} capability
* @param {Ucanto.Invocation<import('@web3-storage/capabilities/types').VoucherRedeem>} invocation
* @param {Ucanto.Delegation<[import('@web3-storage/access/types').Top]> | undefined} delegation
*/
async create(capability, invocation, delegation) {
try {
const metadata =
/** @type {import('@web3-storage/access/types').SpaceTableMetadata | undefined} */ (
/** @type {unknown} */ (invocation.facts[0])
)
const result = await this.d1
.withPlugin(spacePlugin)
.insertInto('spaces')
.values({
agent: invocation.issuer.did(),
did: capability.nb.space,
email: capability.nb.identity.replace('mailto:', ''),
invocation: await delegationToString(invocation),
product: capability.nb.product,
metadata,
delegation: !delegation
? undefined
: await delegationToString(delegation),
})
.returning('spaces.did')
.execute()
return { data: result }
} catch (error) {
return {
error: new D1Error(
/** @type {import('../bindings').D1ErrorRaw} */ (error)
),
}
}
}

/**
* Get space by DID
*
* @param {Ucanto.URI<"did:">} did
*/
async get(did) {
const space = await this.d1
.withPlugin(spacePlugin)
.selectFrom('spaces')
.selectAll()
.where('spaces.did', '=', did)
.executeTakeFirst()

if (space) {
return space
}
}

/**
* @param {Ucanto.URI<"mailto:">} email
*/
async getByEmail(email) {
const spaces = await this.d1
.withPlugin(spacePlugin)
.selectFrom('spaces')
.selectAll()
.where('spaces.email', '=', email.replace('mailto:', ''))
.execute()

if (spaces.length === 0) {
return
}

return spaces
}
}
File renamed without changes.
4 changes: 2 additions & 2 deletions packages/access-api/src/routes/validate-email.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ export async function validateEmail(req, env) {
}
if (req.query && req.query.ucan) {
try {
const delegation = await env.kvs.validations.put(
const delegation = await env.models.validations.put(
/** @type {import('@web3-storage/access/src/types.js').EncodedDelegation<[import('@web3-storage/access/src/types.js').VoucherClaim]>} */ (
req.query.ucan
)
Expand Down Expand Up @@ -62,7 +62,7 @@ export async function validateEmail(req, env) {
*/
async function recover(req, env) {
try {
const delegation = await env.kvs.validations.put(
const delegation = await env.models.validations.put(
/** @type {import('@web3-storage/access/src/types.js').EncodedDelegation<[import('@web3-storage/access/src/types.js').SpaceRecover]>} */ (
req.query.ucan
)
Expand Down
4 changes: 2 additions & 2 deletions packages/access-api/src/routes/validate-ws.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import pRetry from 'p-retry'

const run = async (
/** @type {import('../kvs/validations').Validations} */ kv,
/** @type {import('../models/validations').Validations} */ kv,
/** @type {WebSocket} */ server,
/** @type {string} */ did
) => {
Expand Down Expand Up @@ -36,7 +36,7 @@ export async function validateWS(req, env) {
const { did } = JSON.parse(msg.data)

try {
await pRetry(() => run(env.kvs.validations, server, did), {
await pRetry(() => run(env.models.validations, server, did), {
retries: 200,
minTimeout: 1000,
factor: 1,
Expand Down
Loading

0 comments on commit 834ac15

Please sign in to comment.