3
3
*/
4
4
5
5
var express = require ( 'express' )
6
+ , proto = require ( './application' )
6
7
, fs = require ( 'fs' )
7
8
, ejs = require ( 'ejs' )
8
9
, EventEmitter = require ( 'events' ) . EventEmitter
@@ -29,18 +30,6 @@ var express = require('express')
29
30
30
31
var loopback = exports = module . exports = createApplication ;
31
32
32
- /**
33
- * True if running in a browser environment; false otherwise.
34
- */
35
-
36
- loopback . isBrowser = typeof window !== 'undefined' ;
37
-
38
- /**
39
- * True if running in a server environment; false otherwise.
40
- */
41
-
42
- loopback . isServer = ! loopback . isBrowser ;
43
-
44
33
/**
45
34
* Framework version.
46
35
*/
@@ -68,9 +57,6 @@ loopback.compat = require('./compat');
68
57
function createApplication ( ) {
69
58
var app = express ( ) ;
70
59
71
- // Defer loading of `./application` until all `loopback` static methods
72
- // are defined, because `./application` depends on loopback.
73
- var proto = require ( './application' ) ;
74
60
merge ( app , proto ) ;
75
61
76
62
// Create a new instance of models registry per each app instance
@@ -93,17 +79,23 @@ function createApplication() {
93
79
return app ;
94
80
}
95
81
82
+ function mixin ( source ) {
83
+ for ( var key in source ) {
84
+ var desc = Object . getOwnPropertyDescriptor ( source , key ) ;
85
+ Object . defineProperty ( loopback , key , desc ) ;
86
+ }
87
+ }
88
+
89
+ mixin ( require ( './runtime' ) ) ;
90
+ mixin ( require ( './registry' ) ) ;
91
+
96
92
/*!
97
93
* Expose express.middleware as loopback.*
98
94
* for example `loopback.errorHandler` etc.
99
95
*/
100
96
101
- for ( var key in express ) {
102
- Object . defineProperty (
103
- loopback
104
- , key
105
- , Object . getOwnPropertyDescriptor ( express , key ) ) ;
106
- }
97
+ mixin ( express ) ;
98
+
107
99
108
100
/*!
109
101
* Expose additional loopback middleware
@@ -129,143 +121,6 @@ if (loopback.isServer) {
129
121
130
122
loopback . errorHandler . title = 'Loopback' ;
131
123
132
- /**
133
- * Create a data source with passing the provided options to the connector.
134
- *
135
- * @param {String } name Optional name.
136
- * @options {Object} Data Source options
137
- * @property {Object } connector LoopBack connector.
138
- * @property {* } Other properties See the relevant connector documentation.
139
- */
140
-
141
- loopback . createDataSource = function ( name , options ) {
142
- var ds = new DataSource ( name , options , loopback . Model . modelBuilder ) ;
143
- ds . createModel = function ( name , properties , settings ) {
144
- var ModelCtor = loopback . createModel ( name , properties , settings ) ;
145
- ModelCtor . attachTo ( ds ) ;
146
- return ModelCtor ;
147
- } ;
148
-
149
- if ( ds . settings && ds . settings . defaultForType ) {
150
- loopback . setDefaultDataSourceForType ( ds . settings . defaultForType , ds ) ;
151
- }
152
-
153
- return ds ;
154
- } ;
155
-
156
- /**
157
- * Create a named vanilla JavaScript class constructor with an attached set of properties and options.
158
- *
159
- * @param {String } name Unique name.
160
- * @param {Object } properties
161
- * @param {Object } options (optional)
162
- */
163
-
164
- loopback . createModel = function ( name , properties , options ) {
165
- options = options || { } ;
166
- var BaseModel = options . base || options . super ;
167
-
168
- if ( typeof BaseModel === 'string' ) {
169
- BaseModel = loopback . getModel ( BaseModel ) ;
170
- }
171
-
172
- BaseModel = BaseModel || loopback . Model ;
173
-
174
- var model = BaseModel . extend ( name , properties , options ) ;
175
-
176
- // try to attach
177
- try {
178
- loopback . autoAttachModel ( model ) ;
179
- } catch ( e ) { }
180
-
181
- return model ;
182
- } ;
183
-
184
- /**
185
- * Create a model as described by the configuration object.
186
- *
187
- * @example
188
- *
189
- * ```js
190
- * loopback.createModelFromConfig({
191
- * name: 'Author',
192
- * properties: {
193
- * firstName: 'string',
194
- * lastName: 'string
195
- * },
196
- * relations: {
197
- * books: {
198
- * model: 'Book',
199
- * type: 'hasAndBelongsToMany'
200
- * }
201
- * }
202
- * });
203
- * ```
204
- *
205
- * @options {Object} model configuration
206
- * @property {String } name Unique name.
207
- * @property {Object= } properties Model properties
208
- * @property {Object= } options Model options. Options can be specified on the
209
- * top level config object too. E.g. `{ base: 'User' }` is the same as
210
- * `{ options: { base: 'User' } }`.
211
- */
212
- loopback . createModelFromConfig = function ( config ) {
213
- var name = config . name ;
214
- var properties = config . properties ;
215
- var options = buildModelOptionsFromConfig ( config ) ;
216
-
217
- assert ( typeof name === 'string' ,
218
- 'The model-config property `name` must be a string' ) ;
219
-
220
- return loopback . createModel ( name , properties , options ) ;
221
- } ;
222
-
223
- function buildModelOptionsFromConfig ( config ) {
224
- var options = merge ( { } , config . options ) ;
225
- for ( var key in config ) {
226
- if ( [ 'name' , 'properties' , 'options' ] . indexOf ( key ) !== - 1 ) {
227
- // Skip items which have special meaning
228
- continue ;
229
- }
230
-
231
- if ( options [ key ] !== undefined ) {
232
- // When both `config.key` and `config.options.key` are set,
233
- // use the latter one
234
- continue ;
235
- }
236
-
237
- options [ key ] = config [ key ] ;
238
- }
239
- return options ;
240
- }
241
-
242
- /**
243
- * Alter an existing Model class.
244
- * @param {Model } ModelCtor The model constructor to alter.
245
- * @options {Object} Additional configuration to apply
246
- * @property {DataSource } dataSource Attach the model to a dataSource.
247
- * @property {Object } relations Model relations to add/update.
248
- */
249
- loopback . configureModel = function ( ModelCtor , config ) {
250
- var settings = ModelCtor . settings ;
251
-
252
- if ( config . relations ) {
253
- var relations = settings . relations = settings . relations || { } ;
254
- Object . keys ( config . relations ) . forEach ( function ( key ) {
255
- relations [ key ] = merge ( relations [ key ] || { } , config . relations [ key ] ) ;
256
- } ) ;
257
- }
258
-
259
- // It's important to attach the datasource after we have updated
260
- // configuration, so that the datasource picks up updated relations
261
- if ( config . dataSource ) {
262
- assert ( config . dataSource instanceof DataSource ,
263
- 'Cannot configure ' + ModelCtor . modelName +
264
- ': config.dataSource must be an instance of loopback.DataSource' ) ;
265
- ModelCtor . attachTo ( config . dataSource ) ;
266
- }
267
- } ;
268
-
269
124
/**
270
125
* Add a remote method to a model.
271
126
* @param {Function } fn
@@ -298,119 +153,11 @@ loopback.template = function (file) {
298
153
return ejs . compile ( str ) ;
299
154
} ;
300
155
301
- /**
302
- * Get an in-memory data source. Use one if it already exists.
303
- *
304
- * @param {String } [name] The name of the data source. If not provided, the `'default'` is used.
305
- */
306
-
307
- loopback . memory = function ( name ) {
308
- name = name || 'default' ;
309
- var memory = (
310
- this . _memoryDataSources
311
- || ( this . _memoryDataSources = { } )
312
- ) [ name ] ;
313
-
314
- if ( ! memory ) {
315
- memory = this . _memoryDataSources [ name ] = loopback . createDataSource ( {
316
- connector : loopback . Memory
317
- } ) ;
318
- }
319
-
320
- return memory ;
321
- } ;
322
-
323
- /**
324
- * Look up a model class by name from all models created by loopback.createModel()
325
- * @param {String } modelName The model name
326
- * @returns {Model } The model class
327
- */
328
- loopback . getModel = function ( modelName ) {
329
- return loopback . Model . modelBuilder . models [ modelName ] ;
330
- } ;
331
-
332
- /**
333
- * Look up a model class by the base model class. The method can be used by LoopBack
334
- * to find configured models in models.json over the base model.
335
- * @param {Model } The base model class
336
- * @returns {Model } The subclass if found or the base class
337
- */
338
- loopback . getModelByType = function ( modelType ) {
339
- assert ( typeof modelType === 'function' , 'The model type must be a constructor' ) ;
340
- var models = loopback . Model . modelBuilder . models ;
341
- for ( var m in models ) {
342
- if ( models [ m ] . prototype instanceof modelType ) {
343
- return models [ m ] ;
344
- }
345
- }
346
- return modelType ;
347
- } ;
348
-
349
- /**
350
- * Set the default `dataSource` for a given `type`.
351
- * @param {String } type The datasource type
352
- * @param {Object|DataSource } dataSource The data source settings or instance
353
- * @returns {DataSource } The data source instance
354
- */
355
-
356
- loopback . setDefaultDataSourceForType = function ( type , dataSource ) {
357
- var defaultDataSources = this . defaultDataSources || ( this . defaultDataSources = { } ) ;
358
-
359
- if ( ! ( dataSource instanceof DataSource ) ) {
360
- dataSource = this . createDataSource ( dataSource ) ;
361
- }
362
-
363
- defaultDataSources [ type ] = dataSource ;
364
- return dataSource ;
365
- } ;
366
-
367
- /**
368
- * Get the default `dataSource` for a given `type`.
369
- * @param {String } type The datasource type
370
- * @returns {DataSource } The data source instance
371
- */
372
-
373
- loopback . getDefaultDataSourceForType = function ( type ) {
374
- return this . defaultDataSources && this . defaultDataSources [ type ] ;
375
- } ;
376
-
377
- /**
378
- * Attach any model that does not have a dataSource to
379
- * the default dataSource for the type the Model requests
380
- */
381
-
382
- loopback . autoAttach = function ( ) {
383
- var models = this . Model . modelBuilder . models ;
384
- assert . equal ( typeof models , 'object' , 'Cannot autoAttach without a models object' ) ;
385
-
386
- Object . keys ( models ) . forEach ( function ( modelName ) {
387
- var ModelCtor = models [ modelName ] ;
388
-
389
- // Only auto attach if the model doesn't have an explicit data source
390
- if ( ModelCtor && ( ! ( ModelCtor . dataSource instanceof DataSource ) ) ) {
391
- loopback . autoAttachModel ( ModelCtor ) ;
392
- }
393
- } ) ;
394
- } ;
395
-
396
- loopback . autoAttachModel = function ( ModelCtor ) {
397
- if ( ModelCtor . autoAttach ) {
398
- var ds = loopback . getDefaultDataSourceForType ( ModelCtor . autoAttach ) ;
399
-
400
- assert ( ds instanceof DataSource , 'cannot autoAttach model "'
401
- + ModelCtor . modelName
402
- + '". No dataSource found of type ' + ModelCtor . autoAttach ) ;
403
-
404
- ModelCtor . attachTo ( ds ) ;
405
- }
406
- } ;
407
156
408
157
/*!
409
158
* Built in models / services
410
159
*/
411
160
412
- loopback . Model = require ( './models/model' ) ;
413
- loopback . DataModel = require ( './models/data-model' ) ;
414
161
loopback . Email = require ( './models/email' ) ;
415
162
loopback . User = require ( './models/user' ) ;
416
163
loopback . Application = require ( './models/application' ) ;
0 commit comments