Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

React to 18 test - POC for using react-18 in ssg-hx-uk #95

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
.DS_Store
node_modules/
lib/
# lib/
npm-debug.log
.eslintrc
.eslintcache
34 changes: 34 additions & 0 deletions lib/apiCaller.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
"use strict";

Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _pageData = _interopRequireDefault(require("./components/pageData"));
var _path = _interopRequireDefault(require("path"));
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
var apiCaller = function apiCaller(opts) {
return function (files, metalsmith, done) {
var _opts$url;
var postQuery = (opts === null || opts === void 0 || (_opts$url = opts.url) === null || _opts$url === void 0 ? void 0 : _opts$url.postBuild) || false;
new _pageData.default({
opts: opts,
files: files
}).then(function (data) {
var newDone = function newDone(data) {
files = data;
done();
};
if (postQuery) {
var pathToFunc = _path.default.join(metalsmith._directory, postQuery);
var func = require(pathToFunc);
if (typeof func !== 'function') return newDone(data);
func(data).then(newDone).catch(function (err) {
console.log(err);
newDone(data);
});
} else newDone(data);
});
};
};
var _default = exports.default = apiCaller;
237 changes: 237 additions & 0 deletions lib/components/pageData.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,237 @@
"use strict";

Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _http = _interopRequireDefault(require("http"));
var _https = _interopRequireDefault(require("https"));
var _pageNameChanger = _interopRequireDefault(require("./pageNameChanger"));
var _pageNameSanitiser = _interopRequireDefault(require("./pageNameSanitiser"));
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
function _classCallCheck(a, n) { if (!(a instanceof n)) throw new TypeError("Cannot call a class as a function"); }
function _defineProperties(e, r) { for (var t = 0; t < r.length; t++) { var o = r[t]; o.enumerable = o.enumerable || !1, o.configurable = !0, "value" in o && (o.writable = !0), Object.defineProperty(e, _toPropertyKey(o.key), o); } }
function _createClass(e, r, t) { return r && _defineProperties(e.prototype, r), t && _defineProperties(e, t), Object.defineProperty(e, "prototype", { writable: !1 }), e; }
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; }
function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
var PageData = /*#__PURE__*/function () {
function PageData() {
var params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
_classCallCheck(this, PageData);
this.params = params;
return this.init();
}
return _createClass(PageData, [{
key: "returnFiles",
value: function returnFiles() {
return this.params.files;
}
}, {
key: "extractData",
value: function extractData(data, fileName, fileParams) {
var extraFiles = fileParams.extraFiles,
_fileParams$dataSourc = fileParams.dataSource,
dataSource = _fileParams$dataSourc === void 0 ? {} : _fileParams$dataSourc;
var repeater = dataSource.repeater,
pageDataField = dataSource.pageDataField,
pageNameField = dataSource.pageNameField;
var newFiles = [];
if (repeater) data = data[repeater];
if (!data || !data.length) {
return {
data: data,
response: newFiles
};
}
for (var i = 0; i < data.length; i++) {
var newFile = extraFiles ? {} : JSON.parse(JSON.stringify(this.params.files[fileName]));
var folder = fileName.split('/');
folder = folder && folder.length > 1 ? folder.slice(0, -1).join('/') + '/' : '';

// Attach page data to props passed to the page
var pageData = data[i];
if (pageDataField) pageData = data[i][pageDataField];
var pageName = pageData[pageNameField];
pageName = (0, _pageNameSanitiser.default)(pageName);
pageName = (0, _pageNameChanger.default)(pageName, dataSource);
pageName = folder + pageName;
if (extraFiles) newFile = pageData;else newFile.pageData = pageData;
newFile.pagename = newFile.pageName = pageName + '.html';

// Create the new page in metalsmith
newFile.srcFile = fileName;
// Filter out files that have a trailing slash. (will become something like "/foobarbaz/.html", which can't be build)
if (/\/.html$/.test(newFile.pageName)) {
console.log("Page ".concat(newFile.pageName, " has a trailing slash and cannot be built"));
continue;
}
if (!extraFiles) this.params.files[newFile.pageName] = newFile;
data[i] = newFile;
newFiles.push({
data: newFile,
key: newFile.pageName
});
}
return {
data: data,
response: newFiles
};
}

// Make request to the API endpoint in the markdown file
}, {
key: "getDataForPage",
value: function getDataForPage(res, fileName, fileParams) {
var _this = this;
return new Promise(function (resolve, reject) {
var data = '';
res.on('data', function (d) {
data += d;
});
res.on('end', function () {
try {
var newData = data.split('').map(function (char) {
return char.charCodeAt(0).toString().length < 4 ? char : "&#".concat(char.charCodeAt(0), ";");
}).join('').replace(/(\\u|\\x|\\d)\d{4}/gm, '').replace(/&#822[0-1];/gm, '\\"').replace(/&#821[6-7];/gm, '\'');
data = newData;
} catch (e) {
console.log(e, 'Can\'t convert charCodeAt');
}
try {
data = JSON.parse(data);
if (!data) return reject(new Error('Nothing returned'));
if (data.message) return reject(data.message);
var response = _this.extractData(data, fileName, fileParams);
return resolve(response);
} catch (e) {
return reject(e);
}
});
});
}

// Call the API per markdown file and get data for each one returned.
}, {
key: "callAPI",
value: function callAPI(fileName, fileParams) {
var _this2 = this;
return new Promise(function (resolve, reject) {
var request = _this2.prepareRequest(fileParams);
var requestMethod = request.port === '443' ? _https.default : _http.default;
requestMethod.get(request, function (res) {
_this2.getDataForPage(res, fileName, fileParams).then(function (fileData) {
// Remove the markdown file from metalsmith as its not an actual page
delete _this2.params.files[fileName];
if (fileData.response) return resolve(fileData.response);
return reject(new Error('No response found'));
}).catch(reject);
});
});
}
}, {
key: "makeExtraAPICalls",
value: function makeExtraAPICalls(data, fileParams, callBack) {
var _this3 = this;
// Now check for additional requests per page returned from API call
// This can be prodlib data based on an SEO object
if (!fileParams.dataSource.extras) return callBack();
var loop = fileParams.dataSource.extras;
return Object.keys(loop).filter(function (opt) {
return loop[opt].query;
}).map(function (opt) {
loop[opt].extraFiles = true;
var option = loop[opt].query.match(/<%([^%].*)%>/);
var extraPageData = data.map(function (currentFile) {
return new Promise(function (resolve, reject) {
if (!currentFile.data.pageData[option[1]]) {
var errorMsg = "No extra options found for ".concat(_this3.params.files[currentFile.key].pageName);
console.log(errorMsg);
reject(new Error(errorMsg));
return delete _this3.params.files[currentFile.key];
}
var value = currentFile.data.pageData[option[1]];
fileParams = Object.assign({}, loop[opt]);
fileParams.query = fileParams.query.replace(option[0], value);
fileParams.dataSource = fileParams; // Needs to double up for functions
var request = _this3.prepareRequest(fileParams);
var requestMethod = request.port === '443' ? _https.default : _http.default;
return requestMethod.get(request, function (res) {
_this3.getDataForPage(res, currentFile.key, fileParams).then(function (newFiles) {
_this3.params.files[currentFile.key][opt] = newFiles.data;
resolve();
}).catch(reject);
});
});
});
Promise.all(extraPageData).then(callBack).catch(callBack);
return opt;
});
}
}, {
key: "prepareRequest",
value: function prepareRequest(fileParams) {
var opts = this.params.opts;
var request = {
timeout: 10000,
host: fileParams.dataSource.host,
port: fileParams.dataSource.port || '443',
headers: {
accept: '*/*'
}
};
request.path = fileParams.dataSource.query.replace(/\s+/gm, '');
if (opts.token && opts.token.name && opts.token.value) {
request.path += request.path.indexOf('?') > -1 ? '&' : '?';
request.path += opts.token.name + '=' + opts.token.value;
}
return request;
}

// Remove anything in the markdown query that isn't this single page
}, {
key: "singlePageReduce",
value: function singlePageReduce(query) {
if (!query) return false;
var selector = '&filter[pageName]=';
if (query.indexOf(selector) < 0) return query;
var pageList = query.split(selector);
query = query.split(selector).slice(0, 1);
var newQuery = '';
pageList.filter(function (page) {
return page.split('&')[0] === process.env.singlePage;
}).forEach(function (page) {
newQuery += selector + page;
});
return newQuery !== '' ? query + newQuery : false;
}

// Loop over all the markdown files and lookup the data for the API request
}, {
key: "init",
value: function init() {
var _this4 = this;
var fetchedPageData = Object.keys(this.params.files).map(function (fileName) {
return new Promise(function (resolve, reject) {
var fileParams = _this4.params.files[fileName];
if (_this4.params.opts.initSetup) fileParams = _this4.params.opts.initSetup(fileParams);
if (!fileParams.dataSource) return reject(new Error('SSG Error: no dataSource'));
if (process.env.singlePage) fileParams.dataSource.query = _this4.singlePageReduce(fileParams.dataSource.query);
if (!fileParams.dataSource.query) {
delete _this4.params.files[fileName];
return resolve();
}
return _this4.callAPI(fileName, fileParams).then(function (data) {
_this4.makeExtraAPICalls(data, fileParams, resolve);
}).catch(reject);
});
});
return Promise.all(fetchedPageData).then(function () {
return _this4.returnFiles();
}).catch(function () {
return _this4.returnFiles();
});
}
}]);
}();
var _default = exports.default = PageData;
28 changes: 28 additions & 0 deletions lib/components/pageNameChanger.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
"use strict";

Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var pageNameChanger = function pageNameChanger(pageName, fileParams) {
var _fileParams$postPageN = fileParams.postPageNameChange,
postPageNameChange = _fileParams$postPageN === void 0 ? '' : _fileParams$postPageN,
_fileParams$fileNameP = fileParams.fileNamePrefix,
fileNamePrefix = _fileParams$fileNameP === void 0 ? '' : _fileParams$fileNameP,
_fileParams$fileNameS = fileParams.fileNameSuffix,
fileNameSuffix = _fileParams$fileNameS === void 0 ? '' : _fileParams$fileNameS;
if (!postPageNameChange) return "".concat(fileNamePrefix).concat(pageName).concat(fileNameSuffix);
if (postPageNameChange === 'strip') {
pageName = pageName.split('/');
pageName = pageName[pageName.length - 1].replace(/[\d]+/, '');
var pageNames = pageName.split('-');
var start = pageNames[0] === '' ? 1 : 0;
pageNames = pageNames.slice(start, pageNames.length);
if (pageNames[pageNames.length - 1] === '') {
pageNames = pageNames.slice(0, pageNames.length - 1);
}
pageName = pageNames.join('-').toLowerCase().replace(/--+/, '-');
}
return "".concat(fileNamePrefix).concat(pageName).concat(fileNameSuffix);
};
var _default = exports.default = pageNameChanger;
21 changes: 21 additions & 0 deletions lib/components/pageNameSanitiser.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
"use strict";

Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var findreplace = {
'haven-t': 'havent',
'isn-t': 'isnt',
'can-t': 'cant'
};
var regExp = new RegExp('(' + Object.keys(findreplace).map(function (word) {
return word.replace(/[.?*+^$[\]\\(){}|-]/g, '\\$&');
}).join('|') + ')', 'g');
var regExpReplace = function regExpReplace(s) {
return findreplace[s];
};
var pageNameSanitiser = function pageNameSanitiser(str) {
return str.replace(regExp, regExpReplace);
};
var _default = exports.default = pageNameSanitiser;
48 changes: 48 additions & 0 deletions lib/getDataSource.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
"use strict";

Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _metalsmithPrismic = _interopRequireDefault(require("./metalsmith-prismic"));
var _getHXSEOContent = _interopRequireDefault(require("./getHXSEOContent"));
var _writeRedirect = _interopRequireDefault(require("./writeRedirect"));
var _apiCaller = _interopRequireDefault(require("./apiCaller"));
var _lodash = _interopRequireDefault(require("lodash"));
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
var getDataSource = function getDataSource(opts) {
if (!opts.dataSource) return false;
if (typeof opts.dataSource === 'function') return opts.dataSource;

// Lets work out the datasource
if (opts.dataSource.type === 'prismic') {
var configLinkResolver = opts.config.linkResolver instanceof Function && opts.config.linkResolver;
return (0, _metalsmithPrismic.default)({
url: opts.dataSource.url,
accessToken: opts.dataSource.accessToken,
linkResolver: configLinkResolver || function (ctx, doc) {
if (doc.isBroken) return '';

// create redirect script if needed
(0, _writeRedirect.default)(doc.data);

// Page url
if (_lodash.default.has(doc, 'data.slug.json.value')) {
var regExpDomain = new RegExp(".*".concat(opts.config.domainSettings.domainLive));
// Strip domain (+ everything before it) off of the slug in case it was added by mistake
var slug = doc.data.slug.json.value;
return slug.replace(regExpDomain, '');
}
return '/' + doc.uid;
}
});
}
if (opts.dataSource.type === 'hxseo') {
return (0, _getHXSEOContent.default)(opts.dataSource.url);
}
if (opts.dataSource.type === 'api') {
return (0, _apiCaller.default)(opts.dataSource);
}
return false; // fallback
};
var _default = exports.default = getDataSource;
Loading
Loading