import { RepoApi } from '../repo-api' ; import { NodeBodyCreate } from './node-body-create' ; import { NodeContentTree , flattenNodeContentTree } from './node-content-tree' ; import { NodesApi as AdfNodeApi , NodeBodyLock , NodeEntry , NodeChildAssociationPaging } from '@alfresco/js-api' ; import { Utils } from '../../../../utilities/utils' ; export class NodesApi extends RepoApi { nodesApi = new AdfNodeApi ( this . alfrescoJsApi ) ; constructor ( username ? , password ? ) { super ( username , password ) ; } async getNodeByPath ( relativePath = '/' , parentFolderId = '-my-' ) { try { await this . apiAuth ( ) ; return await this . nodesApi . getNode ( parentFolderId , { relativePath } ) ; } catch ( error ) { this . handleError ( `${ this . constructor . name } ${ this . getNodeByPath . name }` , error ) ; return null ; } } async getNodeById ( id ) { try { await this . apiAuth ( ) ; return await this . nodesApi . getNode ( id ) ; } catch ( error ) { this . handleError ( `${ this . constructor . name } ${ this . getNodeById . name }` , error ) ; return null ; } } async getNodeIdFromParent ( name , parentId ) { try { const children = ( await this . getNodeChildren ( parentId ) ) . list . entries ; return children . find ( ( elem ) => elem . entry . name === name ) . entry . id || '' ; } catch ( error ) { this . handleError ( `${ this . constructor . name } ${ this . getNodeIdFromParent . name }` , error ) ; return '' ; } } async getNodeDescription ( name , parentId ) { try { const children = ( await this . getNodeChildren ( parentId ) ) . list . entries ; return children . find ( ( elem ) => elem . entry . name === name ) . entry . properties [ 'cm:description' ] ; } catch ( error ) { this . handleError ( `${ this . constructor . name } ${ this . getNodeDescription . name }` , error ) ; return '' ; } } async getNodeTitle ( name , parentId ) { try { const children = ( await this . getNodeChildren ( parentId ) ) . list . entries ; return children . find ( ( elem ) => elem . entry . name === name ) . entry . properties [ 'cm:title' ] ; } catch ( error ) { this . handleError ( `${ this . constructor . name } ${ this . getNodeTitle . name }` , error ) ; return '' ; } } async getNodeProperty ( nodeId , property ) { try { const node = await this . getNodeById ( nodeId ) ; return ( node . entry . properties && node . entry . properties [ property ] ) || '' ; } catch ( error ) { this . handleError ( `${ this . constructor . name } ${ this . getNodeProperty . name }` , error ) ; return '' ; } } async getFileVersionType ( nodeId ) { try { const prop = await this . getNodeProperty ( nodeId , 'cm:versionType' ) ; return prop || '' ; } catch ( error ) { this . handleError ( `${ this . constructor . name } ${ this . getFileVersionType . name }` , error ) ; return '' ; } } async getFileVersionLabel ( nodeId ) { try { const prop = await this . getNodeProperty ( nodeId , 'cm:versionLabel' ) ; return prop || '' ; } catch ( error ) { this . handleError ( `${ this . constructor . name } ${ this . getFileVersionLabel . name }` , error ) ; return '' ; } } async getSharedId ( nodeId ) { try { const sharedId = await this . getNodeProperty ( nodeId , 'qshare:sharedId' ) ; return sharedId || '' ; } catch ( error ) { this . handleError ( `${ this . constructor . name } ${ this . getSharedId . name }` , error ) ; return '' ; } } async getSharedExpiryDate ( nodeId ) { try { const expiryDate = await this . getNodeProperty ( nodeId , 'qshare:expiryDate' ) ; return expiryDate || '' ; } catch ( error ) { this . handleError ( `${ this . constructor . name } ${ this . getSharedExpiryDate . name }` , error ) ; return '' ; } } async isFileShared ( nodeId ) { try { const sharedId = await this . getSharedId ( nodeId ) ; return sharedId !== '' ; } catch ( error ) { this . handleError ( `${ this . constructor . name } ${ this . isFileShared . name }` , error ) ; return null ; } } async deleteNodeById ( id , permanent = true ) { try { await this . apiAuth ( ) ; await this . nodesApi . deleteNode ( id , { permanent } ) ; } catch ( error ) { this . handleError ( `${ this . constructor . name } ${ this . deleteNodeById . name }` , error ) ; } } async deleteNodeByPath ( path , permanent = true , parentFolderId ? ) { try { const id = ( await this . getNodeByPath ( path , parentFolderId ) ) . entry . id ; await this . deleteNodeById ( id , permanent ) ; } catch ( error ) { this . handleError ( `${ this . constructor . name } ${ this . deleteNodeByPath . name }` , error ) ; } } async deleteNodes ( names , relativePath = '' , permanent = true ) { try { await names . reduce ( async ( previous , current ) => { await previous ; const req = await this . deleteNodeByPath ( `${ relativePath }/${ current }` , permanent ) ; return req ; } , Promise . resolve ( ) ) ; } catch ( error ) { this . handleError ( `${ this . constructor . name } ${ this . deleteNodes . name }` , error ) ; } } async deleteNodesById ( ids , permanent = true ) { try { for ( const id of ids ) { await this . deleteNodeById ( id , permanent ) ; } } catch ( error ) { this . handleError ( `${ this . constructor . name } ${ this . deleteNodesById . name }` , error ) ; } } async getNodeChildren ( nodeId ) { try { const opts = { include : [ 'properties' ] } ; await this . apiAuth ( ) ; return await this . nodesApi . listNodeChildren ( nodeId , opts ) ; } catch ( error ) { this . handleError ( `${ this . constructor . name } ${ this . getNodeChildren . name }` , error ) ; return null ; } } async deleteNodeChildren ( parentId , exceptNodesNamed ? ) { try { const listEntries = ( await this . getNodeChildren ( parentId ) ) . list . entries ; let nodeIds ; if ( exceptNodesNamed ) { nodeIds = listEntries . filter ( ( entries ) => ! exceptNodesNamed . includes ( entries . entry . name ) ) . map ( ( entries ) => entries . entry . id ) ; } else { nodeIds = listEntries . map ( ( entries ) => entries . entry . id ) ; } await this . deleteNodesById ( nodeIds ) ; } catch ( error ) { this . handleError ( `${ this . constructor . name } ${ this . deleteNodeChildren . name }` , error ) ; } } async createImageNode ( name , parentId = '-my-' , title = '' , description = '' ) { const imageProps = { 'exif:pixelXDimension' : 1000 , 'exif:pixelYDimension' : 1200 } ; try { return await this . createNode ( 'cm:content' , name , parentId , title , description , imageProps ) ; } catch ( error ) { this . handleError ( `${ this . constructor . name } ${ this . createImageNode . name }` , error ) ; return null ; } } async createNode ( nodeType , name , parentId = '-my-' , title = '' , description = '' , imageProps = null , author = '' , majorVersion = true , aspectNames = null ) { if ( ! aspectNames ) { aspectNames = [ 'cm:versionable' ] ; } const nodeBody = { name , nodeType , properties : { 'cm:title' : title , 'cm:description' : description , 'cm:author' : author } , aspectNames } ; if ( imageProps ) { nodeBody . properties = Object . assign ( nodeBody . properties , imageProps ) ; } try { await this . apiAuth ( ) ; return await this . nodesApi . createNode ( parentId , nodeBody , { majorVersion } ) ; } catch ( error ) { this . handleError ( `${ this . constructor . name } ${ this . createNode . name }` , error ) ; return null ; } } async createFile ( name , parentId = '-my-' , title = '' , description = '' , author = '' , majorVersion = true , aspectNames = null ) { try { return await this . createNode ( 'cm:content' , name , parentId , title , description , null , author , majorVersion , aspectNames ) ; } catch ( error ) { this . handleError ( `${ this . constructor . name } ${ this . createFile . name }` , error ) ; return null ; } } async createImage ( name , parentId = '-my-' , title = '' , description = '' ) { try { return await this . createImageNode ( name , parentId , title , description ) ; } catch ( error ) { this . handleError ( `${ this . constructor . name } ${ this . createImage . name }` , error ) ; return null ; } } async createFolder ( name , parentId = '-my-' , title = '' , description = '' , author = '' , aspectNames = null ) { try { return await this . createNode ( 'cm:folder' , name , parentId , title , description , null , author , null , aspectNames ) ; } catch ( error ) { this . handleError ( `${ this . constructor . name } ${ this . createFolder . name }` , error ) ; return null ; } } async createChildren ( data ) { try { await this . apiAuth ( ) ; return await this . nodesApi . createNode ( '-my-' , data as any ) ; } catch ( error ) { this . handleError ( `${ this . constructor . name } ${ this . createChildren . name }` , error ) ; } } async createContent ( content , relativePath = '/' ) { try { return await this . createChildren ( flattenNodeContentTree ( content , relativePath ) ) ; } catch ( error ) { this . handleError ( `${ this . constructor . name } ${ this . createContent . name }` , error ) ; } } async createFolders ( names , relativePath = '/' ) { try { return await this . createContent ( { folders : names } , relativePath ) ; } catch ( error ) { this . handleError ( `${ this . constructor . name } ${ this . createFolders . name }` , error ) ; } } async createFiles ( names , relativePath = '/' ) { try { return await this . createContent ( { files : names } , relativePath ) ; } catch ( error ) { this . handleError ( `${ this . constructor . name } ${ this . createFiles . name }` , error ) ; } } async addAspects ( nodeId , aspectNames ) { try { await this . apiAuth ( ) ; return this . nodesApi . updateNode ( nodeId , { aspectNames } ) ; } catch ( error ) { this . handleError ( `${ this . constructor . name } ${ this . addAspects . name }` , error ) ; return null ; } } async createFileLink ( originalNodeId , destinationId ) { const name = ( await this . getNodeById ( originalNodeId ) ) . entry . name ; const nodeBody = { name : `Link to ${ name }.url` , nodeType : 'app:filelink' , properties : { 'cm:destination' : originalNodeId } } ; try { await this . apiAuth ( ) ; const link = await this . nodesApi . createNode ( destinationId , nodeBody ) ; await this . addAspects ( originalNodeId , [ 'app:linked' ] ) ; return link ; } catch ( error ) { this . handleError ( `${ this . constructor . name } ${ this . createFileLink . name }` , error ) ; return null ; } } async createFolderLink ( originalNodeId , destinationId ) { const name = ( await this . getNodeById ( originalNodeId ) ) . entry . name ; const nodeBody = { name : `Link to ${ name }.url` , nodeType : 'app:folderlink' , properties : { 'cm:title' : `Link to ${ name }.url` , 'cm:destination' : originalNodeId , 'cm:description' : `Link to ${ name }.url` , 'app:icon' : 'space-icon-link' } } ; try { await this . apiAuth ( ) ; const link = await this . nodesApi . createNode ( destinationId , nodeBody ) ; await this . addAspects ( originalNodeId , [ 'app:linked' ] ) ; return link ; } catch ( error ) { this . handleError ( `${ this . constructor . name } ${ this . createFolderLink . name }` , error ) ; return null ; } } async getNodeContent ( nodeId ) { try { await this . apiAuth ( ) ; return await this . nodesApi . getNodeContent ( nodeId ) ; } catch ( error ) { this . handleError ( `${ this . constructor . name } ${ this . getNodeContent . name }` , error ) ; } } async updateNodeContent ( nodeId , content , majorVersion = true , comment ? , newName ? ) { try { const opts = { majorVersion , comment , name : newName } ; await this . apiAuth ( ) ; return await this . nodesApi . updateNodeContent ( nodeId , content , opts ) ; } catch ( error ) { this . handleError ( `${ this . constructor . name } ${ this . updateNodeContent . name }` , error ) ; return null ; } } async renameNode ( nodeId , newName ) { try { await this . apiAuth ( ) ; return this . nodesApi . updateNode ( nodeId , { name : newName } ) ; } catch ( error ) { this . handleError ( `${ this . constructor . name } ${ this . renameNode . name }` , error ) ; return null ; } } async setInheritPermissions ( nodeId , inheritPermissions ) { const data = { permissions : { isInheritanceEnabled : inheritPermissions } } ; try { await this . apiAuth ( ) ; return await this . nodesApi . updateNode ( nodeId , data ) ; } catch ( error ) { this . handleError ( `${ this . constructor . name } ${ this . setGranularPermission . name }` , error ) ; return null ; } } async setGranularPermission ( nodeId , inheritPermissions = false , username , role ) { const data = { permissions : { isInheritanceEnabled : inheritPermissions , locallySet : [ { authorityId : username , name : role } ] } } ; try { await this . apiAuth ( ) ; return await this . nodesApi . updateNode ( nodeId , data ) ; } catch ( error ) { this . handleError ( `${ this . constructor . name } ${ this . setGranularPermission . name }` , error ) ; return null ; } } async lockFile ( nodeId , lockType = 'ALLOW_OWNER_CHANGES' ) { const data = { type : lockType } as NodeBodyLock ; try { await this . apiAuth ( ) ; return await this . nodesApi . lockNode ( nodeId , data ) ; } catch ( error ) { this . handleError ( `${ this . constructor . name } ${ this . lockFile . name }` , error ) ; return null ; } } async unlockFile ( nodeId ) { try { await this . apiAuth ( ) ; return await this . nodesApi . unlockNode ( nodeId ) ; } catch ( error ) { this . handleError ( `${ this . constructor . name } ${ this . unlockFile . name }` , error ) ; return null ; } } async getLockType ( nodeId ) { try { const lockType = await this . getNodeProperty ( nodeId , 'cm:lockType' ) ; return lockType || '' ; } catch ( error ) { this . handleError ( `${ this . constructor . name } ${ this . getLockType . name }` , error ) ; return '' ; } } async getLockOwner ( nodeId ) { try { const lockOwner = await this . getNodeProperty ( nodeId , 'cm:lockOwner' ) ; return lockOwner || '' ; } catch ( error ) { this . handleError ( `${ this . constructor . name } ${ this . getLockOwner . name }` , error ) ; return '' ; } } async isFileLockedWrite ( nodeId ) { try { return ( await this . getLockType ( nodeId ) ) === 'WRITE_LOCK' ; } catch ( error ) { this . handleError ( `${ this . constructor . name } ${ this . isFileLockedWrite . name }` , error ) ; return null ; } } async isFileLockedWriteWithRetry ( nodeId , expect ) { const data = { expect : expect , retry : 5 } ; let isLocked = false ; try { const locked = async ( ) => { isLocked = ( await this . getLockType ( nodeId ) ) === 'WRITE_LOCK' ; if ( isLocked !== data . expect ) { return Promise . reject ( isLocked ) ; } else { return Promise . resolve ( isLocked ) ; } } ; return await Utils . retryCall ( locked , data . retry ) ; } catch ( error ) { this . handleError ( `${ this . constructor . name } ${ this . isFileLockedWriteWithRetry . name }` , error ) ; } return isLocked ; } async isFileLockedByName ( fileName , parentId ) { try { const id = await this . getNodeIdFromParent ( fileName , parentId ) ; return await this . isFileLockedWrite ( id ) ; } catch ( error ) { this . handleError ( `${ this . constructor . name } ${ this . isFileLockedByName . name }` , error ) ; return null ; } } }