import { ISPService , ILibsOptions , LibsOrderBy } from "./ISPService" ; import { ISPField , ISPList , ISPLists , IUploadImageResult } from "../common/SPEntities" ; import { BaseComponentContext } from '@microsoft/sp-component-base' ; import { SPHttpClient , ISPHttpClientOptions } from "@microsoft/sp-http" ; import { urlCombine } from "../common/utilities" ; import filter from 'lodash/filter' ; import find from 'lodash/find' ; export default class SPService implements ISPService { private _webAbsoluteUrl : string ; constructor ( private _context , webAbsoluteUrl ? ) { this . _webAbsoluteUrl = webAbsoluteUrl ? webAbsoluteUrl : this . _context . pageContext . web . absoluteUrl ; } public getField = async ( listId , internalColumnName , webUrl ? ) : Promise < ISPField | undefined > => { try { const webAbsoluteUrl = ! webUrl ? this . _webAbsoluteUrl : webUrl ; const apiUrl = `${ webAbsoluteUrl }/_api/web/lists('${ listId }')/fields/getByInternalNameOrTitle('${ internalColumnName }')` ; const data = await this . _context . spHttpClient . get ( apiUrl , SPHttpClient . configurations . v1 ) ; if ( data . ok ) { const results = await data . json ( ) ; if ( results ) { const field = results as ISPField ; if ( field . TypeAsString === 'Calculated' ) { const resultTypeRegEx = /ResultType="(\w+)"/gmi ; const resultTypeMatch = resultTypeRegEx . exec ( field . SchemaXml ) ; field . ResultType = resultTypeMatch [ 1 ] ; } return field ; } } } catch ( error ) { return Promise . reject ( error ) ; } } ; param options public async getLibs ( options ? ) { let filtered ; let queryUrl = `${ this . _webAbsoluteUrl }/_api/web/lists?$select=Title,id,BaseTemplate` ; if ( options . contentTypeId ) { queryUrl += `,ContentTypes/Id&$expand=ContentTypes` ; } if ( options . orderBy ) { queryUrl += `&$orderby=${ options . orderBy === LibsOrderBy . Id ? 'Id' : 'Title' }` ; } if ( options . filter ) { queryUrl += `&$filter=${ encodeURIComponent ( options . filter ) }` ; } else { if ( options . baseTemplate ) { if ( Array . isArray ( options . baseTemplate ) ) { const numbers = options . baseTemplate ; const mapNumbers = numbers . map ( ( i ) => { if ( i == numbers [ 0 ] ) { return `BaseTemplate eq ${ i }` ; } else { return `or BaseTemplate eq ${ i }` ; } } ) ; queryUrl += `&$filter=${ mapNumbers . join ( " " ) }` ; filtered = true ; } else { queryUrl += `&$filter=BaseTemplate eq ${ options . baseTemplate }` ; filtered = true ; } } if ( options . includeHidden === false ) { queryUrl += filtered ? ' and Hidden eq false' : '&$filter=Hidden eq false' ; filtered = true ; } } const data = await this . _context . spHttpClient . get ( queryUrl , SPHttpClient . configurations . v1 ) ; if ( data . ok ) { const result = await data . json ( ) ; if ( options . contentTypeId ) { const filteredLists = filter ( result . value , ( aList ) => { return find ( aList . ContentTypes , ( ct ) => { return ct . Id . StringValue . toUpperCase ( ) . startsWith ( options . contentTypeId . toUpperCase ( ) ) ; } ) ; } ) ; result . value = filteredLists as ISPList [ ] ; } return result as ISPLists ; } else { return null ; } } /**
     * Get List Items
     */ public async getListItems ( filterText , listId , internalColumnName , field , keyInternalColumnName ? , webUrl ? , filterString ? , substringSearch = false , orderBy ? ) { let returnItems ; const webAbsoluteUrl = ! webUrl ? this . _webAbsoluteUrl : webUrl ; let apiUrl = '' ; let isPost = false ; if ( field && field . TypeAsString === 'Calculated' ) { let orderByStr = '' ; if ( orderBy ) { const orderByParts = orderBy . split ( ' ' ) ; let ascStr = '' ; if ( orderByParts [ 1 ] && orderByParts [ 1 ] . toLowerCase ( ) === 'desc' ) { ascStr = `Ascending="FALSE"` ; } orderByStr = `<OrderBy><FieldRef Name="${ orderByParts [ 0 ] }" ${ ascStr } />` ; } const camlQuery = `<View><Query><Where>${ substringSearch ? '<Contains>' : '<BeginsWith>' }<FieldRef Name="${ internalColumnName }"/><Value Type="${ field . ResultType }">${ filterText }</Value>${ substringSearch ? '</Contains>' : '</BeginsWith>' }</Where>${ orderByStr }</Query></View>` ; apiUrl = `${ webAbsoluteUrl }/_api/web/lists('${ listId }')/GetItems(query=@v1)?$select=${ keyInternalColumnName || 'Id' },${ internalColumnName }&@v1=${ JSON . stringify ( { ViewXml : camlQuery } ) }` ; isPost = true ; } else { const filterStr = substringSearch ? `${ filterText ? `substringof('${ encodeURIComponent ( filterText . replace ( "'" , "''" ) ) }',${ internalColumnName })` : '' }${ filterString ? ( filterText ? ' and ' : '' ) + filterString : '' }` : `${ filterText ? `startswith(${ internalColumnName },'${ encodeURIComponent ( filterText . replace ( "'" , "''" ) ) }')` : '' }${ filterString ? ( filterText ? ' and ' : '' ) + filterString : '' }` ; apiUrl = `${ webAbsoluteUrl }/_api/web/lists('${ listId }')/items?$select=${ keyInternalColumnName || 'Id' },${ internalColumnName }&$filter=${ filterStr }&$orderby=${ orderBy }` ; } try { const data = isPost ? await this . _context . spHttpClient . post ( apiUrl , SPHttpClient . configurations . v1 , { } ) : await this . _context . spHttpClient . get ( apiUrl , SPHttpClient . configurations . v1 ) ; if ( data . ok ) { const results = await data . json ( ) ; if ( results && results . value && results . value . length > 0 ) { return results . value ; } } return [ ] ; } catch ( error ) { return Promise . reject ( error ) ; } } param filterText param listId param internalColumnName param keyInternalColumnName param webUrl param filterList returns public async getListItemsForListItemPicker ( filterText , listId , internalColumnName , keyInternalColumnName ? , webUrl ? , filterList ? ) { let _filter = `$filter=startswith(${ internalColumnName },'${ encodeURIComponent ( filterText . replace ( "'" , "''" ) ) }') ` ; let costumfilter = filterList ? `and ${ filterList }` : "" ; let _top = " &$top=2000" ; if ( ( filterText . trim ( ) . indexOf ( "*" ) == 0 && filterText . trim ( ) . length == 1 ) || filterText . trim ( ) . length == 0 ) { _filter = "" ; costumfilter = filterList ? `$filter=${ filterList }&` : "" ; _top = `$top=500` ; } try { const webAbsoluteUrl = ! webUrl ? this . _webAbsoluteUrl : webUrl ; const apiUrl = `${ webAbsoluteUrl }/_api/web/lists('${ listId }')/items?$orderby=${ internalColumnName }&$select=${ keyInternalColumnName || "Id" },${ internalColumnName }&${ _filter }${ costumfilter }${ _top }` ; const data = await this . _context . spHttpClient . get ( apiUrl , SPHttpClient . configurations . v1 ) ; if ( data . ok ) { const results = await data . json ( ) ; if ( results && results . value && results . value . length > 0 ) { return results . value ; } } return [ ] ; } catch ( error ) { return Promise . reject ( error ) ; } } param listId param itemId param webUrl public async getListItemAttachments ( listId , itemId , webUrl ? ) { try { const webAbsoluteUrl = ! webUrl ? this . _webAbsoluteUrl : webUrl ; const apiUrl = `${ webAbsoluteUrl }/_api/web/lists(@listId)/items(@itemId)/AttachmentFiles?@listId=guid'${ encodeURIComponent ( listId ) }'&@itemId=${ encodeURIComponent ( String ( itemId ) ) }` ; const data = await this . _context . spHttpClient . get ( apiUrl , SPHttpClient . configurations . v1 ) ; if ( data . ok ) { const results = await data . json ( ) ; if ( results && results . value ) { return results . value ; } } return null ; } catch ( error ) { console . dir ( error ) ; return Promise . reject ( error ) ; } } param fileName param listId param itemId param webUrl public async deleteAttachment ( fileName , listId , itemId , webUrl ? ) { try { const spOpts = { headers : { "X-HTTP-Method" : 'DELETE' , } } ; const webAbsoluteUrl = ! webUrl ? this . _webAbsoluteUrl : webUrl ; const apiUrl = `${ webAbsoluteUrl }/_api/web/lists(@listId)/items(@itemId)/AttachmentFiles/getByFileName(@fileName)/RecycleObject?@listId=guid'${ encodeURIComponent ( listId ) }'&@itemId=${ encodeURIComponent ( String ( itemId ) ) }&@fileName='${ encodeURIComponent ( fileName . replace ( /'/g , "''" ) ) }'` ; const data = await this . _context . spHttpClient . post ( apiUrl , SPHttpClient . configurations . v1 , spOpts ) ; } catch ( error ) { console . dir ( error ) ; return Promise . reject ( error ) ; } } param listId param itemId param fileName param file param webUrl public async addAttachment ( listId , itemId , fileName , file , webUrl ? ) { try { fileName = fileName . replace ( /[\~\#\%\&\*\{\}\\\:\<\>\?\/\+\|]/gi , '' ) ; const fileExists = await this . checkAttachmentExists ( listId , itemId , fileName , webUrl ) ; if ( fileExists ) { await this . deleteAttachment ( fileName , listId , itemId , webUrl ) ; } const spOpts = { body : file } ; const webAbsoluteUrl = ! webUrl ? this . _webAbsoluteUrl : webUrl ; const apiUrl = `${ webAbsoluteUrl }/_api/web/lists(@listId)/items(@itemId)/AttachmentFiles/add(FileName=@fileName)?@listId=guid'${ encodeURIComponent ( listId ) }'&@itemId=${ encodeURIComponent ( String ( itemId ) ) }&@fileName='${ encodeURIComponent ( fileName . replace ( /'/g , "''" ) ) }'` ; const data = await this . _context . spHttpClient . post ( apiUrl , SPHttpClient . configurations . v1 , spOpts ) ; return ; } catch ( error ) { return Promise . reject ( error ) ; } } param listId param itemId param fileName param webUrl public async getAttachment ( listId , itemId , fileName , webUrl ? ) { const webAbsoluteUrl = ! webUrl ? this . _webAbsoluteUrl : webUrl ; const apiUrl = `${ webAbsoluteUrl }/_api/web/lists(@listId)/items(@itemId)/AttachmentFiles/GetByFileBame(@fileName))?@listId=guid'${ encodeURIComponent ( listId ) }'&@itemId=${ encodeURIComponent ( String ( itemId ) ) }&@fileName='${ encodeURIComponent ( fileName . replace ( /'/g , "''" ) ) }'` ; const data = await this . _context . spHttpClient . get ( apiUrl , SPHttpClient . configurations . v1 ) ; if ( data . ok ) { const file = await data . json ( ) ; if ( file ) { return file ; } } return null ; } param listId param itemId param fileName param webUrl public async checkAttachmentExists ( listId , itemId , fileName , webUrl ? ) { try { const listServerRelativeUrl = await this . getListServerRelativeUrl ( listId , webUrl ) ; const webAbsoluteUrl = ! webUrl ? this . _webAbsoluteUrl : webUrl ; const fileServerRelativeUrl = `${ listServerRelativeUrl }/Attachments/${ itemId }/${ fileName }` ; const apiUrl = `${ webAbsoluteUrl }/_api/web/getfilebyserverrelativeurl(@url)/Exists?@url='${ encodeURIComponent ( fileServerRelativeUrl . replace ( /'/g , "''" ) ) }'` ; const data = await this . _context . spHttpClient . get ( apiUrl , SPHttpClient . configurations . v1 ) ; if ( data . ok ) { const results = await data . json ( ) ; if ( results ) { return results . value ; } } return false ; } catch ( error ) { return Promise . reject ( error ) ; } } param listId param webUrl public async getListName ( listId , webUrl ? ) { const webAbsoluteUrl = ! webUrl ? this . _webAbsoluteUrl : webUrl ; const apiUrl = `${ webAbsoluteUrl }/_api/web/lists(@listId)/RootFolder/Name?@listId=guid'${ encodeURIComponent ( listId ) }'` ; const data = await this . _context . spHttpClient . get ( apiUrl , SPHttpClient . configurations . v1 ) ; if ( data . ok ) { const results = await data . json ( ) ; if ( results ) { return results . value ; } } return ; } param listId param webUrl public async getListServerRelativeUrl ( listId , webUrl ? ) { const webAbsoluteUrl = ! webUrl ? this . _webAbsoluteUrl : webUrl ; const apiUrl = `${ webAbsoluteUrl }/_api/web/lists(@listId)/RootFolder/ServerRelativeUrl?@listId=guid'${ encodeURIComponent ( listId ) }'` ; const data = await this . _context . spHttpClient . get ( apiUrl , SPHttpClient . configurations . v1 ) ; if ( data . ok ) { const results = await data . json ( ) ; if ( results ) { return results . value ; } } return ; } public async getLookupValue ( listId , listItemID , fieldName , webUrl ? ) { try { const webAbsoluteUrl = ! webUrl ? this . _context . pageContext . web . absoluteUrl : webUrl ; let apiUrl = `${ webAbsoluteUrl }/_api/web/lists(@listId)/items(${ listItemID })/?@listId=guid'${ encodeURIComponent ( listId ) }'&$select=${ fieldName }/ID,${ fieldName }/Title&$expand=${ fieldName }` ; const data = await this . _context . spHttpClient . get ( apiUrl , SPHttpClient . configurations . v1 ) ; if ( data . ok ) { const result = await data . json ( ) ; if ( result && result [ fieldName ] ) { return [ { key : result [ fieldName ] . ID , name : result [ fieldName ] . Title } ] ; } } return null ; } catch ( error ) { console . dir ( error ) ; return Promise . reject ( error ) ; } } public async getLookupValues ( listId , listItemID , fieldName , webUrl ? ) { try { const webAbsoluteUrl = ! webUrl ? this . _context . pageContext . web . absoluteUrl : webUrl ; let apiUrl = `${ webAbsoluteUrl }/_api/web/lists(@listId)/items(${ listItemID })?@listId=guid'${ encodeURIComponent ( listId ) }'&$select=${ fieldName }/ID,${ fieldName }/Title&$expand=${ fieldName }` ; const data = await this . _context . spHttpClient . get ( apiUrl , SPHttpClient . configurations . v1 ) ; if ( data . ok ) { const result = await data . json ( ) ; if ( result && result [ fieldName ] ) { let lookups = [ ] ; result [ fieldName ] . forEach ( element => { lookups . push ( { key : element . ID , name : element . Title } ) ; } ) ; return lookups ; } } return null ; } catch ( error ) { console . dir ( error ) ; return Promise . reject ( error ) ; } } public async getTaxonomyFieldInternalName ( listId , fieldName , webUrl ? ) { try { const webAbsoluteUrl = ! webUrl ? this . _context . pageContext . web . absoluteUrl : webUrl ; let apiUrl = `${ webAbsoluteUrl }/_api/web/lists(@listId)/Fields/getByInternalNameOrTitle('${ fieldName }_0')/InternalName?@listId=guid'${ encodeURIComponent ( listId ) }'` ; const data = await this . _context . spHttpClient . get ( apiUrl , SPHttpClient . configurations . v1 ) ; if ( data . ok ) { const results = await data . json ( ) ; if ( results ) { return results ; } } return null ; } catch ( error ) { console . dir ( error ) ; return Promise . reject ( error ) ; } } public async getUsersUPNFromFieldValue ( listId , listItemId , fieldName , webUrl ? ) { try { const webAbsoluteUrl = ! webUrl ? this . _context . pageContext . web . absoluteUrl : webUrl ; let apiUrl = `${ webAbsoluteUrl }/_api/web/lists(@listId)/items(${ listItemId })?@listId=guid'${ encodeURIComponent ( listId ) }'&$select=${ fieldName }/Title,${ fieldName }/Id&$expand=${ fieldName }` ; const data = await this . _context . spHttpClient . get ( apiUrl , SPHttpClient . configurations . v1 ) ; if ( data . ok ) { const result = await data . json ( ) ; if ( result && result [ fieldName ] ) { let emails = [ ] ; result [ fieldName ] . forEach ( element => { emails . push ( element . Id + "/" + element . Title ) ; } ) ; return emails ; } } return null ; } catch ( error ) { console . dir ( error ) ; return Promise . reject ( error ) ; } } public async getUserUPNById ( userId , webUrl ? ) { try { const webAbsoluteUrl = ! webUrl ? this . _context . pageContext . web . absoluteUrl : webUrl ; let apiUrl = `${ webAbsoluteUrl }/_api/web/getuserbyid(${ userId })?$select=UserPrincipalName,Title` ; const data = await this . _context . spHttpClient . get ( apiUrl , SPHttpClient . configurations . v1 ) ; if ( data . ok ) { const results = await data . json ( ) ; if ( results ) { return userId + "/" + results . Title ; } } return null ; } catch ( error ) { console . dir ( error ) ; return Promise . reject ( error ) ; } } public async getSingleManagedMtadataLabel ( listId , listItemId , fieldName ) { try { const webAbsoluteUrl = this . _context . pageContext . web . absoluteUrl ; let apiUrl = `${ webAbsoluteUrl }/_api/web/lists(@listId)/RenderListDataAsStream?@listId=guid'${ encodeURIComponent ( listId ) }'` ; const data = await this . _context . spHttpClient . post ( apiUrl , SPHttpClient . configurations . v1 , { body : JSON . stringify ( { parameters : { RenderOptions : 2 , ViewXml : `<View Scope="RecursiveAll">
                        <ViewFields>
                          <FieldRef Name="${ fieldName }"/>
                        </ViewFields>
                        <Query>
                          <Where>
                            <Eq>
                              <FieldRef Name="ID"/>
                              <Value Type="Number">${ listItemId }</Value>
                            </Eq>
                          </Where>
                        </Query>
                        <RowLimit Paged="TRUE">1</RowLimit>
                      </View>` } } ) } ) ; if ( data . ok ) { const results = await data . json ( ) ; if ( results ) { return results . Row [ 0 ] [ fieldName ] ; } } return null ; } catch ( error ) { console . dir ( error ) ; return Promise . reject ( error ) ; } } public async uploadImage ( listId , itemId , fileName , file , listTitle , webUrl ? ) { const webAbsoluteUrl = ! webUrl ? this . _context . pageContext . web . absoluteUrl : webUrl ; let listTitleValue = listTitle ; if ( ! listTitle ) { const listApiUrl = urlCombine ( webAbsoluteUrl , `/_api/web/lists('${ listId }')` , false ) ; const listResponse = await this . _context . spHttpClient . get ( listApiUrl , SPHttpClient . configurations . v1 ) ; const listJson = await listResponse . json ( ) ; listTitleValue = listJson . Title ; } const apiUrl = urlCombine ( webAbsoluteUrl , `/_api/web/UploadImage(listTitle=@a1,imageName=@a2,listId=@a3,itemId=@a4)?@a1='${ listTitleValue }'&@a2='${ fileName }'&@a3='${ listId }'&@a4=${ itemId || 0 }` , false ) ; const response = await this . _context . spHttpClient . post ( apiUrl , SPHttpClient . configurations . v1 , { body : file , headers : { 'content-length' : file . byteLength . toString ( ) } } ) ; const result = await response . json ( ) as IUploadImageResult ; return result ; } }