Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

assetgraph-hashfiles

Package Overview
Dependencies
Maintainers
1
Versions
4
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

assetgraph-hashfiles - npm Package Compare versions

Comparing version 1.0.1 to 1.1.0

lib/moveAssetsInOrder.js

14

CHANGELOG.md

@@ -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 @@

186

lib/hashfiles.js
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",

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc