mirror of
				https://github.com/strapi/strapi.git
				synced 2025-10-31 01:47:13 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			206 lines
		
	
	
		
			6.6 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			206 lines
		
	
	
		
			6.6 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| 'use strict';
 | |
| 
 | |
| /**
 | |
|  * Module dependencies
 | |
|  */
 | |
| 
 | |
| // Node.js core.
 | |
| const path = require('path');
 | |
| const spawn = require('child_process').spawnSync;
 | |
| 
 | |
| // Public node modules.
 | |
| const _ = require('lodash');
 | |
| const Waterline = require('waterline');
 | |
| const WaterlineGraphQL = require('waterline-graphql');
 | |
| 
 | |
| // Local utilities.
 | |
| const helpers = require('./helpers/index');
 | |
| 
 | |
| /**
 | |
|  * Waterline ORM hook
 | |
|  */
 | |
| 
 | |
| module.exports = function (strapi) {
 | |
|   const hook = {
 | |
| 
 | |
|     /**
 | |
|      * Default options
 | |
|      */
 | |
| 
 | |
|     defaults: {
 | |
|       orm: {
 | |
|         adapters: {
 | |
|           disk: 'sails-disk'
 | |
|         },
 | |
|         defaultConnection: 'default',
 | |
|         connections: {
 | |
|           default: {
 | |
|             adapter: 'disk',
 | |
|             filePath: '.tmp/',
 | |
|             fileName: 'default.db',
 | |
|             migrate: 'alter'
 | |
|           },
 | |
|           permanent: {
 | |
|             adapter: 'disk',
 | |
|             filePath: './data/',
 | |
|             fileName: 'permanent.db',
 | |
|             migrate: 'alter'
 | |
|           }
 | |
|         }
 | |
|       },
 | |
|       globals: {
 | |
|         models: true
 | |
|       }
 | |
|     },
 | |
| 
 | |
|     /**
 | |
|      * Initialize the hook
 | |
|      */
 | |
| 
 | |
|     initialize: function (cb) {
 | |
|       if (_.isPlainObject(strapi.config.orm) && !_.isEmpty(strapi.config.orm)) {
 | |
|         strapi.adapters = {};
 | |
| 
 | |
|         // Expose a new instance of Waterline.
 | |
|         if (!strapi.orm) {
 | |
|           strapi.orm = new Waterline();
 | |
|         }
 | |
| 
 | |
|         // Prefix every adapter and require them from the
 | |
|         // `node_modules` directory of the application.
 | |
|         _.forEach(strapi.config.orm.adapters, function (adapter, name) {
 | |
|           try {
 | |
|             strapi.adapters[name] = require(path.resolve(strapi.config.appPath, 'node_modules', adapter));
 | |
|           } catch (err) {
 | |
|             if (strapi.config.environment === 'development') {
 | |
|               strapi.log.warn('Installing the `' + adapter + '` adapter, please wait...');
 | |
|               spawn('npm', ['install', adapter, '--save']);
 | |
|             } else {
 | |
|               strapi.log.error('The adapter `' + adapter + '` is not installed.');
 | |
|               strapi.log.error('Execute `$ npm install ' + adapter + ' --save` to install it.');
 | |
|               process.exit(1);
 | |
|             }
 | |
|           }
 | |
|         });
 | |
| 
 | |
|         // Check if the adapter in every connections exists.
 | |
|         _.forEach(strapi.config.orm.connections, function (settings, name) {
 | |
|           if (!_.has(strapi.config.orm.adapters, settings.adapter)) {
 | |
|             strapi.log.error('Unknown adapter `' + settings.adapter + '` for connection `' + name + '`.');
 | |
|             process.exit(1);
 | |
|           }
 | |
|         });
 | |
| 
 | |
|         // Parse each models.
 | |
|         _.forEach(strapi.models, function (definition, model) {
 | |
|           _.bindAll(definition);
 | |
| 
 | |
|           // Make sure the model has a connection.
 | |
|           // If not, use the default connection.
 | |
|           if (_.isEmpty(definition.connection)) {
 | |
|             definition.connection = strapi.config.orm.defaultConnection;
 | |
|           }
 | |
| 
 | |
|           // Make sure this connection exists.
 | |
|           if (!_.has(strapi.config.orm.connections, definition.connection)) {
 | |
|             strapi.log.error('The connection `' + definition.connection + '` specified in the `' + model + '` model does not exist.');
 | |
|             process.exit(1);
 | |
|           }
 | |
| 
 | |
|           // Make sure this connection has a migrate strategy.
 | |
|           // If not, use the `alter` strategy.
 | |
|           if (!_.has(strapi.config.orm.connections[definition.connection], 'migrate')) {
 | |
|             strapi.log.warn('The connection `' + definition.connection + '` does not have a migrate strategy.');
 | |
|             strapi.log.warn('Setting the migrate strategy for `' + definition.connection + '` to `alter`.');
 | |
|             strapi.config.orm.connections[definition.connection].migrate = 'alter';
 | |
|           }
 | |
| 
 | |
|           // Apply the migrate strategy to the model.
 | |
|           definition.migrate = strapi.config.orm.connections[definition.connection].migrate;
 | |
| 
 | |
|           // Derive information about this model's associations from its schema
 | |
|           // and attach/expose the metadata as `SomeModel.associations` (an array).
 | |
|           definition.associations = _.reduce(definition.attributes, function (associatedWith, attrDef, attrName) {
 | |
|             if (typeof attrDef === 'object' && (attrDef.model || attrDef.collection)) {
 | |
|               const assoc = {
 | |
|                 alias: attrName,
 | |
|                 type: attrDef.model ? 'model' : 'collection'
 | |
|               };
 | |
| 
 | |
|               if (attrDef.model) {
 | |
|                 assoc.model = attrDef.model;
 | |
|               }
 | |
| 
 | |
|               if (attrDef.collection) {
 | |
|                 assoc.collection = attrDef.collection;
 | |
|               }
 | |
| 
 | |
|               if (attrDef.via) {
 | |
|                 assoc.via = attrDef.via;
 | |
|               }
 | |
| 
 | |
|               associatedWith.push(assoc);
 | |
|             }
 | |
| 
 | |
|             return associatedWith;
 | |
|           }, []);
 | |
| 
 | |
|           // Finally, load the collection in the Waterline instance.
 | |
|           try {
 | |
|             strapi.orm.loadCollection(Waterline.Collection.extend(definition));
 | |
|           } catch (err) {
 | |
|             strapi.log.error('Impossible to register the `' + model + '` model.');
 | |
|             process.exit(1);
 | |
|           }
 | |
|         });
 | |
| 
 | |
|         // Finally, initialize the Waterline ORM and
 | |
|         // globally expose models.
 | |
|         strapi.orm.initialize({
 | |
|           adapters: strapi.adapters,
 | |
|           models: strapi.models,
 | |
|           connections: strapi.config.orm.connections,
 | |
|           defaults: {
 | |
|             connection: strapi.config.orm.defaultConnection
 | |
|           }
 | |
|         }, function () {
 | |
|           if (strapi.config.globals.models === true) {
 | |
|             _.forEach(strapi.models, function (definition, model) {
 | |
|               const globalName = _.capitalize(strapi.models[model].globalId);
 | |
|               global[globalName] = strapi.orm.collections[model];
 | |
|             });
 | |
|           }
 | |
|         });
 | |
| 
 | |
|         // Parse each models and look for associations.
 | |
|         _.forEach(strapi.orm.collections, function (definition, model) {
 | |
|           _.forEach(definition.associations, function (association) {
 | |
|             association.nature = helpers.getAssociationType(model, association);
 | |
|           });
 | |
|         });
 | |
| 
 | |
|         if (strapi.config.graphql.enabled === true) {
 | |
|           // Parse each models and add associations array
 | |
|           _.forEach(strapi.orm.collections, function (collection, key) {
 | |
|             if (strapi.models.hasOwnProperty(key)) {
 | |
|               collection.associations = strapi.models[key].associations || [];
 | |
|             }
 | |
|           });
 | |
| 
 | |
|           // Expose the GraphQL schemas at `strapi.schemas`
 | |
|           strapi.schemas = WaterlineGraphQL.getGraphQLSchema({
 | |
|             collections: strapi.orm.collections,
 | |
|             usefulFunctions: true
 | |
|           });
 | |
|         }
 | |
|       } else {
 | |
|         strapi.log.warn('Waterline ORM disabled!');
 | |
|       }
 | |
| 
 | |
|       cb();
 | |
|     }
 | |
|   };
 | |
| 
 | |
|   return hook;
 | |
| };
 | 
