microsoft/vscode-react-native

Public

mirrored from https://github.com/microsoft/vscode-react-nativeAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
0.6.6

Branches

Tags

  • No tags available.
0Branches0Tags
Go to file
Add file
Code

Clone

HTTPS

Download ZIP

src/extension/appcenter/codepush/release-strategy/legacyCodePushServiceClient.ts

111lines · modecode

1// Copyright (c) Microsoft Corporation. All rights reserved.
2// Licensed under the MIT license. See LICENSE file in the project root for details.
3
4import * as request from "request";
5import { DefaultApp } from "../../command/commandParams";
6import * as fs from "fs";
7import * as Q from "q";
8import { models } from "../../api/index";
9
10export interface PackageInfo {
11 appVersion?: string;
12 description?: string;
13 isDisabled?: boolean;
14 isMandatory?: boolean;
15 label?: string;
16 packageHash?: string;
17 rollout?: number;
18}
19
20export interface Package extends PackageInfo {
21 /*generated*/ blobUrl: string;
22 /*generated*/ diffPackageMap?: PackageHashToBlobInfoMap;
23 /*generated*/ originalLabel?: string; // Set on "Promote" and "Rollback"
24 /*generated*/ originalDeployment?: string; // Set on "Promote"
25 /*generated*/ releasedBy?: string; // Set by commitPackage
26 /*generated*/ releaseMethod?: string; // "Upload", "Promote" or "Rollback". Unknown if unspecified
27 /*generated*/ size: number;
28 /*generated*/ uploadTime: number;
29}
30
31export interface PackageHashToBlobInfoMap {
32 [packageHash: string]: BlobInfo;
33}
34
35export interface BlobInfo {
36 size: number;
37 url: string;
38}
39
40export type Headers = { [headerName: string]: string };
41
42export default class LegacyCodePushServiceClient {
43 private static API_VERSION: number = 2;
44
45 constructor(private accessKey: string, private app: DefaultApp, private serverUrl: string) {
46 if (!accessKey) throw new Error("A token must be specified to execute server calls.");
47 if (!serverUrl) throw new Error("A server url must be specified to execute server calls.");
48 }
49
50 public release(deploymentName: string, filePath: string, updateMetadata: PackageInfo): Q.Promise<models.CodePushRelease> {
51 const appName = this.app.identifier;
52 return Q.Promise<models.CodePushRelease>((resolve, reject) => {
53 const options = {
54 url: this.serverUrl + this.urlEncode(`/apps/${this.appNameParam(appName)}/deployments/${deploymentName}/release`),
55 headers: {
56 "Accept": `application/vnd.code-push.v${LegacyCodePushServiceClient.API_VERSION}+json`,
57 "Authorization": `Bearer ${this.accessKey}`,
58 },
59 formData: {
60 "packageInfo": JSON.stringify(updateMetadata),
61 "package": fs.createReadStream(filePath),
62 },
63 };
64
65 request.post(options, (err: any, httpResponse: any) => {
66 if (err) {
67 reject(this.getErrorMessage(err, httpResponse));
68 return;
69 }
70 if (httpResponse.statusCode === 201) {
71 resolve(<models.CodePushRelease>JSON.parse(httpResponse.body).package);
72 } else {
73 reject(this.getErrorMessage(null, httpResponse));
74 return;
75 }
76 });
77 });
78 }
79
80 // A template string tag function that URL encodes the substituted values
81 private urlEncode(strings: any, ...values: string[]): string {
82 let result = "";
83 for (let i = 0; i < strings.length; i++) {
84 result += strings[i];
85 if (i < values.length) {
86 result += encodeURIComponent(values[i]);
87 }
88 }
89
90 return result;
91 }
92
93 // IIS and Azure web apps have this annoying behavior where %2F (URL encoded slashes) in the URL are URL decoded
94 // BEFORE the requests reach node. That essentially means there's no good way to encode a "/" in the app name--
95 // URL encodeing will work when running locally but when running on Azure it gets decoded before express sees it,
96 // so app names with slashes don't get routed properly. See https://github.com/tjanczuk/iisnode/issues/343 (or other sites
97 // that complain about the same) for some more info. I explored some IIS config based workarounds, but the previous
98 // link seems to say they won't work, so I eventually gave up on that.
99 // Anyway, to workaround this issue, we now allow the client to encode / characters as ~~ (two tildes, URL encoded).
100 // The CLI now converts / to ~~ if / appears in an app name, before passing that as part of the URL. This code below
101 // does the encoding. It's hack, but seems like the least bad option here.
102 // Eventually, this service will go away & we'll all be on Max's new service. That's hosted in docker, no more IIS,
103 // so this issue should go away then.
104 private appNameParam(appName: string) {
105 return appName.replace("/", "~~");
106 }
107
108 private getErrorMessage(error: Error | null, response: request.RequestResponse): string {
109 return response && response.body ? response.body : (error ? error.message : "");
110 }
111}
112