@typed/content-hash
Version:
Content hash a directory of HTML/JS/CSS files and other static assets
101 lines • 4.94 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.contentHashDirectory = void 0;
const Disposable_1 = require("@typed/fp/Disposable");
const Env_1 = require("@typed/fp/Env");
const FxEnv_1 = require("@typed/fp/FxEnv");
const Resume_1 = require("@typed/fp/Resume");
const function_1 = require("fp-ts/function");
const Option_1 = require("fp-ts/Option");
const path_1 = require("path");
const typed_colors_1 = require("typed-colors");
const application_1 = require("./application");
const infrastructure_1 = require("./infrastructure");
const normalizeRegistry_1 = require("./infrastructure/normalizeRegistry");
const getFileExtension_1 = require("./infrastructure/plugins/getFileExtension");
const DEFAULT_LOG_LEVEL = application_1.LogLevel.Error;
const DEFAULT_LOG_PREFIX = (0, typed_colors_1.gray)(`[typed-content-hash]`);
const DEFAULT_HASH_LENGTH = Infinity;
const DEFAULT_ASSET_MANIFEST = 'asset-manifest.json';
function contentHashDirectory(options) {
const { directory, plugins, logLevel = DEFAULT_LOG_LEVEL, logPrefix = DEFAULT_LOG_PREFIX, documentRegistry = new Map(), hashLength = DEFAULT_HASH_LENGTH, assetManifest = DEFAULT_ASSET_MANIFEST, baseUrl, registryFile = logLevel === application_1.LogLevel.Debug ? '_document_registry.json' : undefined, sourceMaps = true, } = options;
const readFilePath = (0, infrastructure_1.createReadFilePath)(plugins);
const documentRegistryEnv = { documentRegistry };
const loggerEnv = {
logLevel,
logPrefix,
logger: (msg) => (0, Env_1.fromIO)(() => {
console.log(msg);
}),
};
const program = (0, FxEnv_1.Do)(function* (_) {
const registry = yield* _((0, application_1.hashDirectory)(directory));
const assetManifiestJson = yield* _((0, application_1.generateAssetManifest)(registry));
const filePath = path_1.posix.resolve(directory, assetManifest);
const assetManifiestDoc = {
filePath: filePath,
fileExtension: (0, getFileExtension_1.getFileExtension)(filePath),
contents: JSON.stringify(assetManifiestJson, null, 2),
contentHash: Option_1.none,
sourceMap: Option_1.none,
isBase64Encoded: false,
dependencies: [],
};
const toWrite = new Map([...registry, [assetManifiestDoc.filePath, assetManifiestDoc]]);
if (registryFile) {
const filePath = path_1.posix.resolve(directory, registryFile);
toWrite.set(filePath, {
filePath,
fileExtension: (0, getFileExtension_1.getFileExtension)(filePath),
contents: JSON.stringify((0, normalizeRegistry_1.normalizeRegistry)(directory, registry), null, 2),
contentHash: Option_1.none,
sourceMap: Option_1.none,
dependencies: [],
isBase64Encoded: false,
});
}
yield* _((0, application_1.writeDocuments)(toWrite));
return registry;
});
const env = (0, function_1.pipe)(program, (0, Env_1.provideAll)({
...documentRegistryEnv,
...loggerEnv,
readDirectory: infrastructure_1.fsReadDirectory,
readDependencies: (directory, doc) => (0, FxEnv_1.Do)(function* (_) {
const documents = yield* _((0, infrastructure_1.fsReadDependencies)(directory, doc));
if (sourceMaps) {
return documents;
}
return documents
.map(removeSourceMaps)
.filter(Option_1.isSome)
.map((o) => o.value);
}),
sortDocuments: infrastructure_1.sortDiGraph,
readFilePath: (path) => (0, FxEnv_1.Do)(function* (_) {
const doc = yield* _(readFilePath(path));
if (sourceMaps || (0, Option_1.isNone)(doc)) {
return doc;
}
return removeSourceMaps(doc.value);
}),
rewriteSourceMapUrls: () => (0, infrastructure_1.rewriteSourceMapUrls)(hashLength, sourceMaps),
rewriteDependencies: (...args) => (0, function_1.pipe)((0, infrastructure_1.rewriteDependencies)(...args), (0, Env_1.provideSome)({
hashLength,
directory,
baseUrl,
sourceMaps,
})),
generateAssetManifest: (doc) => (0, infrastructure_1.generateAssetManfiestFromRegistry)(directory, doc, hashLength, baseUrl),
writeDocuments: (docs) => (0, infrastructure_1.fsWriteDocuments)(docs, hashLength),
}));
return new Promise((resolve) => (0, Resume_1.run)((0, Disposable_1.undisposable)(resolve))(env({})));
}
exports.contentHashDirectory = contentHashDirectory;
function removeSourceMaps(doc) {
if (doc.fileExtension.endsWith('.map')) {
return Option_1.none;
}
return (0, Option_1.some)({ ...doc, sourceMap: Option_1.none });
}
//# sourceMappingURL=contentHashDirectory.js.map