@adonis-agora/media 0.1.1 → 0.2.1
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 +87 -0
- package/dist/configure.d.ts +2 -2
- package/dist/configure.d.ts.map +1 -1
- package/dist/configure.js +3 -2
- package/dist/configure.js.map +1 -1
- package/dist/providers/media_provider.d.ts +15 -0
- package/dist/providers/media_provider.d.ts.map +1 -1
- package/dist/providers/media_provider.js +224 -12
- package/dist/providers/media_provider.js.map +1 -1
- package/dist/src/attachment.d.ts +1 -0
- package/dist/src/attachment.d.ts.map +1 -1
- package/dist/src/attachment.js +57 -21
- package/dist/src/attachment.js.map +1 -1
- package/dist/src/define_config.d.ts +83 -5
- package/dist/src/define_config.d.ts.map +1 -1
- package/dist/src/define_config.js +3 -1
- package/dist/src/define_config.js.map +1 -1
- package/dist/src/diagnostics.d.ts +32 -1
- package/dist/src/diagnostics.d.ts.map +1 -1
- package/dist/src/diagnostics.js.map +1 -1
- package/dist/src/disks/factory.d.ts +62 -0
- package/dist/src/disks/factory.d.ts.map +1 -0
- package/dist/src/disks/factory.js +57 -0
- package/dist/src/disks/factory.js.map +1 -0
- package/dist/src/disks/s3.d.ts +76 -0
- package/dist/src/disks/s3.d.ts.map +1 -0
- package/dist/src/disks/s3.js +357 -0
- package/dist/src/disks/s3.js.map +1 -0
- package/dist/src/disks/xml_fallback.d.ts +29 -0
- package/dist/src/disks/xml_fallback.d.ts.map +1 -0
- package/dist/src/disks/xml_fallback.js +68 -0
- package/dist/src/disks/xml_fallback.js.map +1 -0
- package/dist/src/errors.d.ts +34 -0
- package/dist/src/errors.d.ts.map +1 -1
- package/dist/src/errors.js +60 -0
- package/dist/src/errors.js.map +1 -1
- package/dist/src/extended_disk.d.ts +10 -0
- package/dist/src/extended_disk.d.ts.map +1 -0
- package/dist/src/extended_disk.js +19 -0
- package/dist/src/extended_disk.js.map +1 -0
- package/dist/src/index.d.ts +17 -7
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +11 -4
- package/dist/src/index.js.map +1 -1
- package/dist/src/media_library.d.ts +4 -2
- package/dist/src/media_library.d.ts.map +1 -1
- package/dist/src/media_library.js +83 -32
- package/dist/src/media_library.js.map +1 -1
- package/dist/src/media_manager.d.ts +48 -0
- package/dist/src/media_manager.d.ts.map +1 -1
- package/dist/src/media_manager.js +68 -0
- package/dist/src/media_manager.js.map +1 -1
- package/dist/src/media_store.d.ts +40 -0
- package/dist/src/media_store.d.ts.map +1 -1
- package/dist/src/media_store.js +28 -1
- package/dist/src/media_store.js.map +1 -1
- package/dist/src/multipart.d.ts +10 -0
- package/dist/src/multipart.d.ts.map +1 -0
- package/dist/src/multipart.js +16 -0
- package/dist/src/multipart.js.map +1 -0
- package/dist/src/resumable_upload.d.ts +131 -0
- package/dist/src/resumable_upload.d.ts.map +1 -0
- package/dist/src/resumable_upload.js +177 -0
- package/dist/src/resumable_upload.js.map +1 -0
- package/dist/src/services/main.d.ts +14 -0
- package/dist/src/services/main.d.ts.map +1 -0
- package/dist/src/services/main.js +18 -0
- package/dist/src/services/main.js.map +1 -0
- package/dist/src/stores/factory.d.ts +12 -4
- package/dist/src/stores/factory.d.ts.map +1 -1
- package/dist/src/stores/factory.js +20 -1
- package/dist/src/stores/factory.js.map +1 -1
- package/dist/src/stores/lucid.d.ts +2 -1
- package/dist/src/stores/lucid.d.ts.map +1 -1
- package/dist/src/stores/lucid.js +42 -7
- package/dist/src/stores/lucid.js.map +1 -1
- package/dist/src/telescope/dashboard.d.ts +19 -0
- package/dist/src/telescope/dashboard.d.ts.map +1 -0
- package/dist/src/telescope/dashboard.js +116 -0
- package/dist/src/telescope/dashboard.js.map +1 -0
- package/dist/src/telescope/data-providers.d.ts +36 -0
- package/dist/src/telescope/data-providers.d.ts.map +1 -0
- package/dist/src/telescope/data-providers.js +286 -0
- package/dist/src/telescope/data-providers.js.map +1 -0
- package/dist/src/telescope/extension.d.ts +26 -0
- package/dist/src/telescope/extension.d.ts.map +1 -0
- package/dist/src/telescope/extension.js +42 -0
- package/dist/src/telescope/extension.js.map +1 -0
- package/dist/src/telescope/index.d.ts +5 -0
- package/dist/src/telescope/index.d.ts.map +1 -0
- package/dist/src/telescope/index.js +4 -0
- package/dist/src/telescope/index.js.map +1 -0
- package/dist/src/telescope/telescope-sdk.d.ts +125 -0
- package/dist/src/telescope/telescope-sdk.d.ts.map +1 -0
- package/dist/src/telescope/telescope-sdk.js +14 -0
- package/dist/src/telescope/telescope-sdk.js.map +1 -0
- package/dist/src/testing/in_memory_disk.d.ts +10 -0
- package/dist/src/testing/in_memory_disk.d.ts.map +1 -1
- package/dist/src/testing/in_memory_disk.js +11 -0
- package/dist/src/testing/in_memory_disk.js.map +1 -1
- package/dist/src/testing/in_memory_media_store.d.ts +2 -1
- package/dist/src/testing/in_memory_media_store.d.ts.map +1 -1
- package/dist/src/testing/in_memory_media_store.js +28 -0
- package/dist/src/testing/in_memory_media_store.js.map +1 -1
- package/dist/src/testing/in_memory_upload_session_store.d.ts +18 -0
- package/dist/src/testing/in_memory_upload_session_store.d.ts.map +1 -0
- package/dist/src/testing/in_memory_upload_session_store.js +40 -0
- package/dist/src/testing/in_memory_upload_session_store.js.map +1 -0
- package/dist/src/testing/index.d.ts +1 -0
- package/dist/src/testing/index.d.ts.map +1 -1
- package/dist/src/testing/index.js +1 -0
- package/dist/src/testing/index.js.map +1 -1
- package/dist/src/tus.d.ts +57 -0
- package/dist/src/tus.d.ts.map +1 -0
- package/dist/src/tus.js +143 -0
- package/dist/src/tus.js.map +1 -0
- package/dist/src/types.d.ts +125 -0
- package/dist/src/types.d.ts.map +1 -1
- package/dist/src/upload_manager.d.ts +127 -0
- package/dist/src/upload_manager.d.ts.map +1 -0
- package/dist/src/upload_manager.js +152 -0
- package/dist/src/upload_manager.js.map +1 -0
- package/dist/src/upload_mode.d.ts +27 -0
- package/dist/src/upload_mode.d.ts.map +1 -0
- package/dist/src/upload_mode.js +22 -0
- package/dist/src/upload_mode.js.map +1 -0
- package/dist/src/upload_sessions/factory.d.ts +62 -0
- package/dist/src/upload_sessions/factory.d.ts.map +1 -0
- package/dist/src/upload_sessions/factory.js +60 -0
- package/dist/src/upload_sessions/factory.js.map +1 -0
- package/dist/src/upload_sessions/lucid.d.ts +35 -0
- package/dist/src/upload_sessions/lucid.d.ts.map +1 -0
- package/dist/src/upload_sessions/lucid.js +105 -0
- package/dist/src/upload_sessions/lucid.js.map +1 -0
- package/dist/stubs/config/media.stub +16 -1
- package/dist/stubs/database/migrations/create_media_upload_sessions_table.stub +45 -0
- package/package.json +37 -1
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A local, structural mirror of the `@adonis-agora/telescope` extension SDK contract.
|
|
3
|
+
*
|
|
4
|
+
* We deliberately do NOT import `@adonis-agora/telescope` — it lives in a separate repo, so a workspace
|
|
5
|
+
* dependency would not resolve, and `@adonis-agora/telescope` is only an OPTIONAL peer (a host may run
|
|
6
|
+
* `@adonis-agora/media` without any observability at all). This is the same cross-repo decoupling
|
|
7
|
+
* `@adonis-agora/telescope` itself uses to read `@adonis-agora/diagnostics` without importing it, and the
|
|
8
|
+
* same pattern `@adonis-agora/durable/telescope` follows. Instead we declare the same shapes here; the
|
|
9
|
+
* exported extension object structurally satisfies `@adonis-agora/telescope`'s `TelescopeExtension` when
|
|
10
|
+
* an app wires it into `config/telescope.ts` (where both packages are installed). Keep these in lockstep
|
|
11
|
+
* with `@adonis-agora/telescope`'s `src/extension/types.ts`.
|
|
12
|
+
*/
|
|
13
|
+
/** The slice of a telescope entry the data providers read. */
|
|
14
|
+
export interface TelescopeEntryLike {
|
|
15
|
+
content?: unknown;
|
|
16
|
+
createdAt?: Date;
|
|
17
|
+
}
|
|
18
|
+
/** The slice of the telescope store the data providers read (a subset of `TelescopeStore`). */
|
|
19
|
+
export interface TelescopeStoreLike {
|
|
20
|
+
list(query?: {
|
|
21
|
+
type?: string;
|
|
22
|
+
tag?: string;
|
|
23
|
+
limit?: number;
|
|
24
|
+
}): Promise<TelescopeEntryLike[]>;
|
|
25
|
+
}
|
|
26
|
+
/** The slice of the AdonisJS container an extension uses to resolve host services. */
|
|
27
|
+
export interface ContainerLike {
|
|
28
|
+
make<T>(token: unknown): Promise<T>;
|
|
29
|
+
}
|
|
30
|
+
/** Read-only context handed to every extension hook (mirror of `@adonis-agora/telescope`'s). */
|
|
31
|
+
export interface ExtensionContext {
|
|
32
|
+
readonly store: TelescopeStoreLike;
|
|
33
|
+
readonly container: ContainerLike;
|
|
34
|
+
readonly config: unknown;
|
|
35
|
+
}
|
|
36
|
+
export interface ExtensionEntryType {
|
|
37
|
+
id: string;
|
|
38
|
+
label: string;
|
|
39
|
+
dot: string;
|
|
40
|
+
}
|
|
41
|
+
export interface PanelThresholds {
|
|
42
|
+
warn: number;
|
|
43
|
+
bad: number;
|
|
44
|
+
direction: 'up-bad' | 'down-bad';
|
|
45
|
+
}
|
|
46
|
+
export interface DashboardSection {
|
|
47
|
+
title?: string;
|
|
48
|
+
cols?: 2 | 3 | 4;
|
|
49
|
+
panels: Panel[];
|
|
50
|
+
}
|
|
51
|
+
export interface DashboardSpec {
|
|
52
|
+
id: string;
|
|
53
|
+
label: string;
|
|
54
|
+
navGroup?: string;
|
|
55
|
+
panels: Panel[];
|
|
56
|
+
sections?: DashboardSection[];
|
|
57
|
+
}
|
|
58
|
+
export interface DataBinding {
|
|
59
|
+
provider: string;
|
|
60
|
+
query?: Record<string, unknown>;
|
|
61
|
+
}
|
|
62
|
+
export interface LinkSpec {
|
|
63
|
+
href: string;
|
|
64
|
+
external?: boolean;
|
|
65
|
+
}
|
|
66
|
+
export interface Column {
|
|
67
|
+
key: string;
|
|
68
|
+
label: string;
|
|
69
|
+
link?: LinkSpec;
|
|
70
|
+
}
|
|
71
|
+
export type Panel = {
|
|
72
|
+
kind: 'stat';
|
|
73
|
+
title: string;
|
|
74
|
+
data: DataBinding;
|
|
75
|
+
format?: 'number' | 'percent' | 'duration' | 'rate';
|
|
76
|
+
accent?: string;
|
|
77
|
+
spark?: boolean;
|
|
78
|
+
thresholds?: PanelThresholds;
|
|
79
|
+
} | {
|
|
80
|
+
kind: 'timeseries';
|
|
81
|
+
title: string;
|
|
82
|
+
data: DataBinding;
|
|
83
|
+
series: string[];
|
|
84
|
+
style?: 'area' | 'stacked';
|
|
85
|
+
} | {
|
|
86
|
+
kind: 'topN';
|
|
87
|
+
title: string;
|
|
88
|
+
data: DataBinding;
|
|
89
|
+
limit?: number;
|
|
90
|
+
} | {
|
|
91
|
+
kind: 'table';
|
|
92
|
+
title: string;
|
|
93
|
+
data: DataBinding;
|
|
94
|
+
columns: Column[];
|
|
95
|
+
} | {
|
|
96
|
+
kind: 'distribution';
|
|
97
|
+
title: string;
|
|
98
|
+
data: DataBinding;
|
|
99
|
+
markers?: Array<'p50' | 'p95' | 'p99'>;
|
|
100
|
+
format?: 'duration' | 'number';
|
|
101
|
+
} | {
|
|
102
|
+
kind: 'gauge';
|
|
103
|
+
title: string;
|
|
104
|
+
data: DataBinding;
|
|
105
|
+
min?: number;
|
|
106
|
+
max?: number;
|
|
107
|
+
format?: 'number' | 'percent' | 'duration' | 'rate';
|
|
108
|
+
thresholds?: PanelThresholds;
|
|
109
|
+
} | {
|
|
110
|
+
kind: 'breakdown';
|
|
111
|
+
title: string;
|
|
112
|
+
data: DataBinding;
|
|
113
|
+
style?: 'donut' | 'bar';
|
|
114
|
+
};
|
|
115
|
+
export interface DataProvider {
|
|
116
|
+
name: string;
|
|
117
|
+
resolve(query: Record<string, unknown> | undefined, ctx: ExtensionContext): Promise<unknown>;
|
|
118
|
+
}
|
|
119
|
+
export interface TelescopeExtension {
|
|
120
|
+
name: string;
|
|
121
|
+
entryTypes?(ctx: ExtensionContext): ExtensionEntryType[];
|
|
122
|
+
dashboards?(ctx: ExtensionContext): DashboardSpec[];
|
|
123
|
+
dataProviders?(ctx: ExtensionContext): DataProvider[];
|
|
124
|
+
}
|
|
125
|
+
//# sourceMappingURL=telescope-sdk.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"telescope-sdk.d.ts","sourceRoot":"","sources":["../../../src/telescope/telescope-sdk.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A local, structural mirror of the `@adonis-agora/telescope` extension SDK contract.
|
|
3
|
+
*
|
|
4
|
+
* We deliberately do NOT import `@adonis-agora/telescope` — it lives in a separate repo, so a workspace
|
|
5
|
+
* dependency would not resolve, and `@adonis-agora/telescope` is only an OPTIONAL peer (a host may run
|
|
6
|
+
* `@adonis-agora/media` without any observability at all). This is the same cross-repo decoupling
|
|
7
|
+
* `@adonis-agora/telescope` itself uses to read `@adonis-agora/diagnostics` without importing it, and the
|
|
8
|
+
* same pattern `@adonis-agora/durable/telescope` follows. Instead we declare the same shapes here; the
|
|
9
|
+
* exported extension object structurally satisfies `@adonis-agora/telescope`'s `TelescopeExtension` when
|
|
10
|
+
* an app wires it into `config/telescope.ts` (where both packages are installed). Keep these in lockstep
|
|
11
|
+
* with `@adonis-agora/telescope`'s `src/extension/types.ts`.
|
|
12
|
+
*/
|
|
13
|
+
export {};
|
|
14
|
+
//# sourceMappingURL=telescope-sdk.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"telescope-sdk.js","sourceRoot":"","sources":["../../../src/telescope/telescope-sdk.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG"}
|
|
@@ -4,6 +4,15 @@ interface StoredFile {
|
|
|
4
4
|
data: Buffer;
|
|
5
5
|
contentType?: string | undefined;
|
|
6
6
|
lastModified: Date;
|
|
7
|
+
/**
|
|
8
|
+
* The `contentLength` the writer declared, recorded verbatim (`undefined` when it declared
|
|
9
|
+
* none, and always `undefined` for `put`, which needs no declaration).
|
|
10
|
+
*
|
|
11
|
+
* It is kept only so tests can assert it. A real S3 disk CANNOT write a stream without it,
|
|
12
|
+
* but this disk has the bytes in hand and never needs it — so silently ignoring it let
|
|
13
|
+
* callers drop the size and still pass every test here, while failing against real S3.
|
|
14
|
+
*/
|
|
15
|
+
contentLength?: number | undefined;
|
|
7
16
|
}
|
|
8
17
|
/**
|
|
9
18
|
* In-memory {@link Disk} satisfying the same structural contract as an `@adonisjs/drive` disk.
|
|
@@ -18,6 +27,7 @@ export declare class InMemoryDisk implements Disk {
|
|
|
18
27
|
/** Used to render `getUrl`/`getSignedUrl`. */
|
|
19
28
|
baseUrl?: string);
|
|
20
29
|
put(key: string, contents: Uint8Array, options?: DiskWriteOptions): Promise<void>;
|
|
30
|
+
putStream(key: string, contents: Readable, options?: DiskWriteOptions): Promise<void>;
|
|
21
31
|
getBytes(key: string): Promise<Uint8Array>;
|
|
22
32
|
getStream(key: string): Promise<Readable>;
|
|
23
33
|
exists(key: string): Promise<boolean>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"in_memory_disk.d.ts","sourceRoot":"","sources":["../../../src/testing/in_memory_disk.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACvC,OAAO,KAAK,EACV,IAAI,EACJ,YAAY,EACZ,YAAY,EACZ,gBAAgB,EAChB,gBAAgB,EACjB,MAAM,aAAa,CAAC;AAErB,UAAU,UAAU;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACjC,YAAY,EAAE,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"in_memory_disk.d.ts","sourceRoot":"","sources":["../../../src/testing/in_memory_disk.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACvC,OAAO,KAAK,EACV,IAAI,EACJ,YAAY,EACZ,YAAY,EACZ,gBAAgB,EAChB,gBAAgB,EACjB,MAAM,aAAa,CAAC;AAErB,UAAU,UAAU;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACjC,YAAY,EAAE,IAAI,CAAC;IACnB;;;;;;;OAOG;IACH,aAAa,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACpC;AAED;;;;GAIG;AACH,qBAAa,YAAa,YAAW,IAAI;IAIrC,8CAA8C;IAC9C,OAAO,CAAC,QAAQ,CAAC,OAAO;IAJ1B,QAAQ,CAAC,KAAK,0BAAiC;;IAG7C,8CAA8C;IAC7B,OAAO,SAAkB;IAGtC,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,UAAU,EAAE,OAAO,CAAC,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC;IAQjF,SAAS,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,OAAO,CAAC,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC;IAWrF,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC;IAK1C,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC;IAIzC,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAIrC,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIlC,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAIpC,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,gBAAgB,GAAG,OAAO,CAAC,MAAM,CAAC;IAKtE,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC;IASrD,OAAO,CAAC,OAAO;CAKhB;AAED;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,GAAE,MAAM,EAAgB,GAAG;IACnE,OAAO,EAAE,YAAY,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;CACrC,CAWA"}
|
|
@@ -19,6 +19,17 @@ export class InMemoryDisk {
|
|
|
19
19
|
lastModified: new Date(),
|
|
20
20
|
});
|
|
21
21
|
}
|
|
22
|
+
async putStream(key, contents, options) {
|
|
23
|
+
const chunks = [];
|
|
24
|
+
for await (const chunk of contents)
|
|
25
|
+
chunks.push(Buffer.from(chunk));
|
|
26
|
+
this.files.set(key, {
|
|
27
|
+
data: Buffer.concat(chunks),
|
|
28
|
+
contentType: options?.contentType,
|
|
29
|
+
lastModified: new Date(),
|
|
30
|
+
contentLength: options?.contentLength,
|
|
31
|
+
});
|
|
32
|
+
}
|
|
22
33
|
async getBytes(key) {
|
|
23
34
|
const file = this.require(key);
|
|
24
35
|
return Buffer.from(file.data);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"in_memory_disk.js","sourceRoot":"","sources":["../../../src/testing/in_memory_disk.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"in_memory_disk.js","sourceRoot":"","sources":["../../../src/testing/in_memory_disk.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import type { MediaRecord } from '../media_record.js';
|
|
2
|
-
import type
|
|
2
|
+
import { type MediaListOptions, type MediaListPage, type MediaStore } from '../media_store.js';
|
|
3
3
|
/** In-memory {@link MediaStore} for tests and scratch apps. */
|
|
4
4
|
export declare class InMemoryMediaStore implements MediaStore {
|
|
5
5
|
private readonly records;
|
|
6
6
|
save(record: MediaRecord): Promise<MediaRecord>;
|
|
7
7
|
find(id: string): Promise<MediaRecord | null>;
|
|
8
8
|
listByOwner(ownerType: string, ownerId: string, collection?: string): Promise<MediaRecord[]>;
|
|
9
|
+
list(options?: MediaListOptions): Promise<MediaListPage>;
|
|
9
10
|
delete(id: string): Promise<void>;
|
|
10
11
|
nextOrder(ownerType: string, ownerId: string, collection: string): Promise<number>;
|
|
11
12
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"in_memory_media_store.d.ts","sourceRoot":"","sources":["../../../src/testing/in_memory_media_store.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"in_memory_media_store.d.ts","sourceRoot":"","sources":["../../../src/testing/in_memory_media_store.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EACL,KAAK,gBAAgB,EACrB,KAAK,aAAa,EAClB,KAAK,UAAU,EAIhB,MAAM,mBAAmB,CAAC;AAE3B,+DAA+D;AAC/D,qBAAa,kBAAmB,YAAW,UAAU;IACnD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAkC;IAEpD,IAAI,CAAC,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,WAAW,CAAC;IAM/C,IAAI,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC;IAK7C,WAAW,CACf,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,EACf,UAAU,CAAC,EAAE,MAAM,GAClB,OAAO,CAAC,WAAW,EAAE,CAAC;IAYnB,IAAI,CAAC,OAAO,GAAE,gBAAqB,GAAG,OAAO,CAAC,aAAa,CAAC;IAwC5D,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIjC,SAAS,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;CAIzF"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { clampMediaListLimit, decodeMediaCursor, encodeMediaCursor, } from '../media_store.js';
|
|
1
2
|
/** In-memory {@link MediaStore} for tests and scratch apps. */
|
|
2
3
|
export class InMemoryMediaStore {
|
|
3
4
|
records = new Map();
|
|
@@ -18,6 +19,33 @@ export class InMemoryMediaStore {
|
|
|
18
19
|
.sort((a, b) => a.order - b.order)
|
|
19
20
|
.map((r) => ({ ...r }));
|
|
20
21
|
}
|
|
22
|
+
async list(options = {}) {
|
|
23
|
+
const limit = clampMediaListLimit(options.limit);
|
|
24
|
+
const ordered = [...this.records.values()]
|
|
25
|
+
.filter((r) => (options.ownerType === undefined || r.ownerType === options.ownerType) &&
|
|
26
|
+
(options.ownerId === undefined || r.ownerId === options.ownerId) &&
|
|
27
|
+
(options.collection === undefined || r.collection === options.collection) &&
|
|
28
|
+
(options.prefix === undefined ||
|
|
29
|
+
options.prefix === '' ||
|
|
30
|
+
r.path.startsWith(options.prefix)))
|
|
31
|
+
// Newest first, tie-broken by id desc — the same stable keyset the Lucid store paginates on.
|
|
32
|
+
.sort((a, b) => b.createdAt.getTime() - a.createdAt.getTime() || (a.id < b.id ? 1 : a.id > b.id ? -1 : 0));
|
|
33
|
+
// Drop everything up to and including the cursor row, per the (createdAt desc, id desc) order.
|
|
34
|
+
const cursor = decodeMediaCursor(options.cursor);
|
|
35
|
+
const after = cursor
|
|
36
|
+
? ordered.filter((r) => r.createdAt.getTime() < cursor.createdAt ||
|
|
37
|
+
(r.createdAt.getTime() === cursor.createdAt && r.id < cursor.id))
|
|
38
|
+
: ordered;
|
|
39
|
+
const page = after.slice(0, limit);
|
|
40
|
+
const hasMore = after.length > limit;
|
|
41
|
+
const last = page[page.length - 1];
|
|
42
|
+
return {
|
|
43
|
+
items: page.map((r) => ({ ...r })),
|
|
44
|
+
nextCursor: hasMore && last
|
|
45
|
+
? encodeMediaCursor({ createdAt: last.createdAt.getTime(), id: last.id })
|
|
46
|
+
: null,
|
|
47
|
+
};
|
|
48
|
+
}
|
|
21
49
|
async delete(id) {
|
|
22
50
|
this.records.delete(id);
|
|
23
51
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"in_memory_media_store.js","sourceRoot":"","sources":["../../../src/testing/in_memory_media_store.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"in_memory_media_store.js","sourceRoot":"","sources":["../../../src/testing/in_memory_media_store.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { UploadSession, UploadSessionListFilter, UploadSessionStore } from '../resumable_upload.js';
|
|
2
|
+
import type { MultipartPart } from '../types.js';
|
|
3
|
+
/**
|
|
4
|
+
* In-memory {@link UploadSessionStore} for tests and single-process scratch apps. Non-durable —
|
|
5
|
+
* sessions vanish on restart. Returns defensive copies so mutating a result never mutates the store.
|
|
6
|
+
*/
|
|
7
|
+
export declare class InMemoryUploadSessionStore implements UploadSessionStore {
|
|
8
|
+
private readonly sessions;
|
|
9
|
+
private readonly parts;
|
|
10
|
+
create(session: UploadSession): Promise<UploadSession>;
|
|
11
|
+
get(id: string): Promise<UploadSession | null>;
|
|
12
|
+
update(session: UploadSession): Promise<UploadSession>;
|
|
13
|
+
delete(id: string): Promise<void>;
|
|
14
|
+
addPart(id: string, part: MultipartPart): Promise<void>;
|
|
15
|
+
listParts(id: string): Promise<MultipartPart[]>;
|
|
16
|
+
list(filter?: UploadSessionListFilter): Promise<UploadSession[]>;
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=in_memory_upload_session_store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"in_memory_upload_session_store.d.ts","sourceRoot":"","sources":["../../../src/testing/in_memory_upload_session_store.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,aAAa,EACb,uBAAuB,EACvB,kBAAkB,EACnB,MAAM,wBAAwB,CAAC;AAChC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAEjD;;;GAGG;AACH,qBAAa,0BAA2B,YAAW,kBAAkB;IACnE,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAoC;IAC7D,OAAO,CAAC,QAAQ,CAAC,KAAK,CAA0C;IAE1D,MAAM,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,aAAa,CAAC;IAMtD,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC;IAK9C,MAAM,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,aAAa,CAAC;IAKtD,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAKjC,OAAO,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC;IAMvD,SAAS,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC;IAM/C,IAAI,CAAC,MAAM,GAAE,uBAA4B,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC;CAS3E"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* In-memory {@link UploadSessionStore} for tests and single-process scratch apps. Non-durable —
|
|
3
|
+
* sessions vanish on restart. Returns defensive copies so mutating a result never mutates the store.
|
|
4
|
+
*/
|
|
5
|
+
export class InMemoryUploadSessionStore {
|
|
6
|
+
sessions = new Map();
|
|
7
|
+
parts = new Map();
|
|
8
|
+
async create(session) {
|
|
9
|
+
const stored = { ...session, createdAt: session.createdAt ?? new Date() };
|
|
10
|
+
this.sessions.set(stored.id, { ...stored });
|
|
11
|
+
return { ...stored };
|
|
12
|
+
}
|
|
13
|
+
async get(id) {
|
|
14
|
+
const found = this.sessions.get(id);
|
|
15
|
+
return found ? { ...found } : null;
|
|
16
|
+
}
|
|
17
|
+
async update(session) {
|
|
18
|
+
this.sessions.set(session.id, { ...session });
|
|
19
|
+
return { ...session };
|
|
20
|
+
}
|
|
21
|
+
async delete(id) {
|
|
22
|
+
this.sessions.delete(id);
|
|
23
|
+
this.parts.delete(id);
|
|
24
|
+
}
|
|
25
|
+
async addPart(id, part) {
|
|
26
|
+
const existing = this.parts.get(id) ?? new Map();
|
|
27
|
+
existing.set(part.partNumber, part.etag);
|
|
28
|
+
this.parts.set(id, existing);
|
|
29
|
+
}
|
|
30
|
+
async listParts(id) {
|
|
31
|
+
return [...(this.parts.get(id) ?? new Map()).entries()].map(([partNumber, etag]) => ({ partNumber, etag }));
|
|
32
|
+
}
|
|
33
|
+
async list(filter = {}) {
|
|
34
|
+
return [...this.sessions.values()]
|
|
35
|
+
.filter((session) => (filter.disk === undefined || session.disk === filter.disk) &&
|
|
36
|
+
(filter.keyPrefix === undefined || session.key.startsWith(filter.keyPrefix)))
|
|
37
|
+
.map((session) => ({ ...session }));
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=in_memory_upload_session_store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"in_memory_upload_session_store.js","sourceRoot":"","sources":["../../../src/testing/in_memory_upload_session_store.ts"],"names":[],"mappings":"AAOA;;;GAGG;AACH,MAAM,OAAO,0BAA0B;IACpB,QAAQ,GAAG,IAAI,GAAG,EAAyB,CAAC;IAC5C,KAAK,GAAG,IAAI,GAAG,EAA+B,CAAC;IAEhE,KAAK,CAAC,MAAM,CAAC,OAAsB;QACjC,MAAM,MAAM,GAAkB,EAAE,GAAG,OAAO,EAAE,SAAS,EAAE,OAAO,CAAC,SAAS,IAAI,IAAI,IAAI,EAAE,EAAE,CAAC;QACzF,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,EAAE,EAAE,GAAG,MAAM,EAAE,CAAC,CAAC;QAC5C,OAAO,EAAE,GAAG,MAAM,EAAE,CAAC;IACvB,CAAC;IAED,KAAK,CAAC,GAAG,CAAC,EAAU;QAClB,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACpC,OAAO,KAAK,CAAC,CAAC,CAAC,EAAE,GAAG,KAAK,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;IACrC,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,OAAsB;QACjC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,EAAE,EAAE,GAAG,OAAO,EAAE,CAAC,CAAC;QAC9C,OAAO,EAAE,GAAG,OAAO,EAAE,CAAC;IACxB,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,EAAU;QACrB,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QACzB,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;IACxB,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,EAAU,EAAE,IAAmB;QAC3C,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,IAAI,GAAG,EAAkB,CAAC;QACjE,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;QACzC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,EAAE,QAAQ,CAAC,CAAC;IAC/B,CAAC;IAED,KAAK,CAAC,SAAS,CAAC,EAAU;QACxB,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,IAAI,GAAG,EAAkB,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,GAAG,CACzE,CAAC,CAAC,UAAU,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC,CAC/C,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,SAAkC,EAAE;QAC7C,OAAO,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC;aAC/B,MAAM,CACL,CAAC,OAAO,EAAE,EAAE,CACV,CAAC,MAAM,CAAC,IAAI,KAAK,SAAS,IAAI,OAAO,CAAC,IAAI,KAAK,MAAM,CAAC,IAAI,CAAC;YAC3D,CAAC,MAAM,CAAC,SAAS,KAAK,SAAS,IAAI,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAC/E;aACA,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,OAAO,EAAE,CAAC,CAAC,CAAC;IACxC,CAAC;CACF"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export { InMemoryMediaStore } from './in_memory_media_store.js';
|
|
2
|
+
export { InMemoryUploadSessionStore } from './in_memory_upload_session_store.js';
|
|
2
3
|
export { InMemoryDisk, inMemoryDiskResolver } from './in_memory_disk.js';
|
|
3
4
|
export { FakeImageProcessor } from './fake_image_processor.js';
|
|
4
5
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/testing/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAChE,OAAO,EAAE,YAAY,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AACzE,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/testing/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAChE,OAAO,EAAE,0BAA0B,EAAE,MAAM,qCAAqC,CAAC;AACjF,OAAO,EAAE,YAAY,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AACzE,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export { InMemoryMediaStore } from './in_memory_media_store.js';
|
|
2
|
+
export { InMemoryUploadSessionStore } from './in_memory_upload_session_store.js';
|
|
2
3
|
export { InMemoryDisk, inMemoryDiskResolver } from './in_memory_disk.js';
|
|
3
4
|
export { FakeImageProcessor } from './fake_image_processor.js';
|
|
4
5
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/testing/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAChE,OAAO,EAAE,YAAY,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AACzE,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/testing/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAChE,OAAO,EAAE,0BAA0B,EAAE,MAAM,qCAAqC,CAAC;AACjF,OAAO,EAAE,YAAY,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AACzE,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import type { ResumableUploadManager } from './resumable_upload.js';
|
|
2
|
+
/** The TUS protocol version this server implements. */
|
|
3
|
+
export declare const TUS_VERSION = "1.0.0";
|
|
4
|
+
/** A web-framework-neutral TUS request (the provider maps an AdonisJS `HttpContext` to this). */
|
|
5
|
+
export interface TusRequest {
|
|
6
|
+
method: 'OPTIONS' | 'POST' | 'HEAD' | 'PATCH' | 'DELETE';
|
|
7
|
+
/** Upload id parsed from the URL (for HEAD/PATCH/DELETE). */
|
|
8
|
+
uploadId?: string;
|
|
9
|
+
headers: Record<string, string | undefined>;
|
|
10
|
+
body?: Uint8Array;
|
|
11
|
+
}
|
|
12
|
+
/** A web-framework-neutral TUS response (the provider writes it back onto the `HttpContext`). */
|
|
13
|
+
export interface TusResponse {
|
|
14
|
+
status: number;
|
|
15
|
+
headers: Record<string, string>;
|
|
16
|
+
body?: string;
|
|
17
|
+
}
|
|
18
|
+
export interface TusUploadHandlerOptions {
|
|
19
|
+
manager: ResumableUploadManager;
|
|
20
|
+
/** Disk uploads land on. */
|
|
21
|
+
disk: string;
|
|
22
|
+
/** Base path the upload resources are exposed at, for the `Location` header. Default `/uploads`. */
|
|
23
|
+
basePath?: string;
|
|
24
|
+
/** Reject creations whose `Upload-Length` exceeds this. */
|
|
25
|
+
maxSize?: number;
|
|
26
|
+
/** Compute the final object key. Default: `uploads/<token>/<filename>`. */
|
|
27
|
+
keyFor?: (filename: string, token: string, metadata: Record<string, string>) => string;
|
|
28
|
+
idGenerator?: () => string;
|
|
29
|
+
}
|
|
30
|
+
/** Parse a TUS `Upload-Metadata` header (`key b64val,key2 b64val2`). */
|
|
31
|
+
export declare function parseTusMetadata(header?: string): Record<string, string>;
|
|
32
|
+
/**
|
|
33
|
+
* TUS 1.0.0 server core (`creation` + `termination` + `expiration` extensions), delegating storage
|
|
34
|
+
* to a {@link ResumableUploadManager}. It is framework-agnostic: a thin AdonisJS route adapter maps
|
|
35
|
+
* the `HttpContext` request/response to/from {@link TusRequest}/{@link TusResponse}.
|
|
36
|
+
*
|
|
37
|
+
* Protocol surface:
|
|
38
|
+
* - `OPTIONS` — advertise `Tus-Version`/`Tus-Extension`/`Tus-Max-Size`.
|
|
39
|
+
* - `POST` — create with `Upload-Length` + `Upload-Metadata`; returns `201` + `Location`.
|
|
40
|
+
* - `HEAD` — report `Upload-Offset` (+ `Upload-Length`/`Upload-Expires`).
|
|
41
|
+
* - `PATCH` — append at `Upload-Offset` with `Content-Type: application/offset+octet-stream`;
|
|
42
|
+
* auto-completes at the declared length.
|
|
43
|
+
* - `DELETE` — terminate (abort) an in-flight upload.
|
|
44
|
+
*/
|
|
45
|
+
export declare class TusUploadHandler {
|
|
46
|
+
private readonly manager;
|
|
47
|
+
private readonly disk;
|
|
48
|
+
private readonly basePath;
|
|
49
|
+
private readonly maxSize;
|
|
50
|
+
private readonly keyFor;
|
|
51
|
+
private readonly newId;
|
|
52
|
+
constructor(options: TusUploadHandlerOptions);
|
|
53
|
+
handle(req: TusRequest): Promise<TusResponse>;
|
|
54
|
+
/** Map storage errors onto TUS status codes (409 conflict, 410 expired, 404 unknown). */
|
|
55
|
+
private mapError;
|
|
56
|
+
}
|
|
57
|
+
//# sourceMappingURL=tus.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tus.d.ts","sourceRoot":"","sources":["../../src/tus.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAqB,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AAEvF,uDAAuD;AACvD,eAAO,MAAM,WAAW,UAAU,CAAC;AAEnC,iGAAiG;AACjG,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,SAAS,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,QAAQ,CAAC;IACzD,6DAA6D;IAC7D,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;IAC5C,IAAI,CAAC,EAAE,UAAU,CAAC;CACnB;AAED,iGAAiG;AACjG,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,uBAAuB;IACtC,OAAO,EAAE,sBAAsB,CAAC;IAChC,4BAA4B;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,oGAAoG;IACpG,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,2DAA2D;IAC3D,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,2EAA2E;IAC3E,MAAM,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,KAAK,MAAM,CAAC;IACvF,WAAW,CAAC,EAAE,MAAM,MAAM,CAAC;CAC5B;AAED,wEAAwE;AACxE,wBAAgB,gBAAgB,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAQxE;AAED;;;;;;;;;;;;GAYG;AACH,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAyB;IACjD,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAS;IAC9B,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAqB;IAC7C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA8D;IACrF,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAe;gBAEzB,OAAO,EAAE,uBAAuB;IAStC,MAAM,CAAC,GAAG,EAAE,UAAU,GAAG,OAAO,CAAC,WAAW,CAAC;IA0FnD,yFAAyF;IACzF,OAAO,CAAC,QAAQ;CAMjB"}
|
package/dist/src/tus.js
ADDED
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
import { randomUUID } from 'node:crypto';
|
|
2
|
+
import { UploadOffsetConflictError, UploadSessionExpiredError, UploadSessionNotFoundError, } from './errors.js';
|
|
3
|
+
/** The TUS protocol version this server implements. */
|
|
4
|
+
export const TUS_VERSION = '1.0.0';
|
|
5
|
+
/** Parse a TUS `Upload-Metadata` header (`key b64val,key2 b64val2`). */
|
|
6
|
+
export function parseTusMetadata(header) {
|
|
7
|
+
const out = {};
|
|
8
|
+
if (!header)
|
|
9
|
+
return out;
|
|
10
|
+
for (const pair of header.split(',')) {
|
|
11
|
+
const [key, value] = pair.trim().split(' ');
|
|
12
|
+
if (key)
|
|
13
|
+
out[key] = value ? Buffer.from(value, 'base64').toString('utf8') : '';
|
|
14
|
+
}
|
|
15
|
+
return out;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* TUS 1.0.0 server core (`creation` + `termination` + `expiration` extensions), delegating storage
|
|
19
|
+
* to a {@link ResumableUploadManager}. It is framework-agnostic: a thin AdonisJS route adapter maps
|
|
20
|
+
* the `HttpContext` request/response to/from {@link TusRequest}/{@link TusResponse}.
|
|
21
|
+
*
|
|
22
|
+
* Protocol surface:
|
|
23
|
+
* - `OPTIONS` — advertise `Tus-Version`/`Tus-Extension`/`Tus-Max-Size`.
|
|
24
|
+
* - `POST` — create with `Upload-Length` + `Upload-Metadata`; returns `201` + `Location`.
|
|
25
|
+
* - `HEAD` — report `Upload-Offset` (+ `Upload-Length`/`Upload-Expires`).
|
|
26
|
+
* - `PATCH` — append at `Upload-Offset` with `Content-Type: application/offset+octet-stream`;
|
|
27
|
+
* auto-completes at the declared length.
|
|
28
|
+
* - `DELETE` — terminate (abort) an in-flight upload.
|
|
29
|
+
*/
|
|
30
|
+
export class TusUploadHandler {
|
|
31
|
+
manager;
|
|
32
|
+
disk;
|
|
33
|
+
basePath;
|
|
34
|
+
maxSize;
|
|
35
|
+
keyFor;
|
|
36
|
+
newId;
|
|
37
|
+
constructor(options) {
|
|
38
|
+
this.manager = options.manager;
|
|
39
|
+
this.disk = options.disk;
|
|
40
|
+
this.basePath = (options.basePath ?? '/uploads').replace(/\/+$/, '');
|
|
41
|
+
this.maxSize = options.maxSize;
|
|
42
|
+
this.keyFor = options.keyFor ?? ((filename, token) => `uploads/${token}/${filename}`);
|
|
43
|
+
this.newId = options.idGenerator ?? (() => randomUUID());
|
|
44
|
+
}
|
|
45
|
+
async handle(req) {
|
|
46
|
+
const base = { 'Tus-Resumable': TUS_VERSION };
|
|
47
|
+
switch (req.method) {
|
|
48
|
+
case 'OPTIONS':
|
|
49
|
+
return {
|
|
50
|
+
status: 204,
|
|
51
|
+
headers: {
|
|
52
|
+
...base,
|
|
53
|
+
'Tus-Version': TUS_VERSION,
|
|
54
|
+
'Tus-Extension': 'creation,termination,expiration',
|
|
55
|
+
...(this.maxSize ? { 'Tus-Max-Size': String(this.maxSize) } : {}),
|
|
56
|
+
},
|
|
57
|
+
};
|
|
58
|
+
case 'POST': {
|
|
59
|
+
const length = Number(req.headers['upload-length']);
|
|
60
|
+
if (this.maxSize && Number.isFinite(length) && length > this.maxSize) {
|
|
61
|
+
return { status: 413, headers: base, body: 'Upload exceeds maximum size' };
|
|
62
|
+
}
|
|
63
|
+
const metadata = parseTusMetadata(req.headers['upload-metadata']);
|
|
64
|
+
const filename = metadata.filename ?? 'upload';
|
|
65
|
+
const token = this.newId();
|
|
66
|
+
const input = {
|
|
67
|
+
disk: this.disk,
|
|
68
|
+
key: this.keyFor(filename, token, metadata),
|
|
69
|
+
metadata,
|
|
70
|
+
};
|
|
71
|
+
if (Number.isFinite(length))
|
|
72
|
+
input.size = length;
|
|
73
|
+
if (metadata.filetype)
|
|
74
|
+
input.contentType = metadata.filetype;
|
|
75
|
+
const session = await this.manager.createUpload(input);
|
|
76
|
+
const headers = {
|
|
77
|
+
...base,
|
|
78
|
+
Location: `${this.basePath}/${session.id}`,
|
|
79
|
+
'Upload-Offset': '0',
|
|
80
|
+
};
|
|
81
|
+
if (session.expiresAt)
|
|
82
|
+
headers['Upload-Expires'] = session.expiresAt.toUTCString();
|
|
83
|
+
return { status: 201, headers };
|
|
84
|
+
}
|
|
85
|
+
case 'HEAD': {
|
|
86
|
+
try {
|
|
87
|
+
const status = await this.manager.status(req.uploadId ?? '');
|
|
88
|
+
const headers = {
|
|
89
|
+
...base,
|
|
90
|
+
'Upload-Offset': String(status.offset),
|
|
91
|
+
'Cache-Control': 'no-store',
|
|
92
|
+
...(status.size != null ? { 'Upload-Length': String(status.size) } : {}),
|
|
93
|
+
};
|
|
94
|
+
if (status.expiresAt)
|
|
95
|
+
headers['Upload-Expires'] = status.expiresAt.toUTCString();
|
|
96
|
+
return { status: 200, headers };
|
|
97
|
+
}
|
|
98
|
+
catch (err) {
|
|
99
|
+
return this.mapError(err, base);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
case 'PATCH': {
|
|
103
|
+
if (req.headers['content-type'] !== 'application/offset+octet-stream') {
|
|
104
|
+
return { status: 415, headers: base, body: 'Unsupported Media Type' };
|
|
105
|
+
}
|
|
106
|
+
const offset = Number(req.headers['upload-offset']);
|
|
107
|
+
try {
|
|
108
|
+
const result = await this.manager.writeChunk(req.uploadId ?? '', offset, req.body ?? new Uint8Array());
|
|
109
|
+
const status = await this.manager.status(req.uploadId ?? '');
|
|
110
|
+
if (status.size != null && result.offset >= status.size) {
|
|
111
|
+
await this.manager.complete(req.uploadId ?? '');
|
|
112
|
+
}
|
|
113
|
+
const headers = {
|
|
114
|
+
...base,
|
|
115
|
+
'Upload-Offset': String(result.offset),
|
|
116
|
+
};
|
|
117
|
+
if (status.expiresAt)
|
|
118
|
+
headers['Upload-Expires'] = status.expiresAt.toUTCString();
|
|
119
|
+
return { status: 204, headers };
|
|
120
|
+
}
|
|
121
|
+
catch (err) {
|
|
122
|
+
return this.mapError(err, base);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
case 'DELETE':
|
|
126
|
+
await this.manager.abort(req.uploadId ?? '');
|
|
127
|
+
return { status: 204, headers: base };
|
|
128
|
+
default:
|
|
129
|
+
return { status: 405, headers: base };
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
/** Map storage errors onto TUS status codes (409 conflict, 410 expired, 404 unknown). */
|
|
133
|
+
mapError(err, base) {
|
|
134
|
+
if (err instanceof UploadOffsetConflictError)
|
|
135
|
+
return { status: 409, headers: base };
|
|
136
|
+
if (err instanceof UploadSessionExpiredError)
|
|
137
|
+
return { status: 410, headers: base };
|
|
138
|
+
if (err instanceof UploadSessionNotFoundError)
|
|
139
|
+
return { status: 404, headers: base };
|
|
140
|
+
throw err;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
//# sourceMappingURL=tus.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tus.js","sourceRoot":"","sources":["../../src/tus.ts"],"names":[],"mappings":"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"}
|