0

Update File

by
Published today

Rename a file, change its description, or replace its content from Windmill object storage.

Script gdrive Verified

The script

Submitted by hugo989 Bun
Verified 1 hour ago
1
import * as wmill from "windmill-client"
2
import { S3Object } from "windmill-client"
3

4
/**
5
 * Update File
6
 * Rename a file, change its description, and/or replace its content with a file from Windmill object storage (a new revision; any size, resumable upload). Leave a field empty to keep it unchanged. Google Docs/Sheets/Slides can't take raw content; replace those by uploading a new file.
7
 */
8
export async function main(
9
  auth: RT.Gdrive,
10
  file_id: string,
11
  name: string | undefined,
12
  description: string | undefined,
13
  file: S3Object | undefined,
14
  mime_type: string | undefined
15
) {
16
  const metadata: { [key: string]: any } = {}
17
  if (name) metadata.name = name
18
  if (description) metadata.description = description
19

20
  const headers = { Authorization: `Bearer ${auth.token}` }
21

22
  if (!file?.s3) {
23
    const url = new URL(`https://www.googleapis.com/drive/v3/files/${file_id}`)
24
    url.searchParams.append("supportsAllDrives", "true")
25
    url.searchParams.append("fields", "*")
26
    const response = await fetch(url, {
27
      method: "PATCH",
28
      headers: {
29
        ...headers,
30
        "Content-Type": "application/json",
31
        Accept: "application/json",
32
      },
33
      body: JSON.stringify(metadata),
34
    })
35
    if (!response.ok) {
36
      throw new Error(`${response.status} ${await response.text()}`)
37
    }
38
    return await response.json()
39
  }
40

41
  const bytes = await wmill.loadS3File(file)
42
  if (!bytes) {
43
    throw new Error("Could not load the file from object storage")
44
  }
45

46
  // 1. Open a resumable session carrying the metadata changes
47
  const url = new URL(
48
    `https://www.googleapis.com/upload/drive/v3/files/${file_id}`
49
  )
50
  url.searchParams.append("uploadType", "resumable")
51
  url.searchParams.append("supportsAllDrives", "true")
52
  url.searchParams.append("fields", "*")
53
  const session = await fetch(url, {
54
    method: "PATCH",
55
    headers: {
56
      ...headers,
57
      "Content-Type": "application/json; charset=UTF-8",
58
      ...(mime_type ? { "X-Upload-Content-Type": mime_type } : {}),
59
    },
60
    body: JSON.stringify(metadata),
61
  })
62
  if (!session.ok) {
63
    throw new Error(`${session.status} ${await session.text()}`)
64
  }
65

66
  // 2. Send the new bytes to the session URI
67
  const response = await fetch(session.headers.get("Location")!, {
68
    method: "PUT",
69
    headers: {
70
      ...headers,
71
      ...(mime_type ? { "Content-Type": mime_type } : {}),
72
    },
73
    body: bytes,
74
  })
75

76
  if (!response.ok) {
77
    throw new Error(`${response.status} ${await response.text()}`)
78
  }
79

80
  return await response.json()
81
}
82