@adonis-agora/media 0.10.4 → 0.11.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.
Files changed (48) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/README.md +46 -6
  3. package/dist/assets/spa/assets/index--0MZJr6W.css +1 -0
  4. package/dist/assets/spa/assets/index-Dvw2uJpF.js +83 -0
  5. package/dist/assets/spa/assets/index-Dvw2uJpF.js.map +1 -0
  6. package/dist/assets/spa/index.html +20 -0
  7. package/dist/configure.d.ts +6 -2
  8. package/dist/configure.d.ts.map +1 -1
  9. package/dist/configure.js +8 -2
  10. package/dist/configure.js.map +1 -1
  11. package/dist/providers/dashboard_provider.d.ts +29 -0
  12. package/dist/providers/dashboard_provider.d.ts.map +1 -0
  13. package/dist/providers/dashboard_provider.js +520 -0
  14. package/dist/providers/dashboard_provider.js.map +1 -0
  15. package/dist/src/dashboard/auth.d.ts +76 -0
  16. package/dist/src/dashboard/auth.d.ts.map +1 -0
  17. package/dist/src/dashboard/auth.js +134 -0
  18. package/dist/src/dashboard/auth.js.map +1 -0
  19. package/dist/src/dashboard/cookie.d.ts +20 -0
  20. package/dist/src/dashboard/cookie.d.ts.map +1 -0
  21. package/dist/src/dashboard/cookie.js +44 -0
  22. package/dist/src/dashboard/cookie.js.map +1 -0
  23. package/dist/src/dashboard/define_config.d.ts +56 -0
  24. package/dist/src/dashboard/define_config.d.ts.map +1 -0
  25. package/dist/src/dashboard/define_config.js +5 -0
  26. package/dist/src/dashboard/define_config.js.map +1 -0
  27. package/dist/src/dashboard/index.d.ts +10 -0
  28. package/dist/src/dashboard/index.d.ts.map +1 -0
  29. package/dist/src/dashboard/index.js +9 -0
  30. package/dist/src/dashboard/index.js.map +1 -0
  31. package/dist/src/dashboard/object_insights.d.ts +42 -0
  32. package/dist/src/dashboard/object_insights.d.ts.map +1 -0
  33. package/dist/src/dashboard/object_insights.js +42 -0
  34. package/dist/src/dashboard/object_insights.js.map +1 -0
  35. package/dist/src/dashboard/service.d.ts +215 -0
  36. package/dist/src/dashboard/service.d.ts.map +1 -0
  37. package/dist/src/dashboard/service.js +470 -0
  38. package/dist/src/dashboard/service.js.map +1 -0
  39. package/dist/src/dashboard/spa.d.ts +29 -0
  40. package/dist/src/dashboard/spa.d.ts.map +1 -0
  41. package/dist/src/dashboard/spa.js +47 -0
  42. package/dist/src/dashboard/spa.js.map +1 -0
  43. package/dist/src/dashboard/types.d.ts +201 -0
  44. package/dist/src/dashboard/types.d.ts.map +1 -0
  45. package/dist/src/dashboard/types.js +10 -0
  46. package/dist/src/dashboard/types.js.map +1 -0
  47. package/dist/stubs/config/media_dashboard.stub +39 -0
  48. package/package.json +15 -4
@@ -0,0 +1,215 @@
1
+ import type { Readable } from 'node:stream';
2
+ import type { MediaRecord } from '../media_record.js';
3
+ import type { MediaListOptions, MediaListPage } from '../media_store.js';
4
+ import type { UploadSession } from '../resumable_upload.js';
5
+ import type { Disk, MultipartPart } from '../types.js';
6
+ import type { ObjectInsightProvider } from './object_insights.js';
7
+ import type { CollectionFilter, CollectionListResponse, CollectionsSummaryResponse, DiskListResponse, MediaDetailResponse, ObjectDetailResponse, ObjectInsightsResponse, ObjectListResponse, Topology, UploadDetailResponse, UploadListResponse } from './types.js';
8
+ /** TTL of the signed URLs handed to the browser for object preview/download. */
9
+ export declare const URL_TTL_SECONDS = 300;
10
+ /** Cap on the get→put streaming path used for cross-disk copy/move (drivers can't copy across disks). */
11
+ export declare const MAX_TRANSFER_BYTES: number;
12
+ /** Page size for the flat sweep that recursive folder delete/copy/move paginates over. */
13
+ export declare const FOLDER_SWEEP_LIMIT = 1000;
14
+ /** Page size for the client-side scan behind {@link DashboardService.collectionsSummary}. */
15
+ export declare const COLLECTIONS_SUMMARY_PAGE_SIZE = 200;
16
+ /** Hard cap on records scanned by {@link DashboardService.collectionsSummary} — beyond this the
17
+ * rollup is partial rather than unbounded. */
18
+ export declare const COLLECTIONS_SUMMARY_SCAN_LIMIT = 5000;
19
+ /** Ceiling for a console (direct) upload — buffered in memory, so bounded to protect the process
20
+ * heap. Larger files belong on the resumable (TUS) upload path, not this convenience upload. */
21
+ export declare const MAX_UPLOAD_BYTES: number;
22
+ /** The slice of `MediaManager` the dashboard depends on — kept structural so it's trivial to fake in tests. */
23
+ export interface MediaManagerLike {
24
+ readonly storage: {
25
+ readonly defaultDisk: string;
26
+ disk(name?: string): Disk;
27
+ };
28
+ readonly hasResumable: boolean;
29
+ readonly resumable: {
30
+ list(filter?: {
31
+ disk?: string;
32
+ keyPrefix?: string;
33
+ }): Promise<UploadSession[]>;
34
+ /** Discard an in-flight session (native multipart + buffered parts), then drop its record. */
35
+ abort(id: string): Promise<void>;
36
+ /** All recorded parts for a session (multipart-capable disks); empty for a buffered session. */
37
+ listParts(id: string): Promise<MultipartPart[]>;
38
+ };
39
+ /** The persistence SPI — the console reads stored records via the cross-owner `list`, and a single
40
+ * record (+ delete) for the record-detail drill-in. */
41
+ readonly store: {
42
+ list(options?: MediaListOptions): Promise<MediaListPage>;
43
+ find(id: string): Promise<MediaRecord | null>;
44
+ delete(id: string): Promise<void>;
45
+ };
46
+ }
47
+ export interface DashboardServiceOptions {
48
+ /** Disk names the console may browse/act on. The first entry (or the manager default) is the default. */
49
+ diskNames: string[];
50
+ /** Whether mutating actions (copy/move/delete) are permitted. */
51
+ actions: boolean;
52
+ }
53
+ /** An error carrying an HTTP status for the provider to surface verbatim. */
54
+ export declare class DashboardError extends Error {
55
+ readonly status: number;
56
+ constructor(message: string, status: number);
57
+ }
58
+ /**
59
+ * All dashboard read/action logic, expressed over a structural {@link MediaManagerLike}. It reads the
60
+ * *real* `@adonis-agora/media` surface — disk `list`/`stat`/`getSignedUrl`/`copy`/`move`/`deleteMany`
61
+ * and the resumable `UploadSessionStore.list()` — and never invents its own persistence. The provider
62
+ * is a thin HTTP shell around this; the logic is pure and unit-tested without booting AdonisJS.
63
+ */
64
+ export declare class DashboardService {
65
+ private readonly manager;
66
+ private readonly options;
67
+ /** Host-registered {@link ObjectInsightProvider}s, from `config/media_dashboard.ts`'s `objectInsights`. */
68
+ private readonly insightProviders;
69
+ constructor(manager: MediaManagerLike, options: DashboardServiceOptions,
70
+ /** Host-registered {@link ObjectInsightProvider}s, from `config/media_dashboard.ts`'s `objectInsights`. */
71
+ insightProviders?: ObjectInsightProvider[]);
72
+ /** Coarse capability topology for the SPA to enable/disable affordances. */
73
+ topology(): Topology;
74
+ /** Enumerate the exposed disks with their capabilities (non-extended disks report `list:false`). */
75
+ disks(): DiskListResponse;
76
+ /** List one page of a bucket under `prefix` (cursor-based, folders rolled up on the `/` delimiter). */
77
+ objects(diskName: string, params?: {
78
+ prefix?: string;
79
+ cursor?: string;
80
+ limit?: number;
81
+ }): Promise<ObjectListResponse>;
82
+ /** Object metadata + a short-lived signed URL for preview/download. */
83
+ object(diskName: string, key: string): Promise<ObjectDetailResponse>;
84
+ /**
85
+ * The object's raw byte stream plus the metadata the provider needs to serve it inline. Backs the
86
+ * console's same-origin preview proxy so text/PDF render in the browser instead of downloading
87
+ * (and so a CORS-locked bucket is still previewable).
88
+ */
89
+ objectStream(diskName: string, key: string): Promise<{
90
+ stream: Readable;
91
+ contentType: string;
92
+ size: number;
93
+ }>;
94
+ /**
95
+ * What the HOST knows about this object, from every registered `objectInsights` provider (see
96
+ * `config/media_dashboard.ts`). `{ insights: [] }` when none are registered. A provider that
97
+ * throws is skipped and logged — annotation must never be able to stop an admin opening a file, and
98
+ * providers run concurrently so one host lookup being slow doesn't serialize the others.
99
+ */
100
+ objectInsights(diskName: string, key: string): Promise<ObjectInsightsResponse>;
101
+ /** In-progress resumable uploads, projected from the session store (empty when unconfigured). */
102
+ uploads(filter?: {
103
+ disk?: string;
104
+ prefix?: string;
105
+ }): Promise<UploadListResponse>;
106
+ /** Full detail (+ recorded parts) of one resumable upload session. */
107
+ uploadDetail(id: string): Promise<UploadDetailResponse>;
108
+ /**
109
+ * Cancels a resumable session: discards its native multipart upload (or buffered parts) and drops
110
+ * its record, so it stops appearing as in-progress. Actions-gated.
111
+ */
112
+ abortUpload(id: string): Promise<void>;
113
+ /**
114
+ * One cursor-paginated page of stored media-library records across owners/collections, projected to
115
+ * the SPA's {@link MediaEntry}. Delegates to the real {@link MediaStore.list} — no bespoke query.
116
+ */
117
+ collections(params?: CollectionFilter & {
118
+ cursor?: string;
119
+ limit?: number;
120
+ }): Promise<CollectionListResponse>;
121
+ /**
122
+ * Per-collection rollup (record count + total bytes) for the console's collection chips.
123
+ * `MediaStore` has no aggregate query, so this walks `list()` in batches and sums client-side —
124
+ * bounded at {@link COLLECTIONS_SUMMARY_SCAN_LIMIT} records so a very large library degrades to a
125
+ * partial (still useful) summary instead of an unbounded scan.
126
+ */
127
+ collectionsSummary(): Promise<CollectionsSummaryResponse>;
128
+ /**
129
+ * Full detail of one stored `MediaRecord`, plus signed URLs for its generated conversions. Only
130
+ * conversions carrying a concrete `{disk, path}` artifact get a link — a metadata-only conversion
131
+ * (probe results with no output file) has nothing to preview.
132
+ */
133
+ mediaRecord(id: string): Promise<MediaDetailResponse>;
134
+ /** Deletes a stored `MediaRecord`. Actions-gated (does not touch its underlying disk object). */
135
+ deleteMediaRecord(id: string): Promise<void>;
136
+ /** Server-side copy (same disk) or streamed cross-disk copy. Original is kept. */
137
+ copy(body: {
138
+ disk: string;
139
+ from: string;
140
+ to: string;
141
+ toDisk?: string;
142
+ }): Promise<void>;
143
+ /** Server-side move (same disk) or streamed cross-disk move. Source is deleted after transfer. */
144
+ move(body: {
145
+ disk: string;
146
+ from: string;
147
+ to: string;
148
+ toDisk?: string;
149
+ }): Promise<void>;
150
+ /** Batched delete of many keys on one disk. */
151
+ remove(body: {
152
+ disk: string;
153
+ keys: string[];
154
+ }): Promise<void>;
155
+ /**
156
+ * Writes an object from a byte stream (a browser upload) — the console's convenience upload,
157
+ * distinct from the resumable TUS path. The caller supplies the full key (prefix + filename).
158
+ * Bounded at {@link MAX_UPLOAD_BYTES} so a runaway upload can't exhaust the process heap. Actions-gated.
159
+ */
160
+ putObject(diskName: string, key: string, body: AsyncIterable<Uint8Array>, contentType?: string): Promise<void>;
161
+ /**
162
+ * Create a "folder" — a zero-byte marker object at `<prefix>/`, which S3-style delimiter listing
163
+ * surfaces as a navigable folder. Normalizes to exactly one trailing slash (so the key never
164
+ * double-slashes); rejects an empty prefix. Actions-gated.
165
+ */
166
+ createFolder(body: {
167
+ disk: string;
168
+ prefix: string;
169
+ }): Promise<void>;
170
+ /**
171
+ * Recursively delete a "folder": every object under `<prefix>/` (nested included) plus the
172
+ * zero-byte marker itself. Sweeps with an EMPTY delimiter so the driver lists keys FLAT — the
173
+ * default `/` delimiter would roll nested keys up into folder prefixes and the sweep would miss
174
+ * them, deleting only direct children. Paginates until the disk reports no more, then deletes the
175
+ * marker explicitly (its key equals the sweep prefix, which `list` filters out). Actions-gated.
176
+ */
177
+ deleteFolder(body: {
178
+ disk: string;
179
+ prefix: string;
180
+ }): Promise<void>;
181
+ /** Copy a whole "folder" (every object under `<from>/`, nested included) to `<to>/`, same or cross disk. */
182
+ copyFolder(body: {
183
+ disk: string;
184
+ from: string;
185
+ to: string;
186
+ toDisk?: string;
187
+ }): Promise<void>;
188
+ /** Move a whole "folder" (every object under `<from>/`, nested included) to `<to>/`, same or cross disk. */
189
+ moveFolder(body: {
190
+ disk: string;
191
+ from: string;
192
+ to: string;
193
+ toDisk?: string;
194
+ }): Promise<void>;
195
+ private transfer;
196
+ /**
197
+ * Relocate a single object, same disk or across disks. Same-disk uses the driver's native
198
+ * `copy`/`move` (server-side, no bytes through the app). Cross-disk has no driver primitive, so the
199
+ * object is streamed through the app (get→put, capped at {@link MAX_TRANSFER_BYTES}); a `move` then
200
+ * deletes the source. Callers gate actions.
201
+ */
202
+ private transferKey;
203
+ /**
204
+ * Shared engine for {@link copyFolder}/{@link moveFolder}. Same flat-listing sweep as
205
+ * {@link deleteFolder}; each key is relocated via {@link transferKey} (so cross-disk works
206
+ * transparently), preserving its path relative to the source. On the SAME disk, rejects a
207
+ * destination inside the source (which would recurse forever); across disks that can't happen. The
208
+ * destination folder marker is written, and for a move the source marker removed, so both listings
209
+ * stay consistent. Actions-gated.
210
+ */
211
+ private transferFolder;
212
+ private extended;
213
+ private assertActions;
214
+ }
215
+ //# sourceMappingURL=service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../../../src/dashboard/service.ts"],"names":[],"mappings":"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"}