Skip to content

Commit dbca8fa

Browse files
authored
Merge pull request #170 from opencloud-eu/pick-ext-system-improvements
Pick ext system improvements
2 parents 4021900 + 7600a9b commit dbca8fa

File tree

13 files changed

+106
-34
lines changed

13 files changed

+106
-34
lines changed

packages/extension-sdk/index.mjs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import { readFileSync } from 'fs'
1010
import vue from '@vitejs/plugin-vue'
1111
import serve from 'rollup-plugin-serve'
1212

13-
const distDir = 'dist'
13+
const distDir = process.env.OPENCLOUD_EXTENSION_DIST_DIR || 'dist'
1414

1515
const certsDir = process.env.OPENCLOUD_CERTS_DIR
1616
const defaultHttps = () =>

packages/web-client/src/helpers/resource/functions.ts

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,10 @@ const convertObjectToCamelCaseKeys = (data: Record<string, any>) => {
9292
return converted
9393
}
9494

95-
export function buildResource(resource: WebDavResponseResource): Resource {
95+
export function buildResource(
96+
resource: WebDavResponseResource,
97+
extraPropNames: string[] = []
98+
): Resource {
9699
const name = resource.props[DavProperty.Name]?.toString() || basename(resource.filename)
97100
const id = resource.props[DavProperty.FileId]
98101

@@ -128,6 +131,16 @@ export function buildResource(resource: WebDavResponseResource): Resource {
128131
}
129132
}
130133

134+
const extraProps: Record<string, unknown> = {}
135+
for (const name of extraPropNames || []) {
136+
// only use the tag name, the namespace is ignored by our WebDav library
137+
// https://github.com/perry-mitchell/webdav-client/issues/210
138+
const extraPropName = name.split(':').pop()
139+
if (resource.props[extraPropName]) {
140+
extraProps[name] = resource.props[extraPropName]
141+
}
142+
}
143+
131144
const r = {
132145
id,
133146
fileId: id,
@@ -166,6 +179,7 @@ export function buildResource(resource: WebDavResponseResource): Resource {
166179
location: convertObjectToCamelCaseKeys(resource.props[DavProperty.Location]),
167180
image: convertObjectToCamelCaseKeys(resource.props[DavProperty.Image]),
168181
photo: convertObjectToCamelCaseKeys(resource.props[DavProperty.Photo]),
182+
extraProps,
169183
canUpload: function () {
170184
return this.permissions.indexOf(DavPermission.FolderCreateable) >= 0
171185
},

packages/web-client/src/helpers/resource/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ export interface Resource {
7878
privateLink?: string
7979
owner?: Identity
8080
extension?: string
81+
extraProps?: Record<string, unknown>
8182

8283
// necessary for incoming share resources and resources inside shares
8384
remoteItemId?: string

packages/web-client/src/webdav/client/builders.ts

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,36 @@
11
import { XMLBuilder } from 'fast-xml-parser'
22
import { DavProperties, DavPropertyValue } from '../constants'
33

4-
const getNamespacedDavProps = (obj: Partial<Record<DavPropertyValue, unknown>>) => {
5-
return Object.keys(obj).reduce<Record<string, unknown>>((acc, val) => {
6-
const davNamespace = DavProperties.DavNamespace.includes(val as DavPropertyValue)
7-
acc[davNamespace ? `d:${val}` : `oc:${val}`] = obj[val as DavPropertyValue] || ''
8-
return acc
9-
}, {})
4+
const getNamespacedDavProps = (
5+
obj: Partial<Record<DavPropertyValue, unknown>>,
6+
extraProps: string[]
7+
) => {
8+
return Object.fromEntries(
9+
Object.entries(obj).map(([name, value]) => {
10+
if (extraProps.includes(name)) {
11+
return [name, value || '']
12+
}
13+
14+
const davNamespace = DavProperties.DavNamespace.includes(name as unknown as DavPropertyValue)
15+
const propName = davNamespace ? `d:${name}` : `oc:${name}`
16+
return [propName, value || '']
17+
})
18+
)
1019
}
1120

1221
export const buildPropFindBody = (
1322
properties: DavPropertyValue[] = [],
1423
{
1524
pattern,
1625
filterRules,
17-
limit = 0
26+
limit = 0,
27+
extraProps = []
1828
}: {
1929
pattern?: string
2030
filterRules?: Partial<Record<DavPropertyValue, unknown>>
2131
limit?: number
22-
} = {}
32+
extraProps: string[]
33+
}
2334
): string => {
2435
let bodyType = 'd:propfind'
2536
if (pattern) {
@@ -31,7 +42,7 @@ export const buildPropFindBody = (
3142
}
3243

3344
const object = properties.reduce((obj, item) => Object.assign(obj, { [item]: null }), {})
34-
const props = getNamespacedDavProps(object)
45+
const props = getNamespacedDavProps(object, extraProps)
3546

3647
const xmlObj = {
3748
[bodyType]: {
@@ -42,7 +53,7 @@ export const buildPropFindBody = (
4253
'oc:search': { 'oc:pattern': pattern, 'oc:limit': limit }
4354
}),
4455
...(filterRules && {
45-
'oc:filter-rules': getNamespacedDavProps(filterRules)
56+
'oc:filter-rules': getNamespacedDavProps(filterRules, [])
4657
})
4758
}
4859
}
@@ -62,7 +73,7 @@ export const buildPropPatchBody = (
6273
): string => {
6374
const xmlObj = {
6475
'd:propertyupdate': {
65-
'd:set': { 'd:prop': getNamespacedDavProps(properties) },
76+
'd:set': { 'd:prop': getNamespacedDavProps(properties, []) },
6677
'@@xmlns:d': 'DAV:',
6778
'@@xmlns:oc': 'http://owncloud.org/ns'
6879
}

packages/web-client/src/webdav/client/dav.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,11 +34,13 @@ export class DAV {
3434
private client: WebDAVClient
3535
private davPath: string
3636
private headers: () => Headers
37+
public extraProps: string[]
3738

3839
constructor({ baseUrl, headers }: DAVOptions) {
3940
this.davPath = urlJoin(baseUrl, 'remote.php/dav')
4041
this.client = createClient(this.davPath, {})
4142
this.headers = headers
43+
this.extraProps = []
4244
}
4345

4446
public mkcol(path: string, opts: DAVRequestOptions = {}) {
@@ -57,7 +59,7 @@ export class DAV {
5759
const requestHeaders = { ...headers, Depth: depth.toString() }
5860
const { body, result } = await this.request(path, {
5961
method: DavMethod.propfind,
60-
data: buildPropFindBody(properties),
62+
data: buildPropFindBody(properties, { extraProps: this.extraProps }),
6163
headers: requestHeaders,
6264
...opts
6365
})
@@ -87,7 +89,12 @@ export class DAV {
8789
) {
8890
const { body, result } = await this.request(path, {
8991
method: DavMethod.report,
90-
data: buildPropFindBody(properties, { pattern, filterRules, limit }),
92+
data: buildPropFindBody(properties, {
93+
pattern,
94+
filterRules,
95+
limit,
96+
extraProps: this.extraProps
97+
}),
9198
...opts
9299
})
93100

packages/web-client/src/webdav/index.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,11 @@ export const webdav = (baseURI: string, headers?: () => Headers): WebDAV => {
3737
}
3838

3939
const options = { axiosClient, baseUrl: baseURI, headers }
40+
4041
const dav = new DAV({ baseUrl: baseURI, headers })
42+
const registerExtraProp = (name: string) => {
43+
dav.extraProps.push(name)
44+
}
4145

4246
const pathForFileIdFactory = GetPathForFileIdFactory(dav, options)
4347
const { getPathForFileId } = pathForFileIdFactory
@@ -91,6 +95,8 @@ export const webdav = (baseURI: string, headers?: () => Headers): WebDAV => {
9195
clearTrashBin,
9296
search,
9397
listFavoriteFiles,
94-
setFavorite
98+
setFavorite,
99+
100+
registerExtraProp
95101
}
96102
}

packages/web-client/src/webdav/listFileVersions.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ export const ListFileVersionsFactory = (dav: DAV, options: WebDavOptions) => {
1111
urlJoin('meta', id, 'v', { leadingSlash: true }),
1212
opts
1313
)
14-
return versions.map(buildResource)
14+
return versions.map((v) => buildResource(v, dav.extraProps))
1515
}
1616
}
1717
}

packages/web-client/src/webdav/listFiles.ts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -91,10 +91,10 @@ export const ListFilesFactory = (
9191
driveAlias: space.driveAlias,
9292
webDavPath: space.webDavPath
9393
}),
94-
children: children.map(buildResource)
94+
children: children.map((c) => buildResource(c, dav.extraProps))
9595
} as ListFilesResult
9696
}
97-
const resources = webDavResources.map(buildResource)
97+
const resources = webDavResources.map((r) => buildResource(r, dav.extraProps))
9898
return { resource: resources[0], children: resources.slice(1) } as ListFilesResult
9999
}
100100

@@ -118,11 +118,13 @@ export const ListFilesFactory = (
118118
})
119119
if (isTrash) {
120120
return {
121-
resource: buildResource(webDavResources[0]),
121+
resource: buildResource(webDavResources[0], dav.extraProps),
122122
children: webDavResources.slice(1).map(buildDeletedResource)
123123
} as ListFilesResult
124124
}
125-
const resources = webDavResources.map(buildResource)
125+
126+
const resources = webDavResources.map((r) => buildResource(r, dav.extraProps))
127+
126128
const resourceIsSpace = fileId === space.id
127129
if (fileId && !resourceIsSpace && fileId !== resources[0].fileId) {
128130
return listFilesCorrectedPath()

packages/web-client/src/webdav/search.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ export const SearchFactory = (dav: DAV, options: WebDavOptions) => {
2929

3030
return {
3131
resources: results.map((r) => ({
32-
...buildResource(r),
32+
...buildResource(r, dav.extraProps),
3333
highlights: r.props[DavProperty.Highlights] || ''
3434
})),
3535
totalResults: range ? parseInt(range?.split('/')[1]) : null

packages/web-client/src/webdav/types.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,4 +45,10 @@ export interface WebDAV {
4545
search: ReturnType<typeof SearchFactory>['search']
4646
listFavoriteFiles: ReturnType<typeof ListFavoriteFilesFactory>['listFavoriteFiles']
4747
setFavorite: ReturnType<typeof SetFavoriteFactory>['setFavorite']
48+
49+
// register prop that will be added to resource.extraProps if available in a response
50+
// because of a limitation in our WebDAV library, we cannot differentiate between
51+
// the same tag in two different namespaces. Make sure to use unique tag names despite
52+
// differing namespaces.
53+
registerExtraProp(name: string)
4854
}

0 commit comments

Comments
 (0)