UNPKG

3.11 kBJavaScriptView Raw
1'use strict';
2
3const path = require('path');
4const fs = require('fs');
5const EventEmitter = require('events').EventEmitter;
6const requestHandler = require('./lib/request-handler');
7const fetchTemplate = require('./lib/fetch-template');
8const parseTemplate = require('./lib/parse-template');
9const requestFragment = require('./lib/request-fragment');
10const filterReqHeadersFn = require('./lib/filter-headers');
11const PIPE_DEFINITION = fs.readFileSync(
12 path.resolve(__dirname, 'src/pipe.min.js')
13);
14const AMD_LOADER_URL =
15 'https://cdnjs.cloudflare.com/ajax/libs/require.js/2.1.22/require.min.js';
16
17const stripUrl = fileUrl => path.normalize(fileUrl.replace('file://', ''));
18const getPipeAttributes = attributes => {
19 const { primary, id } = attributes;
20 return {
21 primary: !!(primary || primary === ''),
22 id
23 };
24};
25
26module.exports = class Tailor extends EventEmitter {
27 constructor(options) {
28 super();
29 const {
30 amdLoaderUrl = AMD_LOADER_URL,
31 filterRequestHeaders = options.filterHeaders || filterReqHeadersFn,
32 maxAssetLinks,
33 templatesPath
34 } = options;
35
36 options.maxAssetLinks = isNaN(maxAssetLinks)
37 ? 1
38 : Math.max(1, maxAssetLinks);
39
40 let memoizedDefinition;
41 const pipeChunk = (amdLoaderUrl, pipeInstanceName) => {
42 if (!memoizedDefinition) {
43 // Allow reading from fs for inlining AMD
44 if (amdLoaderUrl.startsWith('file://')) {
45 let fileData = fs.readFileSync(
46 stripUrl(amdLoaderUrl),
47 'utf-8'
48 );
49 memoizedDefinition = `<script>${fileData}\n`;
50 } else {
51 memoizedDefinition = `<script src="${amdLoaderUrl}"></script>\n<script>`;
52 }
53 }
54 return Buffer.from(
55 `${memoizedDefinition}var ${pipeInstanceName}=${PIPE_DEFINITION}</script>\n`
56 );
57 };
58
59 const requestOptions = Object.assign(
60 {
61 fetchContext: () => Promise.resolve({}),
62 fetchTemplate: fetchTemplate(
63 templatesPath || path.join(process.cwd(), 'templates')
64 ),
65 fragmentTag: 'fragment',
66 handledTags: [],
67 handleTag: () => '',
68 requestFragment: requestFragment(filterRequestHeaders),
69 pipeInstanceName: 'Pipe',
70 pipeDefinition: pipeChunk.bind(null, amdLoaderUrl),
71 pipeAttributes: getPipeAttributes
72 },
73 options
74 );
75
76 requestOptions.parseTemplate = parseTemplate(
77 [requestOptions.fragmentTag].concat(requestOptions.handledTags),
78 ['script', requestOptions.fragmentTag]
79 );
80
81 this.requestHandler = requestHandler.bind(this, requestOptions);
82 // To Prevent from exiting the process - https://nodejs.org/api/events.html#events_error_events
83 this.on('error', () => {});
84 }
85};