webpack.dev.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268
  1. /* eslint-disable */
  2. var path = require('path');
  3. const merge = require('webpack-merge');
  4. const common = require('./webpack.common.js');
  5. const bodyParser = require('body-parser')
  6. const MiniCssExtractPlugin = require('mini-css-extract-plugin');
  7. const { config } = require('process');
  8. const HtmlWebPackPlugin = require('html-webpack-plugin');
  9. const SpriteLoaderPlugin = require('svg-sprite-loader/plugin');
  10. const { Command } = require('commander');
  11. let cmdLines= { };
  12. var { parseArgsStringToArgv } = require('string-argv');
  13. const data = {
  14. messages: require("../mock/messages.json"),
  15. messagequeue: require("../mock/messages.json"),
  16. message_queue_sequence: [],
  17. commands: require("../mock/commands.json"),
  18. scan: require("../mock/scan.json"),
  19. ap: require("../mock/ap.json"),
  20. config: require("../mock/config.json"),
  21. statusdefinition: require("../mock/statusdefinition.json"),
  22. status: require("../mock/status.json"),
  23. messages_ota_fail: require("../mock/messages_ota_fail.json"),
  24. messages_ota: require("../mock/messages_ota.json")
  25. };
  26. const messagingTypes= {
  27. MESSAGING_INFO : 'MESSAGING_INFO',
  28. MESSAGING_WARNING : 'MESSAGING_WARNING',
  29. MESSAGING_ERROR : 'MESSAGING_ERROR'
  30. };
  31. const messagingClass= {
  32. MESSAGING_CLASS_OTA : 'MESSAGING_CLASS_OTA',
  33. MESSAGING_CLASS_SYSTEM : 'MESSAGING_CLASS_SYSTEM',
  34. MESSAGING_CLASS_STATS : 'MESSAGING_CLASS_STATS',
  35. MESSAGING_CLASS_CFGCMD: 'MESSAGING_CLASS_CFGCMD',
  36. MESSAGING_CLASS_BT: 'MESSAGING_CLASS_BT'
  37. } ;
  38. function requeueMessages(){
  39. data.messagequeue = [];
  40. data.messagequeue.push(...data.messages);
  41. console.log(`Re-queued ${data.messages.length} messages. Total queue length is: ${data.messagequeue.length}`);
  42. }
  43. function sendMessaging(cmdname,msgtype,msgClass,msg){
  44. let message_txt=`${cmdname}\n${msg}`;
  45. var d = new Date();
  46. var n = d.getMilliseconds();
  47. data.messagequeue.push({
  48. message: message_txt,
  49. type: msgtype,
  50. class: msgClass,
  51. sent_time: n,
  52. current_time: n});
  53. console.log(`Queued message ~${data.messagequeue.length} type ${msgtype}, class ${msgClass}: ${message_txt}`);
  54. }
  55. Array.prototype.filter = function(fun /*, thisp*/) {
  56. var len = this.length >>> 0;
  57. if (typeof fun != "function")
  58. throw new TypeError();
  59. var res = [];
  60. var thisp = arguments[1];
  61. for (var i = 0; i < len; i++) {
  62. if (i in this) {
  63. var val = this[i];
  64. if (fun.call(thisp, val, i, this))
  65. res.push(val);
  66. }
  67. }
  68. return res;
  69. };
  70. for(const cmdIdx in data.commands.commands){
  71. const cmd = data.commands.commands[cmdIdx];
  72. //console.log(`Creating command structure for ${cmd.name}`);
  73. cmdLines[cmd.name] = {
  74. cmd: new Command(),
  75. };
  76. cmdLines[cmd.name].cmd
  77. .storeOptionsAsProperties(true)
  78. .name(cmd.name)
  79. .exitOverride();
  80. for(const argIdx in cmd.argtable){
  81. const arg=cmd.argtable[argIdx];
  82. const optstr=((arg.shortopts?'-'+arg.shortopts:'')+
  83. (arg.shortopts && arg.longopts?', ':'')+
  84. (arg.longopts?'--'+arg.longopts:'') +
  85. (arg.hasvalue?`${(arg.shortopts || arg.longopts?' ':'')}<${arg.datatype.replace(/[<>]/gm,'')}>`:''));
  86. //console.log(` Option: ${optstr}, Glossary: ${arg.glossary}`);
  87. if(arg.mincount>0){
  88. cmdLines[cmd.name].cmd.requiredOption( optstr,arg.glossary);
  89. }
  90. else {
  91. cmdLines[cmd.name].cmd.option( optstr,arg.glossary);
  92. }
  93. }
  94. }
  95. const connectReturnCode = {
  96. UPDATE_CONNECTION_OK : 0,
  97. UPDATE_FAILED_ATTEMPT : 1,
  98. UPDATE_USER_DISCONNECT : 2,
  99. UPDATE_LOST_CONNECTION : 3,
  100. UPDATE_FAILED_ATTEMPT_AND_RESTORE : 4
  101. }
  102. module.exports = merge(common, {
  103. mode: 'development',
  104. devtool: 'inline-source-map',
  105. entry: {
  106. test: './src/test.ts'
  107. },
  108. devServer: {
  109. contentBase: path.join(__dirname, 'dist'),
  110. publicPath: '/',
  111. port: 9100,
  112. host: '127.0.0.1',//your ip address
  113. disableHostCheck: true,
  114. headers: {'Access-Control-Allow-Origin': '*',
  115. 'Accept-Encoding': 'identity'},
  116. overlay: true,
  117. before: function(app) {
  118. app.use(bodyParser.json()) // for parsing application/json
  119. app.use(bodyParser.urlencoded({ extended: true })) // for parsing application/x-www-form-urlencoded
  120. app.get('/ap.json', function(req, res) { res.json( data.ap ); });
  121. app.get('/scan.json', function(req, res) { res.json( data.scan ); });
  122. app.get('/config.json', function(req, res) { res.json( data.config ); });
  123. app.get('/status.json', function(req, res) { res.json( data.status ); });
  124. app.get('/messages.json', function(req, res) {
  125. if(data.message_queue_sequence.length>0){
  126. data.messagequeue.push(data.message_queue_sequence.shift());
  127. }
  128. res.json( data.messagequeue ) ;
  129. data.messagequeue=[];
  130. });
  131. app.get('/statusdefinition.json', function(req, res) { res.json( data.statusdefinition ); });
  132. app.get('/commands.json', function(req, res) { res.json( data.commands ); });
  133. app.post('/commands.json', function(req, res) {
  134. console.log(req.body.command);
  135. try {
  136. const cmdName=req.body.command.split(" ")[0];
  137. const args=parseArgsStringToArgv(req.body.command,'node ');
  138. let cmd=cmdLines[cmdName].cmd;
  139. if(cmd){
  140. for (const property in cmd.opts()) {
  141. delete cmd[property];
  142. }
  143. cmd.parse(args);
  144. const msg=`Received Options: ${JSON.stringify(cmd.opts())}\n`;
  145. console.log('Options: ', cmd.opts());
  146. console.log('Remaining arguments: ', cmd.args);
  147. sendMessaging(cmdName,messagingTypes.MESSAGING_INFO,messagingClass.MESSAGING_CLASS_CFGCMD,msg);
  148. }
  149. } catch (error) {
  150. console.error(error);
  151. }
  152. res.json( { 'Result' : 'Success' } );
  153. });
  154. app.post('/config.json', function(req, res) {
  155. var fwurl='';
  156. console.log(req.body);
  157. console.log(data.config);
  158. for (const property in req.body.config) {
  159. console.log(`${property}: ${req.body.config[property].value}`);
  160. if(property=='fwurl'){
  161. fwurl=req.body.config[property].value;
  162. }
  163. else {
  164. if(data.config[property]=== undefined){
  165. console.log(`Added config value ${property} [${req.body.config[property].value}]`);
  166. data.config[property] = {value: req.body.config[property].value};
  167. }
  168. else if (data.config[property].value!=req.body.config[property].value){
  169. console.log(`Updated config value ${property}\nFrom: ${data.config[property].value}\nTo: ${req.body.config[property].value}]`);
  170. data.config[property].value=req.body.config[property].value;
  171. }
  172. }
  173. }
  174. res.json( {} );
  175. if(fwurl!==''){
  176. data.status.recovery=1;
  177. requeueMessages();
  178. if(fwurl.toLowerCase().includes('fail')){
  179. console.log(`queuing ${data.messages_ota_fail.length} ota messages `);
  180. data.message_queue_sequence.push(...data.messages_ota_fail);
  181. }
  182. else {
  183. console.log(`queuing ${data.messages_ota.length} ota messages `);
  184. data.message_queue_sequence.push(...data.messages_ota);
  185. }
  186. }
  187. });
  188. app.post('/status.json', function(req, res) {
  189. for (const property in req.body.status) {
  190. if(data.status[property]=== undefined){
  191. console.log(`Added status value ${property} [${req.body.status[property]}]`);
  192. data.status[property] = {value: req.body.status[property]};
  193. }
  194. else if (data.status[property]!==req.body.status[property]){
  195. console.log(`Updated status value ${property}\nFrom: ${data.status[property]}\nTo: ${req.body.status[property]}`);
  196. data.status[property]=req.body.status[property];
  197. }
  198. }
  199. res.json( {} );
  200. });
  201. app.post('/connect.json', function(req, res) {
  202. setTimeout(function(r){
  203. if(r.body.ssid.search('fail')>=0){
  204. if(data.status.ssid){
  205. // in this case, the same ssid will be reused - the ESP32 would restore its previous state on failure
  206. data.status.urc=connectReturnCode.UPDATE_FAILED_ATTEMPT_AND_RESTORE;
  207. }
  208. else {
  209. data.status.urc=connectReturnCode.UPDATE_FAILED_ATTEMPT;
  210. }
  211. }
  212. else {
  213. data.status.ssid=r.body.ssid;
  214. data.status.urc=connectReturnCode.UPDATE_CONNECTION_OK;
  215. }
  216. }, 1000, req);
  217. res.json( {} );
  218. });
  219. app.post('/reboot_ota.json', function(req, res) {
  220. data.status.recovery=0;
  221. requeueMessages();
  222. res.json( {} );
  223. });
  224. app.post('/reboot.json', function(req, res) {
  225. res.json( {} );
  226. requeueMessages();
  227. });
  228. app.post('/recovery.json', function(req, res) {
  229. data.status.recovery=1;
  230. requeueMessages();
  231. res.json( { } );
  232. });
  233. app.post('/flash.json', function(req, res) {
  234. if(data.status.recovery>0){
  235. res.json({});
  236. }
  237. else {
  238. res.status(404).end();
  239. }
  240. });
  241. app.delete('/connect.json', function(req, res) {
  242. data.status.ssid='';
  243. res.json( {} ); });
  244. app.get('/reboot', function(req, res) { res.json( {} ); });
  245. },
  246. },
  247. plugins: [
  248. new MiniCssExtractPlugin({
  249. filename: 'css/[name].css',
  250. chunkFilename: 'css/[id].css' ,
  251. }),
  252. new HtmlWebPackPlugin({
  253. title: 'SqueezeESP32-test',
  254. template: './src/test.ejs',
  255. filename: 'test',
  256. minify: false,
  257. excludeChunks: ['index'],
  258. }),
  259. new SpriteLoaderPlugin({plainSprite: true})
  260. ],
  261. });