1 | # base-app [![NPM version](https://img.shields.io/npm/v/base-app.svg?style=flat)](https://www.npmjs.com/package/base-app) [![NPM monthly downloads](https://img.shields.io/npm/dm/base-app.svg?style=flat)](https://npmjs.org/package/base-app) [![NPM total downloads](https://img.shields.io/npm/dt/base-app.svg?style=flat)](https://npmjs.org/package/base-app) [![Linux Build Status](https://img.shields.io/travis/node-base/base-app.svg?style=flat&label=Travis)](https://travis-ci.org/node-base/base-app)
|
2 |
|
3 | > Starting point for creating a base application, with a few light plugins for running tasks and writing to the file system, and a functional CLI.
|
4 |
|
5 | Please consider following this project's author, [Jon Schlinkert](https://github.com/jonschlinkert), and consider starring the project to show your :heart: and support.
|
6 |
|
7 | - [Install](#install)
|
8 | - [Quickstart](#quickstart)
|
9 | - [CLI](#cli)
|
10 | - [API Documentation](#api-documentation)
|
11 | - [.cwd](#cwd)
|
12 | - [File System API](#file-system-api)
|
13 | * [.src](#src)
|
14 | * [.symlink](#symlink)
|
15 | * [.dest](#dest)
|
16 | * [.copy](#copy)
|
17 | - [Task API](#task-api)
|
18 | * [.task](#task)
|
19 | * [.build](#build)
|
20 | * [.series](#series)
|
21 | * [.parallel](#parallel)
|
22 | - [Events](#events)
|
23 | * [starting](#starting)
|
24 | * [finished](#finished)
|
25 | * [error](#error)
|
26 | * [task:starting](#taskstarting)
|
27 | * [task:finished](#taskfinished)
|
28 | * [task:error](#taskerror)
|
29 | * [.dataLoader](#dataloader)
|
30 | - [Plugin API](#plugin-api)
|
31 | * [.use](#use)
|
32 | * [.run](#run)
|
33 | - [Options API](#options-api)
|
34 | * [.option](#option)
|
35 | * [.hasOption](#hasoption)
|
36 | * [.enable](#enable)
|
37 | * [.disable](#disable)
|
38 | * [.enabled](#enabled)
|
39 | * [.disabled](#disabled)
|
40 | * [.isTrue](#istrue)
|
41 | * [.isFalse](#isfalse)
|
42 | * [.isBoolean](#isboolean)
|
43 | * [.option.set](#optionset)
|
44 | * [.option.get](#optionget)
|
45 | * [.option.create](#optioncreate)
|
46 | - [Data API](#data-api)
|
47 | * [.data](#data)
|
48 | * [.data.extend](#dataextend)
|
49 | * [.data.merge](#datamerge)
|
50 | * [.data.union](#dataunion)
|
51 | * [.data.set](#dataset)
|
52 | * [.data.get](#dataget)
|
53 | * [Glob patterns](#glob-patterns)
|
54 | * [Namespacing](#namespacing)
|
55 | - [About](#about)
|
56 |
|
57 | _(TOC generated by [verb](https://github.com/verbose/verb) using [markdown-toc](https://github.com/jonschlinkert/markdown-toc))_
|
58 |
|
59 | ## Install
|
60 |
|
61 | Install with [npm](https://www.npmjs.com/):
|
62 |
|
63 | ```sh
|
64 | $ npm install --save base-app
|
65 | ```
|
66 |
|
67 | ## Quickstart
|
68 |
|
69 | Below we provide a more detailed explanation of how to get started. But if you're familiar with node.js and prefer a fast-track:
|
70 |
|
71 | **Install**
|
72 |
|
73 | ```sh
|
74 | $ npm i -g base-app
|
75 | ```
|
76 |
|
77 | **Create an "app"**
|
78 |
|
79 | Then create a `basefile.js` with the following code:
|
80 |
|
81 | ```js
|
82 | module.exports = function(app, base) {
|
83 | app.task('default', function(cb) {
|
84 | console.log('task >', this.name);
|
85 | cb();
|
86 | });
|
87 | };
|
88 | ```
|
89 |
|
90 | **Run base**
|
91 |
|
92 | In the command line, run:
|
93 |
|
94 | ```sh
|
95 | $ base
|
96 | ```
|
97 |
|
98 | If everthing installed correctly, you should see `task > default` in the command line.
|
99 |
|
100 | ## CLI
|
101 |
|
102 | **Installing the CLI**
|
103 |
|
104 | To run base from the command line, you'll need to install `base-app` globally first. You can that now with the following command:
|
105 |
|
106 | ```sh
|
107 | $ npm i -g base-app
|
108 | ```
|
109 |
|
110 | This adds the `base` command to your system path, allowing it to be run from any directory or sub-directory in a project.
|
111 |
|
112 | **How the CLI works**
|
113 |
|
114 | When the `base` command is run, the globally installed `base-app` looks for a locally installed [base](https://github.com/node-base/base) module using node's `require()` system.
|
115 |
|
116 | If a locally installed [base](https://github.com/node-base/base) is found, the CLI loads the local installation of the [base](https://github.com/node-base/base) library. If a local [base](https://github.com/node-base/base) module is not found, the globally installed `base-app` will be used.
|
117 |
|
118 | Once the module is resolved, base applies the configuration from your `basefile.js` then executes any [generators](https://github.com/node-base/base-generators) or tasks you've specified for base to run.
|
119 |
|
120 | ## .cwd
|
121 |
|
122 | Getter/setter that ensures the current working directory is always a fully resolved absolute filepath.
|
123 |
|
124 | ```js
|
125 | app.cwd = 'foo';
|
126 | console.log(app.cwd);
|
127 | //=> /User/dev/base-app/foo
|
128 | ```
|
129 |
|
130 | ## File System API
|
131 |
|
132 | ### .src
|
133 |
|
134 | Glob patterns or filepaths to source files.
|
135 |
|
136 | **Params**
|
137 |
|
138 | * `glob` **{String|Array}**: Glob patterns or file paths to source files.
|
139 | * `options` **{Object}**: Options or locals to merge into the context and/or pass to `src` plugins
|
140 |
|
141 | **Example**
|
142 |
|
143 | ```js
|
144 | app.src('src/*.hbs', {layout: 'default'});
|
145 | ```
|
146 |
|
147 | ### .symlink
|
148 |
|
149 | Glob patterns or paths for symlinks.
|
150 |
|
151 | **Params**
|
152 |
|
153 | * `glob` **{String|Array}**
|
154 |
|
155 | **Example**
|
156 |
|
157 | ```js
|
158 | app.symlink('src/**');
|
159 | ```
|
160 |
|
161 | ### .dest
|
162 |
|
163 | Specify a destination for processed files.
|
164 |
|
165 | **Params**
|
166 |
|
167 | * `dest` **{String|Function}**: File path or rename function.
|
168 | * `options` **{Object}**: Options and locals to pass to `dest` plugins
|
169 |
|
170 | **Example**
|
171 |
|
172 | ```js
|
173 | app.dest('dist/');
|
174 | ```
|
175 |
|
176 | ### .copy
|
177 |
|
178 | Copy files with the given glob `patterns` to the specified `dest`.
|
179 |
|
180 | **Params**
|
181 |
|
182 | * `patterns` **{String|Array}**: Glob patterns of files to copy.
|
183 | * `dest` **{String|Function}**: Desination directory.
|
184 | * `returns` **{Stream}**: Stream, to continue processing if necessary.
|
185 |
|
186 | **Example**
|
187 |
|
188 | ```js
|
189 | app.task('assets', function(cb) {
|
190 | app.copy('assets/**', 'dist/')
|
191 | .on('error', cb)
|
192 | .on('finish', cb)
|
193 | });
|
194 | ```
|
195 |
|
196 | ## Task API
|
197 |
|
198 | Methods for running tasks are from the [base-task](https://github.com/base/base-task) plugin, which uses [composer](https://github.com/doowb/composer). Additional documentation can be found on those libaries.
|
199 |
|
200 | ### .task
|
201 |
|
202 | Register a task
|
203 |
|
204 | **Params**
|
205 |
|
206 | * `name` **{String}**: Task name to register (tasks are cached on `app.tasks`)
|
207 | * `dependencies` **{String|Array|Function}**: String, list or array of tasks.
|
208 | * `callback` **{Function}**: Function to be called when the task is executed. Task functions should either return a stream or call the callback to let [composer](https://github.com/doowb/composer) know when the task is finished.
|
209 |
|
210 | **Examples**
|
211 |
|
212 | Register a task.
|
213 |
|
214 | ```js
|
215 | app.task('default', function() {
|
216 | // return the stream to signal "done"
|
217 | return app.src('pages/*.hbs')
|
218 | .pipe(app.dest('dist'));
|
219 | });
|
220 | ```
|
221 |
|
222 | Register a task with dependencies (other tasks to run before executing the task):
|
223 |
|
224 | ```js
|
225 | app.task('site', ['styles'], function() {
|
226 | return app.src('pages/*.hbs')
|
227 | .pipe(app.dest('dist'));
|
228 | });
|
229 |
|
230 | app.task('default', ['site']);
|
231 | ```
|
232 |
|
233 | **Get a task**
|
234 |
|
235 | ```js
|
236 | var task = app.task('site');
|
237 | ```
|
238 |
|
239 | ### .build
|
240 |
|
241 | Run a task or array of tasks.
|
242 |
|
243 | **Example**
|
244 |
|
245 | ```js
|
246 | app.build('default', function(err, results) {
|
247 | if (err) {
|
248 | console.error(err);
|
249 | return;
|
250 | }
|
251 | console.log(results);
|
252 | });
|
253 | ```
|
254 |
|
255 | ### .series
|
256 |
|
257 | Compose task or list of tasks into a single function that runs the tasks in series.
|
258 |
|
259 | **Params**
|
260 |
|
261 | * `tasks` **{String|Array|Function}**: List of tasks by name, function, or array of names/functions.
|
262 | * `returns` **{Function}**: Composed function that may take a callback function.
|
263 |
|
264 | **Example**
|
265 |
|
266 | ```js
|
267 | app.task('foo', function(cb) {
|
268 | console.log('this is foo');
|
269 | cb();
|
270 | });
|
271 |
|
272 | var fn = app.series('foo', function(cb) {
|
273 | console.log('this is bar');
|
274 | cb();
|
275 | });
|
276 |
|
277 | fn(function(err) {
|
278 | if (err) return console.error(err);
|
279 | console.log('finished');
|
280 | });
|
281 | //=> this is foo
|
282 | //=> this is bar
|
283 | //=> finished
|
284 | ```
|
285 |
|
286 | ### .parallel
|
287 |
|
288 | Compose task or list of tasks into a single function that runs the tasks in parallel.
|
289 |
|
290 | **Params**
|
291 |
|
292 | * `tasks` **{String|Array|Function}**: List of tasks by name, function, or array of names/functions.
|
293 | * `returns` **{Function}**: Composed function that may take a callback function.
|
294 |
|
295 | **Example**
|
296 |
|
297 | ```js
|
298 | app.task('foo', function(cb) {
|
299 | setTimeout(function() {
|
300 | console.log('this is foo');
|
301 | cb();
|
302 | }, 500);
|
303 | });
|
304 |
|
305 | var fn = app.parallel('foo', function(cb) {
|
306 | console.log('this is bar');
|
307 | cb();
|
308 | });
|
309 |
|
310 | fn(function(err) {
|
311 | if (err) return console.error(err);
|
312 | console.log('finished');
|
313 | });
|
314 | //=> this is bar
|
315 | //=> this is foo
|
316 | //=> finished
|
317 | ```
|
318 |
|
319 | ## Events
|
320 |
|
321 | The following events are emitted by [composer](https://github.com/doowb/composer). See the composer docs for more details
|
322 |
|
323 | ### starting
|
324 |
|
325 | Emitted when a `build` is starting.
|
326 |
|
327 | ```js
|
328 | app.on('starting', function(app, build) {});
|
329 | ```
|
330 |
|
331 | The event emits 2 arguments:
|
332 |
|
333 | 1. the current instance of [composer](https://github.com/doowb/composer) as the `app` and
|
334 | 2. An object with `build` runtime information:
|
335 |
|
336 | * `.date`: an object with the `.start` time as a `Date` object.
|
337 | * `.hr`: an object with the `.start` time as an `hrtime` array.
|
338 |
|
339 | ### finished
|
340 |
|
341 | Emitted when a `build` is finished.
|
342 |
|
343 | ```js
|
344 | app.on('finished', function(app, build) {});
|
345 | ```
|
346 |
|
347 | The event emits 2 arguments:
|
348 |
|
349 | 1. `app`: instance of [composer](https://github.com/doowb/composer)
|
350 | 2. `build`: an object with build runtime information:
|
351 |
|
352 | * `.date`: object with `.start` and `.end` properties, with staring and ending times of the build as `Date` objects.
|
353 | * `.hr`: object with `.start`, `.end`, `.duration`, and `.diff` properties with timing information calculated using `process.hrtime`
|
354 |
|
355 | ### error
|
356 |
|
357 | Emitted when an error occurrs during a `build`.
|
358 |
|
359 | ```js
|
360 | app.on('error', function(err) {});
|
361 | ```
|
362 |
|
363 | ### task:starting
|
364 |
|
365 | Emitted when a task is starting.
|
366 |
|
367 | ```js
|
368 | app.on('task:starting', function(task, run) {});
|
369 | ```
|
370 |
|
371 | ### task:finished
|
372 |
|
373 | Emitted when a task has finished.
|
374 |
|
375 | ```js
|
376 | app.on('task:finished', function(task, run) {});
|
377 | ```
|
378 |
|
379 | ### task:error
|
380 |
|
381 | Emitted when an error occurrs while running a task.
|
382 |
|
383 | ```js
|
384 | app.on('task:error', function(err) {});
|
385 | ```
|
386 |
|
387 | ### .dataLoader
|
388 |
|
389 | Register a data loader for loading data onto `app.cache.data`.
|
390 |
|
391 | **Params**
|
392 |
|
393 | * `ext` **{String}**: The file extension for to match to the loader
|
394 | * `fn` **{Function}**: The loader function.
|
395 |
|
396 | **Example**
|
397 |
|
398 | ```js
|
399 | var yaml = require('js-yaml');
|
400 |
|
401 | app.dataLoader('yml', function(str, fp) {
|
402 | return yaml.safeLoad(str);
|
403 | });
|
404 |
|
405 | app.data('foo.yml');
|
406 | //=> loads and parses `foo.yml` as yaml
|
407 | ```
|
408 |
|
409 | ## Plugin API
|
410 |
|
411 | ### .use
|
412 |
|
413 | Define a plugin function to be called immediately upon init. The only parameter exposed to the plugin is the application instance.
|
414 |
|
415 | Also, if a plugin returns a function, the function will be pushed
|
416 | onto the `fns` array, allowing the plugin to be called at a
|
417 | later point, elsewhere in the application.
|
418 |
|
419 | **Params**
|
420 |
|
421 | * `fn` **{Function}**: plugin function to call
|
422 | * `returns` **{Object}**: Returns the item instance for chaining.
|
423 |
|
424 | **Example**
|
425 |
|
426 | ```js
|
427 | // define a plugin
|
428 | function foo(app) {
|
429 | // do stuff
|
430 | }
|
431 |
|
432 | // register plugins
|
433 | var app = new Base()
|
434 | .use(foo)
|
435 | .use(bar)
|
436 | .use(baz)
|
437 | ```
|
438 |
|
439 | ### .run
|
440 |
|
441 | Run all plugins
|
442 |
|
443 | **Params**
|
444 |
|
445 | * `value` **{Object}**: Object to be modified by plugins.
|
446 | * `returns` **{Object}**: Returns the item instance for chaining.
|
447 |
|
448 | **Example**
|
449 |
|
450 | ```js
|
451 | var config = {};
|
452 | app.run(config);
|
453 | ```
|
454 |
|
455 | ## Options API
|
456 |
|
457 | ### .option
|
458 |
|
459 | Set or get an option.
|
460 |
|
461 | **Params**
|
462 |
|
463 | * `key` **{String}**: The option name.
|
464 | * `value` **{any}**: The value to set.
|
465 | * `returns` **{any}**: Returns a `value` when only `key` is defined.
|
466 |
|
467 | **Example**
|
468 |
|
469 | ```js
|
470 | app.option('a', true);
|
471 | app.option('a');
|
472 | //=> true
|
473 | ```
|
474 |
|
475 | ### .hasOption
|
476 |
|
477 | Return true if `options.hasOwnProperty(key)`
|
478 |
|
479 | **Params**
|
480 |
|
481 | * `prop` **{String}**
|
482 | * `returns` **{Boolean}**: True if `prop` exists.
|
483 |
|
484 | **Example**
|
485 |
|
486 | ```js
|
487 | app.hasOption('a');
|
488 | //=> false
|
489 | app.option('a', 'b');
|
490 | app.hasOption('a');
|
491 | //=> true
|
492 | ```
|
493 |
|
494 | ### .enable
|
495 |
|
496 | Enable `key`.
|
497 |
|
498 | **Params**
|
499 |
|
500 | * `key` **{String}**
|
501 | * `returns` **{Object}** `Options`: to enable chaining
|
502 |
|
503 | **Example**
|
504 |
|
505 | ```js
|
506 | app.enable('a');
|
507 | ```
|
508 |
|
509 | ### .disable
|
510 |
|
511 | Disable `key`.
|
512 |
|
513 | **Params**
|
514 |
|
515 | * `key` **{String}**: The option to disable.
|
516 | * `returns` **{Object}** `Options`: to enable chaining
|
517 |
|
518 | **Example**
|
519 |
|
520 | ```js
|
521 | app.disable('a');
|
522 | ```
|
523 |
|
524 | ### .enabled
|
525 |
|
526 | Check if `prop` is enabled (truthy).
|
527 |
|
528 | **Params**
|
529 |
|
530 | * `prop` **{String}**
|
531 | * `returns` **{Boolean}**
|
532 |
|
533 | **Example**
|
534 |
|
535 | ```js
|
536 | app.enabled('a');
|
537 | //=> false
|
538 |
|
539 | app.enable('a');
|
540 | app.enabled('a');
|
541 | //=> true
|
542 | ```
|
543 |
|
544 | ### .disabled
|
545 |
|
546 | Check if `prop` is disabled (falsey).
|
547 |
|
548 | **Params**
|
549 |
|
550 | * `prop` **{String}**
|
551 | * `returns` **{Boolean}**: Returns true if `prop` is disabled.
|
552 |
|
553 | **Example**
|
554 |
|
555 | ```js
|
556 | app.disabled('a');
|
557 | //=> true
|
558 |
|
559 | app.enable('a');
|
560 | app.disabled('a');
|
561 | //=> false
|
562 | ```
|
563 |
|
564 | ### .isTrue
|
565 |
|
566 | Returns true if the value of `prop` is strictly `true`.
|
567 |
|
568 | **Params**
|
569 |
|
570 | * `prop` **{String}**
|
571 | * `returns` **{Boolean}**: Uses strict equality for comparison.
|
572 |
|
573 | **Example**
|
574 |
|
575 | ```js
|
576 | app.option('a', 'b');
|
577 | app.isTrue('a');
|
578 | //=> false
|
579 |
|
580 | app.option('c', true);
|
581 | app.isTrue('c');
|
582 | //=> true
|
583 |
|
584 | app.option({a: {b: {c: true}}});
|
585 | app.isTrue('a.b.c');
|
586 | //=> true
|
587 | ```
|
588 |
|
589 | ### .isFalse
|
590 |
|
591 | Returns true if the value of `key` is strictly `false`.
|
592 |
|
593 | **Params**
|
594 |
|
595 | * `prop` **{String}**
|
596 | * `returns` **{Boolean}**: Uses strict equality for comparison.
|
597 |
|
598 | **Example**
|
599 |
|
600 | ```js
|
601 | app.option('a', null);
|
602 | app.isFalse('a');
|
603 | //=> false
|
604 |
|
605 | app.option('c', false);
|
606 | app.isFalse('c');
|
607 | //=> true
|
608 |
|
609 | app.option({a: {b: {c: false}}});
|
610 | app.isFalse('a.b.c');
|
611 | //=> true
|
612 | ```
|
613 |
|
614 | ### .isBoolean
|
615 |
|
616 | Return true if the value of key is either `true` or `false`.
|
617 |
|
618 | **Params**
|
619 |
|
620 | * `key` **{String}**
|
621 | * `returns` **{Boolean}**: True if `true` or `false`.
|
622 |
|
623 | **Example**
|
624 |
|
625 | ```js
|
626 | app.option('a', 'b');
|
627 | app.isBoolean('a');
|
628 | //=> false
|
629 |
|
630 | app.option('c', true);
|
631 | app.isBoolean('c');
|
632 | //=> true
|
633 | ```
|
634 |
|
635 | ### .option.set
|
636 |
|
637 | Set option `key` on `app.options` with the given `value`
|
638 |
|
639 | **Params**
|
640 |
|
641 | * `key` **{String}**: Option key, dot-notation may be used.
|
642 | * `value` **{any}**
|
643 |
|
644 | **Example**
|
645 |
|
646 | ```js
|
647 | app.option.set('a', 'b');
|
648 | console.log(app.option.get('a'));
|
649 | //=> 'b'
|
650 | ```
|
651 |
|
652 | ### .option.get
|
653 |
|
654 | Get option `key` from `app.options`
|
655 |
|
656 | **Params**
|
657 |
|
658 | * `key` **{String}**: Option key, dot-notation may be used.
|
659 | * `returns` **{any}**
|
660 |
|
661 | **Example**
|
662 |
|
663 | ```js
|
664 | app.option({a: 'b'});
|
665 | console.log(app.option.get('a'));
|
666 | //=> 'b'
|
667 | ```
|
668 |
|
669 | ### .option.create
|
670 |
|
671 | Returns a shallow clone of `app.options` with all of the options methods, as well as a `.merge` method for merging options onto the cloned object.
|
672 |
|
673 | **Params**
|
674 |
|
675 | * `options` **{Options}**: Object to merge onto the returned options object.
|
676 | * `returns` **{Object}**
|
677 |
|
678 | **Example**
|
679 |
|
680 | ```js
|
681 | var opts = app.option.create();
|
682 | opts.merge({foo: 'bar'});
|
683 | ```
|
684 |
|
685 | ## Data API
|
686 |
|
687 | ### .data
|
688 |
|
689 | Load data onto `app.cache.data`
|
690 |
|
691 | **Params**
|
692 |
|
693 | * `key` **{String|Object}**: Key of the value to set, or object to extend.
|
694 | * `val` **{any}**
|
695 | * `returns` **{Object}**: Returns the instance of `Template` for chaining
|
696 |
|
697 | **Example**
|
698 |
|
699 | ```js
|
700 | console.log(app.cache.data);
|
701 | //=> {};
|
702 |
|
703 | app.data('a', 'b');
|
704 | app.data({c: 'd'});
|
705 | console.log(app.cache.data);
|
706 | //=> {a: 'b', c: 'd'}
|
707 |
|
708 | // set an array
|
709 | app.data('e', ['f']);
|
710 |
|
711 | // overwrite the array
|
712 | app.data('e', ['g']);
|
713 |
|
714 | // update the array
|
715 | app.data('e', ['h'], true);
|
716 | console.log(app.cache.data.e);
|
717 | //=> ['g', 'h']
|
718 | ```
|
719 |
|
720 | ### .data.extend
|
721 |
|
722 | Shallow extend an object onto `app.cache.data`.
|
723 |
|
724 | **Params**
|
725 |
|
726 | * `key` **{String|Object}**: Property name or object to extend onto `app.cache.data`. Dot-notation may be used for extending nested properties.
|
727 | * `value` **{Object}**: The object to extend onto `app.cache.data`
|
728 | * `returns` **{Object}**: returns the instance for chaining
|
729 |
|
730 | **Example**
|
731 |
|
732 | ```js
|
733 | app.data({a: {b: {c: 'd'}}});
|
734 | app.data.extend('a.b', {x: 'y'});
|
735 | console.log(app.get('a.b'));
|
736 | //=> {c: 'd', x: 'y'}
|
737 | ```
|
738 |
|
739 | ### .data.merge
|
740 |
|
741 | Deeply merge an object onto `app.cache.data`.
|
742 |
|
743 | **Params**
|
744 |
|
745 | * `key` **{String|Object}**: Property name or object to merge onto `app.cache.data`. Dot-notation may be used for merging nested properties.
|
746 | * `value` **{Object}**: The object to merge onto `app.cache.data`
|
747 | * `returns` **{Object}**: returns the instance for chaining
|
748 |
|
749 | **Example**
|
750 |
|
751 | ```js
|
752 | app.data({a: {b: {c: {d: {e: 'f'}}}}});
|
753 | app.data.merge('a.b', {c: {d: {g: 'h'}}});
|
754 | console.log(app.get('a.b'));
|
755 | //=> {c: {d: {e: 'f', g: 'h'}}}
|
756 | ```
|
757 |
|
758 | ### .data.union
|
759 |
|
760 | Union the given value onto a new or existing array value on `app.cache.data`.
|
761 |
|
762 | **Params**
|
763 |
|
764 | * `key` **{String}**: Property name. Dot-notation may be used for nested properties.
|
765 | * `array` **{Object}**: The array to add or union on `app.cache.data`
|
766 | * `returns` **{Object}**: returns the instance for chaining
|
767 |
|
768 | **Example**
|
769 |
|
770 | ```js
|
771 | app.data({a: {b: ['c', 'd']}});
|
772 | app.data.union('a.b', ['e', 'f']}});
|
773 | console.log(app.get('a.b'));
|
774 | //=> ['c', 'd', 'e', 'f']
|
775 | ```
|
776 |
|
777 | ### .data.set
|
778 |
|
779 | Set the given value onto `app.cache.data`.
|
780 |
|
781 | **Params**
|
782 |
|
783 | * `key` **{String|Object}**: Property name or object to merge onto `app.cache.data`. Dot-notation may be used for nested properties.
|
784 | * `val` **{any}**: The value to set on `app.cache.data`
|
785 | * `returns` **{Object}**: returns the instance for chaining
|
786 |
|
787 | **Example**
|
788 |
|
789 | ```js
|
790 | app.data.set('a.b', ['c', 'd']}});
|
791 | console.log(app.get('a'));
|
792 | //=> {b: ['c', 'd']}
|
793 | ```
|
794 |
|
795 | ### .data.get
|
796 |
|
797 | Get the value of `key` from `app.cache.data`. Dot-notation may be used for getting nested properties.
|
798 |
|
799 | **Params**
|
800 |
|
801 | * `key` **{String}**: The name of the property to get.
|
802 | * `returns` **{any}**: Returns the value of `key`
|
803 |
|
804 | **Example**
|
805 |
|
806 | ```js
|
807 | app.data({a: {b: {c: 'd'}}});
|
808 | console.log(app.get('a.b'));
|
809 | //=> {c: 'd'}
|
810 | ```
|
811 |
|
812 | ### Glob patterns
|
813 |
|
814 | Glob patterns may be passed as a string or array. All of these work:
|
815 |
|
816 | ```js
|
817 | app.data('foo.json');
|
818 | app.data('*.json');
|
819 | app.data(['*.json']);
|
820 | // pass options to node-glob
|
821 | app.data(['*.json'], {dot: true});
|
822 | ```
|
823 |
|
824 | ### Namespacing
|
825 |
|
826 | Namespacing allows you to load data onto a specific key, optionally using part of the file path as the key.
|
827 |
|
828 | **Example**
|
829 |
|
830 | Given that `foo.json` contains `{a: 'b'}`:
|
831 |
|
832 | ```js
|
833 | app.data('foo.json');
|
834 | console.log(app.cache.data);
|
835 | //=> {a: 'b'}
|
836 |
|
837 | app.data('foo.json', {namespace: true});
|
838 | console.log(app.cache.data);
|
839 | //=> {foo: {a: 'b'}}
|
840 |
|
841 | app.data('foo.json', {
|
842 | namespace: function(fp) {
|
843 | return path.basename(fp);
|
844 | }
|
845 | });
|
846 | console.log(app.cache.data);
|
847 | //=> {'foo.json': {a: 'b'}}
|
848 | ```
|
849 |
|
850 | ## About
|
851 |
|
852 | <details>
|
853 | <summary><strong>Contributing</strong></summary>
|
854 |
|
855 | Pull requests and stars are always welcome. For bugs and feature requests, [please create an issue](../../issues/new).
|
856 |
|
857 | </details>
|
858 |
|
859 | <details>
|
860 | <summary><strong>Running Tests</strong></summary>
|
861 |
|
862 | Running and reviewing unit tests is a great way to get familiarized with a library and its API. You can install dependencies and run tests with the following command:
|
863 |
|
864 | ```sh
|
865 | $ npm install && npm test
|
866 | ```
|
867 |
|
868 | </details>
|
869 |
|
870 | <details>
|
871 | <summary><strong>Building docs</strong></summary>
|
872 |
|
873 | _(This project's readme.md is generated by [verb](https://github.com/verbose/verb-generate-readme), please don't edit the readme directly. Any changes to the readme must be made in the [.verb.md](.verb.md) readme template.)_
|
874 |
|
875 | To generate the readme, run the following command:
|
876 |
|
877 | ```sh
|
878 | $ npm install -g verbose/verb#dev verb-generate-readme && verb
|
879 | ```
|
880 |
|
881 | </details>
|
882 |
|
883 | ### Related projects
|
884 |
|
885 | You might also be interested in these projects:
|
886 |
|
887 | * [base-fs](https://www.npmjs.com/package/base-fs): base-methods plugin that adds vinyl-fs methods to your 'base' application for working with the file… [more](https://github.com/node-base/base-fs) | [homepage](https://github.com/node-base/base-fs "base-methods plugin that adds vinyl-fs methods to your 'base' application for working with the file system, like src, dest, copy and symlink.")
|
888 | * [base-pipeline](https://www.npmjs.com/package/base-pipeline): base-methods plugin that adds pipeline and plugin methods for dynamically composing streaming plugin pipelines. | [homepage](https://github.com/node-base/base-pipeline "base-methods plugin that adds pipeline and plugin methods for dynamically composing streaming plugin pipelines.")
|
889 | * [base](https://www.npmjs.com/package/base): Framework for rapidly creating high quality, server-side node.js applications, using plugins like building blocks | [homepage](https://github.com/node-base/base "Framework for rapidly creating high quality, server-side node.js applications, using plugins like building blocks")
|
890 |
|
891 | ### Author
|
892 |
|
893 | **Jon Schlinkert**
|
894 |
|
895 | * [LinkedIn Profile](https://linkedin.com/in/jonschlinkert)
|
896 | * [GitHub Profile](https://github.com/jonschlinkert)
|
897 | * [Twitter Profile](https://twitter.com/jonschlinkert)
|
898 |
|
899 | ### License
|
900 |
|
901 | Copyright © 2018, [Jon Schlinkert](https://github.com/jonschlinkert).
|
902 | Released under the [MIT License](LICENSE).
|
903 |
|
904 | ***
|
905 |
|
906 | _This file was generated by [verb-generate-readme](https://github.com/verbose/verb-generate-readme), v0.6.0, on April 13, 2018._ |
\ | No newline at end of file |