From 2dca02e97a0541df7e754bfe8ae2af3f7928363f Mon Sep 17 00:00:00 2001 From: Scott Dallamura Date: Wed, 7 Jun 2017 15:49:41 -0400 Subject: [PATCH] add getItem to FileContainerApi --- api/FileContainerApi.ts | 87 +++++++++++++++++++++++++++++++++++++++- samples/filecontainer.ts | 52 ++++++++++++++++++++++++ samples/samples.json | 3 +- samples/tsconfig.json | 3 +- 4 files changed, 141 insertions(+), 4 deletions(-) create mode 100644 samples/filecontainer.ts diff --git a/api/FileContainerApi.ts b/api/FileContainerApi.ts index f88098a6..d8319bf1 100644 --- a/api/FileContainerApi.ts +++ b/api/FileContainerApi.ts @@ -12,6 +12,7 @@ import stream = require("stream"); import * as restm from 'typed-rest-client/RestClient'; +import * as httpm from 'typed-rest-client//HttpClient'; import VsoBaseInterfaces = require('./interfaces/common/VsoBaseInterfaces'); import FileContainerApiBase = require("./FileContainerApiBase"); import FileContainerInterfaces = require("./interfaces/FileContainerInterfaces"); @@ -19,13 +20,95 @@ import vsom = require('./VsoClient'); export interface IFileContainerApi extends FileContainerApiBase.IFileContainerApiBase { createItem(contentStream: NodeJS.ReadableStream, uncompressedLength: number, containerId: number, itemPath: string, scope: string, options: any): Promise; + getItem(containerId: number, scope?: string, itemPath?: string, downloadFileName?: string): Promise>; } export class FileContainerApi extends FileContainerApiBase.FileContainerApiBase implements IFileContainerApi { constructor(baseUrl: string, handlers: VsoBaseInterfaces.IRequestHandler[]) { super(baseUrl, handlers); } - + + /** + * @param {number} containerId + * @param {string} scope + * @param {string} itemPath + * @param {string} downloadFileName + */ + public async getItem( + containerId: number, + scope?: string, + itemPath?: string, + downloadFileName?: string + ): Promise> { + + return new Promise>(async (resolve, reject) => { + let routeValues: any = { + containerId: containerId + }; + + let queryValues: any = { + scope: scope, + itemPath: itemPath, + '$format': "OctetStream", + downloadFileName: downloadFileName + }; + + try { + let verData: vsom.ClientVersioningData = await this.vsoClient.getVersioningData( + "3.2-preview.4", + "Container", + "e4f5c81e-e250-447b-9fef-bd48471bea5e", + routeValues, + queryValues); + + let url: string = verData.requestUrl; + let options: restm.IRequestOptions = this.createRequestOptions('application/octet-stream', + verData.apiVersion); + + let res = await this.http.get(url); + + let rres: restm.IRestResponse = >{}; + let statusCode = res.message.statusCode; + rres.statusCode = statusCode; + // not found leads to null obj returned + if (statusCode == httpm.HttpCodes.NotFound) { + resolve(rres); + } + + if (statusCode > 299) { + let msg; + // if exception/error in body, attempt to get better error + let contents = await res.readBody(); + let obj; + if (contents && contents.length > 0) { + obj = JSON.parse(contents); + if (options && options.responseProcessor) { + rres.result = options.responseProcessor(obj); + } + else { + rres.result = obj; + } + } + + if (obj && obj.message) { + msg = obj.message; + } + else { + msg = "Failed request: (" + statusCode + ") " + res.message.url; + } + reject(new Error(msg)); + } + else { + rres.result = res.message; + resolve(rres); + } + } + catch (err) { + reject(err); + } + }); + } + public createItem(contentStream: NodeJS.ReadableStream, uncompressedLength: number, containerId: number, itemPath: string, scope: string, options: any): Promise { return new Promise((resolve, reject) => { let chunkStream = new ChunkStream(this, uncompressedLength, containerId, itemPath, scope, options); @@ -61,7 +144,7 @@ export class FileContainerApi extends FileContainerApiBase.FileContainerApiBase customHeaders["Content-Type"] = ""; - this.vsoClient.getVersioningData("2.2-preview.3", "Container", "e4f5c81e-e250-447b-9fef-bd48471bea5e", routeValues, queryValues) + this.vsoClient.getVersioningData("3.2-preview.4", "Container", "e4f5c81e-e250-447b-9fef-bd48471bea5e", routeValues, queryValues) .then((versioningData: vsom.ClientVersioningData) => { var url: string = versioningData.requestUrl; var serializationData = { responseTypeMetadata: FileContainerInterfaces.TypeInfo.FileContainerItem, responseIsCollection: false }; diff --git a/samples/filecontainer.ts b/samples/filecontainer.ts new file mode 100644 index 00000000..760f7b44 --- /dev/null +++ b/samples/filecontainer.ts @@ -0,0 +1,52 @@ +import * as fs from 'fs'; +import * as path from 'path'; +import * as stream from 'stream'; + +import * as cm from './common'; +import * as vm from 'vso-node-api'; + +import * as ta from 'vso-node-api/FileContainerApi'; +import * as ti from 'vso-node-api/interfaces/FileContainerInterfaces'; + +export async function run() { + try + { + let vsts: vm.WebApi = await cm.getWebApi(); + let fileContainerApi = vsts.getFileContainerApi(); + + let containers = await fileContainerApi.getContainers(null, null); + if (containers.length > 0) { + let container = containers[0]; + console.log("found container " + container.name); + + let items = await fileContainerApi.getItems(container.id, null, null, null, null, null, null, false); + console.log("found " + items.length + " items"); + + let item = items.filter((item) => { + return item.itemType === ti.ContainerItemType.File; + })[0]; + + if (item) { + console.log("downloading " + item.path); + let restResponse = await fileContainerApi.getItem(container.id, null, item.path, item.path.substring(item.path.lastIndexOf('/') + 1)); + + let output = ""; + await new Promise((resolve, reject) => { + restResponse.result.on('data', (chunk) => { + output += chunk; + }); + restResponse.result.on('end', () => { + resolve(output); + }); + }); + console.log("downloaded " + item.path); + console.log(output); + } + + } + } + catch (err) { + console.error('Error: ' + err.stack); + } + +} diff --git a/samples/samples.json b/samples/samples.json index c0df3a59..3ac1a55e 100644 --- a/samples/samples.json +++ b/samples/samples.json @@ -1,4 +1,5 @@ [ "build", - "task" + "task", + "filecontainer" ] \ No newline at end of file diff --git a/samples/tsconfig.json b/samples/tsconfig.json index 016d7c54..2926c808 100644 --- a/samples/tsconfig.json +++ b/samples/tsconfig.json @@ -7,6 +7,7 @@ "files": [ "run.ts", "build.ts", - "task.ts" + "task.ts", + "filecontainer.ts" ] } \ No newline at end of file