1 | import * as wmill from "windmill-client" |
2 | import { S3Object } from "windmill-client" |
3 |
|
4 | const graph = "https://graph.microsoft.com/v1.0" |
5 |
|
6 | export type DynSelect_site_id = string |
7 |
|
8 | export async function site_id(auth: RT.MsSharepoint) { |
9 | const response = await fetch( |
10 | `${graph}/sites?search=*&$select=id,displayName,webUrl&$top=200`, |
11 | { |
12 | headers: { |
13 | Authorization: `Bearer ${auth.token}`, |
14 | Accept: "application/json", |
15 | }, |
16 | } |
17 | ) |
18 | if (!response.ok) { |
19 | throw new Error(`${response.status} ${await response.text()}`) |
20 | } |
21 | const { value } = (await response.json()) as { |
22 | value: { id: string; displayName: string; webUrl: string }[] |
23 | } |
24 | return value.map((s) => ({ |
25 | value: s.id, |
26 | label: `${s.displayName} (${s.webUrl})`, |
27 | })) |
28 | } |
29 |
|
30 | export type DynSelect_drive_id = string |
31 |
|
32 | export async function drive_id(auth: RT.MsSharepoint, site_id: string) { |
33 | const response = await fetch( |
34 | `${graph}/sites/${site_id}/drives?$select=id,name`, |
35 | { |
36 | headers: { |
37 | Authorization: `Bearer ${auth.token}`, |
38 | Accept: "application/json", |
39 | }, |
40 | } |
41 | ) |
42 | if (!response.ok) { |
43 | throw new Error(`${response.status} ${await response.text()}`) |
44 | } |
45 | const { value } = (await response.json()) as { |
46 | value: { id: string; name: string }[] |
47 | } |
48 | return value.map((d) => ({ value: d.id, label: d.name })) |
49 | } |
50 |
|
51 | |
52 | function driveUrl(site_id: string, drive_id: string | undefined) { |
53 | return drive_id != null && drive_id !== "" |
54 | ? `${graph}/drives/${encodeURIComponent(drive_id)}` |
55 | : `${graph}/sites/${site_id}/drive` |
56 | } |
57 |
|
58 | |
59 | function ref(item: string | undefined) { |
60 | if (item == null || item === "" || item === "/") return "root" |
61 | if (!item.startsWith("/")) return `items/${encodeURIComponent(item)}` |
62 | const path = item |
63 | .replace(/\/+$/, "") |
64 | .split("/") |
65 | .map(encodeURIComponent) |
66 | .join("/") |
67 | return `root:${path}:` |
68 | } |
69 |
|
70 | |
71 | * Download File |
72 | * Download a file in a site's default document library, or in another of its libraries when `drive_id` is set to Windmill object storage and return its S3 reference. `item` is an id, or a path from the drive root starting with "/" (e.g. `/Reports/2026/summary.xlsx`). `convert_to_pdf` converts Office documents (docx, xlsx, pptx and others) to PDF on the way out. Requires Sites.Read.All (covered by the default Sites.ReadWrite.All). |
73 | */ |
74 | export async function main( |
75 | auth: RT.MsSharepoint, |
76 | site_id: DynSelect_site_id, |
77 | item: string, |
78 | destination: S3Object, |
79 | convert_to_pdf: boolean = false, |
80 | drive_id: DynSelect_drive_id | undefined |
81 | ) { |
82 | const drive = driveUrl(site_id, drive_id) |
83 | const url = new URL(`${drive}/${ref(item)}/content`) |
84 | if (convert_to_pdf) url.searchParams.append("format", "pdf") |
85 |
|
86 | |
87 | const response = await fetch(url, { |
88 | headers: { Authorization: `Bearer ${auth.token}` }, |
89 | }) |
90 |
|
91 | if (!response.ok) { |
92 | throw new Error(`${response.status} ${await response.text()}`) |
93 | } |
94 |
|
95 | await wmill.writeS3File( |
96 | destination, |
97 | response.body as ReadableStream<Uint8Array> |
98 | ) |
99 | return destination |
100 | } |
101 |
|