]> 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/promzard.js
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 / promzard.js
1 module.exports = promzard
2 promzard.PromZard = PromZard
3
4 var fs = require('fs')
5 var vm = require('vm')
6 var util = require('util')
7 var files = {}
8 var crypto = require('crypto')
9 var EventEmitter = require('events').EventEmitter
10 var read = require('read')
11
12 var Module = require('module').Module
13 var path = require('path')
14
15 function promzard (file, ctx, cb) {
16   if (typeof ctx === 'function') cb = ctx, ctx = null;
17   if (!ctx) ctx = {};
18   var pz = new PromZard(file, ctx)
19   pz.on('error', cb)
20   pz.on('data', function (data) {
21     cb(null, data)
22   })
23 }
24 promzard.fromBuffer = function (buf, ctx, cb) {
25   var filename = 0
26   do {
27     filename = '\0' + Math.random();
28   } while (files[filename])
29   files[filename] = buf
30   var ret = promzard(filename, ctx, cb)
31   delete files[filename]
32   return ret
33 }
34
35 function PromZard (file, ctx) {
36   if (!(this instanceof PromZard))
37     return new PromZard(file, ctx)
38   EventEmitter.call(this)
39   this.file = file
40   this.ctx = ctx
41   this.unique = crypto.randomBytes(8).toString('hex')
42   this.load()
43 }
44
45 PromZard.prototype = Object.create(
46   EventEmitter.prototype,
47   { constructor: {
48       value: PromZard,
49       readable: true,
50       configurable: true,
51       writable: true,
52       enumerable: false } } )
53
54 PromZard.prototype.load = function () {
55   if (files[this.file])
56     return this.loaded()
57
58   fs.readFile(this.file, 'utf8', function (er, d) {
59     if (er && this.backupFile) {
60       this.file = this.backupFile
61       delete this.backupFile
62       return this.load()
63     }
64     if (er)
65       return this.emit('error', this.error = er)
66     files[this.file] = d
67     this.loaded()
68   }.bind(this))
69 }
70
71 PromZard.prototype.loaded = function () {
72   this.ctx.prompt = this.makePrompt()
73   this.ctx.__filename = this.file
74   this.ctx.__dirname = path.dirname(this.file)
75   this.ctx.__basename = path.basename(this.file)
76   var mod = this.ctx.module = this.makeModule()
77   this.ctx.require = function (path) {
78     return mod.require(path)
79   }
80   this.ctx.require.resolve = function(path) {
81     return Module._resolveFilename(path, mod);
82   }
83   this.ctx.exports = mod.exports
84
85   this.script = this.wrap(files[this.file])
86   var fn = vm.runInThisContext(this.script, this.file)
87   var args = Object.keys(this.ctx).map(function (k) {
88     return this.ctx[k]
89   }.bind(this))
90   try { var res = fn.apply(this.ctx, args) }
91   catch (er) { this.emit('error', er) }
92   if (res &&
93       typeof res === 'object' &&
94       exports === mod.exports &&
95       Object.keys(exports).length === 1) {
96     this.result = res
97   } else {
98     this.result = mod.exports
99   }
100   this.walk()
101 }
102
103 PromZard.prototype.makeModule = function () {
104   var mod = new Module(this.file, module)
105   mod.loaded = true
106   mod.filename = this.file
107   mod.id = this.file
108   mod.paths = Module._nodeModulePaths(path.dirname(this.file))
109   return mod
110 }
111
112 PromZard.prototype.wrap = function (body) {
113   var s = '(function( %s ) { %s\n })'
114   var args = Object.keys(this.ctx).join(', ')
115   return util.format(s, args, body)
116 }
117
118 PromZard.prototype.makePrompt = function () {
119   this.prompts = []
120   return prompt.bind(this)
121   function prompt () {
122     var p, d, t
123     for (var i = 0; i < arguments.length; i++) {
124       var a = arguments[i]
125       if (typeof a === 'string' && p)
126         d = a
127       else if (typeof a === 'string')
128         p = a
129       else if (typeof a === 'function')
130         t = a
131       else if (a && typeof a === 'object') {
132         p = a.prompt || p
133         d = a.default || d
134         t = a.transform || t
135       }
136     }
137
138     try { return this.unique + '-' + this.prompts.length }
139     finally { this.prompts.push([p, d, t]) }
140   }
141 }
142
143 PromZard.prototype.walk = function (o, cb) {
144   o = o || this.result
145   cb = cb || function (er, res) {
146     if (er)
147       return this.emit('error', this.error = er)
148     this.result = res
149     return this.emit('data', res)
150   }
151   cb = cb.bind(this)
152   var keys = Object.keys(o)
153   var i = 0
154   var len = keys.length
155
156   L.call(this)
157   function L () {
158     if (this.error)
159       return
160     while (i < len) {
161       var k = keys[i]
162       var v = o[k]
163       i++
164
165       if (v && typeof v === 'object') {
166         return this.walk(v, function (er, res) {
167           if (er) return cb(er)
168           o[k] = res
169           L.call(this)
170         }.bind(this))
171       } else if (v &&
172                  typeof v === 'string' &&
173                  v.indexOf(this.unique) === 0) {
174         var n = +v.substr(this.unique.length + 1)
175         var prompt = this.prompts[n]
176         if (isNaN(n) || !prompt)
177           continue
178
179         // default to the key
180         if (undefined === prompt[0])
181           prompt[0] = k
182
183         // default to the ctx value, if there is one
184         if (undefined === prompt[1])
185           prompt[1] = this.ctx[k]
186
187         return this.prompt(prompt, function (er, res) {
188           if (er) {
189             if (!er.notValid) {
190               return this.emit('error', this.error = er);
191             }
192             console.log(er.message)
193             i --
194             return L.call(this)
195           }
196           o[k] = res
197           L.call(this)
198         }.bind(this))
199       } else if (typeof v === 'function') {
200         try { return v.call(this.ctx, function (er, res) {
201           if (er)
202             return this.emit('error', this.error = er)
203           o[k] = res
204           // back up so that we process this one again.
205           // this is because it might return a prompt() call in the cb.
206           i --
207           L.call(this)
208         }.bind(this)) }
209         catch (er) { this.emit('error', er) }
210       }
211     }
212     // made it to the end of the loop, maybe
213     if (i >= len)
214       return cb(null, o)
215   }
216 }
217
218 PromZard.prototype.prompt = function (pdt, cb) {
219   var prompt = pdt[0]
220   var def = pdt[1]
221   var tx = pdt[2]
222
223   if (tx) {
224     cb = function (cb) { return function (er, data) {
225       try {
226         var res = tx(data)
227         if (!er && res instanceof Error && !!res.notValid) {
228           return cb(res, null)
229         }
230         return cb(er, res)
231       }
232       catch (er) { this.emit('error', er) }
233     }}(cb).bind(this)
234   }
235
236   read({ prompt: prompt + ':' , default: def }, cb)
237 }
238