Skip to content
This repository was archived by the owner on Jan 14, 2022. It is now read-only.

Commit 91f96d0

Browse files
authored
Merge pull request #73 from pwa-builder/downloadIconsSupportSrc
check exception cases for validator library
2 parents fe02545 + 4a508db commit 91f96d0

File tree

4 files changed

+98
-65
lines changed

4 files changed

+98
-65
lines changed

lib/projectBuilder.js

Lines changed: 67 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,17 @@ var path = require('path');
55
var Q = require('q');
66

77
var CustomError = require('./customError'),
8-
fileTools = require('./fileTools'),
9-
log = require('./log'),
10-
manifestTools = require('./manifestTools'),
11-
platformTools = require('./platformTools'),
12-
projectTools = require('./projectTools'),
13-
utils = require('./utils'),
14-
constants = require('./constants'),
15-
validationConstants = require('./constants').validation;
16-
17-
function processPlatformTasks (tasks) {
8+
fileTools = require('./fileTools'),
9+
log = require('./log'),
10+
manifestTools = require('./manifestTools'),
11+
platformTools = require('./platformTools'),
12+
projectTools = require('./projectTools'),
13+
projectValidation = require('./validations').projectValidation,
14+
utils = require('./utils'),
15+
constants = require('./constants'),
16+
validationConstants = require('./constants').validation;
17+
18+
function processPlatformTasks(tasks) {
1819
return Q.allSettled(tasks).then(function (results) {
1920
var result = results.reduce(function (success, result) {
2021
if (result.state !== 'fulfilled') {
@@ -28,7 +29,7 @@ function processPlatformTasks (tasks) {
2829
if (!result) {
2930
return Q.reject(new Error('One or more platforms could not be generated successfully.'));
3031
} else {
31-
return Q.resolve(results.map(function(result) {
32+
return Q.resolve(results.map(function (result) {
3233
return result.value;
3334
}));
3435
}
@@ -42,12 +43,17 @@ function validateManifest(w3cManifestInfo, platformModules, platforms) {
4243
var maxLenSeverity = 10;
4344
validationResults.forEach(function (result) {
4445
var severity = result.level.toUpperCase();
45-
var validationMessage = 'Manifest validation ' + severity + new Array(Math.max(maxLenSeverity - severity.length + 1, 0)).join(' ') + ' - ' + result.description + '(member: ' + result.member + ').';
46+
var validationMessage = 'Manifest validation ' + severity + new Array(Math.max(maxLenSeverity - severity.length + 1, 0)).join(' ') + ' - ' + result.description + '(member: ' + result.member + ').';
4647
if (result.level === validationConstants.levels.suggestion || result.level === validationConstants.levels.warning) {
4748
log.warn(validationMessage, result.platform);
4849
} else if (result.level === validationConstants.levels.error) {
49-
log.error(validationMessage, result.platform);
50-
invalidManifest = true;
50+
// handle expected errors rather than deeming it as invalid
51+
if (projectValidation.isExpectedValidationError(result) && projectValidation.isExpectedCase(result, w3cManifestInfo)) {
52+
log.warn('Manifest validation ' + "WARNING" + new Array(Math.max(maxLenSeverity - severity.length + 1, 0)).join(' ') + ' - ' + result.description + '(member: ' + result.member + ').', result.platform);
53+
} else {
54+
log.error(validationMessage, result.platform);
55+
invalidManifest = true;
56+
}
5157
}
5258
});
5359

@@ -93,7 +99,7 @@ function copyAssets(assets, generatedAppDir, callback) {
9399
return Q.resolve().nodeify(callback);
94100
}
95101

96-
function createApps (w3cManifestInfo, rootDir, platforms, options, href, callback) {
102+
function createApps(w3cManifestInfo, rootDir, platforms, options, href, callback) {
97103
// validate arguments
98104
if (arguments.length < 3) {
99105
return Q.reject(new Error('One or more required arguments are missing.')).nodeify(callback);
@@ -122,47 +128,47 @@ function createApps (w3cManifestInfo, rootDir, platforms, options, href, callbac
122128
// load the platform modules
123129
return platformTools.loadPlatforms(platforms);
124130
})
125-
.then(function (platformModules) {
126-
// validate the manifest
127-
return validateManifest(w3cManifestInfo, platformModules, platforms).thenResolve(platformModules);
128-
})
129-
.then(function (platformModules) {
130-
// generate missing icons
131-
return generateImages(w3cManifestInfo, options).thenResolve(platformModules);
132-
})
133-
.then(function (platformModules) {
134-
// create apps for each platform
135-
var tasks = platformModules.map(function (platform) {
136-
if (platform) {
137-
log.debug('Creating the \'' + platform.name + '\' app...');
138-
return Q.resolve(generatedAppDir).then(function(generatedAppOutputDir) {
139-
return fileTools.mkdirp(generatedAppOutputDir).then(function() {
140-
var w3cManifestInfoCopy = JSON.parse(JSON.stringify(w3cManifestInfo));
141-
return Q.ninvoke(platform, 'create', w3cManifestInfoCopy, generatedAppOutputDir, options, href).then(function () {
142-
log.info('The ' + platform.name + ' app was created successfully!');
143-
})
144-
.catch(function (err) {
145-
return Q.reject(new CustomError('Failed to create the ' + platform.name + ' app.', err));
131+
.then(function (platformModules) {
132+
// validate the manifest
133+
return validateManifest(w3cManifestInfo, platformModules, platforms).thenResolve(platformModules);
134+
})
135+
.then(function (platformModules) {
136+
// generate missing icons
137+
return generateImages(w3cManifestInfo, options).thenResolve(platformModules);
138+
})
139+
.then(function (platformModules) {
140+
// create apps for each platform
141+
var tasks = platformModules.map(function (platform) {
142+
if (platform) {
143+
log.debug('Creating the \'' + platform.name + '\' app...');
144+
return Q.resolve(generatedAppDir).then(function (generatedAppOutputDir) {
145+
return fileTools.mkdirp(generatedAppOutputDir).then(function () {
146+
var w3cManifestInfoCopy = JSON.parse(JSON.stringify(w3cManifestInfo));
147+
return Q.ninvoke(platform, 'create', w3cManifestInfoCopy, generatedAppOutputDir, options, href).then(function () {
148+
log.info('The ' + platform.name + ' app was created successfully!');
149+
})
150+
.catch(function (err) {
151+
return Q.reject(new CustomError('Failed to create the ' + platform.name + ' app.', err));
152+
});
146153
});
147154
});
148-
});
149-
}
155+
}
150156

151-
return Q.resolve();
152-
});
157+
return Q.resolve();
158+
});
153159

154-
return processPlatformTasks(tasks);
155-
})
156-
.then(function () {
157-
// copy assets to the assets folder
158-
return copyAssets(options.assets, generatedAppDir);
159-
})
160-
// return path to project folder
161-
.thenResolve(generatedAppDir)
162-
.nodeify(callback);
160+
return processPlatformTasks(tasks);
161+
})
162+
.then(function () {
163+
// copy assets to the assets folder
164+
return copyAssets(options.assets, generatedAppDir);
165+
})
166+
// return path to project folder
167+
.thenResolve(generatedAppDir)
168+
.nodeify(callback);
163169
}
164170

165-
function packageApps (platforms, dir, options, callback) {
171+
function packageApps(platforms, dir, options, callback) {
166172
// validate arguments
167173
if (arguments.length < 2) {
168174
return Q.reject(new Error('One or more required arguments are missing.')).nodeify(callback);
@@ -187,14 +193,14 @@ function packageApps (platforms, dir, options, callback) {
187193
var tasks = platformModules.map(function (platform) {
188194
if (platform) {
189195
log.debug('Packaging the \'' + platform.name + '\' app...');
190-
return Q.resolve(rootDir).then(function(rootOutputDir) {
196+
return Q.resolve(rootDir).then(function (rootOutputDir) {
191197
return Q.ninvoke(platform, 'package', rootOutputDir, options).then(function (path) {
192198
log.info('The ' + platform.name + ' app was packaged successfully!');
193199
return Q.resolve(path);
194200
})
195-
.catch (function (err) {
196-
return Q.reject(new CustomError('Failed to package the ' + platform.name + ' app.', err));
197-
});
201+
.catch(function (err) {
202+
return Q.reject(new CustomError('Failed to package the ' + platform.name + ' app.', err));
203+
});
198204
});
199205
} else {
200206
return Q.resolve();
@@ -204,10 +210,10 @@ function packageApps (platforms, dir, options, callback) {
204210
return processPlatformTasks(tasks);
205211
});
206212
})
207-
.nodeify(callback);
213+
.nodeify(callback);
208214
}
209215

210-
function runApp (platformId, dir, options, callback) {
216+
function runApp(platformId, dir, options, callback) {
211217
// validate arguments
212218
if (arguments.length < 2) {
213219
return Q.reject(new Error('One or more required arguments are missing.')).nodeify(callback);
@@ -232,7 +238,7 @@ function runApp (platformId, dir, options, callback) {
232238
if (platformModules && platformModules.length > 0) {
233239
var platform = platformModules[0];
234240
log.debug('Launching the \'' + platform.name + '\' app ...');
235-
return Q.resolve(rootDir).then(function(rootOutputDir) {
241+
return Q.resolve(rootDir).then(function (rootOutputDir) {
236242
return Q.ninvoke(platform, 'run', rootOutputDir, options).catch(function (err) {
237243
return Q.reject(new CustomError('Failed to launch the ' + platform.name + ' app.', err));
238244
});
@@ -242,10 +248,10 @@ function runApp (platformId, dir, options, callback) {
242248
return Q.resolve();
243249
});
244250
})
245-
.nodeify(callback);
251+
.nodeify(callback);
246252
}
247253

248-
function openApp (platformId, dir, options, callback) {
254+
function openApp(platformId, dir, options, callback) {
249255
// validate arguments
250256
if (arguments.length < 2) {
251257
return Q.reject(new Error('One or more required arguments are missing.')).nodeify(callback);
@@ -270,7 +276,7 @@ function openApp (platformId, dir, options, callback) {
270276
if (platformModules && platformModules.length > 0) {
271277
var platform = platformModules[0];
272278
log.debug('Opening the \'' + platform.name + '\' app...');
273-
return Q.resolve(rootDir).then(function(rootOutputDir) {
279+
return Q.resolve(rootDir).then(function (rootOutputDir) {
274280
return Q.ninvoke(platform, 'open', rootOutputDir, options).catch(function (err) {
275281
return Q.reject(new CustomError('Failed to open the ' + platform.name + ' app.', err));
276282
});
@@ -280,7 +286,7 @@ function openApp (platformId, dir, options, callback) {
280286
return Q.resolve();
281287
});
282288
})
283-
.nodeify(callback);
289+
.nodeify(callback);
284290
}
285291

286292
module.exports = {

lib/validations.js

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
'use strict';
22

33
var platformTools = require('./platformTools'),
4-
manifestTools = require('./manifestTools');
4+
manifestTools = require('./manifestTools');
55

66
function platformsValid(platforms) {
77
var availablePlatforms = platformTools.listPlatforms();
@@ -35,9 +35,36 @@ function manifestFormatValid(format) {
3535
return availableFormats.indexOf(format.toLowerCase()) >= 0;
3636
}
3737

38+
function isExpectedValidationError(errorResult) {
39+
const checkForPurposeList = errorResult.member.includes("icons") && errorResult.member.includes("purpose")
40+
41+
return checkForPurposeList
42+
}
43+
44+
function isExpectedCase(errorResult, w3cManifestInfo) {
45+
const errorParams = errorResult.member.split('/').slice(1) //example: /icons/0/purpose -> ['icons', '0', 'purpose']
46+
const isIconsPurpose = errorResult.member.includes("icons") && errorResult.member.includes("purpose")
47+
48+
if (isIconsPurpose) {
49+
const [icons, index, purpose] = errorParams
50+
51+
return w3cManifestInfo.content[icons][index][purpose].split(" ").filter(entry => {
52+
return (entry === "any" || entry === "maskable" || entry === "monochrome");
53+
}).length > 0
54+
}
55+
56+
return false;
57+
}
58+
59+
60+
3861
module.exports = {
3962
platformsValid: platformsValid,
4063
platformToRunValid: platformToRunValid,
4164
logLevelValid: logLevelValid,
42-
manifestFormatValid: manifestFormatValid
65+
manifestFormatValid: manifestFormatValid,
66+
projectValidation: {
67+
isExpectedValidationError: isExpectedValidationError,
68+
isExpectedCase: isExpectedCase,
69+
}
4370
};

package-lock.json

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "pwabuilder-lib",
3-
"version": "2.1.4",
3+
"version": "2.1.5",
44
"description": "PWA Builder Core Library",
55
"repository": {
66
"type": "git",

0 commit comments

Comments
 (0)