]> gerrit.simantics Code Review - simantics/district.git/blob - org.simantics.maps.server/node/node-v4.8.0-win-x64/node_modules/npm/node_modules/init-package-json/node_modules/promzard/README.md
Adding integrated tile server
[simantics/district.git] / org.simantics.maps.server / node / node-v4.8.0-win-x64 / node_modules / npm / node_modules / init-package-json / node_modules / promzard / README.md
1 # promzard
2
3 A prompting wizard for building files from specialized PromZard modules.
4 Used by `npm init`.
5
6 A reimplementation of @SubStack's
7 [prompter](https://github.com/substack/node-prompter), which does not
8 use AST traversal.
9
10 From another point of view, it's a reimplementation of
11 [@Marak](https://github.com/marak)'s
12 [wizard](https://github.com/Marak/wizard) which doesn't use schemas.
13
14 The goal is a nice drop-in enhancement for `npm init`.
15
16 ## Usage
17
18 ```javascript
19 var promzard = require('promzard')
20 promzard(inputFile, optionalContextAdditions, function (er, data) {
21   // .. you know what you doing ..
22 })
23 ```
24
25 In the `inputFile` you can have something like this:
26
27 ```javascript
28 var fs = require('fs')
29 module.exports = {
30   "greeting": prompt("Who shall you greet?", "world", function (who) {
31     return "Hello, " + who
32   }),
33   "filename": __filename,
34   "directory": function (cb) {
35     fs.readdir(__dirname, cb)
36   }
37 }
38 ```
39
40 When run, promzard will display the prompts and resolve the async
41 functions in order, and then either give you an error, or the resolved
42 data, ready to be dropped into a JSON file or some other place.
43
44
45 ### promzard(inputFile, ctx, callback)
46
47 The inputFile is just a node module.  You can require() things, set
48 module.exports, etc.  Whatever that module exports is the result, and it
49 is walked over to call any functions as described below.
50
51 The only caveat is that you must give PromZard the full absolute path
52 to the module (you can get this via Node's `require.resolve`.)  Also,
53 the `prompt` function is injected into the context object, so watch out.
54
55 Whatever you put in that `ctx` will of course also be available in the
56 module.  You can get quite fancy with this, passing in existing configs
57 and so on.
58
59 ### Class: promzard.PromZard(file, ctx)
60
61 Just like the `promzard` function, but the EventEmitter that makes it
62 all happen.  Emits either a `data` event with the data, or a `error`
63 event if it blows up.
64
65 If `error` is emitted, then `data` never will be.
66
67 ### prompt(...)
68
69 In the promzard input module, you can call the `prompt` function.
70 This prompts the user to input some data.  The arguments are interpreted
71 based on type:
72
73 1. `string`  The first string encountered is the prompt.  The second is
74    the default value.
75 2. `function` A transformer function which receives the data and returns
76    something else.  More than meets the eye.
77 3. `object` The `prompt` member is the prompt, the `default` member is
78    the default value, and the `transform` is the transformer.
79
80 Whatever the final value is, that's what will be put on the resulting
81 object.
82
83 ### Functions
84
85 If there are any functions on the promzard input module's exports, then
86 promzard will call each of them with a callback.  This way, your module
87 can do asynchronous actions if necessary to validate or ascertain
88 whatever needs verification.
89
90 The functions are called in the context of the ctx object, and are given
91 a single argument, which is a callback that should be called with either
92 an error, or the result to assign to that spot.
93
94 In the async function, you can also call prompt() and return the result
95 of the prompt in the callback.
96
97 For example, this works fine in a promzard module:
98
99 ```
100 exports.asyncPrompt = function (cb) {
101   fs.stat(someFile, function (er, st) {
102     // if there's an error, no prompt, just error
103     // otherwise prompt and use the actual file size as the default
104     cb(er, prompt('file size', st.size))
105   })
106 }
107 ```
108
109 You can also return other async functions in the async function
110 callback.  Though that's a bit silly, it could be a handy way to reuse
111 functionality in some cases.
112
113 ### Sync vs Async
114
115 The `prompt()` function is not synchronous, though it appears that way.
116 It just returns a token that is swapped out when the data object is
117 walked over asynchronously later, and returns a token.
118
119 For that reason, prompt() calls whose results don't end up on the data
120 object are never shown to the user.  For example, this will only prompt
121 once:
122
123 ```
124 exports.promptThreeTimes = prompt('prompt me once', 'shame on you')
125 exports.promptThreeTimes = prompt('prompt me twice', 'um....')
126 exports.promptThreeTimes = prompt('you cant prompt me again')
127 ```
128
129 ### Isn't this exactly the sort of 'looks sync' that you said was bad about other libraries?
130
131 Yeah, sorta.  I wouldn't use promzard for anything more complicated than
132 a wizard that spits out prompts to set up a config file or something.
133 Maybe there are other use cases I haven't considered.