assetgraph-hashfiles
Advanced tools
Comparing version 1.0.1 to 1.1.0
@@ -1,3 +0,15 @@ | ||
### v1.0.1 (2019-10-20) | ||
### v1.1.0 (2020-08-02) | ||
#### Pull requests | ||
- [#4](https://github.com/assetgraph/assetgraph-hashfiles/pull/4) Warn on cycles ([Peter Müller](mailto:munter@fumle.dk)) | ||
- [#2](https://github.com/assetgraph/assetgraph-hashfiles/pull/2) Adopt the moveAssetsInOrder transform from core ([Andreas Lind](mailto:andreaslindpetersen@gmail.com)) | ||
- [#1](https://github.com/assetgraph/assetgraph-hashfiles/pull/1) Avoid renaming asset with only incoming pre-browsing directives ([Peter Müller](mailto:munter@fumle.dk)) | ||
#### Commits to master | ||
- [Add .vscode debugger launch config](https://github.com/assetgraph/assetgraph-hashfiles/commit/8b87485c8be3bdb98d9e3dc8fce617c66571a5b0) ([Andreas Lind](mailto:andreaslindpetersen@gmail.com)) | ||
### v1.0.1 (2019-10-21) | ||
- [Fix breaking of query strings when moving assets around](https://github.com/assetgraph/assetgraph-hashfiles/commit/e5cf2471677b2c4d100f20ad7a38f8f4c8566f21) ([Peter Müller](mailto:munter@fumle.dk)) | ||
@@ -4,0 +16,0 @@ |
const { ensureTrailingSlash } = require('urltools'); | ||
const moveAssetsInOrder = require('./moveAssetsInOrder'); | ||
/** @typedef {import('assetgraph')} AssetGraph */ | ||
/** @typedef {import('assetgraph/lib/assets/Asset')} Asset */ | ||
/** @typedef {import('assetgraph/lib/relations/Relation')} Relation */ | ||
/** | ||
* @param {Relation} relation | ||
* @returns {boolean} | ||
*/ | ||
function sourceMapCircleFilter(relation) { | ||
@@ -39,131 +48,62 @@ if (relation.type !== 'SourceMapFile') { | ||
const moveAssetsInOrderQuery = { | ||
$and: [ | ||
{ | ||
isLoaded: true, | ||
isRedirect: false, | ||
isInline: false, | ||
type: { $nin: ['CacheManifest', 'Rss', 'Atom'] }, | ||
fileName: { $nin: ['.htaccess', 'humans.txt', 'robots.txt'] } | ||
}, | ||
{ | ||
url: { $not: `${assetGraph.root}favicon.ico` } | ||
}, | ||
moveAssetsInOrder(assetGraph, (asset, assetGraph) => { | ||
let baseUrl = ensureTrailingSlash(`${assetGraph.root}${staticDir}`); | ||
// Conservatively assume that all JavaScriptStaticUrl relations pointing at non-images are intended to be fetched via XHR | ||
// and thus cannot be put on a CDN because of same origin restrictions: | ||
const hasIncomingJavaScriptStaticUrlOrServiceWorkerRelations = | ||
assetGraph.findRelations({ | ||
to: asset, | ||
type: { | ||
$in: [ | ||
'JavaScriptStaticUrl', | ||
'JavaScriptServiceWorkerRegistration', | ||
'HtmlServiceWorkerRegistration' | ||
] | ||
} | ||
}).length > 0; | ||
// Rule for service worker scripts: | ||
// Must be served from the root domain: https://www.w3.org/TR/service-workers/#origin-relativity | ||
// Must keep its file name across builds: https://twitter.com/jaffathecake/status/748123748969095168 | ||
// Exclude service workers from file revisioning. | ||
{ | ||
$not: { | ||
type: 'JavaScript', | ||
incomingRelations: { | ||
$elemMatch: { | ||
type: { | ||
$in: [ | ||
'JavaScriptServiceWorkerRegistration', | ||
'HtmlServiceWorkerRegistration', | ||
'JavaScriptWebWorker' | ||
] | ||
} | ||
} | ||
} | ||
const hasLocalDependencies = assetGraph | ||
.findRelations({ | ||
from: asset, | ||
to: { | ||
isInline: false | ||
} | ||
}, | ||
{ | ||
$not: { | ||
type: 'Html', | ||
incomingRelations: { | ||
$elemMatch: { | ||
type: { | ||
$in: ['HtmlAnchor', 'HtmlMetaRefresh', 'FileRedirect'] | ||
} | ||
} | ||
} | ||
}) | ||
// Don't block on circles between SourceMap and SourceMapFile | ||
.filter(sourceMapCircleFilter) | ||
.some(rel => rel.to.url.startsWith(assetGraph.root)); | ||
if ( | ||
cdnRoot && | ||
asset.type !== 'Htc' && | ||
asset.extension !== '.jar' && | ||
(asset.type !== 'Html' || cdnHtml) && | ||
(asset.type !== 'Flash' || cdnFlash) && | ||
!hasIncomingJavaScriptStaticUrlOrServiceWorkerRelations && | ||
!hasLocalDependencies | ||
) { | ||
baseUrl = ensureTrailingSlash(cdnRoot); | ||
for (const incomingRelation of assetGraph.findRelations({ to: asset })) { | ||
if (cdnRoot.startsWith('//')) { | ||
incomingRelation.hrefType = 'protocolRelative'; | ||
} else if (asset.type === 'SourceMap') { | ||
incomingRelation.hrefType = 'absolute'; | ||
} | ||
}, | ||
{ | ||
$or: [ | ||
{ $not: { isInitial: true } }, | ||
// Assume that non-inline HTML assets without an <html> element, but with incoming relations | ||
// are templates that can safely be moved to /static/ even though they're initial | ||
// (probably the result of loading **/*.html) | ||
{ | ||
type: 'Html', | ||
isFragment: true, | ||
incomingRelations: { $not: { $size: 0 } } | ||
} | ||
] | ||
// Set crossorigin=anonymous on <script> tags pointing at CDN JavaScript. | ||
// See http://blog.errorception.com/2012/12/catching-cross-domain-js-errors.html' | ||
if ( | ||
(asset.type === 'JavaScript' && | ||
incomingRelation.type === 'HtmlScript') || | ||
(asset.type === 'Css' && incomingRelation.type === 'HtmlStyle') | ||
) { | ||
incomingRelation.node.setAttribute('crossorigin', 'anonymous'); | ||
incomingRelation.from.markDirty(); | ||
} | ||
} | ||
] | ||
}; | ||
} | ||
await assetGraph.moveAssetsInOrder( | ||
moveAssetsInOrderQuery, | ||
(asset, assetGraph) => { | ||
let baseUrl = ensureTrailingSlash(`${assetGraph.root}${staticDir}`); | ||
// Conservatively assume that all JavaScriptStaticUrl relations pointing at non-images are intended to be fetched via XHR | ||
// and thus cannot be put on a CDN because of same origin restrictions: | ||
const hasIncomingJavaScriptStaticUrlOrServiceWorkerRelations = | ||
assetGraph.findRelations({ | ||
to: asset, | ||
type: { | ||
$in: [ | ||
'JavaScriptStaticUrl', | ||
'JavaScriptServiceWorkerRegistration', | ||
'HtmlServiceWorkerRegistration' | ||
] | ||
} | ||
}).length > 0; | ||
return `${baseUrl}${asset.fileName}${asset.url.replace(/^[^#?]*(?:)/, '')}`; | ||
}); | ||
const hasLocalDependencies = assetGraph | ||
.findRelations({ | ||
from: asset, | ||
to: { | ||
isInline: false | ||
} | ||
}) | ||
// Don't block on circles between SourceMap and SourceMapFile | ||
.filter(sourceMapCircleFilter) | ||
.some(rel => rel.to.url.startsWith(assetGraph.root)); | ||
if ( | ||
cdnRoot && | ||
asset.type !== 'Htc' && | ||
asset.extension !== '.jar' && | ||
(asset.type !== 'Html' || cdnHtml) && | ||
(asset.type !== 'Flash' || cdnFlash) && | ||
!hasIncomingJavaScriptStaticUrlOrServiceWorkerRelations && | ||
!hasLocalDependencies | ||
) { | ||
baseUrl = ensureTrailingSlash(cdnRoot); | ||
assetGraph | ||
.findRelations({ to: asset }) | ||
.forEach(function(incomingRelation) { | ||
if (cdnRoot.startsWith('//')) { | ||
incomingRelation.hrefType = 'protocolRelative'; | ||
} else if (asset.type === 'SourceMap') { | ||
incomingRelation.hrefType = 'absolute'; | ||
} | ||
// Set crossorigin=anonymous on <script> tags pointing at CDN JavaScript. | ||
// See http://blog.errorception.com/2012/12/catching-cross-domain-js-errors.html' | ||
if ( | ||
(asset.type === 'JavaScript' && | ||
incomingRelation.type === 'HtmlScript') || | ||
(asset.type === 'Css' && incomingRelation.type === 'HtmlStyle') | ||
) { | ||
incomingRelation.node.setAttribute('crossorigin', 'anonymous'); | ||
incomingRelation.from.markDirty(); | ||
} | ||
}); | ||
} | ||
return `${baseUrl}${asset.fileName}${asset.url.replace( | ||
/^[^#?]*(?:)/, | ||
'' | ||
)}`; | ||
} | ||
); | ||
await assetGraph.moveAssetsInOrder(moveAssetsInOrderQuery, function(asset) { | ||
moveAssetsInOrder(assetGraph, function(asset) { | ||
const { url, baseName, extension, md5Hex } = asset; | ||
@@ -170,0 +110,0 @@ return `${baseName}.${md5Hex.substr(0, 10)}${extension}${url.replace(/^[^#?]*(?:)/, '')}`; // Preserve query string and fragment identifier |
@@ -5,3 +5,3 @@ { | ||
"repository": "git://github.com/assetgraph/assetgraph-hashfiles.git", | ||
"version": "1.0.1", | ||
"version": "1.1.0", | ||
"license": "BSD-3-Clause", | ||
@@ -43,3 +43,5 @@ "maintainers": [ | ||
"unexpected-assetgraph": "^1.1.2", | ||
"unexpected-dom": "^4.14.2" | ||
"unexpected-dom": "^4.14.2", | ||
"unexpected-set": "^2.0.1", | ||
"unexpected-sinon": "^10.11.2" | ||
}, | ||
@@ -46,0 +48,0 @@ "main": "lib/hashfiles.js", |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
15356
5
277
21
1