Skip to content

Commit 6c8607b

Browse files
authored
Merge pull request #95 from NativeScript/buhov/refactoring
Refactoring
2 parents 506766e + 5cf5643 commit 6c8607b

39 files changed

+932
-980
lines changed

package.json

+17-48
Original file line numberDiff line numberDiff line change
@@ -111,81 +111,58 @@
111111
{
112112
"name": "Sync on iOS",
113113
"type": "nativescript",
114-
"platform": "ios",
115114
"request": "launch",
115+
"platform": "ios",
116116
"appRoot": "${workspaceRoot}",
117-
"sourceMaps": true,
118-
"diagnosticLogging": false,
119-
"emulator": false,
120-
"rebuild": false,
121-
"syncAllFiles": false
117+
"sourceMaps": true
122118
},
123119
{
124120
"name": "Launch on iOS",
125121
"type": "nativescript",
126-
"platform": "ios",
127122
"request": "launch",
123+
"platform": "ios",
128124
"appRoot": "${workspaceRoot}",
129125
"sourceMaps": true,
130-
"diagnosticLogging": false,
131-
"emulator": false,
132126
"rebuild": true
133127
},
134128
{
135129
"name": "Attach on iOS",
136130
"type": "nativescript",
137-
"platform": "ios",
138131
"request": "attach",
132+
"platform": "ios",
139133
"appRoot": "${workspaceRoot}",
140-
"sourceMaps": true,
141-
"diagnosticLogging": false,
142-
"emulator": false
134+
"sourceMaps": true
143135
},
144136
{
145137
"name": "Sync on Android",
146138
"type": "nativescript",
147-
"platform": "android",
148139
"request": "launch",
140+
"platform": "android",
149141
"appRoot": "${workspaceRoot}",
150-
"sourceMaps": true,
151-
"diagnosticLogging": false,
152-
"emulator": false,
153-
"rebuild": false
142+
"sourceMaps": true
154143
},
155144
{
156145
"name": "Launch on Android",
157146
"type": "nativescript",
158-
"platform": "android",
159147
"request": "launch",
148+
"platform": "android",
160149
"appRoot": "${workspaceRoot}",
161150
"sourceMaps": true,
162-
"diagnosticLogging": false,
163-
"emulator": false,
164151
"rebuild": true
165152
},
166153
{
167154
"name": "Attach on Android",
168155
"type": "nativescript",
169-
"platform": "android",
170156
"request": "attach",
157+
"platform": "android",
171158
"appRoot": "${workspaceRoot}",
172-
"sourceMaps": true,
173-
"diagnosticLogging": false,
174-
"emulator": false
159+
"sourceMaps": true
175160
}
176161
],
177162
"configurationAttributes": {
178163
"launch": {
179164
"required": [],
180165
"properties": {
181-
"runtimeArgs": {
182-
"type": "array",
183-
"description": "Optional arguments passed to the runtime executable.",
184-
"items": {
185-
"type": "string"
186-
},
187-
"default": []
188-
},
189166
"tnsArgs": {
190167
"type": "array",
191168
"description": "Optional arguments passed to the NativeScript CLI executable.",
@@ -219,9 +196,14 @@
219196
"description": "NativeScript platform",
220197
"default": null
221198
},
222-
"emulator": {
199+
"stopOnEntry": {
223200
"type": "boolean",
224-
"description": "Whether the app to run in emulator or on a physical device.",
201+
"description": "Automatically stop on the first line after lauch",
202+
"default": false
203+
},
204+
"noDebug": {
205+
"type": "boolean",
206+
"description": "If true the launch request will launch the program without enabling debugging",
225207
"default": false
226208
},
227209
"rebuild": {
@@ -244,14 +226,6 @@
244226
"attach": {
245227
"required": [],
246228
"properties": {
247-
"runtimeArgs": {
248-
"type": "array",
249-
"description": "Optional arguments passed to the runtime executable.",
250-
"items": {
251-
"type": "string"
252-
},
253-
"default": []
254-
},
255229
"tnsArgs": {
256230
"type": "array",
257231
"description": "Optional arguments passed to the NativeScript CLI executable.",
@@ -285,11 +259,6 @@
285259
"description": "NativeScript platform",
286260
"default": null
287261
},
288-
"emulator": {
289-
"type": "boolean",
290-
"description": "Whether the app to run in emulator or on a physical device.",
291-
"default": false
292-
},
293262
"nativescriptCliPath": {
294263
"type": "string",
295264
"description": "Path to the nativescript CLI to be used by the NativeScript extension.",

src/services/analytics/AnalyticsService.ts renamed to src/analytics/AnalyticsService.ts

+6-15
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,18 @@
11
import * as os from 'os';
22
import * as vscode from 'vscode';
3-
import { Version } from '../../common/Version';
3+
import { Version } from '../common/version';
44
import { GUAService } from './GUAService';
55
import { TelerikAnalyticsService } from './TelerikAnalyticsService';
66
import { AnalyticsBaseInfo, OperatingSystem } from './AnalyticsBaseInfo';
7-
import { ExtensionVersionInfo } from '../ExtensionVersionInfo';
8-
import * as ns from '../NsCliService';
7+
import { ExtensionHostServices as Services } from '../services/extensionHostServices';
8+
import * as utils from '../common/utilities';
99

1010
export class AnalyticsService {
11-
private static _instance: AnalyticsService;
12-
1311
private _baseInfo: AnalyticsBaseInfo;
1412
private _gua: GUAService;
1513
private _ta: TelerikAnalyticsService;
1614
private _analyticsEnabled: boolean;
1715

18-
public static getInstance(): AnalyticsService {
19-
if (!this._instance) {
20-
this._instance = new AnalyticsService();
21-
}
22-
return this._instance;
23-
}
24-
2516
public static generateMachineId(): string {
2617
let machineId = '';
2718
try {
@@ -48,8 +39,8 @@ export class AnalyticsService {
4839
};
4940

5041
this._baseInfo = {
51-
cliVersion: Version.stringify(ns.CliVersionInfo.getInstalledCliVersion()),
52-
extensionVersion: Version.stringify(ExtensionVersionInfo.getExtensionVersion()),
42+
cliVersion: Services.cli.version.toString(),
43+
extensionVersion: utils.getInstalledExtensionVersion().toString(),
5344
operatingSystem: operatingSystem,
5445
userId: AnalyticsService.generateMachineId()
5546
};
@@ -79,7 +70,7 @@ export class AnalyticsService {
7970
this._gua.runRunCommand(platform),
8071
this._ta.runRunCommand(platform)
8172
]);
82-
} catch(e) {}
73+
} catch(e) { }
8374
}
8475
return Promise.resolve();
8576
}
File renamed without changes.

src/common/Logger.ts

+101
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
import * as fs from 'fs';
2+
3+
export enum LoggerMessageType {
4+
Log,
5+
Info,
6+
Warning,
7+
Error
8+
}
9+
10+
export interface LoggerMessageEventArgs {
11+
message: string,
12+
type: LoggerMessageType
13+
}
14+
15+
export type LoggerHandler = ((args: LoggerMessageEventArgs) => void);
16+
type TaggedLoggerHandler = { handler: LoggerHandler, tags: string[] };
17+
18+
/**
19+
* The logger is a singleton.
20+
*/
21+
export class Logger {
22+
private _handlers: TaggedLoggerHandler[];
23+
24+
constructor() {
25+
this._handlers = [];
26+
}
27+
28+
private handleMessage(message: string, type: LoggerMessageType = LoggerMessageType.Log, tag: string = null) {
29+
for (let handler of this._handlers) {
30+
if (!handler.tags || handler.tags.length == 0 || handler.tags.indexOf(tag) > -1) {
31+
handler.handler({ message: message, type: type });
32+
}
33+
}
34+
}
35+
36+
public log(message: string, tag: string = null): void {
37+
this.handleMessage(message, LoggerMessageType.Log, tag);
38+
}
39+
40+
public info(message: string, tag: string = null): void {
41+
this.handleMessage(message, LoggerMessageType.Info, tag);
42+
}
43+
44+
public warn(message: string, tag: string = null): void {
45+
this.handleMessage(message, LoggerMessageType.Warning, tag);
46+
}
47+
48+
public error(message: string, tag: string = null): void {
49+
this.handleMessage(message, LoggerMessageType.Error, tag);
50+
}
51+
52+
public addHandler(handler: LoggerHandler, tags: string[] = null) {
53+
tags = tags || [];
54+
this._handlers.push({ handler: handler, tags: tags });
55+
}
56+
57+
/**
58+
* Removes all occurrence of this handler, ignoring the associated tags
59+
*/
60+
public removeHandler(handlerToRemove: LoggerHandler) {
61+
let i = this._handlers.length;
62+
while (i--) {
63+
if (this._handlers[i].handler == handlerToRemove) {
64+
this._handlers.splice(i, 1);
65+
}
66+
}
67+
}
68+
}
69+
70+
export namespace Tags {
71+
export const FrontendMessage: string = "LoggerTag.FrontendMessage";
72+
}
73+
74+
export namespace Handlers {
75+
export function stdStreamsHandler(args: LoggerMessageEventArgs) {
76+
switch(args.type) {
77+
case LoggerMessageType.Log:
78+
console.log(args.message);
79+
break;
80+
case LoggerMessageType.Info:
81+
console.info(args.message);
82+
break;
83+
case LoggerMessageType.Warning:
84+
console.warn(args.message);
85+
break;
86+
case LoggerMessageType.Error:
87+
console.error(args.message);
88+
break;
89+
}
90+
};
91+
92+
export function createStreamHandler(stream: fs.WriteStream, encoding: string = 'utf8'): LoggerHandler {
93+
let isStreamClosed = false;
94+
stream.on('close', () => { isStreamClosed = true; });
95+
return (args: LoggerMessageEventArgs) => {
96+
if (stream && !isStreamClosed) {
97+
stream.write(args.message, encoding);
98+
}
99+
}
100+
}
101+
}

src/common/Version.ts

-20
This file was deleted.

src/common/extensionVersionService.ts

+84
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
import * as https from 'https';
2+
import * as vscode from 'vscode';
3+
import {Version} from './version';
4+
import * as utils from './utilities';
5+
6+
export type LatestPublishedVersionCheckResult = {latestPublishedVersion: string, timestamp: number};
7+
8+
export class ExtensionVersionService {
9+
private static _extensionId: string = '8d837914-d8fa-45b5-965d-f76ebd6dbf5c';
10+
private static _getLatestPublishedVersionPromise: Promise<LatestPublishedVersionCheckResult> = null;
11+
private _memento: vscode.Memento;
12+
13+
private static getExtensionMetadataFromVSCodeMarketplace(): Promise<LatestPublishedVersionCheckResult> {
14+
return new Promise<LatestPublishedVersionCheckResult>((resolve, reject) =>{
15+
let postData: string = `{ filters: [{ criteria: [{ filterType: 4, value: "${ExtensionVersionService._extensionId}" }] }], flags: 262 }`;
16+
17+
let request = https.request({
18+
hostname: 'marketplace.visualstudio.com',
19+
path: '/_apis/public/gallery/extensionquery',
20+
method: 'POST',
21+
headers: {
22+
'Accept': 'application/json;api-version=2.2-preview.1',
23+
'Content-Type': 'application/json',
24+
'Transfer-Encoding': 'chunked',
25+
'Content-Length': Buffer.byteLength(postData)
26+
}
27+
}, response => {
28+
if (response.statusCode != 200) {
29+
reject(`Unable to download data from Visual Studio Marketplace. Status code: ${response.statusCode}`);
30+
return;
31+
}
32+
let body = '';
33+
response.on('data', chunk => {
34+
body += chunk;
35+
});
36+
response.on('end', () => {
37+
let bodyObj = JSON.parse(body);
38+
if (bodyObj.results[0].extensions[0].extensionId == ExtensionVersionService._extensionId) {
39+
let latestPublishedVersion = bodyObj.results[0].extensions[0].versions[0].version;
40+
resolve({ latestPublishedVersion: latestPublishedVersion, timestamp: Date.now() });
41+
}
42+
});
43+
});
44+
45+
request.on('error', (e) => {
46+
reject(e);
47+
});
48+
49+
request.end(postData);
50+
});
51+
}
52+
53+
constructor(context: vscode.Memento) {
54+
this._memento = context;
55+
}
56+
57+
public get latestPublishedVersion(): Promise<Version> {
58+
if (ExtensionVersionService._getLatestPublishedVersionPromise) {
59+
return ExtensionVersionService._getLatestPublishedVersionPromise.then(result => Version.parse(result.latestPublishedVersion) );
60+
}
61+
62+
// Check the cache for extension version information
63+
let cachedResult: LatestPublishedVersionCheckResult = this._memento.get<LatestPublishedVersionCheckResult>('LatestPublishedExtensionVersion');
64+
if (cachedResult && cachedResult.timestamp > Date.now() - 24 * 60 * 60 * 1000) { // Version is cached for a day
65+
ExtensionVersionService._getLatestPublishedVersionPromise = Promise.resolve(cachedResult);
66+
}
67+
else {
68+
ExtensionVersionService._getLatestPublishedVersionPromise = ExtensionVersionService.getExtensionMetadataFromVSCodeMarketplace().then((result: LatestPublishedVersionCheckResult) => {
69+
this._memento.update('LatestPublishedExtensionVersion', result); // save in cache
70+
return result;
71+
});
72+
}
73+
return ExtensionVersionService._getLatestPublishedVersionPromise.then(result => Version.parse(result.latestPublishedVersion));
74+
}
75+
76+
public get isLatestInstalled(): Promise<{ result: boolean, error: string }> {
77+
return this.latestPublishedVersion.then(latestVersion => {
78+
let extensionVersion = utils.getInstalledExtensionVersion();
79+
let isLatest: boolean = extensionVersion.compareBySubminorTo(latestVersion) >= 0;
80+
let error = isLatest ? null : `A new version of the NativeScript extension is available. Open "Extensions" panel to update to v${latestVersion}.`;
81+
return {result: isLatest, error: error};
82+
});
83+
}
84+
}

0 commit comments

Comments
 (0)