1 | 'use strict';
|
2 |
|
3 | const path = require('path');
|
4 | const fs = require('fs');
|
5 | const EventEmitter = require('events').EventEmitter;
|
6 | const requestHandler = require('./lib/request-handler');
|
7 | const fetchTemplate = require('./lib/fetch-template');
|
8 | const parseTemplate = require('./lib/parse-template');
|
9 | const requestFragment = require('./lib/request-fragment');
|
10 | const filterReqHeadersFn = require('./lib/filter-headers');
|
11 | const PIPE_DEFINITION = fs.readFileSync(
|
12 | path.resolve(__dirname, 'src/pipe.min.js')
|
13 | );
|
14 | const AMD_LOADER_URL =
|
15 | 'https://cdnjs.cloudflare.com/ajax/libs/require.js/2.1.22/require.min.js';
|
16 |
|
17 | const stripUrl = fileUrl => path.normalize(fileUrl.replace('file://', ''));
|
18 | const getPipeAttributes = attributes => {
|
19 | const { primary, id } = attributes;
|
20 | return {
|
21 | primary: !!(primary || primary === ''),
|
22 | id
|
23 | };
|
24 | };
|
25 |
|
26 | module.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 |
|
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 |
|
83 | this.on('error', () => {});
|
84 | }
|
85 | };
|