UNPKG

38.2 kBJavaScriptView Raw
1// Generated by CoffeeScript 1.10.0
2(function() {
3 var colors, crypto, crystal, cson, error, extend, findVersions, force, fs, generate, handlebars, imports, inject, loadModules, loadOutputs, loadProcessor, loadSchemaRefs, loaded_modules, merge, mkdirp, mustache, parse, path, processModules, readdir, request, season, semver, skeemas, sortObject, userHome, yaml;
4
5 crystal = {
6 load: require('./load')
7 };
8
9 colors = require('colors');
10
11 crypto = require('crypto');
12
13 cson = require('cson-parser');
14
15 extend = require('extend-combine');
16
17 findVersions = require('find-versions');
18
19 fs = require('fs');
20
21 error = require('../error');
22
23 handlebars = require('handlebars');
24
25 merge = require('merge');
26
27 mkdirp = require('mkdirp');
28
29 mustache = require('mustache');
30
31 path = require('path');
32
33 readdir = require('fs-readdir-recursive');
34
35 request = require('sync-request');
36
37 season = require('season');
38
39 semver = require('semver');
40
41 skeemas = require('skeemas');
42
43 userHome = require('user-home');
44
45 yaml = require('js-yaml');
46
47 force = false;
48
49 loaded_modules = {};
50
51 imports = {};
52
53 loadModules = function(modules, host) {
54 var engine, export_name, export_path, exported, exported_spec, helper, j, k, len, len1, model_ver, module_alias, module_config, module_name, module_path, module_version, module_version_query, module_versions, module_versions_path, processor, ref, schema, spec, template, transformer;
55 for (module_name in modules) {
56 module_version_query = modules[module_name];
57 if (module_version_query === 'latest') {
58 module_version = 'latest';
59 } else {
60 module_version = null;
61 if (module_version_query.match(/^(\.|\/)/)) {
62 module_versions_path = path.normalize(module_version_query);
63 if (fs.existsSync(module_versions_path)) {
64 module_version = module_version_query;
65 }
66 } else {
67 module_versions_path = path.normalize(userHome + "/.autocode/module/" + host + "/" + module_name);
68 if (fs.existsSync(module_versions_path)) {
69 module_versions = fs.readdirSync(module_versions_path);
70 for (j = 0, len = module_versions.length; j < len; j++) {
71 model_ver = module_versions[j];
72 model_ver = semver.clean(model_ver);
73 if (model_ver && semver.satisfies(model_ver, modules[module_name]) && (!module_version || semver.gt(model_ver, module_version))) {
74 module_version = model_ver;
75 }
76 }
77 }
78 }
79 }
80 if (!module_version) {
81 throw new Error("No matches for Module (" + module_name + ") with version (" + module_version_query + "). Try: autocode update");
82 }
83 module_alias = module_name.substr(module_name.lastIndexOf('/') + 1);
84 if (loaded_modules[module_name] && loaded_modules[module_name][module_version]) {
85 continue;
86 }
87 if (!loaded_modules[module_name]) {
88 loaded_modules[module_name] = {};
89 }
90 if (module_version_query.match(/^(\.|\/)/)) {
91 module_path = module_version_query;
92 } else {
93 module_path = userHome + "/.autocode/module/" + host + "/" + module_name + "/" + module_version;
94 }
95 if (!fs.existsSync(module_path)) {
96 throw new Error("Unknown module (" + module_name + ") at version (" + module_version + "). Try: autocode update");
97 }
98 module_config = crystal.load(module_path);
99 if (!module_config) {
100 throw new Error("Unable to load configuration for module (" + module_name + ")");
101 }
102 if (module_config.exports) {
103 for (export_name in module_config.exports) {
104 exported = module_config.exports[export_name];
105 module_config.exports[export_name].dir = module_path;
106 if (typeof exported.engine === 'string' && exported.engine.match(/\./)) {
107 export_path = module_path + "/.autocode/engine/" + exported.engine;
108 if (fs.existsSync(export_path)) {
109 engine = require(export_path);
110 } else {
111 engine = exported.engine;
112 }
113 module_config.exports[export_name].engine = engine;
114 }
115 if (typeof exported.helper === 'string' && exported.helper.match(/\./)) {
116 export_path = module_path + "/.autocode/helper/" + exported.helper;
117 if (fs.existsSync(export_path)) {
118 helper = require(export_path);
119 } else {
120 helper = exported.helper;
121 }
122 module_config.exports[export_name].helper = helper;
123 }
124 if (typeof exported.processor === 'string' && exported.processor.match(/\./)) {
125 export_path = module_path + "/.autocode/processor/" + exported.processor;
126 if (fs.existsSync(export_path)) {
127 processor = require(export_path);
128 } else {
129 processor = exported.processor;
130 }
131 module_config.exports[export_name].processor = processor;
132 }
133 if (typeof exported.schema === 'string' && exported.schema.match(/\./)) {
134 export_path = module_path + "/.autocode/schema/" + exported.schema;
135 if (fs.existsSync(export_path)) {
136 schema = yaml.safeLoad(fs.readFileSync(export_path));
137 } else {
138 schema = exported.schema;
139 }
140 module_config.exports[export_name].schema = schema;
141 }
142 if (exported.spec instanceof Array) {
143 spec = {};
144 ref = exported.spec;
145 for (k = 0, len1 = ref.length; k < len1; k++) {
146 exported_spec = ref[k];
147 export_path = module_path + "/.autocode/spec/" + exported_spec;
148 if (fs.existsSync(export_path)) {
149 exported_spec = yaml.safeLoad(fs.readFileSync(export_path));
150 } else {
151 exported_spec = exported_spec;
152 }
153 spec = extend(true, true, spec, exported_spec);
154 }
155 module_config.exports[export_name].spec = spec;
156 } else if (typeof exported.spec === 'string' && exported.spec.match(/\./)) {
157 if (exported.spec.match(/^https?:\/\//)) {
158 spec = request('get', exported.spec);
159 module_config.exports[export_name].spec = yaml.safeLoad(spec.body);
160 } else {
161 export_path = module_path + "/.autocode/spec/" + exported.spec;
162 if (fs.existsSync(export_path)) {
163 spec = yaml.safeLoad(fs.readFileSync(export_path));
164 } else {
165 spec = exported.spec;
166 }
167 module_config.exports[export_name].spec = spec;
168 }
169 }
170 if (typeof exported.template === 'string' && exported.template.match(/\./)) {
171 export_path = module_path + "/.autocode/template/" + exported.template;
172 if (fs.existsSync(export_path)) {
173 template = fs.readFileSync(export_path, 'utf8');
174 } else {
175 template = exported.template;
176 }
177 module_config.exports[export_name].template = template;
178 }
179 if (typeof exported.transformer === 'string' && exported.transformer.match(/\./)) {
180 export_path = module_path + "/.autocode/trans/" + exported.transformer;
181 if (fs.existsSync(export_path)) {
182 transformer = require(export_path);
183 } else {
184 transformer = exported.transformer;
185 }
186 module_config.exports[export_name].transformer = transformer;
187 }
188 }
189 }
190 loaded_modules[module_name][module_version] = module_config;
191 if (module_config.imports) {
192 loadModules(module_config.imports, module_config.host);
193 } else if (module_config.modules) {
194 loadModules(module_config.modules, module_config.host);
195 }
196 }
197 return loaded_modules = sortObject(loaded_modules);
198 };
199
200 processModules = function() {
201 var export_name, exported, helper, helper_name, helpers, loaded_module, model_ver, module_name, module_versions, results, submodule_alias, submodule_export, submodule_export_name, submodule_exports, submodule_name, submodule_version, submodule_version_query, submodule_versions, submodule_versions_path, submodules, test, test2, version_name;
202 results = [];
203 for (module_name in loaded_modules) {
204 module_versions = loaded_modules[module_name];
205 results.push((function() {
206 var j, len, results1;
207 results1 = [];
208 for (version_name in module_versions) {
209 loaded_module = module_versions[version_name];
210 submodules = {};
211 if (loaded_module.imports) {
212 loaded_module.modules = loaded_module.imports;
213 }
214 loaded_module.imports = {};
215 for (submodule_name in loaded_module.modules) {
216 submodule_alias = submodule_name.substr(submodule_name.lastIndexOf('/') + 1);
217 submodule_version_query = loaded_module.modules[submodule_name];
218 if (submodule_version_query === 'latest') {
219 submodule_version = 'latest';
220 } else {
221 submodule_version = null;
222 if (submodule_version_query.match(/^(\.|\/)/)) {
223 submodule_versions_path = path.normalize(submodule_version_query);
224 if (fs.existsSync(submodule_versions_path)) {
225 submodule_version = submodule_version_query;
226 }
227 } else {
228 submodule_versions_path = path.normalize(userHome + "/.autocode/module/" + loaded_module.host + "/" + submodule_name);
229 if (fs.existsSync(submodule_versions_path)) {
230 submodule_versions = fs.readdirSync(submodule_versions_path);
231 for (j = 0, len = submodule_versions.length; j < len; j++) {
232 model_ver = submodule_versions[j];
233 model_ver = semver.clean(model_ver);
234 if (model_ver && semver.satisfies(model_ver, submodule_version_query) && (!submodule_version || semver.gt(model_ver, submodule_version))) {
235 submodule_version = model_ver;
236 }
237 }
238 }
239 }
240 }
241 if (!submodule_version) {
242 throw new Error("No matches for submodule (" + submodule_name + ") with version (" + submodule_version_query + "). Try: autocode update");
243 }
244 submodule_exports = loaded_modules[submodule_name][submodule_version].exports;
245 for (submodule_export_name in submodule_exports) {
246 submodule_export = submodule_exports[submodule_export_name];
247 loaded_module.imports[submodule_alias + "." + submodule_export_name] = submodule_name + "." + submodule_export_name;
248 }
249 submodules[submodule_name] = submodule_version;
250 }
251 results1.push((function() {
252 var results2;
253 results2 = [];
254 for (export_name in loaded_module.exports) {
255 exported = loaded_module.exports[export_name];
256 if (exported.copy && typeof exported.copy.engine === 'string') {
257 test = loaded_module.imports[exported.copy.engine].split('.');
258 test2 = test.pop();
259 test = test.join('.');
260 loaded_modules[module_name][version_name].exports[export_name].copy.engine = loaded_modules[test][submodules[test]].exports[test2].engine;
261 }
262 if (exported.copy && exported.copy.dest && exported.copy.dest.engine && typeof exported.copy.dest.engine === 'string') {
263 test = loaded_module.imports[exported.copy.dest.engine].split('.');
264 test2 = test.pop();
265 test = test.join('.');
266 loaded_modules[module_name][version_name].exports[export_name].copy.dest.engine = loaded_modules[test][submodules[test]].exports[test2].engine;
267 }
268 if (typeof exported.engine === 'string' && loaded_module.imports[exported.engine]) {
269 test = loaded_module.imports[exported.engine].split('.');
270 test2 = test.pop();
271 test = test.join('.');
272 loaded_modules[module_name][version_name].exports[export_name].engine = loaded_modules[test][submodules[test]].exports[test2].engine;
273 }
274 if (exported.filename && typeof exported.filename.engine === 'string') {
275 if (!loaded_module.imports[exported.filename.engine]) {
276 throw new Error("Import does not exist for alias (" + exported.filename.engine + ")");
277 }
278 test = loaded_module.imports[exported.filename.engine].split('.');
279 test2 = test.pop();
280 test = test.join('.');
281 loaded_modules[module_name][version_name].exports[export_name].filename.engine = loaded_modules[test][submodules[test]].exports[test2].engine;
282 }
283 if (typeof exported.helper === 'object') {
284 helpers = [];
285 for (helper_name in exported.helper) {
286 helper = exported.helper[helper_name];
287 if (!loaded_module.imports[helper] && !loaded_module.exports[helper]) {
288 throw new Error("Import does not exist for alias (" + helper + ")");
289 }
290 if (loaded_module.exports[helper]) {
291 helpers.push({
292 callback: loaded_module.exports[helper].helper,
293 name: helper_name
294 });
295 } else {
296 test = loaded_module.imports[helper].split('.');
297 test2 = test.pop();
298 test = test.join('.');
299 helpers.push({
300 callback: loaded_modules[test][submodules[test]].exports[test2].helper,
301 name: helper_name
302 });
303 }
304 }
305 loaded_modules[module_name][version_name].exports[export_name].helper = helpers;
306 } else if (typeof exported.helper === 'string' && loaded_module.imports[exported.helper]) {
307 test = loaded_module.imports[exported.helper].split('.');
308 test2 = test.pop();
309 test = test.join('.');
310 if (!loaded_modules[test][submodules[test]].exports[test2]) {
311 throw new Error("Import (" + test2 + ") does not exist for module (" + test + ")");
312 }
313 loaded_modules[module_name][version_name].exports[export_name].helper = [
314 {
315 callback: loaded_modules[test][submodules[test]].exports[test2].helper,
316 name: loaded_modules[test][submodules[test]].exports[test2].name
317 }
318 ];
319 }
320 if (typeof exported.schema === 'string' && loaded_module.imports[exported.schema]) {
321 test = loaded_module.imports[exported.schema].split('.');
322 test2 = test.pop();
323 test = test.join('.');
324 loaded_modules[module_name][version_name].exports[export_name].schema = loaded_modules[test][submodules[test]].exports[test2].schema;
325 }
326 if (typeof exported.transformer === 'string' && loaded_module.imports[exported.transformer]) {
327 test = loaded_module.imports[exported.transformer].split('.');
328 test2 = test.pop();
329 test = test.join('.');
330 results2.push(loaded_modules[module_name][version_name].exports[export_name].transformer = loaded_modules[test][submodules[test]].exports[test2].transformer);
331 } else {
332 results2.push(void 0);
333 }
334 }
335 return results2;
336 })());
337 }
338 return results1;
339 })());
340 }
341 return results;
342 };
343
344 loadOutputs = function(outputs, imports, config) {
345 var cache, cache_checksum, cache_filename, code_dir, code_file, code_files, content, content_checksum, content_spec, copy_dest, copy_dir, copy_filename, copy_src, engine, file, file_checksum, file_last_path, file_name, filename, filename_checksum, filename_options, files, gen_schema, generator, generator_filename, generator_processor, helpers, i, injectors, iterator, j, k, l, len, len1, len2, len3, m, name, output, output_i, output_path, output_processor, output_spec, ref, ref1, ref2, results, spec, spec_filename, template, transformer, validate;
346 if (!imports) {
347 throw new Error('No imports available for output');
348 }
349 if (!(outputs instanceof Array)) {
350 outputs = sortObject(outputs);
351 }
352 results = [];
353 for (output_i in outputs) {
354 output = outputs[output_i];
355 if (!(outputs instanceof Array)) {
356 if (output.filename === true) {
357 delete output.filename;
358 } else if (output.filename && output.filename.engine && imports[output.filename.engine]) {
359 output.filename = {
360 engine: imports[output.filename.engine],
361 value: output_i
362 };
363 } else if (!output.filename) {
364 output.filename = output_i;
365 }
366 }
367 if (output.generator && !imports[output.generator]) {
368 throw new Error("Generator (" + output.generator + ") does not exist for output in config (" + config.name + ")");
369 }
370 generator = imports[output.generator] || {};
371 output_processor = output.processor;
372 generator_processor = generator.processor;
373 output_processor = loadProcessor(output_processor, generator_processor, imports);
374 spec = {};
375 if (output.spec) {
376 if (output.spec instanceof Array) {
377 ref = output.spec;
378 for (j = 0, len = ref.length; j < len; j++) {
379 output_spec = ref[j];
380 if (typeof output_spec === 'string') {
381 if (imports[output_spec]) {
382 output_processor = loadProcessor(imports[output_spec].processor, null, imports);
383 output_spec = imports[output_spec].spec;
384 } else if (output_spec.match(/^https?:\/\//)) {
385 output_spec = request('get', output_spec);
386 output_spec = yaml.safeLoad(spec.body);
387 } else {
388 spec_filename = ".autocode/spec/" + output_spec;
389 if (!fs.existsSync(spec_filename)) {
390 throw new Error("File (" + spec_filename + ") does not exist for spec in output for config (" + config.id + ")");
391 }
392 output_spec = yaml.safeLoad(fs.readFileSync(spec_filename, 'utf8'));
393 }
394 }
395 output_spec = parse(output_spec, config, output_processor);
396 spec = extend(true, true, spec, output_spec);
397 }
398 } else {
399 if (typeof output.spec === 'object') {
400 spec = output.spec;
401 } else if (typeof output.spec === 'string') {
402 if (imports[output.spec]) {
403 output_processor = loadProcessor(imports[output.spec].processor, null, imports);
404 spec = imports[output.spec].spec;
405 } else if (output.spec.match(/^https?:\/\//)) {
406 spec = request('get', output.spec);
407 spec = yaml.safeLoad(spec.body);
408 } else {
409 spec_filename = ".autocode/spec/" + output.spec;
410 if (!fs.existsSync(spec_filename)) {
411 throw new Error("File (" + spec_filename + ") does not exist for spec in output for config (" + config.id + ")");
412 }
413 spec = yaml.safeLoad(fs.readFileSync(spec_filename, 'utf8'));
414 }
415 }
416 spec = parse(spec, config, output_processor);
417 }
418 }
419 if (generator.schema) {
420 gen_schema = loadSchemaRefs(generator.schema);
421 validate = skeemas.validate(spec, gen_schema);
422 if (!validate.valid) {
423 console.log(validate.errors);
424 console.log("ERROR: Specification failed validation.");
425 ref1 = validate.errors;
426 for (k = 0, len1 = ref1.length; k < len1; k++) {
427 error = ref1[k];
428 console.log("- " + error.message + " for specification (" + (error.context.substr(2)) + ") in generator (" + output.generator + ")");
429 }
430 throw new Error("ERROR: Invalid specification.");
431 }
432 }
433 engine = output.engine || generator.engine;
434 if (typeof engine === 'string') {
435 if (!imports[engine] || !imports[engine].engine) {
436 throw new Error("Engine was not imported (" + engine + ") at path " + config.path);
437 }
438 engine = imports[engine].engine;
439 }
440 helpers = generator.helper ? generator.helper : null;
441 injectors = output.injector ? output.injector : null;
442 if (generator.copy) {
443 if (typeof generator.copy === 'object') {
444 if (!generator.copy.src) {
445 throw new Error("Copy requires source");
446 }
447 copy_src = generator.copy.src;
448 } else if (typeof generator.copy === 'string') {
449 copy_src = generator.copy;
450 } else {
451 throw new Error("Invalid value for copy");
452 }
453 if (generator.copy.dest) {
454 if (typeof generator.copy.dest === 'object') {
455 if (!generator.copy.dest.engine) {
456 throw new Error("Destination engine is required for copy");
457 }
458 if (!generator.copy.dest.value) {
459 throw new Error("Destination value is required for copy");
460 }
461 copy_dest = generator.copy.dest.engine(spec, generator.copy.dest.value, helpers);
462 } else if (typeof generator.copy.dest === 'string') {
463 copy_dest = generator.copy.dest;
464 } else {
465 throw new Error("Invalid Destination for copy");
466 }
467 if (copy_dest.substr(copy_dest.length - 1) !== '/') {
468 copy_dest += '/';
469 }
470 } else {
471 copy_dest = '';
472 }
473 copy_dir = generator.dir + "/.autocode/" + copy_src;
474 if (!fs.existsSync(copy_dir)) {
475 throw new Error("Directory (" + copy_dir + ") does not exist in copy");
476 }
477 code_files = readdir(copy_dir, function(x) {
478 return true;
479 });
480 for (l = 0, len2 = code_files.length; l < len2; l++) {
481 code_file = code_files[l];
482 copy_filename = output.path + "/" + copy_dest + code_file;
483 code_dir = copy_filename.substring(0, copy_filename.lastIndexOf('/') + 1);
484 if (!fs.existsSync(code_dir)) {
485 mkdirp.sync(code_dir);
486 }
487 fs.writeFileSync("" + copy_filename, fs.readFileSync(copy_dir + "/" + code_file));
488 console.log(("Generated file: " + copy_filename).green);
489 }
490 }
491 generator_filename = output.filename || generator.filename;
492 if (!generator_filename) {
493 continue;
494 }
495 iterator = output.iterator || generator.iterator;
496 if (iterator) {
497 if (!spec[iterator]) {
498 throw new Error("Iterator (" + iterator + ") not found in spec for generator (" + generator + ") in config (" + config.id + ")");
499 }
500 files = [];
501 if (spec[iterator] instanceof Array) {
502 ref2 = spec[iterator];
503 for (m = 0, len3 = ref2.length; m < len3; m++) {
504 file = ref2[m];
505 files.push(file);
506 }
507 } else if (typeof spec[iterator] === 'object') {
508 for (name in spec[iterator]) {
509 files.push(name);
510 }
511 }
512 } else {
513 files = [generator_filename];
514 }
515 results.push((function() {
516 var results1;
517 results1 = [];
518 for (i in files) {
519 file = files[i];
520 if (file.name) {
521 filename_options = {
522 name: file.name
523 };
524 file = file.name;
525 } else {
526 filename_options = [];
527 filename_options[0] = {};
528 filename_options[0][file] = spec;
529 file_name = null;
530 }
531 if (generator_filename.engine) {
532 filename = generator_filename.engine(filename_options, generator_filename.value, helpers);
533 } else {
534 filename = generator_filename;
535 }
536 if (output.path) {
537 if (!fs.existsSync(output.path)) {
538 mkdirp(output.path);
539 }
540 filename = output.path + "/" + filename;
541 }
542 if (!spec) {
543 throw new Error("Spec is required.");
544 }
545 if (output.template) {
546 output_path = ".autocode/template/" + output.template;
547 if (fs.existsSync(output_path)) {
548 template = fs.readFileSync(output_path, 'utf8');
549 } else {
550 template = output.template;
551 }
552 } else {
553 template = generator.template;
554 }
555 if (engine) {
556 if (iterator) {
557 content_spec = extend(true, true, {}, spec[iterator][i] || spec[iterator][file]);
558 if (content_spec) {
559 content_spec = extend(true, true, content_spec, spec);
560 content_spec.name = file;
561 }
562 if (content_spec && content_spec[iterator] && content_spec[iterator][file] && content_spec[iterator][file]['$injector']) {
563 template = inject(template, injectors, false);
564 template = inject(template, content_spec[iterator][file]['$injector'], false);
565 template = inject(template, null, true);
566 } else {
567 template = inject(template, injectors, true);
568 }
569 content = engine(content_spec, template, helpers);
570 } else {
571 if (template) {
572 template = inject(template, injectors, true);
573 }
574 content = engine(spec, template, helpers);
575 }
576 } else if (template) {
577 template = inject(template, injectors, true);
578 content = template;
579 } else if (spec) {
580 content = spec;
581 } else {
582 content = "";
583 }
584 transformer = output.transformer || generator.transformer;
585 if (transformer) {
586 if (typeof transformer === 'string') {
587 if (!imports[transformer]) {
588 throw new Error("Transformer " + transformer + " does not exist");
589 }
590 transformer = imports[transformer].transformer;
591 }
592 content = transformer(content);
593 } else if (typeof content === 'object') {
594 content = "";
595 }
596 cache_filename = ".autocode/cache.yml";
597 if (fs.existsSync(cache_filename)) {
598 cache = yaml.safeLoad(fs.readFileSync(cache_filename, 'utf8'));
599 if (!cache.checksum) {
600 cache.checksum = {};
601 }
602 } else {
603 cache = {
604 checksum: {}
605 };
606 }
607 filename_checksum = crypto.createHash('md5').update(filename, 'utf8').digest('hex');
608 if (cache.checksum[filename_checksum]) {
609 if (!fs.existsSync(filename)) {
610 if (force !== true) {
611 throw new Error(("ERROR: File (" + filename + ") has been manually deleted outside of Crystal. Use -f to force code generation and overwrite this deletion.").red.bold);
612 }
613 } else {
614 cache_checksum = cache.checksum[filename_checksum];
615 file_checksum = crypto.createHash('md5').update(fs.readFileSync(filename, 'utf8'), 'utf8').digest('hex');
616 if (cache_checksum !== file_checksum && force !== true) {
617 throw new Error(("ERROR: File (" + filename + ") has been manually changed outside of Crystal. Use -f to force code generation and overwrite these changes.").red.bold);
618 }
619 }
620 }
621 content_checksum = crypto.createHash('md5').update(content, 'utf8').digest('hex');
622 cache.checksum[filename_checksum] = content_checksum;
623 if (!fs.existsSync(".autocode")) {
624 mkdirp.sync(".autocode");
625 }
626 fs.writeFileSync(".autocode/cache.yml", yaml.safeDump(cache));
627 file_last_path = filename.lastIndexOf('/');
628 if (file_last_path !== -1) {
629 mkdirp.sync(filename.substr(0, file_last_path));
630 }
631 fs.writeFileSync(filename, content);
632 results1.push(console.log("- " + filename));
633 }
634 return results1;
635 })());
636 }
637 return results;
638 };
639
640 loadProcessor = function(output_processor, generator_processor, imports) {
641 var j, len, processor, processors;
642 if (generator_processor) {
643 if (typeof output_processor === 'string') {
644 output_processor = [output_processor];
645 }
646 if (typeof generator_processor === 'string') {
647 generator_processor = [generator_processor];
648 }
649 if (output_processor && generator_processor) {
650 output_processor = extend(true, true, output_processor, generator_processor);
651 } else {
652 output_processor = generator_processor;
653 }
654 }
655 if (output_processor instanceof Array) {
656 processors = [];
657 for (j = 0, len = output_processor.length; j < len; j++) {
658 processor = output_processor[j];
659 if (!imports[processor]) {
660 throw new Error("Import does not exist for alias (" + processor + ")");
661 }
662 processors.push({
663 alias: processor,
664 callback: imports[processor].processor
665 });
666 }
667 output_processor = processors;
668 } else if (typeof output_processor === 'string') {
669 if (!imports[output_processor]) {
670 throw new Error("Import does not exist for alias (" + output_processor + ")");
671 }
672 output_processor = [
673 {
674 alias: output_processor,
675 callback: imports[output_processor].processor
676 }
677 ];
678 }
679 return output_processor;
680 };
681
682 loadSchemaRefs = function(schema) {
683 var property_name, resp, schema_path;
684 if (schema['$ref'] && !!schema['$ref'].match(/^http:\/\//)) {
685 schema_path = path.join(userHome, '.autocode/schema/', schema['$ref'].replace(/(^http:\/\/|#)/g, '') + '.json');
686 if (!fs.existsSync(schema_path)) {
687 console.log("Loading schema for ref: " + schema['$ref']);
688 resp = request('get', schema['$ref']);
689 if (!fs.existsSync(path.dirname(schema_path))) {
690 mkdirp.sync(path.dirname(schema_path));
691 }
692 fs.writeFileSync(schema_path, resp);
693 }
694 schema = yaml.safeLoad(fs.readFileSync(schema_path));
695 return schema;
696 }
697 if (schema.properties) {
698 for (property_name in schema.properties) {
699 if (schema.properties[property_name].properties) {
700 schema.properties[property_name] = loadSchemaRefs(schema.properties[property_name]);
701 } else {
702 schema.properties[property_name] = loadSchemaRefs(schema.properties[property_name]);
703 }
704 }
705 }
706 if (schema.definitions) {
707 for (property_name in schema.definitions) {
708 if (schema.definitions[property_name].definitions) {
709 schema.definitions[property_name] = loadSchemaRefs(schema.definitions[property_name]);
710 } else {
711 schema.definitions[property_name] = loadSchemaRefs(schema.definitions[property_name]);
712 }
713 }
714 }
715 return schema;
716 };
717
718 generate = function(opts) {
719 var config, export_name, exported, exports, j, len, model_ver, module_alias, module_name, module_version, module_version_query, module_versions, module_versions_path;
720 loaded_modules = {};
721 config = this.config;
722 if (opts && opts.force) {
723 force = true;
724 }
725 if (config.imports) {
726 config.modules = config.imports;
727 if (config.name) {
728 config.modules[config.name] = process.cwd();
729 }
730 delete config.imports;
731 }
732 if (config.modules) {
733 loadModules(config.modules, config.host);
734 processModules();
735 }
736 for (module_name in config.modules) {
737 module_alias = module_name.substr(module_name.lastIndexOf('/') + 1);
738 module_version_query = config.modules[module_name];
739 if (module_version_query === 'latest') {
740 module_version = 'latest';
741 } else {
742 module_version = null;
743 if (module_version_query.match(/^(\.|\/)/)) {
744 module_versions_path = path.normalize(module_version_query);
745 if (!fs.existsSync(module_versions_path)) {
746 throw new Error("Module (" + module_name + ") not found at local path (" + module_version_query + ").");
747 } else {
748 module_version = module_version_query;
749 }
750 } else {
751 module_versions_path = path.normalize(userHome + "/.autocode/module/" + config.host + "/" + module_name);
752 if (fs.existsSync(module_versions_path)) {
753 module_versions = fs.readdirSync(module_versions_path);
754 for (j = 0, len = module_versions.length; j < len; j++) {
755 model_ver = module_versions[j];
756 model_ver = semver.clean(model_ver);
757 if (model_ver && semver.satisfies(model_ver, config.modules[module_name]) && (!module_version || semver.gt(model_ver, module_version))) {
758 module_version = model_ver;
759 }
760 }
761 }
762 }
763 }
764 if (!module_version) {
765 throw new Error("No matches for Module (" + module_name + ") with version (" + module_version_query + "). Try: autocode update");
766 }
767 exports = loaded_modules[module_name][module_version].exports;
768 for (export_name in exports) {
769 exported = exports[export_name];
770 if (module_alias === config.name) {
771 imports["" + export_name] = exported;
772 }
773 imports[module_alias + "." + export_name] = exported;
774 }
775 }
776 if (config.outputs) {
777 console.log("Loading outputs...".bold);
778 return loadOutputs(config.outputs, imports, config);
779 }
780 };
781
782 inject = function(template, injectors, remove_injector) {
783 if (remove_injector == null) {
784 remove_injector = true;
785 }
786 return template.replace(/([ |\t]+)?>>>[a-z_]*<<<\n?/ig, function(injector) {
787 var inj, inject_final, injected, injector_tabs, j, len, ref;
788 injector_tabs = injector.match(/^[\s]+>/g);
789 if (injector_tabs) {
790 injector_tabs = injector_tabs[0].substr(0, injector_tabs[0].length - 1);
791 } else {
792 injector_tabs = '';
793 }
794 injector = injector.replace(/[\s]+/g, '');
795 injector = injector.substr(3, injector.length - 6);
796 if (injectors && injectors[injector]) {
797 if (injectors[injector] instanceof Array) {
798 injected = injectors[injector].join("\n");
799 } else if ((injectors[injector].substr(0, 1) === '/' || injectors[injector].substr(0, 2) === './') && fs.existsSync(".autocode/" + injectors[injector])) {
800 injected = fs.readFileSync(".autocode/" + injectors[injector], 'utf8');
801 } else {
802 injected = injectors[injector];
803 }
804 if (remove_injector === true) {
805 inject_final = '';
806 } else {
807 inject_final = injector_tabs + ">>>" + injector + "<<<\n";
808 }
809 ref = injected.split("\n");
810 for (j = 0, len = ref.length; j < len; j++) {
811 inj = ref[j];
812 inject_final += "" + injector_tabs + inj + "\n";
813 }
814 return inject_final += "";
815 } else if (remove_injector === true) {
816 return '';
817 } else {
818 return injector_tabs + ">>>" + injector + "<<<\n";
819 }
820 });
821 };
822
823 parse = function(spec, config, processors) {
824 var i, j, k, l, len, len1, len2, len3, m, proc, processor, ref, ref1, s;
825 if (spec['$processor']) {
826 if (typeof spec['$processor'] === 'string') {
827 spec['$processor'] = [spec['$processor']];
828 }
829 ref = spec['$processor'];
830 for (j = 0, len = ref.length; j < len; j++) {
831 proc = ref[j];
832 for (k = 0, len1 = processors.length; k < len1; k++) {
833 processor = processors[k];
834 if (processor.alias === proc) {
835 spec['$value'] = processor.callback(spec['$value']);
836 }
837 }
838 }
839 return spec['$value'];
840 }
841 for (i in spec) {
842 s = spec[i];
843 if (s === void 0) {
844 continue;
845 }
846 if (typeof s === 'object' && !s['$processor']) {
847 spec[i] = parse(spec[i], config, processors);
848 } else if (typeof s === 'string' && s.substr(0, 1) === '$' && config[s.substr(1)]) {
849 spec[i] = config[s.substr(1)];
850 }
851 if (spec[i]['$processor']) {
852 if (typeof spec[i]['$processor'] === 'string') {
853 spec[i]['$processor'] = [spec[i]['$processor']];
854 }
855 ref1 = spec[i]['$processor'];
856 for (l = 0, len2 = ref1.length; l < len2; l++) {
857 proc = ref1[l];
858 if (processors) {
859 for (m = 0, len3 = processors.length; m < len3; m++) {
860 processor = processors[m];
861 if (processor.alias === proc) {
862 if (typeof spec[i]['$value'] === 'string') {
863 if (imports[spec[i]['$value']]) {
864 spec[i]['$value'] = imports[spec[i]['$value']].spec;
865 } else if (spec[i]['$value'].match(/^https?:\/\//)) {
866 spec[i]['$value'] = request('get', spec[i]['$value']);
867 spec[i]['$value'] = yaml.safeLoad(spec[i]['$value'].body);
868 }
869 }
870 spec[i]['$value'] = processor.callback(spec[i]['$value']);
871 }
872 }
873 }
874 }
875 spec[i] = spec[i]['$value'];
876 }
877 }
878 return spec;
879 };
880
881 sortObject = function(object) {
882 return Object.keys(object).sort().reduce((function(result, key) {
883 result[key] = object[key];
884 return result;
885 }), {});
886 };
887
888 module.exports = generate;
889
890}).call(this);