amphora-html 6.0.0-dev.0 → 6.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/ci.yml +40 -0
- package/lib/media.js +68 -76
- package/lib/media.test.js +4 -115
- package/lib/render.js +12 -5
- package/package.json +4 -1
- package/.circleci/config.yml +0 -44
- package/.github/workflows/push.yml +0 -26
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: ['**']
|
|
6
|
+
tags: ['**']
|
|
7
|
+
pull_request:
|
|
8
|
+
workflow_dispatch:
|
|
9
|
+
|
|
10
|
+
concurrency:
|
|
11
|
+
group: ${{ github.workflow }}-${{ github.ref }}
|
|
12
|
+
cancel-in-progress: true
|
|
13
|
+
|
|
14
|
+
permissions:
|
|
15
|
+
contents: read
|
|
16
|
+
|
|
17
|
+
jobs:
|
|
18
|
+
test:
|
|
19
|
+
name: Test (Node ${{ matrix.node-version }})
|
|
20
|
+
runs-on: ubuntu-latest
|
|
21
|
+
strategy:
|
|
22
|
+
fail-fast: false
|
|
23
|
+
matrix:
|
|
24
|
+
node-version: [20]
|
|
25
|
+
steps:
|
|
26
|
+
- uses: actions/checkout@v4
|
|
27
|
+
|
|
28
|
+
- name: Use Node.js ${{ matrix.node-version }}
|
|
29
|
+
uses: actions/setup-node@v4
|
|
30
|
+
with:
|
|
31
|
+
node-version: ${{ matrix.node-version }}
|
|
32
|
+
cache: npm
|
|
33
|
+
cache-dependency-path: package-lock.json
|
|
34
|
+
|
|
35
|
+
- name: Install dependencies
|
|
36
|
+
run: npm ci
|
|
37
|
+
|
|
38
|
+
- name: Run tests
|
|
39
|
+
run: npm test
|
|
40
|
+
|
package/lib/media.js
CHANGED
|
@@ -6,12 +6,10 @@ const _ = require('lodash'),
|
|
|
6
6
|
bluebird = require('bluebird'),
|
|
7
7
|
setup = require('./setup'),
|
|
8
8
|
styleguide = require('./styleguide'),
|
|
9
|
-
url = require('url'),
|
|
10
9
|
STYLE_TAG = 'style',
|
|
11
10
|
SCRIPT_TAG = 'scripts',
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
ASYNC_DEFER_SCRIPT_TAG = 'async-defer',
|
|
11
|
+
MODULE_SCRIPT_TAG = 'module',
|
|
12
|
+
MODULEPRELOAD_TAG = 'modulepreload',
|
|
15
13
|
MEDIA_DIRECTORY = path.join(process.cwd(), 'public');
|
|
16
14
|
|
|
17
15
|
/**
|
|
@@ -150,47 +148,36 @@ function appendMediaToBottom(scripts, html) {
|
|
|
150
148
|
return splice(html, index, scripts);
|
|
151
149
|
}
|
|
152
150
|
|
|
153
|
-
|
|
151
|
+
/**
|
|
152
|
+
* Build inline <link>/<script> tags for an array of asset paths. Used by edit
|
|
153
|
+
* mode (where assets are loaded individually rather than bundled) and by the
|
|
154
|
+
* Vite ESM pipeline (module / modulepreload).
|
|
155
|
+
*
|
|
156
|
+
* @param {string[]} fileArray asset paths
|
|
157
|
+
* @param {string} tag one of STYLE_TAG, SCRIPT_TAG, MODULE_SCRIPT_TAG, MODULEPRELOAD_TAG
|
|
158
|
+
* @returns {Promise<string>} newline-joined tag string
|
|
159
|
+
*/
|
|
160
|
+
function injectTags(fileArray, tag) {
|
|
154
161
|
var buster = module.exports.cacheBuster ? `?version=${module.exports.cacheBuster}` : '';
|
|
162
|
+
// When omitCacheBusterOnModules is enabled, content-hashed ESM files omit the
|
|
163
|
+
// ?version= query string — the hash in the filename already provides cache busting.
|
|
164
|
+
// Defaults to false so existing deployments are unaffected.
|
|
165
|
+
var moduleBuster = module.exports.omitCacheBusterOnModules ? '' : buster;
|
|
155
166
|
|
|
156
167
|
return bluebird.resolve(_.map(fileArray, function (file) {
|
|
157
168
|
if (tag === STYLE_TAG) {
|
|
158
169
|
return `<link rel="stylesheet" type="text/css" href="${file}${buster}">`;
|
|
159
|
-
} else if (tag ===
|
|
160
|
-
return `<script
|
|
161
|
-
} else if (tag ===
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
return `<
|
|
165
|
-
} else {
|
|
166
|
-
return `<script type="text/javascript" src="${file}${buster}"></script>`;
|
|
170
|
+
} else if (tag === MODULE_SCRIPT_TAG) {
|
|
171
|
+
return `<script type="module" src="${file}${moduleBuster}"></script>`;
|
|
172
|
+
} else if (tag === MODULEPRELOAD_TAG) {
|
|
173
|
+
// <link rel="modulepreload"> tells the browser to fetch ESM scripts early,
|
|
174
|
+
// during HTML parsing, before reaching the <script> tags at </body>.
|
|
175
|
+
return `<link rel="modulepreload" href="${file}${moduleBuster}">`;
|
|
167
176
|
}
|
|
168
|
-
}).join('\n'));
|
|
169
|
-
}
|
|
170
177
|
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
*
|
|
175
|
-
* @param {Object} state - Amphora render state.
|
|
176
|
-
* @returns {string[]} - A list of components not available through Webpack.
|
|
177
|
-
*/
|
|
178
|
-
function filterManifestComponents(state) {
|
|
179
|
-
const site = state.locals.site,
|
|
180
|
-
assetDir = site && site.assetDir || MEDIA_DIRECTORY,
|
|
181
|
-
manifestName = site && site.manifestName || 'assets-manifest.json',
|
|
182
|
-
manifestFile = path.resolve(path.join(assetDir, manifestName));
|
|
183
|
-
let manifest;
|
|
184
|
-
|
|
185
|
-
try {
|
|
186
|
-
manifest = files.tryRequire(manifestFile);
|
|
187
|
-
} catch (err) {
|
|
188
|
-
return state._components;
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
return state._components
|
|
193
|
-
.filter(componentName => !manifest.hasOwnProperty(`${ componentName }.js`));
|
|
178
|
+
// Default: classic <script src=...> for SCRIPT_TAG and any other value.
|
|
179
|
+
return `<script type="text/javascript" src="${file}${buster}"></script>`;
|
|
180
|
+
}).join('\n'));
|
|
194
181
|
}
|
|
195
182
|
|
|
196
183
|
/**
|
|
@@ -202,7 +189,6 @@ function getMediaMap(state) {
|
|
|
202
189
|
return {
|
|
203
190
|
styles: module.exports.getStyleFiles(state),
|
|
204
191
|
scripts: module.exports.getScriptFiles(state),
|
|
205
|
-
manifestAssets: module.exports.getManifestAssets(state)
|
|
206
192
|
};
|
|
207
193
|
}
|
|
208
194
|
|
|
@@ -303,7 +289,7 @@ function getScriptFiles(state) {
|
|
|
303
289
|
assetPath = site && site.assetPath || '',
|
|
304
290
|
assetHost = site && site.assetHost || '';
|
|
305
291
|
|
|
306
|
-
return
|
|
292
|
+
return state._components
|
|
307
293
|
.reduce((prev, name) => {
|
|
308
294
|
prev.push(
|
|
309
295
|
path.join(assetDir, 'js', `${name}.js`),
|
|
@@ -316,36 +302,6 @@ function getScriptFiles(state) {
|
|
|
316
302
|
.map(pathJoin(assetHost, assetPath, assetDir));
|
|
317
303
|
}
|
|
318
304
|
|
|
319
|
-
/**
|
|
320
|
-
* Read the asset manifest generated by the `clay pack` bundling command and
|
|
321
|
-
* check for scripts which match the rendered component names. The manifest for
|
|
322
|
-
* each asset lists its complete set of dependencies, so we dedupe them.
|
|
323
|
-
* Webpack's runtime is added to the beginning of the list, downstream legacy
|
|
324
|
-
* globals and Clay CLI's init script to the end.
|
|
325
|
-
*
|
|
326
|
-
* @param {Object} state - Amphora's render state.
|
|
327
|
-
* @return {string[]} A list of component assets.
|
|
328
|
-
*/
|
|
329
|
-
function getManifestAssets(state) {
|
|
330
|
-
const site = state.locals.site,
|
|
331
|
-
assetDir = site && site.assetDir || MEDIA_DIRECTORY,
|
|
332
|
-
assetHost = site && site.assetHost || '/',
|
|
333
|
-
manifestName = site && site.manifestName || 'assets-manifest.json',
|
|
334
|
-
manifestFile = path.resolve(path.join(assetDir, manifestName));
|
|
335
|
-
let manifest;
|
|
336
|
-
|
|
337
|
-
try {
|
|
338
|
-
manifest = files.tryRequire(manifestFile);
|
|
339
|
-
} catch (err) {
|
|
340
|
-
return [];
|
|
341
|
-
}
|
|
342
|
-
|
|
343
|
-
const entrypoints = _.get(manifest, 'entrypoints', []);
|
|
344
|
-
const scriptFiles = _.flatMap(entrypoints, entrypoint => _.get(entrypoint, 'assets.js', []));
|
|
345
|
-
|
|
346
|
-
return scriptFiles.map(script => url.resolve(assetHost, script));
|
|
347
|
-
}
|
|
348
|
-
|
|
349
305
|
/**
|
|
350
306
|
* Trim the path on the file system bythe link of the
|
|
351
307
|
* asset directory and then join it with either the assetHost
|
|
@@ -378,6 +334,14 @@ function configure(options, cacheBuster = '') {
|
|
|
378
334
|
if (options && _.isObject(options)) {
|
|
379
335
|
module.exports.editStylesTags = options.styles || false;
|
|
380
336
|
module.exports.editScriptsTags = options.scripts || false;
|
|
337
|
+
// modulepreload: when true, <link rel="modulepreload"> hints are injected
|
|
338
|
+
// into <head> for ESM scripts, and ?version= is omitted from module URLs
|
|
339
|
+
// since content-hashed filenames already provide cache busting.
|
|
340
|
+
// Opt-in only — defaults to false for backwards compatibility.
|
|
341
|
+
if (options.modulepreload !== undefined) {
|
|
342
|
+
module.exports.modulepreload = !!options.modulepreload;
|
|
343
|
+
module.exports.omitCacheBusterOnModules = !!options.modulepreload;
|
|
344
|
+
}
|
|
381
345
|
} else {
|
|
382
346
|
module.exports.editStylesTags = options;
|
|
383
347
|
module.exports.editScriptsTags = options;
|
|
@@ -397,6 +361,7 @@ function configure(options, cacheBuster = '') {
|
|
|
397
361
|
* @param {Object} state
|
|
398
362
|
* @return {Function}
|
|
399
363
|
*/
|
|
364
|
+
/* eslint-disable complexity */
|
|
400
365
|
function injectScriptsAndStyles(state) {
|
|
401
366
|
const { locals } = state;
|
|
402
367
|
|
|
@@ -412,26 +377,50 @@ function injectScriptsAndStyles(state) {
|
|
|
412
377
|
mediaMap = module.exports.getMediaMap(state);
|
|
413
378
|
|
|
414
379
|
// allow site to change the media map before applying it
|
|
380
|
+
// Expose rendered component names so resolveMedia can do per-component script resolution
|
|
381
|
+
// (e.g. pack-next manifest lookup) without needing a reference to the full state object.
|
|
382
|
+
locals._components = state._components;
|
|
415
383
|
if (setup.resolveMedia) mediaMap = setup.resolveMedia(mediaMap, locals) || mediaMap;
|
|
416
384
|
|
|
385
|
+
// moduleScripts: ESM scripts (e.g. from esbuild pack-next) that need type="module"
|
|
386
|
+
const moduleScriptFiles = mediaMap.moduleScripts || [];
|
|
387
|
+
|
|
388
|
+
mediaMap.moduleScripts = moduleScriptFiles.length
|
|
389
|
+
? injectTags(moduleScriptFiles, MODULE_SCRIPT_TAG)
|
|
390
|
+
: bluebird.resolve(false);
|
|
391
|
+
|
|
392
|
+
// modulePreloads: <link rel="modulepreload"> hints for <head>.
|
|
393
|
+
// Only active when configure({ modulepreload: true }) has been called — opt-in so
|
|
394
|
+
// sites not using the clay build pipeline are completely unaffected.
|
|
395
|
+
const modulePreloadFiles = module.exports.modulepreload
|
|
396
|
+
? mediaMap.modulePreloads || []
|
|
397
|
+
: [];
|
|
398
|
+
|
|
399
|
+
mediaMap.modulePreloads = modulePreloadFiles.length
|
|
400
|
+
? injectTags(modulePreloadFiles, MODULEPRELOAD_TAG)
|
|
401
|
+
: bluebird.resolve(false);
|
|
402
|
+
|
|
417
403
|
if (!locals.edit) {
|
|
418
404
|
mediaMap.styles = combineFileContents(mediaMap.styles, 'public/css', '/css/', STYLE_TAG);
|
|
419
|
-
mediaMap.scripts =
|
|
420
|
-
? injectTags(mediaMap.manifestAssets, locals.site, SCRIPT_TAG)
|
|
421
|
-
: combineFileContents(mediaMap.scripts, 'public/js', '/js/', SCRIPT_TAG);
|
|
405
|
+
mediaMap.scripts = combineFileContents(mediaMap.scripts, 'public/js', '/js/', SCRIPT_TAG);
|
|
422
406
|
} else {
|
|
423
|
-
mediaMap.styles = module.exports.editStylesTags ? injectTags(mediaMap.styles,
|
|
424
|
-
mediaMap.scripts = module.exports.editScriptsTags ? injectTags(mediaMap.scripts,
|
|
407
|
+
mediaMap.styles = module.exports.editStylesTags ? injectTags(mediaMap.styles, STYLE_TAG) : combineFileContents(mediaMap.styles, 'public/css', '/css/', STYLE_TAG);
|
|
408
|
+
mediaMap.scripts = module.exports.editScriptsTags ? injectTags(mediaMap.scripts, SCRIPT_TAG) : combineFileContents(mediaMap.scripts, 'public/js', '/js/', SCRIPT_TAG);
|
|
425
409
|
}
|
|
426
410
|
|
|
427
411
|
return bluebird.props(mediaMap)
|
|
428
412
|
.then(combinedFiles => {
|
|
413
|
+
// modulepreload hints go first in <head>, before CSS, so the browser can
|
|
414
|
+
// start fetching ESM scripts at the earliest possible moment.
|
|
415
|
+
html = combinedFiles.modulePreloads ? appendMediaToTop(combinedFiles.modulePreloads, html) : html;
|
|
429
416
|
html = combinedFiles.styles ? appendMediaToTop(combinedFiles.styles, html) : html; // If there are styles, append them
|
|
417
|
+
html = combinedFiles.moduleScripts ? appendMediaToBottom(combinedFiles.moduleScripts, html) : html; // ESM module scripts (type="module")
|
|
430
418
|
html = combinedFiles.scripts ? appendMediaToBottom(combinedFiles.scripts, html) : html; // If there are scripts, append them
|
|
431
419
|
return html; // Return the compiled HTML
|
|
432
420
|
});
|
|
433
421
|
};
|
|
434
422
|
}
|
|
423
|
+
/* eslint-enable complexity */
|
|
435
424
|
|
|
436
425
|
module.exports.injectScriptsAndStyles = injectScriptsAndStyles;
|
|
437
426
|
module.exports.getMediaMap = getMediaMap;
|
|
@@ -439,8 +428,11 @@ module.exports.cacheBuster = '';
|
|
|
439
428
|
module.exports.configure = configure;
|
|
440
429
|
module.exports.editStylesTags = false;
|
|
441
430
|
module.exports.editScriptsTags = false;
|
|
431
|
+
// Opt-in flags for the clay build (esbuild) pipeline.
|
|
432
|
+
// Enable via configure({ modulepreload: true }).
|
|
433
|
+
module.exports.modulepreload = false;
|
|
434
|
+
module.exports.omitCacheBusterOnModules = false;
|
|
442
435
|
|
|
443
436
|
// For testing
|
|
444
|
-
module.exports.getManifestAssets = getManifestAssets;
|
|
445
437
|
module.exports.getScriptFiles = getScriptFiles;
|
|
446
438
|
module.exports.getStyleFiles = getStyleFiles;
|
package/lib/media.test.js
CHANGED
|
@@ -101,7 +101,7 @@ describe(_.startCase(filename), () => {
|
|
|
101
101
|
const fn = lib['getMediaMap'];
|
|
102
102
|
|
|
103
103
|
test('accepts state with empty components', () => {
|
|
104
|
-
expect(fn(state)).toEqual({
|
|
104
|
+
expect(fn(state)).toEqual({scripts: [], styles: []});
|
|
105
105
|
});
|
|
106
106
|
|
|
107
107
|
test('accepts list, empty slug (non-existent components)', () => {
|
|
@@ -114,7 +114,7 @@ describe(_.startCase(filename), () => {
|
|
|
114
114
|
_.omit(state, ['locals.site.slug'])
|
|
115
115
|
)
|
|
116
116
|
)
|
|
117
|
-
).toEqual({
|
|
117
|
+
).toEqual({scripts: [], styles: []});
|
|
118
118
|
});
|
|
119
119
|
|
|
120
120
|
test('accepts list and slug (non-existent components)', () => {
|
|
@@ -127,7 +127,7 @@ describe(_.startCase(filename), () => {
|
|
|
127
127
|
state
|
|
128
128
|
)
|
|
129
129
|
)
|
|
130
|
-
).toEqual({
|
|
130
|
+
).toEqual({scripts: [], styles: []});
|
|
131
131
|
});
|
|
132
132
|
|
|
133
133
|
test(
|
|
@@ -151,7 +151,7 @@ describe(_.startCase(filename), () => {
|
|
|
151
151
|
}
|
|
152
152
|
)
|
|
153
153
|
)
|
|
154
|
-
).toEqual({
|
|
154
|
+
).toEqual({scripts: expectedScriptFiles, styles: []});
|
|
155
155
|
}
|
|
156
156
|
);
|
|
157
157
|
});
|
|
@@ -625,117 +625,6 @@ describe(_.startCase(filename), () => {
|
|
|
625
625
|
);
|
|
626
626
|
});
|
|
627
627
|
|
|
628
|
-
describe('getManifestAssets', () => {
|
|
629
|
-
const fn = lib['getManifestAssets'];
|
|
630
|
-
|
|
631
|
-
describe('constructs the correct asset URL', () => {
|
|
632
|
-
test('when assetHost is configured', () => {
|
|
633
|
-
const assetHost = 'https://assets.nymag.com';
|
|
634
|
-
const localState = {
|
|
635
|
-
locals: {
|
|
636
|
-
site: {
|
|
637
|
-
assetHost
|
|
638
|
-
}
|
|
639
|
-
},
|
|
640
|
-
_components: [
|
|
641
|
-
'a',
|
|
642
|
-
'b'
|
|
643
|
-
]
|
|
644
|
-
};
|
|
645
|
-
const manifest = {
|
|
646
|
-
entrypoints: {
|
|
647
|
-
a: {
|
|
648
|
-
assets: {
|
|
649
|
-
js: ['/a.js']
|
|
650
|
-
}
|
|
651
|
-
},
|
|
652
|
-
b: {
|
|
653
|
-
assets: {
|
|
654
|
-
js: ['b.js']
|
|
655
|
-
}
|
|
656
|
-
}
|
|
657
|
-
}
|
|
658
|
-
};
|
|
659
|
-
|
|
660
|
-
jest.spyOn(files, 'tryRequire').mockImplementation(() => manifest);
|
|
661
|
-
|
|
662
|
-
expect(fn(localState)).toEqual([
|
|
663
|
-
`${ assetHost }/a.js`,
|
|
664
|
-
`${ assetHost }/b.js`
|
|
665
|
-
]);
|
|
666
|
-
});
|
|
667
|
-
|
|
668
|
-
test('when assetHost is not configured', () => {
|
|
669
|
-
const localState = {
|
|
670
|
-
locals: {
|
|
671
|
-
site: {
|
|
672
|
-
}
|
|
673
|
-
},
|
|
674
|
-
_components: [
|
|
675
|
-
'a',
|
|
676
|
-
'b'
|
|
677
|
-
]
|
|
678
|
-
};
|
|
679
|
-
const manifest = {
|
|
680
|
-
entrypoints: {
|
|
681
|
-
a: {
|
|
682
|
-
assets: {
|
|
683
|
-
js: ['/a.js']
|
|
684
|
-
}
|
|
685
|
-
},
|
|
686
|
-
b: {
|
|
687
|
-
assets: {
|
|
688
|
-
js: ['b.js']
|
|
689
|
-
}
|
|
690
|
-
}
|
|
691
|
-
}
|
|
692
|
-
};
|
|
693
|
-
|
|
694
|
-
jest.spyOn(files, 'tryRequire').mockImplementation(() => manifest);
|
|
695
|
-
|
|
696
|
-
expect(fn(localState)).toEqual([
|
|
697
|
-
'/a.js',
|
|
698
|
-
'/b.js'
|
|
699
|
-
]);
|
|
700
|
-
});
|
|
701
|
-
|
|
702
|
-
test('without prepending assetPath', () => {
|
|
703
|
-
const localState = {
|
|
704
|
-
locals: {
|
|
705
|
-
site: {
|
|
706
|
-
assetPath: '/strategist'
|
|
707
|
-
}
|
|
708
|
-
},
|
|
709
|
-
_components: [
|
|
710
|
-
'a',
|
|
711
|
-
'b'
|
|
712
|
-
]
|
|
713
|
-
};
|
|
714
|
-
const manifest = {
|
|
715
|
-
entrypoints: {
|
|
716
|
-
a: {
|
|
717
|
-
assets: {
|
|
718
|
-
js: ['/a.js']
|
|
719
|
-
}
|
|
720
|
-
},
|
|
721
|
-
b: {
|
|
722
|
-
assets: {
|
|
723
|
-
js: ['b.js']
|
|
724
|
-
}
|
|
725
|
-
}
|
|
726
|
-
}
|
|
727
|
-
};
|
|
728
|
-
|
|
729
|
-
jest.spyOn(files, 'tryRequire').mockImplementation(() => manifest);
|
|
730
|
-
|
|
731
|
-
expect(fn(localState)).toEqual([
|
|
732
|
-
'/a.js',
|
|
733
|
-
'/b.js'
|
|
734
|
-
]);
|
|
735
|
-
});
|
|
736
|
-
});
|
|
737
|
-
});
|
|
738
|
-
|
|
739
628
|
describe('injectScriptsAndStyles', () => {
|
|
740
629
|
const fn = lib['injectScriptsAndStyles'];
|
|
741
630
|
|
package/lib/render.js
CHANGED
|
@@ -38,9 +38,12 @@ function applyRenderHooks(ref, data, locals) {
|
|
|
38
38
|
*
|
|
39
39
|
* @param {String} ref
|
|
40
40
|
* @param {Object} locals
|
|
41
|
+
* @param {Object} res
|
|
42
|
+
* @param {String} self Clay ref of the component being rendered, e.g.
|
|
43
|
+
* "site.com/_components/article/instances/foo"
|
|
41
44
|
* @returns {Function}
|
|
42
45
|
*/
|
|
43
|
-
function applyPostRenderHooks(ref, locals) {
|
|
46
|
+
function applyPostRenderHooks(ref, locals, res, self) {
|
|
44
47
|
return (html) => {
|
|
45
48
|
|
|
46
49
|
// skip postRender hooks in edit mode
|
|
@@ -50,7 +53,7 @@ function applyPostRenderHooks(ref, locals) {
|
|
|
50
53
|
|
|
51
54
|
return setup.plugins.filter((plugin) => plugin.postRender)
|
|
52
55
|
.reduce((val, plugin) => {
|
|
53
|
-
return plugin.postRender(ref, html, locals);
|
|
56
|
+
return plugin.postRender(ref, html, locals, res, self);
|
|
54
57
|
}, html);
|
|
55
58
|
};
|
|
56
59
|
}
|
|
@@ -148,7 +151,7 @@ function render(data, meta, res) {
|
|
|
148
151
|
return applyRenderHooks(state._layoutRef || state.self, data, state.locals)
|
|
149
152
|
.then(makeHtml(state))
|
|
150
153
|
.then(mediaService.injectScriptsAndStyles(state))
|
|
151
|
-
.then(applyPostRenderHooks(state._layoutRef || state.self, state.locals))
|
|
154
|
+
.then(applyPostRenderHooks(state._layoutRef || state.self, state.locals, res, meta._ref))
|
|
152
155
|
.then(result => {
|
|
153
156
|
res.type('text/html');
|
|
154
157
|
res.send(result);
|
|
@@ -182,8 +185,12 @@ function logTime(hrStart, msg, route) {
|
|
|
182
185
|
};
|
|
183
186
|
}
|
|
184
187
|
|
|
185
|
-
function configure({ editAssetTags, cacheBuster }) {
|
|
186
|
-
|
|
188
|
+
function configure({ editAssetTags, cacheBuster, modulepreload }) {
|
|
189
|
+
const mediaOptions = editAssetTags && typeof editAssetTags === 'object'
|
|
190
|
+
? Object.assign({}, editAssetTags, modulepreload !== undefined ? { modulepreload } : {})
|
|
191
|
+
: editAssetTags;
|
|
192
|
+
|
|
193
|
+
mediaService.configure(mediaOptions, cacheBuster);
|
|
187
194
|
}
|
|
188
195
|
|
|
189
196
|
/**
|
package/package.json
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "amphora-html",
|
|
3
|
-
"version": "6.0.0
|
|
3
|
+
"version": "6.0.0",
|
|
4
4
|
"description": "An HTML renderer for component data",
|
|
5
5
|
"main": "index.js",
|
|
6
|
+
"engines": {
|
|
7
|
+
"node": ">=20.14.0"
|
|
8
|
+
},
|
|
6
9
|
"scripts": {
|
|
7
10
|
"test": "npm run eslint && npm run jest -- --coverage --no-cache",
|
|
8
11
|
"eslint": "eslint --max-warnings 0 lib test",
|
package/.circleci/config.yml
DELETED
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
version: 2
|
|
2
|
-
|
|
3
|
-
# Set defaults to reuse
|
|
4
|
-
defaults: &defaults
|
|
5
|
-
working_directory: ~/repo
|
|
6
|
-
docker:
|
|
7
|
-
- image: circleci/node:8.10.0
|
|
8
|
-
|
|
9
|
-
jobs:
|
|
10
|
-
test:
|
|
11
|
-
<<: *defaults
|
|
12
|
-
steps:
|
|
13
|
-
- checkout
|
|
14
|
-
|
|
15
|
-
- restore_cache:
|
|
16
|
-
keys:
|
|
17
|
-
- v2-dependencies-{{ checksum "package.json" }}
|
|
18
|
-
# fallback to using the latest cache if no exact match is found
|
|
19
|
-
- v2-dependencies-
|
|
20
|
-
|
|
21
|
-
- run: npm install
|
|
22
|
-
- run:
|
|
23
|
-
name: Run tests
|
|
24
|
-
command: npm test
|
|
25
|
-
- run:
|
|
26
|
-
name: Send to Coveralls
|
|
27
|
-
command: cat coverage/lcov.info | ./node_modules/coveralls/bin/coveralls.js
|
|
28
|
-
- save_cache:
|
|
29
|
-
paths:
|
|
30
|
-
- node_modules
|
|
31
|
-
key: v2-dependencies-{{ checksum "package.json" }}
|
|
32
|
-
|
|
33
|
-
- persist_to_workspace:
|
|
34
|
-
root: ~/repo
|
|
35
|
-
paths: .
|
|
36
|
-
|
|
37
|
-
workflows:
|
|
38
|
-
version: 2
|
|
39
|
-
test-deploy:
|
|
40
|
-
jobs:
|
|
41
|
-
- test:
|
|
42
|
-
filters:
|
|
43
|
-
tags:
|
|
44
|
-
only: /^v[0-9]+\.[0-9]+\.[0-9]+/
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
on: push
|
|
2
|
-
name: Deploy to GitHub Pages
|
|
3
|
-
jobs:
|
|
4
|
-
filterBranch:
|
|
5
|
-
name: Filter branch
|
|
6
|
-
runs-on: ubuntu-latest
|
|
7
|
-
steps:
|
|
8
|
-
- uses: actions/checkout@master
|
|
9
|
-
- name: Filter branch
|
|
10
|
-
uses: actions/bin/filter@master
|
|
11
|
-
with:
|
|
12
|
-
args: branch master
|
|
13
|
-
- name: Install
|
|
14
|
-
uses: actions/npm@master
|
|
15
|
-
with:
|
|
16
|
-
args: install --prefix ./website
|
|
17
|
-
- name: Update version
|
|
18
|
-
uses: clay/docusaurus-github-action@master
|
|
19
|
-
with:
|
|
20
|
-
args: version
|
|
21
|
-
- name: Build and push docs
|
|
22
|
-
uses: clay/docusaurus-github-action@master
|
|
23
|
-
env:
|
|
24
|
-
DEPLOY_SSH_KEY: ${{ secrets.DEPLOY_SSH_KEY }}
|
|
25
|
-
with:
|
|
26
|
-
args: deploy
|