Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(util): validate options.* correctly #1298

Merged
merged 5 commits into from
Nov 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 36 additions & 19 deletions src/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -307,7 +307,11 @@ export const parse = async (options, pkg) => {
* @throws {Error} Throw error if options are invalid
*/
export const validate = async (options, releaseInfo) => {
if (!['get', 'run', 'build'].includes(options.mode)) {
if (
options.mode !== 'get' &&
options.mode !== 'run' &&
options.mode !== 'build'
) {
throw new Error(
`Unknown mode ${options.mode}. Expected "get", "run" or "build".`,
);
Expand All @@ -331,16 +335,23 @@ export const validate = async (options, releaseInfo) => {
`Platform ${options.platform} and architecture ${options.arch} is not supported by this download server.`,
);
}
// if (typeof options.cacheDir !== "string") {
// throw new Error("Expected options.cacheDir to be a string. Got " + typeof options.cacheDir);
// }
if (typeof options.downloadUrl === 'string' && !options.downloadUrl.startsWith('http') && !options.downloadUrl.startsWith('file')) {
throw new Error('Expected options.downloadUrl to be a string and starts with `http` or `file`.');
}
if (typeof options.manifestUrl === 'string' && !options.manifestUrl.startsWith('http') && !options.manifestUrl.startsWith('file')) {
throw new Error('Expected options.manifestUrl to be a string and starts with `http` or `file`.');
}
if (typeof options.cacheDir !== 'string') {
throw new Error('Expected options.cacheDir to be a string. Got ' + typeof options.cacheDir);
}

if (typeof options.cache !== 'boolean') {
return new Error(
throw new Error(
'Expected options.cache to be a boolean. Got ' + typeof options.cache,
);
}
if (typeof options.ffmpeg !== 'boolean') {
return new Error(
throw new Error(
'Expected options.ffmpeg to be a boolean. Got ' + typeof options.ffmpeg,
);
}
Expand All @@ -360,56 +371,62 @@ export const validate = async (options, releaseInfo) => {
if (options.mode === 'get') {
return undefined;
}
if (typeof options.srcDir !== 'string') {
throw new Error('Expected options.srcDir to be a string. Got ' + typeof options.srcDir);
}
if (Array.isArray(options.argv)) {
return new Error(
throw new Error(
'Expected options.argv to be an array. Got ' + typeof options.argv,
);
}
if (typeof options.glob !== 'boolean') {
return new Error(
throw new Error(
'Expected options.glob to be a boolean. Got ' + typeof options.glob,
);
}

if (options.srcDir) {
await fs.promises.readdir(options.srcDir);
}

if (options.mode === 'run') {
return undefined;
}

if (options.outDir) {
await fs.promises.readdir(options.outDir);
if (typeof options.outDir !== 'string') {
throw new Error('Expected options.outDir to be a string. Got ' + typeof options.outDir);
}

if (
typeof options.managedManifest !== 'boolean' &&
typeof options.managedManifest !== 'object' &&
typeof options.managedManifest !== 'string'
) {
return new Error(
throw new Error(
'Expected options.managedManifest to be a boolean, object or string. Got ' +
typeof options.managedManifest,
);
}

if (typeof options.managedManifest === 'object') {
if (options.managedManifest.name === undefined) {
return new Error('Expected NW.js Manifest to have a `name` property.');
throw new Error('Expected NW.js Manifest to have a `name` property.');
}
if (options.managedManifest.main === undefined) {
return new Error('Expected NW.js Manifest to have a `main` property.');
throw new Error('Expected NW.js Manifest to have a `main` property.');
}
}

if (typeof options.nativeAddon !== 'boolean') {
if (typeof options.nativeAddon !== 'boolean' && typeof options.nativeAddon !== 'string') {
return new Error('Expected options.nativeAddon to be a boolean or string type. Got ' + typeof options.nativeAddon);
throw new Error('Expected options.nativeAddon to be a boolean or string type. Got ' + typeof options.nativeAddon);
}

if (semver.parse(options.version).minor >= '83' && options.nativeAddon !== false) {
return new Error('Native addons are not supported for NW.js v0.82.0 and below');
throw new Error('Native addons are not supported for NW.js v0.82.0 and below');
}

if (typeof options.zip !== 'boolean' &
options.zip !== 'zip' &&
options.zip !== 'tar' &&
options.zip !== 'tgz') {
throw new Error('Expected options.zip to be a boolean, `zip`, `tar` or `tgz`. Got ' + typeof options.zip);
}
}

Expand Down
46 changes: 45 additions & 1 deletion tests/specs/util.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,49 @@ describe('util/log', function () {
it('throws error if user defined log level is invalid', async function () {
expect(() => util.log('debug', 'errory', 'Lorem ipsum')).toThrow();
});

});

describe('util/validate', function () {

it('throws error on invalid mode', async function () {
await expect(util.validate({ mode: 'gety' }, {})).rejects.toThrow(Error);
});

it('throws error if releases info is undefined', async function () {
await expect(util.validate({ mode: 'get' }, undefined)).rejects.toThrow(Error);
});

it('throws error on invalid flavor', async function () {
await expect(util.validate({ mode: 'get', flavor: 'notsdk' }, { flavours: ['normal'] })).rejects.toThrow(Error);
});

it('throws error on invalid platform', async function () {
await expect(util.validate({ mode: 'get', flavor: 'normal', platform: 'linox' }, { flavours: ['normal'], files: ['linux-x64'] })).rejects.toThrow(Error);
});

it('throws error on invalid architecture', async function () {
await expect(util.validate({ mode: 'get', flavor: 'normal', platform: 'linux', arch: 'x64000' }, { flavors: ['normal'], files: ['linux-x64'] })).rejects.toThrow(Error);
});

it('throws error on invalid download url', async function () {
await expect(util.validate({ mode: 'get', flavor: 'normal', platform: 'linux', arch: 'x64', downloadUrl: null }, { flavors: ['normal'], files: ['linux-x64'] })).rejects.toThrow(Error);
});

it('throws error on invalid manifest url', async function () {
await expect(util.validate({ mode: 'get', flavor: 'normal', platform: 'linux', arch: 'x64', downloadUrl: 'file://path/to/fs', manifestUrl: null }, { flavors: ['normal'], files: ['linux-x64'] })).rejects.toThrow(Error);
});

it('throws error on invalid cache directory', async function () {
await expect(util.validate({ mode: 'get', flavor: 'normal', platform: 'linux', arch: 'x64', downloadUrl: 'file://path/to/fs', manifestUrl: 'http://path/to/manifest', cacheDir: null }, { flavors: ['normal'], files: ['linux-x64'] })).rejects.toThrow(Error);
});

it('throws error on invalid cache flag', async function () {
await expect(util.validate({ mode: 'get', flavor: 'normal', platform: 'linux', arch: 'x64', downloadUrl: 'file://path/to/fs', manifestUrl: 'http://path/to/manifest', cacheDir: './path/to/cache', cache: 'true' }, { flavors: ['normal'], files: ['linux-x64'] })).rejects.toThrow(Error);
});

it('throws error on invalid ffmpeg flag', async function () {
await expect(util.validate({ mode: 'get', flavor: 'normal', platform: 'linux', arch: 'x64', downloadUrl: 'file://path/to/fs', manifestUrl: 'http://path/to/manifest', cacheDir: './path/to/cache', cache: true, ffmpeg: 'true' }, { flavors: ['normal'], files: ['linux-x64'] })).rejects.toThrow(Error);
});

});