1 | const path = require("path");
|
2 | const chalk = require("chalk");
|
3 | const {
|
4 |
|
5 | NETLIFYDEVLOG
|
6 |
|
7 |
|
8 | } = require("netlify-cli-logo");
|
9 | const inquirer = require("inquirer");
|
10 | const fs = require("fs");
|
11 | const detectors = fs
|
12 | .readdirSync(path.join(__dirname, "detectors"))
|
13 | .filter(x => x.endsWith(".js"))
|
14 | .map(det => require(path.join(__dirname, `detectors/${det}`)));
|
15 |
|
16 | module.exports.serverSettings = async devConfig => {
|
17 | let settingsArr = [];
|
18 | let settings = null;
|
19 | for (const i in detectors) {
|
20 | const detectorResult = detectors[i]();
|
21 | if (detectorResult) settingsArr.push(detectorResult);
|
22 | }
|
23 | if (settingsArr.length === 1) {
|
24 |
|
25 | settings = settingsArr[0];
|
26 | settings.args = settings.possibleArgsArrs[0];
|
27 | if (!settings.args) {
|
28 | const { scripts } = JSON.parse(
|
29 | fs.readFileSync("package.json", { encoding: "utf8" })
|
30 | );
|
31 |
|
32 | console.error(
|
33 | "empty args assigned, this is an internal Netlify Dev bug, please report your settings and scripts so we can improve",
|
34 | { scripts, settings }
|
35 | );
|
36 |
|
37 | process.exit(1);
|
38 | }
|
39 | } else if (settingsArr.length > 1) {
|
40 |
|
41 |
|
42 | inquirer.registerPrompt(
|
43 | "autocomplete",
|
44 | require("inquirer-autocomplete-prompt")
|
45 | );
|
46 | const fuzzy = require("fuzzy");
|
47 | const scriptInquirerOptions = formatSettingsArrForInquirer(settingsArr);
|
48 | const { chosenSetting } = await inquirer.prompt({
|
49 | name: "chosenSetting",
|
50 | message: `Multiple possible start commands found`,
|
51 | type: "autocomplete",
|
52 | source: async function(_, input) {
|
53 | if (!input || input === "") {
|
54 | return scriptInquirerOptions;
|
55 | }
|
56 |
|
57 | return filterSettings(scriptInquirerOptions, input);
|
58 | }
|
59 | });
|
60 | settings = chosenSetting;
|
61 |
|
62 |
|
63 |
|
64 | function filterSettings(scriptInquirerOptions, input) {
|
65 | const filteredSettings = fuzzy.filter(
|
66 | input,
|
67 | scriptInquirerOptions.map(x => x.name)
|
68 | );
|
69 | const filteredSettingNames = filteredSettings.map(x =>
|
70 | input ? x.string : x
|
71 | );
|
72 | return scriptInquirerOptions.filter(t =>
|
73 | filteredSettingNames.includes(t.name)
|
74 | );
|
75 | }
|
76 |
|
77 |
|
78 | function formatSettingsArrForInquirer(settingsArr) {
|
79 | let ans = [];
|
80 | settingsArr.forEach(setting => {
|
81 | setting.possibleArgsArrs.forEach(args => {
|
82 | ans.push({
|
83 | name: `[${chalk.yellow(setting.type)}] ${
|
84 | setting.command
|
85 | } ${args.join(" ")}`,
|
86 | value: { ...setting, args },
|
87 | short: setting.type + "-" + args.join(" ")
|
88 | });
|
89 | });
|
90 | });
|
91 | return ans;
|
92 | }
|
93 | }
|
94 |
|
95 |
|
96 | const tellUser = settingsField => dV =>
|
97 |
|
98 | console.log(
|
99 | `${NETLIFYDEVLOG} Overriding ${chalk.yellow(
|
100 | settingsField
|
101 | )} with setting derived from netlify.toml [dev] block: `,
|
102 | dV
|
103 | );
|
104 |
|
105 | if (devConfig) {
|
106 | settings = settings || {};
|
107 | if (devConfig.command) {
|
108 | settings.command = assignLoudly(
|
109 | devConfig.command.split(/\s/)[0],
|
110 | settings.command || null,
|
111 | tellUser("command")
|
112 | );
|
113 | let devConfigArgs = devConfig.command.split(/\s/).slice(1);
|
114 | if (devConfigArgs[0] === "run") devConfigArgs = devConfigArgs.slice(1);
|
115 | settings.args = assignLoudly(
|
116 | devConfigArgs,
|
117 | settings.command || null,
|
118 | tellUser("command")
|
119 | );
|
120 | }
|
121 | if (devConfig.port) {
|
122 | settings.proxyPort = devConfig.port || settings.proxyPort;
|
123 | const regexp =
|
124 | devConfig.urlRegexp ||
|
125 | new RegExp(`(http://)([^:]+:)${devConfig.port}(/)?`, "g");
|
126 | settings.urlRegexp = settings.urlRegexp || regexp;
|
127 | }
|
128 | settings.dist = devConfig.publish || settings.dist;
|
129 | }
|
130 | return settings;
|
131 | };
|
132 |
|
133 |
|
134 | function assignLoudly(
|
135 | optionalValue,
|
136 | defaultValue,
|
137 | // eslint-disable-next-line no-console
|
138 | tellUser = dV => console.log(`No value specified, using fallback of `, dV)
|
139 | ) {
|
140 | if (defaultValue === undefined) throw new Error("must have a defaultValue");
|
141 | if (defaultValue !== optionalValue && optionalValue === undefined) {
|
142 | tellUser(defaultValue);
|
143 | return defaultValue;
|
144 | }
|
145 | return optionalValue;
|
146 | }
|