UNPKG

24.3 kBJavaScriptView Raw
1"use strict";
2var fs = require("fs");
3var xml2js = require("xml2js");
4var _ = require("lodash");
5var path = require("path");
6var es6_promise_1 = require("es6-promise");
7var semver = require("semver");
8var csproj2ts;
9(function (csproj2ts) {
10 csproj2ts.DEFAULT_TYPESCRIPT_VERSION = "2.5.3";
11 var cboolean = function (value) {
12 return (typeof value === 'string') ? (value.toLowerCase() === 'true') : value;
13 };
14 var getSettingOrDefault = function (item, abbreviatedSettingName, defaultValue) {
15 if (item["TypeScript" + abbreviatedSettingName]) {
16 return item["TypeScript" + abbreviatedSettingName][0];
17 }
18 return defaultValue;
19 };
20 csproj2ts.fixVersion = function (version) {
21 var testVersion = version + "";
22 if (!testVersion) {
23 return csproj2ts.DEFAULT_TYPESCRIPT_VERSION;
24 }
25 if (testVersion.indexOf("-") > -1) {
26 var versionInfo = testVersion.split("-");
27 testVersion = versionInfo[0];
28 }
29 if (semver.valid(testVersion)) {
30 return testVersion;
31 }
32 testVersion += ".0";
33 if (semver.valid(testVersion)) {
34 return testVersion;
35 }
36 testVersion += ".0";
37 if (semver.valid(testVersion)) {
38 return testVersion;
39 }
40 return csproj2ts.DEFAULT_TYPESCRIPT_VERSION;
41 };
42 var getTSSetting = function (project, abbreviatedSettingName, projectConfiguration, projectPlatform, defaultValue) {
43 var typeOfGrouping = "PropertyGroup";
44 var result = defaultValue;
45 if (project[typeOfGrouping]) {
46 var items = toArray(project[typeOfGrouping]);
47 _.map(items, function (item) {
48 if (item["$"] && item["$"]["Condition"]) {
49 var condition = item["$"]["Condition"];
50 condition = condition.replace(/ /g, "");
51 if (condition === "'$(Configuration)'=='" + projectConfiguration + "'" ||
52 condition === "'$(Configuration)|$(Platform)'=='" + projectConfiguration + "|" + projectPlatform + "'") {
53 result = getSettingOrDefault(item, abbreviatedSettingName, result);
54 }
55 }
56 else {
57 result = getSettingOrDefault(item, abbreviatedSettingName, result);
58 }
59 });
60 }
61 return result;
62 };
63 csproj2ts.xml2jsReadXMLFile = function (fileName) {
64 return new es6_promise_1.Promise(function (resolve, reject) {
65 var parser = new xml2js.Parser();
66 parser.addListener('end', function (parsedXMLFileResult) {
67 resolve(parsedXMLFileResult);
68 });
69 fs.readFile(fileName, function (err, data) {
70 if (err && err.errno !== 0) {
71 reject(err);
72 }
73 else {
74 parser.parseString(data);
75 }
76 });
77 });
78 };
79 csproj2ts.getTypeScriptSettings = function (projectInfo) {
80 if (!projectInfo.MSBuildExtensionsPath32) {
81 projectInfo.MSBuildExtensionsPath32 = path.join(csproj2ts.programFiles(), "/MSBuild/");
82 }
83 return new es6_promise_1.Promise(function (resolve, reject) {
84 csproj2ts.xml2jsReadXMLFile(projectInfo.ProjectFileName).then(function (parsedVSProject) {
85 if (!parsedVSProject || !parsedVSProject.Project) {
86 reject(new Error("No result from parsing the project."));
87 }
88 else {
89 var project = parsedVSProject.Project;
90 var projectDefaultConfig = getDefaultConfiguration(project);
91 var projectDefaultPlatform = getDefaultPlatform(project);
92 var projectActiveConfig = projectInfo.ActiveConfiguration || projectDefaultConfig;
93 var projectActivePlat = projectInfo.ActivePlatform || projectDefaultPlatform;
94 var result = {
95 VSProjectDetails: {
96 DefaultProjectConfiguration: projectDefaultConfig,
97 DefaultProjectPlatform: projectDefaultPlatform,
98 DefaultVisualStudioVersion: getDefaultVisualStudioVersion(project),
99 TypeScriptDefaultPropsFilePath: getTypeScriptDefaultPropsFilePath(project),
100 ActiveConfiguration: projectInfo.ActiveConfiguration,
101 ActivePlatform: projectInfo.ActivePlatform,
102 MSBuildExtensionsPath32: projectInfo.MSBuildExtensionsPath32,
103 ProjectFileName: projectInfo.ProjectFileName,
104 VisualStudioVersion: projectInfo.VisualStudioVersion,
105 TypeScriptVersion: csproj2ts.fixVersion(projectInfo.TypeScriptVersion)
106 },
107 files: getTypeScriptFilesToCompile(project),
108 AdditionalFlags: getTSSetting(project, "AdditionalFlags", projectActiveConfig, projectActivePlat, undefined),
109 AllowJS: cboolean(getTSSetting(project, "AllowJS", projectActiveConfig, projectActivePlat, undefined)),
110 AllowSyntheticDefaultImports: cboolean(getTSSetting(project, "AllowSyntheticDefaultImports", projectActiveConfig, projectActivePlat, undefined)),
111 AllowUnreachableCode: cboolean(getTSSetting(project, "AllowUnreachableCode", projectActiveConfig, projectActivePlat, undefined)),
112 AllowUnusedLabels: cboolean(getTSSetting(project, "AllowUnusedLabels", projectActiveConfig, projectActivePlat, undefined)),
113 AlwaysStrict: cboolean(getTSSetting(project, "AlwaysStrict", projectActiveConfig, projectActivePlat, undefined)),
114 BaseUrl: getTSSetting(project, "BaseUrl", projectActiveConfig, projectActivePlat, undefined),
115 Charset: getTSSetting(project, "Charset", projectActiveConfig, projectActivePlat, undefined),
116 CheckJs: cboolean(getTSSetting(project, "CheckJs", projectActiveConfig, projectActivePlat, undefined)),
117 CodePage: getTSSetting(project, "CodePage", projectActiveConfig, projectActivePlat, undefined),
118 CompileBlocked: getTSSetting(project, "CompileBlocked", projectActiveConfig, projectActivePlat, false),
119 CompileOnSaveEnabled: cboolean(getTSSetting(project, "CompileOnSaveEnabled", projectActiveConfig, projectActivePlat, undefined)),
120 DeclarationDir: getTSSetting(project, "DeclarationDir", projectActiveConfig, projectActivePlat, undefined),
121 DownlevelIteration: cboolean(getTSSetting(project, "DownlevelIteration", projectActiveConfig, projectActivePlat, undefined)),
122 EmitBOM: cboolean(getTSSetting(project, "EmitBOM", projectActiveConfig, projectActivePlat, undefined)),
123 EmitDecoratorMetadata: cboolean(getTSSetting(project, "EmitDecoratorMetadata", projectActiveConfig, projectActivePlat, undefined)),
124 ESModuleInterop: cboolean(getTSSetting(project, "ESModuleInterop", projectActiveConfig, projectActivePlat, undefined)),
125 ExperimentalAsyncFunctions: cboolean(getTSSetting(project, "ExperimentalAsyncFunctions", projectActiveConfig, projectActivePlat, undefined)),
126 ExperimentalDecorators: cboolean(getTSSetting(project, "ExperimentalDecorators", projectActiveConfig, projectActivePlat, undefined)),
127 ForceConsistentCasingInFileNames: cboolean(getTSSetting(project, "ForceConsistentCasingInFileNames", projectActiveConfig, projectActivePlat, undefined)),
128 GeneratesDeclarations: cboolean(getTSSetting(project, "GeneratesDeclarations", projectActiveConfig, projectActivePlat, undefined)),
129 ImportHelpers: cboolean(getTSSetting(project, "ImportHelpers", projectActiveConfig, projectActivePlat, undefined)),
130 InlineSourceMap: cboolean(getTSSetting(project, "InlineSourceMap", projectActiveConfig, projectActivePlat, undefined)),
131 InlineSources: cboolean(getTSSetting(project, "InlineSources", projectActiveConfig, projectActivePlat, undefined)),
132 IsolatedModules: cboolean(getTSSetting(project, "IsolatedModules", projectActiveConfig, projectActivePlat, undefined)),
133 JSXEmit: getTSSetting(project, "JSXEmit", projectActiveConfig, projectActivePlat, undefined),
134 JSXFactory: getTSSetting(project, "JSXFactory", projectActiveConfig, projectActivePlat, undefined),
135 Lib: getTSSetting(project, "Lib", projectActiveConfig, projectActivePlat, undefined),
136 MapRoot: getTSSetting(project, "MapRoot", projectActiveConfig, projectActivePlat, undefined),
137 ModuleKind: getTSSetting(project, "ModuleKind", projectActiveConfig, projectActivePlat, undefined),
138 ModuleResolution: getTSSetting(project, "ModuleResolution", projectActiveConfig, projectActivePlat, undefined),
139 NewLine: getTSSetting(project, "NewLine", projectActiveConfig, projectActivePlat, undefined),
140 NoEmitHelpers: cboolean(getTSSetting(project, "NoEmitHelpers", projectActiveConfig, projectActivePlat, undefined)),
141 NoEmitOnError: cboolean(getTSSetting(project, "NoEmitOnError", projectActiveConfig, projectActivePlat, undefined)),
142 NoFallthroughCasesInSwitch: cboolean(getTSSetting(project, "NoFallthroughCasesInSwitch", projectActiveConfig, projectActivePlat, undefined)),
143 NoImplicitAny: cboolean(getTSSetting(project, "NoImplicitAny", projectActiveConfig, projectActivePlat, undefined)),
144 NoImplicitThis: cboolean(getTSSetting(project, "NoImplicitThis", projectActiveConfig, projectActivePlat, undefined)),
145 NoImplicitReturns: cboolean(getTSSetting(project, "NoImplicitReturns", projectActiveConfig, projectActivePlat, undefined)),
146 NoImplicitUseStrict: cboolean(getTSSetting(project, "NoImplicitUseStrict", projectActiveConfig, projectActivePlat, undefined)),
147 NoLib: cboolean(getTSSetting(project, "NoLib", projectActiveConfig, projectActivePlat, undefined)),
148 NoResolve: cboolean(getTSSetting(project, "NoResolve", projectActiveConfig, projectActivePlat, undefined)),
149 NoStrictGenericChecks: cboolean(getTSSetting(project, "NoStrictGenericChecks", projectActiveConfig, projectActivePlat, undefined)),
150 NoUnusedLocals: cboolean(getTSSetting(project, "NoUnusedLocals", projectActiveConfig, projectActivePlat, undefined)),
151 NoUnusedParameters: cboolean(getTSSetting(project, "NoUnusedParameters", projectActiveConfig, projectActivePlat, undefined)),
152 OutDir: getTSSetting(project, "OutDir", projectActiveConfig, projectActivePlat, undefined),
153 OutFile: getTSSetting(project, "OutFile", projectActiveConfig, projectActivePlat, undefined),
154 PreferredUILang: getTSSetting(project, "PreferredUILang", projectActiveConfig, projectActivePlat, undefined),
155 PreserveConstEnums: cboolean(getTSSetting(project, "PreserveConstEnums", projectActivePlat, projectActiveConfig, undefined)),
156 PreserveSymlinks: cboolean(getTSSetting(project, "PreserveSymlinks", projectActiveConfig, projectActivePlat, undefined)),
157 ReactNamespace: getTSSetting(project, "ReactNamespace", projectActiveConfig, projectActivePlat, undefined),
158 RemoveComments: cboolean(getTSSetting(project, "RemoveComments", projectActiveConfig, projectActivePlat, undefined)),
159 RootDir: getTSSetting(project, "RootDir", projectActiveConfig, projectActivePlat, undefined),
160 SkipDefaultLibCheck: cboolean(getTSSetting(project, "SkipDefaultLibCheck", projectActiveConfig, projectActivePlat, undefined)),
161 SkipLibCheck: cboolean(getTSSetting(project, "SkipLibCheck", projectActiveConfig, projectActivePlat, undefined)),
162 SourceMap: cboolean(getTSSetting(project, "SourceMap", projectActiveConfig, projectActivePlat, undefined)),
163 SourceRoot: getTSSetting(project, "SourceRoot", projectActiveConfig, projectActivePlat, undefined),
164 Strict: cboolean(getTSSetting(project, "Strict", projectActiveConfig, projectActivePlat, undefined)),
165 StrictFunctionTypes: cboolean(getTSSetting(project, "StrictFunctionTypes", projectActiveConfig, projectActivePlat, undefined)),
166 StrictNullChecks: cboolean(getTSSetting(project, "StrictNullChecks", projectActiveConfig, projectActivePlat, undefined)),
167 StrictPropertyInitialization: cboolean(getTSSetting(project, "StrictPropertyInitialization", projectActiveConfig, projectActivePlat, undefined)),
168 SuppressImplicitAnyIndexErrors: cboolean(getTSSetting(project, "SuppressImplicitAnyIndexErrors", projectActiveConfig, projectActivePlat, undefined)),
169 SuppressExcessPropertyErrors: cboolean(getTSSetting(project, "SuppressExcessPropertyErrors", projectActiveConfig, projectActivePlat, undefined)),
170 Target: getTSSetting(project, "Target", projectActiveConfig, projectActivePlat, undefined)
171 };
172 ["OutDir", "OutFile", "SourceRoot", "RootDir", "MapRoot"].forEach(function (item) {
173 if (result[item]) {
174 result[item] = result[item].replace(/\\/g, "/");
175 }
176 });
177 csproj2ts.getTypeScriptDefaultsFromPropsFileOrDefaults(result)
178 .then(function (typeScriptDefaults) {
179 result.VSProjectDetails.TypeScriptDefaultConfiguration = typeScriptDefaults;
180 finishUp(typeScriptDefaults);
181 }).catch(function (error) {
182 var fallbackDefaults = VSTypeScriptDefaults(result.VSProjectDetails.TypeScriptVersion);
183 result.VSProjectDetails.TypeScriptDefaultConfiguration = fallbackDefaults;
184 finishUp(fallbackDefaults);
185 });
186 var finishUp = function (defaults) {
187 _.forOwn(result, function (value, key) {
188 if (_.isNull(value) || _.isUndefined(value)) {
189 result[key] = defaults[key];
190 }
191 });
192 resolve(result);
193 };
194 }
195 }, function (error) {
196 reject(error);
197 });
198 });
199 };
200 csproj2ts.normalizePath = function (path, settings) {
201 if (path.indexOf("$(VisualStudioVersion)") > -1) {
202 path = path.replace(/\$\(VisualStudioVersion\)/g, settings.VSProjectDetails.VisualStudioVersion || settings.VSProjectDetails.DefaultVisualStudioVersion);
203 }
204 if (path.indexOf("$(MSBuildExtensionsPath32)") > -1) {
205 path = path.replace(/\$\(MSBuildExtensionsPath32\)/g, settings.VSProjectDetails.MSBuildExtensionsPath32);
206 }
207 return path;
208 };
209 var toArray = function (itemOrArray) {
210 if (_.isArray(itemOrArray)) {
211 return itemOrArray;
212 }
213 else {
214 return [itemOrArray];
215 }
216 };
217 var getImports = function (project) {
218 var result = [];
219 if (project.Import) {
220 var importItems = toArray(project.Import);
221 _.map(importItems, function (item) {
222 if (item["$"]) {
223 result.push(item["$"]);
224 }
225 });
226 }
227 return result;
228 };
229 var getVSConfigDefault = function (project, typeOfGrouping, nodeName, defaultCondition) {
230 var result = "";
231 if (project[typeOfGrouping]) {
232 var items = toArray(project[typeOfGrouping]);
233 _.map(items, function (item) {
234 if (item[nodeName] && _.isArray(item[nodeName]) && item[nodeName].length > 0) {
235 var subitem = item[nodeName][0]["$"];
236 if (subitem.Condition) {
237 var condition = subitem.Condition.replace(/ /g, '');
238 if (defaultCondition.indexOf(condition) > -1 || !defaultCondition) {
239 result = item[nodeName][0]["_"] + "";
240 }
241 }
242 }
243 });
244 }
245 return result;
246 };
247 var getDefaultVisualStudioVersion = function (project) {
248 return getVSConfigDefault(project, "PropertyGroup", "VisualStudioVersion", "'$(VisualStudioVersion)'==''");
249 };
250 var getDefaultConfiguration = function (project) {
251 return getVSConfigDefault(project, "PropertyGroup", "Configuration", "'$(Configuration)'==''");
252 };
253 var getDefaultPlatform = function (project) {
254 return getVSConfigDefault(project, "PropertyGroup", "Platform", "'$(Platform)'==''");
255 };
256 var getTypeScriptFilesToCompile = function (project) {
257 var typeOfGrouping = "ItemGroup";
258 var result = [];
259 var osPath;
260 if (project[typeOfGrouping]) {
261 var items = toArray(project[typeOfGrouping]);
262 _.map(items, function (item) {
263 if (item["TypeScriptCompile"]) {
264 _.map(toArray(item["TypeScriptCompile"]), function (compileItem) {
265 if (compileItem["$"] && compileItem["$"]["Include"]) {
266 osPath = compileItem["$"]["Include"].replace(/\\/g, "/");
267 result.push(osPath);
268 }
269 });
270 }
271 });
272 }
273 return result;
274 };
275 var getTypeScriptDefaultPropsFilePath = function (project) {
276 var typeOfGrouping = "Import";
277 var result = "";
278 if (project[typeOfGrouping]) {
279 var items = toArray(project[typeOfGrouping]);
280 _.map(items, function (item) {
281 if (item["$"] && item["$"]["Project"]) {
282 var projectValue = item["$"]["Project"];
283 if (projectValue.indexOf("Microsoft.TypeScript.Default.props") > -1) {
284 result = projectValue;
285 }
286 }
287 });
288 }
289 return result;
290 };
291 function getFirstValueOrDefault(item, defaultValue) {
292 if (item && _.isArray(item) && item.length > 0 && !_.isNull(item[0]) && !_.isUndefined(item[0])) {
293 if (typeof defaultValue === "boolean") {
294 return cboolean(item[0]);
295 }
296 return item[0];
297 }
298 return defaultValue;
299 }
300 var highestVisualStudioVersionToTestFor = function () {
301 var currentYear = new Date().getFullYear();
302 return currentYear - 1995;
303 };
304 var minimumVisualStudioVersion = 10;
305 var findPropsFileName = function (settings) {
306 return new es6_promise_1.Promise(function (resolve, reject) {
307 var propsFileName = csproj2ts.normalizePath(settings.VSProjectDetails.TypeScriptDefaultPropsFilePath, settings);
308 if (fs.existsSync(propsFileName)) {
309 resolve(propsFileName);
310 return;
311 }
312 var alternateSettings = _.cloneDeep(settings);
313 for (var i = highestVisualStudioVersionToTestFor(); i >= minimumVisualStudioVersion; i -= 1) {
314 alternateSettings.VSProjectDetails.VisualStudioVersion = i.toString() + ".0";
315 propsFileName = csproj2ts.normalizePath(settings.VSProjectDetails.TypeScriptDefaultPropsFilePath, alternateSettings);
316 if (fs.existsSync(propsFileName)) {
317 resolve(propsFileName);
318 return;
319 }
320 }
321 reject(new Error("Could not find a valid props file."));
322 });
323 };
324 csproj2ts.getTypeScriptDefaultsFromPropsFileOrDefaults = function (settings) {
325 return new es6_promise_1.Promise(function (resolve, reject) {
326 findPropsFileName(settings).then(function (propsFileName) {
327 csproj2ts.xml2jsReadXMLFile(propsFileName).then(function (parsedPropertiesFile) {
328 if (!parsedPropertiesFile || !parsedPropertiesFile.Project || !parsedPropertiesFile.Project.PropertyGroup) {
329 reject(new Error("No result from parsing the project."));
330 }
331 else {
332 var pg = toArray(parsedPropertiesFile.Project.PropertyGroup)[0];
333 var result = {};
334 var def = VSTypeScriptDefaults(settings.VSProjectDetails.TypeScriptVersion);
335 result.Target = getFirstValueOrDefault(pg.TypeScriptTarget, def.Target);
336 result.CompileOnSaveEnabled = getFirstValueOrDefault(pg.TypeScriptCompileOnSaveEnabled, def.CompileOnSaveEnabled);
337 result.NoImplicitAny = getFirstValueOrDefault(pg.TypeScriptNoImplicitAny, def.NoImplicitAny);
338 result.ModuleKind = getFirstValueOrDefault(pg.TypeScriptModuleKind, def.ModuleKind);
339 result.RemoveComments = getFirstValueOrDefault(pg.TypeScriptRemoveComments, def.RemoveComments);
340 result.OutFile = getFirstValueOrDefault(pg.TypeScriptOutFile, def.OutFile);
341 result.OutDir = getFirstValueOrDefault(pg.TypeScriptOutDir, def.OutDir);
342 result.GeneratesDeclarations = getFirstValueOrDefault(pg.TypeScriptGeneratesDeclarations, def.GeneratesDeclarations);
343 result.SourceMap = getFirstValueOrDefault(pg.TypeScriptSourceMap, def.SourceMap);
344 result.MapRoot = getFirstValueOrDefault(pg.TypeScript, def.MapRoot);
345 result.SourceRoot = getFirstValueOrDefault(pg.TypeScriptSourceRoot, def.SourceRoot);
346 result.NoEmitOnError = getFirstValueOrDefault(pg.TypeScript, def.NoEmitOnError);
347 resolve(result);
348 }
349 }, function (error) { reject(error); });
350 }, function (error) {
351 reject(error);
352 });
353 });
354 };
355 var VSTypeScriptDefaults = function (version) {
356 if (!version) {
357 version = csproj2ts.DEFAULT_TYPESCRIPT_VERSION;
358 }
359 var target = semver.lt(version, "1.5.0") ? "ES3" : "ES5";
360 var noEmitOnError = semver.gte(version, "1.4.0");
361 var dev = {
362 Target: target,
363 CompileOnSaveEnabled: false,
364 NoImplicitAny: false,
365 ModuleKind: "",
366 RemoveComments: false,
367 OutFile: "",
368 OutDir: "",
369 GeneratesDeclarations: false,
370 SourceMap: false,
371 MapRoot: "",
372 SourceRoot: "",
373 NoEmitOnError: noEmitOnError
374 };
375 return dev;
376 };
377 csproj2ts.programFiles = function () {
378 return process.env["ProgramFiles(x86)"] || process.env["ProgramFiles"] || "";
379 };
380})(csproj2ts || (csproj2ts = {}));
381module.exports = csproj2ts;