1*02eef4e1SKudo Chien/**
2*02eef4e1SKudo Chien * Tool to generate vol JSON fixture from a project.
3*02eef4e1SKudo Chien *
4*02eef4e1SKudo Chien * Usage: npx ts-node scripts/createFixture /path/to/app /path/to/output.json
5*02eef4e1SKudo Chien */
6*02eef4e1SKudo Chienimport realFS from 'fs';
7*02eef4e1SKudo Chienimport glob from 'glob';
8*02eef4e1SKudo Chienimport { fs, vol } from 'memfs';
9*02eef4e1SKudo Chienimport path from 'path';
10*02eef4e1SKudo Chien
11*02eef4e1SKudo Chienfunction globAsync(pattern: string, options: Parameters<typeof glob>[1]): Promise<string[]> {
12*02eef4e1SKudo Chien  return new Promise((resolve, reject) => {
13*02eef4e1SKudo Chien    glob(pattern, options, (err, matches) => {
14*02eef4e1SKudo Chien      if (err != null) {
15*02eef4e1SKudo Chien        reject(err);
16*02eef4e1SKudo Chien      } else {
17*02eef4e1SKudo Chien        resolve(matches);
18*02eef4e1SKudo Chien      }
19*02eef4e1SKudo Chien    });
20*02eef4e1SKudo Chien  });
21*02eef4e1SKudo Chien}
22*02eef4e1SKudo Chien
23*02eef4e1SKudo Chienasync function createFixtureAsync(targetDir: string, outputFile: string) {
24*02eef4e1SKudo Chien  const files = await globAsync('**/*', {
25*02eef4e1SKudo Chien    cwd: targetDir,
26*02eef4e1SKudo Chien    ignore: [
27*02eef4e1SKudo Chien      // binary files
28*02eef4e1SKudo Chien      '**/*.{jpg,png}',
29*02eef4e1SKudo Chien
30*02eef4e1SKudo Chien      // lock files
31*02eef4e1SKudo Chien      '**/*.lock',
32*02eef4e1SKudo Chien
33*02eef4e1SKudo Chien      // node files
34*02eef4e1SKudo Chien      '**/node_modules/**',
35*02eef4e1SKudo Chien
36*02eef4e1SKudo Chien      // generated files
37*02eef4e1SKudo Chien      '**/build/**',
38*02eef4e1SKudo Chien
39*02eef4e1SKudo Chien      // ios files
40*02eef4e1SKudo Chien      'ios/Pods/**',
41*02eef4e1SKudo Chien      'vendor/**',
42*02eef4e1SKudo Chien      '**/xcuserdata/**',
43*02eef4e1SKudo Chien      '**/*.xcassets/**',
44*02eef4e1SKudo Chien      '**/IDEWorkspaceChecks.plist',
45*02eef4e1SKudo Chien
46*02eef4e1SKudo Chien      // android files
47*02eef4e1SKudo Chien      '**/*.jar',
48*02eef4e1SKudo Chien      '**/*.keystore',
49*02eef4e1SKudo Chien      '**/gradlew',
50*02eef4e1SKudo Chien      '**/gradlew.bat',
51*02eef4e1SKudo Chien      '**/gradle/wrapper/**',
52*02eef4e1SKudo Chien    ],
53*02eef4e1SKudo Chien    nodir: true,
54*02eef4e1SKudo Chien  });
55*02eef4e1SKudo Chien  for (const file of files) {
56*02eef4e1SKudo Chien    const content = realFS.readFileSync(path.join(targetDir, file), 'utf8');
57*02eef4e1SKudo Chien    fs.mkdirSync(path.join('/', path.dirname(file)), { recursive: true });
58*02eef4e1SKudo Chien    fs.writeFileSync(path.join('/', file), content);
59*02eef4e1SKudo Chien  }
60*02eef4e1SKudo Chien  const resultJSON: Record<string, string | null> = {};
61*02eef4e1SKudo Chien  for (const [key, value] of Object.entries(vol.toJSON())) {
62*02eef4e1SKudo Chien    resultJSON[path.join('/app', path.relative('/', key))] = value;
63*02eef4e1SKudo Chien  }
64*02eef4e1SKudo Chien  realFS.writeFileSync(outputFile, JSON.stringify(resultJSON, null, 2));
65*02eef4e1SKudo Chien}
66*02eef4e1SKudo Chien
67*02eef4e1SKudo Chien(async () => {
68*02eef4e1SKudo Chien  if (process.argv.length !== 4) {
69*02eef4e1SKudo Chien    console.log(`Usage: ${path.basename(process.argv[1])} targetDir outputFile`);
70*02eef4e1SKudo Chien    process.exit(1);
71*02eef4e1SKudo Chien  }
72*02eef4e1SKudo Chien  const targetDir = process.argv[2];
73*02eef4e1SKudo Chien  const outputFile = process.argv[3];
74*02eef4e1SKudo Chien
75*02eef4e1SKudo Chien  try {
76*02eef4e1SKudo Chien    await createFixtureAsync(targetDir, outputFile);
77*02eef4e1SKudo Chien  } catch (e) {
78*02eef4e1SKudo Chien    console.error('Uncaught Error', e);
79*02eef4e1SKudo Chien    process.exit(1);
80*02eef4e1SKudo Chien  }
81*02eef4e1SKudo Chien})();
82