chore: upgrade to typescript 7 with tsconfig strictest

This commit is contained in:
2026-09-06 22:29:02 +02:00
parent 6a4d40e7be
commit 849ab7e4c5
9 changed files with 54 additions and 26 deletions
+2 -1
View File
@@ -3,11 +3,12 @@ import { access, constants, writeFile } from 'node:fs/promises'
import { basename, resolve } from 'node:path' import { basename, resolve } from 'node:path'
import { decode } from '@msgpack/msgpack' import { decode } from '@msgpack/msgpack'
import pretty from 'pretty-bytes' import pretty from 'pretty-bytes'
import { decrypt, deriveKey, setServer, getServer, info, get, decompress } from '@cryptgeon/shared' import { decrypt, deriveKey, setServer, info, get, decompress } from '@cryptgeon/shared'
export async function download(url: URL, all: boolean, suggestedPassword?: string) { export async function download(url: URL, all: boolean, suggestedPassword?: string) {
setServer(url.origin) setServer(url.origin)
const id = url.pathname.split('/')[2] const id = url.pathname.split('/')[2]
if (!id) throw new Error('Invalid URL')
const meta = await info(id) const meta = await info(id)
if (!meta) throw new Error('Note does not exist or is expired') if (!meta) throw new Error('Note does not exist or is expired')
+2 -2
View File
@@ -1,9 +1,9 @@
import { readFile, stat } from 'node:fs/promises' import { readFile } from 'node:fs/promises'
import { basename } from 'node:path' import { basename } from 'node:path'
import { encode } from '@msgpack/msgpack' import { encode } from '@msgpack/msgpack'
import mime from 'mime' import mime from 'mime'
import { encrypt, generateKey, deriveKey, randomBytes, setServer, getServer, create, utf8ToBytes, compress } from '@cryptgeon/shared' import { encrypt, generateKey, deriveKey, randomBytes, getServer, create, compress } from '@cryptgeon/shared'
export type UploadOptions = { views?: number; expiration?: number; password?: string } export type UploadOptions = { views?: number; expiration?: number; password?: string }
+16 -7
View File
@@ -21,7 +21,8 @@ const views = new Option('-v --views <number>', 'Amount of views before getting
const minutes = new Option('-m --minutes <number>', 'Minutes before the note expires').argParser(parseNumber) const minutes = new Option('-m --minutes <number>', 'Minutes before the note expires').argParser(parseNumber)
// Node 18 guard // Node 18 guard
parseInt(process.version.slice(1).split(',')[0]) < 18 && exit('Node 18 or higher is required') const major = Number(process.version.slice(1).split('.')[0])
if (!Number.isFinite(major) || major < 18) exit('Node 18 or higher is required')
// @ts-ignore // @ts-ignore
const version: string = VERSION const version: string = VERSION
@@ -33,10 +34,10 @@ program
.description('show information about the server') .description('show information about the server')
.addOption(server) .addOption(server)
.action(async (options) => { .action(async (options) => {
setServer(options.server) setServer(options.server!)
const response = await status() const response = await status()
const formatted = Object.fromEntries( const formatted = Object.fromEntries(
Object.entries({ ...response, max_size: prettyBytes(response.max_size as number) }) Object.entries({ ...response, max_size: prettyBytes(response.max_size) })
.filter(([key]) => !key.startsWith('theme_')) .filter(([key]) => !key.startsWith('theme_'))
) )
console.table(formatted) console.table(formatted)
@@ -51,11 +52,15 @@ send
.addOption(minutes) .addOption(minutes)
.addOption(password) .addOption(password)
.action(async (files, options) => { .action(async (files, options) => {
setServer(options.server) setServer(options.server!)
await checkConstrains(options) await checkConstrains(options)
options.password ||= await getStdin() options.password ||= await getStdin()
try { try {
const url = await upload(files, { views: options.views, expiration: options.minutes, password: options.password }) const url = await upload(files, {
...(options.views !== undefined ? { views: options.views } : {}),
...(options.minutes !== undefined ? { expiration: options.minutes } : {}),
password: options.password,
})
console.log(`Note created:\n\n${url}`) console.log(`Note created:\n\n${url}`)
} catch { } catch {
exit('Could not create note') exit('Could not create note')
@@ -69,11 +74,15 @@ send
.addOption(minutes) .addOption(minutes)
.addOption(password) .addOption(password)
.action(async (text, options) => { .action(async (text, options) => {
setServer(options.server) setServer(options.server!)
await checkConstrains(options) await checkConstrains(options)
options.password ||= await getStdin() options.password ||= await getStdin()
try { try {
const url = await upload(text, { views: options.views, expiration: options.minutes, password: options.password }) const url = await upload(text, {
...(options.views !== undefined ? { views: options.views } : {}),
...(options.minutes !== undefined ? { expiration: options.minutes } : {}),
password: options.password,
})
console.log(`Note created:\n\n${url}`) console.log(`Note created:\n\n${url}`)
} catch { } catch {
exit('Could not create note') exit('Could not create note')
+2 -2
View File
@@ -10,8 +10,8 @@ export async function checkConstrains(constrains: { views?: number; minutes?: nu
if (!constrains.views && !constrains.minutes) constrains.views = 1 if (!constrains.views && !constrains.minutes) constrains.views = 1
const response = await status() const response = await status()
if (constrains.views && constrains.views > (response.max_views as number)) if (constrains.views && constrains.views > response.max_views)
exit(`Only a maximum of ${response.max_views} views allowed. ${constrains.views} given.`) exit(`Only a maximum of ${response.max_views} views allowed. ${constrains.views} given.`)
if (constrains.minutes && constrains.minutes > (response.max_expiration as number)) if (constrains.minutes && constrains.minutes > response.max_expiration)
exit(`Only a maximum of ${response.max_expiration} minutes allowed. ${constrains.minutes} given.`) exit(`Only a maximum of ${response.max_expiration} minutes allowed. ${constrains.minutes} given.`)
} }
+6 -5
View File
@@ -1,13 +1,14 @@
{ {
"extends": "@tsconfig/strictest/tsconfig.json",
"compilerOptions": { "compilerOptions": {
"target": "es2022", "target": "esnext",
"module": "es2022", "module": "esnext",
"moduleResolution": "Bundler", "moduleResolution": "Bundler",
"declaration": true, "declaration": true,
"emitDeclarationOnly": true, "emitDeclarationOnly": true,
"strict": true,
"outDir": "./dist", "outDir": "./dist",
"rootDir": "./src", "rootDir": "./src",
"allowSyntheticDefaultImports": true "allowSyntheticDefaultImports": true
} },
} "exclude": ["vite.config.ts"]
}
+5 -4
View File
@@ -8,14 +8,15 @@
}, },
"dependencies": { "dependencies": {
"@msgpack/msgpack": "^3.1.3", "@msgpack/msgpack": "^3.1.3",
"@noble/ciphers": "^2.2.0", "@noble/ciphers": "^2.4.0",
"@noble/hashes": "^2.2.0", "@noble/hashes": "^2.4.0",
"lz4js": "^0.2.0" "lz4js": "^0.2.0"
}, },
"devDependencies": { "devDependencies": {
"@tsconfig/strictest": "catalog:",
"@types/lz4js": "^0.2.2", "@types/lz4js": "^0.2.2",
"typescript": "^5.9.3", "typescript": "catalog:",
"vitest": "^4.1.7" "vitest": "^4.1.11"
}, },
"scripts": { "scripts": {
"test": "vitest run", "test": "vitest run",
+2 -2
View File
@@ -1,6 +1,6 @@
import { encode, decode } from "@msgpack/msgpack"; import { encode, decode } from "@msgpack/msgpack";
import type { ServerNote } from "./types.js"; import type { ServerNote, Status } from "./types.js";
let server = ""; let server = "";
@@ -51,7 +51,7 @@ export async function get(id: string): Promise<ServerNote | null> {
return { meta, data: d instanceof Uint8Array ? d : new Uint8Array(d) } satisfies ServerNote; return { meta, data: d instanceof Uint8Array ? d : new Uint8Array(d) } satisfies ServerNote;
} }
export async function status(): Promise<Record<string, unknown>> { export async function status(): Promise<Status> {
const res = await fetch(api("status")); const res = await fetch(api("status"));
if (!res.ok) throw new Error("status failed"); if (!res.ok) throw new Error("status failed");
return res.json(); return res.json();
+17
View File
@@ -18,4 +18,21 @@ export type FileDTO = {
mime: string; mime: string;
size: number; size: number;
data: Uint8Array; data: Uint8Array;
};
export type Status = {
version: string;
max_size: number;
max_views: number;
max_expiration: number;
allow_advanced: boolean;
allow_files: boolean;
imprint_url: string;
imprint_html: string;
theme_image: string;
theme_text: string;
theme_page_title: string;
theme_favicon: string;
theme_new_note_notice: boolean;
theme_home_link: boolean;
}; };
+2 -3
View File
@@ -1,10 +1,9 @@
{ {
"extends": "@tsconfig/strictest/tsconfig.json",
"compilerOptions": { "compilerOptions": {
"target": "ESNext", "target": "ESNext",
"module": "ESNext", "module": "ESNext",
"moduleResolution": "bundler", "moduleResolution": "bundler",
"strict": true, "noEmit": true
"noEmit": true,
"skipLibCheck": true
} }
} }