@adonis-agora/media 0.11.0 → 0.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +27 -0
- package/README.md +63 -9
- package/dist/assets/spa/assets/index-Bo658_9z.js +83 -0
- package/dist/assets/spa/assets/{index-Dvw2uJpF.js.map → index-Bo658_9z.js.map} +1 -1
- package/dist/assets/spa/index.html +1 -1
- package/dist/providers/media_provider.d.ts.map +1 -1
- package/dist/providers/media_provider.js +34 -2
- package/dist/providers/media_provider.js.map +1 -1
- package/package.json +3 -2
- package/dist/assets/spa/assets/index-Dvw2uJpF.js +0 -83
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,32 @@
|
|
|
1
1
|
# @adonis-agora/media
|
|
2
2
|
|
|
3
|
+
## 0.12.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [#46](https://github.com/DavideCarvalho/adonis-agora-media/pull/46) [`e2baf99`](https://github.com/DavideCarvalho/adonis-agora-media/commit/e2baf993dae1a7d3574128085abe1cf48087a023) Thanks [@DavideCarvalho](https://github.com/DavideCarvalho)! - **Behaviour change — omitting `disk` now really uses Drive's default disk.** Read this if your `config/media.ts` does not set `disk`.
|
|
8
|
+
|
|
9
|
+
The documented fallback ("omit `disk` and the provider uses the `default` of your `config/drive.ts`") had never worked in any environment. `MediaProvider` read it as `app.config.get('drive').default`, but `app.config.get('drive')` returns the value your config file exported — Drive's `defineConfig()` returns an **unresolved `ConfigProvider`** (`{ type: 'provider', resolver }`), so `.default` was always `undefined` and the fallback always returned the literal string `'default'`. (Reading `.config.default` instead does not help either: `{ config: { default, fakes, services } }` is the shape the provider's resolver _returns_, never the shape of the provider itself.) The provider now resolves the config provider — the same thing `@adonisjs/drive`'s own provider does before it builds its manager — and reads the default disk name off the resolved config. Drive's `DriveManager` cannot be asked instead: it keeps that config in a `#private` field and exposes no accessor.
|
|
10
|
+
|
|
11
|
+
**Am I affected?** Look at the `default` key of your `config/drive.ts`:
|
|
12
|
+
|
|
13
|
+
- `default: 'default'` (or you set `disk` in `config/media.ts`, or you have no Drive config at all) → nothing changes.
|
|
14
|
+
- `default` is anything else _and_ your `services` map has **no** disk named `default` → media was hard-broken for you (every disk operation threw inside flydrive, because it was asked for a service named `'default'` that does not exist). This release fixes it; there is nothing to migrate.
|
|
15
|
+
- `default` is anything else _and_ your `services` map **does** have a disk named `default` → **this moves where your files are written and read.** New objects now go to your real Drive default (e.g. `s3`) instead of the disk named `default`.
|
|
16
|
+
|
|
17
|
+
**Migration.** Objects already written under the `'default'` disk will not be found on the new disk — nothing copies them. Media records persist their own `disk`, so rows attached before this upgrade keep resolving to `'default'` and stay readable as long as that disk still exists in `config/drive.ts`; anything that recomputes a location from the _current_ default (or any object you wrote outside the media record store) will look on the new disk and miss. To keep the old behaviour exactly, pin it explicitly:
|
|
18
|
+
|
|
19
|
+
```ts
|
|
20
|
+
// config/media.ts
|
|
21
|
+
export default defineConfig({
|
|
22
|
+
disk: "default", // was implicit before this release
|
|
23
|
+
});
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
Otherwise, move the existing objects to your real default disk (or point that Drive service at the same bucket/location) before upgrading.
|
|
27
|
+
|
|
28
|
+
This is a minor, not a major: the package is pre-1.0, where minor is the breaking-change channel, and a `1.0.0` would signal an API stability this package has not declared. The affected surface is narrow (a host that both omits `disk` and keeps a Drive disk literally named `default` alongside a different Drive `default`), the alternative for most affected hosts was a crash, and pinning the old behaviour is a one-line config change.
|
|
29
|
+
|
|
3
30
|
## 0.11.0
|
|
4
31
|
|
|
5
32
|
### Minor Changes
|
package/README.md
CHANGED
|
@@ -4,12 +4,16 @@ Media-library for **AdonisJS**, part of the [Agora](https://github.com/DavideCar
|
|
|
4
4
|
spatie/laravel-media-library feel, on top of [`@adonisjs/drive`](https://github.com/adonisjs/drive).
|
|
5
5
|
|
|
6
6
|
Attach files to entities, organize them into collections (MIME whitelist, single-file replace,
|
|
7
|
-
ordering), and generate image conversions (eager or lazy)
|
|
8
|
-
|
|
7
|
+
ordering), and generate image conversions (eager or lazy) — plus **content transformers**, the same
|
|
8
|
+
seam driven beyond images: the bundled `transformers.hls()` packages a video into an HLS ladder and
|
|
9
|
+
`transformers.probe()` records duration/codecs as metadata, both persisted into the same
|
|
10
|
+
`record.conversions` map. Storage is delegated entirely to Drive, so you reuse your existing
|
|
11
|
+
`local` / `s3` / `gcs` disks — this package never reimplements disk drivers.
|
|
9
12
|
|
|
10
13
|
This is the **core library**: `MediaLibrary`, `AttachmentManager`, the `MediaStore` SPI (in-memory +
|
|
11
|
-
Lucid), the `ImageProcessor` SPI (sharp), the
|
|
12
|
-
|
|
14
|
+
Lucid), the `ImageProcessor` SPI (sharp), the `Transformer` SPI (HLS video packaging + metadata
|
|
15
|
+
probe), the bundled `disks.s3()` driver, proxy/direct/resumable uploads, configurable delivery, the
|
|
16
|
+
provider + `defineConfig`, and a testing kit. The management
|
|
13
17
|
**console ships embedded** — registering `@adonis-agora/media/dashboard_provider` is all a consuming
|
|
14
18
|
app needs (see [Dashboard](#dashboard) below); no separate install. Pair it with
|
|
15
19
|
[`@adonis-agora/media-react`](https://github.com/DavideCarvalho/adonis-media/tree/master/packages/react)
|
|
@@ -22,11 +26,12 @@ The package uses **subpath exports** (the Agora idiom), so heavy backends stay o
|
|
|
22
26
|
| Subpath | What |
|
|
23
27
|
|---|---|
|
|
24
28
|
| `@adonis-agora/media` | barrel — `defineConfig`, `stores`, `processors`, `disks`, `uploadSessions`, `MediaManager`, `MediaLibrary`, `AttachmentManager`, `UploadManager`, `ResumableUploadManager`, `MediaDeliveryHandler`, SPIs, errors |
|
|
29
|
+
| `@adonis-agora/media/services/main` | the app-bound `MediaManager` singleton — `import media from '@adonis-agora/media/services/main'`, importable at any time (it resolves lazily on first use) |
|
|
25
30
|
| `@adonis-agora/media/media_provider` | the service provider (binds `MediaManager`, mounts optional upload/TUS routes) |
|
|
26
31
|
| `@adonis-agora/media/dashboard_provider` | the embedded management-console provider (React SPA + JSON API) |
|
|
27
32
|
| `@adonis-agora/media/dashboard` | `defineConfig` + types for `config/media_dashboard.ts`, `DashboardService`, the session-auth helpers, `ObjectInsightProvider` |
|
|
28
33
|
| `@adonis-agora/media/configure` | `node ace configure` hook |
|
|
29
|
-
| `@adonis-agora/media/single-file` | `storeSingleFile` / `removeSingleFile` / `isSingleFileStoreAvailable` — lets other packages delegate single-file uploads (e.g. avatars) to media without a hard dependency |
|
|
34
|
+
| `@adonis-agora/media/single-file` | `storeSingleFile` / `removeSingleFile` / `storeSingleFileWith` / `removeSingleFileWith` / `isSingleFileStoreAvailable` — lets other packages delegate single-file uploads (e.g. avatars) to media without a hard dependency |
|
|
30
35
|
| `@adonis-agora/media/stores/lucid` | the Lucid `MediaStore` (`@adonisjs/lucid` peer) |
|
|
31
36
|
| `@adonis-agora/media/upload_sessions/lucid` | the Lucid resumable `UploadSessionStore` (`@adonisjs/lucid` peer) |
|
|
32
37
|
| `@adonis-agora/media/disks/s3` | the bundled `S3Disk` (`@aws-sdk/client-s3` peer; presigning is hand-rolled SigV4) |
|
|
@@ -44,9 +49,13 @@ node ace configure @adonis-agora/media
|
|
|
44
49
|
```
|
|
45
50
|
|
|
46
51
|
`configure` registers the media provider **and the dashboard provider**, publishes `config/media.ts`
|
|
47
|
-
and `config/media_dashboard.ts`, and publishes the `media` table
|
|
48
|
-
the
|
|
49
|
-
|
|
52
|
+
and `config/media_dashboard.ts`, and publishes **two** migrations — the `media` table for the `lucid`
|
|
53
|
+
store and the session table for the `lucid` upload-session store. Delete the ones you don't need (the
|
|
54
|
+
in-memory equivalents need no table); otherwise `node ace migration:run`. The management console is
|
|
55
|
+
live at `/media/dashboard` the moment your app boots — see [Dashboard](#dashboard).
|
|
56
|
+
|
|
57
|
+
Required peers: `@adonisjs/core` (`^7.3.0`) and `@adonisjs/drive` — **either major**, `^3.0.0` or
|
|
58
|
+
`^4.0.0`.
|
|
50
59
|
|
|
51
60
|
Optional peers, loaded lazily only when selected:
|
|
52
61
|
|
|
@@ -141,6 +150,50 @@ A `ConversionPreset` is `{ name, width?, height?, fit?, format?, quality?, eager
|
|
|
141
150
|
generated synchronously on `attach`; the rest are generated lazily on the first `url(id, name)` and
|
|
142
151
|
cached on the record. `fit` and `format` map straight onto sharp.
|
|
143
152
|
|
|
153
|
+
## Transformers and HLS video
|
|
154
|
+
|
|
155
|
+
Image conversions answer "same image, different size". **Transformers** answer everything else:
|
|
156
|
+
*transform this content into that*. A transformer takes a stored media's bytes and produces many
|
|
157
|
+
files (an HLS package), one file (an extracted audio track), or none at all (a metadata probe) —
|
|
158
|
+
persisted into the same `record.conversions` map, so presets and transformers share one namespace
|
|
159
|
+
per collection.
|
|
160
|
+
|
|
161
|
+
Two ship with the package, both over the optional `mediabunny` peer (pure TypeScript — **no ffmpeg
|
|
162
|
+
binary**), imported lazily inside the first `transform()` call:
|
|
163
|
+
|
|
164
|
+
```ts
|
|
165
|
+
// config/media.ts
|
|
166
|
+
import { defineConfig, transformers } from '@adonis-agora/media'
|
|
167
|
+
|
|
168
|
+
export default defineConfig({
|
|
169
|
+
collections: [
|
|
170
|
+
{
|
|
171
|
+
name: 'videos',
|
|
172
|
+
acceptsMimeTypes: ['video/mp4'],
|
|
173
|
+
transformers: [
|
|
174
|
+
transformers.hls({ targetDuration: 4 }), // MPEG-TS segments behind a master playlist
|
|
175
|
+
transformers.probe({ eager: true }), // duration / resolution / codecs, no artifact
|
|
176
|
+
],
|
|
177
|
+
},
|
|
178
|
+
],
|
|
179
|
+
})
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
Transformations are assumed heavy, so nothing runs on attach unless you mark it `eager`. Trigger one
|
|
183
|
+
from your own job — `transform(id, name)` is idempotent, so a retry skips straight through:
|
|
184
|
+
|
|
185
|
+
```ts
|
|
186
|
+
await media.library.transform(mediaId, 'hls')
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
Serving the result is `HlsDeliveryHandler`: playlists come back with every reference rewritten (each
|
|
190
|
+
sub-playlist hop through your own route, so your auth stays in the path), and segments as presigned
|
|
191
|
+
URLs or streamed bytes. Like every handler here it performs **no authorization** — you mount the
|
|
192
|
+
route and guard it. Writing your own transformer is one interface (`name` + `transform(context)`);
|
|
193
|
+
the context hands you the record, the original's bytes/stream, and a sandboxed `write()` that keys
|
|
194
|
+
every artifact under the conversion's own prefix.
|
|
195
|
+
|
|
196
|
+
|
|
144
197
|
## Uploads, S3 and delivery
|
|
145
198
|
|
|
146
199
|
Large-file uploads ship in three flavours — **proxy** (bytes stream through your app), **direct-S3
|
|
@@ -209,7 +262,8 @@ that already register it directly. Don't register both providers in the same app
|
|
|
209
262
|
|
|
210
263
|
## Diagnostics
|
|
211
264
|
|
|
212
|
-
|
|
265
|
+
All nine lifecycle events — `attach`, `delete`, `conversion`, `attachment.create`,
|
|
266
|
+
`attachment.delete`, `upload.start`, `upload.progress`, `upload.complete`, `upload.abort` — are
|
|
213
267
|
emitted on the `agora:media:*` channel via the `@agora/diagnostics:emit` global slot — read
|
|
214
268
|
structurally, with **no hard dependency** on `@adonis-agora/diagnostics`. When that package isn't
|
|
215
269
|
installed, emitting is an inert no-op; when it is, the Telescope generic watcher (or
|