Skip to content

Commit

Permalink
feat(FileCollection): Create archive link by file ids with specific page
Browse files Browse the repository at this point in the history
Added `createArchiveLinkByIds` method
and depreciated `getArchiveLinkByIds` method.

The name is more accurate and it allows us to refine
the selection by giving the pages we want for each file.
  • Loading branch information
Merkur39 committed Jun 26, 2024
1 parent b07e2ac commit df94e82
Show file tree
Hide file tree
Showing 3 changed files with 202 additions and 3 deletions.
55 changes: 55 additions & 0 deletions docs/api/cozy-stack-client.md
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,9 @@ Deleted and design docs are filtered by default, thus documents are retrieved in
<dt><a href="#OAuthClient">OAuthClient</a> : <code>object</code></dt>
<dd><p>Document representing a io.cozy.oauth.clients</p>
</dd>
<dt><a href="#ArchivePages">ArchivePages</a> : <code>object</code></dt>
<dd><p>Attributes used for create archive link by ids</p>
</dd>
<dt><a href="#FetchChangesReturnValue">FetchChangesReturnValue</a> ⇒ <code><a href="#FetchChangesReturnValue">FetchChangesReturnValue</a></code></dt>
<dd><p>Use cozy-stack&#39;s _changes API for io.cozy.files
Design docs are filtered by default, thus documents are retrieved in the
Expand Down Expand Up @@ -739,6 +742,9 @@ files associated to a specific document
* [.download(file, versionId, filename)](#FileCollection+download)
* [.fetchFileContentById(id)](#FileCollection+fetchFileContentById)
* [.getBeautifulSize(file, decimal)](#FileCollection+getBeautifulSize)
* [.downloadArchive(fileIds, [notSecureFilename], [options])](#FileCollection+downloadArchive)
* ~~[.getArchiveLinkByIds()](#FileCollection+getArchiveLinkByIds)~~
* [.createArchiveLinkByIds(params)](#FileCollection+createArchiveLinkByIds) ⇒ <code>Promise.&lt;string&gt;</code>
* [.isChildOf(child, parent)](#FileCollection+isChildOf) ⇒ <code>boolean</code>
* [.statById(id, options)](#FileCollection+statById) ⇒ <code>object</code>
* [.createDirectoryByPath(path)](#FileCollection+createDirectoryByPath) ⇒ <code>object</code>
Expand Down Expand Up @@ -1031,6 +1037,42 @@ Get a beautified size for a given file
| file | <code>object</code> | io.cozy.files object |
| decimal | <code>number</code> | number of decimal |

<a name="FileCollection+downloadArchive"></a>

### fileCollection.downloadArchive(fileIds, [notSecureFilename], [options])
Download an archive of the files

**Kind**: instance method of [<code>FileCollection</code>](#FileCollection)

| Param | Type | Description |
| --- | --- | --- |
| fileIds | <code>Array.&lt;string&gt;</code> | List of file ids |
| [notSecureFilename] | <code>string</code> | Name of the archive (default: 'files') |
| [options] | <code>object</code> | Additional options |
| [options.pages] | [<code>Array.&lt;ArchivePages&gt;</code>](#ArchivePages) | Array of objects, with `id` the file identifier, and `page` the page number (1 is the first page) |

<a name="FileCollection+getArchiveLinkByIds"></a>

### ~~fileCollection.getArchiveLinkByIds()~~
***Deprecated***

**Kind**: instance method of [<code>FileCollection</code>](#FileCollection)
<a name="FileCollection+createArchiveLinkByIds"></a>

### fileCollection.createArchiveLinkByIds(params) ⇒ <code>Promise.&lt;string&gt;</code>
Create the archive link for a list of files
The generated archive is temporary and is not persisted

**Kind**: instance method of [<code>FileCollection</code>](#FileCollection)
**Returns**: <code>Promise.&lt;string&gt;</code> - - The archive link

| Param | Type | Description |
| --- | --- | --- |
| params | <code>object</code> | Parameters |
| params.ids | <code>Array.&lt;string&gt;</code> | List of file ids |
| [params.name] | <code>string</code> | Name of the archive (default: 'files') |
| [params.pages] | [<code>Array.&lt;ArchivePages&gt;</code>](#ArchivePages) | Array of objects, with `id` the file identifier, and `page` the page number (1 is the first page) |

<a name="FileCollection+isChildOf"></a>

### fileCollection.isChildOf(child, parent) ⇒ <code>boolean</code>
Expand Down Expand Up @@ -2753,6 +2795,19 @@ If this is the case, call the onRevocationChange callback

**Kind**: instance method of [<code>OAuthClient</code>](#OAuthClient)
**Returns**: <code>Promise.&lt;boolean&gt;</code> - A Promise that resolves to `false` if client is still valid, or `true` if it has been revoked.
<a name="ArchivePages"></a>

## ArchivePages : <code>object</code>
Attributes used for create archive link by ids

**Kind**: global typedef
**Properties**

| Name | Type | Description |
| --- | --- | --- |
| id | <code>string</code> | Id of the file |
| page | <code>number</code> | The page number. PDF files only (1 is the first page) |

<a name="FetchChangesReturnValue"></a>

## FetchChangesReturnValue ⇒ [<code>FetchChangesReturnValue</code>](#FetchChangesReturnValue)
Expand Down
56 changes: 53 additions & 3 deletions packages/cozy-stack-client/src/FileCollection.js
Original file line number Diff line number Diff line change
Expand Up @@ -721,14 +721,40 @@ class FileCollection extends DocumentCollection {
return formatBytes(parseInt(file.size), decimal)
}

async downloadArchive(fileIds, notSecureFilename = 'files') {
const filename = slugify(notSecureFilename)
const href = await this.getArchiveLinkByIds(fileIds, filename)
/**
* Attributes used for create archive link by ids
*
* @typedef {object} ArchivePages
* @property {string} id - Id of the file
* @property {number} page - The page number. PDF files only (1 is the first page)
*/

/**
* Download an archive of the files
*
* @param {string[]} fileIds - List of file ids
* @param {string} [notSecureFilename] - Name of the archive (default: 'files')
* @param {object} [options] - Additional options
* @param {ArchivePages[]} [options.pages] - Array of objects, with `id` the file identifier, and `page` the page number (1 is the first page)
*/
async downloadArchive(fileIds, notSecureFilename, { pages } = {}) {
const filename = notSecureFilename ? slugify(notSecureFilename) : 'files'
const href = await this.createArchiveLinkByIds({
ids: fileIds,
name: filename,
pages
})
const fullpath = this.stackClient.fullpath(href)
this.forceFileDownload(fullpath, filename + '.zip')
}

/**
* @deprecated Use createArchiveLinkByIds instead
*/
async getArchiveLinkByIds(ids, name = 'files') {
logger.warn(
'CozyClient FileCollection getArchiveLinkByIds method is deprecated. Use createArchiveLinkByIds instead'
)
const resp = await this.stackClient.fetchJSON('POST', '/files/archive', {
data: {
type: 'io.cozy.archives',
Expand All @@ -741,6 +767,30 @@ class FileCollection extends DocumentCollection {
return resp.links.related
}

/**
* Create the archive link for a list of files
* The generated archive is temporary and is not persisted
*
* @param {object} params - Parameters
* @param {string[]} params.ids - List of file ids
* @param {string} [params.name] - Name of the archive (default: 'files')
* @param {ArchivePages[]} [params.pages] - Array of objects, with `id` the file identifier, and `page` the page number (1 is the first page)
* @returns {Promise<string>} - The archive link
*/
async createArchiveLinkByIds({ ids, name = 'files', pages }) {
const resp = await this.stackClient.fetchJSON('POST', '/files/archive', {
data: {
type: 'io.cozy.archives',
attributes: {
name,
ids,
...(pages && { pages })
}
}
})
return resp.links.related
}

/**
* Checks if the file belongs to the parent's hierarchy.
*
Expand Down
94 changes: 94 additions & 0 deletions packages/cozy-stack-client/src/FileCollection.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -1850,4 +1850,98 @@ describe('FileCollection', () => {
)
})
})

describe('createArchiveLinkByIds', () => {
beforeEach(() => {
client.fetchJSON.mockResolvedValue({ links: { related: 'link' } })
})
afterEach(() => {
client.fetchJSON.mockReset()
})

it('should call the right route', async () => {
const ids = ['42', '43']
await collection.createArchiveLinkByIds({ ids })
expect(client.fetchJSON).toHaveBeenCalledWith('POST', '/files/archive', {
data: {
attributes: {
ids,
name: 'files'
},
type: 'io.cozy.archives'
}
})
})
it('should call the right route with a custom name', async () => {
const ids = ['42', '43']
const name = 'my-archive'
await collection.createArchiveLinkByIds({ ids, name })
expect(client.fetchJSON).toHaveBeenCalledWith('POST', '/files/archive', {
data: {
attributes: {
ids,
name
},
type: 'io.cozy.archives'
}
})
})
it('should call the right route with a specific page by file', async () => {
const ids = ['42', '43']
const pages = [{ id: '42', page: 1 }, { id: '43', page: 2 }]
await collection.createArchiveLinkByIds({ ids, pages })
expect(client.fetchJSON).toHaveBeenCalledWith('POST', '/files/archive', {
data: {
attributes: {
ids,
name: 'files',
pages
},
type: 'io.cozy.archives'
}
})
})
})

describe('downloadArchive', () => {
beforeEach(() => {
client.fetchJSON.mockResolvedValue({ links: { related: 'link' } })
})
afterEach(() => {
client.fetchJSON.mockReset()
})

it('should call the right route', async () => {
const ids = ['42']
await collection.downloadArchive(ids)
expect(client.fetchJSON).toHaveBeenCalledWith('POST', '/files/archive', {
data: {
attributes: { ids, name: 'files' },
type: 'io.cozy.archives'
}
})
})
it('should call the right route with a custom name', async () => {
const ids = ['42']
const name = 'my-archive'
await collection.downloadArchive(ids, name)
expect(client.fetchJSON).toHaveBeenCalledWith('POST', '/files/archive', {
data: {
attributes: { ids, name },
type: 'io.cozy.archives'
}
})
})
it('should call the right route with a specific page by file', async () => {
const ids = ['42']
const pages = [{ id: '42', page: 1 }]
await collection.downloadArchive(ids, undefined, { pages })
expect(client.fetchJSON).toHaveBeenCalledWith('POST', '/files/archive', {
data: {
attributes: { ids, name: 'files', pages },
type: 'io.cozy.archives'
}
})
})
})
})

0 comments on commit df94e82

Please sign in to comment.