xref: /expo/tools/src/Codegen.ts (revision d04463cb)
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 runReactNativeCodegen(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  const codegenOutputDir =
43    params.type === 'components'
44      ? path.join(params.outputDir, 'react', 'renderer', 'components', params.name)
45      : path.join(params.outputDir, params.name);
46  await fs.ensureDir(params.outputDir);
47
48  // generate schema.json from js & flow types
49  await spawnAsync('node', [genSchemaScript, schemaOutputPath, params.jsSrcsDir]);
50
51  // generate code from schema.json
52  await spawnAsync('node', [
53    genCodeScript,
54    '--platform',
55    params.platform,
56    '--schemaPath',
57    schemaOutputPath,
58    '--outputDir',
59    codegenOutputDir,
60    '--libraryName',
61    params.name,
62    '--libraryType',
63    params.type,
64  ]);
65
66  const keepIntermediateSchema = params.keepIntermediateSchema ?? false;
67  if (!keepIntermediateSchema) {
68    await fs.remove(schemaOutputPath);
69  }
70}
71