@mevdragon/vidfarm-devcli 0.2.3 → 0.2.5

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/README.md CHANGED
@@ -51,7 +51,7 @@ The local CLI runs the same template contract used by the hosted platform, but w
51
51
 
52
52
  Use `vidfarm session` to print reusable auth headers and a sample `curl` request for the local REST API.
53
53
 
54
- For hosted preview-media uploads, use `vidfarm-devcli presign-preview-media`. It calls the authenticated Vidfarm API with `VIDFARM_API_KEY` and returns a presigned PUT URL under `developer/<user_id>/preview_media/*` plus the resulting Vidfarm media URL.
54
+ For hosted preview-media uploads, use `vidfarm-devcli presign-preview-media`. It calls the authenticated Vidfarm API with `VIDFARM_API_KEY`, mints a presigned PUT URL under `developer/<user_id>/*`, stores each uploaded file under a UUID path segment while preserving the original filename, uploads the file automatically when `--file` is provided, and returns a public-read media URL for the uploaded object.
55
55
 
56
56
  ## What The Hosted Platform Expects From Templates
57
57
 
@@ -221,7 +221,7 @@ drafts/
221
221
 
222
222
  This is the preferred handoff shape for agent-driven template creation. A Vidfarm developer should be able to drag media into `drafts/preview/`, add rough notes to `drafts/source_notes.md`, then tell the agent to create a template from those relative paths.
223
223
 
224
- If the source media is not already present in the repo, upload it into the authenticated developer preview-media namespace first instead of inventing ad hoc external hosting. Use:
224
+ If the source media is not already present in the repo, upload it into the authenticated developer storage namespace first instead of inventing ad hoc external hosting. An agent can take a developer-provided local file path and run this directly:
225
225
 
226
226
  ```bash
227
227
  npx @mevdragon/vidfarm-devcli presign-preview-media \
@@ -229,7 +229,7 @@ npx @mevdragon/vidfarm-devcli presign-preview-media \
229
229
  --directory drafts/preview
230
230
  ```
231
231
 
232
- That command calls the hosted Vidfarm API with the user's `VIDFARM_API_KEY`, mints a presigned PUT URL scoped under `developer/<user_id>/preview_media/*`, and returns both the `storage_key` and a Vidfarm `preview_media_url`. Agents should prefer that path for hosted preview uploads.
232
+ That command calls the hosted Vidfarm API with the user's `VIDFARM_API_KEY`, mints a presigned PUT URL scoped under `developer/<user_id>/*`, stores each uploaded file under a UUID path segment while preserving the original filename, uploads the file automatically when `--file` is provided, and returns both the `storage_key` and a public-read `preview_media_url`. Objects under `developer/<user_id>/*` may be read directly by URL but should not be treated as listable or writable without authenticated API access. Agents should prefer that path for hosted preview uploads whenever the input is a local media file path.
233
233
 
234
234
  ### 2. Start local runtime
235
235
 
package/dist/src/app.js CHANGED
@@ -1,3 +1,4 @@
1
+ import { randomUUID } from "node:crypto";
1
2
  import { readFileSync, statSync } from "node:fs";
2
3
  import path from "node:path";
3
4
  import { Hono } from "hono";
@@ -979,17 +980,19 @@ app.post(`${USER_PREFIX}/me/developer/preview-media/presign`, async (c) => {
979
980
  return c.json({ error: `Unsupported preview media type: ${fileName}` }, 400);
980
981
  }
981
982
  const directory = sanitizeStorageSubpath(body.directory);
982
- const storageKey = storage.developerPreviewMediaKey(customer.id, directory, createId("preview"), fileName);
983
+ const storageKey = storage.developerScopedKey(customer.id, directory, randomUUID(), fileName);
983
984
  const upload = await storage.createWriteUrl(storageKey, {
984
985
  contentType,
985
- publicRead: false,
986
+ publicRead: true,
986
987
  expiresIn: 3600
987
988
  });
989
+ const publicUrl = storage.getPublicUrl(storageKey) ?? buildAbsoluteUrl(c, `/template-media?key=${encodeURIComponent(storageKey)}`);
988
990
  return c.json({
989
991
  file_name: fileName,
990
992
  content_type: contentType,
991
993
  storage_key: storageKey,
992
- preview_media_url: buildAbsoluteUrl(c, `/template-media?key=${encodeURIComponent(storageKey)}`),
994
+ preview_media_url: publicUrl,
995
+ public_url: publicUrl,
993
996
  upload: {
994
997
  method: upload.method,
995
998
  url: upload.url,
package/dist/src/cli.js CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { cpSync, existsSync, mkdirSync, mkdtempSync, readFileSync, readdirSync, rmSync, writeFileSync } from "node:fs";
2
+ import { cpSync, existsSync, mkdirSync, mkdtempSync, readFileSync, readdirSync, rmSync, statSync, writeFileSync } from "node:fs";
3
3
  import { execFile } from "node:child_process";
4
4
  import { randomUUID } from "node:crypto";
5
5
  import os from "node:os";
@@ -516,6 +516,25 @@ async function runPresignPreviewMediaCommand(argv) {
516
516
  if (!response.ok) {
517
517
  throw new Error(typeof payload.error === "string" ? payload.error : `Preview-media presign failed with ${response.status}.`);
518
518
  }
519
+ let uploadResult = null;
520
+ if (filePath) {
521
+ const body = readFileSync(filePath);
522
+ const uploadResponse = await fetch(String(payload.upload?.url), {
523
+ method: String(payload.upload?.method ?? "PUT"),
524
+ headers: payload.upload?.headers,
525
+ body
526
+ });
527
+ if (!uploadResponse.ok) {
528
+ const errorText = await uploadResponse.text().catch(() => "");
529
+ throw new Error(`Preview-media upload failed with ${uploadResponse.status}${errorText ? `: ${errorText}` : "."}`);
530
+ }
531
+ uploadResult = {
532
+ uploaded: true,
533
+ size_bytes: statSync(filePath).size,
534
+ method: payload.upload?.method ?? "PUT",
535
+ status: uploadResponse.status
536
+ };
537
+ }
519
538
  console.log(JSON.stringify({
520
539
  base_url: baseUrl,
521
540
  file_path: filePath,
@@ -523,6 +542,8 @@ async function runPresignPreviewMediaCommand(argv) {
523
542
  content_type: payload.content_type,
524
543
  storage_key: payload.storage_key,
525
544
  preview_media_url: payload.preview_media_url,
545
+ public_url: payload.public_url ?? payload.preview_media_url,
546
+ upload_result: uploadResult,
526
547
  upload: payload.upload,
527
548
  curl_upload_example: [
528
549
  `curl -X ${payload.upload.method} '${payload.upload.url}' \\`,
@@ -20,8 +20,8 @@ export class StorageService {
20
20
  developerAttachmentKey(customerId, attachmentId, fileName) {
21
21
  return joinStorageKey("developer", customerId, "attachments", attachmentId, fileName);
22
22
  }
23
- developerPreviewMediaKey(customerId, ...parts) {
24
- return joinStorageKey("developer", customerId, "preview_media", ...parts);
23
+ developerScopedKey(customerId, ...parts) {
24
+ return joinStorageKey("developer", customerId, ...parts);
25
25
  }
26
26
  templateJobPrefix(templateId, customerId, jobId) {
27
27
  return joinStorageKey("templates", templateId, "users", customerId, "jobs", jobId);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mevdragon/vidfarm-devcli",
3
- "version": "0.2.3",
3
+ "version": "0.2.5",
4
4
  "description": "Developer CLI for running the Vidfarm local template platform.",
5
5
  "type": "module",
6
6
  "bin": {