diff --git a/eslint.config.js b/eslint.config.js index 5c3fd17..8a585f0 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -6,13 +6,14 @@ import prettier from 'eslint-plugin-prettier/recommended' import react from 'eslint-plugin-react' import reactHooks from 'eslint-plugin-react-hooks' import tsdoc from 'eslint-plugin-tsdoc' +import {defineConfig} from 'eslint/config' import globals from 'globals' import path from 'node:path' import tseslint from 'typescript-eslint' const gitignore = path.resolve(import.meta.dirname, '.gitignore') -export default tseslint.config( +export default defineConfig( includeIgnoreFile(gitignore, '.gitignore'), // all files by default get shared globals @@ -54,10 +55,7 @@ export default tseslint.config( '@typescript-eslint/restrict-template-expressions': 'off', // I need to be able to do `while(true)`, come on yall... - '@typescript-eslint/no-unnecessary-condition': [ - 'warn', - {allowConstantLoopConditions: 'always'}, - ], + '@typescript-eslint/no-unnecessary-condition': ['warn', {allowConstantLoopConditions: 'always'}], // this breaks when I want to use a type parameter to allow type checking inline arguments // it's "unnecessary type parameters" or an `as` declaration, which I don't like diff --git a/prettier.config.js b/prettier.config.js index c670295..799ffa7 100644 --- a/prettier.config.js +++ b/prettier.config.js @@ -3,7 +3,7 @@ * @type {import("prettier").Config} */ export default { - printWidth: 100, + printWidth: 120, tabWidth: 2, semi: false, singleQuote: true, diff --git a/src/client/components/feed-import-nytimes.tsx b/src/client/components/feed-import-nytimes.tsx index bf54873..1a54418 100644 --- a/src/client/components/feed-import-nytimes.tsx +++ b/src/client/components/feed-import-nytimes.tsx @@ -113,9 +113,7 @@ export const FeedImportNYTimes: preact.FunctionComponent = () => { return (
{errors$.value.length > 0 && ( diff --git a/src/client/components/feed-import-podcasts.tsx b/src/client/components/feed-import-podcasts.tsx index 4d2c3c4..145d936 100644 --- a/src/client/components/feed-import-podcasts.tsx +++ b/src/client/components/feed-import-podcasts.tsx @@ -61,9 +61,7 @@ export const FeedImportPodcasts: preact.FunctionComponent = () => { return (
{errors$.value.length > 0 && ( diff --git a/src/client/components/feed-import-tech.tsx b/src/client/components/feed-import-tech.tsx index e8c572f..c616a38 100644 --- a/src/client/components/feed-import-tech.tsx +++ b/src/client/components/feed-import-tech.tsx @@ -60,9 +60,7 @@ export const FeedImportTech: preact.FunctionComponent = () => { return (
{errors$.value.length > 0 && ( diff --git a/src/client/page-app.tsx b/src/client/page-app.tsx index 3b66af0..6ffc9f1 100644 --- a/src/client/page-app.tsx +++ b/src/client/page-app.tsx @@ -22,11 +22,7 @@ export const App: preact.FunctionComponent = () => { const wsurl = `${wsproto}://${wshost}/stream` return ( - + diff --git a/src/client/root/context-database.tsx b/src/client/root/context-database.tsx index bd6aec0..4026e2d 100644 --- a/src/client/root/context-database.tsx +++ b/src/client/root/context-database.tsx @@ -13,9 +13,7 @@ export interface DatabaseContext { useDbSignal: (querier: DbQuerier) => ReadonlySignal } -export const DatabaseProvider: preact.FunctionComponent<{children: preact.ComponentChildren}> = ( - props, -) => { +export const DatabaseProvider: preact.FunctionComponent<{children: preact.ComponentChildren}> = (props) => { const db = useMemo(() => new Database(), []) function useDbSignal(querier: DbQuerier): ReadonlySignal { @@ -32,9 +30,7 @@ export const DatabaseProvider: preact.FunctionComponent<{children: preact.Compon return signal } - return ( - {props.children} - ) + return {props.children} } export function useDatabase() { diff --git a/src/client/skypod/action-dispatch/context.tsx b/src/client/skypod/action-dispatch/context.tsx index d5a468b..3ac0f00 100644 --- a/src/client/skypod/action-dispatch/context.tsx +++ b/src/client/skypod/action-dispatch/context.tsx @@ -8,10 +8,7 @@ import {LogicalClock} from '#realm/protocol/logical-clock' import {Action, ActionMap, ActionOpts} from '#skypod/actions' -export type MiddlewareFn = ( - this: undefined, - action: Action, -) => void | Action[] | Promise +export type MiddlewareFn = (this: undefined, action: Action) => void | Action[] | Promise export type MiddlewareRouterFn = ( this: undefined, @@ -89,11 +86,7 @@ export const ActionDispatchProvider: preact.FunctionComponent<{ } }, - action: ( - msg: N, - dat: ActionMap[N]['dat'], - opt?: ActionOpts, - ): ActionMap[N] => { + action: (msg: N, dat: ActionMap[N]['dat'], opt?: ActionOpts): ActionMap[N] => { const clk = identity.clock.now() return {typ: 'act', clk, msg, dat, opt} as ActionMap[N] }, @@ -135,11 +128,7 @@ export const ActionDispatchProvider: preact.FunctionComponent<{ }, }) - return ( - - {props.children} - - ) + return {props.children} } export function useActionDispatch() { diff --git a/src/client/skypod/feed-processor/worker.ts b/src/client/skypod/feed-processor/worker.ts index fa9335e..73b9811 100644 --- a/src/client/skypod/feed-processor/worker.ts +++ b/src/client/skypod/feed-processor/worker.ts @@ -47,24 +47,12 @@ class FeedFetch { async processPending() { const pendingFeeds = this.#db.feeds.where('lastRefresh.status').equals('pending') - return await this.#db.withLock( - 'feeds', - pendingFeeds, - this.#clock, - this.#owner, - this.#processLocked, - ) + return await this.#db.withLock('feeds', pendingFeeds, this.#clock, this.#owner, this.#processLocked) } async processUrls(urls: string[]) { const requestedFeeds = this.#db.feeds.where('url').anyOf(urls) - return await this.#db.withLock( - 'feeds', - requestedFeeds, - this.#clock, - this.#owner, - this.#processLocked, - ) + return await this.#db.withLock('feeds', requestedFeeds, this.#clock, this.#owner, this.#processLocked) } #poll = () => { diff --git a/src/cmd/register-ident.ts b/src/cmd/register-ident.ts index 2bbfbb3..6cea8d0 100644 --- a/src/cmd/register-ident.ts +++ b/src/cmd/register-ident.ts @@ -15,10 +15,7 @@ async function generateRegistrationJWT(realm?: string) { pubkey: await jwkExport.parseAsync(keypair.publicKey), } - const jwt = await generateSignableJwt(payload) - .setIssuedAt() - .setExpirationTime('1m') - .sign(keypair.privateKey) + const jwt = await generateSignableJwt(payload).setIssuedAt().setExpirationTime('1m').sign(keypair.privateKey) console.log('Generated Preauth JWT:') console.log(jwt) diff --git a/src/common/crypto/cipher.ts b/src/common/crypto/cipher.ts index 8cfe6d3..742caea 100644 --- a/src/common/crypto/cipher.ts +++ b/src/common/crypto/cipher.ts @@ -43,13 +43,10 @@ async function deriveKey( const nonce = encoder.encode(`${nonceStr}-nonce-cryptosystem`) const derivedsalt = new Uint8Array([...salt, ...nonce]) - return await crypto.subtle.deriveKey( - {...deriveAlgo, salt: derivedsalt, iterations}, - derivedkey, - encrAlgo, - false, - ['encrypt', 'decrypt'], - ) + return await crypto.subtle.deriveKey({...deriveAlgo, salt: derivedsalt, iterations}, derivedkey, encrAlgo, false, [ + 'encrypt', + 'decrypt', + ]) } /** @@ -96,11 +93,7 @@ export class Cipher { async encrypt(data: string | Uint8Array): Promise { const iv = crypto.getRandomValues(new Uint8Array(12)) const encoded = asUint8Array(data) - const encrypted = await crypto.subtle.encrypt( - {...encrAlgo, iv}, - this.#cryptokey, - encoded as BufferSource, - ) + const encrypted = await crypto.subtle.encrypt({...encrAlgo, iv}, this.#cryptokey, encoded as BufferSource) // output = [iv + encrypted] which gives us the auth tag diff --git a/src/common/crypto/jwts.ts b/src/common/crypto/jwts.ts index 846f3a1..a5a81bb 100644 --- a/src/common/crypto/jwts.ts +++ b/src/common/crypto/jwts.ts @@ -20,22 +20,20 @@ export type JWTTokenPayload = { * schema describing a decoded JWT. * **important** - this does no claims validation, only decoding from string to JWT! */ -export const jwtSchema: z.ZodType = z - .jwt({abort: true}) - .transform((token, ctx) => { - try { - const claims = jose.decodeJwt(token) - return {claims, token} - } catch (e) { - ctx.issues.push({ - code: 'custom', - message: `error while decoding token: ${e}`, - input: token, - }) +export const jwtSchema: z.ZodType = z.jwt({abort: true}).transform((token, ctx) => { + try { + const claims = jose.decodeJwt(token) + return {claims, token} + } catch (e) { + ctx.issues.push({ + code: 'custom', + message: `error while decoding token: ${e}`, + input: token, + }) - return z.NEVER - } - }) + return z.NEVER + } +}) /** * schema describing a verified payload in a JWT. diff --git a/src/common/socket.ts b/src/common/socket.ts index 95fde6e..9f0b391 100644 --- a/src/common/socket.ts +++ b/src/common/socket.ts @@ -66,11 +66,7 @@ export async function takeSocket(ws: WebSocket, signal?: AbortSignal): Promise( - ws: WebSocket, - schema: z.ZodType, - signal?: AbortSignal, -): Promise { +export async function takeSocketJson(ws: WebSocket, schema: z.ZodType, signal?: AbortSignal): Promise { const data = await takeSocket(ws, signal) return parseJson.pipe(schema).parseAsync(data) } @@ -191,10 +187,7 @@ export async function* streamSocket(ws: WebSocket, config_?: Partial, -): AsyncGenerator { +export async function* streamSocketJson(ws: WebSocket, config?: Partial): AsyncGenerator { for await (const message of streamSocket(ws, config)) { yield parseJson.parseAsync(message) } diff --git a/src/realm/client/components/connection-manager.tsx b/src/realm/client/components/connection-manager.tsx index c8b7cb3..266baa1 100644 --- a/src/realm/client/components/connection-manager.tsx +++ b/src/realm/client/components/connection-manager.tsx @@ -81,10 +81,7 @@ export const RealmConnectionManager: preact.FunctionComponent = () => {

Exchange an invite: -