UNPKG

@typed/content-hash

Version:

Content hash a directory of HTML/JS/CSS files and other static assets

90 lines 4.61 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.rewriteDependencies = void 0; const tslib_1 = require("tslib"); const Env_1 = require("@typed/fp/Env"); const FxEnv_1 = require("@typed/fp/FxEnv"); const base64url_1 = (0, tslib_1.__importDefault)(require("base64url")); const crypto_1 = require("crypto"); const function_1 = require("fp-ts/function"); const Option_1 = require("fp-ts/Option"); const path_1 = require("path"); const logging_1 = require("../application/services/logging"); const applyOrigin_1 = require("./applyOrigin"); const ensureRelative_1 = require("./ensureRelative"); const hashes_1 = require("./hashes"); const getHashedPath_1 = require("./hashes/getHashedPath"); const rewriteDocumentContents_1 = require("./rewriteDocumentContents"); const sha512Hash_1 = require("./sha512Hash"); const dtsRegex = new RegExp(`.d.ts$`); const rewriteDependencies = (documents) => (0, FxEnv_1.Do)(function* (_) { const env = yield* _((0, Env_1.ask)()); const computedHashes = computeContentHashes(documents, env.documentRegistry, env.hashLength); let documentRegistry = env.documentRegistry; for (const document of documents) { const { filePath } = document; yield* _((0, logging_1.debug)(`Rewriting dependencies ${filePath}...`)); const hasComputedHash = computedHashes.has(filePath); const updatedDocument = hasComputedHash ? { ...document, contentHash: (0, Option_1.some)({ type: 'hash', hash: computedHashes.get(filePath) }) } : document; documentRegistry = yield* _((0, function_1.pipe)((0, rewriteDocumentContents_1.rewriteDocumentContents)(updatedDocument, rewriteDocumentDependencies(updatedDocument, computedHashes, env), env.sourceMaps, hasComputedHash), (0, Env_1.useSome)({ documentRegistry }))); } return documentRegistry; }); exports.rewriteDependencies = rewriteDependencies; const rewriteDocumentDependencies = (document, computedHashes, env) => (ms) => { for (const dep of document.dependencies) { const depDoc = env.documentRegistry.get(dep.filePath); if (depDoc) { ms.overwrite(dep.position.start, dep.position.end, determineReplacementPath({ document, depDoc, dep, computedHashes, ...env })); } } }; function determineReplacementPath({ document, depDoc, documentRegistry, hashLength, directory, dep, baseUrl, computedHashes, }) { const hashedPath = computedHashes.has(depDoc.filePath) ? (0, hashes_1.replaceHash)(depDoc.filePath, depDoc.fileExtension, computedHashes.get(depDoc.filePath).slice(0, hashLength)) : (0, getHashedPath_1.getHashedPath)(depDoc, documentRegistry, hashLength); const relativePath = (0, ensureRelative_1.ensureRelative)(path_1.posix.relative(path_1.posix.dirname(document.filePath), hashedPath)); const absolutePath = ensureAbsolute(path_1.posix.relative(directory, hashedPath)); const pathToUse = baseUrl ? (0, applyOrigin_1.applyOrigin)(directory, hashedPath, baseUrl) : dep.specifier.startsWith('/') ? absolutePath : relativePath; const replacementPath = dtsRegex.test(pathToUse) ? pathToUse.replace(dtsRegex, '') : pathToUse; return replacementPath; } function ensureAbsolute(path) { if (path[0] !== '/') { return '/' + path; } return path; } function computeContentHashes(documents, registry, hashLength) { const computedHashes = new Map(); if (documents.length < 2) { return computedHashes; } for (const document of documents) { if ((0, Option_1.isSome)(document.contentHash) && document.contentHash.value.type == 'hash') { computedHashes.set(document.filePath, computeContentHash(document, registry, hashLength)); } } return computedHashes; } function computeContentHash(document, registry, hashLength) { const getHash = (d) => (0, function_1.pipe)((0, hashes_1.getContentHash)(d, registry, hashLength), (0, Option_1.getOrElse)(() => (0, sha512Hash_1.sha512Hash)(d.contents))); const computed = (0, crypto_1.createHash)('sha512'); computed.update(getHash(document)); const dependenciesForHashing = new Set(document.dependencies); for (const dep of dependenciesForHashing) { const depDoc = registry.get(dep.filePath); if (depDoc) { computed.update(getHash(depDoc)); depDoc.dependencies.forEach((d) => dependenciesForHashing.add(d)); } } return base64url_1.default.fromBase64(computed.digest('base64')); } //# sourceMappingURL=rewriteDependencies.js.map