@adonis-agora/media 0.8.2 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (104) hide show
  1. package/CHANGELOG.md +76 -0
  2. package/README.md +2 -2
  3. package/dist/providers/media_provider.d.ts.map +1 -1
  4. package/dist/providers/media_provider.js +113 -0
  5. package/dist/providers/media_provider.js.map +1 -1
  6. package/dist/src/content_type.d.ts +6 -1
  7. package/dist/src/content_type.d.ts.map +1 -1
  8. package/dist/src/content_type.js +102 -7
  9. package/dist/src/content_type.js.map +1 -1
  10. package/dist/src/define_config.d.ts +88 -5
  11. package/dist/src/define_config.d.ts.map +1 -1
  12. package/dist/src/define_config.js +7 -2
  13. package/dist/src/define_config.js.map +1 -1
  14. package/dist/src/direct_upload.d.ts +177 -0
  15. package/dist/src/direct_upload.d.ts.map +1 -0
  16. package/dist/src/direct_upload.js +299 -0
  17. package/dist/src/direct_upload.js.map +1 -0
  18. package/dist/src/direct_upload_handler.d.ts +83 -0
  19. package/dist/src/direct_upload_handler.d.ts.map +1 -0
  20. package/dist/src/direct_upload_handler.js +180 -0
  21. package/dist/src/direct_upload_handler.js.map +1 -0
  22. package/dist/src/disks/factory.d.ts +11 -3
  23. package/dist/src/disks/factory.d.ts.map +1 -1
  24. package/dist/src/disks/factory.js +5 -3
  25. package/dist/src/disks/factory.js.map +1 -1
  26. package/dist/src/disks/s3.d.ts +10 -0
  27. package/dist/src/disks/s3.d.ts.map +1 -1
  28. package/dist/src/disks/s3.js +96 -22
  29. package/dist/src/disks/s3.js.map +1 -1
  30. package/dist/src/disks/sigv4.d.ts +58 -0
  31. package/dist/src/disks/sigv4.d.ts.map +1 -0
  32. package/dist/src/disks/sigv4.js +87 -0
  33. package/dist/src/disks/sigv4.js.map +1 -0
  34. package/dist/src/disks/xml_fallback.d.ts +3 -3
  35. package/dist/src/disks/xml_fallback.js +3 -3
  36. package/dist/src/errors.d.ts +104 -0
  37. package/dist/src/errors.d.ts.map +1 -1
  38. package/dist/src/errors.js +145 -0
  39. package/dist/src/errors.js.map +1 -1
  40. package/dist/src/hls/delivery.d.ts +112 -0
  41. package/dist/src/hls/delivery.d.ts.map +1 -0
  42. package/dist/src/hls/delivery.js +118 -0
  43. package/dist/src/hls/delivery.js.map +1 -0
  44. package/dist/src/hls/playlist.d.ts +67 -0
  45. package/dist/src/hls/playlist.d.ts.map +1 -0
  46. package/dist/src/hls/playlist.js +126 -0
  47. package/dist/src/hls/playlist.js.map +1 -0
  48. package/dist/src/index.d.ts +18 -3
  49. package/dist/src/index.d.ts.map +1 -1
  50. package/dist/src/index.js +13 -2
  51. package/dist/src/index.js.map +1 -1
  52. package/dist/src/media_collection.d.ts +8 -1
  53. package/dist/src/media_collection.d.ts.map +1 -1
  54. package/dist/src/media_collection.js +23 -1
  55. package/dist/src/media_collection.js.map +1 -1
  56. package/dist/src/media_library.d.ts +32 -2
  57. package/dist/src/media_library.d.ts.map +1 -1
  58. package/dist/src/media_library.js +218 -11
  59. package/dist/src/media_library.js.map +1 -1
  60. package/dist/src/media_manager.d.ts +37 -2
  61. package/dist/src/media_manager.d.ts.map +1 -1
  62. package/dist/src/media_manager.js +54 -1
  63. package/dist/src/media_manager.js.map +1 -1
  64. package/dist/src/media_record.d.ts +22 -2
  65. package/dist/src/media_record.d.ts.map +1 -1
  66. package/dist/src/testing/fake_transformer.d.ts +32 -0
  67. package/dist/src/testing/fake_transformer.d.ts.map +1 -0
  68. package/dist/src/testing/fake_transformer.js +32 -0
  69. package/dist/src/testing/fake_transformer.js.map +1 -0
  70. package/dist/src/testing/index.d.ts +2 -0
  71. package/dist/src/testing/index.d.ts.map +1 -1
  72. package/dist/src/testing/index.js +1 -0
  73. package/dist/src/testing/index.js.map +1 -1
  74. package/dist/src/transformer.d.ts +111 -0
  75. package/dist/src/transformer.d.ts.map +1 -0
  76. package/dist/src/transformer.js +2 -0
  77. package/dist/src/transformer.js.map +1 -0
  78. package/dist/src/transformers/factory.d.ts +30 -0
  79. package/dist/src/transformers/factory.d.ts.map +1 -0
  80. package/dist/src/transformers/factory.js +34 -0
  81. package/dist/src/transformers/factory.js.map +1 -0
  82. package/dist/src/transformers/hls.d.ts +110 -0
  83. package/dist/src/transformers/hls.d.ts.map +1 -0
  84. package/dist/src/transformers/hls.js +111 -0
  85. package/dist/src/transformers/hls.js.map +1 -0
  86. package/dist/src/transformers/mediabunny.d.ts +5 -0
  87. package/dist/src/transformers/mediabunny.d.ts.map +1 -0
  88. package/dist/src/transformers/mediabunny.js +150 -0
  89. package/dist/src/transformers/mediabunny.js.map +1 -0
  90. package/dist/src/transformers/mediabunny_loader.d.ts +15 -0
  91. package/dist/src/transformers/mediabunny_loader.d.ts.map +1 -0
  92. package/dist/src/transformers/mediabunny_loader.js +21 -0
  93. package/dist/src/transformers/mediabunny_loader.js.map +1 -0
  94. package/dist/src/transformers/probe.d.ts +56 -0
  95. package/dist/src/transformers/probe.d.ts.map +1 -0
  96. package/dist/src/transformers/probe.js +32 -0
  97. package/dist/src/transformers/probe.js.map +1 -0
  98. package/dist/src/transformers/source_file.d.ts +20 -0
  99. package/dist/src/transformers/source_file.d.ts.map +1 -0
  100. package/dist/src/transformers/source_file.js +30 -0
  101. package/dist/src/transformers/source_file.js.map +1 -0
  102. package/dist/stubs/config/media.stub +12 -0
  103. package/package.json +11 -7
  104. package/LICENSE +0 -21
@@ -1,5 +1,6 @@
1
1
  import { AttachmentManager } from './attachment.js';
2
- import { ResumableUploadsNotConfiguredError } from './errors.js';
2
+ import { DirectUploadManager } from './direct_upload.js';
3
+ import { DirectUploadsNotConfiguredError, ResumableUploadsNotConfiguredError } from './errors.js';
3
4
  import { MediaLibrary } from './media_library.js';
4
5
  import { ResumableUploadManager } from './resumable_upload.js';
5
6
  import { StorageManager } from './storage_manager.js';
@@ -28,6 +29,8 @@ export class MediaManager {
28
29
  uploads;
29
30
  /** Resumable (TUS) upload coordinator — present only when a session store is configured. */
30
31
  #resumable;
32
+ /** Session-backed direct upload coordinator — present only when a session store is configured. */
33
+ #direct;
31
34
  constructor(options) {
32
35
  this.store = options.store;
33
36
  this.storage = new StorageManager({ default: options.defaultDisk, resolve: options.resolve });
@@ -80,6 +83,25 @@ export class MediaManager {
80
83
  : {}),
81
84
  });
82
85
  }
86
+ if (options.directUploadSessions !== undefined) {
87
+ this.#direct = new DirectUploadManager({
88
+ storage: this.storage,
89
+ sessions: options.directUploadSessions,
90
+ // The manager reads the whitelist from the same registry attach uses, so the initiate
91
+ // gate and the attach-time barrier cannot drift.
92
+ collections: this.library.collections,
93
+ ...(options.directPartSize !== undefined ? { partSize: options.directPartSize } : {}),
94
+ ...(options.directPresignTtlSeconds !== undefined
95
+ ? { presignTtlSeconds: options.directPresignTtlSeconds }
96
+ : {}),
97
+ ...(options.directSessionTtlSeconds !== undefined
98
+ ? { sessionTtlSeconds: options.directSessionTtlSeconds }
99
+ : {}),
100
+ ...(options.emitDiagnostics !== undefined
101
+ ? { emitDiagnostics: options.emitDiagnostics }
102
+ : {}),
103
+ });
104
+ }
83
105
  }
84
106
  /**
85
107
  * The resumable (TUS) upload coordinator. Throws {@link ResumableUploadsNotConfiguredError} unless
@@ -110,6 +132,37 @@ export class MediaManager {
110
132
  const { key, disk, size } = await this.resumable.complete(sessionId);
111
133
  return this.library.attachExisting({ ...input, key, disk, size });
112
134
  }
135
+ /**
136
+ * The session-backed direct upload coordinator. Throws {@link DirectUploadsNotConfiguredError}
137
+ * unless a session store was configured via `uploads.direct` in `config/media.ts`.
138
+ */
139
+ get direct() {
140
+ if (!this.#direct)
141
+ throw new DirectUploadsNotConfiguredError();
142
+ return this.#direct;
143
+ }
144
+ /** Whether session-backed direct uploads are configured (a session store is present). */
145
+ get hasDirect() {
146
+ return this.#direct !== undefined;
147
+ }
148
+ /**
149
+ * Finish a session-backed direct upload and register the assembled object as a media record, in
150
+ * one step — the direct-mode twin of {@link completeUploadToLibrary}, meeting the two layers at
151
+ * the manager the same way. `attachExisting` adopts the object zero-copy and re-validates the
152
+ * collection's whitelist against the REAL bytes (a short head read), so a client that lied about
153
+ * `contentType` at initiate is caught here, exactly like every other upload path.
154
+ *
155
+ * ```ts
156
+ * await media.completeDirectUploadToLibrary(sessionId, {
157
+ * ownerType: 'Lesson', ownerId: lesson.id, collection: 'video',
158
+ * fileName: 'original.mp4', mimeType: 'video/mp4',
159
+ * }, partsFromClient)
160
+ * ```
161
+ */
162
+ async completeDirectUploadToLibrary(sessionId, input, parts = []) {
163
+ const { key, disk, size } = await this.direct.complete(sessionId, parts);
164
+ return this.library.attachExisting({ ...input, key, disk, size });
165
+ }
113
166
  /**
114
167
  * The registered collection configs — the single source of truth for `acceptsMimeTypes`. Exposed
115
168
  * so the upload edge (`TusUploadHandler`) can enforce the very same whitelist the library will
@@ -1 +1 @@
1
- {"version":3,"file":"media_manager.js","sourceRoot":"","sources":["../../src/media_manager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAEpD,OAAO,EAAE,kCAAkC,EAAE,MAAM,aAAa,CAAC;AAGjE,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAIlD,OAAO,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AAE/D,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAEtD,OAAO,EAML,aAAa,GACd,MAAM,qBAAqB,CAAC;AAkC7B;;;;;;;;;;GAUG;AACH,MAAM,OAAO,YAAY;IACd,OAAO,CAAiB;IACxB,OAAO,CAAe;IACtB,WAAW,CAAoB;IACxC;;;OAGG;IACM,KAAK,CAAa;IAC3B,qEAAqE;IAC5D,OAAO,CAAgB;IAChC,4FAA4F;IACnF,UAAU,CAAqC;IAExD,YAAY,OAA4B;QACtC,IAAI,CAAC,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC;QAC3B,IAAI,CAAC,OAAO,GAAG,IAAI,cAAc,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,WAAW,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;QAC9F,IAAI,CAAC,OAAO,GAAG,IAAI,YAAY,CAAC;YAC9B,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,KAAK,EAAE,OAAO,CAAC,KAAK;YACpB,GAAG,CAAC,OAAO,CAAC,WAAW,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAClF,GAAG,CAAC,OAAO,CAAC,cAAc,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,cAAc,EAAE,OAAO,CAAC,cAAc,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAC3F,GAAG,CAAC,OAAO,CAAC,eAAe,KAAK,SAAS;gBACvC,CAAC,CAAC,EAAE,eAAe,EAAE,OAAO,CAAC,eAAe,EAAE;gBAC9C,CAAC,CAAC,EAAE,CAAC;YACP,GAAG,CAAC,OAAO,CAAC,YAAY,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,YAAY,EAAE,OAAO,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACrF,GAAG,CAAC,OAAO,CAAC,wBAAwB,KAAK,SAAS;gBAChD,CAAC,CAAC,EAAE,wBAAwB,EAAE,OAAO,CAAC,wBAAwB,EAAE;gBAChE,CAAC,CAAC,EAAE,CAAC;SACR,CAAC,CAAC;QACH,IAAI,CAAC,WAAW,GAAG,IAAI,iBAAiB,CAAC;YACvC,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,GAAG,CAAC,OAAO,CAAC,cAAc,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,cAAc,EAAE,OAAO,CAAC,cAAc,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAC3F,GAAG,CAAC,OAAO,CAAC,mBAAmB,KAAK,SAAS;gBAC3C,CAAC,CAAC,EAAE,SAAS,EAAE,OAAO,CAAC,mBAAmB,EAAE;gBAC5C,CAAC,CAAC,EAAE,CAAC;YACP,GAAG,CAAC,OAAO,CAAC,eAAe,KAAK,SAAS;gBACvC,CAAC,CAAC,EAAE,eAAe,EAAE,OAAO,CAAC,eAAe,EAAE;gBAC9C,CAAC,CAAC,EAAE,CAAC;SACR,CAAC,CAAC;QACH,IAAI,CAAC,OAAO,GAAG,IAAI,aAAa,CAAC;YAC/B,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,GAAG,CAAC,OAAO,CAAC,UAAU,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACzE,GAAG,CAAC,OAAO,CAAC,cAAc,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,OAAO,CAAC,cAAc,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACrF,GAAG,CAAC,OAAO,CAAC,uBAAuB,KAAK,SAAS;gBAC/C,CAAC,CAAC,EAAE,iBAAiB,EAAE,OAAO,CAAC,uBAAuB,EAAE;gBACxD,CAAC,CAAC,EAAE,CAAC;YACP,GAAG,CAAC,OAAO,CAAC,eAAe,KAAK,SAAS;gBACvC,CAAC,CAAC,EAAE,eAAe,EAAE,OAAO,CAAC,eAAe,EAAE;gBAC9C,CAAC,CAAC,EAAE,CAAC;SACR,CAAC,CAAC;QACH,IAAI,OAAO,CAAC,cAAc,KAAK,SAAS,EAAE,CAAC;YACzC,IAAI,CAAC,UAAU,GAAG,IAAI,sBAAsB,CAAC;gBAC3C,OAAO,EAAE,IAAI,CAAC,OAAO;gBACrB,QAAQ,EAAE,OAAO,CAAC,cAAc;gBAChC,GAAG,CAAC,OAAO,CAAC,kBAAkB,KAAK,SAAS;oBAC1C,CAAC,CAAC,EAAE,SAAS,EAAE,OAAO,CAAC,kBAAkB,EAAE;oBAC3C,CAAC,CAAC,EAAE,CAAC;gBACP,GAAG,CAAC,OAAO,CAAC,0BAA0B,KAAK,SAAS;oBAClD,CAAC,CAAC,EAAE,iBAAiB,EAAE,OAAO,CAAC,0BAA0B,EAAE;oBAC3D,CAAC,CAAC,EAAE,CAAC;gBACP,GAAG,CAAC,OAAO,CAAC,eAAe,KAAK,SAAS;oBACvC,CAAC,CAAC,EAAE,eAAe,EAAE,OAAO,CAAC,eAAe,EAAE;oBAC9C,CAAC,CAAC,EAAE,CAAC;aACR,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED;;;OAGG;IACH,IAAI,SAAS;QACX,IAAI,CAAC,IAAI,CAAC,UAAU;YAAE,MAAM,IAAI,kCAAkC,EAAE,CAAC;QACrE,OAAO,IAAI,CAAC,UAAU,CAAC;IACzB,CAAC;IAED;;;;;;;;;;;;;;;OAeG;IACH,KAAK,CAAC,uBAAuB,CAC3B,SAAiB,EACjB,KAAyD;QAEzD,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;QACrE,OAAO,IAAI,CAAC,OAAO,CAAC,cAAc,CAAC,EAAE,GAAG,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;IACpE,CAAC;IAED;;;;OAIG;IACH,IAAI,WAAW;QACb,OAAO,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC;IAClC,CAAC;IAED,mFAAmF;IACnF,IAAI,YAAY;QACd,OAAO,IAAI,CAAC,UAAU,KAAK,SAAS,CAAC;IACvC,CAAC;IAED,8EAA8E;IAC9E,IAAI,CAAC,IAAa;QAChB,OAAO,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACjC,CAAC;IAED,uFAAuF;IACvF,oBAAoB,CAAC,KAAgC;QACnD,OAAO,IAAI,CAAC,OAAO,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC;IAC5C,CAAC;IAED,gEAAgE;IAChE,oBAAoB,CAAC,KAAgC;QACnD,OAAO,IAAI,CAAC,OAAO,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC;IAC5C,CAAC;IAED,qDAAqD;IACrD,iBAAiB,CAAC,KAA6B;QAC7C,OAAO,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;IACzC,CAAC;IAED,kFAAkF;IAClF,WAAW,CAAC,KAAuB;QACjC,OAAO,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;IACzC,CAAC;CACF"}
1
+ {"version":3,"file":"media_manager.js","sourceRoot":"","sources":["../../src/media_manager.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,26 @@
1
+ /**
2
+ * One generated derivative of a media record, keyed by conversion name in
3
+ * {@link MediaRecord.conversions}. Three shapes share this type:
4
+ *
5
+ * - an **image conversion** (a `ConversionPreset`): `{ path, disk }` — one file.
6
+ * - a **transformer output with artifacts** (e.g. the HLS package): `path` is the entry artifact
7
+ * (the master playlist), `prefix` is the storage prefix holding every artifact, and `files`
8
+ * lists them all relative to `prefix` — the authority for serving files out of the package and
9
+ * for deleting it whole.
10
+ * - a **metadata-only transform** (a probe, a blurhash): no artifact at all — `path`/`disk` are
11
+ * absent and only `meta` carries the result.
12
+ */
1
13
  export interface MediaConversion {
2
- path: string;
3
- disk: string;
14
+ /** Entry-point artifact key. Absent for metadata-only transforms. */
15
+ path?: string;
16
+ /** Disk holding the artifact(s). Absent when there are none. */
17
+ disk?: string;
18
+ /** Storage prefix (ends in `/`) holding every artifact of a multi-file conversion. */
19
+ prefix?: string;
20
+ /** Every artifact key relative to {@link prefix}, the entry included. */
21
+ files?: string[];
22
+ /** Transformer-reported metadata (duration, codecs, hashes, …), persisted verbatim. */
23
+ meta?: Record<string, unknown>;
4
24
  }
5
25
  /** A stored file associated with an owning entity (spatie media-library style). */
6
26
  export interface MediaRecord {
@@ -1 +1 @@
1
- {"version":3,"file":"media_record.d.ts","sourceRoot":"","sources":["../../src/media_record.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd;AAED,mFAAmF;AACnF,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,0EAA0E;IAC1E,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC1C,kEAAkE;IAClE,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;IAC7C,SAAS,EAAE,IAAI,CAAC;IAChB,SAAS,EAAE,IAAI,CAAC;CACjB"}
1
+ {"version":3,"file":"media_record.d.ts","sourceRoot":"","sources":["../../src/media_record.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,eAAe;IAC9B,qEAAqE;IACrE,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,gEAAgE;IAChE,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,sFAAsF;IACtF,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,yEAAyE;IACzE,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,uFAAuF;IACvF,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAChC;AAED,mFAAmF;AACnF,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,0EAA0E;IAC1E,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC1C,kEAAkE;IAClE,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;IAC7C,SAAS,EAAE,IAAI,CAAC;IAChB,SAAS,EAAE,IAAI,CAAC;CACjB"}
@@ -0,0 +1,32 @@
1
+ import type { TransformResult, Transformer, TransformerContext } from '../transformer.js';
2
+ export interface FakeTransformerOptions<Name extends string = string> {
3
+ /** Conversion name this fake produces. */
4
+ name: Name;
5
+ eager?: boolean;
6
+ /** Artifacts to write through `context.write`, keyed by prefix-relative path. */
7
+ artifacts?: Record<string, string>;
8
+ /**
9
+ * Entry declared in the result. Defaults to the first artifact key; pass `null` for a
10
+ * metadata-only result (with no artifacts).
11
+ */
12
+ entry?: string | null;
13
+ /** Metadata declared in the result. */
14
+ meta?: Record<string, unknown>;
15
+ /** Full behavior override — everything above but `name`/`eager` is ignored when set. */
16
+ behavior?: (context: TransformerContext) => Promise<TransformResult>;
17
+ }
18
+ /**
19
+ * Deterministic {@link Transformer} for tests — the transformer counterpart of
20
+ * `FakeImageProcessor`. It records every context it is called with and writes/declares exactly
21
+ * what it was configured to, so eager/deferred behaviour, artifact bookkeeping and rollback can be
22
+ * asserted without a media engine.
23
+ */
24
+ export declare class FakeTransformer<Name extends string = string> implements Transformer {
25
+ readonly name: Name;
26
+ readonly eager: boolean;
27
+ readonly calls: TransformerContext[];
28
+ private readonly options;
29
+ constructor(options: FakeTransformerOptions<Name>);
30
+ transform(context: TransformerContext): Promise<TransformResult>;
31
+ }
32
+ //# sourceMappingURL=fake_transformer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fake_transformer.d.ts","sourceRoot":"","sources":["../../../src/testing/fake_transformer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,WAAW,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAE1F,MAAM,WAAW,sBAAsB,CAAC,IAAI,SAAS,MAAM,GAAG,MAAM;IAClE,0CAA0C;IAC1C,IAAI,EAAE,IAAI,CAAC;IACX,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,iFAAiF;IACjF,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACnC;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,uCAAuC;IACvC,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/B,wFAAwF;IACxF,QAAQ,CAAC,EAAE,CAAC,OAAO,EAAE,kBAAkB,KAAK,OAAO,CAAC,eAAe,CAAC,CAAC;CACtE;AAED;;;;;GAKG;AACH,qBAAa,eAAe,CAAC,IAAI,SAAS,MAAM,GAAG,MAAM,CAAE,YAAW,WAAW;IAC/E,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC;IACpB,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,KAAK,EAAE,kBAAkB,EAAE,CAAM;IAC1C,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA+B;gBAE3C,OAAO,EAAE,sBAAsB,CAAC,IAAI,CAAC;IAM3C,SAAS,CAAC,OAAO,EAAE,kBAAkB,GAAG,OAAO,CAAC,eAAe,CAAC;CAgBvE"}
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Deterministic {@link Transformer} for tests — the transformer counterpart of
3
+ * `FakeImageProcessor`. It records every context it is called with and writes/declares exactly
4
+ * what it was configured to, so eager/deferred behaviour, artifact bookkeeping and rollback can be
5
+ * asserted without a media engine.
6
+ */
7
+ export class FakeTransformer {
8
+ name;
9
+ eager;
10
+ calls = [];
11
+ options;
12
+ constructor(options) {
13
+ this.name = options.name;
14
+ this.eager = options.eager ?? false;
15
+ this.options = options;
16
+ }
17
+ async transform(context) {
18
+ this.calls.push(context);
19
+ if (this.options.behavior)
20
+ return this.options.behavior(context);
21
+ const artifacts = Object.entries(this.options.artifacts ?? {});
22
+ for (const [path, content] of artifacts) {
23
+ await context.write(path, Buffer.from(content, 'utf8'));
24
+ }
25
+ const entry = this.options.entry === null ? undefined : (this.options.entry ?? artifacts[0]?.[0]);
26
+ return {
27
+ ...(entry !== undefined ? { entry } : {}),
28
+ ...(this.options.meta !== undefined ? { meta: this.options.meta } : {}),
29
+ };
30
+ }
31
+ }
32
+ //# sourceMappingURL=fake_transformer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fake_transformer.js","sourceRoot":"","sources":["../../../src/testing/fake_transformer.ts"],"names":[],"mappings":"AAmBA;;;;;GAKG;AACH,MAAM,OAAO,eAAe;IACjB,IAAI,CAAO;IACX,KAAK,CAAU;IACf,KAAK,GAAyB,EAAE,CAAC;IACzB,OAAO,CAA+B;IAEvD,YAAY,OAAqC;QAC/C,IAAI,CAAC,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;QACzB,IAAI,CAAC,KAAK,GAAG,OAAO,CAAC,KAAK,IAAI,KAAK,CAAC;QACpC,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;IACzB,CAAC;IAED,KAAK,CAAC,SAAS,CAAC,OAA2B;QACzC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACzB,IAAI,IAAI,CAAC,OAAO,CAAC,QAAQ;YAAE,OAAO,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;QAEjE,MAAM,SAAS,GAAG,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,IAAI,EAAE,CAAC,CAAC;QAC/D,KAAK,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,IAAI,SAAS,EAAE,CAAC;YACxC,MAAM,OAAO,CAAC,KAAK,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC;QAC1D,CAAC;QAED,MAAM,KAAK,GACT,IAAI,CAAC,OAAO,CAAC,KAAK,KAAK,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,IAAI,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QACtF,OAAO;YACL,GAAG,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACzC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SACxE,CAAC;IACJ,CAAC;CACF"}
@@ -3,4 +3,6 @@ export { InMemoryUploadSessionStore } from './in_memory_upload_session_store.js'
3
3
  export { InMemoryDisk, inMemoryDiskResolver } from './in_memory_disk.js';
4
4
  export type { DiskVisibility } from './in_memory_disk.js';
5
5
  export { FakeImageProcessor } from './fake_image_processor.js';
6
+ export { FakeTransformer } from './fake_transformer.js';
7
+ export type { FakeTransformerOptions } from './fake_transformer.js';
6
8
  //# 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,0BAA0B,EAAE,MAAM,qCAAqC,CAAC;AACjF,OAAO,EAAE,YAAY,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AACzE,YAAY,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAC1D,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,YAAY,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAC1D,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,YAAY,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC"}
@@ -2,4 +2,5 @@ export { InMemoryMediaStore } from './in_memory_media_store.js';
2
2
  export { InMemoryUploadSessionStore } from './in_memory_upload_session_store.js';
3
3
  export { InMemoryDisk, inMemoryDiskResolver } from './in_memory_disk.js';
4
4
  export { FakeImageProcessor } from './fake_image_processor.js';
5
+ export { FakeTransformer } from './fake_transformer.js';
5
6
  //# 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,0BAA0B,EAAE,MAAM,qCAAqC,CAAC;AACjF,OAAO,EAAE,YAAY,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAEzE,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;AAEzE,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC"}
@@ -0,0 +1,111 @@
1
+ import type { Readable } from 'node:stream';
2
+ import type { MediaRecord } from './media_record.js';
3
+ import type { StorageManager } from './storage_manager.js';
4
+ import type { Disk } from './types.js';
5
+ /**
6
+ * Options for {@link TransformerContext.write}. `contentLength` matters when `contents` is a
7
+ * `Readable` on a disk that streams (S3 needs the length up front); it is ignored for byte payloads.
8
+ */
9
+ export interface TransformerWriteOptions {
10
+ contentType?: string;
11
+ contentLength?: number;
12
+ }
13
+ /**
14
+ * Everything a {@link Transformer} gets to work with: the record being transformed, read access to
15
+ * its original bytes, and a sandboxed writer for the derived artifacts.
16
+ *
17
+ * The context — not the transformer — decides WHERE artifacts live: every {@link write} lands under
18
+ * {@link outputPrefix} (`<owner>/<id>/conversions/<name>/`), and the library tracks each written
19
+ * path so it can persist the artifact list on the record and delete every artifact when the media
20
+ * is deleted. A transformer never touches disk keys outside its prefix.
21
+ */
22
+ export interface TransformerContext {
23
+ /** The media record whose content is being transformed. */
24
+ record: MediaRecord;
25
+ /** The disk holding the original object (and receiving the artifacts). */
26
+ disk: Disk;
27
+ /** Name of {@link disk}, as resolvable through the storage manager. */
28
+ diskName: string;
29
+ /**
30
+ * The storage façade, for reads OUTSIDE the record's own disk — auxiliary assets a transformer
31
+ * was configured with (a watermark logo on another disk, a font, a sidecar file). Artifact
32
+ * writes still go through {@link write}, never directly through a disk.
33
+ */
34
+ storage: StorageManager;
35
+ /** Buffer the original's bytes. Convenient for small originals; prefer {@link getStream} for video. */
36
+ getBytes(): Promise<Uint8Array>;
37
+ /** Stream the original without buffering it. */
38
+ getStream(): Promise<Readable>;
39
+ /**
40
+ * Storage prefix (ending in `/`) reserved for this transformation's artifacts:
41
+ * `<ownerType>/<ownerId>/<collection>/<mediaId>/conversions/<transformerName>/`.
42
+ */
43
+ outputPrefix: string;
44
+ /**
45
+ * Write one artifact at `outputPrefix + relativePath`. The path is validated (no `..`, no
46
+ * absolute paths) and recorded — the persisted conversion lists every written artifact, which is
47
+ * what makes multi-file outputs (an HLS package) deletable and servable file-by-file.
48
+ *
49
+ * A `Readable` with a known `contentLength` streams straight to the disk; anything else is
50
+ * buffered.
51
+ */
52
+ write(relativePath: string, contents: Uint8Array | Readable, options?: TransformerWriteOptions): Promise<void>;
53
+ }
54
+ /**
55
+ * What a {@link Transformer.transform} run reports back. The artifacts themselves were already
56
+ * written through {@link TransformerContext.write}; this names which of them is the entry point and
57
+ * attaches free-form metadata.
58
+ */
59
+ export interface TransformResult {
60
+ /**
61
+ * The entry-point artifact, relative to {@link TransformerContext.outputPrefix} — what
62
+ * `url(id, name)` / `deliver(id, { conversion: name })` resolve for this conversion. Required
63
+ * when any artifact was written (and must be one of them); omit it for a metadata-only
64
+ * transform (a probe, a blurhash) that wrote nothing.
65
+ */
66
+ entry?: string;
67
+ /**
68
+ * Transformer-specific metadata persisted verbatim on the conversion entry
69
+ * (`record.conversions[name].meta`): duration, resolution, codecs, a blurhash string — whatever
70
+ * the transformer learned. Must be JSON-serializable (the Lucid store serializes it).
71
+ */
72
+ meta?: Record<string, unknown>;
73
+ }
74
+ /**
75
+ * A pluggable content transformation: takes a stored media's content and produces derived
76
+ * artifacts on the disk and/or metadata on the record, persisted as a named conversion
77
+ * (`record.conversions[transformer.name]`).
78
+ *
79
+ * This is the seam the library's own {@link HlsTransformer} and {@link MetadataProbeTransformer}
80
+ * implement, and the one you implement for your own derivations — extract an audio track,
81
+ * stamp a watermark, generate a poster frame, request a transcription. The shapes it supports:
82
+ *
83
+ * - **many artifacts** — an HLS package (segments + playlists); `entry` names the master playlist.
84
+ * - **one artifact** — an optimized image, an extracted audio file; `entry` names it.
85
+ * - **no artifact** — a metadata probe or perceptual hash; return only `meta`.
86
+ * - **auxiliary inputs** — configure them on your transformer instance (bytes, a path, a media id)
87
+ * and read foreign disks through {@link TransformerContext.storage}.
88
+ *
89
+ * Registered per collection (`collections: [{ name, transformers: [...] }]`). Set `eager: true`
90
+ * only for cheap transforms — they run synchronously inside `attach`/`attachExisting` (and so
91
+ * inside a TUS finalize), and a failure rolls the new media back. Heavy transforms (video!) stay
92
+ * deferred: the app triggers them from its own job via `media.library.transform(id, name)`,
93
+ * which is idempotent — already generated ⇒ skip.
94
+ *
95
+ * Import heavy engines lazily INSIDE `transform` (the built-ins import `mediabunny` there), so
96
+ * configuring a transformer never loads its optional peer at boot. A transformer that needs a
97
+ * runtime capability the host lacks (e.g. WebCodecs for re-encoding) should throw
98
+ * {@link TransformerRuntimeMissingError} with a clear hint rather than failing obscurely.
99
+ */
100
+ export interface Transformer {
101
+ /** Unique conversion name this transformer produces (the key in `record.conversions`). */
102
+ readonly name: string;
103
+ /**
104
+ * Run synchronously on attach (like an eager image conversion) instead of waiting for an
105
+ * explicit `transform()` call. Default `false` — transformations are assumed heavy.
106
+ */
107
+ readonly eager?: boolean;
108
+ /** Produce the derived artifacts/metadata for one media record. */
109
+ transform(context: TransformerContext): Promise<TransformResult>;
110
+ }
111
+ //# sourceMappingURL=transformer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transformer.d.ts","sourceRoot":"","sources":["../../src/transformer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAEvC;;;GAGG;AACH,MAAM,WAAW,uBAAuB;IACtC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED;;;;;;;;GAQG;AACH,MAAM,WAAW,kBAAkB;IACjC,2DAA2D;IAC3D,MAAM,EAAE,WAAW,CAAC;IACpB,0EAA0E;IAC1E,IAAI,EAAE,IAAI,CAAC;IACX,uEAAuE;IACvE,QAAQ,EAAE,MAAM,CAAC;IACjB;;;;OAIG;IACH,OAAO,EAAE,cAAc,CAAC;IACxB,uGAAuG;IACvG,QAAQ,IAAI,OAAO,CAAC,UAAU,CAAC,CAAC;IAChC,gDAAgD;IAChD,SAAS,IAAI,OAAO,CAAC,QAAQ,CAAC,CAAC;IAC/B;;;OAGG;IACH,YAAY,EAAE,MAAM,CAAC;IACrB;;;;;;;OAOG;IACH,KAAK,CACH,YAAY,EAAE,MAAM,EACpB,QAAQ,EAAE,UAAU,GAAG,QAAQ,EAC/B,OAAO,CAAC,EAAE,uBAAuB,GAChC,OAAO,CAAC,IAAI,CAAC,CAAC;CAClB;AAED;;;;GAIG;AACH,MAAM,WAAW,eAAe;IAC9B;;;;;OAKG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;;OAIG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAChC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,MAAM,WAAW,WAAW;IAC1B,0FAA0F;IAC1F,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB;;;OAGG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC;IACzB,mEAAmE;IACnE,SAAS,CAAC,OAAO,EAAE,kBAAkB,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC;CAClE"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=transformer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transformer.js","sourceRoot":"","sources":["../../src/transformer.ts"],"names":[],"mappings":""}
@@ -0,0 +1,30 @@
1
+ import { HlsTransformer, type HlsTransformerOptions } from './hls.js';
2
+ import { MetadataProbeTransformer, type MetadataProbeTransformerOptions } from './probe.js';
3
+ /**
4
+ * The transformer factory namespace used in `config/media.ts` — the {@link Transformer}
5
+ * counterpart of `processors`/`disks`/`stores`:
6
+ *
7
+ * ```ts
8
+ * import { defineConfig, transformers } from '@adonis-agora/media'
9
+ *
10
+ * export default defineConfig({
11
+ * collections: [
12
+ * {
13
+ * name: 'videos',
14
+ * acceptsMimeTypes: ['video/mp4'],
15
+ * transformers: [transformers.hls({ targetDuration: 4 }), transformers.probe()],
16
+ * },
17
+ * ],
18
+ * })
19
+ * ```
20
+ *
21
+ * Constructing a transformer here never loads its engine — the optional `mediabunny` peer is
22
+ * imported inside the first `transform()` call, so config stays side-effect-free.
23
+ */
24
+ export declare const transformers: {
25
+ /** Video → HLS package (MPEG-TS segments + playlists) via mediabunny. Default name `'hls'`. */
26
+ hls<Name extends string = "hls">(options?: HlsTransformerOptions<Name>): HlsTransformer<Name>;
27
+ /** Metadata-only probe (duration/resolution/codecs) via mediabunny. Default name `'probe'`. */
28
+ probe<Name extends string = "probe">(options?: MetadataProbeTransformerOptions<Name>): MetadataProbeTransformer<Name>;
29
+ };
30
+ //# sourceMappingURL=factory.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../../../src/transformers/factory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,KAAK,qBAAqB,EAAE,MAAM,UAAU,CAAC;AACtE,OAAO,EAAE,wBAAwB,EAAE,KAAK,+BAA+B,EAAE,MAAM,YAAY,CAAC;AAE5F;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,eAAO,MAAM,YAAY;IACvB,+FAA+F;QAC3F,IAAI,SAAS,MAAM,oBAAmB,qBAAqB,CAAC,IAAI,CAAC;IAGrE,+FAA+F;UACzF,IAAI,SAAS,MAAM,sBAAqB,+BAA+B,CAAC,IAAI,CAAC;CAGpF,CAAC"}
@@ -0,0 +1,34 @@
1
+ import { HlsTransformer } from './hls.js';
2
+ import { MetadataProbeTransformer } from './probe.js';
3
+ /**
4
+ * The transformer factory namespace used in `config/media.ts` — the {@link Transformer}
5
+ * counterpart of `processors`/`disks`/`stores`:
6
+ *
7
+ * ```ts
8
+ * import { defineConfig, transformers } from '@adonis-agora/media'
9
+ *
10
+ * export default defineConfig({
11
+ * collections: [
12
+ * {
13
+ * name: 'videos',
14
+ * acceptsMimeTypes: ['video/mp4'],
15
+ * transformers: [transformers.hls({ targetDuration: 4 }), transformers.probe()],
16
+ * },
17
+ * ],
18
+ * })
19
+ * ```
20
+ *
21
+ * Constructing a transformer here never loads its engine — the optional `mediabunny` peer is
22
+ * imported inside the first `transform()` call, so config stays side-effect-free.
23
+ */
24
+ export const transformers = {
25
+ /** Video → HLS package (MPEG-TS segments + playlists) via mediabunny. Default name `'hls'`. */
26
+ hls(options = {}) {
27
+ return new HlsTransformer(options);
28
+ },
29
+ /** Metadata-only probe (duration/resolution/codecs) via mediabunny. Default name `'probe'`. */
30
+ probe(options = {}) {
31
+ return new MetadataProbeTransformer(options);
32
+ },
33
+ };
34
+ //# sourceMappingURL=factory.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"factory.js","sourceRoot":"","sources":["../../../src/transformers/factory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAA8B,MAAM,UAAU,CAAC;AACtE,OAAO,EAAE,wBAAwB,EAAwC,MAAM,YAAY,CAAC;AAE5F;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG;IAC1B,+FAA+F;IAC/F,GAAG,CAA8B,UAAuC,EAAE;QACxE,OAAO,IAAI,cAAc,CAAC,OAAO,CAAC,CAAC;IACrC,CAAC;IACD,+FAA+F;IAC/F,KAAK,CAAgC,UAAiD,EAAE;QACtF,OAAO,IAAI,wBAAwB,CAAC,OAAO,CAAC,CAAC;IAC/C,CAAC;CACF,CAAC"}
@@ -0,0 +1,110 @@
1
+ import type { TransformResult, Transformer, TransformerContext } from '../transformer.js';
2
+ /**
3
+ * Lazily supplies a WebCodecs implementation (`{ VideoEncoder, VideoDecoder, AudioEncoder, … }`).
4
+ * Node has no built-in WebCodecs, which is exactly why the HLS transformer is remux-only by
5
+ * default — but NAPI-based implementations exist (e.g. `@napi-rs/webcodecs`), and injecting one
6
+ * unlocks the re-encode fallback for sources whose codecs cannot be stream-copied:
7
+ *
8
+ * ```ts
9
+ * transformers.hls({ webcodecs: () => import('@napi-rs/webcodecs') })
10
+ * ```
11
+ *
12
+ * The engine installs the provided classes onto `globalThis` (only the ones missing — a native
13
+ * implementation is never overwritten), because that is where the underlying media engine looks
14
+ * the API up.
15
+ */
16
+ export type WebCodecsProvider = () => Promise<Record<string, unknown>>;
17
+ /** How a runtime can satisfy the WebCodecs requirement. See {@link resolveWebCodecsSupport}. */
18
+ export type WebCodecsSupport = 'native' | 'injected' | 'absent';
19
+ /**
20
+ * Detect how (whether) WebCodecs is available: `'native'` when the runtime already exposes
21
+ * `VideoEncoder`, `'injected'` when a {@link WebCodecsProvider} supplies one, `'absent'` otherwise.
22
+ * `'absent'` means encoding is impossible — transforms stay stream-copy only, and a transformer
23
+ * that cannot proceed without an encoder should throw `TransformerRuntimeMissingError`.
24
+ */
25
+ export declare function resolveWebCodecsSupport(provider?: WebCodecsProvider): Promise<WebCodecsSupport>;
26
+ /** What {@link HlsRemuxEngine.remux} receives. */
27
+ export interface HlsRemuxRequest {
28
+ /** Local path of the source file. */
29
+ sourcePath: string;
30
+ /** Local directory the engine writes the whole package into (entry playlist at its root). */
31
+ outputDir: string;
32
+ /** File name of the entry (master) playlist, e.g. `index.m3u8`. */
33
+ entryName: string;
34
+ /** Target (max) segment duration in seconds. */
35
+ targetDuration: number;
36
+ /** Optional WebCodecs implementation enabling the re-encode fallback. */
37
+ webcodecs?: WebCodecsProvider | undefined;
38
+ }
39
+ /** What the engine learned about the source while remuxing — persisted into the conversion `meta`. */
40
+ export interface HlsRemuxSummary {
41
+ durationSeconds?: number;
42
+ width?: number;
43
+ height?: number;
44
+ videoCodec?: string | null;
45
+ audioCodec?: string | null;
46
+ }
47
+ /**
48
+ * The engine seam of {@link HlsTransformer}: local file in, HLS package (playlists + segments) in
49
+ * a local directory out. The default engine is mediabunny, loaded lazily on first transform; tests
50
+ * inject a fake that writes files, so every bit of orchestration around the engine is testable
51
+ * without the optional peer.
52
+ */
53
+ export interface HlsRemuxEngine {
54
+ remux(request: HlsRemuxRequest): Promise<HlsRemuxSummary>;
55
+ }
56
+ export interface HlsTransformerOptions<Name extends string = 'hls'> {
57
+ /** Conversion name on the record. Default `'hls'`. */
58
+ name?: Name;
59
+ /**
60
+ * Run inside attach. Default `false`, and think twice: a remux takes real time, and an eager
61
+ * failure rolls the attach back. The intended flow is deferred —
62
+ * `media.library.transform(id, 'hls')` from a job.
63
+ */
64
+ eager?: boolean;
65
+ /** Target (max) segment duration in seconds. Default 4. */
66
+ targetDuration?: number;
67
+ /** WebCodecs implementation for the re-encode fallback (see {@link WebCodecsProvider}). */
68
+ webcodecs?: WebCodecsProvider;
69
+ /** Replace the mediabunny engine (mainly for tests). */
70
+ engine?: HlsRemuxEngine;
71
+ }
72
+ /** File name of the entry (master) playlist an {@link HlsTransformer} produces. */
73
+ export declare const HLS_ENTRY_PLAYLIST = "index.m3u8";
74
+ /**
75
+ * The built-in video {@link Transformer}: converts a stored video into an HLS package — MPEG-TS
76
+ * segments plus media playlists behind one master playlist — written under the conversion prefix
77
+ * and persisted as `record.conversions['hls']` with duration/resolution/codec metadata.
78
+ *
79
+ * **Remux-only by default.** The engine (mediabunny, pure JS — no ffmpeg binary) stream-copies
80
+ * the source's h264/aac tracks into segments without re-encoding, because encoding needs
81
+ * WebCodecs, which Node does not provide. Two consequences, both deliberate:
82
+ *
83
+ * - a source whose codecs MPEG-TS cannot carry (vp9, av1…) fails with a clear, definitive
84
+ * `HlsSourceUnsupportedError` — unless a {@link WebCodecsProvider} is configured, which enables
85
+ * the engine's re-encode fallback;
86
+ * - the package has a single variant at the original resolution. Multi-quality renditions are the
87
+ * documented evolution once an encoder is present (mediabunny supports fan-out video options),
88
+ * not something this transformer fakes today.
89
+ *
90
+ * The engine also carries the subtle bit the naive implementation gets wrong: AAC audio with
91
+ * priming (an mp4 edit list) starts at a **negative** timestamp, and a conversion trimmed at t=0
92
+ * would kick that track off the stream-copy fast path — impossible without an encoder. The
93
+ * conversion is therefore trimmed at the source's real first timestamp, shifting all tracks
94
+ * equally (sync is unchanged) and keeping every track copyable.
95
+ *
96
+ * Serving the result is the other half: playlists are stored with storage-relative references and
97
+ * must be rewritten per request — see {@link HlsDeliveryHandler}.
98
+ */
99
+ export declare class HlsTransformer<Name extends string = 'hls'> implements Transformer {
100
+ readonly name: Name;
101
+ readonly eager: boolean;
102
+ private readonly targetDuration;
103
+ private readonly webcodecs;
104
+ private readonly engine;
105
+ constructor(options?: HlsTransformerOptions<Name>);
106
+ transform(context: TransformerContext): Promise<TransformResult>;
107
+ }
108
+ /** Drop `undefined` values so the persisted meta round-trips identically through JSON stores. */
109
+ export declare function compactMeta(meta: Record<string, unknown>): Record<string, unknown>;
110
+ //# sourceMappingURL=hls.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hls.d.ts","sourceRoot":"","sources":["../../../src/transformers/hls.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,eAAe,EAAE,WAAW,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAI1F;;;;;;;;;;;;;GAaG;AACH,MAAM,MAAM,iBAAiB,GAAG,MAAM,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;AAEvE,gGAAgG;AAChG,MAAM,MAAM,gBAAgB,GAAG,QAAQ,GAAG,UAAU,GAAG,QAAQ,CAAC;AAEhE;;;;;GAKG;AACH,wBAAsB,uBAAuB,CAC3C,QAAQ,CAAC,EAAE,iBAAiB,GAC3B,OAAO,CAAC,gBAAgB,CAAC,CAI3B;AAED,kDAAkD;AAClD,MAAM,WAAW,eAAe;IAC9B,qCAAqC;IACrC,UAAU,EAAE,MAAM,CAAC;IACnB,6FAA6F;IAC7F,SAAS,EAAE,MAAM,CAAC;IAClB,mEAAmE;IACnE,SAAS,EAAE,MAAM,CAAC;IAClB,gDAAgD;IAChD,cAAc,EAAE,MAAM,CAAC;IACvB,yEAAyE;IACzE,SAAS,CAAC,EAAE,iBAAiB,GAAG,SAAS,CAAC;CAC3C;AAED,sGAAsG;AACtG,MAAM,WAAW,eAAe;IAC9B,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B;AAED;;;;;GAKG;AACH,MAAM,WAAW,cAAc;IAC7B,KAAK,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC;CAC3D;AAED,MAAM,WAAW,qBAAqB,CAAC,IAAI,SAAS,MAAM,GAAG,KAAK;IAChE,sDAAsD;IACtD,IAAI,CAAC,EAAE,IAAI,CAAC;IACZ;;;;OAIG;IACH,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,2DAA2D;IAC3D,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,2FAA2F;IAC3F,SAAS,CAAC,EAAE,iBAAiB,CAAC;IAC9B,wDAAwD;IACxD,MAAM,CAAC,EAAE,cAAc,CAAC;CACzB;AAED,mFAAmF;AACnF,eAAO,MAAM,kBAAkB,eAAe,CAAC;AAE/C;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,qBAAa,cAAc,CAAC,IAAI,SAAS,MAAM,GAAG,KAAK,CAAE,YAAW,WAAW;IAC7E,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC;IACpB,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IACxB,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAS;IACxC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAgC;IAC1D,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA6B;gBAExC,OAAO,GAAE,qBAAqB,CAAC,IAAI,CAAM;IAQ/C,SAAS,CAAC,OAAO,EAAE,kBAAkB,GAAG,OAAO,CAAC,eAAe,CAAC;CA8CvE;AAED,iGAAiG;AACjG,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAElF"}