xref: /expo/tools/src/Codegen.ts (revision 415deeaa)
1import spawnAsync from '@expo/spawn-async';
2import fs from 'fs-extra';
3import path from 'path';
4
5export interface ReactNativeCodegenParameters {
6  // path to `react-native` package
7  reactNativeRoot: string;
8
9  // path to `react-native-codegen` package
10  codegenPkgRoot: string;
11
12  // output path for generated code
13  outputDir: string;
14
15  // library name
16  name: string;
17
18  // library type
19  type: 'components' | 'modules';
20
21  // platform for generated code
22  platform: 'android' | 'ios';
23
24  // absolute path to library's javascript code
25  jsSrcsDir: string;
26
27  // keep the intermediate schema.json (default is false)
28  keepIntermediateSchema?: boolean;
29}
30
31export async function runReactNativeCodegenAsync(params: ReactNativeCodegenParameters) {
32  const genSchemaScript = path.join(
33    params.codegenPkgRoot,
34    'lib',
35    'cli',
36    'combine',
37    'combine-js-to-schema-cli.js'
38  );
39  const genCodeScript = path.join(params.reactNativeRoot, 'scripts', 'generate-specs-cli.js');
40
41  const schemaOutputPath = path.join(params.outputDir, 'schema.json');
42  await fs.ensureDir(params.outputDir);
43
44  // generate schema.json from js & flow types
45  await spawnAsync('node', [genSchemaScript, schemaOutputPath, params.jsSrcsDir]);
46
47  // generate code from schema.json
48  await spawnAsync('node', [
49    genCodeScript,
50    '--platform',
51    params.platform,
52    '--schemaPath',
53    schemaOutputPath,
54    '--outputDir',
55    params.outputDir,
56    '--libraryName',
57    params.name,
58    '--libraryType',
59    params.type,
60  ]);
61
62  const keepIntermediateSchema = params.keepIntermediateSchema ?? false;
63  if (!keepIntermediateSchema) {
64    await fs.remove(schemaOutputPath);
65  }
66}
67