diff --git a/alias.ts b/alias.ts index 9b95034f..e284552c 100644 --- a/alias.ts +++ b/alias.ts @@ -108,6 +108,12 @@ export const alias = { '@devframes/plugin-messages/cli': p('messages/src/cli.ts'), '@devframes/plugin-messages/vite': p('messages/src/vite.ts'), '@devframes/plugin-messages': p('messages/src/index.ts'), + '@devframes/plugin-assets/client': p('assets/src/client/index.ts'), + '@devframes/plugin-assets/node': p('assets/src/node/index.ts'), + '@devframes/plugin-assets/rpc': p('assets/src/rpc/index.ts'), + '@devframes/plugin-assets/cli': p('assets/src/cli.ts'), + '@devframes/plugin-assets/vite': p('assets/src/vite.ts'), + '@devframes/plugin-assets': p('assets/src/index.ts'), } // update tsconfig.base.json — CSS aliases exist for Vite resolution only; diff --git a/docs/.vitepress/config.ts b/docs/.vitepress/config.ts index 738d1a5d..b3ce436a 100644 --- a/docs/.vitepress/config.ts +++ b/docs/.vitepress/config.ts @@ -71,6 +71,7 @@ function pluginsItems(prefix: string) { { text: 'Git', link: `${prefix}/plugins/git` }, { text: 'Terminals', link: `${prefix}/plugins/terminals` }, { text: 'Code Server', link: `${prefix}/plugins/code-server` }, + { text: 'Assets', link: `${prefix}/plugins/assets` }, ] satisfies DefaultTheme.NavItemWithLink[] } diff --git a/docs/errors/DF0042.md b/docs/errors/DF0042.md new file mode 100644 index 00000000..96c364c4 --- /dev/null +++ b/docs/errors/DF0042.md @@ -0,0 +1,32 @@ +--- +outline: deep +--- + +# DF0042: Static Build Disabled By The Definition + +## Message + +> "`{id}`" declares `capabilities.build: false` — its static export is not meaningful (writes are excluded and any live-served data won't be there). + +## Cause + +`createBuild` runs unconditionally when called directly, but a definition can opt out of static export via `capabilities.build: false` — typically because the devframe is inherently live (it manages real files on disk, spawns a process, etc.) and a `mode: 'build'` export would only ever produce a broken, write-less shell of the tool. `createCac` already skips registering the `build` subcommand for such a definition; this diagnostic covers the remaining path — a caller invoking `createBuild()` directly, bypassing the CLI. + +## Example + +```ts +// ✗ Bad — builds a devframe that opted out of static export +await createBuild(assetsDevframe) // throws DF0042 + +// ✓ Good — the degraded export is still useful to you +await createBuild(assetsDevframe, { force: true }) +``` + +## Fix + +- Pass `{ force: true }` to `createBuild()` if the degraded export is still useful to you. +- Otherwise, drop `capabilities.build: false` on the definition if a static export should be supported after all. + +## Source + +- [`packages/devframe/src/adapters/build.ts`](https://github.com/devframes/devframe/blob/main/packages/devframe/src/adapters/build.ts) — `createBuild()` throws this when `capabilities.build` is `false` and `force` isn't set. diff --git a/docs/plugins/assets.md b/docs/plugins/assets.md new file mode 100644 index 00000000..a13699de --- /dev/null +++ b/docs/plugins/assets.md @@ -0,0 +1,90 @@ +--- +outline: deep +--- + +# Assets + +Browse, preview, upload, rename, and delete the files in a directory, built as a **Vue** SPA on `@antfu/design` — a framework-neutral port of Nuxt DevTools' Assets tab. + +Package: `@devframes/plugin-assets` · framework: **Vue + @antfu/design** + +## What it does + +Search by name and filter by type from an inline chip row, switch between a thumbnail grid (grouped by folder) and a file tree, and open a resizable right-hand details panel with a live preview (image, video, audio, font, or text), file metadata, and ready-to-copy usage snippets (``, CSS `background-image`, `@font-face`, a download link). Upload files with the toolbar button (native file picker) or by dropping them anywhere on the frame, and select multiple assets to delete them together. A live file watcher keeps every connected client's listing in sync with changes made outside the UI. + +The standalone server requires devframe's trust handshake by default because it can read, write, and delete real files. Uploads, renames, deletes, and folder creation are enabled by default — pass `{ write: false }` (or `--read-only` on the standalone CLI) for a browse-only deployment. + +## Standalone + +```sh +pnpx @devframes/plugin-assets # manages /public +pnpx @devframes/plugin-assets --read-only # disable upload / rename / delete / mkdir +``` + +## Mount into a Vite host + +```ts +// vite.config.ts +import { assetsVitePlugin } from '@devframes/plugin-assets/vite' +import { defineConfig } from 'vite' + +export default defineConfig({ + plugins: [ + assetsVitePlugin(), + ], +}) +``` + +## Programmatic + +`createAssetsDevframe(options)` returns a definition you can deploy through any adapter: + +```ts +import { createAssetsDevframe } from '@devframes/plugin-assets' + +export default createAssetsDevframe({ + dir: 'static', // defaults to `/public` + baseURL: '/', // the URL the host serves `dir` at + write: true, + uploadExtensions: ['png', 'jpg', 'svg', 'webp'], // defaults to Nuxt DevTools' own allow-list, or '*' for any +}) +``` + +| Option | Default | Description | +|--------|---------|-------------| +| `dir` | `/public` | Directory this devframe manages. | +| `baseURL` | `/` | URL base the host serves `dir` at — each asset's `publicPath` is `baseURL` + its path. Match a non-root deployment base (e.g. Nuxt's `app.baseURL`). | +| `write` | `true` | Enable upload, rename, delete, and folder creation from the UI. | +| `uploadExtensions` | Nuxt DevTools' allow-list | Extensions `upload` accepts, or `'*'` for any. | +| `serveStatic` | `false` | Serve the directory's bytes from this devframe itself. Left off when mounted into a host that already serves `public/`; the standalone CLI turns it on. | +| `build` | `false` | Register the `build` CLI subcommand. See [why it's off by default](#static-export) below. | + +## How previews are served + +Asset previews (``, `