xref: /expo/packages/@expo/cli/src/utils/plist.ts (revision 8a424beb)
1c4ef02aeSEvan Baconimport plist from '@expo/plist';
2c4ef02aeSEvan Baconimport binaryPlist from 'bplist-parser';
3c4ef02aeSEvan Baconimport fs from 'fs/promises';
4c4ef02aeSEvan Bacon
5c4ef02aeSEvan Baconimport { CommandError } from './errors';
6*8a424bebSJames Ideimport * as Log from '../log';
7c4ef02aeSEvan Bacon
8c4ef02aeSEvan Baconconst CHAR_CHEVRON_OPEN = 60;
9c4ef02aeSEvan Baconconst CHAR_B_LOWER = 98;
10c4ef02aeSEvan Bacon// .mobileprovision
11c4ef02aeSEvan Bacon// const CHAR_ZERO = 30;
12c4ef02aeSEvan Bacon
13c4ef02aeSEvan Baconexport async function parsePlistAsync(plistPath: string) {
14c4ef02aeSEvan Bacon  Log.debug(`Parse plist: ${plistPath}`);
15c4ef02aeSEvan Bacon
16c4ef02aeSEvan Bacon  return parsePlistBuffer(await fs.readFile(plistPath));
17c4ef02aeSEvan Bacon}
18c4ef02aeSEvan Bacon
19c4ef02aeSEvan Baconexport function parsePlistBuffer(contents: Buffer) {
20c4ef02aeSEvan Bacon  if (contents[0] === CHAR_CHEVRON_OPEN) {
21c4ef02aeSEvan Bacon    const info = plist.parse(contents.toString());
22c4ef02aeSEvan Bacon    if (Array.isArray(info)) return info[0];
23c4ef02aeSEvan Bacon    return info;
24c4ef02aeSEvan Bacon  } else if (contents[0] === CHAR_B_LOWER) {
25c4ef02aeSEvan Bacon    // @ts-expect-error
26c4ef02aeSEvan Bacon    const info = binaryPlist.parseBuffer(contents);
27c4ef02aeSEvan Bacon    if (Array.isArray(info)) return info[0];
28c4ef02aeSEvan Bacon    return info;
29c4ef02aeSEvan Bacon  } else {
30c4ef02aeSEvan Bacon    throw new CommandError(
31c4ef02aeSEvan Bacon      'PLIST',
32c4ef02aeSEvan Bacon      `Cannot parse plist of type byte (0x${contents[0].toString(16)})`
33c4ef02aeSEvan Bacon    );
34c4ef02aeSEvan Bacon  }
35c4ef02aeSEvan Bacon}
36