microsoft/vscode-react-native

Public

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

CodeCommitsIssuesPull requestsActionsInsightsSecurity
1.5.1

Branches

Tags

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

Clone

HTTPS

Download ZIP

src/extension/exponent/exponentHelper.ts

511lines · modeblame

1c32fe84Patricio Beltran9 years ago1// Copyright (c) Microsoft Corporation. All rights reserved.
2// Licensed under the MIT license. See LICENSE file in the project root for details.
3
94cd5149Artem Egorov8 years ago4/// <reference path="exponentHelper.d.ts" />
5
1c32fe84Patricio Beltran9 years ago6import * as path from "path";
8f50947fRedMickey5 years ago7import * as semver from "semver";
efb436fcRedMickey5 years ago8import * as vscode from "vscode";
7059d307Patricio Beltran9 years ago9import * as XDL from "./xdlInterface";
66412fdfRuslan Bikkinin7 years ago10import { Package, IPackageInformation } from "../../common/node/package";
e3706a1cRedMickey6 years ago11import { ProjectVersionHelper } from "../../common/projectVersionHelper";
34472878RedMickey5 years ago12import { OutputChannelLogger } from "../log/OutputChannelLogger";
94cd5149Artem Egorov8 years ago13import stripJSONComments = require("strip-json-comments");
d7d405aeYuri Skorokhodov7 years ago14import * as nls from "vscode-nls";
15import { ErrorHelper } from "../../common/error/errorHelper";
efb436fcRedMickey5 years ago16import { getNodeModulesGlobalPath } from "../../common/utils";
17import PackageLoader from "../../common/packageLoader";
d7d405aeYuri Skorokhodov7 years ago18import { InternalErrorCode } from "../../common/error/internalErrorCode";
ce5e88eeYuri Skorokhodov5 years ago19import { FileSystem } from "../../common/node/fileSystem";
34472878RedMickey5 years ago20nls.config({
21messageFormat: nls.MessageFormat.bundle,
22bundleFormat: nls.BundleFormat.standalone,
23})();
d7d405aeYuri Skorokhodov7 years ago24const localize = nls.loadMessageBundle();
1c32fe84Patricio Beltran9 years ago25
94cd5149Artem Egorov8 years ago26const APP_JSON = "app.json";
27const EXP_JSON = "exp.json";
1c32fe84Patricio Beltran9 years ago28
29const EXPONENT_INDEX = "exponentIndex.js";
94cd5149Artem Egorov8 years ago30const DEFAULT_EXPONENT_INDEX = "index.js";
1c32fe84Patricio Beltran9 years ago31const DEFAULT_IOS_INDEX = "index.ios.js";
32const DEFAULT_ANDROID_INDEX = "index.android.js";
33
94cd5149Artem Egorov8 years ago34const DBL_SLASHES = /\\/g;
1c32fe84Patricio Beltran9 years ago35
efb436fcRedMickey5 years ago36const NGROK_PACKAGE = "@expo/ngrok";
37
1c32fe84Patricio Beltran9 years ago38export class ExponentHelper {
38edb09eAlexander Sorokin9 years ago39private workspaceRootPath: string;
94cd5149Artem Egorov8 years ago40private projectRootPath: string;
2956dba4Yuri Skorokhodov7 years ago41private fs: FileSystem;
a57e740bPatricio Beltran9 years ago42private hasInitialized: boolean;
efb436fcRedMickey5 years ago43private nodeModulesGlobalPathAddedToEnv: boolean;
0a68f8dbArtem Egorov8 years ago44private logger: OutputChannelLogger = OutputChannelLogger.getMainChannel();
1c32fe84Patricio Beltran9 years ago45
34472878RedMickey5 years ago46public constructor(
47workspaceRootPath: string,
48projectRootPath: string,
49fs: FileSystem = new FileSystem(),
50) {
38edb09eAlexander Sorokin9 years ago51this.workspaceRootPath = workspaceRootPath;
52this.projectRootPath = projectRootPath;
2956dba4Yuri Skorokhodov7 years ago53this.fs = fs;
a57e740bPatricio Beltran9 years ago54this.hasInitialized = false;
55// Constructor is slim by design. This is to add as less computation as possible
56// to the initialization of the extension. If a public method is added, make sure
b0af599cJimmy Thomson9 years ago57// to call this.lazilyInitialize() at the begining of the code to be sure all variables
a57e740bPatricio Beltran9 years ago58// are correctly initialized.
efb436fcRedMickey5 years ago59this.nodeModulesGlobalPathAddedToEnv = false;
1c32fe84Patricio Beltran9 years ago60}
61
ce5e88eeYuri Skorokhodov5 years ago62public configureExponentEnvironment(): Promise<void> {
d1d77244Jimmy Thomson9 years ago63this.lazilyInitialize();
34472878RedMickey5 years ago64this.logger.info(
65localize(
66"MakingSureYourProjectUsesCorrectExponentDependencies",
67"Making sure your project uses the correct dependencies for Expo. This may take a while...",
68),
69);
d7d405aeYuri Skorokhodov7 years ago70this.logger.logStream(localize("CheckingIfThisIsExpoApp", "Checking if this is Expo app."));
66412fdfRuslan Bikkinin7 years ago71let isExpo: boolean;
72return this.isExpoApp(true)
73.then(result => {
74isExpo = result;
75if (!isExpo) {
34472878RedMickey5 years ago76return this.appHasExpoInstalled().then(expoInstalled => {
66412fdfRuslan Bikkinin7 years ago77if (!expoInstalled) {
78// Expo requires expo package to be installed inside RN application in order to be able to run it
79// https://github.com/expo/expo-cli/issues/255#issuecomment-453214632
80this.logger.logStream("\n");
34472878RedMickey5 years ago81this.logger.logStream(
82localize(
83"ExpoPackageIsNotInstalled",
84'[Warning] Please make sure that expo package is installed locally for your project, otherwise further errors may occur. Please, run "npm install expo --save-dev" inside your project to install it.',
85),
86);
66412fdfRuslan Bikkinin7 years ago87this.logger.logStream("\n");
88}
89});
90}
91return;
34472878RedMickey5 years ago92})
93.then(() => {
0a68f8dbArtem Egorov8 years ago94this.logger.logStream(".\n");
94cd5149Artem Egorov8 years ago95return this.patchAppJson(isExpo);
96});
d1d77244Jimmy Thomson9 years ago97}
98
99/**
100* Returns the current user. If there is none, asks user for username and password and logins to exponent servers.
101*/
5c8365a6Artem Egorov8 years ago102public loginToExponent(
ce5e88eeYuri Skorokhodov5 years ago103promptForInformation: (message: string, password: boolean) => Promise<string>,
34472878RedMickey5 years ago104showMessage: (message: string) => Promise<string>,
ce5e88eeYuri Skorokhodov5 years ago105): Promise<XDL.IUser> {
d1d77244Jimmy Thomson9 years ago106this.lazilyInitialize();
107return XDL.currentUser()
34472878RedMickey5 years ago108.then(user => {
d1d77244Jimmy Thomson9 years ago109if (!user) {
110let username = "";
34472878RedMickey5 years ago111return showMessage(
112localize(
113"YouNeedToLoginToExpo",
114"You need to login to Expo. Please provide your Expo account username and password in the input boxes after closing this window. If you don't have an account, please go to https://expo.io to create one.",
115),
116)
d1d77244Jimmy Thomson9 years ago117.then(() =>
34472878RedMickey5 years ago118promptForInformation(localize("ExpoUsername", "Expo username"), false),
119)
120.then((name: string) => {
d1d77244Jimmy Thomson9 years ago121username = name;
34472878RedMickey5 years ago122return promptForInformation(
123localize("ExpoPassword", "Expo password"),
124true,
125);
d1d77244Jimmy Thomson9 years ago126})
34472878RedMickey5 years ago127.then((password: string) => XDL.login(username, password));
d1d77244Jimmy Thomson9 years ago128}
129return user;
130})
131.catch(error => {
ce5e88eeYuri Skorokhodov5 years ago132return Promise.reject<XDL.IUser>(error);
d1d77244Jimmy Thomson9 years ago133});
134}
135
242759feJiglioNero5 years ago136public async getExpPackagerOptions(projectRoot: string): Promise<ExpMetroConfig> {
6458f408Nikita Matrosov9 years ago137this.lazilyInitialize();
242759feJiglioNero5 years ago138const options = await this.getFromExpConfig<any>("packagerOpts").then(opts => opts || {});
139const metroConfig = await this.getArgumentsFromExpoMetroConfig(projectRoot);
140return { ...options, ...metroConfig };
6458f408Nikita Matrosov9 years ago141}
142
ce5e88eeYuri Skorokhodov5 years ago143public appHasExpoInstalled(): Promise<boolean> {
34472878RedMickey5 years ago144return this.getAppPackageInformation().then((packageJson: IPackageInformation) => {
145if (packageJson.dependencies && packageJson.dependencies.expo) {
146this.logger.debug(
147"'expo' package is found in 'dependencies' section of package.json",
148);
149return true;
150} else if (packageJson.devDependencies && packageJson.devDependencies.expo) {
151this.logger.debug(
152"'expo' package is found in 'devDependencies' section of package.json",
153);
154return true;
155}
156return false;
157});
66412fdfRuslan Bikkinin7 years ago158}
159
ce5e88eeYuri Skorokhodov5 years ago160public appHasExpoRNSDKInstalled(): Promise<boolean> {
34472878RedMickey5 years ago161return this.getAppPackageInformation().then((packageJson: IPackageInformation) => {
162const reactNativeValue: string | undefined =
163packageJson.dependencies && packageJson.dependencies["react-native"];
164if (reactNativeValue) {
165this.logger.debug(
166`'react-native' package with value '${reactNativeValue}' is found in 'dependencies' section of package.json`,
167);
168if (
169reactNativeValue.startsWith("https://github.com/expo/react-native/archive/sdk")
170) {
171return true;
66412fdfRuslan Bikkinin7 years ago172}
34472878RedMickey5 years ago173}
174return false;
175});
66412fdfRuslan Bikkinin7 years ago176}
177
ce5e88eeYuri Skorokhodov5 years ago178public isExpoApp(showProgress: boolean = false): Promise<boolean> {
db6fd42aRuslan Bikkinin7 years ago179if (showProgress) {
180this.logger.logStream("...");
181}
182
34472878RedMickey5 years ago183return Promise.all([this.appHasExpoInstalled(), this.appHasExpoRNSDKInstalled()])
184.then(([expoInstalled, expoRNSDKInstalled]) => {
ce5e88eeYuri Skorokhodov5 years ago185if (showProgress) this.logger.logStream(".");
186return expoInstalled && expoRNSDKInstalled;
34472878RedMickey5 years ago187})
188.catch(e => {
66412fdfRuslan Bikkinin7 years ago189this.logger.error(e.message, e, e.stack);
db6fd42aRuslan Bikkinin7 years ago190if (showProgress) {
191this.logger.logStream(".");
192}
193// Not in a react-native project
194return false;
195});
196}
197
efb436fcRedMickey5 years ago198public findOrInstallNgrokGlobally(): Promise<void> {
199return this.addNodeModulesPathToEnvIfNotPresent()
200.then(() => XDL.isNgrokInstalled(this.projectRootPath))
201.catch(() => false)
202.then(ngrokInstalled => {
203if (!ngrokInstalled) {
204const outputMessage = localize(
205"ExpoInstallNgrokGlobally",
206'It seems that "@expo/ngrok" package isn\'t installed globally. This package is required to use Expo tunnels, would you like to install it globally?',
207);
208const installButton = localize("InstallNgrokGloballyButtonOK", "Install");
209const cancelButton = localize("InstallNgrokGloballyButtonCancel", "Cancel");
210
211return vscode.window
212.showWarningMessage(outputMessage, installButton, cancelButton)
213.then(selectedItem => {
214if (selectedItem === installButton) {
215return PackageLoader.getInstance()
216.installGlobalPackage(NGROK_PACKAGE, this.projectRootPath)
217.then(() => {
218this.logger.info(
219localize(
220"NgrokInstalledGlobally",
221'"@expo/ngrok" package has been successfully installed globally.',
222),
223);
224});
225}
226throw ErrorHelper.getInternalError(
227InternalErrorCode.NgrokIsNotInstalledGlobally,
228);
229});
230}
231return void 0;
232});
233}
234
235public removeNodeModulesPathFromEnvIfWasSet(): void {
236if (this.nodeModulesGlobalPathAddedToEnv) {
237delete process.env["NODE_MODULES"];
238this.nodeModulesGlobalPathAddedToEnv = false;
239}
240}
241
242public addNodeModulesPathToEnvIfNotPresent(): Promise<void> {
243if (!process.env["NODE_MODULES"]) {
244return getNodeModulesGlobalPath().then(nodeModulesGlobalPath => {
245process.env["NODE_MODULES"] = nodeModulesGlobalPath;
246this.nodeModulesGlobalPathAddedToEnv = true;
247});
248}
249return Promise.resolve();
250}
251
252private async getArgumentsFromExpoMetroConfig(projectRoot: string): Promise<ExpMetroConfig> {
253return XDL.getMetroConfig(projectRoot).then(config => {
254return { sourceExts: config.resolver.sourceExts };
255});
256}
257
1c32fe84Patricio Beltran9 years ago258/**
94cd5149Artem Egorov8 years ago259* Path to a given file inside the .vscode directory
1c32fe84Patricio Beltran9 years ago260*/
66412fdfRuslan Bikkinin7 years ago261private dotvscodePath(filename: string, isAbsolute: boolean): string {
262let paths = [".vscode", filename];
263if (isAbsolute) {
264paths = [this.workspaceRootPath].concat(...paths);
265}
266return path.join(...paths);
94cd5149Artem Egorov8 years ago267}
268
ce5e88eeYuri Skorokhodov5 years ago269private createExpoEntry(name: string): Promise<void> {
b0af599cJimmy Thomson9 years ago270this.lazilyInitialize();
34472878RedMickey5 years ago271return this.detectEntry().then((entryPoint: string) => {
272const content = this.generateFileContent(name, entryPoint);
273return this.fs.writeFile(this.dotvscodePath(EXPONENT_INDEX, true), content);
274});
94cd5149Artem Egorov8 years ago275}
1c32fe84Patricio Beltran9 years ago276
ce5e88eeYuri Skorokhodov5 years ago277private detectEntry(): Promise<string> {
94cd5149Artem Egorov8 years ago278this.lazilyInitialize();
ce5e88eeYuri Skorokhodov5 years ago279return Promise.all([
94cd5149Artem Egorov8 years ago280this.fs.exists(this.pathToFileInWorkspace(DEFAULT_EXPONENT_INDEX)),
281this.fs.exists(this.pathToFileInWorkspace(DEFAULT_IOS_INDEX)),
282this.fs.exists(this.pathToFileInWorkspace(DEFAULT_ANDROID_INDEX)),
ce5e88eeYuri Skorokhodov5 years ago283]).then(([expo, ios]) => {
34472878RedMickey5 years ago284return expo
285? this.pathToFileInWorkspace(DEFAULT_EXPONENT_INDEX)
286: ios
287? this.pathToFileInWorkspace(DEFAULT_IOS_INDEX)
288: this.pathToFileInWorkspace(DEFAULT_ANDROID_INDEX);
ce5e88eeYuri Skorokhodov5 years ago289});
94cd5149Artem Egorov8 years ago290}
1c32fe84Patricio Beltran9 years ago291
94cd5149Artem Egorov8 years ago292private generateFileContent(name: string, entryPoint: string): string {
293return `// This file is automatically generated by VS Code
294// Please do not modify it manually. All changes will be lost.
295var React = require('${this.pathToFileInWorkspace("/node_modules/react")}');
296var { Component } = React;
297var ReactNative = require('${this.pathToFileInWorkspace("/node_modules/react-native")}');
298var { AppRegistry } = ReactNative;
f6b41bbfAlexander Sorokin9 years ago299AppRegistry.registerRunnable('main', function(appParameters) {
94cd5149Artem Egorov8 years ago300AppRegistry.runApplication('${name}', appParameters);
253b6e8eRedMickey5 years ago301});
302var entryPoint = require('${entryPoint}');`;
1c32fe84Patricio Beltran9 years ago303}
304
ce5e88eeYuri Skorokhodov5 years ago305private patchAppJson(isExpo: boolean = true): Promise<void> {
94cd5149Artem Egorov8 years ago306return this.readAppJson()
307.catch(() => {
308// if app.json doesn't exist but it's ok, we will create it
309return {};
310})
311.then((config: AppJson) => {
312let expoConfig = <ExpConfig>(config.expo || {});
313if (!expoConfig.name || !expoConfig.slug) {
34472878RedMickey5 years ago314return this.getPackageName().then((name: string) => {
315expoConfig.slug = expoConfig.slug || config.name || name.replace(" ", "-");
316expoConfig.name = expoConfig.name || config.name || name;
317config.expo = expoConfig;
318return config;
319});
b0af599cJimmy Thomson9 years ago320}
321
94cd5149Artem Egorov8 years ago322return config;
323})
66412fdfRuslan Bikkinin7 years ago324.then((config: AppJson) => {
325if (!config.name) {
34472878RedMickey5 years ago326return this.getPackageName().then((name: string) => {
327config.name = name;
328return config;
329});
66412fdfRuslan Bikkinin7 years ago330}
331
332return config;
333})
94cd5149Artem Egorov8 years ago334.then((config: AppJson) => {
335if (!config.expo.sdkVersion) {
34472878RedMickey5 years ago336return this.exponentSdk(true).then(sdkVersion => {
337config.expo.sdkVersion = sdkVersion;
338return config;
339});
1c32fe84Patricio Beltran9 years ago340}
66412fdfRuslan Bikkinin7 years ago341
94cd5149Artem Egorov8 years ago342return config;
1c32fe84Patricio Beltran9 years ago343})
94cd5149Artem Egorov8 years ago344.then((config: AppJson) => {
345if (!isExpo) {
66412fdfRuslan Bikkinin7 years ago346// entryPoint must be relative
347// https://docs.expo.io/versions/latest/workflow/configuration/#entrypoint
348config.expo.entryPoint = this.dotvscodePath(EXPONENT_INDEX, false);
94cd5149Artem Egorov8 years ago349}
1c32fe84Patricio Beltran9 years ago350
94cd5149Artem Egorov8 years ago351return config;
352})
353.then((config: AppJson) => {
5c8365a6Artem Egorov8 years ago354return config ? this.writeAppJson(config) : config;
1c32fe84Patricio Beltran9 years ago355})
94cd5149Artem Egorov8 years ago356.then((config: AppJson) => {
ce5e88eeYuri Skorokhodov5 years ago357return isExpo ? Promise.resolve() : this.createExpoEntry(config.expo.name);
1c32fe84Patricio Beltran9 years ago358});
27710197Vladimir Kotikov8 years ago359}
1c32fe84Patricio Beltran9 years ago360
361/**
362* Exponent sdk version that maps to the current react-native version
363* If react native version is not supported it returns null.
364*/
ce5e88eeYuri Skorokhodov5 years ago365private exponentSdk(showProgress: boolean = false): Promise<string> {
94cd5149Artem Egorov8 years ago366if (showProgress) {
0a68f8dbArtem Egorov8 years ago367this.logger.logStream("...");
1c32fe84Patricio Beltran9 years ago368}
94cd5149Artem Egorov8 years ago369
34472878RedMickey5 years ago370return ProjectVersionHelper.getReactNativeVersions(this.projectRootPath).then(versions => {
371if (showProgress) this.logger.logStream(".");
8f50947fRedMickey5 years ago372return this.mapFacebookReactNativeVersionToExpoVersion(
373versions.reactNativeVersion,
374).then(sdkVersion => {
34472878RedMickey5 years ago375if (!sdkVersion) {
8f50947fRedMickey5 years ago376return this.getFacebookReactNativeVersions().then(versions => {
34472878RedMickey5 years ago377return Promise.reject<string>(
378ErrorHelper.getInternalError(
379InternalErrorCode.RNVersionNotSupportedByExponent,
380versions.join(", "),
381),
382);
1c32fe84Patricio Beltran9 years ago383});
34472878RedMickey5 years ago384}
385return sdkVersion;
1c32fe84Patricio Beltran9 years ago386});
34472878RedMickey5 years ago387});
1c32fe84Patricio Beltran9 years ago388}
389
8f50947fRedMickey5 years ago390private getFacebookReactNativeVersions(): Promise<string[]> {
391return XDL.getExpoSdkVersions().then(sdkVersions => {
392const facebookReactNativeVersions = new Set(
393Object.values(sdkVersions)
394.map(data => data.facebookReactNativeVersion)
395.filter(version => version),
396);
397return Array.from(facebookReactNativeVersions);
398});
399}
400
401private mapFacebookReactNativeVersionToExpoVersion(
402outerFacebookReactNativeVersion: string,
403): Promise<string | null> {
404if (!semver.valid(outerFacebookReactNativeVersion)) {
405return Promise.reject(
406new Error(
407`${outerFacebookReactNativeVersion} is not a valid version. It must be in the form of x.y.z`,
408),
409);
410}
411
412return XDL.getReleasedExpoSdkVersions().then(sdkVersions => {
413let currentSdkVersion: string | null = null;
414
415for (const [version, { facebookReactNativeVersion }] of Object.entries(sdkVersions)) {
416if (
417semver.major(outerFacebookReactNativeVersion) ===
418semver.major(facebookReactNativeVersion) &&
419semver.minor(outerFacebookReactNativeVersion) ===
420semver.minor(facebookReactNativeVersion) &&
421(!currentSdkVersion || semver.gt(version, currentSdkVersion))
422) {
423currentSdkVersion = version;
424}
425}
426
427return currentSdkVersion;
428});
429}
430
1c32fe84Patricio Beltran9 years ago431/**
94cd5149Artem Egorov8 years ago432* Name specified on user's package.json
1c32fe84Patricio Beltran9 years ago433*/
ce5e88eeYuri Skorokhodov5 years ago434private getPackageName(): Promise<string> {
94cd5149Artem Egorov8 years ago435return new Package(this.projectRootPath, { fileSystem: this.fs }).name();
436}
437
ce5e88eeYuri Skorokhodov5 years ago438private getExpConfig(): Promise<ExpConfig> {
34472878RedMickey5 years ago439return this.readExpJson().catch(err => {
440if (err.code === "ENOENT") {
441return this.readAppJson().then((config: AppJson) => {
442return config.expo || {};
443});
444}
445
446return err;
447});
1c32fe84Patricio Beltran9 years ago448}
449
242759feJiglioNero5 years ago450private getFromExpConfig<T>(key: string): Promise<T> {
34472878RedMickey5 years ago451return this.getExpConfig().then((config: ExpConfig) => config[key]);
1c32fe84Patricio Beltran9 years ago452}
453
454/**
94cd5149Artem Egorov8 years ago455* Returns the specified setting from exp.json if it exists
1c32fe84Patricio Beltran9 years ago456*/
ce5e88eeYuri Skorokhodov5 years ago457private readExpJson(): Promise<ExpConfig> {
94cd5149Artem Egorov8 years ago458const expJsonPath = this.pathToFileInWorkspace(EXP_JSON);
34472878RedMickey5 years ago459return this.fs.readFile(expJsonPath).then(content => {
460return JSON.parse(stripJSONComments(content.toString()));
461});
1c32fe84Patricio Beltran9 years ago462}
463
ce5e88eeYuri Skorokhodov5 years ago464private readAppJson(): Promise<AppJson> {
94cd5149Artem Egorov8 years ago465const appJsonPath = this.pathToFileInWorkspace(APP_JSON);
34472878RedMickey5 years ago466return this.fs.readFile(appJsonPath).then(content => {
467return JSON.parse(stripJSONComments(content.toString()));
468});
1c32fe84Patricio Beltran9 years ago469}
470
ce5e88eeYuri Skorokhodov5 years ago471private writeAppJson(config: AppJson): Promise<AppJson> {
94cd5149Artem Egorov8 years ago472const appJsonPath = this.pathToFileInWorkspace(APP_JSON);
34472878RedMickey5 years ago473return this.fs.writeFile(appJsonPath, JSON.stringify(config, null, 2)).then(() => config);
1c32fe84Patricio Beltran9 years ago474}
475
ce5e88eeYuri Skorokhodov5 years ago476private getAppPackageInformation(): Promise<IPackageInformation> {
66412fdfRuslan Bikkinin7 years ago477return new Package(this.projectRootPath, { fileSystem: this.fs }).parsePackageInformation();
478}
479
1c32fe84Patricio Beltran9 years ago480/**
38edb09eAlexander Sorokin9 years ago481* Path to a given file from the workspace root
1c32fe84Patricio Beltran9 years ago482*/
483private pathToFileInWorkspace(filename: string): string {
94cd5149Artem Egorov8 years ago484return path.join(this.projectRootPath, filename).replace(DBL_SLASHES, "/");
1c32fe84Patricio Beltran9 years ago485}
486
a57e740bPatricio Beltran9 years ago487/**
488* Works as a constructor but only initiliazes when it's actually needed.
489*/
b0af599cJimmy Thomson9 years ago490private lazilyInitialize(): void {
a57e740bPatricio Beltran9 years ago491if (!this.hasInitialized) {
492this.hasInitialized = true;
493
494XDL.configReactNativeVersionWargnings();
38edb09eAlexander Sorokin9 years ago495XDL.attachLoggerStream(this.projectRootPath, {
a57e740bPatricio Beltran9 years ago496stream: {
497write: (chunk: any) => {
498if (chunk.level <= 30) {
0a68f8dbArtem Egorov8 years ago499this.logger.logStream(chunk.msg);
a57e740bPatricio Beltran9 years ago500} else if (chunk.level === 40) {
0a68f8dbArtem Egorov8 years ago501this.logger.warning(chunk.msg);
a57e740bPatricio Beltran9 years ago502} else {
0a68f8dbArtem Egorov8 years ago503this.logger.error(chunk.msg);
a57e740bPatricio Beltran9 years ago504}
505},
506},
507type: "raw",
508});
509}
510}
5c8365a6Artem Egorov8 years ago511}