Merge pull request #12534 from strapi/content-68/fix-public-path

Move public path config to server.js
This commit is contained in:
Pierre Noël 2022-03-25 16:35:42 +01:00 committed by GitHub
commit cf33ce0b63
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 368 additions and 343 deletions

View File

@ -50,8 +50,8 @@ const LIFECYCLES = {
class Strapi { class Strapi {
constructor(opts = {}) { constructor(opts = {}) {
destroyOnSignal(this); destroyOnSignal(this);
this.dirs = utils.getDirs(opts.dir || process.cwd()); const rootDir = opts.dir || process.cwd();
const appConfig = loadConfiguration(this.dirs.root, opts); const appConfig = loadConfiguration(rootDir, opts);
this.container = createContainer(this); this.container = createContainer(this);
this.container.register('config', createConfigProvider(appConfig)); this.container.register('config', createConfigProvider(appConfig));
this.container.register('content-types', contentTypesRegistry(this)); this.container.register('content-types', contentTypesRegistry(this));
@ -65,6 +65,8 @@ class Strapi {
this.container.register('apis', apisRegistry(this)); this.container.register('apis', apisRegistry(this));
this.container.register('auth', createAuth(this)); this.container.register('auth', createAuth(this));
this.dirs = utils.getDirs(rootDir, { strapi: this });
this.isLoaded = false; this.isLoaded = false;
this.reload = this.reload(); this.reload = this.reload();
this.server = createServer(this); this.server = createServer(this);

View File

@ -8,6 +8,7 @@ const execa = require('execa');
const { getOr } = require('lodash/fp'); const { getOr } = require('lodash/fp');
const { createLogger } = require('@strapi/logger'); const { createLogger } = require('@strapi/logger');
const { joinBy } = require('@strapi/utils');
const loadConfiguration = require('../core/app-configuration'); const loadConfiguration = require('../core/app-configuration');
const strapi = require('../index'); const strapi = require('../index');
const buildAdmin = require('./build'); const buildAdmin = require('./build');
@ -131,6 +132,8 @@ function watchFileChanges({ dir, strapiInstance, watchIgnoreFiles, polling }) {
'**/index.html', '**/index.html',
'**/public', '**/public',
'**/public/**', '**/public/**',
strapiInstance.dirs.public,
joinBy('/', strapiInstance.dirs.public, '**'),
'**/*.db*', '**/*.db*',
'**/exports/**', '**/exports/**',
...watchIgnoreFiles, ...watchIgnoreFiles,

View File

@ -21,6 +21,7 @@ const defaultConfig = {
proxy: false, proxy: false,
cron: { enabled: false }, cron: { enabled: false },
admin: { autoOpen: false }, admin: { autoOpen: false },
dirs: { public: './public' },
}, },
admin: {}, admin: {},
api: { api: {

View File

@ -1,8 +1,9 @@
'use strict'; 'use strict';
const { getConfigUrls } = require('@strapi/utils'); const { getConfigUrls } = require('@strapi/utils');
const fse = require('fs-extra');
module.exports = function({ strapi }) { module.exports = async function({ strapi }) {
strapi.config.port = strapi.config.get('server.port') || strapi.config.port; strapi.config.port = strapi.config.get('server.port') || strapi.config.port;
strapi.config.host = strapi.config.get('server.host') || strapi.config.host; strapi.config.host = strapi.config.get('server.host') || strapi.config.host;
@ -22,4 +23,11 @@ module.exports = function({ strapi }) {
if (!shouldServeAdmin) { if (!shouldServeAdmin) {
strapi.config.serveAdminPanel = false; strapi.config.serveAdminPanel = false;
} }
// ensure public repository exists
if (!(await fse.pathExists(strapi.dirs.public))) {
throw new Error(
`The public folder (${strapi.dirs.public}) doesn't exist or is not accessible. Please make sure it exists.`
);
}
}; };

View File

@ -1,8 +1,8 @@
'use strict'; 'use strict';
const { join } = require('path'); const { join, resolve } = require('path');
const getDirs = root => ({ const getDirs = (root, { strapi }) => ({
root, root,
src: join(root, 'src'), src: join(root, 'src'),
api: join(root, 'src', 'api'), api: join(root, 'src', 'api'),
@ -11,7 +11,7 @@ const getDirs = root => ({
policies: join(root, 'src', 'policies'), policies: join(root, 'src', 'policies'),
middlewares: join(root, 'src', 'middlewares'), middlewares: join(root, 'src', 'middlewares'),
config: join(root, 'config'), config: join(root, 'config'),
public: join(root, 'public'), public: resolve(root, strapi.config.get('server.dirs.public')),
}); });
module.exports = getDirs; module.exports = getDirs;

View File

@ -1,14 +1,18 @@
'use strict'; 'use strict';
const { join } = require('path');
const bootstrap = require('../bootstrap'); const bootstrap = require('../bootstrap');
jest.mock('@strapi/provider-upload-local', () => ({ init() {} }));
describe('Upload plugin bootstrap function', () => { describe('Upload plugin bootstrap function', () => {
test('Sets default config if id does not exist', async () => { test('Sets default config if it does not exist', async () => {
const setStore = jest.fn(() => {}); const setStore = jest.fn(() => {});
const registerMany = jest.fn(() => {}); const registerMany = jest.fn(() => {});
global.strapi = { global.strapi = {
dirs: { root: process.cwd() }, dirs: { root: process.cwd(), public: join(process.cwd(), 'public') },
admin: { admin: {
services: { permission: { actionProvider: { registerMany } } }, services: { permission: { actionProvider: { registerMany } } },
}, },
@ -16,10 +20,7 @@ describe('Upload plugin bootstrap function', () => {
error() {}, error() {},
}, },
config: { config: {
get: jest get: jest.fn().mockReturnValueOnce({ provider: 'local' }),
.fn()
.mockReturnValueOnce({ provider: 'local' })
.mockReturnValueOnce('public'),
paths: {}, paths: {},
info: { info: {
dependencies: {}, dependencies: {},

View File

@ -7,6 +7,7 @@ const {
getCommonBeginning, getCommonBeginning,
getCommonPath, getCommonPath,
toRegressedEnumValue, toRegressedEnumValue,
joinBy,
} = require('../string-formatting'); } = require('../string-formatting');
describe('string-formatting', () => { describe('string-formatting', () => {
@ -121,4 +122,25 @@ describe('string-formatting', () => {
expect(toRegressedEnumValue(string)).toBe(expectedResult); expect(toRegressedEnumValue(string)).toBe(expectedResult);
}); });
}); });
describe('joinBy', () => {
test.each([
[['/', ''], ''],
[['/', '/a/'], '/a/'],
[['/', 'a', 'b'], 'a/b'],
[['/', 'a', '/b'], 'a/b'],
[['/', 'a/', '/b'], 'a/b'],
[['/', 'a/', 'b'], 'a/b'],
[['/', 'a//', 'b'], 'a/b'],
[['/', 'a//', '//b'], 'a/b'],
[['/', 'a', '//b'], 'a/b'],
[['/', '/a//', '//b/'], '/a/b/'],
[['/', 'a', 'b', 'c'], 'a/b/c'],
[['/', 'a/', '/b/', '/c'], 'a/b/c'],
[['/', 'a//', '//b//', '//c'], 'a/b/c'],
[['/', '///a///', '///b///', '///c///'], '///a/b/c///'],
])('%s => %s', (args, expectedResult) => {
expect(joinBy(...args)).toBe(expectedResult);
});
});
}); });

View File

@ -21,6 +21,7 @@ const {
isCamelCase, isCamelCase,
toRegressedEnumValue, toRegressedEnumValue,
startsWithANumber, startsWithANumber,
joinBy,
} = require('./string-formatting'); } = require('./string-formatting');
const { removeUndefined } = require('./object-formatting'); const { removeUndefined } = require('./object-formatting');
const { getConfigUrls, getAbsoluteAdminUrl, getAbsoluteServerUrl } = require('./config'); const { getConfigUrls, getAbsoluteAdminUrl, getAbsoluteServerUrl } = require('./config');
@ -51,6 +52,7 @@ module.exports = {
nameToSlug, nameToSlug,
toRegressedEnumValue, toRegressedEnumValue,
startsWithANumber, startsWithANumber,
joinBy,
nameToCollectionName, nameToCollectionName,
getCommonBeginning, getCommonBeginning,
getConfigUrls, getConfigUrls,

View File

@ -1,5 +1,6 @@
'use strict'; 'use strict';
const _ = require('lodash'); const _ = require('lodash');
const { trimChars, trimCharsEnd, trimCharsStart } = require('lodash/fp');
const slugify = require('@sindresorhus/slugify'); const slugify = require('@sindresorhus/slugify');
const nameToSlug = (name, options = { separator: '-' }) => slugify(name, options); const nameToSlug = (name, options = { separator: '-' }) => slugify(name, options);
@ -44,6 +45,19 @@ const isCamelCase = value => /^[a-z][a-zA-Z0-9]+$/.test(value);
const isKebabCase = value => /^([a-z][a-z0-9]*)(-[a-z0-9]+)*$/.test(value); const isKebabCase = value => /^([a-z][a-z0-9]*)(-[a-z0-9]+)*$/.test(value);
const startsWithANumber = value => /^[0-9]/.test(value); const startsWithANumber = value => /^[0-9]/.test(value);
const joinBy = (joint, ...args) => {
const trim = trimChars(joint);
const trimEnd = trimCharsEnd(joint);
const trimStart = trimCharsStart(joint);
return args.reduce((url, path, index) => {
if (args.length === 1) return path;
if (index === 0) return trimEnd(path);
if (index === args.length - 1) return url + joint + trimStart(path);
return url + joint + trim(path);
}, '');
};
module.exports = { module.exports = {
nameToSlug, nameToSlug,
nameToCollectionName, nameToCollectionName,
@ -56,4 +70,5 @@ module.exports = {
isKebabCase, isKebabCase,
toRegressedEnumValue, toRegressedEnumValue,
startsWithANumber, startsWithANumber,
joinBy,
}; };

View File

@ -8,8 +8,11 @@
const { pipeline } = require('stream'); const { pipeline } = require('stream');
const fs = require('fs'); const fs = require('fs');
const path = require('path'); const path = require('path');
const fse = require('fs-extra');
const { PayloadTooLargeError } = require('@strapi/utils').errors; const { PayloadTooLargeError } = require('@strapi/utils').errors;
const UPLOADS_FOLDER_NAME = 'uploads';
module.exports = { module.exports = {
init({ sizeLimit = 1000000 } = {}) { init({ sizeLimit = 1000000 } = {}) {
const verifySize = file => { const verifySize = file => {
@ -18,7 +21,13 @@ module.exports = {
} }
}; };
const publicDir = strapi.dirs.public; // Ensure uploads folder exists
const uploadPath = path.resolve(strapi.dirs.public, UPLOADS_FOLDER_NAME);
if (!fse.pathExistsSync(uploadPath)) {
throw new Error(
`The upload folder (${uploadPath}) doesn't exist or is not accessible. Please make sure it exists.`
);
}
return { return {
uploadStream(file) { uploadStream(file) {
@ -27,7 +36,7 @@ module.exports = {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
pipeline( pipeline(
file.stream, file.stream,
fs.createWriteStream(path.join(publicDir, `/uploads/${file.hash}${file.ext}`)), fs.createWriteStream(path.join(uploadPath, `${file.hash}${file.ext}`)),
err => { err => {
if (err) { if (err) {
return reject(err); return reject(err);
@ -44,24 +53,21 @@ module.exports = {
verifySize(file); verifySize(file);
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
fs.writeFile( // write file in public/assets folder
path.join(publicDir, `/uploads/${file.hash}${file.ext}`), fs.writeFile(path.join(uploadPath, `${file.hash}${file.ext}`), file.buffer, err => {
file.buffer,
err => {
if (err) { if (err) {
return reject(err); return reject(err);
} }
file.url = `/uploads/${file.hash}${file.ext}`; file.url = `/${UPLOADS_FOLDER_NAME}/${file.hash}${file.ext}`;
resolve(); resolve();
} });
);
}); });
}, },
delete(file) { delete(file) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
const filePath = path.join(publicDir, `/uploads/${file.hash}${file.ext}`); const filePath = path.join(uploadPath, `${file.hash}${file.ext}`);
if (!fs.existsSync(filePath)) { if (!fs.existsSync(filePath)) {
return resolve("File doesn't exist"); return resolve("File doesn't exist");

View File

@ -35,7 +35,8 @@
"test": "echo \"no tests yet\"" "test": "echo \"no tests yet\""
}, },
"dependencies": { "dependencies": {
"@strapi/utils": "4.1.5" "@strapi/utils": "4.1.5",
"fs-extra": "10.0.0"
}, },
"engines": { "engines": {
"node": ">=12.22.0 <=16.x.x", "node": ">=12.22.0 <=16.x.x",

594
yarn.lock

File diff suppressed because it is too large Load Diff