问题
I'm trying to get a list of documents from my on premises TFS 2017 (U3) web extension using Microsoft/vsts-node-api. I can get the extension itself with something like the following
import * as v from 'vso-node-api';
import * as xa from 'vso-node-api/ExtensionManagementApi';
import * as xi from 'vso-node-api/interfaces/ExtensionManagementInterfaces';
let serverUrl = process.argv[2];
let extensionId = process.argv[3];
async function getWebApi(serverUrl): Promise<vm.WebApi> {
return new Promise<vm.WebApi>(async (resolve, reject) => {
try {
let token = getEnv('API_TOKEN'); // personal access token
let authHandler = v.getPersonalAccessTokenHandler(token);
let option = undefined;
let webApi: v.WebApi = new v.WebApi(serverUrl, authHandler, option);
let connData: lim.ConnectionData = await vsts.connect();
console.log('Hello ' + connData.authenticatedUser.providerDisplayName);
resolve(webApi);
}
catch (err) {
reject(err);
}
});
}
let vsts: v.WebApi = await getWebApi(serverUrl);
let vstsX: xa.IExtensionManagementApi = await vsts.getExtensionManagementApi();
let extension: xi.InstalledExtension =
(await vstsX.getInstalledExtensions()).find(x => x.extensionId === extensionId);
And now I want to get a list of all documents in that extension. To do that, I think first I have to get all the 'collections' of documents (not to be confused with TFS/VSTS collections) in that extension. I think the API method I want is queryCollectionsByName, which returns an array of ExtensionDataCollection which I think is what I want, but I don't know how to create the ExtensionDataCollectionQuery object (which is itself just an array of ExtensionDataCollection) it wants for the first parameter. I don't understand why it wants an array of ExtensionDataCollection as an input parameter - I want all of the ExtensionDataCollections in the extension.
I tried this:
let collectionQuery: xi.ExtensionDataCollectionQuery;
let dataCollection : xi.ExtensionDataCollection[] =
await vstsX.queryCollectionsByName(collectionQuery, extension.publisherName, extension.extensionName);
But I get
Error: value cannot be null
The docs don't seem very helpful to me but maybe I'm not reading them properly: https://www.visualstudio.com/en-us/docs/integrate/extensions/reference/client/api/vss/references/sdk_interfaces/extensiondatacollectionquery
How can I get a list of document collections from a web extension?
Update: REST URLs
To put the question another way.
I can get a list of Installed Extension with this URL:
https://{account}.extmgmt.visualstudio.com/_apis/ExtensionManagement/InstalledExtensions
and I can get a list of documents from a collection if I know the "Collection Name":
https://{account}.extmgmt.visualstudio.com/_apis/ExtensionManagement/InstalledExtensions/{publisherName}/{extensionName}/Data/Scopes/Default/Current/Collections/{collectionName}/Documents/
What URL can I use to get a list of Collections in a given extension? I tried this, which would be analagous to the way we get a list of extensions, but I get a 404:
https://{account}.extmgmt.visualstudio.com/_apis/ExtensionManagement/InstalledExtensions/{publisherName}/{extensionName}/Data/Scopes/Default/Current/Collections
回答1:
This apparently cannot be done - you need to know the Collection Names (as well as the extension ID and publisher ID).
Then, the documents in the collection can be retrieved like this:
let documentCollection =
await vstsX.getDocumentsByName(extension.publisherId, extension.extensionId, "Default", "Current", collectionName);
Refer here: https://github.com/Microsoft/vsts-node-api/issues/160
回答2:
Currently I faced the same issue. May someone helps. I Write a PowerShell Script that cover the following scenarios:
Create a Document
Get all Documents
Patch a Document
Remove all Documents
Scope-Type: Collection
As reference for the VSS SDK take a look at Data storage
#VARIABLES TO SET
$Uri = "{devops url}"
$Collection = "{collection name}"
$PAT = "{personal access token}"
$Publisher = "{publisher of extension}"
$Extension = "{name of extension}"
#JSON FILE TO UPLOAD
$jsonFile = "{ 'A': { 'A1': 10, 'A2': 20 }, 'B': { 'B1': 30, 'B2': 40 } }"
#AUTHORIZATION HEADERS
$headers = @{
"Authorization" = ('Basic {0}' -f [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes(":$($PAT)")))
"If-Match" = ""
}
#CREATE DOCUMENT
$body = $jsonFile
$api = "api-version=3.1-preview.1"
$url = "$Uri/$Collection/_apis/ExtensionManagement/InstalledExtensions/$Publisher/$Extension/Data/Scopes/Default/Current/Collections/$Collection/Documents?$api"
$result = Invoke-RestMethod -Uri $url -Method POST -ContentType "application/json" -Headers $headers -Body $body -TimeoutSec $timeout -Verbose
Write-Host "[ps1] create document: $result" -ForegroundColor Green
#GET ALL DOCUMENTS
$url = "$Uri/$Collection/_apis/ExtensionManagement/InstalledExtensions/$Publisher/$Extension/Data/Scopes/Default/Current/Collections/$Collection/Documents?"
$result = Invoke-RestMethod -Uri $url -Method GET -ContentType "application/json" -Headers $headers -TimeoutSec $timeout -Verbose
Write-Host "[ps1] get all documents: $result" -ForegroundColor Yellow
foreach($item in $result){
Write-Host "[ps1] A: $($item.value.A[0])" -ForegroundColor DarkGray
#GET ETAG AND ID OF THE FIRST DOCUMENT
$etag = $item.value.__etag[0]
$id = $item.value.id[0]
break;
}
#PATCH DOCUMENT
$json = $jsonFile | ConvertFrom-Json
$json.A.A1 = 15
$json | Add-Member @{"id"= $id}
$json | Add-Member @{"__etag"= $etag}
$body = $json | ConvertTo-Json
$api = "api-version=3.1-preview.1"
$url = "$Uri/$Collection/_apis/ExtensionManagement/InstalledExtensions/$Publisher/$Extension/Data/Scopes/Default/Current/Collections/$Collection/Documents?$api"
$patch = Invoke-RestMethod -Uri $url -Method PATCH -ContentType "application/json" -Headers $headers -Body $body -TimeoutSec $timeout -Verbose
Write-Host "[ps1] patch document: $patch" -ForegroundColor Yellow
Write-Host "[ps1] patched A: $($patch.A)" -ForegroundColor Gray
#REMOVE ALL DOCUMENTS
Write-Host "[ps1] documents to remove: $($result.count)"
for($i = 0; $i -lt $result.count; $i++){
$id = $result.value[$i].id
$api = "api-version=3.1-preview.1"
$url = "$Uri/$Collection/_apis/ExtensionManagement/InstalledExtensions/$Publisher/$Extension/Data/Scopes/Default/Current/Collections/$Collection/Documents/$($result.value[$i].id)?$api"
Invoke-RestMethod -Uri $url -Method DELETE -ContentType "application/json" -Headers $headers -TimeoutSec $timeout -Verbose
Write-Host "[ps1] delete document: $id" -ForegroundColor Red
}
来源:https://stackoverflow.com/questions/49329682/how-do-i-get-a-list-of-document-collections-in-a-given-tfs-web-extension