@vxrn/utils 2.0.0-beta.33.1 → 2.0.0-beta.362.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (73) hide show
  1. package/dist/cjs/createMessageSocket.cjs +115 -121
  2. package/dist/cjs/createMessageSocket.native.cjs +166 -0
  3. package/dist/cjs/createMessageSocket.native.js +152 -166
  4. package/dist/cjs/createMessageSocket.native.js.map +1 -1
  5. package/dist/cjs/detectPackageManager.cjs +76 -72
  6. package/dist/cjs/detectPackageManager.native.cjs +106 -0
  7. package/dist/cjs/detectPackageManager.native.js +82 -77
  8. package/dist/cjs/detectPackageManager.native.js.map +1 -1
  9. package/dist/cjs/exec.cjs +43 -45
  10. package/dist/cjs/exec.native.cjs +65 -0
  11. package/dist/cjs/exec.native.js +48 -49
  12. package/dist/cjs/exec.native.js.map +1 -1
  13. package/dist/cjs/index.cjs +10 -11
  14. package/dist/cjs/index.native.cjs +26 -0
  15. package/dist/cjs/index.native.js +10 -10
  16. package/dist/cjs/index.native.js.map +1 -1
  17. package/dist/cjs/mustReplace.cjs +27 -35
  18. package/dist/cjs/mustReplace.native.cjs +60 -0
  19. package/dist/cjs/mustReplace.native.js +44 -60
  20. package/dist/cjs/mustReplace.native.js.map +1 -1
  21. package/dist/cjs/nativeAppManifest.cjs +328 -0
  22. package/dist/cjs/nativeAppManifest.native.cjs +445 -0
  23. package/dist/cjs/nativeAppManifest.native.js +447 -0
  24. package/dist/cjs/nativeAppManifest.native.js.map +1 -0
  25. package/dist/cjs/publicEnv.cjs +38 -0
  26. package/dist/cjs/publicEnv.native.cjs +57 -0
  27. package/dist/cjs/publicEnv.native.js +59 -0
  28. package/dist/cjs/publicEnv.native.js.map +1 -0
  29. package/dist/esm/createMessageSocket.mjs +103 -103
  30. package/dist/esm/createMessageSocket.mjs.map +1 -1
  31. package/dist/esm/createMessageSocket.native.js +139 -148
  32. package/dist/esm/createMessageSocket.native.js.map +1 -1
  33. package/dist/esm/detectPackageManager.mjs +65 -55
  34. package/dist/esm/detectPackageManager.mjs.map +1 -1
  35. package/dist/esm/detectPackageManager.native.js +71 -61
  36. package/dist/esm/detectPackageManager.native.js.map +1 -1
  37. package/dist/esm/exec.mjs +29 -27
  38. package/dist/esm/exec.mjs.map +1 -1
  39. package/dist/esm/exec.native.js +34 -32
  40. package/dist/esm/exec.native.js.map +1 -1
  41. package/dist/esm/index.js +13 -7
  42. package/dist/esm/index.mjs +13 -7
  43. package/dist/esm/index.native.js +13 -7
  44. package/dist/esm/mustReplace.mjs +15 -17
  45. package/dist/esm/mustReplace.mjs.map +1 -1
  46. package/dist/esm/mustReplace.native.js +32 -43
  47. package/dist/esm/mustReplace.native.js.map +1 -1
  48. package/dist/esm/nativeAppManifest.mjs +305 -0
  49. package/dist/esm/nativeAppManifest.mjs.map +1 -0
  50. package/dist/esm/nativeAppManifest.native.js +420 -0
  51. package/dist/esm/nativeAppManifest.native.js.map +1 -0
  52. package/dist/esm/publicEnv.mjs +14 -0
  53. package/dist/esm/publicEnv.mjs.map +1 -0
  54. package/dist/esm/publicEnv.native.js +31 -0
  55. package/dist/esm/publicEnv.native.js.map +1 -0
  56. package/package.json +18 -5
  57. package/src/index.ts +1 -0
  58. package/src/nativeAppManifest.test.ts +360 -0
  59. package/src/nativeAppManifest.ts +702 -0
  60. package/src/publicEnv.ts +19 -0
  61. package/types/createMessageSocket.d.ts +1 -1
  62. package/types/createMessageSocket.d.ts.map +1 -1
  63. package/types/detectPackageManager.d.ts.map +1 -1
  64. package/types/exec.d.ts.map +1 -1
  65. package/types/index.d.ts +1 -0
  66. package/types/index.d.ts.map +1 -1
  67. package/types/nativeAppManifest.d.ts +180 -0
  68. package/types/nativeAppManifest.d.ts.map +1 -0
  69. package/types/publicEnv.d.ts +9 -0
  70. package/types/publicEnv.d.ts.map +1 -0
  71. package/dist/esm/index.js.map +0 -1
  72. package/dist/esm/index.mjs.map +0 -1
  73. package/dist/esm/index.native.js.map +0 -1
@@ -1,7 +1,13 @@
1
- export * from "@vxrn/debug";
2
- export * from "@vxrn/resolve";
3
- export * from "./createMessageSocket.mjs";
4
- export * from "./detectPackageManager.mjs";
5
- export * from "./exec.mjs";
6
- export * from "./mustReplace.mjs";
7
- //# sourceMappingURL=index.mjs.map
1
+ export * from "@vxrn/debug"
2
+
3
+ export * from "@vxrn/resolve"
4
+
5
+ export * from "./createMessageSocket.mjs"
6
+
7
+ export * from "./detectPackageManager.mjs"
8
+
9
+ export * from "./exec.mjs"
10
+
11
+ export * from "./mustReplace.mjs"
12
+
13
+ export * from "./publicEnv.mjs"
@@ -1,7 +1,13 @@
1
- export * from "@vxrn/debug";
2
- export * from "@vxrn/resolve";
3
- export * from "./createMessageSocket.native.js";
4
- export * from "./detectPackageManager.native.js";
5
- export * from "./exec.native.js";
6
- export * from "./mustReplace.native.js";
7
- //# sourceMappingURL=index.native.js.map
1
+ export * from "@vxrn/debug"
2
+
3
+ export * from "@vxrn/resolve"
4
+
5
+ export * from "./createMessageSocket.native.js"
6
+
7
+ export * from "./detectPackageManager.native.js"
8
+
9
+ export * from "./exec.native.js"
10
+
11
+ export * from "./mustReplace.native.js"
12
+
13
+ export * from "./publicEnv.native.js"
@@ -1,24 +1,22 @@
1
1
  import { writeFileSync } from "node:fs";
2
2
  import { tmpdir } from "node:os";
3
3
  import { join } from "node:path";
4
+
4
5
  function mustReplace(source, replacements) {
5
- let sourceOut = source;
6
- for (const {
7
- find,
8
- replace,
9
- optional
10
- } of replacements) {
11
- if (!optional) {
12
- const found = find instanceof RegExp ? find.test(sourceOut) : sourceOut.includes(find);
13
- if (!found) {
14
- const tmpPath = join(tmpdir(), `replace-error-${Math.random()}`);
15
- writeFileSync(tmpPath, sourceOut, "utf-8");
16
- throw new Error(`Substring or pattern "${find}" not found in the string, replacing in source: ${tmpPath}.`);
17
- }
18
- }
19
- sourceOut = sourceOut.replace(find, replace);
20
- }
21
- return sourceOut;
6
+ let sourceOut = source;
7
+ for (const { find, replace, optional } of replacements) {
8
+ if (!optional) {
9
+ const found = find instanceof RegExp ? find.test(sourceOut) : sourceOut.includes(find);
10
+ if (!found) {
11
+ const tmpPath = join(tmpdir(), `replace-error-${Math.random()}`);
12
+ writeFileSync(tmpPath, sourceOut, "utf-8");
13
+ throw new Error(`Substring or pattern "${find}" not found in the string, replacing in source: ${tmpPath}.`);
14
+ }
15
+ }
16
+ sourceOut = sourceOut.replace(find, replace);
17
+ }
18
+ return sourceOut;
22
19
  }
20
+
23
21
  export { mustReplace };
24
22
  //# sourceMappingURL=mustReplace.mjs.map
@@ -1 +1 @@
1
- {"version":3,"names":["writeFileSync","tmpdir","join","mustReplace","source","replacements","sourceOut","find","replace","optional","found","RegExp","test","includes","tmpPath","Math","random","Error"],"sources":["../../src/mustReplace.ts"],"sourcesContent":[null],"mappings":"AAAA,SAASA,aAAA,QAAqB;AAC9B,SAASC,MAAA,QAAc;AACvB,SAASC,IAAA,QAAY;AAEd,SAASC,YACdC,MAAA,EACAC,YAAA,EAKA;EACA,IAAIC,SAAA,GAAYF,MAAA;EAChB,WAAW;IAAEG,IAAA;IAAMC,OAAA;IAASC;EAAS,KAAKJ,YAAA,EAAc;IACtD,IAAI,CAACI,QAAA,EAAU;MACb,MAAMC,KAAA,GACJH,IAAA,YAAgBI,MAAA,GAASJ,IAAA,CAAKK,IAAA,CAAKN,SAAS,IAAIA,SAAA,CAAUO,QAAA,CAASN,IAAI;MACzE,IAAI,CAACG,KAAA,EAAO;QACV,MAAMI,OAAA,GAAUZ,IAAA,CAAKD,MAAA,CAAO,GAAG,iBAAiBc,IAAA,CAAKC,MAAA,CAAO,CAAC,EAAE;QAC/DhB,aAAA,CAAcc,OAAA,EAASR,SAAA,EAAW,OAAO;QACzC,MAAM,IAAIW,KAAA,CACR,yBAAyBV,IAAI,mDAAmDO,OAAO,GACzF;MACF;IACF;IAGAR,SAAA,GAAYA,SAAA,CAAUE,OAAA,CAAQD,IAAA,EAAMC,OAAO;EAC7C;EACA,OAAOF,SAAA;AACT","ignoreList":[]}
1
+ {"version":3,"file":"mustReplace.js","names":[],"sources":["esm/mustReplace.js"],"sourcesContent":["import { writeFileSync } from \"node:fs\";\nimport { tmpdir } from \"node:os\";\nimport { join } from \"node:path\";\nfunction mustReplace(source, replacements) {\n let sourceOut = source;\n for (const { find, replace, optional } of replacements) {\n if (!optional) {\n const found = find instanceof RegExp ? find.test(sourceOut) : sourceOut.includes(find);\n if (!found) {\n const tmpPath = join(tmpdir(), `replace-error-${Math.random()}`);\n writeFileSync(tmpPath, sourceOut, \"utf-8\");\n throw new Error(\n `Substring or pattern \"${find}\" not found in the string, replacing in source: ${tmpPath}.`\n );\n }\n }\n sourceOut = sourceOut.replace(find, replace);\n }\n return sourceOut;\n}\nexport {\n mustReplace\n};\n//# sourceMappingURL=mustReplace.js.map\n"],"mappings":";;;;;AAGA,SAAS,YAAY,QAAQ,cAAc;CACzC,IAAI,YAAY;CAChB,KAAK,MAAM,EAAE,MAAM,SAAS,cAAc,cAAc;EACtD,IAAI,CAAC,UAAU;GACb,MAAM,QAAQ,gBAAgB,SAAS,KAAK,KAAK,SAAS,IAAI,UAAU,SAAS,IAAI;GACrF,IAAI,CAAC,OAAO;IACV,MAAM,UAAU,KAAK,OAAO,GAAG,iBAAiB,KAAK,OAAO,GAAG;IAC/D,cAAc,SAAS,WAAW,OAAO;IACzC,MAAM,IAAI,MACR,yBAAyB,KAAK,kDAAkD,QAAQ,EAC1F;GACF;EACF;EACA,YAAY,UAAU,QAAQ,MAAM,OAAO;CAC7C;CACA,OAAO;AACT"}
@@ -1,50 +1,39 @@
1
1
  import { writeFileSync } from "fs";
2
2
  import { tmpdir } from "os";
3
3
  import { join } from "path";
4
- function _instanceof(left, right) {
5
- if (right != null && typeof Symbol !== "undefined" && right[Symbol.hasInstance]) {
6
- return !!right[Symbol.hasInstance](left);
7
- } else {
8
- return left instanceof right;
9
- }
10
- }
4
+
11
5
  function mustReplace(source, replacements) {
12
- var sourceOut = source;
13
- var _iteratorNormalCompletion = true,
14
- _didIteratorError = false,
15
- _iteratorError = void 0;
16
- try {
17
- for (var _iterator = replacements[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
18
- var {
19
- find,
20
- replace,
21
- optional
22
- } = _step.value;
23
- if (!optional) {
24
- var found = _instanceof(find, RegExp) ? find.test(sourceOut) : sourceOut.includes(find);
25
- if (!found) {
26
- var tmpPath = join(tmpdir(), `replace-error-${Math.random()}`);
27
- writeFileSync(tmpPath, sourceOut, "utf-8");
28
- throw new Error(`Substring or pattern "${find}" not found in the string, replacing in source: ${tmpPath}.`);
29
- }
30
- }
31
- sourceOut = sourceOut.replace(find, replace);
32
- }
33
- } catch (err) {
34
- _didIteratorError = true;
35
- _iteratorError = err;
36
- } finally {
37
- try {
38
- if (!_iteratorNormalCompletion && _iterator.return != null) {
39
- _iterator.return();
40
- }
41
- } finally {
42
- if (_didIteratorError) {
43
- throw _iteratorError;
44
- }
45
- }
46
- }
47
- return sourceOut;
6
+ var sourceOut = source;
7
+ var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = void 0;
8
+ try {
9
+ for (var _iterator = replacements[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
10
+ var { find, replace, optional } = _step.value;
11
+ if (!optional) {
12
+ var found = find instanceof RegExp ? find.test(sourceOut) : sourceOut.includes(find);
13
+ if (!found) {
14
+ var tmpPath = join(tmpdir(), `replace-error-${Math.random()}`);
15
+ writeFileSync(tmpPath, sourceOut, "utf-8");
16
+ throw new Error(`Substring or pattern "${find}" not found in the string, replacing in source: ${tmpPath}.`);
17
+ }
18
+ }
19
+ sourceOut = sourceOut.replace(find, replace);
20
+ }
21
+ } catch (err) {
22
+ _didIteratorError = true;
23
+ _iteratorError = err;
24
+ } finally {
25
+ try {
26
+ if (!_iteratorNormalCompletion && _iterator.return != null) {
27
+ _iterator.return();
28
+ }
29
+ } finally {
30
+ if (_didIteratorError) {
31
+ throw _iteratorError;
32
+ }
33
+ }
34
+ }
35
+ return sourceOut;
48
36
  }
37
+
49
38
  export { mustReplace };
50
39
  //# sourceMappingURL=mustReplace.native.js.map
@@ -1 +1 @@
1
- {"version":3,"names":["writeFileSync","tmpdir","join","_instanceof","left","right","Symbol","hasInstance","mustReplace","source","replacements","sourceOut","_iteratorNormalCompletion","_didIteratorError","_iteratorError","_iterator","iterator","_step","next","done","find","replace","optional","value","found","RegExp","test","includes","tmpPath","Math","random"],"sources":["../../src/mustReplace.ts"],"sourcesContent":[null],"mappings":"AAAA,SAASA,aAAA,QAAqB;AAC9B,SAASC,MAAA,QAAc;AACvB,SAASC,IAAA,QAAY;AAEd,SAASC,YACdC,IAAA,EAAAC,KACA;EAMA,IAAIA,KAAA,QAAY,WAAAC,MAAA,oBAAAD,KAAA,CAAAC,MAAA,CAAAC,WAAA;IAChB,SAAWF,KAAE,CAAAC,MAAM,CAAAC,WAAS,EAASH,IAAA,CAAK;EACxC,OAAK;IACH,OAAAA,IAAM,YACJC,KAAA;EACF;AACE;AACA,SAAAG,YAAAC,MAAc,EAAAC,YAAS,EAAW;EAClC,IAAAC,SAAM,GAAIF,MAAA;EAAA,IAAAG,yBACR,OAAyB;IAAIC,iBAAA;IAAAC,cAAA,SAAmD;EAAO;IACzF,KACF,IAAAC,SAAA,GAAAL,YAAA,CAAAJ,MAAA,CAAAU,QAAA,KAAAC,KAAA,IAAAL,yBAAA,IAAAK,KAAA,GAAAF,SAAA,CAAAG,IAAA,IAAAC,IAAA,GAAAP,yBAAA;MACF;QAAAQ,IAAA;QAAAC,OAAA;QAAAC;MAAA,IAAAL,KAAA,CAAAM,KAAA;MAGA,KAAAD,QAAY;QACd,IAAAE,KAAA,GAAArB,WAAA,CAAAiB,IAAA,EAAAK,MAAA,IAAAL,IAAA,CAAAM,IAAA,CAAAf,SAAA,IAAAA,SAAA,CAAAgB,QAAA,CAAAP,IAAA;QACA,IAAO,CAAAI,KAAA;UACT,IAAAI,OAAA,GAAA1B,IAAA,CAAAD,MAAA,qBAAA4B,IAAA,CAAAC,MAAA","ignoreList":[]}
1
+ {"version":3,"file":"mustReplace.native.js","names":[],"sources":["esm/mustReplace.native.js"],"sourcesContent":["import { writeFileSync } from \"fs\";\nimport { tmpdir } from \"os\";\nimport { join } from \"path\";\nfunction mustReplace(source, replacements) {\n var sourceOut = source;\n var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = void 0;\n try {\n for (var _iterator = replacements[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {\n var { find, replace, optional } = _step.value;\n if (!optional) {\n var found = find instanceof RegExp ? find.test(sourceOut) : sourceOut.includes(find);\n if (!found) {\n var tmpPath = join(tmpdir(), `replace-error-${Math.random()}`);\n writeFileSync(tmpPath, sourceOut, \"utf-8\");\n throw new Error(`Substring or pattern \"${find}\" not found in the string, replacing in source: ${tmpPath}.`);\n }\n }\n sourceOut = sourceOut.replace(find, replace);\n }\n } catch (err) {\n _didIteratorError = true;\n _iteratorError = err;\n } finally {\n try {\n if (!_iteratorNormalCompletion && _iterator.return != null) {\n _iterator.return();\n }\n } finally {\n if (_didIteratorError) {\n throw _iteratorError;\n }\n }\n }\n return sourceOut;\n}\nexport {\n mustReplace\n};\n//# sourceMappingURL=mustReplace.js.map\n"],"mappings":";;;;;AAGA,SAAS,YAAY,QAAQ,cAAc;CACzC,IAAI,YAAY;CAChB,IAAI,4BAA4B,MAAM,oBAAoB,OAAO,iBAAiB,KAAK;CACvF,IAAI;EACF,KAAK,IAAI,YAAY,aAAa,OAAO,SAAS,CAAC,GAAG,OAAO,EAAE,6BAA6B,QAAQ,UAAU,KAAK,EAAC,CAAE,OAAO,4BAA4B,MAAM;GAC7J,IAAI,EAAE,MAAM,SAAS,aAAa,MAAM;GACxC,IAAI,CAAC,UAAU;IACb,IAAI,QAAQ,gBAAgB,SAAS,KAAK,KAAK,SAAS,IAAI,UAAU,SAAS,IAAI;IACnF,IAAI,CAAC,OAAO;KACV,IAAI,UAAU,KAAK,OAAO,GAAG,iBAAiB,KAAK,OAAO,GAAG;KAC7D,cAAc,SAAS,WAAW,OAAO;KACzC,MAAM,IAAI,MAAM,yBAAyB,KAAK,kDAAkD,QAAQ,EAAE;IAC5G;GACF;GACA,YAAY,UAAU,QAAQ,MAAM,OAAO;EAC7C;CACF,SAAS,KAAK;EACZ,oBAAoB;EACpB,iBAAiB;CACnB,UAAU;EACR,IAAI;GACF,IAAI,CAAC,6BAA6B,UAAU,UAAU,MAAM;IAC1D,UAAU,OAAO;GACnB;EACF,UAAU;GACR,IAAI,mBAAmB;IACrB,MAAM;GACR;EACF;CACF;CACA,OAAO;AACT"}
@@ -0,0 +1,305 @@
1
+ const TARGET_NAME = /^[A-Za-z][A-Za-z0-9_]*$/;
2
+ const SCHEME = /^[a-z][a-z0-9+.-]*$/i;
3
+ const VERSION = /^\d+\.\d+\.\d+/;
4
+ const BUILD_NUMBER = /^[A-Za-z0-9.]+$/;
5
+ const REVERSE_DNS = /^[A-Za-z][A-Za-z0-9-]*(\.[A-Za-z][A-Za-z0-9-]*)+$/;
6
+ const DEPLOYMENT_TARGET = /^\d+\.\d+$/;
7
+ const HEX_COLOR = /^#[\da-f]{6}$/i;
8
+ const FONT_FILE = /\.(ttf|otf)$/i;
9
+ const ORIENTATIONS = [
10
+ "portrait",
11
+ "landscape",
12
+ "default"
13
+ ];
14
+ const USER_INTERFACE_STYLES = [
15
+ "light",
16
+ "dark",
17
+ "automatic"
18
+ ];
19
+ function fail(message) {
20
+ throw new Error(`[one] invalid native.app: ${message}`);
21
+ }
22
+ function validateNativeApp(manifest, platform) {
23
+ if (!manifest || typeof manifest !== "object") fail("manifest must be an object");
24
+ if (!manifest.name || typeof manifest.name !== "string") fail("name is required");
25
+ if (!TARGET_NAME.test(manifest.name)) {
26
+ fail(`name "${manifest.name}" must start with a letter and contain only letters, digits, and underscore`);
27
+ }
28
+ const schemes = manifest.scheme === void 0 ? [] : Array.isArray(manifest.scheme) ? manifest.scheme : [manifest.scheme];
29
+ for (const scheme of schemes) {
30
+ if (typeof scheme !== "string" || !SCHEME.test(scheme)) {
31
+ fail(`scheme "${scheme}" must be a valid uri scheme`);
32
+ }
33
+ }
34
+ if (manifest.orientation !== void 0 && !ORIENTATIONS.includes(manifest.orientation)) {
35
+ fail(`orientation "${manifest.orientation}" must be ${ORIENTATIONS.join(", ")}`);
36
+ }
37
+ if (manifest.userInterfaceStyle !== void 0 && !USER_INTERFACE_STYLES.includes(manifest.userInterfaceStyle)) {
38
+ fail(`userInterfaceStyle "${manifest.userInterfaceStyle}" must be ${USER_INTERFACE_STYLES.join(", ")}`);
39
+ }
40
+ if (manifest.fonts !== void 0) {
41
+ const names = /* @__PURE__ */ new Set();
42
+ for (const font of manifest.fonts) {
43
+ if (typeof font !== "string" || !FONT_FILE.test(font)) {
44
+ fail(`fonts entry "${font}" must be a .ttf or .otf file path`);
45
+ }
46
+ const name = font.split("/").pop() ?? font;
47
+ if (names.has(name)) fail(`fonts lists ${name} twice`);
48
+ names.add(name);
49
+ }
50
+ }
51
+ if (manifest.version !== void 0 && !VERSION.test(manifest.version)) {
52
+ fail(`version "${manifest.version}" must start with major.minor.patch`);
53
+ }
54
+ if (manifest.icon !== void 0 && (!manifest.icon.source || !HEX_COLOR.test(manifest.icon.backgroundColor))) {
55
+ fail("icon requires source and a six-digit hex backgroundColor");
56
+ }
57
+ if (manifest.ios?.alternateIcons !== void 0) {
58
+ if (!manifest.icon) fail("ios.alternateIcons requires a primary icon");
59
+ const entries = Object.entries(manifest.ios.alternateIcons);
60
+ if (entries.length === 0) fail("ios.alternateIcons requires at least one icon");
61
+ for (const [name, icon] of entries) {
62
+ if (name === "AppIcon" || !TARGET_NAME.test(name)) {
63
+ fail(`ios.alternateIcons name "${name}" must be an identifier other than AppIcon`);
64
+ }
65
+ if (!icon?.source || !HEX_COLOR.test(icon.backgroundColor)) {
66
+ fail(`ios.alternateIcons.${name} requires source and a six-digit hex backgroundColor`);
67
+ }
68
+ }
69
+ }
70
+ if (manifest.ios?.backgroundTasks !== void 0) {
71
+ const tasks = manifest.ios.backgroundTasks;
72
+ if (!tasks || tasks.refresh !== void 0 && !Array.isArray(tasks.refresh) || tasks.processing !== void 0 && !Array.isArray(tasks.processing)) {
73
+ fail("ios.backgroundTasks refresh and processing must be arrays of identifiers");
74
+ }
75
+ const identifiers = [...tasks.refresh ?? [], ...tasks.processing ?? []];
76
+ if (!identifiers.length || new Set(identifiers).size !== identifiers.length) {
77
+ fail("ios.backgroundTasks needs distinct refresh or processing identifiers");
78
+ }
79
+ for (const identifier of identifiers) {
80
+ if (typeof identifier !== "string" || !REVERSE_DNS.test(identifier)) {
81
+ fail(`ios.backgroundTasks identifier "${identifier}" must use reverse DNS notation`);
82
+ }
83
+ }
84
+ }
85
+ if (manifest.ios?.appIntents !== void 0) {
86
+ const actions = manifest.ios.appIntents?.actions;
87
+ if (!Array.isArray(actions) || actions.length === 0) {
88
+ fail("ios.appIntents.actions must be a non-empty array");
89
+ }
90
+ const ids = /* @__PURE__ */ new Set();
91
+ for (const action of actions) {
92
+ if (!action || typeof action !== "object" || typeof action.id !== "string" || !action.id.trim() || typeof action.title !== "string" || !action.title.trim() || action.textParameterTitle !== void 0 && (typeof action.textParameterTitle !== "string" || !action.textParameterTitle.trim()) || typeof action.shortcutPhrase !== "string" || action.shortcutPhrase.split("{app}").length !== 2 || !action.shortcutPhrase.replace("{app}", "").trim()) {
93
+ fail("ios.appIntents actions need unique non-empty id/title, optional textParameterTitle, and a shortcutPhrase with one {app}");
94
+ }
95
+ if (ids.has(action.id)) fail(`ios.appIntents action "${action.id}" is duplicated`);
96
+ ids.add(action.id);
97
+ }
98
+ }
99
+ if (manifest.splash !== void 0 && (!manifest.splash.source || !HEX_COLOR.test(manifest.splash.backgroundColor) || manifest.splash.width !== void 0 && (!Number.isFinite(manifest.splash.width) || manifest.splash.width < 1 || manifest.splash.width > 288))) {
100
+ fail("splash requires source, a six-digit hex backgroundColor, and width from 1 to 288");
101
+ }
102
+ if (manifest.splash?.dark !== void 0 && !HEX_COLOR.test(manifest.splash.dark.backgroundColor)) {
103
+ fail("splash.dark requires a six-digit hex backgroundColor");
104
+ }
105
+ if (manifest.splash?.dark?.backgroundImage !== void 0 && manifest.splash.backgroundImage === void 0) {
106
+ fail("splash.dark.backgroundImage needs splash.backgroundImage for the light launch");
107
+ }
108
+ if (manifest.splash?.resizeMode !== void 0 && manifest.splash.resizeMode !== "contain" && manifest.splash.resizeMode !== "cover") {
109
+ fail(`splash.resizeMode "${manifest.splash.resizeMode}" must be contain or cover`);
110
+ }
111
+ if (manifest.imagePicker?.camera !== void 0 && (typeof manifest.imagePicker.camera !== "string" || manifest.imagePicker.camera.trim() === "")) {
112
+ fail("imagePicker.camera must be a non-empty string");
113
+ }
114
+ if (manifest.photoLibrary !== void 0 && (!manifest.photoLibrary || manifest.photoLibrary.addOnly === void 0 && manifest.photoLibrary.readWrite === void 0)) {
115
+ fail("photoLibrary must configure addOnly or readWrite");
116
+ }
117
+ if (manifest.photoLibrary?.addOnly !== void 0 && (typeof manifest.photoLibrary.addOnly !== "string" || manifest.photoLibrary.addOnly.trim() === "")) {
118
+ fail("photoLibrary.addOnly must be a non-empty string");
119
+ }
120
+ if (manifest.photoLibrary?.readWrite !== void 0 && (typeof manifest.photoLibrary.readWrite !== "string" || manifest.photoLibrary.readWrite.trim() === "")) {
121
+ fail("photoLibrary.readWrite must be a non-empty string");
122
+ }
123
+ if (manifest.contacts !== void 0 && (!manifest.contacts || typeof manifest.contacts.usage !== "string" || manifest.contacts.usage.trim() === "")) {
124
+ fail("contacts.usage must be a non-empty string");
125
+ }
126
+ if (manifest.calendar !== void 0) {
127
+ if (!manifest.calendar || manifest.calendar.usage === void 0 && manifest.calendar.remindersUsage === void 0) {
128
+ fail("calendar.usage or calendar.remindersUsage must be a non-empty string");
129
+ }
130
+ if (manifest.calendar.usage !== void 0 && (typeof manifest.calendar.usage !== "string" || manifest.calendar.usage.trim() === "")) {
131
+ fail("calendar.usage must be a non-empty string");
132
+ }
133
+ if (manifest.calendar.remindersUsage !== void 0 && (typeof manifest.calendar.remindersUsage !== "string" || manifest.calendar.remindersUsage.trim() === "")) {
134
+ fail("calendar.remindersUsage must be a non-empty string");
135
+ }
136
+ }
137
+ if (manifest.location !== void 0 && (!manifest.location || typeof manifest.location.whenInUse !== "string" || manifest.location.whenInUse.trim() === "")) {
138
+ fail("location.whenInUse must be a non-empty string");
139
+ }
140
+ if (manifest.location?.background !== void 0 && typeof manifest.location.background !== "boolean") {
141
+ fail("location.background must be a boolean");
142
+ }
143
+ if (manifest.audio !== void 0) {
144
+ if (!manifest.audio || typeof manifest.audio !== "object") {
145
+ fail("audio must configure microphone or background playback");
146
+ }
147
+ if (manifest.audio.microphone !== void 0 && (typeof manifest.audio.microphone !== "string" || manifest.audio.microphone.trim() === "")) {
148
+ fail("audio.microphone must be a non-empty string");
149
+ }
150
+ if (manifest.audio.background !== void 0 && typeof manifest.audio.background !== "boolean") {
151
+ fail("audio.background must be a boolean");
152
+ }
153
+ if (manifest.audio.microphone === void 0 && manifest.audio.background !== true) {
154
+ fail("audio must configure microphone or background playback");
155
+ }
156
+ }
157
+ if (manifest.ios?.faceIdUsageDescription !== void 0 && (typeof manifest.ios.faceIdUsageDescription !== "string" || manifest.ios.faceIdUsageDescription.trim() === "")) {
158
+ fail("ios.faceIdUsageDescription must be a non-empty string");
159
+ }
160
+ if (manifest.speech !== void 0 && (typeof manifest.speech?.recognition !== "string" || manifest.speech.recognition.trim() === "" || typeof manifest.speech.microphone !== "string" || manifest.speech.microphone.trim() === "")) {
161
+ fail("speech.recognition and speech.microphone must be non-empty strings");
162
+ }
163
+ if (manifest.notifications !== void 0) {
164
+ if (typeof manifest.notifications !== "object" || manifest.notifications.push !== void 0 && typeof manifest.notifications.push !== "boolean") {
165
+ fail("notifications.push must be a boolean");
166
+ }
167
+ const aps = manifest.notifications.apsEnvironment;
168
+ if (aps !== void 0 && aps !== "development" && aps !== "production") {
169
+ fail(`notifications.apsEnvironment "${aps}" must be development or production`);
170
+ }
171
+ if (aps !== void 0 && !manifest.notifications.push) {
172
+ fail("notifications.apsEnvironment needs notifications.push");
173
+ }
174
+ }
175
+ const accent = manifest.ios?.accentColor;
176
+ if (accent !== void 0 && (!HEX_COLOR.test(accent.light) || accent.dark !== void 0 && !HEX_COLOR.test(accent.dark))) {
177
+ fail("ios.accentColor light and dark must be six-digit hex colors");
178
+ }
179
+ if (manifest.pictureInPicture !== void 0 && typeof manifest.pictureInPicture !== "boolean") {
180
+ fail("pictureInPicture must be a boolean");
181
+ }
182
+ if (manifest.updates !== void 0) {
183
+ if (typeof manifest.updates.runtimeVersion !== "string" || manifest.updates.runtimeVersion.trim() === "") {
184
+ fail("updates.runtimeVersion must be a non-empty string");
185
+ }
186
+ if (manifest.updates.url !== void 0 && (typeof manifest.updates.url !== "string" || manifest.updates.url.trim() === "")) {
187
+ fail("updates.url must be a non-empty string");
188
+ }
189
+ }
190
+ if (!platform || platform === "ios") {
191
+ if (!manifest.ios?.bundleId || !REVERSE_DNS.test(manifest.ios.bundleId)) {
192
+ fail(`ios.bundleId "${manifest.ios?.bundleId}" must be reverse-dns`);
193
+ }
194
+ if (manifest.ios.deploymentTarget !== void 0 && !DEPLOYMENT_TARGET.test(manifest.ios.deploymentTarget)) {
195
+ fail(`ios.deploymentTarget "${manifest.ios.deploymentTarget}" must look like "17.0"`);
196
+ }
197
+ if (manifest.ios.buildNumber !== void 0 && !BUILD_NUMBER.test(manifest.ios.buildNumber)) {
198
+ fail(`ios.buildNumber "${manifest.ios.buildNumber}" must contain only letters, digits, and dots`);
199
+ }
200
+ const widgets = manifest.ios.widgets;
201
+ if (widgets) {
202
+ if (!manifest.ios.deploymentTarget || Number(manifest.ios.deploymentTarget) < 17) {
203
+ fail("ios.widgets requires ios.deploymentTarget of 17.0 or newer");
204
+ }
205
+ if (!/^group\.[A-Za-z][A-Za-z0-9-]*(\.[A-Za-z][A-Za-z0-9-]*)+$/.test(widgets.appGroup)) {
206
+ fail("ios.widgets.appGroup must be a reverse-dns App Group beginning with group.");
207
+ }
208
+ if (!/^[A-Za-z][A-Za-z0-9._-]*$/.test(widgets.kind)) {
209
+ fail("ios.widgets.kind must be a non-empty WidgetKit kind");
210
+ }
211
+ if (!widgets.displayName?.trim() || !widgets.description?.trim()) {
212
+ fail("ios.widgets.displayName and description must be non-empty strings");
213
+ }
214
+ if (widgets.pushNotifications !== void 0 && typeof widgets.pushNotifications !== "boolean") {
215
+ fail("ios.widgets.pushNotifications must be a boolean");
216
+ }
217
+ }
218
+ }
219
+ if (!platform || platform === "android") {
220
+ if (!manifest.android?.applicationId || !REVERSE_DNS.test(manifest.android.applicationId)) {
221
+ fail(`android.applicationId "${manifest.android?.applicationId}" must be reverse-dns`);
222
+ }
223
+ if (manifest.android.minSdk !== void 0 && (!Number.isInteger(manifest.android.minSdk) || manifest.android.minSdk < 21 || manifest.android.minSdk > 36)) {
224
+ fail(`android.minSdk "${manifest.android.minSdk}" must be an integer from 21 to 36`);
225
+ }
226
+ if (manifest.android.versionCode !== void 0 && (!Number.isInteger(manifest.android.versionCode) || manifest.android.versionCode < 1)) {
227
+ fail(`android.versionCode "${manifest.android.versionCode}" must be a positive integer`);
228
+ }
229
+ for (const key of ["targetSdk", "compileSdk"]) {
230
+ const value = manifest.android[key];
231
+ if (value !== void 0 && (!Number.isInteger(value) || value < 21)) {
232
+ fail(`android.${key} "${value}" must be an api level integer`);
233
+ }
234
+ }
235
+ if (manifest.android.shrinkResources && !manifest.android.minify) {
236
+ fail("android.shrinkResources needs android.minify");
237
+ }
238
+ for (const link of manifest.android.appLinks ?? []) {
239
+ if (!link.host || !REVERSE_DNS.test(link.host)) {
240
+ fail(`android.appLinks host "${link.host}" must be a domain`);
241
+ }
242
+ if (link.pathPrefix !== void 0 && !link.pathPrefix.startsWith("/")) {
243
+ fail(`android.appLinks pathPrefix "${link.pathPrefix}" must start with /`);
244
+ }
245
+ }
246
+ const adaptiveIcon = manifest.android.adaptiveIcon;
247
+ if (adaptiveIcon !== void 0 && (!adaptiveIcon.foreground || adaptiveIcon.backgroundColor !== void 0 && !HEX_COLOR.test(adaptiveIcon.backgroundColor))) {
248
+ fail("android.adaptiveIcon requires foreground, and backgroundColor must be six-digit hex");
249
+ }
250
+ if (manifest.android.googleMapsApiKey !== void 0 && (typeof manifest.android.googleMapsApiKey !== "string" || manifest.android.googleMapsApiKey.trim() === "")) {
251
+ fail("android.googleMapsApiKey must be a non-empty string");
252
+ }
253
+ }
254
+ return manifest;
255
+ }
256
+ function expoClientFromNativeApp(app) {
257
+ return {
258
+ name: app.displayName ?? app.name,
259
+ slug: app.name,
260
+ scheme: app.scheme,
261
+ version: app.version,
262
+ orientation: app.orientation,
263
+ userInterfaceStyle: app.userInterfaceStyle ?? "automatic",
264
+ icon: app.icon?.source,
265
+ splash: app.splash && {
266
+ image: app.splash.source,
267
+ backgroundImage: app.splash.backgroundImage,
268
+ backgroundColor: app.splash.backgroundColor,
269
+ imageWidth: app.splash.width,
270
+ resizeMode: app.splash.resizeMode,
271
+ dark: app.splash.dark && {
272
+ image: app.splash.dark.source,
273
+ backgroundImage: app.splash.dark.backgroundImage,
274
+ backgroundColor: app.splash.dark.backgroundColor
275
+ }
276
+ },
277
+ plugins: app.fonts?.length ? [["expo-font", { fonts: app.fonts }]] : void 0,
278
+ ios: app.ios && {
279
+ bundleIdentifier: app.ios.bundleId,
280
+ buildNumber: app.ios.buildNumber,
281
+ supportsTablet: app.ios.tablet,
282
+ associatedDomains: app.ios.associatedDomains,
283
+ usesAppleSignIn: app.ios.usesAppleSignIn,
284
+ googleServicesFile: app.ios.googleServicesFile,
285
+ infoPlist: app.ios.infoPlist,
286
+ entitlements: app.ios.entitlements
287
+ },
288
+ android: app.android && {
289
+ package: app.android.applicationId,
290
+ versionCode: app.android.versionCode,
291
+ permissions: app.android.permissions,
292
+ blockedPermissions: app.android.blockedPermissions,
293
+ googleServicesFile: app.android.googleServicesFile,
294
+ adaptiveIcon: app.android.adaptiveIcon && {
295
+ foregroundImage: app.android.adaptiveIcon.foreground,
296
+ backgroundImage: app.android.adaptiveIcon.background,
297
+ backgroundColor: app.android.adaptiveIcon.backgroundColor,
298
+ monochromeImage: app.android.adaptiveIcon.monochrome
299
+ }
300
+ }
301
+ };
302
+ }
303
+
304
+ export { expoClientFromNativeApp, validateNativeApp };
305
+ //# sourceMappingURL=nativeAppManifest.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"nativeAppManifest.js","names":[],"sources":["esm/nativeAppManifest.js"],"sourcesContent":["const TARGET_NAME = /^[A-Za-z][A-Za-z0-9_]*$/;\nconst SCHEME = /^[a-z][a-z0-9+.-]*$/i;\nconst VERSION = /^\\d+\\.\\d+\\.\\d+/;\nconst BUILD_NUMBER = /^[A-Za-z0-9.]+$/;\nconst REVERSE_DNS = /^[A-Za-z][A-Za-z0-9-]*(\\.[A-Za-z][A-Za-z0-9-]*)+$/;\nconst DEPLOYMENT_TARGET = /^\\d+\\.\\d+$/;\nconst HEX_COLOR = /^#[\\da-f]{6}$/i;\nconst FONT_FILE = /\\.(ttf|otf)$/i;\nconst ORIENTATIONS = [\"portrait\", \"landscape\", \"default\"];\nconst USER_INTERFACE_STYLES = [\"light\", \"dark\", \"automatic\"];\nfunction fail(message) {\n throw new Error(`[one] invalid native.app: ${message}`);\n}\nfunction validateNativeApp(manifest, platform) {\n if (!manifest || typeof manifest !== \"object\") fail(\"manifest must be an object\");\n if (!manifest.name || typeof manifest.name !== \"string\") fail(\"name is required\");\n if (!TARGET_NAME.test(manifest.name)) {\n fail(\n `name \"${manifest.name}\" must start with a letter and contain only letters, digits, and underscore`\n );\n }\n const schemes = manifest.scheme === void 0 ? [] : Array.isArray(manifest.scheme) ? manifest.scheme : [manifest.scheme];\n for (const scheme of schemes) {\n if (typeof scheme !== \"string\" || !SCHEME.test(scheme)) {\n fail(`scheme \"${scheme}\" must be a valid uri scheme`);\n }\n }\n if (manifest.orientation !== void 0 && !ORIENTATIONS.includes(manifest.orientation)) {\n fail(`orientation \"${manifest.orientation}\" must be ${ORIENTATIONS.join(\", \")}`);\n }\n if (manifest.userInterfaceStyle !== void 0 && !USER_INTERFACE_STYLES.includes(manifest.userInterfaceStyle)) {\n fail(\n `userInterfaceStyle \"${manifest.userInterfaceStyle}\" must be ${USER_INTERFACE_STYLES.join(\", \")}`\n );\n }\n if (manifest.fonts !== void 0) {\n const names = /* @__PURE__ */ new Set();\n for (const font of manifest.fonts) {\n if (typeof font !== \"string\" || !FONT_FILE.test(font)) {\n fail(`fonts entry \"${font}\" must be a .ttf or .otf file path`);\n }\n const name = font.split(\"/\").pop() ?? font;\n if (names.has(name)) fail(`fonts lists ${name} twice`);\n names.add(name);\n }\n }\n if (manifest.version !== void 0 && !VERSION.test(manifest.version)) {\n fail(`version \"${manifest.version}\" must start with major.minor.patch`);\n }\n if (manifest.icon !== void 0 && (!manifest.icon.source || !HEX_COLOR.test(manifest.icon.backgroundColor))) {\n fail(\"icon requires source and a six-digit hex backgroundColor\");\n }\n if (manifest.ios?.alternateIcons !== void 0) {\n if (!manifest.icon) fail(\"ios.alternateIcons requires a primary icon\");\n const entries = Object.entries(manifest.ios.alternateIcons);\n if (entries.length === 0) fail(\"ios.alternateIcons requires at least one icon\");\n for (const [name, icon] of entries) {\n if (name === \"AppIcon\" || !TARGET_NAME.test(name)) {\n fail(`ios.alternateIcons name \"${name}\" must be an identifier other than AppIcon`);\n }\n if (!icon?.source || !HEX_COLOR.test(icon.backgroundColor)) {\n fail(\n `ios.alternateIcons.${name} requires source and a six-digit hex backgroundColor`\n );\n }\n }\n }\n if (manifest.ios?.backgroundTasks !== void 0) {\n const tasks = manifest.ios.backgroundTasks;\n if (!tasks || tasks.refresh !== void 0 && !Array.isArray(tasks.refresh) || tasks.processing !== void 0 && !Array.isArray(tasks.processing)) {\n fail(\"ios.backgroundTasks refresh and processing must be arrays of identifiers\");\n }\n const identifiers = [...tasks.refresh ?? [], ...tasks.processing ?? []];\n if (!identifiers.length || new Set(identifiers).size !== identifiers.length) {\n fail(\"ios.backgroundTasks needs distinct refresh or processing identifiers\");\n }\n for (const identifier of identifiers) {\n if (typeof identifier !== \"string\" || !REVERSE_DNS.test(identifier)) {\n fail(\n `ios.backgroundTasks identifier \"${identifier}\" must use reverse DNS notation`\n );\n }\n }\n }\n if (manifest.ios?.appIntents !== void 0) {\n const actions = manifest.ios.appIntents?.actions;\n if (!Array.isArray(actions) || actions.length === 0) {\n fail(\"ios.appIntents.actions must be a non-empty array\");\n }\n const ids = /* @__PURE__ */ new Set();\n for (const action of actions) {\n if (!action || typeof action !== \"object\" || typeof action.id !== \"string\" || !action.id.trim() || typeof action.title !== \"string\" || !action.title.trim() || action.textParameterTitle !== void 0 && (typeof action.textParameterTitle !== \"string\" || !action.textParameterTitle.trim()) || typeof action.shortcutPhrase !== \"string\" || action.shortcutPhrase.split(\"{app}\").length !== 2 || !action.shortcutPhrase.replace(\"{app}\", \"\").trim()) {\n fail(\n \"ios.appIntents actions need unique non-empty id/title, optional textParameterTitle, and a shortcutPhrase with one {app}\"\n );\n }\n if (ids.has(action.id)) fail(`ios.appIntents action \"${action.id}\" is duplicated`);\n ids.add(action.id);\n }\n }\n if (manifest.splash !== void 0 && (!manifest.splash.source || !HEX_COLOR.test(manifest.splash.backgroundColor) || manifest.splash.width !== void 0 && (!Number.isFinite(manifest.splash.width) || manifest.splash.width < 1 || manifest.splash.width > 288))) {\n fail(\n \"splash requires source, a six-digit hex backgroundColor, and width from 1 to 288\"\n );\n }\n if (manifest.splash?.dark !== void 0 && !HEX_COLOR.test(manifest.splash.dark.backgroundColor)) {\n fail(\"splash.dark requires a six-digit hex backgroundColor\");\n }\n if (manifest.splash?.dark?.backgroundImage !== void 0 && manifest.splash.backgroundImage === void 0) {\n fail(\"splash.dark.backgroundImage needs splash.backgroundImage for the light launch\");\n }\n if (manifest.splash?.resizeMode !== void 0 && manifest.splash.resizeMode !== \"contain\" && manifest.splash.resizeMode !== \"cover\") {\n fail(`splash.resizeMode \"${manifest.splash.resizeMode}\" must be contain or cover`);\n }\n if (manifest.imagePicker?.camera !== void 0 && (typeof manifest.imagePicker.camera !== \"string\" || manifest.imagePicker.camera.trim() === \"\")) {\n fail(\"imagePicker.camera must be a non-empty string\");\n }\n if (manifest.photoLibrary !== void 0 && (!manifest.photoLibrary || manifest.photoLibrary.addOnly === void 0 && manifest.photoLibrary.readWrite === void 0)) {\n fail(\"photoLibrary must configure addOnly or readWrite\");\n }\n if (manifest.photoLibrary?.addOnly !== void 0 && (typeof manifest.photoLibrary.addOnly !== \"string\" || manifest.photoLibrary.addOnly.trim() === \"\")) {\n fail(\"photoLibrary.addOnly must be a non-empty string\");\n }\n if (manifest.photoLibrary?.readWrite !== void 0 && (typeof manifest.photoLibrary.readWrite !== \"string\" || manifest.photoLibrary.readWrite.trim() === \"\")) {\n fail(\"photoLibrary.readWrite must be a non-empty string\");\n }\n if (manifest.contacts !== void 0 && (!manifest.contacts || typeof manifest.contacts.usage !== \"string\" || manifest.contacts.usage.trim() === \"\")) {\n fail(\"contacts.usage must be a non-empty string\");\n }\n if (manifest.calendar !== void 0) {\n if (!manifest.calendar || manifest.calendar.usage === void 0 && manifest.calendar.remindersUsage === void 0) {\n fail(\"calendar.usage or calendar.remindersUsage must be a non-empty string\");\n }\n if (manifest.calendar.usage !== void 0 && (typeof manifest.calendar.usage !== \"string\" || manifest.calendar.usage.trim() === \"\")) {\n fail(\"calendar.usage must be a non-empty string\");\n }\n if (manifest.calendar.remindersUsage !== void 0 && (typeof manifest.calendar.remindersUsage !== \"string\" || manifest.calendar.remindersUsage.trim() === \"\")) {\n fail(\"calendar.remindersUsage must be a non-empty string\");\n }\n }\n if (manifest.location !== void 0 && (!manifest.location || typeof manifest.location.whenInUse !== \"string\" || manifest.location.whenInUse.trim() === \"\")) {\n fail(\"location.whenInUse must be a non-empty string\");\n }\n if (manifest.location?.background !== void 0 && typeof manifest.location.background !== \"boolean\") {\n fail(\"location.background must be a boolean\");\n }\n if (manifest.audio !== void 0) {\n if (!manifest.audio || typeof manifest.audio !== \"object\") {\n fail(\"audio must configure microphone or background playback\");\n }\n if (manifest.audio.microphone !== void 0 && (typeof manifest.audio.microphone !== \"string\" || manifest.audio.microphone.trim() === \"\")) {\n fail(\"audio.microphone must be a non-empty string\");\n }\n if (manifest.audio.background !== void 0 && typeof manifest.audio.background !== \"boolean\") {\n fail(\"audio.background must be a boolean\");\n }\n if (manifest.audio.microphone === void 0 && manifest.audio.background !== true) {\n fail(\"audio must configure microphone or background playback\");\n }\n }\n if (manifest.ios?.faceIdUsageDescription !== void 0 && (typeof manifest.ios.faceIdUsageDescription !== \"string\" || manifest.ios.faceIdUsageDescription.trim() === \"\")) {\n fail(\"ios.faceIdUsageDescription must be a non-empty string\");\n }\n if (manifest.speech !== void 0 && (typeof manifest.speech?.recognition !== \"string\" || manifest.speech.recognition.trim() === \"\" || typeof manifest.speech.microphone !== \"string\" || manifest.speech.microphone.trim() === \"\")) {\n fail(\"speech.recognition and speech.microphone must be non-empty strings\");\n }\n if (manifest.notifications !== void 0) {\n if (typeof manifest.notifications !== \"object\" || manifest.notifications.push !== void 0 && typeof manifest.notifications.push !== \"boolean\") {\n fail(\"notifications.push must be a boolean\");\n }\n const aps = manifest.notifications.apsEnvironment;\n if (aps !== void 0 && aps !== \"development\" && aps !== \"production\") {\n fail(`notifications.apsEnvironment \"${aps}\" must be development or production`);\n }\n if (aps !== void 0 && !manifest.notifications.push) {\n fail(\"notifications.apsEnvironment needs notifications.push\");\n }\n }\n const accent = manifest.ios?.accentColor;\n if (accent !== void 0 && (!HEX_COLOR.test(accent.light) || accent.dark !== void 0 && !HEX_COLOR.test(accent.dark))) {\n fail(\"ios.accentColor light and dark must be six-digit hex colors\");\n }\n if (manifest.pictureInPicture !== void 0 && typeof manifest.pictureInPicture !== \"boolean\") {\n fail(\"pictureInPicture must be a boolean\");\n }\n if (manifest.updates !== void 0) {\n if (typeof manifest.updates.runtimeVersion !== \"string\" || manifest.updates.runtimeVersion.trim() === \"\") {\n fail(\"updates.runtimeVersion must be a non-empty string\");\n }\n if (manifest.updates.url !== void 0 && (typeof manifest.updates.url !== \"string\" || manifest.updates.url.trim() === \"\")) {\n fail(\"updates.url must be a non-empty string\");\n }\n }\n if (!platform || platform === \"ios\") {\n if (!manifest.ios?.bundleId || !REVERSE_DNS.test(manifest.ios.bundleId)) {\n fail(`ios.bundleId \"${manifest.ios?.bundleId}\" must be reverse-dns`);\n }\n if (manifest.ios.deploymentTarget !== void 0 && !DEPLOYMENT_TARGET.test(manifest.ios.deploymentTarget)) {\n fail(\n `ios.deploymentTarget \"${manifest.ios.deploymentTarget}\" must look like \"17.0\"`\n );\n }\n if (manifest.ios.buildNumber !== void 0 && !BUILD_NUMBER.test(manifest.ios.buildNumber)) {\n fail(\n `ios.buildNumber \"${manifest.ios.buildNumber}\" must contain only letters, digits, and dots`\n );\n }\n const widgets = manifest.ios.widgets;\n if (widgets) {\n if (!manifest.ios.deploymentTarget || Number(manifest.ios.deploymentTarget) < 17) {\n fail(\"ios.widgets requires ios.deploymentTarget of 17.0 or newer\");\n }\n if (!/^group\\.[A-Za-z][A-Za-z0-9-]*(\\.[A-Za-z][A-Za-z0-9-]*)+$/.test(widgets.appGroup)) {\n fail(\"ios.widgets.appGroup must be a reverse-dns App Group beginning with group.\");\n }\n if (!/^[A-Za-z][A-Za-z0-9._-]*$/.test(widgets.kind)) {\n fail(\"ios.widgets.kind must be a non-empty WidgetKit kind\");\n }\n if (!widgets.displayName?.trim() || !widgets.description?.trim()) {\n fail(\"ios.widgets.displayName and description must be non-empty strings\");\n }\n if (widgets.pushNotifications !== void 0 && typeof widgets.pushNotifications !== \"boolean\") {\n fail(\"ios.widgets.pushNotifications must be a boolean\");\n }\n }\n }\n if (!platform || platform === \"android\") {\n if (!manifest.android?.applicationId || !REVERSE_DNS.test(manifest.android.applicationId)) {\n fail(\n `android.applicationId \"${manifest.android?.applicationId}\" must be reverse-dns`\n );\n }\n if (manifest.android.minSdk !== void 0 && (!Number.isInteger(manifest.android.minSdk) || manifest.android.minSdk < 21 || manifest.android.minSdk > 36)) {\n fail(`android.minSdk \"${manifest.android.minSdk}\" must be an integer from 21 to 36`);\n }\n if (manifest.android.versionCode !== void 0 && (!Number.isInteger(manifest.android.versionCode) || manifest.android.versionCode < 1)) {\n fail(\n `android.versionCode \"${manifest.android.versionCode}\" must be a positive integer`\n );\n }\n for (const key of [\"targetSdk\", \"compileSdk\"]) {\n const value = manifest.android[key];\n if (value !== void 0 && (!Number.isInteger(value) || value < 21)) {\n fail(`android.${key} \"${value}\" must be an api level integer`);\n }\n }\n if (manifest.android.shrinkResources && !manifest.android.minify) {\n fail(\"android.shrinkResources needs android.minify\");\n }\n for (const link of manifest.android.appLinks ?? []) {\n if (!link.host || !REVERSE_DNS.test(link.host)) {\n fail(`android.appLinks host \"${link.host}\" must be a domain`);\n }\n if (link.pathPrefix !== void 0 && !link.pathPrefix.startsWith(\"/\")) {\n fail(`android.appLinks pathPrefix \"${link.pathPrefix}\" must start with /`);\n }\n }\n const adaptiveIcon = manifest.android.adaptiveIcon;\n if (adaptiveIcon !== void 0 && (!adaptiveIcon.foreground || adaptiveIcon.backgroundColor !== void 0 && !HEX_COLOR.test(adaptiveIcon.backgroundColor))) {\n fail(\n \"android.adaptiveIcon requires foreground, and backgroundColor must be six-digit hex\"\n );\n }\n if (manifest.android.googleMapsApiKey !== void 0 && (typeof manifest.android.googleMapsApiKey !== \"string\" || manifest.android.googleMapsApiKey.trim() === \"\")) {\n fail(\"android.googleMapsApiKey must be a non-empty string\");\n }\n }\n return manifest;\n}\nfunction expoClientFromNativeApp(app) {\n return {\n name: app.displayName ?? app.name,\n slug: app.name,\n scheme: app.scheme,\n version: app.version,\n orientation: app.orientation,\n // an expo config without the key means light, while prebuild writes no\n // UIUserInterfaceStyle for an unset style and the app follows the system,\n // so the manifest states the style the built app has.\n userInterfaceStyle: app.userInterfaceStyle ?? \"automatic\",\n icon: app.icon?.source,\n splash: app.splash && {\n image: app.splash.source,\n backgroundImage: app.splash.backgroundImage,\n backgroundColor: app.splash.backgroundColor,\n imageWidth: app.splash.width,\n resizeMode: app.splash.resizeMode,\n dark: app.splash.dark && {\n image: app.splash.dark.source,\n backgroundImage: app.splash.dark.backgroundImage,\n backgroundColor: app.splash.dark.backgroundColor\n }\n },\n plugins: app.fonts?.length ? [[\"expo-font\", { fonts: app.fonts }]] : void 0,\n ios: app.ios && {\n bundleIdentifier: app.ios.bundleId,\n buildNumber: app.ios.buildNumber,\n supportsTablet: app.ios.tablet,\n associatedDomains: app.ios.associatedDomains,\n usesAppleSignIn: app.ios.usesAppleSignIn,\n googleServicesFile: app.ios.googleServicesFile,\n infoPlist: app.ios.infoPlist,\n entitlements: app.ios.entitlements\n },\n android: app.android && {\n package: app.android.applicationId,\n versionCode: app.android.versionCode,\n permissions: app.android.permissions,\n blockedPermissions: app.android.blockedPermissions,\n googleServicesFile: app.android.googleServicesFile,\n adaptiveIcon: app.android.adaptiveIcon && {\n foregroundImage: app.android.adaptiveIcon.foreground,\n backgroundImage: app.android.adaptiveIcon.background,\n backgroundColor: app.android.adaptiveIcon.backgroundColor,\n monochromeImage: app.android.adaptiveIcon.monochrome\n }\n }\n };\n}\nexport {\n expoClientFromNativeApp,\n validateNativeApp\n};\n//# sourceMappingURL=nativeAppManifest.js.map\n"],"mappings":"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"}