implements an easier pattern of pointing to files within config
This commit is contained in:
@@ -1,21 +1,23 @@
|
||||
function stringify(obj) {
|
||||
const path = require('path');
|
||||
|
||||
function stringify(obj, config) {
|
||||
if (typeof obj === 'object') {
|
||||
const result = [];
|
||||
Object.keys(obj).forEach((key) => {
|
||||
const val = stringify(obj[key]);
|
||||
const val = stringify(obj[key], config);
|
||||
if (val !== null) {
|
||||
result.push(`"${key}": ${val}`);
|
||||
}
|
||||
});
|
||||
return `{${result.join(',')}}`;
|
||||
}
|
||||
return `React.lazy(() => import('${obj}'))`;
|
||||
return `React.lazy(() => import('${path.join(config.paths.configDir, obj)}'))`;
|
||||
}
|
||||
|
||||
function recursivelyAddFieldComponents(fields) {
|
||||
function recursivelyAddFieldComponents(fields, config) {
|
||||
if (fields) {
|
||||
return fields.reduce((allFields, field) => {
|
||||
const subFields = recursivelyAddFieldComponents(field.fields);
|
||||
const subFields = recursivelyAddFieldComponents(field.fields, config);
|
||||
|
||||
if (!field.name && field.fields) {
|
||||
return {
|
||||
@@ -55,7 +57,7 @@ function customComponents(config) {
|
||||
const newComponents = { ...components };
|
||||
|
||||
newComponents[collection.slug] = {
|
||||
fields: recursivelyAddFieldComponents(collection.fields),
|
||||
fields: recursivelyAddFieldComponents(collection.fields, config),
|
||||
...(collection.admin.components || {}),
|
||||
};
|
||||
|
||||
@@ -66,7 +68,7 @@ function customComponents(config) {
|
||||
const newComponents = { ...globals };
|
||||
|
||||
newComponents[global.slug] = {
|
||||
fields: recursivelyAddFieldComponents(global.fields),
|
||||
fields: recursivelyAddFieldComponents(global.fields, config),
|
||||
...(global.admin.components || {}),
|
||||
};
|
||||
|
||||
@@ -77,7 +79,7 @@ function customComponents(config) {
|
||||
...(allCollectionComponents || {}),
|
||||
...(allGlobalComponents || {}),
|
||||
...(config.admin.components || {}),
|
||||
}).replace(/\\/g, '\\\\');
|
||||
}, config).replace(/\\/g, '\\\\');
|
||||
|
||||
return {
|
||||
code: `
|
||||
|
||||
@@ -9,3 +9,147 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* atom-dark theme for `prism.js`
|
||||
* Based on Atom's `atom-dark` theme: https://github.com/atom/atom-dark-syntax
|
||||
* @author Joe Gibson (@gibsjose)
|
||||
*/
|
||||
|
||||
code[class*="language-"],
|
||||
pre[class*="language-"] {
|
||||
color: #c5c8c6;
|
||||
text-shadow: 0 1px rgba(0, 0, 0, 0.3);
|
||||
font-family: Inconsolata, Monaco, Consolas, 'Courier New', Courier, monospace;
|
||||
direction: ltr;
|
||||
text-align: left;
|
||||
white-space: pre;
|
||||
word-spacing: normal;
|
||||
word-break: normal;
|
||||
line-height: 1.5;
|
||||
|
||||
-moz-tab-size: 4;
|
||||
-o-tab-size: 4;
|
||||
tab-size: 4;
|
||||
|
||||
-webkit-hyphens: none;
|
||||
-moz-hyphens: none;
|
||||
-ms-hyphens: none;
|
||||
hyphens: none;
|
||||
}
|
||||
|
||||
/* Code blocks */
|
||||
pre[class*="language-"] {
|
||||
padding: 1em;
|
||||
margin: .5em 0;
|
||||
overflow: auto;
|
||||
border-radius: 0.3em;
|
||||
}
|
||||
|
||||
:not(pre) > code[class*="language-"],
|
||||
pre[class*="language-"] {
|
||||
background: #1d1f21;
|
||||
}
|
||||
|
||||
/* Inline code */
|
||||
:not(pre) > code[class*="language-"] {
|
||||
padding: .1em;
|
||||
border-radius: .3em;
|
||||
}
|
||||
|
||||
.token.comment,
|
||||
.token.prolog,
|
||||
.token.doctype,
|
||||
.token.cdata {
|
||||
color: #7C7C7C;
|
||||
}
|
||||
|
||||
.token.punctuation {
|
||||
color: #c5c8c6;
|
||||
}
|
||||
|
||||
.namespace {
|
||||
opacity: .7;
|
||||
}
|
||||
|
||||
.token.property,
|
||||
.token.keyword,
|
||||
.token.tag {
|
||||
color: #96CBFE;
|
||||
}
|
||||
|
||||
.token.class-name {
|
||||
color: #FFFFB6;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.token.boolean,
|
||||
.token.constant {
|
||||
color: #99CC99;
|
||||
}
|
||||
|
||||
.token.symbol,
|
||||
.token.deleted {
|
||||
color: #f92672;
|
||||
}
|
||||
|
||||
.token.number {
|
||||
color: #FF73FD;
|
||||
}
|
||||
|
||||
.token.selector,
|
||||
.token.attr-name,
|
||||
.token.string,
|
||||
.token.char,
|
||||
.token.builtin,
|
||||
.token.inserted {
|
||||
color: #A8FF60;
|
||||
}
|
||||
|
||||
.token.variable {
|
||||
color: #C6C5FE;
|
||||
}
|
||||
|
||||
.token.operator {
|
||||
color: #EDEDED;
|
||||
}
|
||||
|
||||
.token.entity {
|
||||
color: #FFFFB6;
|
||||
cursor: help;
|
||||
}
|
||||
|
||||
.token.url {
|
||||
color: #96CBFE;
|
||||
}
|
||||
|
||||
.language-css .token.string,
|
||||
.style .token.string {
|
||||
color: #87C38A;
|
||||
}
|
||||
|
||||
.token.atrule,
|
||||
.token.attr-value {
|
||||
color: #F9EE98;
|
||||
}
|
||||
|
||||
.token.function {
|
||||
color: #DAD085;
|
||||
}
|
||||
|
||||
.token.regex {
|
||||
color: #E9C062;
|
||||
}
|
||||
|
||||
.token.important {
|
||||
color: #fd971f;
|
||||
}
|
||||
|
||||
.token.important,
|
||||
.token.bold {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.token.italic {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
@@ -124,7 +124,6 @@ const propTypes = {
|
||||
collection: PropTypes.shape({
|
||||
slug: PropTypes.string,
|
||||
upload: PropTypes.shape({
|
||||
staticDir: PropTypes.string,
|
||||
adminThumbnail: PropTypes.string,
|
||||
}),
|
||||
}).isRequired,
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
const mkdirp = require('mkdirp');
|
||||
const path = require('path');
|
||||
|
||||
const executeAccess = require('../../auth/executeAccess');
|
||||
|
||||
@@ -9,7 +10,7 @@ const getImageSize = require('../../uploads/getImageSize');
|
||||
const imageMIMETypes = require('../../uploads/imageMIMETypes');
|
||||
|
||||
async function create(args) {
|
||||
const { performFieldOperations } = this;
|
||||
const { performFieldOperations, config } = this;
|
||||
|
||||
const {
|
||||
collection: {
|
||||
@@ -102,19 +103,21 @@ async function create(args) {
|
||||
throw new MissingFile();
|
||||
}
|
||||
|
||||
mkdirp.sync(staticDir);
|
||||
const staticPath = path.join(config.paths.configDir, staticDir);
|
||||
|
||||
const fsSafeName = await getSafeFilename(staticDir, file.name);
|
||||
mkdirp.sync(staticPath);
|
||||
|
||||
await file.mv(`${staticDir}/${fsSafeName}`);
|
||||
const fsSafeName = await getSafeFilename(staticPath, file.name);
|
||||
|
||||
await file.mv(`${staticPath}/${fsSafeName}`);
|
||||
|
||||
if (imageMIMETypes.indexOf(file.mimetype) > -1) {
|
||||
const dimensions = await getImageSize(`${staticDir}/${fsSafeName}`);
|
||||
const dimensions = await getImageSize(`${staticPath}/${fsSafeName}`);
|
||||
fileData.width = dimensions.width;
|
||||
fileData.height = dimensions.height;
|
||||
|
||||
if (Array.isArray(imageSizes) && file.mimetype !== 'image/svg+xml') {
|
||||
fileData.sizes = await resizeAndSave(collectionConfig, fsSafeName, fileData.mimeType);
|
||||
fileData.sizes = await resizeAndSave(staticPath, collectionConfig, fsSafeName, fileData.mimeType);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
const { NotFound, Forbidden, ErrorDeletingFile } = require('../../errors');
|
||||
const executeAccess = require('../../auth/executeAccess');
|
||||
|
||||
@@ -62,7 +64,9 @@ async function deleteQuery(args) {
|
||||
if (collectionConfig.upload) {
|
||||
const { staticDir } = collectionConfig.upload;
|
||||
|
||||
fs.unlink(`${staticDir}/${resultToDelete.filename}`, (err) => {
|
||||
const staticPath = path.resolve(this.config.paths.configDir, staticDir);
|
||||
|
||||
fs.unlink(`${staticPath}/${resultToDelete.filename}`, (err) => {
|
||||
if (err) {
|
||||
throw new ErrorDeletingFile();
|
||||
}
|
||||
@@ -70,7 +74,7 @@ async function deleteQuery(args) {
|
||||
|
||||
if (resultToDelete.sizes) {
|
||||
Object.values(resultToDelete.sizes).forEach((size) => {
|
||||
fs.unlink(`${staticDir}/${size.filename}`, (err) => {
|
||||
fs.unlink(`${staticPath}/${size.filename}`, (err) => {
|
||||
if (err) {
|
||||
throw new ErrorDeletingFile();
|
||||
}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
const httpStatus = require('http-status');
|
||||
const deepmerge = require('deepmerge');
|
||||
const path = require('path');
|
||||
|
||||
const overwriteMerge = require('../../utilities/overwriteMerge');
|
||||
const executeAccess = require('../../auth/executeAccess');
|
||||
const { NotFound, Forbidden, APIError } = require('../../errors');
|
||||
@@ -147,24 +149,26 @@ async function update(args) {
|
||||
|
||||
const { staticDir, imageSizes } = collectionConfig.upload;
|
||||
|
||||
const staticPath = path.resolve(this.config.paths.configDir, staticDir);
|
||||
|
||||
const file = (req.files && req.files.file) ? req.files.file : req.fileData;
|
||||
|
||||
if (file) {
|
||||
const fsSafeName = await getSafeFilename(staticDir, file.name);
|
||||
const fsSafeName = await getSafeFilename(staticPath, file.name);
|
||||
|
||||
await file.mv(`${staticDir}/${fsSafeName}`);
|
||||
await file.mv(`${staticPath}/${fsSafeName}`);
|
||||
|
||||
fileData.filename = fsSafeName;
|
||||
fileData.filesize = file.size;
|
||||
fileData.mimeType = file.mimetype;
|
||||
|
||||
if (imageMIMETypes.indexOf(file.mimetype) > -1) {
|
||||
const dimensions = await getImageSize(`${staticDir}/${fsSafeName}`);
|
||||
const dimensions = await getImageSize(`${staticPath}/${fsSafeName}`);
|
||||
fileData.width = dimensions.width;
|
||||
fileData.height = dimensions.height;
|
||||
|
||||
if (Array.isArray(imageSizes) && file.mimetype !== 'image/svg+xml') {
|
||||
fileData.sizes = await resizeAndSave(collectionConfig, fsSafeName, fileData.mimeType);
|
||||
fileData.sizes = await resizeAndSave(staticPath, collectionConfig, fsSafeName, fileData.mimeType);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
const express = require('express');
|
||||
const passport = require('passport');
|
||||
const path = require('path');
|
||||
const getExecuteStaticAccess = require('../auth/getExecuteStaticAccess');
|
||||
const authenticate = require('./middleware/authenticate');
|
||||
|
||||
@@ -14,7 +15,10 @@ function initStatic() {
|
||||
router.use(authenticate(this.config));
|
||||
|
||||
router.use(getExecuteStaticAccess(collection));
|
||||
router.use(express.static(config.upload.staticDir));
|
||||
|
||||
const staticPath = path.resolve(this.config.paths.configDir, config.upload.staticDir);
|
||||
|
||||
router.use(express.static(staticPath));
|
||||
|
||||
this.express.use(`${config.upload.staticURL}`, router);
|
||||
}
|
||||
|
||||
@@ -19,11 +19,11 @@ const incrementName = (name) => {
|
||||
return `${incrementedName}.${extension}`;
|
||||
};
|
||||
|
||||
async function getSafeFileName(staticDir, desiredFilename) {
|
||||
async function getSafeFileName(staticPath, desiredFilename) {
|
||||
let modifiedFilename = desiredFilename;
|
||||
|
||||
// eslint-disable-next-line no-await-in-loop
|
||||
while (await fileExists(`${staticDir}/${modifiedFilename}`)) {
|
||||
while (await fileExists(`${staticPath}/${modifiedFilename}`)) {
|
||||
modifiedFilename = incrementName(modifiedFilename);
|
||||
}
|
||||
return modifiedFilename;
|
||||
|
||||
@@ -16,7 +16,7 @@ function getOutputImage(sourceImage, size) {
|
||||
};
|
||||
}
|
||||
|
||||
module.exports = async function resizeAndSave(config, savedFilename, mimeType) {
|
||||
module.exports = async function resizeAndSave(staticPath, config, savedFilename, mimeType) {
|
||||
/**
|
||||
* Resize images according to image desired width and height and return sizes
|
||||
* @param config Object
|
||||
@@ -25,53 +25,48 @@ module.exports = async function resizeAndSave(config, savedFilename, mimeType) {
|
||||
* @returns String[]
|
||||
*/
|
||||
|
||||
const { imageSizes, staticDir } = config.upload;
|
||||
const { imageSizes } = config.upload;
|
||||
|
||||
const sourceImage = `${staticDir}/${savedFilename}`;
|
||||
let sizes;
|
||||
try {
|
||||
const dimensions = await getImageSize(sourceImage);
|
||||
sizes = imageSizes
|
||||
.filter(desiredSize => desiredSize.width < dimensions.width)
|
||||
.map(async (desiredSize) => {
|
||||
const outputImage = getOutputImage(savedFilename, desiredSize);
|
||||
const imageNameWithDimensions = `${outputImage.name}-${outputImage.width}x${outputImage.height}.${outputImage.extension}`;
|
||||
const imagePath = `${staticDir}/${imageNameWithDimensions}`;
|
||||
const fileAlreadyExists = await fileExists(imagePath);
|
||||
const sourceImage = `${staticPath}/${savedFilename}`;
|
||||
|
||||
if (fileAlreadyExists) {
|
||||
fs.unlinkSync(imagePath);
|
||||
}
|
||||
const dimensions = await getImageSize(sourceImage);
|
||||
|
||||
const output = await sharp(sourceImage)
|
||||
.resize(desiredSize.width, desiredSize.height, {
|
||||
position: desiredSize.crop || 'centre',
|
||||
})
|
||||
.toFile(imagePath);
|
||||
const sizes = imageSizes
|
||||
.filter((desiredSize) => desiredSize.width < dimensions.width)
|
||||
.map(async (desiredSize) => {
|
||||
const outputImage = getOutputImage(savedFilename, desiredSize);
|
||||
const imageNameWithDimensions = `${outputImage.name}-${outputImage.width}x${outputImage.height}.${outputImage.extension}`;
|
||||
const imagePath = `${staticPath}/${imageNameWithDimensions}`;
|
||||
const fileAlreadyExists = await fileExists(imagePath);
|
||||
|
||||
return {
|
||||
...desiredSize,
|
||||
filename: imageNameWithDimensions,
|
||||
filesize: output.size,
|
||||
mimeType,
|
||||
};
|
||||
});
|
||||
if (fileAlreadyExists) {
|
||||
fs.unlinkSync(imagePath);
|
||||
}
|
||||
|
||||
const savedSizes = await Promise.all(sizes);
|
||||
const output = await sharp(sourceImage)
|
||||
.resize(desiredSize.width, desiredSize.height, {
|
||||
position: desiredSize.crop || 'centre',
|
||||
})
|
||||
.toFile(imagePath);
|
||||
|
||||
return savedSizes.reduce((results, size) => {
|
||||
return {
|
||||
...results,
|
||||
[size.name]: {
|
||||
width: size.width,
|
||||
height: size.height,
|
||||
filename: size.filename,
|
||||
mimeType: size.mimeType,
|
||||
filesize: size.filesize,
|
||||
},
|
||||
...desiredSize,
|
||||
filename: imageNameWithDimensions,
|
||||
filesize: output.size,
|
||||
mimeType,
|
||||
};
|
||||
}, {});
|
||||
} catch (e) {
|
||||
throw e;
|
||||
}
|
||||
});
|
||||
|
||||
const savedSizes = await Promise.all(sizes);
|
||||
|
||||
return savedSizes.reduce((results, size) => ({
|
||||
...results,
|
||||
[size.name]: {
|
||||
width: size.width,
|
||||
height: size.height,
|
||||
filename: size.filename,
|
||||
mimeType: size.mimeType,
|
||||
filesize: size.filesize,
|
||||
},
|
||||
}), {});
|
||||
};
|
||||
|
||||
@@ -21,6 +21,7 @@ const getConfig = (options = {}) => {
|
||||
mongoURL: options.mongoURL,
|
||||
email: options.email,
|
||||
paths: {
|
||||
configDir: configPath.substring(0, configPath.lastIndexOf('/')),
|
||||
...(publicConfig.paths || {}),
|
||||
config: configPath,
|
||||
},
|
||||
|
||||
@@ -121,7 +121,9 @@ module.exports = (config) => {
|
||||
},
|
||||
plugins: [
|
||||
new HtmlWebpackPlugin({
|
||||
template: config.admin && config.admin.indexHTML ? config.admin.indexHTML : path.resolve(__dirname, '../client/index.html'),
|
||||
template: config.admin && config.admin.indexHTML
|
||||
? path.join(config.paths.configDir, config.admin.indexHTML)
|
||||
: path.resolve(__dirname, '../client/index.html'),
|
||||
filename: './index.html',
|
||||
}),
|
||||
new webpack.HotModuleReplacementPlugin(),
|
||||
@@ -139,7 +141,7 @@ module.exports = (config) => {
|
||||
}
|
||||
|
||||
if (config.paths.scss) {
|
||||
webpackConfig.resolve.alias['payload-scss-overrides'] = config.paths.scss;
|
||||
webpackConfig.resolve.alias['payload-scss-overrides'] = path.join(config.paths.configDir, config.paths.scss);
|
||||
} else {
|
||||
webpackConfig.resolve.alias['payload-scss-overrides'] = path.resolve(__dirname, '../client/scss/overrides.scss');
|
||||
}
|
||||
|
||||
@@ -110,7 +110,9 @@ module.exports = (config) => {
|
||||
plugins: [
|
||||
// new BundleAnalyzerPlugin(),
|
||||
new HtmlWebpackPlugin({
|
||||
template: config.admin && config.admin.indexHTML ? config.admin.indexHTML : path.resolve(__dirname, '../client/index.html'),
|
||||
template: config.admin && config.admin.indexHTML
|
||||
? path.join(config.paths.configDir, config.admin.indexHTML)
|
||||
: path.resolve(__dirname, '../client/index.html'),
|
||||
filename: './index.html',
|
||||
minify: true,
|
||||
}),
|
||||
@@ -128,7 +130,7 @@ module.exports = (config) => {
|
||||
}
|
||||
|
||||
if (config.paths.scss) {
|
||||
webpackConfig.resolve.alias['payload-scss-overrides'] = config.paths.scss;
|
||||
webpackConfig.resolve.alias['payload-scss-overrides'] = path.join(config.paths.configDir, config.paths.scss);
|
||||
} else {
|
||||
webpackConfig.resolve.alias['payload-scss-overrides'] = path.resolve(__dirname, '../client/scss/overrides.scss');
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user