| Packages | JSR |
|---|---|
| @maks11060/kv | |
| @maks11060/web | |
| @maks11060/oauth2 | |
| @maks11060/openapi | |
| @maks11060/webauthn |
| Packages | JSR | Repo |
|---|---|---|
| @maks11060/crypto | github | |
| @maks11060/bits | github | |
| @maks11060/otp | github |
deno add jsr:@maks11060/webpnpm jsr:@maks11060/webnpx jsr add @maks11060/webFeatures:
- Fetch with middleware
- BroadcastChannel with types
- URLPattern with typed exec (WIP)
Usage example
import {Fetch} from '@maks11060/web/fetch'
const api = Fetch({baseUrl: 'https://api.myip.com/'})
.use({
onRequest({request, options}) {
// Add authorization header
const headers = new Headers(request.headers)
headers.set('Authorization', 'Bearer token')
return new Request(request, {headers})
},
onResponse({response}) {
// Log response status
console.log(`Response: ${response.status}`)
},
})
const response = await api.fetch('/')
console.log(await response.json())import {BroadcastChannelTyped} from '@maks11060/web/broadcast-channel'
type BcType =
| {type: 'req'}
| {type: 'res'; value: number}
const bc = new BroadcastChannelTyped<BcType>('bc-test')
bc.addEventListener('message', (e) => {
console.log(e.data)
if (e.data.type === 'req') bc.postMessage({type: 'res', value: Date.now()})
})import {URLPatternTyped} from '@maks11060/web/url-pattern'
const p = new URLPatternTyped({
pathname: '/users/:userId{/posts/:postId}?',
})
const res = p.exec({pathname: '/users/123'})!
console.log(
res.pathname.groups satisfies {userId: string; postId?: string},
)implementation of the Webauthn api for a server with a browser-based api
Openapi 3.1 Schema builder.
Kv. Based on Deno.Kv
Usage example
import {kvModel} from '@maks11060/kv'
import {z} from 'zod'
using kv = await Deno.openKv(':memory:')
const userSchema = z.object({
id: z.string(),
username: z.string().min(2).max(50),
})
const passwdSchema = z.object({
id: z.string(),
passwd: z.string().min(4).max(60),
})
const userRegisterSchema = z.object({
username: userSchema.shape.username,
password: passwdSchema.shape.passwd,
})
const userLoginSchema = userRegisterSchema.pick({username: true, password: true})
const userModel = kvModel(kv, userSchema, {
prefix: 'user',
primaryKey: 'id',
index: {
username: {key: (user) => user.username.toLowerCase()},
},
})
const passwdModel = kvModel(kv, passwdSchema, {
prefix: 'passwd',
primaryKey: 'id',
})
const isUsernameAvailable = async (username: string) => {
return !await userModel.findByIndex('username', username)
}
const registerUser = async (data: z.input<typeof userRegisterSchema>) => {
const op = userModel.atomic()
const user = await userModel.create({username: data.username}, {op, transaction: true})
const passwd = await passwdModel.create({passwd: data.password}, {op, key: user.id})
return user
}
const loginUser = async (data: z.input<typeof userLoginSchema>) => {
const user = await userModel.findByIndex('username', data.username, {resolve: true})
if (!user) throw new Error('User not found')
const passwd = await passwdModel.find(user.id)
if (!passwd || passwd.passwd !== data.password) throw new Error('Password invalid')
return user
}