diff --git a/__tests__/files/node.spec.ts b/__tests__/files/node.spec.ts index d7c2fa62..fa2a1d82 100644 --- a/__tests__/files/node.spec.ts +++ b/__tests__/files/node.spec.ts @@ -77,6 +77,51 @@ describe('FileId attribute', () => { }) }) +describe('Id attribute', () => { + test('Id undefined', () => { + const file = new File({ + source: 'https://cloud.domain.com/remote.php/dav/files/emma/picture.jpg', + root: '/files/emma', + mime: 'image/jpeg', + owner: 'emma', + }) + expect(file.id).toBeUndefined() + }) + + test('id definition', () => { + const file = new File({ + source: 'https://cloud.domain.com/remote.php/dav/files/emma/picture.jpg', + root: '/files/emma', + mime: 'image/jpeg', + owner: 'emma', + id: '1234', + }) + expect(file.id).toBe('1234') + }) + + test('Legacy id definition', () => { + const file = new File({ + source: 'https://cloud.domain.com/remote.php/dav/files/emma/picture.jpg', + root: '/files/emma', + mime: 'image/jpeg', + owner: 'emma', + id: 1234, + }) + expect(file.id).toBe('1234') + }) + + test('Legacy failed node id', () => { + const file = new File({ + source: 'https://cloud.domain.com/remote.php/dav/files/emma/picture.jpg', + root: '/files/emma', + mime: 'image/jpeg', + owner: 'emma', + id: -1, + }) + expect(file.id).toBeUndefined() + }) +}) + describe('Mime attribute', () => { test('Mime definition', () => { const file = new File({ @@ -304,7 +349,7 @@ describe('Sanity checks', () => { root: '/files/emma', mime: 'image/jpeg', owner: 'emma', - id: '1234' as unknown as number, + id: true as unknown as number, })).toThrowError('Invalid id type of value') }) diff --git a/lib/node/node.ts b/lib/node/node.ts index cd0246f8..14007333 100644 --- a/lib/node/node.ts +++ b/lib/node/node.ts @@ -287,11 +287,29 @@ export abstract class Node { } /** - * Get the node id if defined. - * There is no setter as the fileid is not meant to be changed + * Get the nodes file id if defined. + * There is no setter as the fileid is not meant to be changed. + * + * @deprecated Nextcloud is migrating to snowflake ids which are strings. Use the `id` attribute instead. */ get fileid(): number | undefined { - return this._data?.id + return typeof this._data?.id === 'number' ? this._data.id : undefined + } + + /** + * Get the nodes id - if defined. + * + * Note: As Nextcloud is migrating to snowflake ids the id has to be a string, + * due to limitations of the JavaScript number type (snowflake ids are 64bit JavaScript numbers can only accurately represent integers up to 53 bit). + */ + get id(): string | undefined { + if (typeof this._data?.id === 'undefined' + || (typeof this._data.id === 'number' && this._data.id < 0)) { + // legacy fileid < 0 means the node failed, this should be communicated via the `status` attribute + // so in that case there is no id available + return undefined + } + return String(this._data.id) } /** diff --git a/lib/node/nodeData.ts b/lib/node/nodeData.ts index dc420c99..d6e5f20f 100644 --- a/lib/node/nodeData.ts +++ b/lib/node/nodeData.ts @@ -37,8 +37,15 @@ export interface NodeData { */ root: string - /** Unique ID */ - id?: number + /** + * Unique ID + * + * This is usually the file id from the backend where this would be a number. + * For some type of nodes this is already a snowflake id and thus as string. + * + * Note: Passing a number is deprecated. + */ + id?: number | string /** Last modified time */ mtime?: Date @@ -91,7 +98,7 @@ export function isDavResource(source: string, davService: RegExp): boolean { * @param davService Pattern to check if source is DAV ressource */ export function validateData(data: NodeData, davService: RegExp) { - if (data.id && typeof data.id !== 'number') { + if (data.id && typeof data.id !== 'number' && typeof data.id !== 'string') { throw new Error('Invalid id type of value') }