@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.
Files changed (137) hide show
  1. package/CHANGELOG.md +87 -0
  2. package/dist/configure.d.ts +2 -2
  3. package/dist/configure.d.ts.map +1 -1
  4. package/dist/configure.js +3 -2
  5. package/dist/configure.js.map +1 -1
  6. package/dist/providers/media_provider.d.ts +15 -0
  7. package/dist/providers/media_provider.d.ts.map +1 -1
  8. package/dist/providers/media_provider.js +224 -12
  9. package/dist/providers/media_provider.js.map +1 -1
  10. package/dist/src/attachment.d.ts +1 -0
  11. package/dist/src/attachment.d.ts.map +1 -1
  12. package/dist/src/attachment.js +57 -21
  13. package/dist/src/attachment.js.map +1 -1
  14. package/dist/src/define_config.d.ts +83 -5
  15. package/dist/src/define_config.d.ts.map +1 -1
  16. package/dist/src/define_config.js +3 -1
  17. package/dist/src/define_config.js.map +1 -1
  18. package/dist/src/diagnostics.d.ts +32 -1
  19. package/dist/src/diagnostics.d.ts.map +1 -1
  20. package/dist/src/diagnostics.js.map +1 -1
  21. package/dist/src/disks/factory.d.ts +62 -0
  22. package/dist/src/disks/factory.d.ts.map +1 -0
  23. package/dist/src/disks/factory.js +57 -0
  24. package/dist/src/disks/factory.js.map +1 -0
  25. package/dist/src/disks/s3.d.ts +76 -0
  26. package/dist/src/disks/s3.d.ts.map +1 -0
  27. package/dist/src/disks/s3.js +357 -0
  28. package/dist/src/disks/s3.js.map +1 -0
  29. package/dist/src/disks/xml_fallback.d.ts +29 -0
  30. package/dist/src/disks/xml_fallback.d.ts.map +1 -0
  31. package/dist/src/disks/xml_fallback.js +68 -0
  32. package/dist/src/disks/xml_fallback.js.map +1 -0
  33. package/dist/src/errors.d.ts +34 -0
  34. package/dist/src/errors.d.ts.map +1 -1
  35. package/dist/src/errors.js +60 -0
  36. package/dist/src/errors.js.map +1 -1
  37. package/dist/src/extended_disk.d.ts +10 -0
  38. package/dist/src/extended_disk.d.ts.map +1 -0
  39. package/dist/src/extended_disk.js +19 -0
  40. package/dist/src/extended_disk.js.map +1 -0
  41. package/dist/src/index.d.ts +17 -7
  42. package/dist/src/index.d.ts.map +1 -1
  43. package/dist/src/index.js +11 -4
  44. package/dist/src/index.js.map +1 -1
  45. package/dist/src/media_library.d.ts +4 -2
  46. package/dist/src/media_library.d.ts.map +1 -1
  47. package/dist/src/media_library.js +83 -32
  48. package/dist/src/media_library.js.map +1 -1
  49. package/dist/src/media_manager.d.ts +48 -0
  50. package/dist/src/media_manager.d.ts.map +1 -1
  51. package/dist/src/media_manager.js +68 -0
  52. package/dist/src/media_manager.js.map +1 -1
  53. package/dist/src/media_store.d.ts +40 -0
  54. package/dist/src/media_store.d.ts.map +1 -1
  55. package/dist/src/media_store.js +28 -1
  56. package/dist/src/media_store.js.map +1 -1
  57. package/dist/src/multipart.d.ts +10 -0
  58. package/dist/src/multipart.d.ts.map +1 -0
  59. package/dist/src/multipart.js +16 -0
  60. package/dist/src/multipart.js.map +1 -0
  61. package/dist/src/resumable_upload.d.ts +131 -0
  62. package/dist/src/resumable_upload.d.ts.map +1 -0
  63. package/dist/src/resumable_upload.js +177 -0
  64. package/dist/src/resumable_upload.js.map +1 -0
  65. package/dist/src/services/main.d.ts +14 -0
  66. package/dist/src/services/main.d.ts.map +1 -0
  67. package/dist/src/services/main.js +18 -0
  68. package/dist/src/services/main.js.map +1 -0
  69. package/dist/src/stores/factory.d.ts +12 -4
  70. package/dist/src/stores/factory.d.ts.map +1 -1
  71. package/dist/src/stores/factory.js +20 -1
  72. package/dist/src/stores/factory.js.map +1 -1
  73. package/dist/src/stores/lucid.d.ts +2 -1
  74. package/dist/src/stores/lucid.d.ts.map +1 -1
  75. package/dist/src/stores/lucid.js +42 -7
  76. package/dist/src/stores/lucid.js.map +1 -1
  77. package/dist/src/telescope/dashboard.d.ts +19 -0
  78. package/dist/src/telescope/dashboard.d.ts.map +1 -0
  79. package/dist/src/telescope/dashboard.js +116 -0
  80. package/dist/src/telescope/dashboard.js.map +1 -0
  81. package/dist/src/telescope/data-providers.d.ts +36 -0
  82. package/dist/src/telescope/data-providers.d.ts.map +1 -0
  83. package/dist/src/telescope/data-providers.js +286 -0
  84. package/dist/src/telescope/data-providers.js.map +1 -0
  85. package/dist/src/telescope/extension.d.ts +26 -0
  86. package/dist/src/telescope/extension.d.ts.map +1 -0
  87. package/dist/src/telescope/extension.js +42 -0
  88. package/dist/src/telescope/extension.js.map +1 -0
  89. package/dist/src/telescope/index.d.ts +5 -0
  90. package/dist/src/telescope/index.d.ts.map +1 -0
  91. package/dist/src/telescope/index.js +4 -0
  92. package/dist/src/telescope/index.js.map +1 -0
  93. package/dist/src/telescope/telescope-sdk.d.ts +125 -0
  94. package/dist/src/telescope/telescope-sdk.d.ts.map +1 -0
  95. package/dist/src/telescope/telescope-sdk.js +14 -0
  96. package/dist/src/telescope/telescope-sdk.js.map +1 -0
  97. package/dist/src/testing/in_memory_disk.d.ts +10 -0
  98. package/dist/src/testing/in_memory_disk.d.ts.map +1 -1
  99. package/dist/src/testing/in_memory_disk.js +11 -0
  100. package/dist/src/testing/in_memory_disk.js.map +1 -1
  101. package/dist/src/testing/in_memory_media_store.d.ts +2 -1
  102. package/dist/src/testing/in_memory_media_store.d.ts.map +1 -1
  103. package/dist/src/testing/in_memory_media_store.js +28 -0
  104. package/dist/src/testing/in_memory_media_store.js.map +1 -1
  105. package/dist/src/testing/in_memory_upload_session_store.d.ts +18 -0
  106. package/dist/src/testing/in_memory_upload_session_store.d.ts.map +1 -0
  107. package/dist/src/testing/in_memory_upload_session_store.js +40 -0
  108. package/dist/src/testing/in_memory_upload_session_store.js.map +1 -0
  109. package/dist/src/testing/index.d.ts +1 -0
  110. package/dist/src/testing/index.d.ts.map +1 -1
  111. package/dist/src/testing/index.js +1 -0
  112. package/dist/src/testing/index.js.map +1 -1
  113. package/dist/src/tus.d.ts +57 -0
  114. package/dist/src/tus.d.ts.map +1 -0
  115. package/dist/src/tus.js +143 -0
  116. package/dist/src/tus.js.map +1 -0
  117. package/dist/src/types.d.ts +125 -0
  118. package/dist/src/types.d.ts.map +1 -1
  119. package/dist/src/upload_manager.d.ts +127 -0
  120. package/dist/src/upload_manager.d.ts.map +1 -0
  121. package/dist/src/upload_manager.js +152 -0
  122. package/dist/src/upload_manager.js.map +1 -0
  123. package/dist/src/upload_mode.d.ts +27 -0
  124. package/dist/src/upload_mode.d.ts.map +1 -0
  125. package/dist/src/upload_mode.js +22 -0
  126. package/dist/src/upload_mode.js.map +1 -0
  127. package/dist/src/upload_sessions/factory.d.ts +62 -0
  128. package/dist/src/upload_sessions/factory.d.ts.map +1 -0
  129. package/dist/src/upload_sessions/factory.js +60 -0
  130. package/dist/src/upload_sessions/factory.js.map +1 -0
  131. package/dist/src/upload_sessions/lucid.d.ts +35 -0
  132. package/dist/src/upload_sessions/lucid.d.ts.map +1 -0
  133. package/dist/src/upload_sessions/lucid.js +105 -0
  134. package/dist/src/upload_sessions/lucid.js.map +1 -0
  135. package/dist/stubs/config/media.stub +16 -1
  136. package/dist/stubs/database/migrations/create_media_upload_sessions_table.stub +45 -0
  137. package/package.json +37 -1
package/CHANGELOG.md ADDED
@@ -0,0 +1,87 @@
1
+ # @adonis-agora/media
2
+
3
+ ## 0.2.1
4
+
5
+ ### Patch Changes
6
+
7
+ - [`00b6ed9`](https://github.com/DavideCarvalho/adonis-media/commit/00b6ed976c5afb43c93f91be939611b8a371914a) Thanks [@DavideCarvalho](https://github.com/DavideCarvalho)! - Fix: streaming a file to an S3 disk always failed
8
+
9
+ The streaming fast-path (a `Readable` with a known size and no conversions, added in 0.2.0)
10
+ never worked against real S3 — every write threw:
11
+
12
+ ```
13
+ Invalid value "undefined" for header "x-amz-decoded-content-length"
14
+ ```
15
+
16
+ S3 cannot size a stream, so it needs `ContentLength` up front, and `S3Disk.putStream` never
17
+ sent it. `MediaLibrary.attach` and `AttachmentManager.createFromFile` made it worse: both
18
+ _gate_ the fast-path on `input.size` being known and then dropped that size instead of
19
+ passing it to the disk. So the one path that had the size threw it away, and the buffered
20
+ path (which doesn't need it) is the only one that worked.
21
+
22
+ `DiskWriteOptions` gains `contentLength`; both call sites forward the size that made them
23
+ eligible; `S3Disk.putStream` sends it as `ContentLength` and throws a named error up front
24
+ when it is missing, instead of failing deep inside the AWS SDK's header layer.
25
+
26
+ If you implement a custom `Disk`, `putStream` now receives `contentLength` in its options.
27
+ Ignoring it stays valid for disks that can size their own payload.
28
+
29
+ Why the tests missed it: `s3_disk.spec.ts` asserted with `aws-sdk-client-mock`, which
30
+ intercepts the command _before_ the SDK's header middleware runs, so the mocked call
31
+ happily accepted a payload the real SDK rejects. The library/attachment tests use the
32
+ in-memory disk, which holds the bytes and never needs the declaration. Both now assert the
33
+ size reaches the disk, and the in-memory disk records the `contentLength` it was handed —
34
+ but the bug was only ever visible against a live S3/MinIO.
35
+
36
+ ## 0.2.0
37
+
38
+ ### Minor Changes
39
+
40
+ - [`803e1b7`](https://github.com/DavideCarvalho/adonis-media/commit/803e1b719fefd47349518e32900a72c56927add8) Thanks [@DavideCarvalho](https://github.com/DavideCarvalho)! - S3 disk, direct/resumable uploads, cross-owner listing, Telescope, and fail-fast store resolution
41
+
42
+ **Storage**
43
+
44
+ - `disks.s3({ bucket, region?, credentials?, endpoint?, forcePathStyle?, keyPrefix?, publicBaseUrl? })`
45
+ — an S3 disk with the extended operations the library needs. The AWS SDK is an
46
+ optional peer, imported lazily only when this disk is selected. `endpoint` +
47
+ `forcePathStyle` make it work against MinIO and R2, not just AWS.
48
+ - `services/main` — an idiomatic singleton import (`import media from
49
+ '@adonis-agora/media/services/main'`).
50
+
51
+ **Uploads**
52
+
53
+ - Direct-to-S3 multipart, in `proxy` and `direct` modes, via
54
+ `uploads: { mode, partSize, presignTtlSeconds }` and the
55
+ `initiateDirectUpload` / `completeDirectUpload` / `abortDirectUpload` / `proxyUpload`
56
+ methods on the manager.
57
+ - Resumable uploads over the TUS protocol (`uploads.resumable`), with an in-memory or
58
+ Lucid session store (`upload_sessions/lucid`).
59
+ - Built-in routes for both are **opt-in** (`routes.enabled`, default `false`) and take the
60
+ object key from the request. They are a development convenience: in a real app leave them
61
+ off and mount your own routes over the manager methods, resolving the key server-side per
62
+ user/tenant so a client cannot point an upload at someone else's object.
63
+
64
+ **Reads**
65
+
66
+ - `media.store.list(options)` — cursor-paginated cross-owner listing (newest first,
67
+ default page 50, max 200), for admin/collection views. Owner-scoped reads stay on
68
+ `media.library`.
69
+ - `./telescope` — a Telescope watcher extension (optional peer).
70
+
71
+ **Robustness** — these change behavior:
72
+
73
+ - Naming a `store` that has no matching factory now **throws** `StoreNotConfiguredError`
74
+ instead of silently falling back to the in-memory store. The old fallback looked fine and
75
+ then lost every record on restart. Only the zero-config path (no `store` at all) still
76
+ resolves to memory.
77
+ - The Lucid store writes via an atomic `insert().onConflict('id').merge()` upsert instead of
78
+ read-then-branch.
79
+ - `ownerId` accepts `string | number` on `attach`/`list`, coerced internally — no more
80
+ `String(post.id)` at the call site.
81
+ - A failed store write now best-effort deletes the object it just wrote, instead of leaving
82
+ an orphan on the disk. Single-file collections delete the previous media only _after_ the
83
+ new record commits, so a failed write keeps the old file.
84
+ - A `Readable` with a known `size` and no conversions streams through `putStream` rather than
85
+ buffering the whole file in memory.
86
+ - Typed `VariantNotFoundError` / `StoreNotConfiguredError` replace bare `Error`s.
87
+ - Dropped the internal `publishMedia` export and the empty `MemoryStoreConfig` type.
@@ -4,8 +4,8 @@ import type Configure from '@adonisjs/core/commands/configure';
4
4
  *
5
5
  * 1. registers the media service provider in `adonisrc.ts`;
6
6
  * 2. publishes `config/media.ts`;
7
- * 3. publishes the Lucid migration for the optional `lucid` store (run
8
- * `node ace migration:run`; delete it if you only use the in-memory store).
7
+ * 3. publishes the Lucid migrations for the optional `lucid` store and the resumable (TUS) session
8
+ * store (run `node ace migration:run`; delete either if you only use the in-memory equivalents).
9
9
  *
10
10
  * Requires `@adonisjs/drive` to be installed and configured first (`node ace add @adonisjs/drive`).
11
11
  */
@@ -1 +1 @@
1
- {"version":3,"file":"configure.d.ts","sourceRoot":"","sources":["../configure.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,SAAS,MAAM,mCAAmC,CAAC;AAG/D;;;;;;;;;GASG;AACH,wBAAsB,SAAS,CAAC,OAAO,EAAE,SAAS,iBASjD"}
1
+ {"version":3,"file":"configure.d.ts","sourceRoot":"","sources":["../configure.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,SAAS,MAAM,mCAAmC,CAAC;AAG/D;;;;;;;;;GASG;AACH,wBAAsB,SAAS,CAAC,OAAO,EAAE,SAAS,iBAcjD"}
package/dist/configure.js CHANGED
@@ -4,8 +4,8 @@ import { stubsRoot } from './stubs/main.js';
4
4
  *
5
5
  * 1. registers the media service provider in `adonisrc.ts`;
6
6
  * 2. publishes `config/media.ts`;
7
- * 3. publishes the Lucid migration for the optional `lucid` store (run
8
- * `node ace migration:run`; delete it if you only use the in-memory store).
7
+ * 3. publishes the Lucid migrations for the optional `lucid` store and the resumable (TUS) session
8
+ * store (run `node ace migration:run`; delete either if you only use the in-memory equivalents).
9
9
  *
10
10
  * Requires `@adonisjs/drive` to be installed and configured first (`node ace add @adonisjs/drive`).
11
11
  */
@@ -16,5 +16,6 @@ export async function configure(command) {
16
16
  });
17
17
  await codemods.makeUsingStub(stubsRoot, 'config/media.stub', {});
18
18
  await codemods.makeUsingStub(stubsRoot, 'database/migrations/create_media_table.stub', {});
19
+ await codemods.makeUsingStub(stubsRoot, 'database/migrations/create_media_upload_sessions_table.stub', {});
19
20
  }
20
21
  //# sourceMappingURL=configure.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"configure.js","sourceRoot":"","sources":["../configure.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAE5C;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,OAAkB;IAChD,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,cAAc,EAAE,CAAC;IAEhD,MAAM,QAAQ,CAAC,YAAY,CAAC,CAAC,MAAM,EAAE,EAAE;QACrC,MAAM,CAAC,WAAW,CAAC,oCAAoC,CAAC,CAAC;IAC3D,CAAC,CAAC,CAAC;IAEH,MAAM,QAAQ,CAAC,aAAa,CAAC,SAAS,EAAE,mBAAmB,EAAE,EAAE,CAAC,CAAC;IACjE,MAAM,QAAQ,CAAC,aAAa,CAAC,SAAS,EAAE,6CAA6C,EAAE,EAAE,CAAC,CAAC;AAC7F,CAAC"}
1
+ {"version":3,"file":"configure.js","sourceRoot":"","sources":["../configure.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAE5C;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,OAAkB;IAChD,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,cAAc,EAAE,CAAC;IAEhD,MAAM,QAAQ,CAAC,YAAY,CAAC,CAAC,MAAM,EAAE,EAAE;QACrC,MAAM,CAAC,WAAW,CAAC,oCAAoC,CAAC,CAAC;IAC3D,CAAC,CAAC,CAAC;IAEH,MAAM,QAAQ,CAAC,aAAa,CAAC,SAAS,EAAE,mBAAmB,EAAE,EAAE,CAAC,CAAC;IACjE,MAAM,QAAQ,CAAC,aAAa,CAAC,SAAS,EAAE,6CAA6C,EAAE,EAAE,CAAC,CAAC;IAC3F,MAAM,QAAQ,CAAC,aAAa,CAC1B,SAAS,EACT,6DAA6D,EAC7D,EAAE,CACH,CAAC;AACJ,CAAC"}
@@ -16,5 +16,20 @@ export default class MediaProvider {
16
16
  protected app: ApplicationService;
17
17
  constructor(app: ApplicationService);
18
18
  register(): void;
19
+ /**
20
+ * Mount the optional direct-S3 upload routes when `uploads.routes.enabled` is set. These are plain
21
+ * AdonisJS routes (NOT controllers): each resolves the {@link MediaManager} singleton lazily and
22
+ * delegates to its upload methods. The object key is taken from the request body/query — resolve
23
+ * it server-side (per user/tenant) in a real app so a client can't point an upload at another
24
+ * object.
25
+ *
26
+ * Routes (relative to `uploads.routes.prefix`, default `/media/uploads`):
27
+ * - `POST /direct/initiate` → presign multipart parts
28
+ * - `POST /direct/:uploadId/parts/:partNumber` → presign one (retried) part
29
+ * - `POST /direct/:uploadId/complete` → assemble the parts
30
+ * - `DELETE /direct/:uploadId` → abort the upload
31
+ * - `PUT /proxy` → stream bytes through the app (proxy mode)
32
+ */
33
+ boot(): void;
19
34
  }
20
35
  //# sourceMappingURL=media_provider.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"media_provider.d.ts","sourceRoot":"","sources":["../../providers/media_provider.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAY/D;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,OAAO,OAAO,aAAa;;IACpB,SAAS,CAAC,GAAG,EAAE,kBAAkB;gBAAvB,GAAG,EAAE,kBAAkB;IAE7C,QAAQ;CAuDT"}
1
+ {"version":3,"file":"media_provider.d.ts","sourceRoot":"","sources":["../../providers/media_provider.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAmB/D;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,OAAO,OAAO,aAAa;;IACpB,SAAS,CAAC,GAAG,EAAE,kBAAkB;gBAAvB,GAAG,EAAE,kBAAkB;IAE7C,QAAQ;IAsER;;;;;;;;;;;;;OAaG;IACH,IAAI;CAkML"}
@@ -1,4 +1,9 @@
1
+ import router from '@adonisjs/core/services/router';
2
+ import { resolveConfiguredDisks } from '../src/disks/factory.js';
1
3
  import { MediaManager } from '../src/media_manager.js';
4
+ import { resolveStore } from '../src/stores/factory.js';
5
+ import { TusUploadHandler } from '../src/tus.js';
6
+ import { resolveUploadSessionStore } from '../src/upload_sessions/factory.js';
2
7
  /**
3
8
  * Wires `@adonis-agora/media` into the AdonisJS application: binds a singleton {@link MediaManager}
4
9
  * built from `config/media.ts`. Storage is delegated to `@adonisjs/drive` — the manager resolves disks
@@ -19,16 +24,36 @@ export default class MediaProvider {
19
24
  register() {
20
25
  this.app.container.singleton(MediaManager, async () => {
21
26
  const config = this.app.config.get('media', {});
27
+ // Validate + build the store from config first, so a misconfigured `store` fails fast (before
28
+ // we touch Drive) rather than silently booting on a non-durable in-memory fallback.
29
+ const ctx = { app: this.app };
30
+ const store = await resolveStore(config, ctx);
31
+ const imageProcessor = await this.#resolveImageProcessor(config);
32
+ // Build the resumable (TUS) session store only when `uploads.resumable` is configured, so its
33
+ // peer (`@adonisjs/lucid`) loads lazily and the resumable subsystem stays fully opt-in.
34
+ const resumable = config.uploads?.resumable;
35
+ const uploadSessions = resumable
36
+ ? await resolveUploadSessionStore({
37
+ ...(resumable.store !== undefined ? { store: resumable.store } : {}),
38
+ ...(resumable.stores !== undefined ? { stores: resumable.stores } : {}),
39
+ }, { app: this.app })
40
+ : undefined;
41
+ // Build any disks declared in `config.disks` (e.g. the bundled `disks.s3()` driver). Each
42
+ // factory lazily loads its peer (the AWS SDK), so nothing is imported unless an S3 disk is
43
+ // actually configured.
44
+ const configuredDisks = await resolveConfiguredDisks(config.disks);
22
45
  // Resolve disks from Drive without a hard dependency: import its service lazily. The Drive
23
46
  // disk satisfies our structural `Disk` (getBytes/put/getUrl/...); cast via `unknown` because
24
47
  // Drive's full surface is wider than the subset we use.
25
48
  const drive = (await import('@adonisjs/drive/services/main'))
26
49
  .default;
27
- const resolve = (name) => drive.use(name);
28
- const ctx = { app: this.app };
29
- const store = await this.#resolveStore(config, ctx);
30
- const imageProcessor = await this.#resolveImageProcessor(config);
31
50
  const defaultDisk = config.disk ?? (await this.#resolveDefaultDiskName());
51
+ // A disk named in `config.disks` wins over a Drive disk of the same name; otherwise fall
52
+ // through to Drive so existing Drive disks keep working unchanged.
53
+ const resolve = (name) => {
54
+ const key = name ?? defaultDisk;
55
+ return configuredDisks[key] ?? drive.use(name);
56
+ };
32
57
  return new MediaManager({
33
58
  defaultDisk,
34
59
  resolve,
@@ -41,17 +66,180 @@ export default class MediaProvider {
41
66
  ...(config.emitDiagnostics !== undefined
42
67
  ? { emitDiagnostics: config.emitDiagnostics }
43
68
  : {}),
69
+ ...(config.uploads?.mode !== undefined ? { uploadMode: config.uploads.mode } : {}),
70
+ ...(config.uploads?.partSize !== undefined
71
+ ? { uploadPartSize: config.uploads.partSize }
72
+ : {}),
73
+ ...(config.uploads?.presignTtlSeconds !== undefined
74
+ ? { uploadPresignTtlSeconds: config.uploads.presignTtlSeconds }
75
+ : {}),
76
+ ...(uploadSessions !== undefined ? { uploadSessions } : {}),
77
+ ...(resumable?.tmpPrefix !== undefined ? { resumableTmpPrefix: resumable.tmpPrefix } : {}),
78
+ ...(resumable?.sessionTtlSeconds !== undefined
79
+ ? { resumableSessionTtlSeconds: resumable.sessionTtlSeconds }
80
+ : {}),
44
81
  });
45
82
  });
46
83
  }
47
- /** Build the configured store; defaults to the in-memory store when none is selected. */
48
- async #resolveStore(config, ctx) {
49
- const name = config.store;
50
- if (name && config.stores?.[name]) {
51
- return config.stores[name](ctx);
52
- }
53
- const { InMemoryMediaStore } = await import('../src/testing/in_memory_media_store.js');
54
- return new InMemoryMediaStore();
84
+ /**
85
+ * Mount the optional direct-S3 upload routes when `uploads.routes.enabled` is set. These are plain
86
+ * AdonisJS routes (NOT controllers): each resolves the {@link MediaManager} singleton lazily and
87
+ * delegates to its upload methods. The object key is taken from the request body/query — resolve
88
+ * it server-side (per user/tenant) in a real app so a client can't point an upload at another
89
+ * object.
90
+ *
91
+ * Routes (relative to `uploads.routes.prefix`, default `/media/uploads`):
92
+ * - `POST /direct/initiate` → presign multipart parts
93
+ * - `POST /direct/:uploadId/parts/:partNumber` → presign one (retried) part
94
+ * - `POST /direct/:uploadId/complete` → assemble the parts
95
+ * - `DELETE /direct/:uploadId` → abort the upload
96
+ * - `PUT /proxy` → stream bytes through the app (proxy mode)
97
+ */
98
+ boot() {
99
+ const config = this.app.config.get('media', {});
100
+ this.#mountTusRoutes(config);
101
+ const routes = config.uploads?.routes;
102
+ if (!routes?.enabled)
103
+ return;
104
+ const prefix = (routes.prefix ?? '/media/uploads').replace(/\/+$/, '');
105
+ const manager = () => this.app.container.make(MediaManager);
106
+ const json = (handler, okStatus = 200) => {
107
+ return async (ctx) => {
108
+ try {
109
+ const result = await handler(await manager(), ctx);
110
+ return ctx.response.status(okStatus).json(result ?? { ok: true });
111
+ }
112
+ catch (error) {
113
+ const message = error instanceof Error ? error.message : 'upload error';
114
+ const code = error.code;
115
+ return ctx.response
116
+ .status(code === 'E_MEDIA_UPLOAD_NOT_SUPPORTED' ? 400 : 500)
117
+ .json({ error: message, ...(code !== undefined ? { code } : {}) });
118
+ }
119
+ };
120
+ };
121
+ router
122
+ .post(`${prefix}/direct/initiate`, json(async (media, ctx) => {
123
+ const body = ctx.request.body();
124
+ return media.initiateDirectUpload({
125
+ key: body.key,
126
+ ...(body.contentType !== undefined ? { contentType: body.contentType } : {}),
127
+ ...(body.visibility !== undefined ? { visibility: body.visibility } : {}),
128
+ ...(body.size !== undefined ? { size: body.size } : {}),
129
+ ...(body.partSize !== undefined ? { partSize: body.partSize } : {}),
130
+ ...(body.disk !== undefined ? { disk: body.disk } : {}),
131
+ });
132
+ }))
133
+ .as('media.uploads.direct.initiate');
134
+ router
135
+ .post(`${prefix}/direct/:uploadId/parts/:partNumber`, json(async (media, ctx) => {
136
+ const key = requireKey(ctx);
137
+ const disk = readDisk(ctx);
138
+ return media.uploads.presignPart({
139
+ key,
140
+ uploadId: String(ctx.params.uploadId),
141
+ partNumber: Number(ctx.params.partNumber),
142
+ ...(disk !== undefined ? { disk } : {}),
143
+ });
144
+ }))
145
+ .as('media.uploads.direct.presignPart');
146
+ router
147
+ .post(`${prefix}/direct/:uploadId/complete`, json(async (media, ctx) => {
148
+ const body = ctx.request.body();
149
+ return media.completeDirectUpload({
150
+ key: body.key,
151
+ uploadId: String(ctx.params.uploadId),
152
+ parts: body.parts,
153
+ ...(body.disk !== undefined ? { disk: body.disk } : {}),
154
+ });
155
+ }))
156
+ .as('media.uploads.direct.complete');
157
+ router
158
+ .delete(`${prefix}/direct/:uploadId`, json(async (media, ctx) => {
159
+ const key = requireKey(ctx);
160
+ const disk = readDisk(ctx);
161
+ await media.abortDirectUpload({
162
+ key,
163
+ uploadId: String(ctx.params.uploadId),
164
+ ...(disk !== undefined ? { disk } : {}),
165
+ });
166
+ return { ok: true };
167
+ }))
168
+ .as('media.uploads.direct.abort');
169
+ router
170
+ .put(`${prefix}/proxy`, json(async (media, ctx) => {
171
+ const key = requireKey(ctx);
172
+ const disk = readDisk(ctx);
173
+ const contentType = ctx.request.header('content-type');
174
+ return media.proxyUpload({
175
+ key,
176
+ // The raw Node request is a Readable — stream it straight to the disk without buffering.
177
+ contents: ctx.request.request,
178
+ ...(contentType !== undefined ? { contentType } : {}),
179
+ ...(disk !== undefined ? { disk } : {}),
180
+ });
181
+ }, 201))
182
+ .as('media.uploads.proxy');
183
+ }
184
+ /**
185
+ * Mount the optional TUS resumable-upload routes when `uploads.resumable.routes.enabled`. Like the
186
+ * direct routes these are plain AdonisJS routes (NOT controllers): each resolves the singleton
187
+ * {@link MediaManager} lazily and drives a framework-agnostic {@link TusUploadHandler} over
188
+ * `media.resumable`. The handler is built once, lazily, from the resolved manager.
189
+ *
190
+ * Routes (relative to `uploads.resumable.routes.prefix`, default `/media/uploads/tus`):
191
+ * - `OPTIONS /` → protocol discovery (version, extensions, max size)
192
+ * - `POST /` → create a session (`Upload-Length` + `Upload-Metadata`) → `201` + `Location`
193
+ * - `HEAD /:id` → report `Upload-Offset` (resume point)
194
+ * - `PATCH /:id` → append bytes at `Upload-Offset`; auto-completes at the declared length
195
+ * - `DELETE /:id` → terminate the upload
196
+ */
197
+ #mountTusRoutes(config) {
198
+ const resumable = config.uploads?.resumable;
199
+ if (!resumable?.routes?.enabled)
200
+ return;
201
+ const prefix = (resumable.routes.prefix ?? '/media/uploads/tus').replace(/\/+$/, '');
202
+ const routeDisk = resumable.routes.disk;
203
+ const maxSize = resumable.routes.maxSize;
204
+ // Build the TUS handler once, on first request, from the resolved MediaManager singleton.
205
+ let handler;
206
+ const getHandler = async () => {
207
+ if (!handler) {
208
+ const media = await this.app.container.make(MediaManager);
209
+ handler = new TusUploadHandler({
210
+ manager: media.resumable,
211
+ disk: routeDisk ?? media.storage.defaultDisk,
212
+ basePath: prefix,
213
+ ...(maxSize !== undefined ? { maxSize } : {}),
214
+ });
215
+ }
216
+ return handler;
217
+ };
218
+ const run = (method, withBody = false) => {
219
+ return async (ctx) => {
220
+ const tus = await getHandler();
221
+ const headers = {};
222
+ for (const [name, value] of Object.entries(ctx.request.headers())) {
223
+ headers[name.toLowerCase()] = Array.isArray(value) ? value[0] : value;
224
+ }
225
+ const req = { method, headers };
226
+ if (ctx.params.id !== undefined)
227
+ req.uploadId = String(ctx.params.id);
228
+ if (withBody)
229
+ req.body = await readRawBody(ctx);
230
+ const res = await tus.handle(req);
231
+ for (const [name, value] of Object.entries(res.headers)) {
232
+ ctx.response.header(name, value);
233
+ }
234
+ ctx.response.status(res.status);
235
+ return res.body ?? '';
236
+ };
237
+ };
238
+ router.route(prefix, ['OPTIONS'], run('OPTIONS')).as('media.uploads.tus.options');
239
+ router.post(prefix, run('POST')).as('media.uploads.tus.create');
240
+ router.route(`${prefix}/:id`, ['HEAD'], run('HEAD')).as('media.uploads.tus.head');
241
+ router.patch(`${prefix}/:id`, run('PATCH', true)).as('media.uploads.tus.patch');
242
+ router.delete(`${prefix}/:id`, run('DELETE')).as('media.uploads.tus.delete');
55
243
  }
56
244
  /** A config `imageProcessor` may be a ready instance or a lazy factory thunk. */
57
245
  async #resolveImageProcessor(config) {
@@ -68,4 +256,28 @@ export default class MediaProvider {
68
256
  return driveConfig.default ?? 'default';
69
257
  }
70
258
  }
259
+ /** Read the object key from the query or JSON body; throw a 400-mappable error when absent. */
260
+ function requireKey(ctx) {
261
+ const fromQuery = ctx.request.input('key');
262
+ const key = typeof fromQuery === 'string' ? fromQuery : undefined;
263
+ if (key)
264
+ return key;
265
+ throw Object.assign(new Error('key is required'), { code: 'E_MEDIA_UPLOAD_NOT_SUPPORTED' });
266
+ }
267
+ /** Read an optional disk-name override from the query or JSON body. */
268
+ function readDisk(ctx) {
269
+ const value = ctx.request.input('disk');
270
+ return typeof value === 'string' ? value : undefined;
271
+ }
272
+ /**
273
+ * Buffer the raw request body for a TUS `PATCH`. The chunk arrives as
274
+ * `application/offset+octet-stream`, which the AdonisJS bodyparser leaves untouched, so the raw Node
275
+ * request stream still holds the bytes.
276
+ */
277
+ async function readRawBody(ctx) {
278
+ const chunks = [];
279
+ for await (const chunk of ctx.request.request)
280
+ chunks.push(Buffer.from(chunk));
281
+ return new Uint8Array(Buffer.concat(chunks));
282
+ }
71
283
  //# sourceMappingURL=media_provider.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"media_provider.js","sourceRoot":"","sources":["../../providers/media_provider.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"media_provider.js","sourceRoot":"","sources":["../../providers/media_provider.ts"],"names":[],"mappings":"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"}
@@ -65,6 +65,7 @@ export interface AttachmentManagerOptions {
65
65
  * you assign to a model column.
66
66
  */
67
67
  export declare class AttachmentManager {
68
+ #private;
68
69
  private readonly storage;
69
70
  private readonly imageProcessor;
70
71
  private readonly keyPrefix;
@@ -1 +1 @@
1
- {"version":3,"file":"attachment.d.ts","sourceRoot":"","sources":["../../src/attachment.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"attachment.d.ts","sourceRoot":"","sources":["../../src/attachment.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,7 @@
1
1
  import { randomUUID } from 'node:crypto';
2
2
  import { asBuffer, toBytes } from './contents.js';
3
3
  import { publishMedia } from './diagnostics.js';
4
+ import { ImageProcessorMissingError, VariantNotFoundError } from './errors.js';
4
5
  /**
5
6
  * A file attached to a model as a column value (adonis-attachment style). Pure value
6
7
  * object — it carries disk + path + variant metadata and serializes to JSON. URL
@@ -63,29 +64,55 @@ export class AttachmentManager {
63
64
  const id = this.newId();
64
65
  const dir = `${prefix}/${id}`;
65
66
  const path = `${dir}/${input.fileName}`;
66
- const bytes = await toBytes(input.contents);
67
- await this.storage.disk(disk).put(path, bytes, { contentType: input.mimeType });
68
- const size = input.size ?? (await this.storage.disk(disk).getMetaData(path)).contentLength;
69
- const variants = {};
67
+ const target = this.storage.disk(disk);
70
68
  const presets = options.variants ?? [];
71
- if (presets.length > 0) {
72
- if (!this.imageProcessor) {
73
- throw new Error('AttachmentManager: variants requested but no ImageProcessor was configured');
69
+ // Stream large uploads straight through (no in-memory buffer) when we can: a Readable with a
70
+ // known size, no variants to generate off the buffered bytes, and a disk that supports it.
71
+ const canStream = !Buffer.isBuffer(input.contents) &&
72
+ input.size !== undefined &&
73
+ presets.length === 0 &&
74
+ typeof target.putStream === 'function';
75
+ if (canStream) {
76
+ // See MediaLibrary.attach: `input.size` gates this path, so it must reach the disk —
77
+ // S3's putStream cannot write without it.
78
+ await target.putStream?.(path, input.contents, {
79
+ contentType: input.mimeType,
80
+ contentLength: input.size,
81
+ });
82
+ }
83
+ else {
84
+ const bytes = await toBytes(input.contents);
85
+ await target.put(path, bytes, { contentType: input.mimeType });
86
+ }
87
+ const variants = {};
88
+ let size;
89
+ try {
90
+ size = input.size ?? (await target.getMetaData(path)).contentLength;
91
+ if (presets.length > 0) {
92
+ if (!this.imageProcessor)
93
+ throw new ImageProcessorMissingError();
94
+ const original = asBuffer(await target.getBytes(path));
95
+ for (const preset of presets) {
96
+ const result = await this.imageProcessor.convert(original, preset);
97
+ const variantPath = `${dir}/variants/${preset.name}.${result.format}`;
98
+ await target.put(variantPath, result.data, { contentType: result.contentType });
99
+ variants[preset.name] = {
100
+ disk,
101
+ path: variantPath,
102
+ size: result.data.byteLength,
103
+ mimeType: result.contentType,
104
+ };
105
+ }
74
106
  }
75
- const original = asBuffer(await this.storage.disk(disk).getBytes(path));
76
- for (const preset of presets) {
77
- const result = await this.imageProcessor.convert(original, preset);
78
- const variantPath = `${dir}/variants/${preset.name}.${result.format}`;
79
- await this.storage.disk(disk).put(variantPath, result.data, {
80
- contentType: result.contentType,
81
- });
82
- variants[preset.name] = {
83
- disk,
84
- path: variantPath,
85
- size: result.data.byteLength,
86
- mimeType: result.contentType,
87
- };
107
+ }
108
+ catch (error) {
109
+ // Compensation: the original (and any variants already written) leaked when the metadata read
110
+ // or a conversion failed — best-effort remove them before rethrowing.
111
+ await this.#safeDelete(disk, path);
112
+ for (const variant of Object.values(variants)) {
113
+ await this.#safeDelete(variant.disk, variant.path);
88
114
  }
115
+ throw error;
89
116
  }
90
117
  const attachment = new Attachment({
91
118
  name: options.name ?? input.fileName,
@@ -137,8 +164,17 @@ export class AttachmentManager {
137
164
  return { disk: attachment.disk, path: attachment.path };
138
165
  const v = attachment.variants[variant];
139
166
  if (!v)
140
- throw new Error(`Attachment has no variant "${variant}"`);
167
+ throw new VariantNotFoundError(variant);
141
168
  return { disk: v.disk, path: v.path };
142
169
  }
170
+ /** Best-effort disk cleanup for the orphan-compensation path; never masks the original error. */
171
+ async #safeDelete(disk, path) {
172
+ try {
173
+ await this.storage.disk(disk).delete(path);
174
+ }
175
+ catch {
176
+ // swallow: this is compensation for a failed create; the original error is what matters
177
+ }
178
+ }
143
179
  }
144
180
  //# sourceMappingURL=attachment.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"attachment.js","sourceRoot":"","sources":["../../src/attachment.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"attachment.js","sourceRoot":"","sources":["../../src/attachment.ts"],"names":[],"mappings":"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"}