xref: /expo/packages/@expo/config/src/Serialize.ts (revision e330c216)
1import { ConfigError } from './Errors';
2
3export function serializeAndEvaluate(val: any): any {
4  if (['undefined', 'string', 'boolean', 'number', 'bigint'].includes(typeof val)) {
5    return val;
6  } else if (typeof val === 'function') {
7    // TODO: Bacon: Should we support async methods?
8    return val();
9  } else if (Array.isArray(val)) {
10    return val.map(serializeAndEvaluate);
11  } else if (typeof val === 'object') {
12    const output: { [key: string]: any } = {};
13    for (const property in val) {
14      if (val.hasOwnProperty(property)) {
15        output[property] = serializeAndEvaluate(val[property]);
16      }
17    }
18    return output;
19  }
20  // symbol
21  throw new ConfigError(`Expo config doesn't support \`Symbols\`: ${val}`, 'INVALID_CONFIG');
22}
23
24export function serializeSkippingMods(val: any): any {
25  if (typeof val === 'object' && !Array.isArray(val)) {
26    const output: { [key: string]: any } = {};
27    for (const property in val) {
28      if (val.hasOwnProperty(property)) {
29        if (property === 'mods' || property === 'plugins') {
30          // Don't serialize mods or plugins
31          output[property] = val[property];
32        } else {
33          output[property] = serializeAndEvaluate(val[property]);
34        }
35      }
36    }
37    return output;
38  }
39  return serializeAndEvaluate(val);
40}
41
42function serializeAndEvaluatePlugin(val: any): any {
43  if (['undefined', 'string', 'boolean', 'number', 'bigint'].includes(typeof val)) {
44    return val;
45  } else if (typeof val === 'function') {
46    return val.name ?? 'withAnonymous';
47  } else if (Array.isArray(val)) {
48    return val.map(serializeAndEvaluatePlugin);
49  } else if (typeof val === 'object') {
50    const output: { [key: string]: any } = {};
51    for (const property in val) {
52      if (val.hasOwnProperty(property)) {
53        output[property] = serializeAndEvaluatePlugin(val[property]);
54      }
55    }
56    return output;
57  }
58  // symbol
59  throw new ConfigError(`Expo config doesn't support \`Symbols\`: ${val}`, 'INVALID_CONFIG');
60}
61
62export function serializeAfterStaticPlugins(val: any): any {
63  if (typeof val === 'object' && !Array.isArray(val)) {
64    const output: { [key: string]: any } = {};
65    for (const property in val) {
66      if (val.hasOwnProperty(property)) {
67        if (property === 'mods') {
68          // Don't serialize mods
69          output[property] = val[property];
70        } else if (property === 'plugins' && Array.isArray(val[property])) {
71          // Serialize the mods by removing any config plugins
72          output[property] = val[property].map(serializeAndEvaluatePlugin);
73        } else {
74          output[property] = serializeAndEvaluate(val[property]);
75        }
76      }
77    }
78    return output;
79  }
80  return serializeAndEvaluate(val);
81}
82