From 7b919f2a53679ec1d9a69614372e8a1396e8d9da Mon Sep 17 00:00:00 2001 From: Niccolo Borgioli Date: Mon, 2 Sep 2024 10:19:35 +0200 Subject: [PATCH] move shared package to cli --- cryptgeon.code-workspace | 3 --- packages/cli/build.js | 5 ++-- packages/cli/package.json | 15 +++++++----- packages/cli/src/{ => actions}/download.ts | 9 +++---- packages/cli/src/{ => actions}/upload.ts | 7 +++--- packages/cli/src/cli.ts | 20 ++++++++-------- packages/cli/src/index.ts | 8 +++---- .../src => cli/src/shared}/adapters.ts | 0 .../{shared/src => cli/src/shared}/api.ts | 24 +++++++++++++------ .../src/index.ts => cli/src/shared/shared.ts} | 0 packages/cli/src/{ => utils}/parsers.ts | 4 ++-- packages/cli/src/{ => utils}/stdin.ts | 1 + packages/cli/src/{ => utils}/utils.ts | 4 ++-- packages/cli/tsconfig.json | 2 +- packages/shared/package.json | 22 ----------------- packages/shared/tsconfig.json | 12 ---------- 16 files changed, 58 insertions(+), 78 deletions(-) rename packages/cli/src/{ => actions}/download.ts (92%) rename packages/cli/src/{ => actions}/upload.ts (87%) rename packages/{shared/src => cli/src/shared}/adapters.ts (100%) rename packages/{shared/src => cli/src/shared}/api.ts (85%) rename packages/{shared/src/index.ts => cli/src/shared/shared.ts} (100%) rename packages/cli/src/{ => utils}/parsers.ts (85%) rename packages/cli/src/{ => utils}/stdin.ts (95%) rename packages/cli/src/{ => utils}/utils.ts (89%) delete mode 100644 packages/shared/package.json delete mode 100644 packages/shared/tsconfig.json diff --git a/cryptgeon.code-workspace b/cryptgeon.code-workspace index d659d68..1d5ce37 100644 --- a/cryptgeon.code-workspace +++ b/cryptgeon.code-workspace @@ -11,9 +11,6 @@ }, { "path": "packages/cli" - }, - { - "path": "packages/shared" } ], "settings": { diff --git a/packages/cli/build.js b/packages/cli/build.js index 7a81d9d..a977c85 100644 --- a/packages/cli/build.js +++ b/packages/cli/build.js @@ -1,13 +1,14 @@ -import pkg from './package.json' with { type: 'json' } import { build } from 'tsup' +import pkg from './package.json' with { type: 'json' } const watch = process.argv.slice(2)[0] === '--watch' await build({ - entry: ['src/index.ts', 'src/cli.ts'], + entry: ['src/index.ts', 'src/cli.ts', 'src/shared/shared.ts'], dts: true, minify: true, format: ['esm', 'cjs'], + target: 'es2020', clean: true, define: { VERSION: `"${pkg.version}"` }, watch, diff --git a/packages/cli/package.json b/packages/cli/package.json index c59b0c7..b07dfe9 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -9,7 +9,11 @@ }, "type": "module", "exports": { - ".": "./dist/index.js" + ".": "./dist/index.js", + "./shared": { + "import": "./dist/shared/shared.js", + "types": "./dist/shared/shared.d.ts" + } }, "types": "./dist/index.d.ts", "bin": { @@ -25,15 +29,14 @@ "prepublishOnly": "run-s build" }, "devDependencies": { - "@commander-js/extra-typings": "^12.0.1", - "@cryptgeon/shared": "workspace:*", + "@commander-js/extra-typings": "^12.1.0", "@types/inquirer": "^9.0.7", - "@types/mime": "^3.0.4", + "@types/mime": "^4.0.0", "@types/node": "^20.11.24", - "commander": "^12.0.0", + "commander": "^12.1.0", "inquirer": "^9.2.15", "mime": "^4.0.1", - "occulto": "^2.0.3", + "occulto": "^2.0.6", "pretty-bytes": "^6.1.1", "tsup": "^8.2.4", "typescript": "^5.3.3" diff --git a/packages/cli/src/download.ts b/packages/cli/src/actions/download.ts similarity index 92% rename from packages/cli/src/download.ts rename to packages/cli/src/actions/download.ts index ae64264..7aa04f1 100644 --- a/packages/cli/src/download.ts +++ b/packages/cli/src/actions/download.ts @@ -1,14 +1,15 @@ -import { Adapters, get, info, setOptions } from '@cryptgeon/shared' import inquirer from 'inquirer' import { access, constants, writeFile } from 'node:fs/promises' import { basename, resolve } from 'node:path' import { AES, Hex } from 'occulto' import pretty from 'pretty-bytes' +import { Adapters } from '../shared/adapters.js' +import { API } from '../shared/api.js' export async function download(url: URL, all: boolean, suggestedPassword?: string) { - setOptions({ server: url.origin }) + API.setOptions({ server: url.origin }) const id = url.pathname.split('/')[2] - const preview = await info(id).catch(() => { + const preview = await API.info(id).catch(() => { throw new Error('Note does not exist or is expired') }) @@ -33,7 +34,7 @@ export async function download(url: URL, all: boolean, suggestedPassword?: strin } const key = derivation ? (await AES.derive(password, derivation))[0] : Hex.decode(password) - const note = await get(id) + const note = await API.get(id) const couldNotDecrypt = new Error('Could not decrypt note. Probably an invalid password') switch (note.meta.type) { diff --git a/packages/cli/src/upload.ts b/packages/cli/src/actions/upload.ts similarity index 87% rename from packages/cli/src/upload.ts rename to packages/cli/src/actions/upload.ts index ef04f9c..3bb1258 100644 --- a/packages/cli/src/upload.ts +++ b/packages/cli/src/actions/upload.ts @@ -1,9 +1,10 @@ import { readFile, stat } from 'node:fs/promises' import { basename } from 'node:path' -import { Adapters, create, getOptions, FileDTO, Note, NoteMeta } from '@cryptgeon/shared' import mime from 'mime' import { AES, Hex } from 'occulto' +import { Adapters } from '../shared/adapters.js' +import { API, FileDTO, Note, NoteMeta } from '../shared/api.js' export type UploadOptions = Pick & { password?: string } @@ -38,8 +39,8 @@ export async function upload(input: string | string[], options: UploadOptions): // Create the actual note and upload it. const note: Note = { ...noteOptions, contents, meta: { type, derivation: derived?.[1] } } - const result = await create(note) - let url = `${getOptions().server}/note/${result.id}` + const result = await API.create(note) + let url = `${API.getOptions().server}/note/${result.id}` if (!derived) url += `#${Hex.encode(key)}` return url } diff --git a/packages/cli/src/cli.ts b/packages/cli/src/cli.ts index bcd9b85..e505df3 100644 --- a/packages/cli/src/cli.ts +++ b/packages/cli/src/cli.ts @@ -1,14 +1,14 @@ #!/usr/bin/env node import { Argument, Option, program } from '@commander-js/extra-typings' -import { setOptions, status } from '@cryptgeon/shared' import prettyBytes from 'pretty-bytes' -import { download } from './download.js' -import { parseFile, parseNumber } from './parsers.js' -import { getStdin } from './stdin.js' -import { upload } from './upload.js' -import { checkConstrains, exit } from './utils.js' +import { download } from './actions/download.js' +import { upload } from './actions/upload.js' +import { API } from './shared/api.js' +import { parseFile, parseNumber } from './utils/parsers.js' +import { getStdin } from './utils/stdin.js' +import { checkConstrains, exit } from './utils/utils.js' const defaultServer = process.env['CRYPTGEON_SERVER'] || 'https://cryptgeon.org' const server = new Option('-s --server ', 'the cryptgeon server to use').default(defaultServer) @@ -33,8 +33,8 @@ program .description('show information about the server') .addOption(server) .action(async (options) => { - setOptions({ server: options.server }) - const response = await status() + API.setOptions({ server: options.server }) + const response = await API.status() const formatted = { ...response, max_size: prettyBytes(response.max_size), @@ -54,7 +54,7 @@ send .addOption(minutes) .addOption(password) .action(async (files, options) => { - setOptions({ server: options.server }) + API.setOptions({ server: options.server }) await checkConstrains(options) options.password ||= await getStdin() try { @@ -72,7 +72,7 @@ send .addOption(minutes) .addOption(password) .action(async (text, options) => { - setOptions({ server: options.server }) + API.setOptions({ server: options.server }) await checkConstrains(options) options.password ||= await getStdin() try { diff --git a/packages/cli/src/index.ts b/packages/cli/src/index.ts index ce1fca2..a22bcf6 100644 --- a/packages/cli/src/index.ts +++ b/packages/cli/src/index.ts @@ -1,4 +1,4 @@ -export * from '@cryptgeon/shared' -export * from './download.js' -export * from './upload.js' -export * from './utils.js' +export * from './actions/download.js' +export * from './actions/upload.js' +export * from './shared/adapters.js' +export * from './shared/api.js' diff --git a/packages/shared/src/adapters.ts b/packages/cli/src/shared/adapters.ts similarity index 100% rename from packages/shared/src/adapters.ts rename to packages/cli/src/shared/adapters.ts diff --git a/packages/shared/src/api.ts b/packages/cli/src/shared/api.ts similarity index 85% rename from packages/shared/src/api.ts rename to packages/cli/src/shared/api.ts index e210f40..fa085ac 100644 --- a/packages/shared/src/api.ts +++ b/packages/cli/src/shared/api.ts @@ -39,15 +39,15 @@ export let client: ClientOptions = { server: '', } -export function setOptions(options: Partial) { +function setOptions(options: Partial) { client = { ...client, ...options } } -export function getOptions(): ClientOptions { +function getOptions(): ClientOptions { return client } -export async function call(options: CallOptions) { +async function call(options: CallOptions) { const url = client.server + '/api/' + options.url const response = await fetch(url, { method: options.method, @@ -65,7 +65,7 @@ export async function call(options: CallOptions) { return response.json() } -export async function create(note: Note) { +async function create(note: Note) { const { meta, ...rest } = note const body: NoteCreate = { ...rest, @@ -79,7 +79,7 @@ export async function create(note: Note) { return data as { id: string } } -export async function get(id: string): Promise { +async function get(id: string): Promise { const data = await call({ url: `notes/${id}`, method: 'delete', @@ -93,7 +93,7 @@ export async function get(id: string): Promise { return note } -export async function info(id: string): Promise { +async function info(id: string): Promise { const data = await call({ url: `notes/${id}`, method: 'get', @@ -112,6 +112,7 @@ export type Status = { max_views: number max_expiration: number allow_advanced: boolean + allow_files: boolean theme_image: string theme_text: string theme_favicon: string @@ -119,10 +120,19 @@ export type Status = { theme_new_note_notice: boolean } -export async function status() { +async function status() { const data = await call({ url: 'status/', method: 'get', }) return data as Status } + +export const API = { + setOptions, + getOptions, + create, + get, + info, + status, +} diff --git a/packages/shared/src/index.ts b/packages/cli/src/shared/shared.ts similarity index 100% rename from packages/shared/src/index.ts rename to packages/cli/src/shared/shared.ts diff --git a/packages/cli/src/parsers.ts b/packages/cli/src/utils/parsers.ts similarity index 85% rename from packages/cli/src/parsers.ts rename to packages/cli/src/utils/parsers.ts index 33cac70..24bc676 100644 --- a/packages/cli/src/parsers.ts +++ b/packages/cli/src/utils/parsers.ts @@ -21,7 +21,7 @@ export function parseURL(value: string, _: URL): URL { } export function parseNumber(value: string, _: number): number { - const n = parseInt(value, 10) - if (isNaN(n)) throw new InvalidOptionArgumentError('invalid number') + const n = Number.parseInt(value, 10) + if (Number.isNaN(n)) throw new InvalidOptionArgumentError('invalid number') return n } diff --git a/packages/cli/src/stdin.ts b/packages/cli/src/utils/stdin.ts similarity index 95% rename from packages/cli/src/stdin.ts rename to packages/cli/src/utils/stdin.ts index d94b46a..4e1a67b 100644 --- a/packages/cli/src/stdin.ts +++ b/packages/cli/src/utils/stdin.ts @@ -18,6 +18,7 @@ export function getStdin(timeout: number = 10): Promise { resolve('') }, timeout) + process.stdin.on('error', reject) process.stdin.on('data', dataHandler) process.stdin.on('end', endHandler) }) diff --git a/packages/cli/src/utils.ts b/packages/cli/src/utils/utils.ts similarity index 89% rename from packages/cli/src/utils.ts rename to packages/cli/src/utils/utils.ts index 37ebb65..18da6a1 100644 --- a/packages/cli/src/utils.ts +++ b/packages/cli/src/utils/utils.ts @@ -1,5 +1,5 @@ -import { status } from '@cryptgeon/shared' import { exit as exitNode } from 'node:process' +import { API } from '../shared/api.js' export function exit(message: string) { console.error(message) @@ -11,7 +11,7 @@ export async function checkConstrains(constrains: { views?: number; minutes?: nu if (views && minutes) exit('cannot set view and minutes constrains simultaneously') if (!views && !minutes) constrains.views = 1 - const response = await status() + const response = await API.status() if (views && views > response.max_views) exit(`Only a maximum of ${response.max_views} views allowed. ${views} given.`) if (minutes && minutes > response.max_expiration) diff --git a/packages/cli/tsconfig.json b/packages/cli/tsconfig.json index 4aab889..5514c3b 100644 --- a/packages/cli/tsconfig.json +++ b/packages/cli/tsconfig.json @@ -2,7 +2,7 @@ "compilerOptions": { "target": "es2022", "module": "es2022", - "moduleResolution": "node", + "moduleResolution": "Bundler", "declaration": true, "emitDeclarationOnly": true, "strict": true, diff --git a/packages/shared/package.json b/packages/shared/package.json deleted file mode 100644 index 8977c9c..0000000 --- a/packages/shared/package.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "private": true, - "name": "@cryptgeon/shared", - "type": "module", - "types": "./dist/index.d.ts", - "exports": { - ".": { - "types": "./dist/index.d.ts", - "import": "./dist/index.js" - } - }, - "scripts": { - "dev": "tsc -w", - "build": "tsc" - }, - "devDependencies": { - "typescript": "^5.3.3" - }, - "dependencies": { - "occulto": "^2.0.3" - } -} diff --git a/packages/shared/tsconfig.json b/packages/shared/tsconfig.json deleted file mode 100644 index 8032071..0000000 --- a/packages/shared/tsconfig.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "compilerOptions": { - "incremental": true, - "composite": true, - "target": "es2022", - "module": "es2022", - "rootDir": "./src", - "moduleResolution": "node", - "outDir": "./dist", - "strict": true - } -}