1const fs = require("fs");
2const path = require("path");
3// const watch = require("node-watch");
4const minify = require("@node-minify/core");
5const babelMinify = require("@node-minify/babel-minify");
6const uglifyJS = require('@node-minify/uglify-js');
7
8let watchFile = false;
9process.argv.forEach((val, index) => {
10  if (val === "--watch") {
11    watchFile = true;
12  }
13});
14
15let macro4libjs = {
16  /* periperal */
17  adc: 'JSE_HW_ADDON_ADC',
18  can: 'JSE_HW_ADDON_CAN',
19  dac: 'JSE_HW_ADDON_DAC',
20  gpio: 'JSE_HW_ADDON_GPIO',
21  i2c: 'JSE_HW_ADDON_I2C',
22  spi: 'JSE_HW_ADDON_SPI',
23  timer: 'JSE_HW_ADDON_TIMER',
24  pwm: 'JSE_HW_ADDON_PWM',
25  rtc: 'JSE_HW_ADDON_RTC',
26  uart: 'JSE_HW_ADDON_UART',
27  wdg: 'JSE_HW_ADDON_WDG',
28  rtc: 'JSE_HW_ADDON_RTC',
29  /* network */
30  udp: 'JSE_NET_ADDON_UDP',
31  tcp: 'JSE_NET_ADDON_TCP',
32  mqtt: 'JSE_NET_ADDON_MQTT',
33  http: 'JSE_NET_ADDON_HTTP',
34  network: ['JSE_NET_ADDON_CELLULAR', 'JSE_NET_ADDON_WIFI'],
35  /* system */
36  init: 'JSE_CORE_ADDON_INITJS',
37  fs: 'JSE_CORE_ADDON_FS',
38  checksum: 'JSE_CORE_ADDON_CHECKSUM',
39  kv: 'JSE_CORE_ADDON_KV',
40  pm: 'JSE_CORE_ADDON_PM',
41  battery: 'JSE_CORE_ADDON_BATTERY',
42  charger: 'JSE_CORE_ADDON_CHARGER',
43  /* adavanced */
44  iot: ['JSE_ADVANCED_ADDON_AIOT_DEVICE', 'JSE_ADVANCED_ADDON_AIOT_GATEWAY'],
45  audioplayer: 'JSE_ADVANCED_ADDON_AUDIOPLAYER',
46  tts: 'JSE_ADVANCED_ADDON_TTS',
47  location: 'JSE_ADVANCED_ADDON_LOCATION',
48  ui: 'JSE_ADVANCED_ADDON_UI',
49  vm: 'JSE_ADVANCED_ADDON_UI',
50  keypad: 'JSE_ADVANCED_ADDON_KEYPAD',
51  und: 'JSE_ADVANCED_ADDON_UND',
52  appota: 'JSE_ADVANCED_ADDON_OTA',
53  at: 'JSE_CORE_ADDON_AT',
54  paybox: 'JSE_ADVANCED_ADDON_PAYBOX',
55  smartcard: 'JSE_ADVANCED_ADDON_SMARTCARD',
56  blecfgnet: 'JSE_ADVANCED_ADDON_BLECFGNET',
57  /* wireless */
58  bt_host: 'JSE_WIRELESS_ADDON_BT_HOST'
59  /* others will not include in macro */
60}
61
62let template = `
63/*
64* Copyright (C) 2015-2020 Alibaba Group Holding Limited
65* This file autogenerated for jsapi
66*/
67
68#include <stdio.h>
69#include <string.h>
70#include "amp_config.h"
71#include "addons/libjs.h"
72
73#ifdef JSE_HIGHLEVEL_JSAPI
74
75`;
76
77// Async/Await
78async function doMinifyLibs(content) {
79  const data = await minify({
80    compressor: babelMinify,
81    content,
82    options: {
83      babelrc: ".babelrc",
84    },
85  });
86  return data;
87}
88
89// 读取lib文件
90async function doBuildLibs() {
91  let files = fs.readdirSync("./lib");
92
93  template += `libjs_entry_t LIBJS_ENTRIES[] = {\n`;
94  for (let i = 0; i < files.length; i++) {
95    let file = files[i];
96    console.log(file);
97    const filePath = `./lib/${file}`;
98    const fileInfo = fs.statSync(filePath);
99    if (fileInfo.isDirectory()) {
100      return;
101    }
102
103    // 转译 + 压缩
104    const fileContent = fs.readFileSync(filePath);
105    console.log(fileContent);
106
107    try {
108      // 转译 + 压缩后的数据,生成C代码
109      let minifyContent = await doMinifyLibs(fileContent);
110      minifyContent = minifyContent.replace(/\\/g, "\\\\").replace(/"/g, "\\\"");
111      console.log(minifyContent);
112      let fileName = path.basename(filePath, ".js");
113
114      if(macro4libjs.hasOwnProperty(fileName)) {
115        console.log(macro4libjs[fileName]);
116        if(typeof macro4libjs[fileName] !== 'string') {
117          template += '#if ';
118          macro4libjs[fileName].forEach((macro, index) => {
119            template += `defined(${macro})`;
120            if(index < macro4libjs[fileName].length - 1){
121              template += ' || ';
122            }
123          });
124          template += `\n     {"${fileName}", "${minifyContent}"},\n#endif\n\n`;
125        }
126        else {
127          template += `#ifdef ${macro4libjs[fileName]}\n     {"${fileName}", "${minifyContent}"},\n#endif\n\n`;
128        }
129      }
130      else {
131        template += `    {"${fileName}", "${minifyContent}"},\n\n`;
132      }
133    } catch (e) {
134      console.log(e);
135      process.exit(-1);
136    }
137  }
138  const initContent = await doBuildInit();
139  console.log(initContent);
140  template += `#ifdef ${macro4libjs['init']}\n    {"init", "${initContent}"},\n#endif\n\n`;
141  template += "};\n\n";
142  template += "int libjs_num = (sizeof(LIBJS_ENTRIES)/ sizeof(LIBJS_ENTRIES[0]));\n\n#endif /* JSE_HIGHLEVEL_JSAPI */\n"
143  console.log(template);
144  // 写入到文件
145  fs.writeFileSync('../engine/duktape_engine/addons/libjs.c', template);
146}
147
148async function doBuildInit() {
149  try {
150    // 转译 + 压缩后的生成init.js
151    await minify({
152      compressor: uglifyJS,
153      input: 'init/*.js',
154      output: 'init.js',
155    });
156    // 打包到c代码,转义部分字符(引号和反斜杠)
157    let initContent = fs.readFileSync('./init.js').toString().replace(/"/g, "\\\"");
158    return initContent;
159  } catch (e) {
160    console.log(e);
161    process.exit(-1);
162  }
163}
164
165doBuildLibs();
166doBuildInit();
167