Skip to content

Commit

Permalink
Stricter types, fixes #43
Browse files Browse the repository at this point in the history
  • Loading branch information
Pelle Wessman committed Jul 20, 2020
1 parent 0b36843 commit 8a51f1b
Show file tree
Hide file tree
Showing 7 changed files with 98 additions and 34 deletions.
1 change: 1 addition & 0 deletions .tsignoreimportrc.yml
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
allow:
- type-fest
tsConfig: tsconfig.json
12 changes: 9 additions & 3 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ const VError = require('verror');

const {
ensurePrefix,
resolveJsonStringArray,
resolveJsonObject,
resolveJsonStringValueObject,
silentSyncLoadJsonFile
} = require('./lib/misc');

Expand Down Expand Up @@ -52,8 +55,10 @@ class AssetVersions {
const result = new Map();
const webpackVersions = webpackManifest ? loadWebpackVersions(resolvedSourceDir, webpackManifest) : {};

const versions = this.useVersionedPaths ? silentSyncLoadJsonFile(versionsPath) : {};
const fileVersions = (versions.files || {});
const versions = resolveJsonObject(this.useVersionedPaths && silentSyncLoadJsonFile(versionsPath), 'asset versions file');
const fileVersions = resolveJsonStringValueObject(versions.files, 'versions.files');
const fileDependencies = resolveJsonObject(versions.dependencies, 'versions.dependencies');

/** @type {Map<string, string[]>} */
const dependencies = new Map();
const allFiles = new Set([
Expand Down Expand Up @@ -97,8 +102,9 @@ class AssetVersions {

result.set(relativeFilePath, relativeTargetFilePath);

const versionsSiblings = fileDependencies[file] ? resolveJsonStringArray(fileDependencies[file], 'versions.dependencies') : undefined;
/** @type {string[]} */
const siblings = (versions.dependencies || {})[file] || (webpackVersions[file] || {}).siblings || [];
const siblings = versionsSiblings || (webpackVersions[file] || {}).siblings || [];

try {
const dependencyPaths = siblings.map(sibling => processFilePaths(sibling).relativeFilePath);
Expand Down
28 changes: 2 additions & 26 deletions lib/asset-options.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ const pathModule = require('path');

const loadJsonFile = require('load-json-file');

const { resolveJsonStringArray } = require('./misc');

/**
* @typedef AssetsOptions
* @property {string[]} files
Expand All @@ -15,32 +17,6 @@ const loadJsonFile = require('load-json-file');
* @property {string} targetDir
*/

/**
* @param {any} data
* @param {string} label
* @returns {string[]}
*/
const resolveJsonStringArray = (data, label) => {
if (!data) return [];
if (typeof data === 'string') return [data];

/** @type {string[]} */
const resolvedArray = [];

if (!Array.isArray(data)) {
throw new TypeError(`Expected a ${label} array, instead got: ${typeof data}`);
}

for (const value of data) {
if (typeof value !== 'string') {
throw new TypeError(`Expected ${label} array to only contain strings, encountered a: ${typeof value}`);
}
resolvedArray.push(value);
}

return resolvedArray;
};

/**
* @param {string} workingDir
* @returns {Promise<AssetsOptions>}
Expand Down
73 changes: 72 additions & 1 deletion lib/misc.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ const ensurePrefix = (prefix, value) => (value[0] === prefix ? '' : prefix) + va

/**
* @param {string} path
* @returns {any}
* @returns {import('type-fest').JsonValue|undefined}
*/
const silentSyncLoadJsonFile = (path) => {
try {
Expand All @@ -24,7 +24,78 @@ const silentSyncLoadJsonFile = (path) => {
}
};

/**
* @param {import('type-fest').JsonValue|undefined} data
* @param {string} label
* @returns {string[]}
*/
const resolveJsonStringArray = (data, label) => {
if (!data) return [];
if (typeof data === 'string') return [data];

/** @type {string[]} */
const result = [];

if (!Array.isArray(data)) {
throw new TypeError(`Expected a ${label} array, instead got: ${typeof data}`);
}

for (const value of data) {
if (typeof value !== 'string') {
throw new TypeError(`Expected ${label} array to only contain strings, encountered a: ${typeof value}`);
}
result.push(value);
}

return result;
};

/**
* @param {import('type-fest').JsonValue|undefined} data
* @param {string} label
* @returns {{ [key: string]: any }}
*/
const resolveJsonObject = (data, label) => {
if (!data) return {};

if (typeof data !== 'object') {
throw new TypeError(`Expected a ${label} object, instead got: ${typeof data}`);
}
if (Array.isArray(data)) {
throw new TypeError(`Expected a ${label} non-array object, instead got: ${typeof data}`);
}

return data;
};

/**
* @param {import('type-fest').JsonValue|undefined} data
* @param {string} label
* @returns {{ [key: string]: string }}
*/
const resolveJsonStringValueObject = (data, label) => {
if (!data) return {};

/** @type {{ [key: string]: string }} */
const result = {};

data = resolveJsonObject(data, label);

for (const key of Object.keys(data)) {
const value = data[key];
if (typeof value !== 'string') {
throw new TypeError(`Expected ${label} object to only contain strings, encountered a: ${typeof value}`);
}
result[key] = value;
}

return result;
};

module.exports = {
ensurePrefix,
resolveJsonStringArray,
resolveJsonObject,
resolveJsonStringValueObject,
silentSyncLoadJsonFile
};
10 changes: 7 additions & 3 deletions lib/webpack.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
const pathModule = require('path');

const {
resolveJsonObject,
silentSyncLoadJsonFile
} = require('./misc');

Expand All @@ -22,10 +23,13 @@ const loadWebpackVersions = (resolvedSourceDir, webpackManifests) => {

for (const manifest of Array.isArray(webpackManifests) ? webpackManifests : [webpackManifests]) {
const webpackManifestPath = pathModule.resolve(resolvedSourceDir, manifest);
/** @type {AssetVersionsWebpackManifest|undefined} */
const result = silentSyncLoadJsonFile(webpackManifestPath);
const rawResult = silentSyncLoadJsonFile(webpackManifestPath);
if (rawResult) {
/** @type {AssetVersionsWebpackManifest|undefined} */
const result = resolveJsonObject(rawResult, 'webpack manifest');

webpackVersions = Object.assign(webpackVersions, result);
webpackVersions = Object.assign(webpackVersions, result);
}
}

return webpackVersions;
Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
"build-test:css": "cp example/src/main.css example/dist/bare/main.css",
"build-test:js": "webpack --mode='production' --devtool hidden-source-map --config example/webpack.config.js --output-public-path /dist/rev/",
"build-test": "run-p build-test:* && rm -rf example/dist/rev && node cli.js -p example",
"check:dependency-check": "dependency-check *.js --no-dev -i @types/*",
"check:dependency-check": "dependency-check *.js --no-dev -i @types/* -i type-fest",
"check:eslint": "eslint .",
"check:installed-check": "installed-check -i eslint",
"check:tsc": "tsc",
Expand Down Expand Up @@ -88,6 +88,7 @@
"load-json-file": "^6.2.0",
"pkg-dir": "^4.1.0",
"rev-file": "^3.0.0",
"type-fest": "^0.16.0",
"verror": "^1.10.0",
"write-json-file": "^4.2.1"
}
Expand Down
5 changes: 5 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -5279,6 +5279,11 @@ type-fest@^0.11.0:
resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.11.0.tgz#97abf0872310fed88a5c466b25681576145e33f1"
integrity sha512-OdjXJxnCN1AvyLSzeKIgXTXxV+99ZuXl3Hpo9XpJAv9MBcHrrJOQ5kV7ypXOuQie+AmWG25hLbiKdwYTifzcfQ==

type-fest@^0.16.0:
version "0.16.0"
resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.16.0.tgz#3240b891a78b0deae910dbeb86553e552a148860"
integrity sha512-eaBzG6MxNzEn9kiwvtre90cXaNLkmadMWa1zQMs3XORCXNbsH/OewwbxC5ia9dCxIxnTAsSxXJaa/p5y8DlvJg==

type-fest@^0.6.0:
version "0.6.0"
resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.6.0.tgz#8d2a2370d3df886eb5c90ada1c5bf6188acf838b"
Expand Down

0 comments on commit 8a51f1b

Please sign in to comment.