Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
87 changes: 85 additions & 2 deletions api/FileContainerApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,20 +12,103 @@

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");
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<FileContainerInterfaces.FileContainerItem>;
getItem(containerId: number, scope?: string, itemPath?: string, downloadFileName?: string): Promise<restm.IRestResponse<NodeJS.ReadableStream>>;
}

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<restm.IRestResponse<NodeJS.ReadableStream>> {

return new Promise<restm.IRestResponse<NodeJS.ReadableStream>>(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<NodeJS.ReadableStream> = <restm.IRestResponse<NodeJS.ReadableStream>>{};
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<FileContainerInterfaces.FileContainerItem> {
return new Promise<FileContainerInterfaces.FileContainerItem>((resolve, reject) => {
let chunkStream = new ChunkStream(this, uncompressedLength, containerId, itemPath, scope, options);
Expand Down Expand Up @@ -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 };
Expand Down
52 changes: 52 additions & 0 deletions samples/filecontainer.ts
Original file line number Diff line number Diff line change
@@ -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);
}

}
3 changes: 2 additions & 1 deletion samples/samples.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
[
"build",
"task"
"task",
"filecontainer"
]
3 changes: 2 additions & 1 deletion samples/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
"files": [
"run.ts",
"build.ts",
"task.ts"
"task.ts",
"filecontainer.ts"
]
}