Path from Fileid
One script reply has been approved by the moderators Verified

Gets the path of a file from its fileid

Created by nextcloud 7 days ago
Submitted by nextcloud Bun
Verified 7 days ago
1
import { createClient } from "webdav";
2

3
/**
4
 * Resolves a Nextcloud file path from its fileid.
5
 */
6
export async function main(
7
  ncResource: RT.Nextcloud,
8
  fileid: string
9
): Promise<string> {
10

11
  const baseUrl = ncResource.baseUrl;
12
  const davBaseUrl = `${baseUrl}/remote.php/dav`;
13
  const client = createClient(davBaseUrl, {
14
    username: ncResource.userId,
15
    password: ncResource.token,
16
  });
17

18
  const searchXml = buildSearchRequestXml(ncResource.userId, fileid);
19
  const rawResponse = await client.customRequest("/", {
20
    method: "SEARCH",
21
    data: searchXml,
22
    headers: {
23
      "Content-Type": "text/xml; charset=utf-8",
24
      Accept: "application/xml, text/xml",
25
    },
26
    responseType: "text",
27
  });
28
  const responseXml = await rawResponse.text();
29
  const path = extractPathFromSearchResponse(responseXml, ncResource.userId);
30
  if (!path) {
31
    throw new Error(`Could not resolve path for fileid "${fileid}"`);
32
  }
33

34
  return path;
35
}
36

37
function buildSearchRequestXml(userId: string, fileId: string): string {
38
  return `<?xml version="1.0" encoding="UTF-8"?>
39
<d:searchrequest xmlns:d="DAV:" xmlns:oc="http://owncloud.org/ns">
40
  <d:basicsearch>
41
    <d:select>
42
      <d:prop>
43
        <d:displayname/>
44
        <oc:fileid/>
45
      </d:prop>
46
    </d:select>
47
    <d:from>
48
      <d:scope>
49
        <d:href>/files/${encodeURIComponent(userId)}</d:href>
50
        <d:depth>infinity</d:depth>
51
      </d:scope>
52
    </d:from>
53
    <d:where>
54
      <d:eq>
55
        <d:prop><oc:fileid/></d:prop>
56
        <d:literal>${encodeURIComponent(fileId)}</d:literal>
57
      </d:eq>
58
    </d:where>
59
  </d:basicsearch>
60
</d:searchrequest>`;
61
}
62

63
function extractPathFromSearchResponse(xml: string, userId: string): string | null {
64
  const hrefRegex = /<d:href>(.*?)<\/d:href>/g;
65
  let match: RegExpExecArray | null = null;
66
  while ((match = hrefRegex.exec(xml)) !== null) {
67
    console.log(match[1]);
68
    const href = decodeURIComponent(match[1] || "").trim();
69
    if (!href) continue;
70

71
    // Expected shape: /remote.php/dav/files/{userId}/path/to/file
72
    const marker = `/files/${userId}/`;
73
    const markerIndex = href.indexOf(marker);
74
    if (markerIndex !== -1) {
75
      return `/${href.slice(markerIndex + marker.length)}`;
76
    }
77
  }
78
  return null;
79
}