@dudousxd/nestjs-media-dashboard 0.16.2 → 0.18.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/dist/client/index.d.ts +1 -2
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +1 -4
- package/dist/client/index.js.map +1 -1
- package/dist/client/media-console-client.d.ts +14 -23
- package/dist/client/media-console-client.d.ts.map +1 -1
- package/dist/client/media-console-client.js +53 -46
- package/dist/client/media-console-client.js.map +1 -1
- package/dist/client/types.d.ts +10 -6
- package/dist/client/types.d.ts.map +1 -1
- package/dist/server/index.cjs +805 -1235
- package/dist/server/index.cjs.map +1 -1
- package/dist/server/index.d.cts +362 -239
- package/dist/server/index.d.ts +362 -239
- package/dist/server/index.js +790 -1235
- package/dist/server/index.js.map +1 -1
- package/dist/spa/assets/{ArchivePreview-h5wYCDJT.js → ArchivePreview-DacpA4QQ.js} +1 -1
- package/dist/spa/assets/CertificatePreview-CEfJ-ORW.js +127 -0
- package/dist/spa/assets/MarkdownPreview-47FMx48l.js +74 -0
- package/dist/spa/assets/ParquetPreview-DHvs5kV-.js +973 -0
- package/dist/spa/assets/{SheetPreview-Bfq7dI0a.js → SheetPreview-AT23RGVb.js} +1 -1
- package/dist/spa/assets/{SqlitePreview-JTQDjJJ3.js → SqlitePreview-D7KZuyZD.js} +1 -1
- package/dist/spa/assets/{index-Cjax4szq.js → index-BmejPQYi.js} +1 -1
- package/dist/spa/assets/{preview-BjGG6sSu.js → preview-DVKz8AwF.js} +2 -2
- package/dist/spa/assets/styles-CG_mruF7.css +1 -0
- package/dist/spa/assets/styles-CTvG1yXb.js +61 -0
- package/dist/spa/index.html +3 -3
- package/dist/spa/preview.html +3 -3
- package/package.json +25 -30
- package/dist/client/console-session.d.ts +0 -69
- package/dist/client/console-session.d.ts.map +0 -1
- package/dist/client/console-session.js +0 -120
- package/dist/client/console-session.js.map +0 -1
- package/dist/react/index.d.ts +0 -4
- package/dist/react/index.d.ts.map +0 -1
- package/dist/react/index.js +0 -15
- package/dist/react/index.js.map +0 -1
- package/dist/react/open-console-button.d.ts +0 -26
- package/dist/react/open-console-button.d.ts.map +0 -1
- package/dist/react/open-console-button.js +0 -29
- package/dist/react/open-console-button.js.map +0 -1
- package/dist/react/use-open-console.d.ts +0 -45
- package/dist/react/use-open-console.d.ts.map +0 -1
- package/dist/react/use-open-console.js +0 -75
- package/dist/react/use-open-console.js.map +0 -1
- package/dist/spa/assets/CertificatePreview-Bm4NkGaO.js +0 -127
- package/dist/spa/assets/MarkdownPreview-Cai2BrTH.js +0 -70
- package/dist/spa/assets/ParquetPreview-DfDTL_6f.js +0 -973
- package/dist/spa/assets/styles-Cui6Yy9Y.js +0 -61
- package/dist/spa/assets/styles-FRkIQ83o.css +0 -1
package/dist/server/index.d.cts
CHANGED
|
@@ -1,86 +1,132 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { HttpException, ExecutionContext, Type, ExceptionFilter, ArgumentsHost, CanActivate, Logger, DynamicModule, InjectionToken, OptionalFactoryDependency, Provider, ModuleMetadata, StreamableFile } from '@nestjs/common';
|
|
2
|
+
import { HttpAdapterHost, ModuleRef } from '@nestjs/core';
|
|
2
3
|
import { Readable } from 'node:stream';
|
|
3
|
-
import {
|
|
4
|
+
import { MediaStore, UploadSessionStore, MultipartDrivers } from '@dudousxd/nestjs-media-core';
|
|
5
|
+
import { Storage, ServeFileOptions } from '@nestjs/storage';
|
|
4
6
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
7
|
+
type ConsoleAuthorizeResult = boolean | {
|
|
8
|
+
allowed: true;
|
|
9
|
+
} | {
|
|
10
|
+
allowed: false;
|
|
11
|
+
reason?: 'unauthenticated' | 'forbidden';
|
|
12
|
+
} | {
|
|
13
|
+
redirectTo: string;
|
|
14
|
+
};
|
|
15
|
+
/** Class form: an `@Injectable()` provider (constructor injection works). */
|
|
16
|
+
interface ConsoleAuthorizer {
|
|
17
|
+
authorize(context: ExecutionContext): ConsoleAuthorizeResult | Promise<ConsoleAuthorizeResult>;
|
|
18
|
+
}
|
|
19
|
+
type ConsoleAuthorizerClass = Type<ConsoleAuthorizer>;
|
|
20
|
+
/** `@nestjs/authorization` policy check: `policy[ability](user)`. */
|
|
21
|
+
interface ConsolePolicyCheck {
|
|
22
|
+
policy: Type<unknown>;
|
|
23
|
+
ability: string;
|
|
24
|
+
}
|
|
25
|
+
type ConsoleAuthorize = ((context: ExecutionContext) => ConsoleAuthorizeResult | Promise<ConsoleAuthorizeResult>) | ConsoleAuthorizerClass | (() => Promise<{
|
|
26
|
+
default: ConsoleAuthorizerClass;
|
|
27
|
+
}>) | ConsolePolicyCheck | string;
|
|
28
|
+
type ConsoleDecision = {
|
|
29
|
+
allowed: true;
|
|
30
|
+
} | {
|
|
31
|
+
allowed: false;
|
|
32
|
+
reason: 'unauthenticated' | 'forbidden';
|
|
33
|
+
redirectTo?: string;
|
|
34
|
+
};
|
|
35
|
+
/** The provider `@dudousxd/nestjs-authz`'s `AuthzModule` registers to resolve gate names. */
|
|
36
|
+
declare const CONSOLE_GATE: symbol;
|
|
37
|
+
/** What `@dudousxd/nestjs-authz` provides under {@link CONSOLE_GATE}. */
|
|
38
|
+
interface ConsoleGate {
|
|
39
|
+
allows(name: string, context: ExecutionContext): Promise<ConsoleAuthorizeResult>;
|
|
40
|
+
}
|
|
41
|
+
/** What a resolved `authorize` is: called once per request, never throws. */
|
|
42
|
+
type ConsoleDecide = (context: ExecutionContext) => Promise<ConsoleDecision>;
|
|
43
|
+
/** The one boot warning for a console with no `authorize`. Same wording in every Aviary console. */
|
|
44
|
+
declare const CONSOLE_AUTHORIZE_MISSING_WARNING: string;
|
|
45
|
+
/** Turns any {@link ConsoleAuthorizeResult} into a {@link ConsoleDecision}. */
|
|
46
|
+
declare function normalizeConsoleResult(result: unknown): ConsoleDecision;
|
|
47
|
+
/**
|
|
48
|
+
* Resolves `authorize` into one function the guard calls per request. Configuration mistakes (a gate
|
|
49
|
+
* name without nestjs-authz, a policy without @nestjs/authorization and its module) throw here, so
|
|
50
|
+
* call it at boot. The returned function never throws: an error is a `forbidden`.
|
|
51
|
+
*
|
|
52
|
+
* `authorize` omitted: open outside production, `forbidden` for every request in production, and one
|
|
53
|
+
* warning logged (unless `warnIfMissing: false`).
|
|
54
|
+
*/
|
|
55
|
+
declare function resolveConsoleAuthorize(authorize: ConsoleAuthorize | undefined, moduleRef: ModuleRef, options?: {
|
|
56
|
+
logger?: Logger;
|
|
57
|
+
warnIfMissing?: boolean;
|
|
58
|
+
registration?: string;
|
|
59
|
+
}): Promise<ConsoleDecide>;
|
|
60
|
+
/**
|
|
61
|
+
* Allows a request carrying `Authorization: Bearer <token>` (compared timing-safe); anything else
|
|
62
|
+
* is `unauthenticated`. Header only: no query string, no custom header. Throws when `token` is
|
|
63
|
+
* empty, so a missing env var fails at config time instead of opening the console.
|
|
64
|
+
*/
|
|
65
|
+
declare function authorizeByToken(options: {
|
|
66
|
+
token: string | undefined;
|
|
67
|
+
}): ConsoleAuthorize;
|
|
68
|
+
/** DI token of the resolved {@link ConsoleDecide} the guard runs. */
|
|
69
|
+
declare const CONSOLE_AUTHORIZE_DECIDE: symbol;
|
|
70
|
+
/** Marks a controller as serving pages: a denied `GET` that accepts HTML gets a page, not JSON. */
|
|
71
|
+
declare const CONSOLE_PAGE_METADATA = "@dudousxd/nestjs-media-dashboard:console-page";
|
|
72
|
+
declare const ConsolePage: () => ClassDecorator;
|
|
73
|
+
/**
|
|
74
|
+
* The denial the guard throws. An `HttpException` with the JSON body, so it still answers correctly
|
|
75
|
+
* where {@link ConsoleAuthorizeFilter} is not applied; the filter adds the page answers.
|
|
76
|
+
*/
|
|
77
|
+
declare class ConsoleAccessDenied extends HttpException {
|
|
78
|
+
readonly decision: Extract<ConsoleDecision, {
|
|
79
|
+
allowed: false;
|
|
80
|
+
}>;
|
|
81
|
+
/** Whether the denied request was a page navigation (answered with a redirect or a page). */
|
|
82
|
+
readonly page: boolean;
|
|
83
|
+
constructor(decision: Extract<ConsoleDecision, {
|
|
84
|
+
allowed: false;
|
|
85
|
+
}>,
|
|
86
|
+
/** Whether the denied request was a page navigation (answered with a redirect or a page). */
|
|
87
|
+
page?: boolean);
|
|
10
88
|
}
|
|
11
|
-
|
|
12
|
-
/** Host hook for Mode A — validates the host's own auth on the raw request. */
|
|
13
|
-
type SessionHook = (request: unknown) => Promise<ConsoleSessionUser | null> | ConsoleSessionUser | null;
|
|
14
|
-
/** Host hook for Mode B — validates submitted credentials from the built-in login screen. */
|
|
15
|
-
type LoginHook = (username: string, password: string) => Promise<ConsoleSessionUser | null> | ConsoleSessionUser | null;
|
|
16
89
|
/**
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
* request, which a console XHR does not carry — this one receives the already-minted session.
|
|
90
|
+
* Runs the console's `authorize` on every request to a console controller. The dashboard applies it
|
|
91
|
+
* (after your `decorators`, so your authentication guards set `request.user` first); on controllers
|
|
92
|
+
* you mount yourself (`routes: false`) apply {@link UseConsoleAuthorize}.
|
|
21
93
|
*/
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
* The platform-native request — Express' `Request`, Fastify's `FastifyRequest`. Typed `unknown`
|
|
27
|
-
* for the same reason `SessionHook`'s is: this package refuses to depend on either platform.
|
|
28
|
-
*/
|
|
29
|
-
request: unknown;
|
|
30
|
-
/**
|
|
31
|
-
* The platform-native response. The hook OWNS it: it must write AND end it. If it returns without
|
|
32
|
-
* writing, the console falls back to serving its own SPA (whose auth screen then renders).
|
|
33
|
-
*/
|
|
34
|
-
response: unknown;
|
|
35
|
-
/** Where this console is mounted (e.g. `/media`) — useful for a "back to the console" link. */
|
|
36
|
-
basePath: string;
|
|
94
|
+
declare class ConsoleAuthorizeGuard implements CanActivate {
|
|
95
|
+
private readonly decide;
|
|
96
|
+
constructor(decide: ConsoleDecide);
|
|
97
|
+
canActivate(context: ExecutionContext): Promise<boolean>;
|
|
37
98
|
}
|
|
38
99
|
/**
|
|
39
|
-
*
|
|
40
|
-
*
|
|
41
|
-
* Without it, an unauthenticated visitor gets the SPA shell, which then renders the built-in auth
|
|
42
|
-
* screen: a generic "open this console from your application" card, generic because the library
|
|
43
|
-
* cannot know who hosts it. This hook replaces that with the host's own page — and, because it is
|
|
44
|
-
* decided BEFORE the shell is served, it also stops the bundle from loading for a visitor who has
|
|
45
|
-
* no session at all.
|
|
46
|
-
*
|
|
47
|
-
* Only consulted under Mode-A-only. With `login` configured the SPA's own login form IS the way in,
|
|
48
|
-
* so gating the shell would lock Mode B hosts out of their own console.
|
|
49
|
-
*
|
|
50
|
-
* Fail-closed by construction: it only ever runs when the request has no valid session. A hook that
|
|
51
|
-
* throws, or returns without writing, falls back to serving the SPA — it cannot let anyone in,
|
|
52
|
-
* because every data route stays behind `MediaConsoleGuard` regardless.
|
|
100
|
+
* Answers a console denial: JSON for API calls; for a page navigation a 302 to `redirectTo`, an
|
|
101
|
+
* "Access denied" page (403) or a "Sign in required" page (401).
|
|
53
102
|
*/
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
secret: string;
|
|
59
|
-
/** Cookie TTL as a duration string (`'8h'`, `'30m'`, `'7d'`). Default `'8h'`. */
|
|
60
|
-
ttl?: string;
|
|
61
|
-
/** Mode A: validate the host's own auth on the raw request. */
|
|
62
|
-
session?: SessionHook;
|
|
63
|
-
/** Mode B: validate credentials from the built-in login screen. */
|
|
64
|
-
login?: LoginHook;
|
|
65
|
-
/** Re-checks the session on sliding renewal. Not a mode — it cannot mint a session on its own. */
|
|
66
|
-
revalidate?: RevalidateHook;
|
|
67
|
-
/** Renders the host's own page for an unauthenticated navigation, in place of serving the SPA and
|
|
68
|
-
* letting its built-in auth screen render; see `UnauthenticatedPageHook`. Mode-A-only. */
|
|
69
|
-
unauthenticatedPage?: UnauthenticatedPageHook;
|
|
103
|
+
declare class ConsoleAuthorizeFilter implements ExceptionFilter {
|
|
104
|
+
private readonly adapterHost;
|
|
105
|
+
constructor(adapterHost: HttpAdapterHost);
|
|
106
|
+
catch(exception: ConsoleAccessDenied, host: ArgumentsHost): void;
|
|
70
107
|
}
|
|
108
|
+
/**
|
|
109
|
+
* The guard and its filter as one class decorator, for a console you mount yourself
|
|
110
|
+
* (`routes: false`). List it ABOVE your authentication guards, so it runs after them.
|
|
111
|
+
*/
|
|
112
|
+
declare const UseConsoleAuthorize: () => ClassDecorator & MethodDecorator;
|
|
71
113
|
|
|
114
|
+
/**
|
|
115
|
+
* What a disk can do, computed by the server from the `@nestjs/storage` disk and its multipart
|
|
116
|
+
* side-car (`MediaDiskCapabilities` in `-core`).
|
|
117
|
+
*/
|
|
72
118
|
interface DiskCapabilities {
|
|
119
|
+
/** `signedUrl()` works (S3, or a local disk with `signedUrls`). */
|
|
73
120
|
presign: boolean;
|
|
121
|
+
/** A multipart side-car is configured for the disk. */
|
|
74
122
|
multipart: boolean;
|
|
123
|
+
/** The disk has a `publicUrl`. */
|
|
75
124
|
publicUrls: boolean;
|
|
76
125
|
list: boolean;
|
|
77
126
|
/**
|
|
78
|
-
* Can the disk serve a byte range
|
|
79
|
-
*
|
|
80
|
-
*
|
|
81
|
-
* this is a WIRE shape: the console bundle can be served by a host still running an older server
|
|
82
|
-
* build that never emits the field. `undefined` means "this server didn't say", which a caller
|
|
83
|
-
* should treat as "don't count on it" — not as `false`.
|
|
127
|
+
* Can the disk serve a byte range (a ranged `object/raw`)? Every `@nestjs/storage` disk can, so
|
|
128
|
+
* current servers always send `true`. Optional because this is a WIRE shape: an older server may
|
|
129
|
+
* not emit it, and `undefined` means "don't count on it", not `false`.
|
|
84
130
|
*/
|
|
85
131
|
ranged?: boolean;
|
|
86
132
|
}
|
|
@@ -287,12 +333,12 @@ interface MediaDashboardOptions {
|
|
|
287
333
|
/**
|
|
288
334
|
* Where the JSON API is mounted (what the SPA fetches). Default `<basePath>/api`. Set it under
|
|
289
335
|
* your app's `/api` prefix — e.g. `/api/media/console` — so the API inherits the app's
|
|
290
|
-
*
|
|
336
|
+
* proxy rules while the UI stays at `basePath`.
|
|
291
337
|
*/
|
|
292
338
|
apiBasePath?: string;
|
|
293
339
|
/**
|
|
294
340
|
* Enable the destructive endpoints (delete object/record, copy/move, abort upload). Default
|
|
295
|
-
* `false` — the read API is always available.
|
|
341
|
+
* `false` — the read API is always available.
|
|
296
342
|
*/
|
|
297
343
|
actions?: boolean;
|
|
298
344
|
/**
|
|
@@ -306,56 +352,87 @@ interface MediaDashboardOptions {
|
|
|
306
352
|
*/
|
|
307
353
|
objectUrls?: ObjectUrlStrategy;
|
|
308
354
|
/**
|
|
309
|
-
*
|
|
310
|
-
*
|
|
311
|
-
*
|
|
312
|
-
|
|
313
|
-
|
|
355
|
+
* Extra `imports` merged into the dashboard's dynamic module — the DI resolution path for the
|
|
356
|
+
* dependencies of a guard passed through {@link decorators} (e.g. `UseGuards(AuthenticationGuard)`),
|
|
357
|
+
* or any other provider the controllers need reachable.
|
|
358
|
+
*/
|
|
359
|
+
imports?: DynamicModule['imports'];
|
|
360
|
+
/**
|
|
361
|
+
* Host-supplied context about a disk object, rendered in the console's preview — see
|
|
362
|
+
* {@link ObjectInsightProvider}. The console can only describe a file as storage sees it; this is
|
|
363
|
+
* how it learns what the file *means* to your app. Omit for no annotation (the default).
|
|
364
|
+
*
|
|
365
|
+
* Use `forRootAsync`'s `useObjectInsights` when a provider needs injected services.
|
|
314
366
|
*/
|
|
315
|
-
|
|
367
|
+
objectInsights?: ObjectInsightProvider[];
|
|
316
368
|
/**
|
|
317
|
-
*
|
|
318
|
-
*
|
|
319
|
-
*
|
|
320
|
-
* session-cookie gate — a request must pass BOTH). Deliberately NOT applied to the auth
|
|
321
|
-
* controller that MINTS that session cookie — see `MediaConsoleApiModule`'s own `guards` doc.
|
|
369
|
+
* Who may use the console: decided on EVERY console request (the page, its assets and the JSON
|
|
370
|
+
* API) by a guard that runs after your `decorators`, so your authentication guards set
|
|
371
|
+
* `request.user` first. Five forms:
|
|
322
372
|
*
|
|
323
|
-
*
|
|
324
|
-
*
|
|
325
|
-
*
|
|
373
|
+
* ```ts
|
|
374
|
+
* authorize: (ctx) => ctx.switchToHttp().getRequest().user?.isAdmin === true,
|
|
375
|
+
* authorize: ConsoleAccess, // @Injectable() implements ConsoleAuthorizer
|
|
376
|
+
* authorize: () => import('./console-access.js'), // lazy, default export
|
|
377
|
+
* authorize: { policy: ConsolePolicy, ability: 'view' }, // @nestjs/authorization policy
|
|
378
|
+
* authorize: 'console.media', // a gate from @dudousxd/nestjs-authz
|
|
379
|
+
* ```
|
|
326
380
|
*
|
|
327
|
-
*
|
|
328
|
-
*
|
|
329
|
-
*
|
|
381
|
+
* Answer `true`/`{ allowed: true }` to allow, `false`/`{ allowed: false }` for 403,
|
|
382
|
+
* `{ allowed: false, reason: 'unauthenticated' }` for 401, or `{ redirectTo: '/login' }` to send a
|
|
383
|
+
* page navigation there (API calls get 401 with `redirectTo`). A throw is a 403.
|
|
330
384
|
*
|
|
331
|
-
*
|
|
332
|
-
*
|
|
333
|
-
* built-in session cookie too. Configure one, the other, or both.
|
|
385
|
+
* Omitted: open outside production; in production every request answers 403, and one warning is
|
|
386
|
+
* logged at boot.
|
|
334
387
|
*
|
|
335
|
-
*
|
|
336
|
-
*
|
|
388
|
+
* This is the console's access. It is not `MediaModule`'s `authorize(user, action, subject)` hook,
|
|
389
|
+
* which governs the product upload routes.
|
|
337
390
|
*/
|
|
338
|
-
|
|
391
|
+
authorize?: ConsoleAuthorize;
|
|
339
392
|
/**
|
|
340
|
-
*
|
|
341
|
-
*
|
|
342
|
-
*
|
|
393
|
+
* Class decorators applied to EVERY controller the console mounts — the page/asset controller
|
|
394
|
+
* and the read and action APIs — e.g.
|
|
395
|
+
* `[UseGuards(AuthenticationGuard), Can(MediaPolicy, 'console')]` with the first-party
|
|
396
|
+
* `@nestjs/authentication` / `@nestjs/authorization`. Default: none.
|
|
397
|
+
*
|
|
398
|
+
* Every console controller is marked `@Can.Anyone()`-open (`'authorization:can-anyone'`) so
|
|
399
|
+
* `@nestjs/authorization`'s deny-by-default global guard doesn't refuse the console; a `Can(...)`
|
|
400
|
+
* passed here is still checked (the guard treats `can-anyone` as open only when no requirement is
|
|
401
|
+
* declared).
|
|
402
|
+
*
|
|
403
|
+
* `decorators` don't decide access on their own: use them for authentication, throttling and the
|
|
404
|
+
* like, and {@link authorize} for who may use the console.
|
|
405
|
+
*
|
|
406
|
+
* Full-page navigations to `basePath` carry only cookies, never an `Authorization` header — a
|
|
407
|
+
* guard here must be able to authenticate the page from a cookie, or every browser visit 401s.
|
|
408
|
+
*
|
|
409
|
+
* Each registration decorates fresh subclasses of the controllers, so one registration's
|
|
410
|
+
* decorators never reach another.
|
|
343
411
|
*/
|
|
344
|
-
|
|
412
|
+
decorators?: ClassDecorator[];
|
|
345
413
|
/**
|
|
346
|
-
*
|
|
347
|
-
*
|
|
348
|
-
*
|
|
414
|
+
* `false` mounts NO controller — no page, no JSON API — while every provider still works and is
|
|
415
|
+
* exported (`MediaConsoleService`, the resolved paths), so you serve
|
|
416
|
+
* the console from controllers of your own by extending the exported controller classes. Apply
|
|
417
|
+
* `UseConsoleAuthorize()` to them, ABOVE your authentication guard (class decorators apply
|
|
418
|
+
* bottom-up, so authentication runs first), so {@link authorize} still decides access. Keep
|
|
419
|
+
* `basePath`/`apiBasePath` equal to where you mount them: the SPA reads both.
|
|
349
420
|
*
|
|
350
|
-
*
|
|
421
|
+
* ```ts
|
|
422
|
+
* @UseConsoleAuthorize()
|
|
423
|
+
* @UseGuards(AuthGuard)
|
|
424
|
+
* @Controller('media/api')
|
|
425
|
+
* export class ConsoleApiController extends MediaConsoleReadController {}
|
|
426
|
+
* ```
|
|
427
|
+
*
|
|
428
|
+
* Default `true`.
|
|
351
429
|
*/
|
|
352
|
-
|
|
430
|
+
routes?: boolean;
|
|
353
431
|
}
|
|
354
432
|
/**
|
|
355
|
-
* Async variant of {@link MediaDashboardOptions}. The mount paths
|
|
356
|
-
* router needs them at module-definition time)
|
|
357
|
-
*
|
|
358
|
-
* admin). Returning `undefined` from the factory leaves the console open.
|
|
433
|
+
* Async variant of {@link MediaDashboardOptions}. The mount paths, `actions` and `decorators` stay
|
|
434
|
+
* static (the router needs them at module-definition time); the `objectInsights` providers are
|
|
435
|
+
* built by an injected factory, so they can reach your repositories and services.
|
|
359
436
|
*/
|
|
360
437
|
interface MediaDashboardAsyncOptions {
|
|
361
438
|
basePath?: string;
|
|
@@ -364,110 +441,83 @@ interface MediaDashboardAsyncOptions {
|
|
|
364
441
|
/** See {@link MediaDashboardOptions.objectUrls}. Static like the mount paths and `actions` —
|
|
365
442
|
* it is read at module-definition time, not per request. */
|
|
366
443
|
objectUrls?: ObjectUrlStrategy;
|
|
367
|
-
/** Modules exporting the providers `inject` needs, or a guard
|
|
368
|
-
* when they're global).
|
|
444
|
+
/** Modules exporting the providers `inject` needs, or a decorator guard's own dependencies (omit
|
|
445
|
+
* when they're global). */
|
|
369
446
|
imports?: DynamicModule['imports'];
|
|
370
|
-
/** Providers injected into `
|
|
447
|
+
/** Providers injected into `useObjectInsights`, in order. */
|
|
371
448
|
inject?: Array<InjectionToken | OptionalFactoryDependency>;
|
|
372
|
-
/** Build the `auth` config from injected deps (or `undefined` to leave the console open). */
|
|
373
|
-
useAuth: (...deps: any[]) => ConsoleAuthOptions | undefined | Promise<ConsoleAuthOptions | undefined>;
|
|
374
|
-
/**
|
|
375
|
-
* Guard classes (or instances) fronting the console — see {@link MediaDashboardOptions.guards}.
|
|
376
|
-
* Passed here directly (not resolved via `useAuth`'s factory) because guard stamping happens at
|
|
377
|
-
* module-build time, synchronously — the SAME constraint as `basePath`/`apiBasePath` above. A
|
|
378
|
-
* class guard's own dependencies resolve from `imports` above (shared with `useAuth`'s `inject`).
|
|
379
|
-
*/
|
|
380
|
-
guards?: Array<Type<CanActivate> | CanActivate>;
|
|
381
449
|
/**
|
|
382
450
|
* Build the {@link MediaDashboardOptions.objectInsights} providers from injected deps — the usual
|
|
383
451
|
* case, since a provider that says anything interesting needs a repository or a service.
|
|
384
452
|
*/
|
|
385
453
|
useObjectInsights?: (...deps: any[]) => ObjectInsightProvider[] | Promise<ObjectInsightProvider[]>;
|
|
386
454
|
/**
|
|
387
|
-
*
|
|
388
|
-
*
|
|
389
|
-
* sharing one list would force every host to inject the union of both.
|
|
455
|
+
* See {@link MediaDashboardOptions.decorators}. Static (not built by a factory): the decorators
|
|
456
|
+
* shape the routes when the module is built.
|
|
390
457
|
*/
|
|
391
|
-
|
|
458
|
+
decorators?: ClassDecorator[];
|
|
459
|
+
/** See {@link MediaDashboardOptions.authorize}. Static, like `decorators`. */
|
|
460
|
+
authorize?: ConsoleAuthorize;
|
|
461
|
+
/** See {@link MediaDashboardOptions.routes}. Static, like `decorators`. */
|
|
462
|
+
routes?: boolean;
|
|
392
463
|
}
|
|
393
464
|
/**
|
|
394
465
|
* Mounts the /media console: the bundled React SPA at `basePath` and its JSON API at `apiBasePath`
|
|
395
466
|
* (default `<basePath>/api`). Import via `MediaDashboardModule.forRoot(...)` (or `forRootAsync` when
|
|
396
|
-
* the `
|
|
397
|
-
* storage/store/upload tokens. Exclude the UI/API paths from any global `/api` prefix.
|
|
467
|
+
* the `objectInsights` providers need injected services) alongside `MediaModule` (global), so it
|
|
468
|
+
* resolves the storage/store/upload tokens. Exclude the UI/API paths from any global `/api` prefix.
|
|
398
469
|
*
|
|
399
|
-
*
|
|
400
|
-
*
|
|
470
|
+
* Decide who may use it with {@link MediaDashboardOptions.authorize}; without it the console is open
|
|
471
|
+
* outside production and answers 403 to everything in production.
|
|
401
472
|
*/
|
|
402
473
|
declare class MediaDashboardModule {
|
|
403
474
|
static forRoot(options?: MediaDashboardOptions): DynamicModule;
|
|
404
|
-
static forRootAsync(options
|
|
405
|
-
/** Shared wiring: static routing + the API module, with
|
|
475
|
+
static forRootAsync(options?: MediaDashboardAsyncOptions): DynamicModule;
|
|
476
|
+
/** Shared wiring: static routing + the API module, with the insights from the given provider. */
|
|
406
477
|
private static build;
|
|
407
478
|
}
|
|
408
479
|
|
|
409
|
-
interface
|
|
480
|
+
interface MediaConsoleApiModuleOptions {
|
|
410
481
|
actions: boolean;
|
|
411
|
-
/** Cookie `Path` — the JSON API base — so the session cookie rides every console API request. */
|
|
412
|
-
cookiePath: string;
|
|
413
|
-
/** Provider for `MEDIA_CONSOLE_AUTH` — a `useValue` (forRoot) or a `useFactory` (forRootAsync). */
|
|
414
|
-
authProvider: Provider;
|
|
415
482
|
/** Provider for `MEDIA_CONSOLE_OBJECT_INSIGHTS` — the host's object-annotation providers.
|
|
416
483
|
* Omitted binds the empty list, which is the no-op the console renders nothing for. */
|
|
417
484
|
insightsProvider?: Provider;
|
|
418
485
|
/** Resolved object-URL strategy + the API mount it builds proxy URLs against. */
|
|
419
486
|
objectUrls: ObjectUrlConfig;
|
|
420
|
-
/** Extra imports the
|
|
487
|
+
/** Extra imports the insights factory's `inject` deps (or a decorator's guards' deps) live in. */
|
|
421
488
|
imports?: ModuleMetadata['imports'];
|
|
422
489
|
/**
|
|
423
|
-
*
|
|
424
|
-
*
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
*
|
|
490
|
+
* Who may use the console API — see `MediaDashboardOptions.authorize`. Omitted: open outside
|
|
491
|
+
* production, every request answers 403 in production, and one warning is logged at boot.
|
|
492
|
+
*/
|
|
493
|
+
authorize?: ConsoleAuthorize;
|
|
494
|
+
/** The registration named in the boot warning when `authorize` is omitted. Default
|
|
495
|
+
* `'MediaConsoleApiModule.register()'`. */
|
|
496
|
+
moduleName?: string;
|
|
497
|
+
/**
|
|
498
|
+
* Class decorators applied to EVERY controller this module mounts (read, actions) — see
|
|
499
|
+
* `MediaDashboardOptions.decorators`. Each call decorates fresh subclasses, never the shared
|
|
500
|
+
* classes, so decorators never leak from one registration into the next.
|
|
429
501
|
*/
|
|
430
|
-
|
|
502
|
+
decorators?: ClassDecorator[];
|
|
503
|
+
/**
|
|
504
|
+
* `false` registers no controller, only the providers (exported), for a host that mounts the
|
|
505
|
+
* controllers itself — see `MediaDashboardOptions.routes`. Default `true`.
|
|
506
|
+
*/
|
|
507
|
+
routes?: boolean;
|
|
431
508
|
}
|
|
432
509
|
/**
|
|
433
|
-
* Holds the console's JSON API: the read controller (always)
|
|
434
|
-
* `actions: true`)
|
|
435
|
-
* is never itself guarded). The read/action controllers carry `MediaConsoleGuard`, a no-op unless
|
|
436
|
-
* the host configured `auth`, plus any host `guards` (see {@link ApiModuleOptions.guards}) — both
|
|
437
|
-
* gates must pass.
|
|
510
|
+
* Holds the console's JSON API: the read controller (always) and the actions controller (only when
|
|
511
|
+
* `actions: true`). Who reaches them is decided by `authorize` (`ConsoleAuthorizeGuard`).
|
|
438
512
|
*/
|
|
439
513
|
declare class MediaConsoleApiModule {
|
|
440
|
-
static register(options:
|
|
514
|
+
static register(options: MediaConsoleApiModuleOptions): DynamicModule;
|
|
441
515
|
}
|
|
442
516
|
|
|
443
517
|
/**
|
|
444
|
-
*
|
|
445
|
-
*
|
|
446
|
-
*
|
|
447
|
-
* 500 bytes") — which cannot be made absolute without the size, and the size is `stat`'s to give.
|
|
448
|
-
* Resolving it here rather than in the controller saves a second `stat` on the request path.
|
|
449
|
-
*/
|
|
450
|
-
type RequestedReadRange = ReadRangeOptions | {
|
|
451
|
-
suffixLength: number;
|
|
452
|
-
};
|
|
453
|
-
/** What {@link MediaConsoleService.objectStream} hands the controller. `range` is present only when
|
|
454
|
-
* a range was requested AND satisfied, already absolute and clamped to the object — so the
|
|
455
|
-
* controller can write `Content-Range`/`Content-Length` without re-deriving anything. */
|
|
456
|
-
interface ObjectStreamResult {
|
|
457
|
-
stream: Readable;
|
|
458
|
-
contentType: string;
|
|
459
|
-
/** Total size of the OBJECT, not of the slice — the `/<size>` in `Content-Range`. */
|
|
460
|
-
size: number;
|
|
461
|
-
/** Absolute inclusive bounds actually being streamed. Absent on a full-body read. */
|
|
462
|
-
range?: {
|
|
463
|
-
start: number;
|
|
464
|
-
end: number;
|
|
465
|
-
};
|
|
466
|
-
}
|
|
467
|
-
/**
|
|
468
|
-
* Read + action logic behind the console's JSON API. Resolves the three by-value media tokens
|
|
469
|
-
* with `@Optional()` so a host without a `MediaStore`/upload store still boots — every method
|
|
470
|
-
* degrades to an empty shape instead of throwing when its capability is absent.
|
|
518
|
+
* Read + action logic behind the console's JSON API, on the disks of `@nestjs/storage` (`Storage`).
|
|
519
|
+
* Resolves the store, upload store and multipart side-cars with `@Optional()` so a host without
|
|
520
|
+
* them still boots — every method degrades to an empty shape instead of throwing.
|
|
471
521
|
*/
|
|
472
522
|
declare class MediaConsoleService {
|
|
473
523
|
private readonly storage;
|
|
@@ -476,16 +526,25 @@ declare class MediaConsoleService {
|
|
|
476
526
|
private readonly actionsEnabled;
|
|
477
527
|
private readonly insightProviders;
|
|
478
528
|
private readonly objectUrls;
|
|
479
|
-
|
|
529
|
+
/** `MediaModuleOptions.multipart`: native folder listing and the multipart badge. */
|
|
530
|
+
private readonly multipart;
|
|
531
|
+
constructor(storage: Storage | null, store: MediaStore | null, uploads: UploadSessionStore | null, actionsEnabled: boolean | null, insightProviders?: ObjectInsightProvider[] | null, objectUrls?: ObjectUrlConfig | null,
|
|
532
|
+
/** `MediaModuleOptions.multipart`: native folder listing and the multipart badge. */
|
|
533
|
+
multipart?: MultipartDrivers | null);
|
|
534
|
+
private readonly logger;
|
|
480
535
|
/**
|
|
481
536
|
* The URL to report for an object's bytes, under the host's {@link ObjectUrlStrategy}. `auto`
|
|
482
|
-
* prefers
|
|
483
|
-
*
|
|
537
|
+
* prefers the disk's public URL, then a signed one (S3 presigns; a local disk signs with
|
|
538
|
+
* `signedUrls`), and falls back to this server's own route for a disk that can do neither.
|
|
539
|
+
* `proxy` always routes through this server.
|
|
484
540
|
*/
|
|
485
541
|
private objectUrl;
|
|
486
|
-
private readonly logger;
|
|
487
542
|
private diskOrThrow;
|
|
488
|
-
listDisks(): DiskListResponse
|
|
543
|
+
listDisks(): Promise<DiskListResponse>;
|
|
544
|
+
/**
|
|
545
|
+
* One folder level. `StorageDisk.list()` is flat; a disk whose multipart side-car lists with a
|
|
546
|
+
* delimiter (S3) asks the store for folders, any other disk folds its flat listing.
|
|
547
|
+
*/
|
|
489
548
|
listObjects(disk: string, options: {
|
|
490
549
|
prefix?: string;
|
|
491
550
|
cursor?: string;
|
|
@@ -493,76 +552,55 @@ declare class MediaConsoleService {
|
|
|
493
552
|
}): Promise<ObjectListResponse>;
|
|
494
553
|
objectDetail(disk: string, key: string): Promise<ObjectDetailResponse>;
|
|
495
554
|
/**
|
|
496
|
-
* What the HOST knows about this object, from every registered provider.
|
|
497
|
-
*
|
|
498
|
-
*
|
|
499
|
-
* endpoint is separate from its document listing: `objectDetail` is on the path of every preview
|
|
500
|
-
* and every navigation, and providers reach into host databases. Folding them in would put a host
|
|
501
|
-
* query on reads that only wanted a presigned URL.
|
|
502
|
-
*
|
|
503
|
-
* Failures are contained per provider. A provider that throws is logged and dropped, and the
|
|
504
|
-
* others still render — annotation must never be able to stop an admin opening a file, and one
|
|
505
|
-
* host lookup being down says nothing about the rest.
|
|
506
|
-
*
|
|
507
|
-
* Providers run concurrently: they are independent host lookups, and running them in series would
|
|
508
|
-
* make the panel as slow as their sum for no gain.
|
|
555
|
+
* What the HOST knows about this object, from every registered provider. Its own call rather
|
|
556
|
+
* than a field on `objectDetail`, so host lookups stay off the preview path. A provider that
|
|
557
|
+
* throws is logged and dropped; providers run concurrently.
|
|
509
558
|
*/
|
|
510
559
|
objectInsights(disk: string, key: string): Promise<ObjectInsightsResponse>;
|
|
511
560
|
/**
|
|
512
|
-
*
|
|
513
|
-
*
|
|
514
|
-
*
|
|
515
|
-
*
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
*
|
|
520
|
-
*
|
|
521
|
-
*
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
*
|
|
526
|
-
*
|
|
561
|
+
* Streams an object as the response through `@nestjs/storage`'s `serveFile()`: a single `Range`
|
|
562
|
+
* gets a 206 with `Content-Range` (how a SQLite/ZIP/Parquet preview reads a few KB out of a huge
|
|
563
|
+
* object), `If-None-Match` a 304, a range past the end a 416, a missing file a 404. `inline`
|
|
564
|
+
* applies only to types that can't run script in this origin; others download.
|
|
565
|
+
*/
|
|
566
|
+
serveObject(disk: string, key: string, options: ServeFileOptions): Promise<StreamableFile | undefined>;
|
|
567
|
+
/**
|
|
568
|
+
* Writes an object from a byte stream (a browser upload), streamed onto the disk: S3Disk turns a
|
|
569
|
+
* body of unknown length into a multipart upload itself, so nothing is buffered here. With the
|
|
570
|
+
* request's `Content-Length`, a body that ends short fails and nothing is written.
|
|
571
|
+
*/
|
|
572
|
+
putObject(disk: string, key: string, body: Readable, contentType?: string, contentLength?: number): Promise<void>;
|
|
573
|
+
/**
|
|
574
|
+
* Creates a folder: a zero-byte `<prefix>/.keep` file (hidden from listings), since
|
|
575
|
+
* `@nestjs/storage` keys can't end with `/`. Listings show the folder because a key lives in it.
|
|
527
576
|
*/
|
|
528
|
-
objectStream(disk: string, key: string, range?: RequestedReadRange): Promise<ObjectStreamResult>;
|
|
529
|
-
/** Writes an object from a byte stream (a browser upload). The caller supplies the full key
|
|
530
|
-
* (prefix + filename); an unknown disk 404s via {@link diskOrThrow}. Actions-gated.
|
|
531
|
-
*
|
|
532
|
-
* The request stream is buffered before the write: S3's PutObject needs a known Content-Length,
|
|
533
|
-
* which a raw request stream doesn't carry, so passing the stream straight through fails. Bounded
|
|
534
|
-
* at {@link MAX_UPLOAD_BYTES} so a runaway upload can't exhaust the pod's heap — larger files
|
|
535
|
-
* belong on the resumable upload path, not this console convenience upload. */
|
|
536
|
-
putObject(disk: string, key: string, body: Readable, contentType?: string): Promise<void>;
|
|
537
|
-
/** Creates a "folder" — a zero-byte marker object at `<prefix>/`, which S3-style listing surfaces
|
|
538
|
-
* as a navigable folder. Normalizes to exactly one trailing slash; rejects an empty prefix. */
|
|
539
577
|
createFolder(disk: string, prefix: string): Promise<void>;
|
|
540
578
|
deleteObject(disk: string, key: string): Promise<void>;
|
|
541
|
-
/**
|
|
542
|
-
*
|
|
543
|
-
*
|
|
544
|
-
*
|
|
545
|
-
|
|
546
|
-
* end. Actions-gated. */
|
|
579
|
+
/**
|
|
580
|
+
* Recursively deletes a folder: every file under `<prefix>/`, nested included (its `.keep`
|
|
581
|
+
* too), a batch of keys per `delete()`. A legacy `prefix/` marker object written by another tool
|
|
582
|
+
* can't be addressed through `@nestjs/storage`; it is skipped.
|
|
583
|
+
*/
|
|
547
584
|
deleteFolder(disk: string, prefix: string): Promise<void>;
|
|
548
585
|
copyObject(fromDisk: string, from: string, toDisk: string, to: string): Promise<void>;
|
|
549
586
|
moveObject(fromDisk: string, from: string, toDisk: string, to: string): Promise<void>;
|
|
550
|
-
/**
|
|
551
|
-
*
|
|
552
|
-
*
|
|
553
|
-
*
|
|
587
|
+
/**
|
|
588
|
+
* Copies or moves one object. Same disk: the disk's own `copy`/`move` (server-side on S3, a
|
|
589
|
+
* rename on a local disk). Across disks: the source's body streams into the destination's
|
|
590
|
+
* `put()` (no size limit, nothing buffered), keeping its content type, cache control,
|
|
591
|
+
* disposition and metadata; a `move` then deletes the source.
|
|
592
|
+
*/
|
|
554
593
|
private transferKey;
|
|
555
|
-
/** Moves a whole
|
|
556
|
-
* disk or across disks, preserving each key's path relative to the source. */
|
|
594
|
+
/** Moves a whole folder (every file under `<from>/`, nested included) to `<to>/`. */
|
|
557
595
|
moveFolder(fromDisk: string, from: string, toDisk: string, to: string): Promise<void>;
|
|
558
|
-
/** Copies a whole
|
|
559
|
-
* across disks, preserving each key's path relative to the source. */
|
|
596
|
+
/** Copies a whole folder (every file under `<from>/`, nested included) to `<to>/`. */
|
|
560
597
|
copyFolder(fromDisk: string, from: string, toDisk: string, to: string): Promise<void>;
|
|
561
|
-
/**
|
|
562
|
-
*
|
|
563
|
-
*
|
|
564
|
-
*
|
|
565
|
-
*
|
|
598
|
+
/**
|
|
599
|
+
* Shared engine for {@link moveFolder}/{@link copyFolder}: a flat sweep of the source, each key
|
|
600
|
+
* relocated via {@link transferKey}, keeping its path relative to the folder (an empty folder's
|
|
601
|
+
* `.keep` goes along). On the SAME disk, a destination inside the source is refused (it would
|
|
602
|
+
* recurse forever).
|
|
603
|
+
*/
|
|
566
604
|
private transferFolder;
|
|
567
605
|
listUploads(filter: {
|
|
568
606
|
disk?: string;
|
|
@@ -589,11 +627,96 @@ declare class MediaConsoleService {
|
|
|
589
627
|
topology(): Topology;
|
|
590
628
|
}
|
|
591
629
|
|
|
630
|
+
/**
|
|
631
|
+
* Serves the bundled /media console SPA at the configured base (+ hashed assets at `<base>/assets`).
|
|
632
|
+
* The path comes from `RouterModule` (set by `MediaDashboardModule.forRoot({ basePath })`), so the
|
|
633
|
+
* controller routes are relative.
|
|
634
|
+
*/
|
|
635
|
+
declare class MediaDashboardUiController {
|
|
636
|
+
private readonly basePath;
|
|
637
|
+
private readonly apiBasePath;
|
|
638
|
+
private readonly dir;
|
|
639
|
+
constructor(basePath: string, apiBasePath: string);
|
|
640
|
+
index(): string;
|
|
641
|
+
asset(file: string): StreamableFile;
|
|
642
|
+
}
|
|
643
|
+
|
|
644
|
+
/**
|
|
645
|
+
* Read-only JSON API for the /media console. Bare `@Controller()` — the path prefix is applied by
|
|
646
|
+
* `RouterModule` (set in `MediaDashboardModule.forRoot({ apiBasePath })`). Always mounted.
|
|
647
|
+
*/
|
|
648
|
+
declare class MediaConsoleReadController {
|
|
649
|
+
private readonly service;
|
|
650
|
+
constructor(service: MediaConsoleService);
|
|
651
|
+
disks(): Promise<DiskListResponse>;
|
|
652
|
+
objects(disk: string, prefix?: string, cursor?: string, limit?: string): Promise<ObjectListResponse>;
|
|
653
|
+
object(disk: string, key: string): Promise<ObjectDetailResponse>;
|
|
654
|
+
/** What the host knows about this object, from its registered `objectInsights` providers. Empty
|
|
655
|
+
* when none are registered — the console renders nothing for an empty list. */
|
|
656
|
+
objectInsights(disk: string, key: string): Promise<ObjectInsightsResponse>;
|
|
657
|
+
/**
|
|
658
|
+
* Streams the object's bytes from the same origin (`serveFile()`), so the SPA can render previews
|
|
659
|
+
* past CORS: `inline` for types that can't run script here (images, PDF, audio, video, plain
|
|
660
|
+
* text), `attachment` for the rest — the text previews read the body with `fetch`, which doesn't
|
|
661
|
+
* care. A single `Range` gets a 206, which is how SQLite/ZIP/Parquet previews read a few KB out
|
|
662
|
+
* of a multi-hundred-MB object.
|
|
663
|
+
*/
|
|
664
|
+
objectRaw(disk: string, key: string, req: unknown, res: unknown): Promise<StreamableFile | undefined>;
|
|
665
|
+
/**
|
|
666
|
+
* The same bytes as `/raw`, but as a SAVE: `Content-Disposition: attachment` with the object's
|
|
667
|
+
* own name. Same-origin and unconditional, so it works where the browser can't reach the store.
|
|
668
|
+
*/
|
|
669
|
+
objectDownload(disk: string, key: string, req: unknown, res: unknown): Promise<StreamableFile | undefined>;
|
|
670
|
+
uploads(disk?: string, prefix?: string): Promise<UploadListResponse>;
|
|
671
|
+
upload(id: string): Promise<UploadDetailResponse>;
|
|
672
|
+
collections(): Promise<CollectionsResponse>;
|
|
673
|
+
library(collection?: string, disk?: string, cursor?: string, limit?: string): Promise<LibraryListResponse>;
|
|
674
|
+
libraryRecord(id: string): Promise<LibraryDetailResponse>;
|
|
675
|
+
topology(): Topology;
|
|
676
|
+
}
|
|
677
|
+
|
|
678
|
+
interface CopyMoveBody {
|
|
679
|
+
from: string;
|
|
680
|
+
to: string;
|
|
681
|
+
/** Destination disk for a cross-disk copy/move. Omitted → same disk as the source (`:disk`). */
|
|
682
|
+
toDisk?: string;
|
|
683
|
+
}
|
|
684
|
+
interface CreateFolderBody {
|
|
685
|
+
prefix: string;
|
|
686
|
+
}
|
|
687
|
+
/**
|
|
688
|
+
* Destructive JSON API for the /media console. Only registered when the host opts in with
|
|
689
|
+
* `MediaDashboardModule.forRoot({ actions: true })` (default off). Bare `@Controller()` — the path
|
|
690
|
+
* prefix comes from `RouterModule`, sharing the API base with the read controller.
|
|
691
|
+
*/
|
|
692
|
+
declare class MediaConsoleActionsController {
|
|
693
|
+
private readonly service;
|
|
694
|
+
constructor(service: MediaConsoleService);
|
|
695
|
+
deleteObject(disk: string, key: string): Promise<void>;
|
|
696
|
+
copyObject(disk: string, body: CopyMoveBody): Promise<void>;
|
|
697
|
+
moveObject(disk: string, body: CopyMoveBody): Promise<void>;
|
|
698
|
+
moveFolder(disk: string, body: CopyMoveBody): Promise<void>;
|
|
699
|
+
copyFolder(disk: string, body: CopyMoveBody): Promise<void>;
|
|
700
|
+
/**
|
|
701
|
+
* Uploads a file to `key` on the disk. The body is the raw bytes sent as `application/octet-stream`
|
|
702
|
+
* so the host's JSON/urlencoded body parsers never consume the stream; the real MIME rides as the
|
|
703
|
+
* `type` query param and becomes the stored object's Content-Type. `@Req()` is the request stream,
|
|
704
|
+
* streamed onto the disk (no size cap, nothing buffered).
|
|
705
|
+
*/
|
|
706
|
+
uploadObject(disk: string, key: string, request: Readable & {
|
|
707
|
+
headers?: Record<string, string | string[] | undefined>;
|
|
708
|
+
}, type?: string): Promise<void>;
|
|
709
|
+
createFolder(disk: string, body: CreateFolderBody): Promise<void>;
|
|
710
|
+
deleteFolder(disk: string, prefix: string): Promise<void>;
|
|
711
|
+
abortUpload(id: string): Promise<void>;
|
|
712
|
+
deleteLibraryRecord(id: string): Promise<void>;
|
|
713
|
+
}
|
|
714
|
+
|
|
592
715
|
/** The configured `MediaStore` (or `null`), provided by `MediaModule`. */
|
|
593
716
|
declare const MEDIA_STORE: symbol;
|
|
594
717
|
/** The configured `UploadSessionStore` (or `null`), provided by `MediaModule`. */
|
|
595
718
|
declare const MEDIA_UPLOAD_SESSIONS: symbol;
|
|
596
|
-
/** The
|
|
597
|
-
declare const
|
|
719
|
+
/** The multipart side-cars by disk name (`MediaModuleOptions.multipart`), provided by `MediaModule`. */
|
|
720
|
+
declare const MEDIA_MULTIPART: symbol;
|
|
598
721
|
|
|
599
|
-
export { type CollectionInfo, type CollectionsResponse, type
|
|
722
|
+
export { CONSOLE_AUTHORIZE_DECIDE, CONSOLE_AUTHORIZE_MISSING_WARNING, CONSOLE_GATE, CONSOLE_PAGE_METADATA, type CollectionInfo, type CollectionsResponse, ConsoleAccessDenied, type ConsoleAuthorize, ConsoleAuthorizeFilter, ConsoleAuthorizeGuard, type ConsoleAuthorizeResult, type ConsoleAuthorizer, type ConsoleAuthorizerClass, type ConsoleDecide, type ConsoleDecision, type ConsoleGate, ConsolePage, type ConsolePolicyCheck, type DiskCapabilities, type DiskInfo, type DiskListResponse, type LibraryDetailResponse, type LibraryListResponse, type LibraryRecord, type LibraryVariant, MEDIA_MULTIPART, MEDIA_STORE, MEDIA_UPLOAD_SESSIONS, MediaConsoleActionsController, MediaConsoleApiModule, type MediaConsoleApiModuleOptions, MediaConsoleReadController, MediaConsoleService, type MediaDashboardAsyncOptions, MediaDashboardModule, type MediaDashboardOptions, MediaDashboardUiController, type ObjectDetailResponse, type ObjectEntry, type ObjectFolder, type ObjectInsight, type ObjectInsightContext, type ObjectInsightFact, type ObjectInsightLink, type ObjectInsightProvider, type ObjectInsightsResponse, type ObjectListResponse, type ObjectUrlConfig, type ObjectUrlStrategy, type Topology, type UploadDetailResponse, type UploadInfo, type UploadListResponse, type UploadPart, UseConsoleAuthorize, authorizeByToken, normalizeConsoleResult, resolveConsoleAuthorize };
|