Skip to content

Commit

Permalink
fix(electron-updater): response from Generic Provider getLatestVersio…
Browse files Browse the repository at this point in the history
…n becomes [ 'Object object' ]

Close #1853
  • Loading branch information
develar committed Jul 25, 2017
1 parent e7112d6 commit 8a0d075
Show file tree
Hide file tree
Showing 17 changed files with 95 additions and 124 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ Platform specific `7zip-bin-*` packages are `optionalDependencies`, which may re
* [electron-react-redux-boilerplate](https://github.com/jschr/electron-react-redux-boilerplate) A minimal boilerplate to get started with Electron, React and Redux.
* [electron-boilerplate](https://github.com/szwacz/electron-boilerplate) A minimalistic yet comprehensive boilerplate application.
* [electron-vue](https://github.com/SimulatedGREG/electron-vue) A boilerplate for making electron applications built with vue.
* [electron-webpack](https://github.com/electron-userland/electron-webpack) — Scripts and configuration to compile Electron applications using webpack.

## Quick Setup Guide

Expand Down
10 changes: 5 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,14 @@
"ajv": "^5.2.2",
"ajv-keywords": "^2.1.0",
"archiver": "^2.0.0",
"aws-sdk": "^2.87.0",
"aws-sdk": "^2.89.0",
"bluebird-lst": "^1.0.2",
"chalk": "^2.0.1",
"chromium-pickle-js": "^0.2.0",
"cuint": "^0.2.2",
"debug": "^2.6.8",
"electron-download-tf": "4.3.1",
"electron-is-dev": "^0.2.0",
"electron-is-dev": "^0.3.0",
"electron-osx-sign": "0.4.6",
"fcopy-pre-bundled": "0.3.4",
"fs-extra-p": "^4.4.0",
Expand All @@ -49,13 +49,13 @@
"lodash.isequal": "^4.5.0",
"mime": "^1.3.6",
"minimatch": "^3.0.4",
"node-emoji": "^1.7.0",
"node-emoji": "^1.8.1",
"normalize-package-data": "^2.4.0",
"parse-color": "^1.0.0",
"plist": "^2.1.0",
"read-config-file": "^0.1.3",
"sanitize-filename": "^1.6.1",
"semver": "^5.3.0",
"semver": "^5.4.1",
"source-map-support": "^0.4.15",
"stat-mode": "^0.2.2",
"ts-jsdoc": "^2.0.3",
Expand All @@ -67,7 +67,7 @@
},
"devDependencies": {
"@types/ini": "^1.3.29",
"@types/jest": "^20.0.2",
"@types/jest": "^20.0.4",
"@types/js-yaml": "^3.9.0",
"@types/source-map-support": "^0.4.0",
"@types/xml2js": "^0.4.0",
Expand Down
5 changes: 3 additions & 2 deletions packages/electron-builder-http/src/bintray.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,12 @@ export class BintrayClient {
}

private bintrayRequest<T>(path: string, auth: string | null, data: {[name: string]: any; } | null = null, cancellationToken: CancellationToken, method?: "GET" | "DELETE" | "PUT"): Promise<T> {
return this.httpExecutor.request<T>(configureRequestOptions({hostname: "api.bintray.com", path, headers: this.requestHeaders || undefined}, auth, method), cancellationToken, data)
return this.httpExecutor.request(configureRequestOptions({hostname: "api.bintray.com", path, headers: this.requestHeaders || undefined}, auth, method), cancellationToken, data)
.then(it => JSON.parse(it))
}

getVersion(version: string): Promise<Version> {
return this.bintrayRequest<Version>(`${this.basePath}/versions/${version}`, this.auth, null, this.cancellationToken)
return this.bintrayRequest(`${this.basePath}/versions/${version}`, this.auth, null, this.cancellationToken)
}

getVersionFiles(version: string): Promise<Array<File>> {
Expand Down
26 changes: 11 additions & 15 deletions packages/electron-builder-http/src/httpExecutor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ export interface RequestHeaders {
[key: string]: any
}

// tslint:disable:no-empty-interface
export interface RequestOptionsEx extends RequestOptions {
}

export interface Response extends EventEmitter {
statusCode?: number
statusMessage?: string
Expand Down Expand Up @@ -49,22 +53,20 @@ export class HttpError extends Error {
export abstract class HttpExecutor<REQUEST> {
protected readonly maxRedirects = 10

request<T>(options: RequestOptions, cancellationToken: CancellationToken = new CancellationToken(), data?: { [name: string]: any; } | null): Promise<T> {
request(options: RequestOptions, cancellationToken: CancellationToken = new CancellationToken(), data?: { [name: string]: any; } | null): Promise<string> {
configureRequestOptions(options)
const encodedData = data == null ? undefined : new Buffer(JSON.stringify(data))
if (encodedData != null) {
options.method = "post"
options.headers!["Content-Type"] = "application/json"
options.headers!["Content-Length"] = encodedData.length
}
return this.doApiRequest<T>(options, cancellationToken, it => (it as any).end(encodedData), 0)
return this.doApiRequest(options, cancellationToken, it => (it as any).end(encodedData), 0)
}

protected abstract doApiRequest<T>(options: any, cancellationToken: CancellationToken, requestProcessor: (request: REQUEST, reject: (error: Error) => void) => void, redirectCount: number): Promise<T>

// abstract download(url: string, destination: string, options: DownloadOptions): Promise<string>
protected abstract doApiRequest(options: RequestOptions, cancellationToken: CancellationToken, requestProcessor: (request: REQUEST, reject: (error: Error) => void) => void, redirectCount: number): Promise<string>

protected handleResponse(response: Response, options: RequestOptions, cancellationToken: CancellationToken, resolve: (data?: any) => void, reject: (error: Error) => void, redirectCount: number, requestProcessor: (request: REQUEST, reject: (error: Error) => void) => void) {
protected handleResponse(response: Response, options: RequestOptionsEx, cancellationToken: CancellationToken, resolve: (data?: any) => void, reject: (error: Error) => void, redirectCount: number, requestProcessor: (request: REQUEST, reject: (error: Error) => void) => void) {
if (debug.enabled) {
debug(`Response status: ${response.statusCode} ${response.statusMessage}, request options: ${dumpRequestOptions(options)}`)
}
Expand Down Expand Up @@ -92,7 +94,7 @@ export abstract class HttpExecutor<REQUEST> {
}

const newUrl = parseUrl(redirectUrl)
this.doApiRequest({...options, ...newUrl}, cancellationToken, requestProcessor, redirectCount)
this.doApiRequest({...options, ...newUrl as any}, cancellationToken, requestProcessor, redirectCount)
.then(resolve)
.catch(reject)
return
Expand All @@ -107,18 +109,12 @@ export abstract class HttpExecutor<REQUEST> {
response.on("end", () => {
try {
const contentType = response.headers["content-type"]
const isJson = contentType != null && (Array.isArray(contentType) ? contentType.find(it => it.includes("json")) != null : contentType.includes("json"))
if (response.statusCode != null && response.statusCode >= 400) {
const isJson = contentType != null && (Array.isArray(contentType) ? contentType.find(it => it.includes("json")) != null : contentType.includes("json"))
reject(new HttpError(response, isJson ? JSON.parse(data) : data))
}
else {
const pathname = (options as any).pathname || options.path
if (data.length === 0) {
resolve()
}
else {
resolve(isJson || (pathname != null && pathname.endsWith(".json")) ? JSON.parse(data) : data)
}
resolve(data.length === 0 ? null : data)
}
}
catch (e) {
Expand Down
2 changes: 1 addition & 1 deletion packages/electron-builder-util/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
"bluebird-lst": "^1.0.2",
"chalk": "^2.0.1",
"debug": "^2.6.8",
"node-emoji": "^1.7.0",
"node-emoji": "^1.8.1",
"electron-builder-http": "~0.0.0-semantic-release",
"source-map-support": "^0.4.15",
"7zip-bin": "^2.1.0",
Expand Down
6 changes: 3 additions & 3 deletions packages/electron-builder-util/src/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,15 +50,15 @@ export function exec(file: string, args?: Array<string> | null, options?: ExecOp
debug(stdout)
}
}
resolve(stdout)
resolve(stdout.toString())
}
else {
let message = red(removePassword(`Exit code: ${(error as any).code}. ${error.message}`))
if (stdout.length !== 0) {
message += `\n${yellow(stdout)}`
message += `\n${yellow(stdout.toString())}`
}
if (stderr.length !== 0) {
message += `\n${red(stderr)}`
message += `\n${red(stderr.toString())}`
}

reject(new Error(message))
Expand Down
2 changes: 1 addition & 1 deletion packages/electron-builder/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@
"parse-color": "^1.0.0",
"plist": "^2.1.0",
"sanitize-filename": "^1.6.1",
"semver": "^5.3.0",
"semver": "^5.4.1",
"update-notifier": "^2.2.0",
"uuid-1345": "^0.99.6",
"yargs": "^8.0.2",
Expand Down
1 change: 1 addition & 0 deletions packages/electron-builder/src/options/winOptions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,7 @@ export interface NsisWebOptions extends NsisOptions {
* The application package download URL. Optional — by default computed using publish configuration.
*
* URL like `https://example.com/download/latest` allows web installer to be version independent (installer will download latest application package).
* Please note — it is [full URL](https://github.com/electron-userland/electron-builder/issues/1810#issuecomment-317650878).
*
* Custom `X-Arch` http header is set to `32` or `64`.
*/
Expand Down
4 changes: 2 additions & 2 deletions packages/electron-builder/src/util/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -131,13 +131,13 @@ export async function computeElectronVersion(projectDir: string, projectMetadata
const electronPrebuiltDep = findFromElectronPrebuilt(projectMetadata || await readJson(packageJsonPath))
if (electronPrebuiltDep == null || electronPrebuiltDep === "latest") {
try {
const releaseInfo = await httpExecutor.request<any>({
const releaseInfo = JSON.parse(await httpExecutor.request({
hostname: "github.com",
path: "/electron/electron/releases/latest",
headers: {
Accept: "application/json",
},
}, new CancellationToken())
}, new CancellationToken()))
return (releaseInfo.tag_name.startsWith("v")) ? releaseInfo.tag_name.substring(1) : releaseInfo.tag_name
}
catch (e) {
Expand Down
3 changes: 2 additions & 1 deletion packages/electron-publish/src/gitHubPublisher.ts
Original file line number Diff line number Diff line change
Expand Up @@ -198,12 +198,13 @@ export class GitHubPublisher extends HttpPublisher {
private githubRequest<T>(path: string, token: string | null, data: {[name: string]: any; } | null = null, method?: "GET" | "DELETE" | "PUT"): Promise<T> {
// host can contains port, but node http doesn't support host as url does
const baseUrl = parseUrl(`https://${this.info.host || "api.github.com"}`)
return httpExecutor.request<T>(configureRequestOptions({
return httpExecutor.request(configureRequestOptions({
hostname: baseUrl.hostname,
port: baseUrl.port as any,
path: (this.info.host != null && this.info.host !== "github.com") ? `/api/v3${path.startsWith("/") ? path : `/${path}`}` : path,
headers: {Accept: "application/vnd.github.v3+json"}
}, token, method), this.context.cancellationToken, data)
.then(it => JSON.parse(it))
}

toString() {
Expand Down
2 changes: 1 addition & 1 deletion packages/electron-publisher-s3/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
],
"dependencies": {
"fs-extra-p": "^4.4.0",
"aws-sdk": "^2.87.0",
"aws-sdk": "^2.89.0",
"mime": "^1.3.6",
"electron-publish": "~0.0.0-semantic-release",
"electron-builder-util": "~0.0.0-semantic-release",
Expand Down
4 changes: 2 additions & 2 deletions packages/electron-updater/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@
"bluebird-lst": "^1.0.2",
"fs-extra-p": "^4.4.0",
"js-yaml": "^3.9.0",
"semver": "^5.3.0",
"semver": "^5.4.1",
"source-map-support": "^0.4.15",
"electron-builder-http": "~0.0.0-semantic-release",
"electron-is-dev": "^0.2.0",
"electron-is-dev": "^0.3.0",
"xelement": "^1.0.16",
"debug": "^2.6.8",
"uuid-1345": "^0.99.6",
Expand Down
9 changes: 4 additions & 5 deletions packages/electron-updater/src/GenericProvider.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { HttpError, HttpExecutor } from "electron-builder-http"
import { HttpError, HttpExecutor, RequestOptionsEx } from "electron-builder-http"
import { GenericServerOptions } from "electron-builder-http/out/publishOptions"
import { UpdateInfo } from "electron-builder-http/out/updateInfo"
import { RequestOptions } from "http"
import { safeLoad } from "js-yaml"
import * as path from "path"
import * as url from "url"
Expand All @@ -20,16 +19,16 @@ export class GenericProvider extends Provider<UpdateInfo> {
const channelFile = getChannelFilename(this.channel)
const pathname = path.posix.resolve(this.baseUrl.pathname || "/", channelFile)
try {
const options: RequestOptions = {
const options: RequestOptionsEx = {
hostname: this.baseUrl.hostname,
path: `${pathname}${this.baseUrl.search || ""}`,
protocol: this.baseUrl.protocol,
headers: this.requestHeaders || undefined
headers: this.requestHeaders || undefined,
}
if (this.baseUrl.port != null) {
options.port = parseInt(this.baseUrl.port, 10)
}
result = safeLoad(await this.executor.request<string>(options))
result = safeLoad(await this.executor.request(options))
}
catch (e) {
if (e instanceof HttpError && e.response.statusCode === 404) {
Expand Down
12 changes: 6 additions & 6 deletions packages/electron-updater/src/GitHubProvider.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { CancellationToken, HttpError, HttpExecutor } from "electron-builder-http"
import { CancellationToken, HttpError, HttpExecutor, RequestOptionsEx } from "electron-builder-http"
import { GithubOptions, githubUrl } from "electron-builder-http/out/publishOptions"
import { UpdateInfo } from "electron-builder-http/out/updateInfo"
import { RequestOptions } from "http"
Expand Down Expand Up @@ -37,7 +37,7 @@ export class GitHubProvider extends BaseGitHubProvider<UpdateInfo> {
const feedXml = await this.executor.request({
path: `${basePath}.atom`,
headers: {...this.requestHeaders, Accept: "application/xml, application/atom+xml, text/xml, */*"},
...this.baseUrl
...this.baseUrl as any
}, cancellationToken)

const feed = new xElement.Parse(feedXml)
Expand All @@ -64,7 +64,7 @@ export class GitHubProvider extends BaseGitHubProvider<UpdateInfo> {
const requestOptions = {path: this.getBaseDownloadPath(version, channelFile), headers: this.requestHeaders || undefined, ...this.baseUrl}
let rawData: string
try {
rawData = await this.executor.request<string>(requestOptions, cancellationToken)
rawData = await this.executor.request(requestOptions, cancellationToken)
}
catch (e) {
if (!this.updater.allowPrerelease) {
Expand Down Expand Up @@ -97,12 +97,12 @@ export class GitHubProvider extends BaseGitHubProvider<UpdateInfo> {
}

private async getLatestVersionString(basePath: string, cancellationToken: CancellationToken): Promise<string> {
const requestOptions: RequestOptions = {
const requestOptions: RequestOptionsEx = {
path: `${basePath}/latest`,
headers: {...this.requestHeaders, Accept: "application/json"}, ...this.baseUrl}
headers: {...this.requestHeaders, Accept: "application/json"}, ...this.baseUrl as any}
try {
// do not use API to avoid limit
const releaseInfo = (await this.executor.request<GithubReleaseInfo>(requestOptions, cancellationToken))
const releaseInfo: GithubReleaseInfo = JSON.parse(await this.executor.request(requestOptions, cancellationToken))
return (releaseInfo.tag_name.startsWith("v")) ? releaseInfo.tag_name.substring(1) : releaseInfo.tag_name
}
catch (e) {
Expand Down
19 changes: 11 additions & 8 deletions packages/electron-updater/src/PrivateGitHubProvider.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import { session } from "electron"
import { CancellationToken, HttpError, HttpExecutor } from "electron-builder-http"
import { CancellationToken, HttpError, HttpExecutor, RequestOptionsEx } from "electron-builder-http"
import { GithubOptions } from "electron-builder-http/out/publishOptions"
import { UpdateInfo } from "electron-builder-http/out/updateInfo"
import { RequestOptions } from "http"
import { safeLoad } from "js-yaml"
import * as path from "path"
import { parse as parseUrl } from "url"
Expand All @@ -29,12 +28,14 @@ export class PrivateGitHubProvider extends BaseGitHubProvider<PrivateGitHubUpdat
const channelFile = getChannelFilename(getDefaultChannelName())

const assets = await this.getLatestVersionInfo(basePath, cancellationToken)
const requestOptions = {
const requestOptions: RequestOptionsEx = {
headers: this.configureHeaders("application/octet-stream"),
session: this.netSession, ...parseUrl(assets.find(it => it.name === channelFile)!.url)}
session: this.netSession,
...parseUrl(assets.find(it => it.name === channelFile)!.url) as any,
}
let result: any
try {
result = safeLoad(await this.executor.request<string>(requestOptions, cancellationToken))
result = safeLoad(await this.executor.request(requestOptions, cancellationToken))
}
catch (e) {
if (e instanceof HttpError && e.response.statusCode === 404) {
Expand Down Expand Up @@ -69,11 +70,13 @@ export class PrivateGitHubProvider extends BaseGitHubProvider<PrivateGitHubUpdat
}

private async getLatestVersionInfo(basePath: string, cancellationToken: CancellationToken): Promise<Array<Asset>> {
const requestOptions: RequestOptions = {
const requestOptions: RequestOptionsEx = {
path: `${basePath}/latest`,
headers: this.configureHeaders("application/vnd.github.v3+json"), ...this.baseUrl}
headers: this.configureHeaders("application/vnd.github.v3+json"), ...this.baseUrl as any,
isParseJson: false,
}
try {
return (await this.executor.request<any>(requestOptions, cancellationToken)).assets
return (JSON.parse(await this.executor.request(requestOptions, cancellationToken))).assets
}
catch (e) {
throw new Error(`Unable to find latest version on GitHub (${formatUrl(requestOptions as any)}), please ensure a production release exists: ${e.stack || e.message}`)
Expand Down
4 changes: 2 additions & 2 deletions packages/electron-updater/src/electronHttpExecutor.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import _debug from "debug"
import { net, session } from "electron"
import { CancellationToken, configureRequestOptions, DownloadOptions, dumpRequestOptions, HttpExecutor } from "electron-builder-http"
import { CancellationToken, configureRequestOptions, DownloadOptions, dumpRequestOptions, HttpExecutor, RequestOptionsEx } from "electron-builder-http"
import { ensureDir } from "fs-extra-p"
import * as path from "path"
import { parse as parseUrl } from "url"
Expand Down Expand Up @@ -41,7 +41,7 @@ export class ElectronHttpExecutor extends HttpExecutor<Electron.ClientRequest> {
})
}

doApiRequest<T>(options: any, cancellationToken: CancellationToken, requestProcessor: (request: Electron.ClientRequest, reject: (error: Error) => void) => void, redirectCount: number = 0): Promise<T> {
doApiRequest<T>(options: RequestOptionsEx, cancellationToken: CancellationToken, requestProcessor: (request: Electron.ClientRequest, reject: (error: Error) => void) => void, redirectCount: number = 0): Promise<T> {
if (debug.enabled) {
debug(`request: ${dumpRequestOptions(options)}`)
}
Expand Down
Loading

0 comments on commit 8a0d075

Please sign in to comment.