better programmatic access

This commit is contained in:
Niccolo Borgioli 2024-08-22 20:01:14 +02:00
parent 5648c76f78
commit 784c54236b
10 changed files with 2205 additions and 1866 deletions

View File

@ -17,5 +17,5 @@
"npm-run-all": "^4.1.5", "npm-run-all": "^4.1.5",
"shelljs": "^0.8.5" "shelljs": "^0.8.5"
}, },
"packageManager": "pnpm@8.15.4" "packageManager": "pnpm@9.8.0"
} }

View File

@ -468,7 +468,7 @@ dependencies = [
[[package]] [[package]]
name = "cryptgeon" name = "cryptgeon"
version = "2.6.1" version = "2.7.0"
dependencies = [ dependencies = [
"actix-files", "actix-files",
"actix-web", "actix-web",

View File

@ -1,6 +1,6 @@
[package] [package]
name = "cryptgeon" name = "cryptgeon"
version = "2.6.1" version = "2.7.0"
authors = ["cupcakearmy <hi@nicco.io>"] authors = ["cupcakearmy <hi@nicco.io>"]
edition = "2021" edition = "2021"
rust-version = "1.80" rust-version = "1.80"

View File

@ -1,6 +1,6 @@
{ {
"name": "cryptgeon", "name": "cryptgeon",
"version": "2.6.1", "version": "2.7.0",
"homepage": "https://github.com/cupcakearmy/cryptgeon", "homepage": "https://github.com/cupcakearmy/cryptgeon",
"repository": { "repository": {
"type": "git", "type": "git",

View File

@ -1,34 +0,0 @@
#!/usr/bin/env node
import { build, context } from 'esbuild'
import pkg from '../package.json' assert { type: 'json' }
const common = {
bundle: true,
minify: true,
platform: 'node',
define: { VERSION: `"${pkg.version}"` },
}
const cliOptions = {
...common,
entryPoints: ['./src/cli.ts'],
format: 'cjs',
outfile: './dist/cli.cjs',
}
const indexOptions = {
...common,
entryPoints: ['./src/index.ts'],
outfile: './dist/index.mjs',
format: 'esm',
}
const watch = process.argv.slice(2)[0] === '--watch'
if (watch) {
const ctx = await context(cliOptions)
ctx.watch()
} else {
await build(cliOptions)
await build(indexOptions)
}

View File

@ -1,7 +1,7 @@
#!/usr/bin/env node #!/usr/bin/env node
import { Argument, Option, program } from '@commander-js/extra-typings' import { Argument, Option, program } from '@commander-js/extra-typings'
import { setBase, status } from '@cryptgeon/shared' import { setOptions, status } from '@cryptgeon/shared'
import prettyBytes from 'pretty-bytes' import prettyBytes from 'pretty-bytes'
import { download } from './download.js' import { download } from './download.js'
@ -33,7 +33,7 @@ program
.description('show information about the server') .description('show information about the server')
.addOption(server) .addOption(server)
.action(async (options) => { .action(async (options) => {
setBase(options.server) setOptions({ server: options.server })
const response = await status() const response = await status()
const formatted = { const formatted = {
...response, ...response,
@ -54,7 +54,7 @@ send
.addOption(minutes) .addOption(minutes)
.addOption(password) .addOption(password)
.action(async (files, options) => { .action(async (files, options) => {
setBase(options.server!) setOptions({ server: options.server })
await checkConstrains(options) await checkConstrains(options)
options.password ||= await getStdin() options.password ||= await getStdin()
try { try {
@ -72,7 +72,7 @@ send
.addOption(minutes) .addOption(minutes)
.addOption(password) .addOption(password)
.action(async (text, options) => { .action(async (text, options) => {
setBase(options.server!) setOptions({ server: options.server })
await checkConstrains(options) await checkConstrains(options)
options.password ||= await getStdin() options.password ||= await getStdin()
try { try {

View File

@ -1,4 +1,4 @@
import { Adapters, get, info, setBase } from '@cryptgeon/shared' import { Adapters, get, info, setOptions } from '@cryptgeon/shared'
import inquirer from 'inquirer' import inquirer from 'inquirer'
import { access, constants, writeFile } from 'node:fs/promises' import { access, constants, writeFile } from 'node:fs/promises'
import { basename, resolve } from 'node:path' import { basename, resolve } from 'node:path'
@ -6,7 +6,7 @@ import { AES, Hex } from 'occulto'
import pretty from 'pretty-bytes' import pretty from 'pretty-bytes'
export async function download(url: URL, all: boolean, suggestedPassword?: string) { export async function download(url: URL, all: boolean, suggestedPassword?: string) {
setBase(url.origin) setOptions({ server: url.origin })
const id = url.pathname.split('/')[2] const id = url.pathname.split('/')[2]
const preview = await info(id).catch(() => { const preview = await info(id).catch(() => {
throw new Error('Note does not exist or is expired') throw new Error('Note does not exist or is expired')

View File

@ -1,7 +1,7 @@
import { readFile, stat } from 'node:fs/promises' import { readFile, stat } from 'node:fs/promises'
import { basename } from 'node:path' import { basename } from 'node:path'
import { Adapters, BASE, create, FileDTO, Note, NoteMeta } from '@cryptgeon/shared' import { Adapters, create, getOptions, FileDTO, Note, NoteMeta } from '@cryptgeon/shared'
import mime from 'mime' import mime from 'mime'
import { AES, Hex } from 'occulto' import { AES, Hex } from 'occulto'
@ -39,7 +39,7 @@ export async function upload(input: string | string[], options: UploadOptions):
// Create the actual note and upload it. // Create the actual note and upload it.
const note: Note = { ...noteOptions, contents, meta: { type, derivation: derived?.[1] } } const note: Note = { ...noteOptions, contents, meta: { type, derivation: derived?.[1] } }
const result = await create(note) const result = await create(note)
let url = `${BASE}/note/${result.id}` let url = `${getOptions().server}/note/${result.id}`
if (!derived) url += `#${Hex.encode(key)}` if (!derived) url += `#${Hex.encode(key)}`
return url return url
} }

View File

@ -23,6 +23,10 @@ export type EncryptedFileDTO = Omit<FileDTO, 'contents'> & {
contents: string contents: string
} }
type ClientOptions = {
server: string
}
type CallOptions = { type CallOptions = {
url: string url: string
method: string method: string
@ -31,14 +35,21 @@ type CallOptions = {
export class PayloadToLargeError extends Error {} export class PayloadToLargeError extends Error {}
export let BASE = '' export let client: ClientOptions = {
server: 'https://cryptgeon.org',
}
export function setBase(url: string) { export function setOptions(options: Partial<ClientOptions>) {
BASE = url client = { ...client, ...options }
}
export function getOptions(): ClientOptions {
return client
} }
export async function call(options: CallOptions) { export async function call(options: CallOptions) {
const response = await fetch(BASE + '/api/' + options.url, { const url = client.server + '/api/' + options.url
const response = await fetch(url, {
method: options.method, method: options.method,
body: options.body === undefined ? undefined : JSON.stringify(options.body), body: options.body === undefined ? undefined : JSON.stringify(options.body),
mode: 'cors', mode: 'cors',

File diff suppressed because it is too large Load Diff