Exports schema.graphql in devmode, load extensions folder and run merge config and overwrites

This commit is contained in:
Alexandre Bodin 2019-04-10 18:11:55 +02:00
parent 2fa8afbb1a
commit eb7c4534f8
17 changed files with 613 additions and 177 deletions

View File

@ -0,0 +1,336 @@
type Articles {
id: ID!
created_at: DateTime!
updated_at: DateTime!
title: String
}
input ArticlesInput {
title: String
}
input createArticlesInput {
data: ArticlesInput
}
type createArticlesPayload {
article: Articles
}
input createRoleInput {
data: RoleInput
}
type createRolePayload {
role: UsersPermissionsRole
}
input createTagsInput {
data: TagsInput
}
type createTagsPayload {
tag: Tags
}
input createUserInput {
data: UserInput
}
type createUserPayload {
user: UsersPermissionsUser
}
"""
The `DateTime` scalar represents a date and time following the ISO 8601 standard
"""
scalar DateTime
input deleteArticlesInput {
where: InputID
}
type deleteArticlesPayload {
article: Articles
}
input deleteRoleInput {
where: InputID
}
type deleteRolePayload {
role: UsersPermissionsRole
}
input deleteTagsInput {
where: InputID
}
type deleteTagsPayload {
tag: Tags
}
input deleteUserInput {
where: InputID
}
type deleteUserPayload {
user: UsersPermissionsUser
}
input editArticlesInput {
title: String
}
input editFileInput {
name: String
hash: String
sha256: String
ext: String
mime: String
size: String
url: String
provider: String
public_id: String
related: [ID]
}
input editRoleInput {
name: String
description: String
type: String
permissions: [ID]
users: [ID]
}
input editTagsInput {
name: String
}
input editTestInput {
type: String
}
input editUserInput {
type: String
username: String
email: String
provider: String
password: String
resetPasswordToken: String
confirmed: Boolean
blocked: Boolean
role: ID
}
input FileInput {
name: String!
hash: String!
sha256: String
ext: String
mime: String!
size: String!
url: String!
provider: String!
public_id: String
related: [ID]
}
input InputID {
id: ID!
}
"""
The `JSON` scalar type represents JSON values as specified by [ECMA-404](http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-404.pdf).
"""
scalar JSON
union Morph = UsersPermissionsMe | UsersPermissionsMeRole | Articles | createArticlesPayload | updateArticlesPayload | deleteArticlesPayload | Tags | createTagsPayload | updateTagsPayload | deleteTagsPayload | UploadFile | UsersPermissionsPermission | UsersPermissionsRole | createRolePayload | updateRolePayload | deleteRolePayload | UsersPermissionsUser | createUserPayload | updateUserPayload | deleteUserPayload | MypluginTest
type Mutation {
createArticles(input: createArticlesInput): createArticlesPayload
updateArticles(input: updateArticlesInput): updateArticlesPayload
deleteArticles(input: deleteArticlesInput): deleteArticlesPayload
createTags(input: createTagsInput): createTagsPayload
updateTags(input: updateTagsInput): updateTagsPayload
deleteTags(input: deleteTagsInput): deleteTagsPayload
"""Create a new role"""
createRole(input: createRoleInput): createRolePayload
"""Update an existing role"""
updateRole(input: updateRoleInput): updateRolePayload
"""Delete an existing role"""
deleteRole(input: deleteRoleInput): deleteRolePayload
"""Create a new user"""
createUser(input: createUserInput): createUserPayload
"""Update an existing user"""
updateUser(input: updateUserInput): updateUserPayload
"""Delete an existing user"""
deleteUser(input: deleteUserInput): deleteUserPayload
upload(refId: ID, ref: String, source: String, file: Upload!): UploadFile!
}
type MypluginTest {
id: ID!
type: String!
}
type Query {
article(id: ID!): Articles
articles(sort: String, limit: Int, start: Int, where: JSON): [Articles]
tag(id: ID!): Tags
tags(sort: String, limit: Int, start: Int, where: JSON): [Tags]
files(sort: String, limit: Int, start: Int, where: JSON): [UploadFile]
role(id: ID!): UsersPermissionsRole
"""
Retrieve all the existing roles. You can't apply filters on this query.
"""
roles(sort: String, limit: Int, start: Int, where: JSON): [UsersPermissionsRole]
user(id: ID!): UsersPermissionsUser
users(sort: String, limit: Int, start: Int, where: JSON): [UsersPermissionsUser]
test(id: ID!): MypluginTest
tests(sort: String, limit: Int, start: Int, where: JSON): [MypluginTest]
me: UsersPermissionsMe
}
input RoleInput {
name: String!
description: String
type: String
permissions: [ID]
users: [ID]
}
type Tags {
id: ID!
created_at: DateTime!
updated_at: DateTime!
name: String
}
input TagsInput {
name: String
}
input TestInput {
type: String!
}
input updateArticlesInput {
where: InputID
data: editArticlesInput
}
type updateArticlesPayload {
article: Articles
}
input updateRoleInput {
where: InputID
data: editRoleInput
}
type updateRolePayload {
role: UsersPermissionsRole
}
input updateTagsInput {
where: InputID
data: editTagsInput
}
type updateTagsPayload {
tag: Tags
}
input updateUserInput {
where: InputID
data: editUserInput
}
type updateUserPayload {
user: UsersPermissionsUser
}
"""The `Upload` scalar type represents a file upload."""
scalar Upload
type UploadFile {
id: ID!
created_at: DateTime!
updated_at: DateTime!
name: String!
hash: String!
sha256: String
ext: String
mime: String!
size: String!
url: String!
provider: String!
public_id: String
related(sort: String, limit: Int, start: Int, where: JSON): [Morph]
}
input UserInput {
type: String
username: String!
email: String!
provider: String
password: String
resetPasswordToken: String
confirmed: Boolean
blocked: Boolean
role: ID
}
type UsersPermissionsMe {
_id: ID!
username: String!
email: String!
confirmed: Boolean
blocked: Boolean
role: UsersPermissionsMeRole
}
type UsersPermissionsMeRole {
_id: ID!
name: String!
description: String
type: String
}
type UsersPermissionsPermission {
id: ID!
type: String!
controller: String!
action: String!
enabled: Boolean!
policy: String
role: UsersPermissionsRole
}
type UsersPermissionsRole {
id: ID!
name: String!
description: String
type: String
permissions(sort: String, limit: Int, start: Int, where: JSON): [UsersPermissionsPermission]
users(sort: String, limit: Int, start: Int, where: JSON): [UsersPermissionsUser]
}
type UsersPermissionsUser {
id: ID!
type: String
username: String!
email: String!
provider: String
confirmed: Boolean
blocked: Boolean
role: UsersPermissionsRole
}

View File

@ -0,0 +1 @@
{"actions":["application.articles.find","application.articles.findone","application.articles.count","application.articles.create","application.articles.update","application.articles.destroy","application.tags.find","application.tags.findone","application.tags.count","application.tags.create","application.tags.update","application.tags.destroy","content-manager.contentmanager.models","content-manager.contentmanager.find","content-manager.contentmanager.count","content-manager.contentmanager.findone","content-manager.contentmanager.create","content-manager.contentmanager.update","content-manager.contentmanager.updatesettings","content-manager.contentmanager.delete","content-manager.contentmanager.deleteall","content-type-builder.contenttypebuilder.getmodels","content-type-builder.contenttypebuilder.getmodel","content-type-builder.contenttypebuilder.getconnections","content-type-builder.contenttypebuilder.createmodel","content-type-builder.contenttypebuilder.updatemodel","content-type-builder.contenttypebuilder.deletemodel","content-type-builder.contenttypebuilder.autoreload","content-type-builder.contenttypebuilder.checktableexists","email.email.send","email.email.getenvironments","email.email.getsettings","email.email.updatesettings","settings-manager.settingsmanager.menu","settings-manager.settingsmanager.environments","settings-manager.settingsmanager.languages","settings-manager.settingsmanager.databases","settings-manager.settingsmanager.database","settings-manager.settingsmanager.databasemodel","settings-manager.settingsmanager.get","settings-manager.settingsmanager.update","settings-manager.settingsmanager.createlanguage","settings-manager.settingsmanager.deletelanguage","settings-manager.settingsmanager.createdatabase","settings-manager.settingsmanager.updatedatabase","settings-manager.settingsmanager.deletedatabase","settings-manager.settingsmanager.autoreload","upload.upload.upload","upload.upload.getenvironments","upload.upload.getsettings","upload.upload.updatesettings","upload.upload.find","upload.upload.findone","upload.upload.count","upload.upload.destroy","upload.upload.search","users-permissions.auth.callback","users-permissions.auth.changepassword","users-permissions.auth.connect","users-permissions.auth.forgotpassword","users-permissions.auth.register","users-permissions.auth.emailconfirmation","users-permissions.user.find","users-permissions.user.me","users-permissions.user.findone","users-permissions.user.create","users-permissions.user.update","users-permissions.user.destroy","users-permissions.user.destroyall","users-permissions.userspermissions.createrole","users-permissions.userspermissions.deleteprovider","users-permissions.userspermissions.deleterole","users-permissions.userspermissions.getpermissions","users-permissions.userspermissions.getpolicies","users-permissions.userspermissions.getrole","users-permissions.userspermissions.getroles","users-permissions.userspermissions.getroutes","users-permissions.userspermissions.index","users-permissions.userspermissions.init","users-permissions.userspermissions.searchusers","users-permissions.userspermissions.updaterole","users-permissions.userspermissions.getemailtemplate","users-permissions.userspermissions.updateemailtemplate","users-permissions.userspermissions.getadvancedsettings","users-permissions.userspermissions.updateadvancedsettings","users-permissions.userspermissions.getproviders","users-permissions.userspermissions.updateproviders","myplugin.test.findone","myplugin.test.find"]}

View File

@ -0,0 +1,3 @@
{
"jwtSecret": "1481145e-8625-4032-a4f0-75de2a3f10c9"
}

View File

@ -0,0 +1,57 @@
{
"connection": "default",
"info": {
"name": "user",
"description": ""
},
"attributes": {
"type": {
"type": "string"
},
"username": {
"type": "string",
"minLength": 3,
"unique": true,
"configurable": false,
"required": true
},
"email": {
"type": "email",
"minLength": 6,
"configurable": false,
"required": true
},
"provider": {
"type": "string",
"configurable": false
},
"password": {
"type": "password",
"minLength": 6,
"configurable": false,
"private": true
},
"resetPasswordToken": {
"type": "string",
"configurable": false,
"private": true
},
"confirmed": {
"type": "boolean",
"default": false,
"configurable": false
},
"blocked": {
"type": "boolean",
"default": false,
"configurable": false
},
"role": {
"model": "role",
"via": "users",
"plugin": "users-permissions",
"configurable": false
}
},
"collectionName": "users-permissions_user"
}

View File

@ -260,15 +260,15 @@ const schemaBuilder = {
`;
// // Build schema.
// const schema = makeExecutableSchema({
// typeDefs,
// resolvers,
// });
if (!strapi.config.currentEnvironment.server.production) {
// Write schema.
const schema = makeExecutableSchema({
typeDefs,
resolvers,
});
// if (!strapi.config.currentEnvironment.server.production) {
// // Write schema.
// this.writeGenerateSchema(graphql.printSchema(schema));
// }
this.writeGenerateSchema(graphql.printSchema(schema));
}
// Remove custom scaler (like Upload);
typeDefs = Types.removeCustomScalar(typeDefs, resolvers);
@ -286,27 +286,8 @@ const schemaBuilder = {
*/
writeGenerateSchema: schema => {
const generatedFolder = path.resolve(
strapi.config.appPath,
'extensions',
'graphql',
'config',
'generated'
);
// Create folder if necessary.
try {
fs.accessSync(generatedFolder, fs.constants.R_OK | fs.constants.W_OK);
} catch (err) {
if (err && err.code === 'ENOENT') {
fs.mkdirSync(generatedFolder);
} else {
strapi.log.error(err);
}
}
fs.writeFileSync(path.join(generatedFolder, 'schema.graphql'), schema);
},
return strapi.fs.writeFile('exports/graphql/schema.graphql', schema);
}
};
module.exports = schemaBuilder;

View File

@ -2,6 +2,8 @@
coverage
build
node_modules
# writable files
jwt.json
config/layout.json
actions.json

View File

@ -7,37 +7,27 @@
* This gives you an opportunity to set up your data model,
* run jobs, or perform some special logic.
*/
const path = require('path');
const fs = require('fs');
const _ = require('lodash');
const uuid = require('uuid/v4');
module.exports = async cb => {
if (!_.get(strapi.plugins['users-permissions'], 'config.jwtSecret')) {
try {
const jwtSecret = uuid();
const jwtSecret = uuid();
_.set(strapi.plugins['users-permissions'], 'config.jwtSecret', jwtSecret);
fs.writeFileSync(path.join(strapi.config.appPath, 'plugins', 'users-permissions', 'config', 'jwt.json'), JSON.stringify({
jwtSecret
}, null, 2), 'utf8');
_.set(strapi.plugins['users-permissions'], 'config.jwtSecret', jwtSecret);
} catch(err) {
strapi.log.error(err);
}
await strapi.fs.writePluginFile('users-permissions', 'config/jwt.json', JSON.stringify({ jwtSecret }, null, 2));
}
const pluginStore = strapi.store({
environment: '',
type: 'plugin',
name: 'users-permissions'
name: 'users-permissions',
});
const grantConfig = {
email: {
enabled: true,
icon: 'envelope'
icon: 'envelope',
},
discord: {
enabled: false,
@ -45,10 +35,7 @@ module.exports = async cb => {
key: '',
secret: '',
callback: '/auth/discord/callback',
scope: [
'identify',
'email'
]
scope: ['identify', 'email'],
},
facebook: {
enabled: false,
@ -56,7 +43,7 @@ module.exports = async cb => {
key: '',
secret: '',
callback: '/auth/facebook/callback',
scope: ['email']
scope: ['email'],
},
google: {
enabled: false,
@ -64,7 +51,7 @@ module.exports = async cb => {
key: '',
secret: '',
callback: '/auth/google/callback',
scope: ['email']
scope: ['email'],
},
github: {
enabled: false,
@ -72,10 +59,7 @@ module.exports = async cb => {
key: '',
secret: '',
redirect_uri: '/auth/github/callback',
scope: [
'user',
'user:email'
]
scope: ['user', 'user:email'],
},
microsoft: {
enabled: false,
@ -83,39 +67,42 @@ module.exports = async cb => {
key: '',
secret: '',
callback: '/auth/microsoft/callback',
scope: ['user.read']
scope: ['user.read'],
},
twitter: {
enabled: false,
icon: 'twitter',
key: '',
secret: '',
callback: '/auth/twitter/callback'
}
callback: '/auth/twitter/callback',
},
};
const prevGrantConfig = await pluginStore.get({key: 'grant'}) || {};
const prevGrantConfig = (await pluginStore.get({ key: 'grant' })) || {};
// store grant auth config to db
// when plugin_users-permissions_grant is not existed in db
// or we have added/deleted provider here.
if (!prevGrantConfig || !_.isEqual(_.keys(prevGrantConfig), _.keys(grantConfig))) {
if (
!prevGrantConfig ||
!_.isEqual(_.keys(prevGrantConfig), _.keys(grantConfig))
) {
// merge with the previous provider config.
_.keys(grantConfig).forEach((key) => {
_.keys(grantConfig).forEach(key => {
if (key in prevGrantConfig) {
grantConfig[key] = _.merge(grantConfig[key], prevGrantConfig[key]);
}
});
await pluginStore.set({key: 'grant', value: grantConfig});
await pluginStore.set({ key: 'grant', value: grantConfig });
}
if (!await pluginStore.get({key: 'email'})) {
if (!(await pluginStore.get({ key: 'email' }))) {
const value = {
'reset_password': {
reset_password: {
display: 'Email.template.reset_password',
icon: 'refresh',
options: {
from: {
name: 'Administration Panel',
email: 'no-reply@strapi.io'
email: 'no-reply@strapi.io',
},
response_email: '',
object: '­Reset password',
@ -125,16 +112,16 @@ module.exports = async cb => {
<p><%= URL %>?code=<%= TOKEN %></p>
<p>Thanks.</p>`
}
<p>Thanks.</p>`,
},
},
'email_confirmation': {
email_confirmation: {
display: 'Email.template.email_confirmation',
icon: 'check-square-o',
options: {
from: {
name: 'Administration Panel',
email: 'no-reply@strapi.io'
email: 'no-reply@strapi.io',
},
response_email: '',
object: 'Account confirmation',
@ -144,24 +131,26 @@ module.exports = async cb => {
<p><%= URL %>?confirmation=<%= CODE %></p>
<p>Thanks.</p>`
}
}
<p>Thanks.</p>`,
},
},
};
await pluginStore.set({key: 'email', value});
await pluginStore.set({ key: 'email', value });
}
if (!await pluginStore.get({key: 'advanced'})) {
if (!(await pluginStore.get({ key: 'advanced' }))) {
const value = {
unique_email: true,
allow_register: true,
email_confirmation: false,
email_confirmation_redirection: `http://${strapi.config.currentEnvironment.server.host}:${strapi.config.currentEnvironment.server.port}/admin`,
default_role: 'authenticated'
email_confirmation_redirection: `http://${
strapi.config.currentEnvironment.server.host
}:${strapi.config.currentEnvironment.server.port}/admin`,
default_role: 'authenticated',
};
await pluginStore.set({key: 'advanced', value});
await pluginStore.set({ key: 'advanced', value });
}
strapi.plugins['users-permissions'].services.userspermissions.initialize(cb);

View File

@ -1,7 +1,5 @@
'use strict';
const fs = require('fs-extra');
const path = require('path');
const _ = require('lodash');
const request = require('request');
@ -279,7 +277,7 @@ module.exports = {
return _.merge({ application: routes }, pluginsRoutes);
},
updatePermissions: async function(cb) {
async updatePermissions() {
// fetch all the current permissions from the database, and format them into an array of actions.
const databasePermissions = await strapi
.query('permission', 'users-permissions')
@ -438,11 +436,7 @@ module.exports = {
),
]),
);
return this.writeActions(currentActions, cb);
}
cb();
},
removeDuplicate: async function() {
@ -490,15 +484,18 @@ module.exports = {
});
},
initialize: async function(cb) {
const roles = await strapi.query('role', 'users-permissions').count();
async initialize(cb) {
const roleCount = await strapi.query('role', 'users-permissions').count();
// It has already been initialized.
if (roles > 0) {
return await this.updatePermissions(async () => {
if (roleCount > 0) {
try {
await this.updatePermissions();
await this.removeDuplicate();
cb();
});
return cb();
} catch (err) {
return cb(err);
}
}
// Create two first default roles.
@ -515,7 +512,8 @@ module.exports = {
}),
]);
await this.updatePermissions(cb);
this.updatePermissions().then(() => cb(), err => cb(err));
},
updateRole: async function(roleID, body) {
@ -610,28 +608,6 @@ module.exports = {
);
},
writeActions: (data, cb) => {
const actionsPath = path.join(strapi.config.appPath, 'extensions', 'users-permissions', 'config', 'actions.json');
try {
// Disable auto-reload.
strapi.reload.isWatching = false;
if (!strapi.config.currentEnvironment.server.production) {
// Rewrite actions.json file.
fs.ensureFileSync(actionsPath);
fs.writeFileSync(actionsPath, JSON.stringify({ actions: data }), 'utf8');
}
// Set value to AST to avoid restart.
_.set(strapi.plugins['users-permissions'], 'config.actions', data);
// Disable auto-reload.
strapi.reload.isWatching = true;
cb();
} catch (err) {
strapi.log.error(err);
}
},
template: (layout, data) => {
const compiledObject = _.template(layout);
return compiledObject(data);

View File

@ -52,7 +52,7 @@ const watchFileChanges = ({ appPath, strapi }) => {
'**/cypress',
'**/cypress/**',
'**/*.db*',
'**/generated/schema.graphql'
'**/exports/**'
],
});

View File

@ -18,10 +18,18 @@ const {
bootstrap,
plugins,
admin,
loadExtensions,
initCoreStore,
} = require('./core');
const initializeMiddlewares = require('./middlewares');
const initializeHooks = require('./hooks');
const createStrapiFs = require('./core/fs');
const getPrefixedDependencies = (prefix, pkgJSON) => {
return Object.keys(pkgJSON.dependencies)
.filter(d => d.startsWith(prefix))
.map(pkgName => pkgName.substring(prefix.length + 1));
};
/**
* Construct an Strapi instance.
@ -88,6 +96,8 @@ class Strapi extends EventEmitter {
functions: {},
routes: {},
};
this.fs = createStrapiFs(this);
}
async start(config = {}, cb) {
@ -211,6 +221,7 @@ class Strapi extends EventEmitter {
process.exit(1);
}
// TODO: Split code
async load() {
await this.enhancer();
@ -223,24 +234,13 @@ class Strapi extends EventEmitter {
}
});
this.config.info = require(path.resolve(
this.config.appPath,
'package.json'
));
this.config.installedPlugins = Object.keys(this.config.info.dependencies)
.filter(d => d.startsWith('strapi-plugin'))
.map(pkgName => pkgName.substring('strapi-plugin'.length + 1));
this.config.installedMiddlewares = Object.keys(
this.config.info.dependencies
)
.filter(d => d.startsWith('strapi-middleware'))
.map(pkgName => pkgName.substring('strapi-middleware'.length + 1));
this.config.installedHooks = Object.keys(this.config.info.dependencies)
.filter(d => d.startsWith('strapi-hook'))
.map(pkgName => pkgName.substring('strapi-hook'.length + 1));
const pkgJSON = require(path.resolve(this.config.appPath, 'package.json'));
Object.assign(this.config, {
info: pkgJSON,
installedPlugins: getPrefixedDependencies('strapi-plugin', pkgJSON),
installedMiddlewares: getPrefixedDependencies('strapi-middleware', pkgJSON),
installedHooks: getPrefixedDependencies('strapi-hook', pkgJSON),
});
// load configs
_.merge(this, await loadConfigs(this.config));
@ -255,6 +255,17 @@ class Strapi extends EventEmitter {
// load hooks
this.hook = await loadHooks(this.config);
/**
* Handle plugin extensions
*/
const extensions = await loadExtensions(this.config);
// merge extensions config folders
_.merge(strapi.plugins, extensions.configs);
// overwrite plugins with extensions overwrites
extensions.overwrites.forEach(({ path, mod }) =>
_.set(strapi.plugins, path, mod)
);
// Populate AST with configurations.
await bootstrap.call(this);
// Usage.

View File

@ -0,0 +1,38 @@
const path = require('path');
const fs = require('fs-extra');
/**
* create strapi fs layer
*/
module.exports = strapi => {
/**
* Writes a file in a strapi app
* @param {Array|string} optPath - file path
* @param {string} data - content
*/
const writeFile = (optPath, data) => {
const filePath = Array.isArray(optPath) ? optPath.join('/') : optPath;
const normalizedPath = path.normalize(filePath).replace(/^(\/?\.\.?)+/, '');
const writePath = path.join(strapi.config.appPath, normalizedPath);
return fs.ensureFile(writePath).then(() => fs.writeFile(writePath, data));
};
/**
* Writes a file in a plugin extensions folder
* @param {string} plugin - plugin name
* @param {Array|string} optPath - path to file
* @param {string} data - content
*/
const writePluginFile = (plugin, optPath, data) => {
const newPath = ['extensions', plugin].concat(optPath).join('/');
return writeFile(newPath, data);
};
return {
writeFile,
writePluginFile,
};
};

View File

@ -3,6 +3,7 @@
const loadConfigs = require('./load-configs');
const loadApis = require('./load-apis');
const loadMiddlewares = require('./load-middlewares');
const loadExtensions = require('./load-extensions');
const loadHooks = require('./load-hooks');
const bootstrap = require('./bootstrap');
const plugins = require('./plugins');
@ -14,6 +15,7 @@ module.exports = {
loadMiddlewares,
loadHooks,
loadApis,
loadExtensions,
bootstrap,
plugins,
admin,

View File

@ -5,8 +5,7 @@ const _ = require('lodash');
const fs = require('fs-extra');
const findPackagePath = require('../load/package-path');
const loadFiles = require('../load/load-files');
const requireFileAndParse = require('../load/require-file-parse');
const loadConfig = require('../load/load-config-files');
module.exports = async ({ appPath, installedPlugins }) => {
const [config, admin, api, plugins, localPlugins] = await Promise.all([
@ -25,38 +24,6 @@ module.exports = async ({ appPath, installedPlugins }) => {
};
};
const loadConfig = dir => {
return loadFiles(dir, 'config/**/*.+(js|json)', {
requireFn: requireFileAndParse,
shouldUseFileNameAsKey,
});
};
const prefixedPaths = [
...['staging', 'production', 'development'].reduce((acc, env) => {
return acc.concat(
`environments/${env}/database`,
`environments/${env}/security`,
`environments/${env}/request`,
`environments/${env}/response`,
`environments/${env}/server`
);
}, []),
'functions',
'policies',
'locales',
'hook',
'middleware',
'language',
'queries',
'layout',
];
const shouldUseFileNameAsKey = file => {
return _.some(prefixedPaths, e => file.startsWith(`config/${e}`))
? true
: false;
};
// Loads an app config folder
const loadAppConfig = async appPath => {

View File

@ -0,0 +1,37 @@
'use strict';
const path = require('path');
const loadConfig = require('../load/load-config-files');
const glob = require('../load/glob');
const filePathToPath = require('../load/filepath-to-prop-path');
const overwritableFoldersGlob = 'models';
module.exports = async function({ appPath }) {
const extensionsDir = path.resolve(appPath, 'extensions');
const overwrites = await loadOverwrites(extensionsDir);
const configs = await loadConfig(extensionsDir, '*/config/**/*.+(js|json)');
return {
overwrites,
configs,
};
};
// returns a list of path and module to overwrite
const loadOverwrites = async extensionsDir => {
const files = await glob(`*/${overwritableFoldersGlob}/*.*(js|json)`, {
cwd: extensionsDir,
});
return files.map(file => {
const mod = require(path.resolve(extensionsDir, file));
const propPath = filePathToPath(file);
return {
path: propPath,
mod,
};
});
};

View File

@ -0,0 +1,13 @@
const path = require('path');
module.exports = (fileP, useFileNameAsKey = true) => {
const prop = path
.normalize(fileP)
.replace(/(.settings|.json|.js)/g, '')
.toLowerCase()
.split('/')
.join('.')
.split('.');
return useFileNameAsKey === true ? prop : prop.slice(0, -1);
};

View File

@ -0,0 +1,34 @@
const _ = require('lodash');
const loadFiles = require('./load-files');
const requireFileAndParse = require('./require-file-parse');
module.exports = (dir, pattern = 'config/**/*.+(js|json)') =>
loadFiles(dir, pattern, {
requireFn: requireFileAndParse,
shouldUseFileNameAsKey,
});
const shouldUseFileNameAsKey = file => {
return _.some(prefixedPaths, e => file.startsWith(`config/${e}`))
? true
: false;
};
const prefixedPaths = [
...['staging', 'production', 'development'].reduce((acc, env) => {
return acc.concat(
`environments/${env}/database`,
`environments/${env}/security`,
`environments/${env}/request`,
`environments/${env}/response`,
`environments/${env}/server`
);
}, []),
'functions',
'policies',
'locales',
'hook',
'middleware',
'language',
'queries',
'layout',
];

View File

@ -1,18 +1,7 @@
const path = require('path');
const glob = require('./glob');
const _ = require('lodash');
const filePathToPath = (fileP, useFileNameAsKey = true) => {
const prop = path
.normalize(fileP)
.replace(/(.settings|.json|.js)/g, '')
.toLowerCase()
.split('/')
.join('.')
.split('.');
return useFileNameAsKey === true ? prop : prop.slice(0, -1);
};
const filePathToPath = require('./filepath-to-prop-path');
module.exports = async (
dir,