File size: 3,915 Bytes
4327358
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
// eslint-disable-next-line @typescript-eslint/no-var-requires
const fs = require('fs');
// eslint-disable-next-line @typescript-eslint/no-var-requires
const path = require('path');
// eslint-disable-next-line @typescript-eslint/no-var-requires
const axios = require('axios');
// eslint-disable-next-line @typescript-eslint/no-var-requires
const { execSync } = require('child_process');
// eslint-disable-next-line @typescript-eslint/no-var-requires
const yargs = require('yargs');

// Defaults
const CONFIG_FILE = 'waha.config.json';
// Load defaults from package.json
gows = (() => {
  try {
    const config = JSON.parse(fs.readFileSync(CONFIG_FILE, 'utf8'));
    return config.waha.gows || {};
  } catch (error) {
    return {};
  }
})();

const DEFAULT_REPO = gows.repo;
if (!DEFAULT_REPO) {
  throw new Error(`Missing default repo in ${CONFIG_FILE}`);
}
const DEFAULT_REF = gows.ref;
if (!DEFAULT_REF) {
  throw new Error('Missing default ref in ${CONFIG_FILE}');
}
const DEFAULT_DIR = './src/core/engines/gows/proto';

const PROTO_FILES = ['gows.proto'];
const PROTO_OUTPUT = './src/core/engines/gows/grpc';

// Helper function to clean directory
function cleanDirectory(directory, suffix) {
  if (!fs.existsSync(directory)) {
    fs.mkdirSync(directory, { recursive: true });
    return;
  }

  const files = fs.readdirSync(directory);
  for (const file of files) {
    const filePath = path.join(directory, file);
    if (file.endsWith(suffix)) {
      fs.unlinkSync(filePath);
    }
  }
}

// Helper function to download files
async function downloadFiles(repo, ref, directory) {
  for (const file of PROTO_FILES) {
    const url = `https://github.com/${repo}/releases/download/${ref}/${file}`;
    const filePath = path.join(directory, file);
    try {
      const response = await axios.get(url, { responseType: 'arraybuffer' });
      fs.writeFileSync(filePath, response.data);
      console.log(`Downloaded: ${file}`);
    } catch (error) {
      console.error(`Failed to download ${file}: ${error.message}`);
    }
  }
}

// Handler for fetch command
async function handleFetch(repo, ref, dir) {
  console.log(`Fetching .proto files from ${repo}@${ref} to ${dir}...`);
  cleanDirectory(dir, '.proto');
  await downloadFiles(repo, ref, dir);
}

// Handler for build command
function handleBuild(dir) {
  console.log('Building gRPC files...');
  cleanDirectory(PROTO_OUTPUT);

  const command = `grpc_tools_node_protoc \
        --plugin=protoc-gen-ts=node_modules/.bin/protoc-gen-ts \
        --plugin=protoc-gen-grpc=node_modules/.bin/grpc_tools_node_protoc_plugin \
        --js_out=import_style=commonjs,binary:${PROTO_OUTPUT} \
        --grpc_out=grpc_js:${PROTO_OUTPUT} \
        --ts_out=grpc_js:${PROTO_OUTPUT} \
        -I ${dir} ${dir}/gows.proto`;

  try {
    execSync(command, { stdio: 'inherit' });
    console.log('gRPC files built successfully.');
  } catch (error) {
    console.error(`Failed to build gRPC files: ${error.message}`);
  }
}

//
// Commands
//

// fetch
yargs.command(
  'fetch',
  'Fetch .proto files from GitHub',
  (yargs) => {
    yargs
      .option('repo', {
        describe: 'GitHub repository (owner/repo)',
        type: 'string',
        default: DEFAULT_REPO,
      })
      .option('ref', {
        describe: 'Git reference (branch or commit SHA)',
        type: 'string',
        default: DEFAULT_REF,
      })
      .option('dir', {
        describe: 'Directory to output .proto files',
        type: 'string',
        default: DEFAULT_DIR,
      });
  },
  async (argv) => {
    await handleFetch(argv.repo, argv.ref, argv.dir);
  },
);

// build
yargs.command(
  'build',
  'Build gRPC files from .proto files',
  (yargs) => {
    yargs.option('dir', {
      describe: 'Directory containing .proto files',
      type: 'string',
      default: DEFAULT_DIR,
    });
  },
  (argv) => {
    handleBuild(argv.dir);
  },
);

// Parse arguments
yargs.parse();