UNPKG

14.9 kBJavaScriptView Raw
1"use strict";
2var utils = require("./task.utils");
3var file = require("./file.utils");
4var task_utils_1 = require("./task.utils");
5var task_utils_2 = require("./task.utils");
6var debug = require("debug")("cb:input");
7var _ = require("../lodash.custom");
8var InputTypes;
9(function (InputTypes) {
10 InputTypes[InputTypes["DefaultExternalFile"] = "DefaultExternalFile"] = "DefaultExternalFile";
11 InputTypes[InputTypes["ExternalFile"] = "ExternalFile"] = "ExternalFile";
12 InputTypes[InputTypes["InlineObject"] = "InlineObject"] = "InlineObject";
13 InputTypes[InputTypes["StubInlineObject"] = "StubInlineObject"] = "StubInlineObject";
14 InputTypes[InputTypes["CBFile"] = "CBFile"] = "CBFile";
15 InputTypes[InputTypes["InlineJSON"] = "InlineJSON"] = "InlineJSON";
16})(InputTypes = exports.InputTypes || (exports.InputTypes = {}));
17function getInputs(config, inlineInput) {
18 /**
19 * If the User provided a -c flag we MUST validate this
20 * request first as it may fail and then we don't want to continue
21 */
22 if (config.input.length) {
23 debug("config flag provided " + config.input);
24 var stringInputs = config.input.filter(function (x) { return typeof x === "string"; });
25 var inlineInputs = config.input.filter(function (x) { return task_utils_2.isPlainObject(x); });
26 var fileInputs = file.readInputFiles(stringInputs, config.cwd);
27 var mergedFileInputs = fileInputs.valid.map(function (file) { return file.input; });
28 var mergedInputs = _.merge.apply(_, [generateBaseInput({})].concat(mergedFileInputs, inlineInputs, [inlineInput]));
29 if (fileInputs.invalid.length) {
30 return {
31 type: InputTypes.ExternalFile,
32 errors: fileInputs.invalid.map(function (x) { return x.errors[0]; }),
33 sources: fileInputs.invalid,
34 inputs: [],
35 };
36 }
37 return {
38 type: InputTypes.ExternalFile,
39 errors: [],
40 sources: fileInputs.valid,
41 inputs: [
42 /**
43 * Merged all given configs into a single obj
44 * This is to allow, for example, production
45 * configuration to override dev etc..
46 */
47 mergedInputs
48 ],
49 };
50 }
51 if (config.fromJson) {
52 try {
53 var parsed = JSON.parse(config.fromJson);
54 return {
55 errors: [],
56 sources: [],
57 type: InputTypes.InlineJSON,
58 inputs: [generateBaseInput(parsed)]
59 };
60 }
61 catch (e) {
62 return {
63 errors: [{ type: task_utils_1.InputErrorTypes.InvalidJson, json: config.fromJson, error: e }],
64 sources: [],
65 type: InputTypes.InlineJSON,
66 inputs: []
67 };
68 }
69 }
70 /**
71 * If the User provided --cbfile flag we MUST validate this
72 * request first as it may fail and then we don't want to continue
73 */
74 if (config.cbfile) {
75 debug("'cbfile' flag provided " + config.cbfile);
76 var cbfiles = file.retrieveCBFiles(config);
77 if (cbfiles.invalid.length) {
78 return {
79 type: InputTypes.CBFile,
80 errors: cbfiles.invalid.map(function (x) { return x.errors[0]; }),
81 sources: cbfiles.invalid,
82 inputs: [],
83 };
84 }
85 return {
86 type: InputTypes.CBFile,
87 errors: [],
88 sources: cbfiles.valid,
89 inputs: [],
90 };
91 }
92 /**
93 * Crossbow may be used with a simple object literal input.
94 * This is how the test suit is even possible in such a system
95 */
96 if (utils.isPlainObject(inlineInput)) {
97 debug("plain object given as input " + JSON.stringify(inlineInput));
98 return {
99 type: InputTypes.InlineObject,
100 errors: [],
101 sources: [],
102 inputs: [generateBaseInput(inlineInput)]
103 };
104 }
105 if (!config.loadDefaultInputs) {
106 debug("config.loadDefaultInputs = false, not looking for default file types");
107 return {
108 errors: [],
109 sources: [],
110 type: InputTypes.StubInlineObject,
111 inputs: [generateBaseInput({})]
112 };
113 }
114 /**
115 * Finally, try any cbfiles in the cwd
116 */
117 var defaultCbFiles = file.retrieveCBFiles(config);
118 /**
119 * If a cbfile.js **was** found in the current
120 * directory, it will have been 'required' and therefor
121 * some code will have run, which may of errored.
122 * So here we check for that possible error by
123 * filtering out `InputFileNotFound` errors (which simply mean
124 * a cbfile.js was not found anyway.
125 */
126 var inputErrors = defaultCbFiles.invalid
127 .filter(function (x) { return x.errors[0].type !== task_utils_1.InputErrorTypes.InputFileNotFound; });
128 if (inputErrors.length) {
129 return {
130 type: InputTypes.CBFile,
131 errors: inputErrors.map(function (x) { return x.errors[0]; }),
132 sources: inputErrors,
133 inputs: [],
134 };
135 }
136 if (defaultCbFiles.valid.length) {
137 debug("Default cbfile found " + defaultCbFiles.valid[0].resolved);
138 return {
139 errors: [],
140 type: InputTypes.CBFile,
141 sources: defaultCbFiles.valid,
142 inputs: []
143 };
144 }
145 /**
146 * At this point, the user has not attempted to load any config files manually
147 * so we try to load any defaults that are in the CWD
148 */
149 var defaultInputputFiles = file.retrieveDefaultInputFiles(config);
150 var notMissingFileErrors = defaultInputputFiles.invalid
151 .filter(function (x) { return x.errors[0].type !== task_utils_1.InputErrorTypes.InputFileNotFound; });
152 if (notMissingFileErrors.length) {
153 debug("Default input found with errors " + notMissingFileErrors[0].resolved);
154 return {
155 errors: notMissingFileErrors.reduce(function (acc, x) { return acc.concat(x.errors); }, []),
156 type: InputTypes.DefaultExternalFile,
157 sources: notMissingFileErrors,
158 inputs: []
159 };
160 }
161 if (defaultInputputFiles.valid.length) {
162 debug("Default input found " + defaultInputputFiles.valid[0].resolved);
163 return {
164 errors: [],
165 type: InputTypes.DefaultExternalFile,
166 sources: defaultInputputFiles.valid,
167 inputs: [generateBaseInput(defaultInputputFiles.valid[0].input)]
168 };
169 }
170 /**
171 * If we reach this point, we're working with
172 * 1. NO external input files
173 * 2. NO inline Object literal
174 *
175 * Which means we just need the stub objects, enough
176 * to allow the system to work.
177 */
178 debug("No external input given/found, using default");
179 return {
180 errors: [],
181 sources: [],
182 type: InputTypes.InlineObject,
183 inputs: [generateBaseInput({})]
184 };
185}
186exports.getInputs = getInputs;
187/**
188 * `Input` is the object that is looked at to resolve tasks/options and
189 * watchers
190 */
191function generateBaseInput(incoming) {
192 return _.merge({
193 tasks: {},
194 watch: {
195 before: [],
196 options: {}
197 },
198 options: {},
199 env: {}
200 }, incoming || {});
201}
202exports.generateBaseInput = generateBaseInput;
203//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5wdXQucmVzb2x2ZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9pbnB1dC5yZXNvbHZlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFHQSxvQ0FBc0M7QUFDdEMsbUNBQXFDO0FBQ3JDLDJDQUE2QztBQUU3QywyQ0FBMkM7QUFFM0MsSUFBTSxLQUFLLEdBQUcsT0FBTyxDQUFDLE9BQU8sQ0FBQyxDQUFDLFVBQVUsQ0FBQyxDQUFDO0FBQzNDLElBQU0sQ0FBQyxHQUFHLE9BQU8sQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDO0FBRXRDLElBQVksVUFPWDtBQVBELFdBQVksVUFBVTtJQUNsQiwrQ0FBMkIscUJBQXFCLHlCQUFBLENBQUE7SUFDaEQsd0NBQW9CLGNBQWMsa0JBQUEsQ0FBQTtJQUNsQyx3Q0FBb0IsY0FBYyxrQkFBQSxDQUFBO0lBQ2xDLDRDQUF3QixrQkFBa0Isc0JBQUEsQ0FBQTtJQUMxQyxrQ0FBYyxRQUFRLFlBQUEsQ0FBQTtJQUN0QixzQ0FBa0IsWUFBWSxnQkFBQSxDQUFBO0FBQ2xDLENBQUMsRUFQVyxVQUFVLEdBQVYsa0JBQVUsS0FBVixrQkFBVSxRQU9yQjtBQVNELG1CQUEyQixNQUE2QixFQUFFLFdBQWlCO0lBRXZFOzs7T0FHRztJQUNILEVBQUUsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQztRQUN0QixLQUFLLENBQUMsMEJBQXdCLE1BQU0sQ0FBQyxLQUFPLENBQUMsQ0FBQztRQUU5QyxJQUFNLFlBQVksR0FBTyxNQUFNLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxVQUFBLENBQUMsSUFBSSxPQUFBLE9BQU8sQ0FBQyxLQUFLLFFBQVEsRUFBckIsQ0FBcUIsQ0FBQyxDQUFDO1FBQ3pFLElBQU0sWUFBWSxHQUFPLE1BQU0sQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLFVBQUEsQ0FBQyxJQUFJLE9BQUEsMEJBQWEsQ0FBQyxDQUFDLENBQUMsRUFBaEIsQ0FBZ0Is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
\No newline at end of file