mirror of
https://github.com/cupcakearmy/cryptgeon.git
synced 2024-10-31 20:34:12 +01:00
Merge pull request #145 from cupcakearmy/better-programmatic-access
better programmatic access
This commit is contained in:
commit
2006be0434
@ -1,5 +1,5 @@
|
|||||||
# FRONTEND
|
# FRONTEND
|
||||||
FROM node:20-alpine as client
|
FROM node:22-alpine as client
|
||||||
ENV PNPM_HOME="/pnpm"
|
ENV PNPM_HOME="/pnpm"
|
||||||
ENV PATH="$PNPM_HOME:$PATH"
|
ENV PATH="$PNPM_HOME:$PATH"
|
||||||
RUN corepack enable
|
RUN corepack enable
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
<a href=""><img src="./.github/lokalise.png" height="50">
|
<a href=""><img src="./.github/lokalise.png" height="50">
|
||||||
<br/><br/>
|
<br/><br/>
|
||||||
|
|
||||||
EN | [简体中文](README_zh-CN.md) | [ES](README_ES.md)
|
EN | [简体中文](README_zh-CN.md) | [ES](README_ES.md)
|
||||||
|
|
||||||
## About?
|
## About?
|
||||||
|
|
||||||
@ -149,8 +149,8 @@ There is a [guide](https://mariushosting.com/how-to-install-cryptgeon-on-your-sy
|
|||||||
|
|
||||||
**Requirements**
|
**Requirements**
|
||||||
|
|
||||||
- `pnpm`: `>=6`
|
- `pnpm`: `>=9`
|
||||||
- `node`: `>=18`
|
- `node`: `>=22`
|
||||||
- `rust`: edition `2021`
|
- `rust`: edition `2021`
|
||||||
|
|
||||||
**Install**
|
**Install**
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev:docker": "docker-compose -f docker-compose.dev.yaml up redis",
|
"dev:docker": "docker compose -f docker-compose.dev.yaml up redis",
|
||||||
"dev:packages": "pnpm --parallel run dev",
|
"dev:packages": "pnpm --parallel run dev",
|
||||||
"dev": "run-p dev:*",
|
"dev": "run-p dev:*",
|
||||||
"docker:up": "docker compose -f docker-compose.dev.yaml up",
|
"docker:up": "docker compose -f docker-compose.dev.yaml up",
|
||||||
@ -12,10 +12,10 @@
|
|||||||
"build": "pnpm run --recursive --filter=!@cryptgeon/backend build"
|
"build": "pnpm run --recursive --filter=!@cryptgeon/backend build"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@playwright/test": "^1.42.1",
|
"@playwright/test": "^1.46.1",
|
||||||
"@types/node": "^20.11.28",
|
"@types/node": "^22.5.0",
|
||||||
"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"
|
||||||
}
|
}
|
||||||
|
2
packages/backend/Cargo.lock
generated
2
packages/backend/Cargo.lock
generated
@ -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",
|
||||||
|
@ -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"
|
||||||
|
14
packages/cli/build.js
Normal file
14
packages/cli/build.js
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
import pkg from './package.json' with { type: 'json' }
|
||||||
|
import { build } from 'tsup'
|
||||||
|
|
||||||
|
const watch = process.argv.slice(2)[0] === '--watch'
|
||||||
|
|
||||||
|
await build({
|
||||||
|
entry: ['src/index.ts', 'src/cli.ts'],
|
||||||
|
dts: true,
|
||||||
|
minify: true,
|
||||||
|
format: ['esm', 'cjs'],
|
||||||
|
clean: true,
|
||||||
|
define: { VERSION: `"${pkg.version}"` },
|
||||||
|
watch,
|
||||||
|
})
|
@ -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",
|
||||||
@ -9,7 +9,7 @@
|
|||||||
},
|
},
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"exports": {
|
"exports": {
|
||||||
".": "./dist/index.mjs"
|
".": "./dist/index.js"
|
||||||
},
|
},
|
||||||
"types": "./dist/index.d.ts",
|
"types": "./dist/index.d.ts",
|
||||||
"bin": {
|
"bin": {
|
||||||
@ -20,8 +20,8 @@
|
|||||||
],
|
],
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"bin": "run-s build package",
|
"bin": "run-s build package",
|
||||||
"build": "rm -rf dist && tsc && ./scripts/build.js",
|
"build": "tsc && node build.js",
|
||||||
"dev": "./scripts/build.js --watch",
|
"dev": "node build.js --watch",
|
||||||
"prepublishOnly": "run-s build"
|
"prepublishOnly": "run-s build"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
@ -31,11 +31,11 @@
|
|||||||
"@types/mime": "^3.0.4",
|
"@types/mime": "^3.0.4",
|
||||||
"@types/node": "^20.11.24",
|
"@types/node": "^20.11.24",
|
||||||
"commander": "^12.0.0",
|
"commander": "^12.0.0",
|
||||||
"esbuild": "^0.20.1",
|
|
||||||
"inquirer": "^9.2.15",
|
"inquirer": "^9.2.15",
|
||||||
"mime": "^4.0.1",
|
"mime": "^4.0.1",
|
||||||
"occulto": "^2.0.3",
|
"occulto": "^2.0.3",
|
||||||
"pretty-bytes": "^6.1.1",
|
"pretty-bytes": "^6.1.1",
|
||||||
|
"tsup": "^8.2.4",
|
||||||
"typescript": "^5.3.3"
|
"typescript": "^5.3.3"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
|
@ -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)
|
|
||||||
}
|
|
@ -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 {
|
||||||
|
@ -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')
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
@ -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: '',
|
||||||
|
}
|
||||||
|
|
||||||
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',
|
||||||
|
@ -4,12 +4,13 @@ const config: PlaywrightTestConfig = {
|
|||||||
use: {
|
use: {
|
||||||
video: 'retain-on-failure',
|
video: 'retain-on-failure',
|
||||||
baseURL: 'http://localhost:1234',
|
baseURL: 'http://localhost:1234',
|
||||||
actionTimeout: 60_000,
|
actionTimeout: 10_000,
|
||||||
},
|
},
|
||||||
|
|
||||||
outputDir: './test-results',
|
outputDir: './test-results',
|
||||||
testDir: './test',
|
testDir: './test',
|
||||||
timeout: 60_000,
|
timeout: 10_000,
|
||||||
|
fullyParallel: true,
|
||||||
|
|
||||||
webServer: {
|
webServer: {
|
||||||
command: 'docker compose -f docker-compose.dev.yaml up',
|
command: 'docker compose -f docker-compose.dev.yaml up',
|
||||||
|
4726
pnpm-lock.yaml
4726
pnpm-lock.yaml
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user