1 | var convict = require('convict')
|
2 | var fs = require('fs')
|
3 |
|
4 | var conf = convict({
|
5 | app: {
|
6 | name: {
|
7 | doc: 'The applicaton name',
|
8 | format: String,
|
9 | default: 'DADI API Repo Default'
|
10 | }
|
11 | },
|
12 | publicUrl: {
|
13 | host: {
|
14 | doc:
|
15 | 'The host of the URL where the API instance can be publicly accessed at',
|
16 | format: '*',
|
17 | default: null,
|
18 | env: 'URL_HOST'
|
19 | },
|
20 | port: {
|
21 | doc:
|
22 | 'The port of the URL where the API instance can be publicly accessed at',
|
23 | format: '*',
|
24 | default: null,
|
25 | env: 'URL_PORT'
|
26 | },
|
27 | protocol: {
|
28 | doc:
|
29 | 'The protocol of the URL where the API instance can be publicly accessed at',
|
30 | format: 'String',
|
31 | default: 'http',
|
32 | env: 'URL_PROTOCOL'
|
33 | }
|
34 | },
|
35 | server: {
|
36 | host: {
|
37 | doc:
|
38 | 'Accept connections on the specified address. If the host is omitted, the server will accept connections on any IPv6 address (::) when IPv6 is available, or any IPv4 address (0.0.0.0) otherwise.',
|
39 | format: '*',
|
40 | default: null,
|
41 | env: 'HOST'
|
42 | },
|
43 | port: {
|
44 | doc:
|
45 | 'Accept connections on the specified port. A value of zero will assign a random port.',
|
46 | format: Number,
|
47 | default: 8081,
|
48 | env: 'PORT'
|
49 | },
|
50 | redirectPort: {
|
51 | doc: 'Port to redirect http connections to https from',
|
52 | format: 'port',
|
53 | default: 0,
|
54 | env: 'REDIRECT_PORT'
|
55 | },
|
56 | protocol: {
|
57 | doc: 'The protocol the web application will use',
|
58 | format: String,
|
59 | default: 'http',
|
60 | env: 'PROTOCOL'
|
61 | },
|
62 | sslPassphrase: {
|
63 | doc: 'The passphrase of the SSL private key',
|
64 | format: String,
|
65 | default: '',
|
66 | env: 'SSL_PRIVATE_KEY_PASSPHRASE'
|
67 | },
|
68 | sslPrivateKeyPath: {
|
69 | doc: 'The filename of the SSL private key',
|
70 | format: String,
|
71 | default: '',
|
72 | env: 'SSL_PRIVATE_KEY_PATH'
|
73 | },
|
74 | sslCertificatePath: {
|
75 | doc: 'The filename of the SSL certificate',
|
76 | format: String,
|
77 | default: '',
|
78 | env: 'SSL_CERTIFICATE_PATH'
|
79 | },
|
80 | sslIntermediateCertificatePath: {
|
81 | doc: 'The filename of an SSL intermediate certificate, if any',
|
82 | format: String,
|
83 | default: '',
|
84 | env: 'SSL_INTERMEDIATE_CERTIFICATE_PATH'
|
85 | },
|
86 | sslIntermediateCertificatePaths: {
|
87 | doc:
|
88 | 'The filenames of SSL intermediate certificates, overrides sslIntermediateCertificate (singular)',
|
89 | format: Array,
|
90 | default: [],
|
91 | env: 'SSL_INTERMEDIATE_CERTIFICATE_PATHS'
|
92 | }
|
93 | },
|
94 | datastore: {
|
95 | doc:
|
96 | 'The name of the npm module that implements the data connector used for storing documents',
|
97 | format: String,
|
98 | default: '@dadi/api-mongodb'
|
99 | },
|
100 | auth: {
|
101 | tokenUrl: {
|
102 | doc: 'The endpoint used for token generation',
|
103 | format: String,
|
104 | default: '/token'
|
105 | },
|
106 | tokenTtl: {
|
107 | doc: 'The amount of time (in seconds) which bearer tokens are valid for',
|
108 | format: Number,
|
109 | default: 1800
|
110 | },
|
111 | tokenKey: {
|
112 | doc: 'The private key used to sign JWT tokens',
|
113 | format: String,
|
114 | default: 'YOU-MUST-CHANGE-ME!'
|
115 | },
|
116 | accessCollection: {
|
117 | doc:
|
118 | 'The name of the internal collection used to store aggregate permissions data',
|
119 | format: String,
|
120 | default: 'accessStore'
|
121 | },
|
122 | clientCollection: {
|
123 | doc: 'The name of the internal collection used to store clients',
|
124 | format: String,
|
125 | default: 'clientStore'
|
126 | },
|
127 | roleCollection: {
|
128 | doc: 'The name of the internal collection used to store roles',
|
129 | format: String,
|
130 | default: 'roleStore'
|
131 | },
|
132 | datastore: {
|
133 | doc:
|
134 | 'The name of the npm module that implements the data connector used for authentication',
|
135 | format: String,
|
136 | default: '@dadi/api-mongodb'
|
137 | },
|
138 | database: {
|
139 | doc: 'The name of the database used to store authentication data',
|
140 | format: String,
|
141 | default: 'test',
|
142 | env: 'DB_AUTH_NAME'
|
143 | },
|
144 | hashSecrets: {
|
145 | doc: 'Whether to hash client secrets',
|
146 | format: Boolean,
|
147 | default: true
|
148 | },
|
149 | saltRounds: {
|
150 | doc: 'The number of rounds to go through when hashing a password',
|
151 | format: Number,
|
152 | default: 10
|
153 | }
|
154 | },
|
155 | search: {
|
156 | database: {
|
157 | doc:
|
158 | 'The name of the database to use for storing and querying indexed documents',
|
159 | format: String,
|
160 | default: 'search',
|
161 | env: 'DB_SEARCH_NAME'
|
162 | },
|
163 | datastore: {
|
164 | doc: 'The datastore to use for storing and querying indexed documents',
|
165 | format: String,
|
166 | default: ''
|
167 | },
|
168 | enabled: {
|
169 | doc: 'If true, API responds to collection /search endpoints',
|
170 | format: Boolean,
|
171 | default: false
|
172 | },
|
173 | indexCollection: {
|
174 | doc:
|
175 | 'The name of the datastore collection that will hold the index of word matches',
|
176 | format: String,
|
177 | default: 'searchIndex'
|
178 | },
|
179 | minQueryLength: {
|
180 | doc: 'Minimum search string length',
|
181 | format: Number,
|
182 | default: 3
|
183 | },
|
184 | wordCollection: {
|
185 | doc:
|
186 | 'The name of the datastore collection that will hold tokenized words',
|
187 | format: String,
|
188 | default: 'searchWords'
|
189 | }
|
190 | },
|
191 | caching: {
|
192 | ttl: {
|
193 | doc: '',
|
194 | format: Number,
|
195 | default: 300
|
196 | },
|
197 | directory: {
|
198 | enabled: {
|
199 | doc: 'If enabled, cache files will be saved to the filesystem',
|
200 | format: Boolean,
|
201 | default: true
|
202 | },
|
203 | path: {
|
204 | doc: 'The relative path to the cache directory',
|
205 | format: String,
|
206 | default: './cache/api'
|
207 | },
|
208 | extension: {
|
209 | doc: 'The extension to use for cache files',
|
210 | format: String,
|
211 | default: 'json'
|
212 | },
|
213 | autoFlush: {
|
214 | doc: '',
|
215 | format: Boolean,
|
216 | default: true
|
217 | },
|
218 | autoFlushInterval: {
|
219 | doc: '',
|
220 | format: Number,
|
221 | default: 60
|
222 | }
|
223 | },
|
224 | redis: {
|
225 | enabled: {
|
226 | doc:
|
227 | 'If enabled, cache files will be saved to the specified Redis server',
|
228 | format: Boolean,
|
229 | default: false,
|
230 | env: 'REDIS_ENABLED'
|
231 | },
|
232 | host: {
|
233 | doc: 'The Redis server host',
|
234 | format: String,
|
235 | default: '127.0.0.1',
|
236 | env: 'REDIS_HOST'
|
237 | },
|
238 | port: {
|
239 | doc: 'The port for the Redis server',
|
240 | format: 'port',
|
241 | default: 6379,
|
242 | env: 'REDIS_PORT'
|
243 | },
|
244 | password: {
|
245 | doc: '',
|
246 | format: String,
|
247 | default: '',
|
248 | env: 'REDIS_PASSWORD'
|
249 | }
|
250 | }
|
251 | },
|
252 | logging: {
|
253 | enabled: {
|
254 | doc: 'If true, logging is enabled using the following settings.',
|
255 | format: Boolean,
|
256 | default: true
|
257 | },
|
258 | level: {
|
259 | doc: 'Sets the logging level.',
|
260 | format: ['debug', 'info', 'warn', 'error', 'trace'],
|
261 | default: 'info'
|
262 | },
|
263 | path: {
|
264 | doc: 'The absolute or relative path to the directory for log files.',
|
265 | format: String,
|
266 | default: './log'
|
267 | },
|
268 | filename: {
|
269 | doc: 'The name to use for the log file, without extension.',
|
270 | format: String,
|
271 | default: 'api'
|
272 | },
|
273 | extension: {
|
274 | doc: 'The extension to use for the log file.',
|
275 | format: String,
|
276 | default: 'log'
|
277 | },
|
278 | accessLog: {
|
279 | enabled: {
|
280 | doc:
|
281 | 'If true, HTTP access logging is enabled. The log file name is similar to the setting used for normal logging, with the addition of "access". For example `api.access.log`.',
|
282 | format: Boolean,
|
283 | default: true
|
284 | },
|
285 | kinesisStream: {
|
286 | doc: 'An AWS Kinesis stream to write to log records to.',
|
287 | format: String,
|
288 | default: '',
|
289 | env: 'KINESIS_STREAM'
|
290 | }
|
291 | }
|
292 | },
|
293 | paths: {
|
294 | collections: {
|
295 | doc: 'The relative or absolute path to collection specification files',
|
296 | format: String,
|
297 | default: 'workspace/collections'
|
298 | },
|
299 | endpoints: {
|
300 | doc: 'The relative or absolute path to custom endpoint files',
|
301 | format: String,
|
302 | default: 'workspace/endpoints'
|
303 | },
|
304 | hooks: {
|
305 | doc: 'The relative or absolute path to hook specification files',
|
306 | format: String,
|
307 | default: 'workspace/hooks'
|
308 | }
|
309 | },
|
310 | feedback: {
|
311 | doc: '',
|
312 | format: Boolean,
|
313 | default: false
|
314 | },
|
315 | status: {
|
316 | enabled: {
|
317 | doc: 'If true, status endpoint is enabled.',
|
318 | format: Boolean,
|
319 | default: false
|
320 | },
|
321 | routes: {
|
322 | doc:
|
323 | 'An array of routes to test. Each route object must contain properties `route` and `expectedResponseTime`.',
|
324 | format: Array,
|
325 | default: []
|
326 | }
|
327 | },
|
328 | query: {
|
329 | useVersionFilter: {
|
330 | doc:
|
331 | 'If true, the API version parameter is extracted from the request URL and passed to the database query',
|
332 | format: Boolean,
|
333 | default: false
|
334 | }
|
335 | },
|
336 | media: {
|
337 | defaultBucket: {
|
338 | doc: 'The name of the default media bucket',
|
339 | format: String,
|
340 | default: 'mediaStore'
|
341 | },
|
342 | buckets: {
|
343 | doc: 'The names of media buckets to be used',
|
344 | format: Array,
|
345 | default: []
|
346 | },
|
347 | tokenSecret: {
|
348 | doc: 'The secret key used to sign and verify tokens when uploading media',
|
349 | format: String,
|
350 | default: 'catboat-beatific-drizzle'
|
351 | },
|
352 | tokenExpiresIn: {
|
353 | doc:
|
354 | 'The duration a signed token is valid for. Expressed in seconds or a string describing a time span (https://github.com/zeit/ms). Eg: 60, "2 days", "10h", "7d"',
|
355 | format: '*',
|
356 | default: '1h'
|
357 | },
|
358 | storage: {
|
359 | doc: 'Determines the storage type for uploads',
|
360 | format: ['disk', 's3'],
|
361 | default: 'disk'
|
362 | },
|
363 | basePath: {
|
364 | doc: 'Sets the root directory for uploads',
|
365 | format: String,
|
366 | default: 'workspace/media'
|
367 | },
|
368 | pathFormat: {
|
369 | doc:
|
370 | 'Determines the format for the generation of subdirectories to store uploads',
|
371 | format: ['none', 'date', 'datetime', 'sha1/4', 'sha1/5', 'sha1/8'],
|
372 | default: 'date'
|
373 | },
|
374 | s3: {
|
375 | accessKey: {
|
376 | doc:
|
377 | 'The access key used to connect to an S3-compatible storage provider',
|
378 | format: String,
|
379 | default: '',
|
380 | env: 'AWS_S3_ACCESS_KEY'
|
381 | },
|
382 | secretKey: {
|
383 | doc:
|
384 | 'The secret key used to connect to an S3-compatible storage provider',
|
385 | format: String,
|
386 | default: '',
|
387 | env: 'AWS_S3_SECRET_KEY'
|
388 | },
|
389 | bucketName: {
|
390 | doc: 'The name of the S3 bucket in which to store uploads',
|
391 | format: String,
|
392 | default: '',
|
393 | env: 'AWS_S3_BUCKET_NAME'
|
394 | },
|
395 | region: {
|
396 | doc: 'The region for an S3-compatible storage provider',
|
397 | format: String,
|
398 | default: '',
|
399 | env: 'AWS_S3_REGION'
|
400 | },
|
401 | endpoint: {
|
402 | doc: 'The endpoint for an S3-compatible storage provider',
|
403 | format: String,
|
404 | default: ''
|
405 | }
|
406 | }
|
407 | },
|
408 | env: {
|
409 | doc: 'The applicaton environment.',
|
410 | format: String,
|
411 | default: 'development',
|
412 | env: 'NODE_ENV',
|
413 | arg: 'node_env'
|
414 | },
|
415 | cluster: {
|
416 | doc:
|
417 | 'If true, API runs in cluster mode, starting a worker for each CPU core',
|
418 | format: Boolean,
|
419 | default: false
|
420 | },
|
421 | cors: {
|
422 | doc:
|
423 | 'If true, responses will include headers for cross-domain resource sharing',
|
424 | format: Boolean,
|
425 | default: true
|
426 | },
|
427 | internalFieldsPrefix: {
|
428 | doc: 'The character to be used for prefixing internal fields',
|
429 | format: 'String',
|
430 | default: '_'
|
431 | },
|
432 | databaseConnection: {
|
433 | maxRetries: {
|
434 | doc:
|
435 | 'The maximum number of times to reconnection attempts after a database fails',
|
436 | format: Number,
|
437 | default: 10
|
438 | }
|
439 | },
|
440 | i18n: {
|
441 | defaultLanguage: {
|
442 | doc: 'ISO-639-1 code of the default language',
|
443 | format: String,
|
444 | default: 'en'
|
445 | },
|
446 | languages: {
|
447 | doc: 'List of ISO-639-1 codes for the supported languages',
|
448 | format: Array,
|
449 | default: []
|
450 | },
|
451 | fieldCharacter: {
|
452 | doc: 'Special character to denote a translated field',
|
453 | format: String,
|
454 | default: ':'
|
455 | }
|
456 | },
|
457 | featureQuery: {
|
458 | enabled: {
|
459 | doc: 'Whether feature query via custom headers is enabled',
|
460 | format: Boolean,
|
461 | default: true
|
462 | }
|
463 | },
|
464 | workQueue: {
|
465 | debounceTime: {
|
466 | doc:
|
467 | 'The amount of idle time (in ms) required for the work queue to start a background job',
|
468 | format: Number,
|
469 | default: 500
|
470 | },
|
471 | pollingTime: {
|
472 | doc:
|
473 | 'The interval (in ms) at which the work queue checks for new background jobs',
|
474 | format: Number,
|
475 | default: 200
|
476 | }
|
477 | }
|
478 | })
|
479 |
|
480 |
|
481 | var env = conf.get('env')
|
482 | conf.loadFile('./config/config.' + env + '.json')
|
483 |
|
484 |
|
485 | conf.updateConfigDataForDomain = function(domain) {
|
486 | var domainConfig = './config/' + domain + '.json'
|
487 |
|
488 | try {
|
489 | var stats = fs.statSync(domainConfig)
|
490 |
|
491 | conf.loadFile(domainConfig)
|
492 | } catch (err) {
|
493 | if (err.code === 'ENOENT') {
|
494 |
|
495 | } else {
|
496 | console.log(err)
|
497 | }
|
498 | }
|
499 | }
|
500 |
|
501 | module.exports = conf
|
502 | module.exports.configPath = function() {
|
503 | return './config/config.' + conf.get('env') + '.json'
|
504 | }
|