chore: add mobile app

This commit is contained in:
2026-02-07 22:33:02 +01:00
parent db34640acc
commit e89384ad4e
29327 changed files with 3886944 additions and 12 deletions
+22
View File
@@ -0,0 +1,22 @@
The MIT License (MIT)
Copyright (c) 2015-present 650 Industries, Inc. (aka Expo)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
+16
View File
@@ -0,0 +1,16 @@
<!-- Title -->
<h1 align="center">
👋 Welcome to <br><code>@expo/prebuild-config</code>
</h1>
<p align="center">Get the modified config for <code>expo prebuild</code>.</p>
<p align="center">
<img src="https://flat.badgen.net/packagephobia/install/@expo/prebuild-config">
<a href="https://www.npmjs.com/package/@expo/prebuild-config">
<img src="https://flat.badgen.net/npm/dw/@expo/prebuild-config" target="_blank" />
</a>
</p>
<!-- Body -->
@@ -0,0 +1,12 @@
import { ModPlatform, StaticPlugin } from '@expo/config-plugins';
import { ExpoConfig } from '@expo/config-types';
/**
* Returns a list of packages that are autolinked to a project.
*
* @param projectRoot
* @param platforms platforms to check for
* @returns list of packages ex: `['expo-camera', 'react-native-screens']`
*/
export declare function getAutolinkedPackagesAsync(projectRoot: string, platforms?: ModPlatform[]): Promise<string[]>;
export declare function resolvePackagesList(platformPaths: Record<string, any>[]): string[];
export declare function shouldSkipAutoPlugin(config: Pick<ExpoConfig, '_internal'>, plugin: StaticPlugin | string): boolean;
@@ -0,0 +1,59 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.getAutolinkedPackagesAsync = getAutolinkedPackagesAsync;
exports.resolvePackagesList = resolvePackagesList;
exports.shouldSkipAutoPlugin = shouldSkipAutoPlugin;
function _unstableAutolinkingExports() {
const data = require("expo/internal/unstable-autolinking-exports");
_unstableAutolinkingExports = function () {
return data;
};
return data;
}
/**
* Returns a list of packages that are autolinked to a project.
*
* @param projectRoot
* @param platforms platforms to check for
* @returns list of packages ex: `['expo-camera', 'react-native-screens']`
*/
async function getAutolinkedPackagesAsync(projectRoot, platforms = ['ios', 'android']) {
const linker = (0, _unstableAutolinkingExports().makeCachedDependenciesLinker)({
projectRoot
});
const dependenciesPerPlatform = await Promise.all(platforms.map(platform => {
return (0, _unstableAutolinkingExports().scanExpoModuleResolutionsForPlatform)(linker, platform);
}));
return resolvePackagesList(dependenciesPerPlatform);
}
function resolvePackagesList(platformPaths) {
const allPlatformPaths = platformPaths.map(paths => Object.keys(paths)).flat();
const uniquePaths = [...new Set(allPlatformPaths)];
return uniquePaths.sort();
}
function shouldSkipAutoPlugin(config, plugin) {
// Hack workaround because expo-dev-client doesn't use expo modules.
if (plugin === 'expo-dev-client') {
return false;
}
// Only perform the check if `autolinkedModules` is defined, otherwise we assume
// this is a legacy runner which doesn't support autolinking.
if (Array.isArray(config._internal?.autolinkedModules)) {
// Resolve the pluginId as a string.
const pluginId = Array.isArray(plugin) ? plugin[0] : plugin;
if (typeof pluginId === 'string') {
// Determine if the autolinked modules list includes our moduleId
const isIncluded = config._internal.autolinkedModules.includes(pluginId);
if (!isIncluded) {
// If it doesn't then we know that any potential plugin shouldn't be applied automatically.
return true;
}
}
}
return false;
}
//# sourceMappingURL=getAutolinkedPackages.js.map
@@ -0,0 +1 @@
{"version":3,"file":"getAutolinkedPackages.js","names":["_unstableAutolinkingExports","data","require","getAutolinkedPackagesAsync","projectRoot","platforms","linker","makeCachedDependenciesLinker","dependenciesPerPlatform","Promise","all","map","platform","scanExpoModuleResolutionsForPlatform","resolvePackagesList","platformPaths","allPlatformPaths","paths","Object","keys","flat","uniquePaths","Set","sort","shouldSkipAutoPlugin","config","plugin","Array","isArray","_internal","autolinkedModules","pluginId","isIncluded","includes"],"sources":["../src/getAutolinkedPackages.ts"],"sourcesContent":["import { ModPlatform, StaticPlugin } from '@expo/config-plugins';\nimport { ExpoConfig } from '@expo/config-types';\nimport {\n makeCachedDependenciesLinker,\n scanExpoModuleResolutionsForPlatform,\n} from 'expo/internal/unstable-autolinking-exports';\n\n/**\n * Returns a list of packages that are autolinked to a project.\n *\n * @param projectRoot\n * @param platforms platforms to check for\n * @returns list of packages ex: `['expo-camera', 'react-native-screens']`\n */\nexport async function getAutolinkedPackagesAsync(\n projectRoot: string,\n platforms: ModPlatform[] = ['ios', 'android']\n) {\n const linker = makeCachedDependenciesLinker({ projectRoot });\n const dependenciesPerPlatform = await Promise.all(\n platforms.map((platform) => {\n return scanExpoModuleResolutionsForPlatform(linker, platform);\n })\n );\n return resolvePackagesList(dependenciesPerPlatform);\n}\n\nexport function resolvePackagesList(platformPaths: Record<string, any>[]) {\n const allPlatformPaths = platformPaths.map((paths) => Object.keys(paths)).flat();\n\n const uniquePaths = [...new Set(allPlatformPaths)];\n\n return uniquePaths.sort();\n}\n\nexport function shouldSkipAutoPlugin(\n config: Pick<ExpoConfig, '_internal'>,\n plugin: StaticPlugin | string\n) {\n // Hack workaround because expo-dev-client doesn't use expo modules.\n if (plugin === 'expo-dev-client') {\n return false;\n }\n\n // Only perform the check if `autolinkedModules` is defined, otherwise we assume\n // this is a legacy runner which doesn't support autolinking.\n if (Array.isArray(config._internal?.autolinkedModules)) {\n // Resolve the pluginId as a string.\n const pluginId = Array.isArray(plugin) ? plugin[0] : plugin;\n if (typeof pluginId === 'string') {\n // Determine if the autolinked modules list includes our moduleId\n const isIncluded = config._internal!.autolinkedModules.includes(pluginId);\n if (!isIncluded) {\n // If it doesn't then we know that any potential plugin shouldn't be applied automatically.\n return true;\n }\n }\n }\n return false;\n}\n"],"mappings":";;;;;;;;AAEA,SAAAA,4BAAA;EAAA,MAAAC,IAAA,GAAAC,OAAA;EAAAF,2BAAA,YAAAA,CAAA;IAAA,OAAAC,IAAA;EAAA;EAAA,OAAAA,IAAA;AAAA;AAKA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,eAAeE,0BAA0BA,CAC9CC,WAAmB,EACnBC,SAAwB,GAAG,CAAC,KAAK,EAAE,SAAS,CAAC,EAC7C;EACA,MAAMC,MAAM,GAAG,IAAAC,0DAA4B,EAAC;IAAEH;EAAY,CAAC,CAAC;EAC5D,MAAMI,uBAAuB,GAAG,MAAMC,OAAO,CAACC,GAAG,CAC/CL,SAAS,CAACM,GAAG,CAAEC,QAAQ,IAAK;IAC1B,OAAO,IAAAC,kEAAoC,EAACP,MAAM,EAAEM,QAAQ,CAAC;EAC/D,CAAC,CACH,CAAC;EACD,OAAOE,mBAAmB,CAACN,uBAAuB,CAAC;AACrD;AAEO,SAASM,mBAAmBA,CAACC,aAAoC,EAAE;EACxE,MAAMC,gBAAgB,GAAGD,aAAa,CAACJ,GAAG,CAAEM,KAAK,IAAKC,MAAM,CAACC,IAAI,CAACF,KAAK,CAAC,CAAC,CAACG,IAAI,CAAC,CAAC;EAEhF,MAAMC,WAAW,GAAG,CAAC,GAAG,IAAIC,GAAG,CAACN,gBAAgB,CAAC,CAAC;EAElD,OAAOK,WAAW,CAACE,IAAI,CAAC,CAAC;AAC3B;AAEO,SAASC,oBAAoBA,CAClCC,MAAqC,EACrCC,MAA6B,EAC7B;EACA;EACA,IAAIA,MAAM,KAAK,iBAAiB,EAAE;IAChC,OAAO,KAAK;EACd;;EAEA;EACA;EACA,IAAIC,KAAK,CAACC,OAAO,CAACH,MAAM,CAACI,SAAS,EAAEC,iBAAiB,CAAC,EAAE;IACtD;IACA,MAAMC,QAAQ,GAAGJ,KAAK,CAACC,OAAO,CAACF,MAAM,CAAC,GAAGA,MAAM,CAAC,CAAC,CAAC,GAAGA,MAAM;IAC3D,IAAI,OAAOK,QAAQ,KAAK,QAAQ,EAAE;MAChC;MACA,MAAMC,UAAU,GAAGP,MAAM,CAACI,SAAS,CAAEC,iBAAiB,CAACG,QAAQ,CAACF,QAAQ,CAAC;MACzE,IAAI,CAACC,UAAU,EAAE;QACf;QACA,OAAO,IAAI;MACb;IACF;EACF;EACA,OAAO,KAAK;AACd","ignoreList":[]}
@@ -0,0 +1,7 @@
import { getConfig } from '@expo/config';
import { ModPlatform } from '@expo/config-plugins';
export declare function getPrebuildConfigAsync(projectRoot: string, props: {
bundleIdentifier?: string;
packageName?: string;
platforms: ModPlatform[];
}): Promise<ReturnType<typeof getConfig>>;
@@ -0,0 +1,84 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.getPrebuildConfigAsync = getPrebuildConfigAsync;
function _config() {
const data = require("@expo/config");
_config = function () {
return data;
};
return data;
}
function _getAutolinkedPackages() {
const data = require("./getAutolinkedPackages");
_getAutolinkedPackages = function () {
return data;
};
return data;
}
function _withDefaultPlugins() {
const data = require("./plugins/withDefaultPlugins");
_withDefaultPlugins = function () {
return data;
};
return data;
}
async function getPrebuildConfigAsync(projectRoot, props) {
const autolinkedModules = await (0, _getAutolinkedPackages().getAutolinkedPackagesAsync)(projectRoot, props.platforms);
return getPrebuildConfig(projectRoot, {
...props,
autolinkedModules
});
}
function getPrebuildConfig(projectRoot, {
platforms,
bundleIdentifier,
packageName,
autolinkedModules
}) {
// let config: ExpoConfig;
let {
exp: config,
...rest
} = (0, _config().getConfig)(projectRoot, {
skipSDKVersionRequirement: true,
isModdedConfig: true
});
if (autolinkedModules) {
if (!config._internal) {
config._internal = {};
}
config._internal.autolinkedModules = autolinkedModules;
}
// Add all built-in plugins first because they should take
// priority over the unversioned plugins.
config = (0, _withDefaultPlugins().withVersionedExpoSDKPlugins)(config);
config = (0, _withDefaultPlugins().withLegacyExpoPlugins)(config);
if (platforms.includes('ios')) {
if (!config.ios) config.ios = {};
config.ios.bundleIdentifier = bundleIdentifier ?? config.ios.bundleIdentifier ?? `com.placeholder.appid`;
// Add all built-in plugins
config = (0, _withDefaultPlugins().withIosExpoPlugins)(config, {
bundleIdentifier: config.ios.bundleIdentifier
});
}
if (platforms.includes('android')) {
if (!config.android) config.android = {};
config.android.package = packageName ?? config.android.package ?? `com.placeholder.appid`;
// Add all built-in plugins
config = (0, _withDefaultPlugins().withAndroidExpoPlugins)(config, {
package: config.android.package,
projectRoot
});
}
return {
exp: config,
...rest
};
}
//# sourceMappingURL=getPrebuildConfig.js.map
@@ -0,0 +1 @@
{"version":3,"file":"getPrebuildConfig.js","names":["_config","data","require","_getAutolinkedPackages","_withDefaultPlugins","getPrebuildConfigAsync","projectRoot","props","autolinkedModules","getAutolinkedPackagesAsync","platforms","getPrebuildConfig","bundleIdentifier","packageName","exp","config","rest","getConfig","skipSDKVersionRequirement","isModdedConfig","_internal","withVersionedExpoSDKPlugins","withLegacyExpoPlugins","includes","ios","withIosExpoPlugins","android","package","withAndroidExpoPlugins"],"sources":["../src/getPrebuildConfig.ts"],"sourcesContent":["import { getConfig } from '@expo/config';\nimport { ModPlatform } from '@expo/config-plugins';\n\nimport { getAutolinkedPackagesAsync } from './getAutolinkedPackages';\nimport {\n withAndroidExpoPlugins,\n withIosExpoPlugins,\n withLegacyExpoPlugins,\n withVersionedExpoSDKPlugins,\n} from './plugins/withDefaultPlugins';\n\nexport async function getPrebuildConfigAsync(\n projectRoot: string,\n props: {\n bundleIdentifier?: string;\n packageName?: string;\n platforms: ModPlatform[];\n }\n): Promise<ReturnType<typeof getConfig>> {\n const autolinkedModules = await getAutolinkedPackagesAsync(projectRoot, props.platforms);\n\n return getPrebuildConfig(projectRoot, {\n ...props,\n autolinkedModules,\n });\n}\n\nfunction getPrebuildConfig(\n projectRoot: string,\n {\n platforms,\n bundleIdentifier,\n packageName,\n autolinkedModules,\n }: {\n bundleIdentifier?: string;\n packageName?: string;\n platforms: ModPlatform[];\n autolinkedModules?: string[];\n }\n) {\n // let config: ExpoConfig;\n let { exp: config, ...rest } = getConfig(projectRoot, {\n skipSDKVersionRequirement: true,\n isModdedConfig: true,\n });\n\n if (autolinkedModules) {\n if (!config._internal) {\n config._internal = {};\n }\n config._internal.autolinkedModules = autolinkedModules;\n }\n\n // Add all built-in plugins first because they should take\n // priority over the unversioned plugins.\n config = withVersionedExpoSDKPlugins(config);\n config = withLegacyExpoPlugins(config);\n\n if (platforms.includes('ios')) {\n if (!config.ios) config.ios = {};\n config.ios.bundleIdentifier =\n bundleIdentifier ?? config.ios.bundleIdentifier ?? `com.placeholder.appid`;\n\n // Add all built-in plugins\n config = withIosExpoPlugins(config, {\n bundleIdentifier: config.ios.bundleIdentifier,\n });\n }\n\n if (platforms.includes('android')) {\n if (!config.android) config.android = {};\n config.android.package = packageName ?? config.android.package ?? `com.placeholder.appid`;\n\n // Add all built-in plugins\n config = withAndroidExpoPlugins(config, {\n package: config.android.package,\n projectRoot,\n });\n }\n\n return { exp: config, ...rest };\n}\n"],"mappings":";;;;;;AAAA,SAAAA,QAAA;EAAA,MAAAC,IAAA,GAAAC,OAAA;EAAAF,OAAA,YAAAA,CAAA;IAAA,OAAAC,IAAA;EAAA;EAAA,OAAAA,IAAA;AAAA;AAGA,SAAAE,uBAAA;EAAA,MAAAF,IAAA,GAAAC,OAAA;EAAAC,sBAAA,YAAAA,CAAA;IAAA,OAAAF,IAAA;EAAA;EAAA,OAAAA,IAAA;AAAA;AACA,SAAAG,oBAAA;EAAA,MAAAH,IAAA,GAAAC,OAAA;EAAAE,mBAAA,YAAAA,CAAA;IAAA,OAAAH,IAAA;EAAA;EAAA,OAAAA,IAAA;AAAA;AAOO,eAAeI,sBAAsBA,CAC1CC,WAAmB,EACnBC,KAIC,EACsC;EACvC,MAAMC,iBAAiB,GAAG,MAAM,IAAAC,mDAA0B,EAACH,WAAW,EAAEC,KAAK,CAACG,SAAS,CAAC;EAExF,OAAOC,iBAAiB,CAACL,WAAW,EAAE;IACpC,GAAGC,KAAK;IACRC;EACF,CAAC,CAAC;AACJ;AAEA,SAASG,iBAAiBA,CACxBL,WAAmB,EACnB;EACEI,SAAS;EACTE,gBAAgB;EAChBC,WAAW;EACXL;AAMF,CAAC,EACD;EACA;EACA,IAAI;IAAEM,GAAG,EAAEC,MAAM;IAAE,GAAGC;EAAK,CAAC,GAAG,IAAAC,mBAAS,EAACX,WAAW,EAAE;IACpDY,yBAAyB,EAAE,IAAI;IAC/BC,cAAc,EAAE;EAClB,CAAC,CAAC;EAEF,IAAIX,iBAAiB,EAAE;IACrB,IAAI,CAACO,MAAM,CAACK,SAAS,EAAE;MACrBL,MAAM,CAACK,SAAS,GAAG,CAAC,CAAC;IACvB;IACAL,MAAM,CAACK,SAAS,CAACZ,iBAAiB,GAAGA,iBAAiB;EACxD;;EAEA;EACA;EACAO,MAAM,GAAG,IAAAM,iDAA2B,EAACN,MAAM,CAAC;EAC5CA,MAAM,GAAG,IAAAO,2CAAqB,EAACP,MAAM,CAAC;EAEtC,IAAIL,SAAS,CAACa,QAAQ,CAAC,KAAK,CAAC,EAAE;IAC7B,IAAI,CAACR,MAAM,CAACS,GAAG,EAAET,MAAM,CAACS,GAAG,GAAG,CAAC,CAAC;IAChCT,MAAM,CAACS,GAAG,CAACZ,gBAAgB,GACzBA,gBAAgB,IAAIG,MAAM,CAACS,GAAG,CAACZ,gBAAgB,IAAI,uBAAuB;;IAE5E;IACAG,MAAM,GAAG,IAAAU,wCAAkB,EAACV,MAAM,EAAE;MAClCH,gBAAgB,EAAEG,MAAM,CAACS,GAAG,CAACZ;IAC/B,CAAC,CAAC;EACJ;EAEA,IAAIF,SAAS,CAACa,QAAQ,CAAC,SAAS,CAAC,EAAE;IACjC,IAAI,CAACR,MAAM,CAACW,OAAO,EAAEX,MAAM,CAACW,OAAO,GAAG,CAAC,CAAC;IACxCX,MAAM,CAACW,OAAO,CAACC,OAAO,GAAGd,WAAW,IAAIE,MAAM,CAACW,OAAO,CAACC,OAAO,IAAI,uBAAuB;;IAEzF;IACAZ,MAAM,GAAG,IAAAa,4CAAsB,EAACb,MAAM,EAAE;MACtCY,OAAO,EAAEZ,MAAM,CAACW,OAAO,CAACC,OAAO;MAC/BrB;IACF,CAAC,CAAC;EACJ;EAEA,OAAO;IAAEQ,GAAG,EAAEC,MAAM;IAAE,GAAGC;EAAK,CAAC;AACjC","ignoreList":[]}
+2
View File
@@ -0,0 +1,2 @@
export { getPrebuildConfigAsync } from './getPrebuildConfig';
export * from './plugins/withDefaultPlugins';
+34
View File
@@ -0,0 +1,34 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var _exportNames = {
getPrebuildConfigAsync: true
};
Object.defineProperty(exports, "getPrebuildConfigAsync", {
enumerable: true,
get: function () {
return _getPrebuildConfig().getPrebuildConfigAsync;
}
});
function _getPrebuildConfig() {
const data = require("./getPrebuildConfig");
_getPrebuildConfig = function () {
return data;
};
return data;
}
var _withDefaultPlugins = require("./plugins/withDefaultPlugins");
Object.keys(_withDefaultPlugins).forEach(function (key) {
if (key === "default" || key === "__esModule") return;
if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;
if (key in exports && exports[key] === _withDefaultPlugins[key]) return;
Object.defineProperty(exports, key, {
enumerable: true,
get: function () {
return _withDefaultPlugins[key];
}
});
});
//# sourceMappingURL=index.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"index.js","names":["_getPrebuildConfig","data","require","_withDefaultPlugins","Object","keys","forEach","key","prototype","hasOwnProperty","call","_exportNames","exports","defineProperty","enumerable","get"],"sources":["../src/index.ts"],"sourcesContent":["export { getPrebuildConfigAsync } from './getPrebuildConfig';\nexport * from './plugins/withDefaultPlugins';\n"],"mappings":";;;;;;;;;;;;;;AAAA,SAAAA,mBAAA;EAAA,MAAAC,IAAA,GAAAC,OAAA;EAAAF,kBAAA,YAAAA,CAAA;IAAA,OAAAC,IAAA;EAAA;EAAA,OAAAA,IAAA;AAAA;AACA,IAAAE,mBAAA,GAAAD,OAAA;AAAAE,MAAA,CAAAC,IAAA,CAAAF,mBAAA,EAAAG,OAAA,WAAAC,GAAA;EAAA,IAAAA,GAAA,kBAAAA,GAAA;EAAA,IAAAH,MAAA,CAAAI,SAAA,CAAAC,cAAA,CAAAC,IAAA,CAAAC,YAAA,EAAAJ,GAAA;EAAA,IAAAA,GAAA,IAAAK,OAAA,IAAAA,OAAA,CAAAL,GAAA,MAAAJ,mBAAA,CAAAI,GAAA;EAAAH,MAAA,CAAAS,cAAA,CAAAD,OAAA,EAAAL,GAAA;IAAAO,UAAA;IAAAC,GAAA,WAAAA,CAAA;MAAA,OAAAZ,mBAAA,CAAAI,GAAA;IAAA;EAAA;AAAA","ignoreList":[]}
@@ -0,0 +1,44 @@
export type ContentsJsonImageIdiom = 'iphone' | 'ipad' | 'watchos' | 'ios' | 'ios-marketing' | 'universal';
export type ContentsJsonImageAppearanceLuminosityType = 'light' | 'dark' | 'tinted';
export type ContentsJsonAppearance = {
appearance: 'luminosity';
value: ContentsJsonImageAppearanceLuminosityType;
};
export type ContentsJsonImageScale = '1x' | '2x' | '3x';
export interface ContentsJsonImage {
appearances?: ContentsJsonAppearance[];
idiom: ContentsJsonImageIdiom;
size?: string;
scale?: ContentsJsonImageScale;
filename?: string;
platform?: ContentsJsonImageIdiom;
}
export interface ContentsJsonColor {
appearances?: ContentsJsonAppearance[];
idiom: ContentsJsonImageIdiom;
color: {
'color-space': 'srgb';
components: {
alpha: string;
blue: string;
green: string;
red: string;
};
};
}
export interface ContentsJson {
images: ContentsJsonImage[];
colors: ContentsJsonColor[];
info: {
version: number;
author: string;
};
}
export declare function createContentsJsonItem(item: ContentsJsonImage): ContentsJsonImage;
/**
* Writes the Config.json which is used to assign images to their respective platform, dpi, and idiom.
*
* @param directory path to add the Contents.json to.
* @param contents image json data
*/
export declare function writeContentsJsonAsync(directory: string, { images }: Pick<ContentsJson, 'images'>): Promise<void>;
@@ -0,0 +1,48 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.createContentsJsonItem = createContentsJsonItem;
exports.writeContentsJsonAsync = writeContentsJsonAsync;
function _fs() {
const data = _interopRequireDefault(require("fs"));
_fs = function () {
return data;
};
return data;
}
function _path() {
const data = require("path");
_path = function () {
return data;
};
return data;
}
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
function createContentsJsonItem(item) {
return item;
}
/**
* Writes the Config.json which is used to assign images to their respective platform, dpi, and idiom.
*
* @param directory path to add the Contents.json to.
* @param contents image json data
*/
async function writeContentsJsonAsync(directory, {
images
}) {
await _fs().default.promises.mkdir(directory, {
recursive: true
});
await _fs().default.promises.writeFile((0, _path().join)(directory, 'Contents.json'), JSON.stringify({
images,
info: {
version: 1,
// common practice is for the tool that generated the icons to be the "author"
author: 'expo'
}
}, null, 2));
}
//# sourceMappingURL=AssetContents.js.map
@@ -0,0 +1 @@
{"version":3,"file":"AssetContents.js","names":["_fs","data","_interopRequireDefault","require","_path","e","__esModule","default","createContentsJsonItem","item","writeContentsJsonAsync","directory","images","fs","promises","mkdir","recursive","writeFile","join","JSON","stringify","info","version","author"],"sources":["../../../src/plugins/icons/AssetContents.ts"],"sourcesContent":["import fs from 'fs';\nimport { join } from 'path';\n\nexport type ContentsJsonImageIdiom =\n | 'iphone'\n | 'ipad'\n | 'watchos'\n | 'ios'\n | 'ios-marketing'\n | 'universal';\n\nexport type ContentsJsonImageAppearanceLuminosityType = 'light' | 'dark' | 'tinted';\n\nexport type ContentsJsonAppearance = {\n appearance: 'luminosity';\n value: ContentsJsonImageAppearanceLuminosityType;\n};\n\nexport type ContentsJsonImageScale = '1x' | '2x' | '3x';\n\nexport interface ContentsJsonImage {\n appearances?: ContentsJsonAppearance[];\n idiom: ContentsJsonImageIdiom;\n size?: string;\n scale?: ContentsJsonImageScale;\n filename?: string;\n platform?: ContentsJsonImageIdiom;\n}\n\nexport interface ContentsJsonColor {\n appearances?: ContentsJsonAppearance[];\n idiom: ContentsJsonImageIdiom;\n color: {\n 'color-space': 'srgb';\n components: {\n alpha: string;\n blue: string;\n green: string;\n red: string;\n };\n };\n}\n\nexport interface ContentsJson {\n images: ContentsJsonImage[];\n colors: ContentsJsonColor[];\n info: {\n version: number;\n author: string;\n };\n}\n\nexport function createContentsJsonItem(item: ContentsJsonImage): ContentsJsonImage {\n return item;\n}\n\n/**\n * Writes the Config.json which is used to assign images to their respective platform, dpi, and idiom.\n *\n * @param directory path to add the Contents.json to.\n * @param contents image json data\n */\nexport async function writeContentsJsonAsync(\n directory: string,\n { images }: Pick<ContentsJson, 'images'>\n): Promise<void> {\n await fs.promises.mkdir(directory, { recursive: true });\n await fs.promises.writeFile(\n join(directory, 'Contents.json'),\n JSON.stringify(\n {\n images,\n info: {\n version: 1,\n // common practice is for the tool that generated the icons to be the \"author\"\n author: 'expo',\n },\n },\n null,\n 2\n )\n );\n}\n"],"mappings":";;;;;;;AAAA,SAAAA,IAAA;EAAA,MAAAC,IAAA,GAAAC,sBAAA,CAAAC,OAAA;EAAAH,GAAA,YAAAA,CAAA;IAAA,OAAAC,IAAA;EAAA;EAAA,OAAAA,IAAA;AAAA;AACA,SAAAG,MAAA;EAAA,MAAAH,IAAA,GAAAE,OAAA;EAAAC,KAAA,YAAAA,CAAA;IAAA,OAAAH,IAAA;EAAA;EAAA,OAAAA,IAAA;AAAA;AAA4B,SAAAC,uBAAAG,CAAA,WAAAA,CAAA,IAAAA,CAAA,CAAAC,UAAA,GAAAD,CAAA,KAAAE,OAAA,EAAAF,CAAA;AAmDrB,SAASG,sBAAsBA,CAACC,IAAuB,EAAqB;EACjF,OAAOA,IAAI;AACb;;AAEA;AACA;AACA;AACA;AACA;AACA;AACO,eAAeC,sBAAsBA,CAC1CC,SAAiB,EACjB;EAAEC;AAAqC,CAAC,EACzB;EACf,MAAMC,aAAE,CAACC,QAAQ,CAACC,KAAK,CAACJ,SAAS,EAAE;IAAEK,SAAS,EAAE;EAAK,CAAC,CAAC;EACvD,MAAMH,aAAE,CAACC,QAAQ,CAACG,SAAS,CACzB,IAAAC,YAAI,EAACP,SAAS,EAAE,eAAe,CAAC,EAChCQ,IAAI,CAACC,SAAS,CACZ;IACER,MAAM;IACNS,IAAI,EAAE;MACJC,OAAO,EAAE,CAAC;MACV;MACAC,MAAM,EAAE;IACV;EACF,CAAC,EACD,IAAI,EACJ,CACF,CACF,CAAC;AACH","ignoreList":[]}
@@ -0,0 +1,39 @@
import { AndroidConfig, ConfigPlugin } from '@expo/config-plugins';
import { ExpoConfig } from '@expo/config-types';
type DPIString = 'mdpi' | 'hdpi' | 'xhdpi' | 'xxhdpi' | 'xxxhdpi';
type dpiMap = Record<DPIString, {
folderName: string;
scale: number;
}>;
export declare const dpiValues: dpiMap;
export declare const ANDROID_RES_PATH = "android/app/src/main/res/";
export declare const withAndroidIcons: ConfigPlugin;
export declare function setRoundIconManifest(config: Pick<ExpoConfig, 'android'>, manifest: AndroidConfig.Manifest.AndroidManifest): AndroidConfig.Manifest.AndroidManifest;
export declare function getIcon(config: ExpoConfig): string | null;
export declare function getAdaptiveIcon(config: ExpoConfig): {
foregroundImage: string | null;
backgroundColor: string | null;
backgroundImage: string | null;
monochromeImage: string | null;
};
/**
* Resizes the user-provided icon to create a set of legacy icon files in
* their respective "mipmap" directories for <= Android 7, and creates a set of adaptive
* icon files for > Android 7 from the adaptive icon files (if provided).
*/
export declare function setIconAsync(projectRoot: string, { icon, backgroundColor, backgroundImage, monochromeImage, isAdaptive, }: {
icon: string | null;
backgroundColor: string | null;
backgroundImage: string | null;
monochromeImage: string | null;
isAdaptive: boolean;
}): Promise<true | null>;
/**
* Configures adaptive icon files to be used on Android 8 and up. A foreground image must be provided,
* and will have a transparent background unless:
* - A backgroundImage is provided, or
* - A backgroundColor was specified
*/
export declare function configureAdaptiveIconAsync(projectRoot: string, foregroundImage: string, backgroundImage: string | null, monochromeImage: string | null, isAdaptive: boolean): Promise<void>;
export declare const createAdaptiveIconXmlString: (backgroundImage: string | null, monochromeImage: string | null) => string;
export {};
@@ -0,0 +1,372 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.ANDROID_RES_PATH = void 0;
exports.configureAdaptiveIconAsync = configureAdaptiveIconAsync;
exports.dpiValues = exports.createAdaptiveIconXmlString = void 0;
exports.getAdaptiveIcon = getAdaptiveIcon;
exports.getIcon = getIcon;
exports.setIconAsync = setIconAsync;
exports.setRoundIconManifest = setRoundIconManifest;
exports.withAndroidIcons = void 0;
function _configPlugins() {
const data = require("@expo/config-plugins");
_configPlugins = function () {
return data;
};
return data;
}
function _imageUtils() {
const data = require("@expo/image-utils");
_imageUtils = function () {
return data;
};
return data;
}
function _fs() {
const data = _interopRequireDefault(require("fs"));
_fs = function () {
return data;
};
return data;
}
function _path() {
const data = _interopRequireDefault(require("path"));
_path = function () {
return data;
};
return data;
}
function _withAndroidManifestIcons() {
const data = require("./withAndroidManifestIcons");
_withAndroidManifestIcons = function () {
return data;
};
return data;
}
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
const {
Colors
} = _configPlugins().AndroidConfig;
const dpiValues = exports.dpiValues = {
mdpi: {
folderName: 'mipmap-mdpi',
scale: 1
},
hdpi: {
folderName: 'mipmap-hdpi',
scale: 1.5
},
xhdpi: {
folderName: 'mipmap-xhdpi',
scale: 2
},
xxhdpi: {
folderName: 'mipmap-xxhdpi',
scale: 3
},
xxxhdpi: {
folderName: 'mipmap-xxxhdpi',
scale: 4
}
};
const LEGACY_BASELINE_PIXEL_SIZE = 48;
const ADAPTIVE_BASELINE_PIXEL_SIZE = 108;
const ANDROID_RES_PATH = exports.ANDROID_RES_PATH = 'android/app/src/main/res/';
const MIPMAP_ANYDPI_V26 = 'mipmap-anydpi-v26';
const ICON_BACKGROUND = 'iconBackground';
const IC_LAUNCHER_WEBP = 'ic_launcher.webp';
const IC_LAUNCHER_ROUND_WEBP = 'ic_launcher_round.webp';
const IC_LAUNCHER_BACKGROUND_WEBP = 'ic_launcher_background.webp';
const IC_LAUNCHER_FOREGROUND_WEBP = 'ic_launcher_foreground.webp';
const IC_LAUNCHER_MONOCHROME_WEBP = 'ic_launcher_monochrome.webp';
const IC_LAUNCHER_XML = 'ic_launcher.xml';
const IC_LAUNCHER_ROUND_XML = 'ic_launcher_round.xml';
const withAndroidIcons = config => {
const {
foregroundImage,
backgroundColor,
backgroundImage,
monochromeImage
} = getAdaptiveIcon(config);
const icon = foregroundImage ?? getIcon(config);
if (!icon) {
return config;
}
config = (0, _withAndroidManifestIcons().withAndroidManifestIcons)(config);
// Apply colors.xml changes
config = withAndroidAdaptiveIconColors(config, backgroundColor);
return (0, _configPlugins().withDangerousMod)(config, ['android', async config => {
await setIconAsync(config.modRequest.projectRoot, {
icon,
backgroundColor,
backgroundImage,
monochromeImage,
isAdaptive: !!config.android?.adaptiveIcon
});
return config;
}]);
};
exports.withAndroidIcons = withAndroidIcons;
function setRoundIconManifest(config, manifest) {
const isAdaptive = !!config.android?.adaptiveIcon;
const application = _configPlugins().AndroidConfig.Manifest.getMainApplicationOrThrow(manifest);
if (isAdaptive) {
application.$['android:roundIcon'] = '@mipmap/ic_launcher_round';
} else {
delete application.$['android:roundIcon'];
}
return manifest;
}
const withAndroidAdaptiveIconColors = (config, backgroundColor) => {
return (0, _configPlugins().withAndroidColors)(config, config => {
config.modResults = setBackgroundColor(backgroundColor ?? '#ffffff', config.modResults);
return config;
});
};
function getIcon(config) {
return config.android?.icon || config.icon || null;
}
function getAdaptiveIcon(config) {
return {
foregroundImage: config.android?.adaptiveIcon?.foregroundImage ?? null,
backgroundColor: config.android?.adaptiveIcon?.backgroundColor ?? null,
backgroundImage: config.android?.adaptiveIcon?.backgroundImage ?? null,
monochromeImage: config.android?.adaptiveIcon?.monochromeImage ?? null
};
}
/**
* Resizes the user-provided icon to create a set of legacy icon files in
* their respective "mipmap" directories for <= Android 7, and creates a set of adaptive
* icon files for > Android 7 from the adaptive icon files (if provided).
*/
async function setIconAsync(projectRoot, {
icon,
backgroundColor,
backgroundImage,
monochromeImage,
isAdaptive
}) {
if (!icon) {
return null;
}
await configureLegacyIconAsync(projectRoot, icon, backgroundImage, backgroundColor);
if (isAdaptive) {
await generateRoundIconAsync(projectRoot, icon, backgroundImage, backgroundColor);
} else {
await deleteIconNamedAsync(projectRoot, IC_LAUNCHER_ROUND_WEBP);
}
await configureAdaptiveIconAsync(projectRoot, icon, backgroundImage, monochromeImage, isAdaptive);
return true;
}
/**
* Configures legacy icon files to be used on Android 7 and earlier. If adaptive icon configuration
* was provided, we create a pseudo-adaptive icon by layering the provided files (or background
* color if no backgroundImage is provided. If no backgroundImage and no backgroundColor are provided,
* the background is set to transparent.)
*/
async function configureLegacyIconAsync(projectRoot, icon, backgroundImage, backgroundColor) {
return generateMultiLayerImageAsync(projectRoot, {
icon,
backgroundImage,
backgroundColor,
outputImageFileName: IC_LAUNCHER_WEBP,
imageCacheFolder: 'android-standard-square',
backgroundImageCacheFolder: 'android-standard-square-background'
});
}
async function generateRoundIconAsync(projectRoot, icon, backgroundImage, backgroundColor) {
return generateMultiLayerImageAsync(projectRoot, {
icon,
borderRadiusRatio: 0.5,
outputImageFileName: IC_LAUNCHER_ROUND_WEBP,
backgroundImage,
backgroundColor,
imageCacheFolder: 'android-standard-circle',
backgroundImageCacheFolder: 'android-standard-round-background',
isAdaptive: false
});
}
/**
* Configures adaptive icon files to be used on Android 8 and up. A foreground image must be provided,
* and will have a transparent background unless:
* - A backgroundImage is provided, or
* - A backgroundColor was specified
*/
async function configureAdaptiveIconAsync(projectRoot, foregroundImage, backgroundImage, monochromeImage, isAdaptive) {
if (monochromeImage) {
await generateMonochromeImageAsync(projectRoot, {
icon: monochromeImage,
imageCacheFolder: 'android-adaptive-monochrome',
outputImageFileName: IC_LAUNCHER_MONOCHROME_WEBP
});
}
await generateMultiLayerImageAsync(projectRoot, {
backgroundColor: 'transparent',
backgroundImage,
backgroundImageCacheFolder: 'android-adaptive-background',
outputImageFileName: IC_LAUNCHER_FOREGROUND_WEBP,
icon: foregroundImage,
imageCacheFolder: 'android-adaptive-foreground',
backgroundImageFileName: IC_LAUNCHER_BACKGROUND_WEBP,
isAdaptive: true
});
// create ic_launcher.xml and ic_launcher_round.xml
const icLauncherXmlString = createAdaptiveIconXmlString(backgroundImage, monochromeImage);
await createAdaptiveIconXmlFiles(projectRoot, icLauncherXmlString,
// If the user only defined icon and not android.adaptiveIcon, then skip enabling the layering system
// this will scale the image down and present it uncropped.
isAdaptive);
}
function setBackgroundColor(backgroundColor, colors) {
return Colors.assignColorValue(colors, {
value: backgroundColor,
name: ICON_BACKGROUND
});
}
const createAdaptiveIconXmlString = (backgroundImage, monochromeImage) => {
const background = backgroundImage ? `@mipmap/ic_launcher_background` : `@color/iconBackground`;
const iconElements = [`<background android:drawable="${background}"/>`, '<foreground android:drawable="@mipmap/ic_launcher_foreground"/>'];
if (monochromeImage) {
iconElements.push('<monochrome android:drawable="@mipmap/ic_launcher_monochrome"/>');
}
return `<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
${iconElements.join('\n ')}
</adaptive-icon>`;
};
exports.createAdaptiveIconXmlString = createAdaptiveIconXmlString;
async function createAdaptiveIconXmlFiles(projectRoot, icLauncherXmlString, add) {
const anyDpiV26Directory = _path().default.resolve(projectRoot, ANDROID_RES_PATH, MIPMAP_ANYDPI_V26);
await _fs().default.promises.mkdir(anyDpiV26Directory, {
recursive: true
});
const launcherPath = _path().default.resolve(anyDpiV26Directory, IC_LAUNCHER_XML);
const launcherRoundPath = _path().default.resolve(anyDpiV26Directory, IC_LAUNCHER_ROUND_XML);
if (add) {
await Promise.all([_fs().default.promises.writeFile(launcherPath, icLauncherXmlString, 'utf8'), _fs().default.promises.writeFile(launcherRoundPath, icLauncherXmlString, 'utf8')]);
} else {
// Remove the xml if the icon switches from adaptive to standard.
await Promise.all([launcherPath, launcherRoundPath].map(async path => {
return _fs().default.promises.rm(path, {
force: true
});
}));
}
}
async function generateMultiLayerImageAsync(projectRoot, {
icon,
backgroundColor,
backgroundImage,
imageCacheFolder,
backgroundImageCacheFolder,
borderRadiusRatio,
outputImageFileName,
backgroundImageFileName,
isAdaptive
}) {
await iterateDpiValues(projectRoot, async ({
dpiFolder,
scale
}) => {
let iconLayer = await generateIconAsync(projectRoot, {
cacheType: imageCacheFolder,
src: icon,
scale,
// backgroundImage overrides backgroundColor
backgroundColor: backgroundImage ? 'transparent' : backgroundColor ?? 'transparent',
borderRadiusRatio,
isAdaptive
});
if (backgroundImage) {
const backgroundLayer = await generateIconAsync(projectRoot, {
cacheType: backgroundImageCacheFolder,
src: backgroundImage,
scale,
backgroundColor: 'transparent',
borderRadiusRatio,
isAdaptive
});
if (backgroundImageFileName) {
await _fs().default.promises.writeFile(_path().default.resolve(dpiFolder, backgroundImageFileName), backgroundLayer);
} else {
iconLayer = await (0, _imageUtils().compositeImagesAsync)({
foreground: iconLayer,
background: backgroundLayer
});
}
} else if (backgroundImageFileName) {
// Remove any instances of ic_launcher_background.png that are there from previous icons
await deleteIconNamedAsync(projectRoot, backgroundImageFileName);
}
await _fs().default.promises.mkdir(dpiFolder, {
recursive: true
});
await _fs().default.promises.writeFile(_path().default.resolve(dpiFolder, outputImageFileName), iconLayer);
});
}
async function generateMonochromeImageAsync(projectRoot, {
icon,
imageCacheFolder,
outputImageFileName
}) {
await iterateDpiValues(projectRoot, async ({
dpiFolder,
scale
}) => {
const monochromeIcon = await generateIconAsync(projectRoot, {
cacheType: imageCacheFolder,
src: icon,
scale,
backgroundColor: 'transparent',
isAdaptive: true
});
await _fs().default.promises.mkdir(dpiFolder, {
recursive: true
});
await _fs().default.promises.writeFile(_path().default.resolve(dpiFolder, outputImageFileName), monochromeIcon);
});
}
function iterateDpiValues(projectRoot, callback) {
return Promise.all(Object.values(dpiValues).map(value => callback({
dpiFolder: _path().default.resolve(projectRoot, ANDROID_RES_PATH, value.folderName),
...value
})));
}
async function deleteIconNamedAsync(projectRoot, name) {
return iterateDpiValues(projectRoot, ({
dpiFolder
}) => {
return _fs().default.promises.rm(_path().default.resolve(dpiFolder, name), {
force: true
});
});
}
async function generateIconAsync(projectRoot, {
cacheType,
src,
scale,
backgroundColor,
borderRadiusRatio,
isAdaptive
}) {
const iconSizePx = (isAdaptive ? ADAPTIVE_BASELINE_PIXEL_SIZE : LEGACY_BASELINE_PIXEL_SIZE) * scale;
return (await (0, _imageUtils().generateImageAsync)({
projectRoot,
cacheType
}, {
src,
width: iconSizePx,
height: iconSizePx,
resizeMode: 'cover',
backgroundColor,
borderRadius: borderRadiusRatio ? iconSizePx * borderRadiusRatio : undefined
})).source;
}
//# sourceMappingURL=withAndroidIcons.js.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1,4 @@
import { AndroidConfig, ConfigPlugin } from '@expo/config-plugins';
import { ExpoConfig } from '@expo/config-types';
export declare const withAndroidManifestIcons: ConfigPlugin;
export declare function setRoundIconManifest(config: Pick<ExpoConfig, 'android'>, manifest: AndroidConfig.Manifest.AndroidManifest): AndroidConfig.Manifest.AndroidManifest;
@@ -0,0 +1,30 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.setRoundIconManifest = setRoundIconManifest;
exports.withAndroidManifestIcons = void 0;
function _configPlugins() {
const data = require("@expo/config-plugins");
_configPlugins = function () {
return data;
};
return data;
}
const withAndroidManifestIcons = config => (0, _configPlugins().withAndroidManifest)(config, config => {
config.modResults = setRoundIconManifest(config, config.modResults);
return config;
});
exports.withAndroidManifestIcons = withAndroidManifestIcons;
function setRoundIconManifest(config, manifest) {
const isAdaptive = !!config.android?.adaptiveIcon;
const application = _configPlugins().AndroidConfig.Manifest.getMainApplicationOrThrow(manifest);
if (isAdaptive) {
application.$['android:roundIcon'] = '@mipmap/ic_launcher_round';
} else {
delete application.$['android:roundIcon'];
}
return manifest;
}
//# sourceMappingURL=withAndroidManifestIcons.js.map
@@ -0,0 +1 @@
{"version":3,"file":"withAndroidManifestIcons.js","names":["_configPlugins","data","require","withAndroidManifestIcons","config","withAndroidManifest","modResults","setRoundIconManifest","exports","manifest","isAdaptive","android","adaptiveIcon","application","AndroidConfig","Manifest","getMainApplicationOrThrow","$"],"sources":["../../../src/plugins/icons/withAndroidManifestIcons.ts"],"sourcesContent":["import { AndroidConfig, ConfigPlugin, withAndroidManifest } from '@expo/config-plugins';\nimport { ExpoConfig } from '@expo/config-types';\n\nexport const withAndroidManifestIcons: ConfigPlugin = (config) =>\n withAndroidManifest(config, (config) => {\n config.modResults = setRoundIconManifest(config, config.modResults);\n return config;\n });\n\nexport function setRoundIconManifest(\n config: Pick<ExpoConfig, 'android'>,\n manifest: AndroidConfig.Manifest.AndroidManifest\n): AndroidConfig.Manifest.AndroidManifest {\n const isAdaptive = !!config.android?.adaptiveIcon;\n const application = AndroidConfig.Manifest.getMainApplicationOrThrow(manifest);\n\n if (isAdaptive) {\n application.$['android:roundIcon'] = '@mipmap/ic_launcher_round';\n } else {\n delete application.$['android:roundIcon'];\n }\n return manifest;\n}\n"],"mappings":";;;;;;;AAAA,SAAAA,eAAA;EAAA,MAAAC,IAAA,GAAAC,OAAA;EAAAF,cAAA,YAAAA,CAAA;IAAA,OAAAC,IAAA;EAAA;EAAA,OAAAA,IAAA;AAAA;AAGO,MAAME,wBAAsC,GAAIC,MAAM,IAC3D,IAAAC,oCAAmB,EAACD,MAAM,EAAGA,MAAM,IAAK;EACtCA,MAAM,CAACE,UAAU,GAAGC,oBAAoB,CAACH,MAAM,EAAEA,MAAM,CAACE,UAAU,CAAC;EACnE,OAAOF,MAAM;AACf,CAAC,CAAC;AAACI,OAAA,CAAAL,wBAAA,GAAAA,wBAAA;AAEE,SAASI,oBAAoBA,CAClCH,MAAmC,EACnCK,QAAgD,EACR;EACxC,MAAMC,UAAU,GAAG,CAAC,CAACN,MAAM,CAACO,OAAO,EAAEC,YAAY;EACjD,MAAMC,WAAW,GAAGC,8BAAa,CAACC,QAAQ,CAACC,yBAAyB,CAACP,QAAQ,CAAC;EAE9E,IAAIC,UAAU,EAAE;IACdG,WAAW,CAACI,CAAC,CAAC,mBAAmB,CAAC,GAAG,2BAA2B;EAClE,CAAC,MAAM;IACL,OAAOJ,WAAW,CAACI,CAAC,CAAC,mBAAmB,CAAC;EAC3C;EACA,OAAOR,QAAQ;AACjB","ignoreList":[]}
@@ -0,0 +1,13 @@
import { ConfigPlugin } from '@expo/config-plugins';
import { ExpoConfig, IOSIcons } from '@expo/config-types';
import { ContentsJsonImage } from './AssetContents';
export declare const withIosIcons: ConfigPlugin;
export declare function getIcons(config: Pick<ExpoConfig, 'icon' | 'ios'>): IOSIcons | string | null;
export declare function setIconsAsync(config: ExpoConfig, projectRoot: string): Promise<void>;
export declare function generateUniversalIconAsync(projectRoot: string, { icon, cacheKey, iosNamedProjectRoot, platform, appearance, }: {
platform: 'watchos' | 'ios';
icon?: string | null;
appearance?: 'dark' | 'tinted';
iosNamedProjectRoot: string;
cacheKey: string;
}): Promise<ContentsJsonImage>;
@@ -0,0 +1,263 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.generateUniversalIconAsync = generateUniversalIconAsync;
exports.getIcons = getIcons;
exports.setIconsAsync = setIconsAsync;
exports.withIosIcons = void 0;
function _configPlugins() {
const data = require("@expo/config-plugins");
_configPlugins = function () {
return data;
};
return data;
}
function _imageUtils() {
const data = require("@expo/image-utils");
_imageUtils = function () {
return data;
};
return data;
}
function _fs() {
const data = _interopRequireDefault(require("fs"));
_fs = function () {
return data;
};
return data;
}
function _path() {
const data = _interopRequireDefault(require("path"));
_path = function () {
return data;
};
return data;
}
function _AssetContents() {
const data = require("./AssetContents");
_AssetContents = function () {
return data;
};
return data;
}
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
const {
getProjectName
} = _configPlugins().IOSConfig.XcodeUtils;
const IMAGE_CACHE_NAME = 'icons';
const IMAGESET_PATH = 'Images.xcassets/AppIcon.appiconset';
const withIosIcons = config => {
config = (0, _configPlugins().withDangerousMod)(config, ['ios', async config => {
await setIconsAsync(config, config.modRequest.projectRoot);
return config;
}]);
config = (0, _configPlugins().withXcodeProject)(config, config => {
const icon = getIcons(config);
const projectName = config.modRequest.projectName;
if (icon && typeof icon === 'string' && _path().default.extname(icon) === '.icon' && projectName) {
const iconName = _path().default.basename(icon, '.icon');
setIconName(config.modResults, iconName);
addIconFileToProject(config.modResults, projectName, iconName);
}
return config;
});
return config;
};
exports.withIosIcons = withIosIcons;
function getIcons(config) {
const iosSpecificIcons = config.ios?.icon;
if (iosSpecificIcons) {
// For backwards compatibility, the icon can be a string
if (typeof iosSpecificIcons === 'string') {
return iosSpecificIcons || config.icon || null;
}
if (typeof iosSpecificIcons === 'object') {
const paths = [iosSpecificIcons.light, iosSpecificIcons.dark, iosSpecificIcons.tinted].filter(Boolean);
for (const iconPath of paths) {
if (typeof iconPath === 'string' && _path().default.extname(iconPath) === '.icon') {
_configPlugins().WarningAggregator.addWarningIOS('icon', `Liquid glass icons (.icon) should be provided as a string to the "ios.icon" property, not as an object. Found: "${iconPath}"`);
}
}
}
// in iOS 18 introduced the ability to specify dark and tinted icons, which users can specify as an object
if (!iosSpecificIcons.light && !iosSpecificIcons.dark && !iosSpecificIcons.tinted) {
return config.icon || null;
}
return iosSpecificIcons;
}
// Top level icon property should not be used to specify a `.icon` folder
if (config.icon && typeof config.icon === 'string' && _path().default.extname(config.icon) === '.icon') {
_configPlugins().WarningAggregator.addWarningIOS('icon', `Liquid glass icons (.icon) should be provided via the "ios.icon" property, not the root "icon" property. Found: "${config.icon}"`);
}
if (config.icon) {
return config.icon;
}
return null;
}
async function setIconsAsync(config, projectRoot) {
const icon = getIcons(config);
if (!icon || typeof icon === 'string' && !icon || typeof icon === 'object' && !icon?.light && !icon?.dark && !icon?.tinted) {
_configPlugins().WarningAggregator.addWarningIOS('icon', 'No icon is defined in the Expo config.');
}
// Something like projectRoot/ios/MyApp/
const iosNamedProjectRoot = getIosNamedProjectPath(projectRoot);
if (typeof icon === 'string' && _path().default.extname(icon) === '.icon') {
return await addLiquidGlassIcon(icon, projectRoot, iosNamedProjectRoot);
}
// Ensure the Images.xcassets/AppIcon.appiconset path exists
await _fs().default.promises.mkdir(_path().default.join(iosNamedProjectRoot, IMAGESET_PATH), {
recursive: true
});
const imagesJson = [];
const baseIconPath = typeof icon === 'object' ? icon?.light || icon?.dark || icon?.tinted : icon;
// Store the image JSON data for assigning via the Contents.json
const baseIcon = await generateUniversalIconAsync(projectRoot, {
icon: baseIconPath,
cacheKey: 'universal-icon',
iosNamedProjectRoot,
platform: 'ios'
});
imagesJson.push(baseIcon);
if (typeof icon === 'object') {
if (icon?.dark) {
const darkIcon = await generateUniversalIconAsync(projectRoot, {
icon: icon.dark,
cacheKey: 'universal-icon-dark',
iosNamedProjectRoot,
platform: 'ios',
appearance: 'dark'
});
imagesJson.push(darkIcon);
}
if (icon?.tinted) {
const tintedIcon = await generateUniversalIconAsync(projectRoot, {
icon: icon.tinted,
cacheKey: 'universal-icon-tinted',
iosNamedProjectRoot,
platform: 'ios',
appearance: 'tinted'
});
imagesJson.push(tintedIcon);
}
}
// Finally, write the Contents.json
await (0, _AssetContents().writeContentsJsonAsync)(_path().default.join(iosNamedProjectRoot, IMAGESET_PATH), {
images: imagesJson
});
}
/**
* Return the project's named iOS path: ios/MyProject/
*
* @param projectRoot Expo project root path.
*/
function getIosNamedProjectPath(projectRoot) {
const projectName = getProjectName(projectRoot);
return _path().default.join(projectRoot, 'ios', projectName);
}
function getAppleIconName(size, scale, appearance) {
let name = 'App-Icon';
if (appearance) {
name = `${name}-${appearance}`;
}
name = `${name}-${size}x${size}@${scale}x.png`;
return name;
}
async function generateUniversalIconAsync(projectRoot, {
icon,
cacheKey,
iosNamedProjectRoot,
platform,
appearance
}) {
const size = 1024;
const filename = getAppleIconName(size, 1, appearance);
let source;
if (icon) {
// Using this method will cache the images in `.expo` based on the properties used to generate them.
// this method also supports remote URLs and using the global sharp instance.
source = (await (0, _imageUtils().generateImageAsync)({
projectRoot,
cacheType: IMAGE_CACHE_NAME + cacheKey
}, {
src: icon,
name: filename,
width: size,
height: size,
// Transparency needs to be preserved in dark variant, but can safely be removed in "light" and "tinted" variants.
removeTransparency: appearance !== 'dark',
// The icon should be square, but if it's not then it will be cropped.
resizeMode: 'cover',
// Force the background color to solid white to prevent any transparency. (for "any" and "tinted" variants)
// TODO: Maybe use a more adaptive option based on the icon color?
backgroundColor: appearance !== 'dark' ? '#ffffff' : undefined
})).source;
} else {
// Create a white square image if no icon exists to mitigate the chance of a submission failure to the app store.
source = await (0, _imageUtils().createSquareAsync)({
size
});
}
// Write image buffer to the file system.
const assetPath = _path().default.join(iosNamedProjectRoot, IMAGESET_PATH, filename);
await _fs().default.promises.writeFile(assetPath, source);
return {
filename,
idiom: 'universal',
platform,
size: `${size}x${size}`,
...(appearance ? {
appearances: [{
appearance: 'luminosity',
value: appearance
}]
} : {})
};
}
async function addLiquidGlassIcon(iconPath, projectRoot, iosNamedProjectRoot) {
const iconName = _path().default.basename(iconPath, '.icon');
const sourceIconPath = _path().default.join(projectRoot, iconPath);
const targetIconPath = _path().default.join(iosNamedProjectRoot, `${iconName}.icon`);
if (!_fs().default.existsSync(sourceIconPath)) {
_configPlugins().WarningAggregator.addWarningIOS('icon', `Liquid glass icon file not found at path: ${iconPath}`);
return;
}
await _fs().default.promises.cp(sourceIconPath, targetIconPath, {
recursive: true
});
}
/**
* Adds the .icons name to the project
*/
function setIconName(project, iconName) {
const configurations = project.pbxXCBuildConfigurationSection();
for (const config of Object.values(configurations)) {
if (config?.buildSettings) {
config.buildSettings.ASSETCATALOG_COMPILER_APPICON_NAME = iconName;
}
}
}
/**
* Adds the .icon file to the project
*/
function addIconFileToProject(project, projectName, iconName) {
const iconPath = `${iconName}.icon`;
_configPlugins().IOSConfig.XcodeUtils.addResourceFileToGroup({
filepath: `${projectName}/${iconPath}`,
groupName: projectName,
project,
isBuildFile: true,
verbose: true
});
}
//# sourceMappingURL=withIosIcons.js.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1,2 @@
import { type ConfigPlugin } from '@expo/config-plugins';
export declare const withSdk52ReactNative77CompatAndroid: ConfigPlugin;
@@ -0,0 +1,76 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.withSdk52ReactNative77CompatAndroid = void 0;
function _configPlugins() {
const data = require("@expo/config-plugins");
_configPlugins = function () {
return data;
};
return data;
}
function _jsonFile() {
const data = _interopRequireDefault(require("@expo/json-file"));
_jsonFile = function () {
return data;
};
return data;
}
function _resolveFrom() {
const data = _interopRequireDefault(require("resolve-from"));
_resolveFrom = function () {
return data;
};
return data;
}
function _semver() {
const data = _interopRequireDefault(require("semver"));
_semver = function () {
return data;
};
return data;
}
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
// TODO(kudo,20241112): Remove this plugin when we drop support for SDK 52.
const withSdk52ReactNative77CompatAndroid = config => {
return (0, _configPlugins().withProjectBuildGradle)(config, async config => {
if (config.sdkVersion !== '52.0.0') {
return config;
}
const reactNativeVersion = await queryReactNativeVersionAsync(config.modRequest.projectRoot);
if (!reactNativeVersion || _semver().default.lt(reactNativeVersion, '0.77.0')) {
return config;
}
if (config.modResults.language === 'groovy') {
config.modResults.contents = setProjectBuildGradle(config.modResults.contents);
} else {
_configPlugins().WarningAggregator.addWarningAndroid('ReactNative77CompatPlugin', `Cannot automatically configure project build.gradle if it's not groovy`);
}
return config;
});
};
exports.withSdk52ReactNative77CompatAndroid = withSdk52ReactNative77CompatAndroid;
function setProjectBuildGradle(contents) {
// Update kotlinVersion
const kotlinVersion = '2.0.21';
let newContents = contents.replace(/\b(kotlinVersion\s*=\s*findProperty\('android.kotlinVersion'\)\s*\?: ['"])(1\.9\.\d+)(['"])/g, `$1${kotlinVersion}$3`);
// Update ndkVersion
const ndkVersion = '27.1.12297006';
newContents = newContents.replace(/\b(ndkVersion\s*=\s*['"])(26.1.10909125)(['"])/g, `$1${ndkVersion}$3`);
return newContents;
}
async function queryReactNativeVersionAsync(projectRoot) {
const packageJsonPath = _resolveFrom().default.silent(projectRoot, 'react-native/package.json');
if (packageJsonPath) {
const packageJson = await _jsonFile().default.readAsync(packageJsonPath);
const version = packageJson.version;
if (typeof version === 'string') {
return _semver().default.parse(version);
}
}
return null;
}
//# sourceMappingURL=ReactNative77CompatPlugin.js.map
@@ -0,0 +1 @@
{"version":3,"file":"ReactNative77CompatPlugin.js","names":["_configPlugins","data","require","_jsonFile","_interopRequireDefault","_resolveFrom","_semver","e","__esModule","default","withSdk52ReactNative77CompatAndroid","config","withProjectBuildGradle","sdkVersion","reactNativeVersion","queryReactNativeVersionAsync","modRequest","projectRoot","semver","lt","modResults","language","contents","setProjectBuildGradle","WarningAggregator","addWarningAndroid","exports","kotlinVersion","newContents","replace","ndkVersion","packageJsonPath","resolveFrom","silent","packageJson","JsonFile","readAsync","version","parse"],"sources":["../../../src/plugins/sdk52/ReactNative77CompatPlugin.ts"],"sourcesContent":["import { withProjectBuildGradle, WarningAggregator, type ConfigPlugin } from '@expo/config-plugins';\nimport JsonFile from '@expo/json-file';\nimport resolveFrom from 'resolve-from';\nimport semver from 'semver';\n\n// TODO(kudo,20241112): Remove this plugin when we drop support for SDK 52.\nexport const withSdk52ReactNative77CompatAndroid: ConfigPlugin = (config) => {\n return withProjectBuildGradle(config, async (config) => {\n if (config.sdkVersion !== '52.0.0') {\n return config;\n }\n const reactNativeVersion = await queryReactNativeVersionAsync(config.modRequest.projectRoot);\n if (!reactNativeVersion || semver.lt(reactNativeVersion, '0.77.0')) {\n return config;\n }\n\n if (config.modResults.language === 'groovy') {\n config.modResults.contents = setProjectBuildGradle(config.modResults.contents);\n } else {\n WarningAggregator.addWarningAndroid(\n 'ReactNative77CompatPlugin',\n `Cannot automatically configure project build.gradle if it's not groovy`\n );\n }\n return config;\n });\n};\n\nfunction setProjectBuildGradle(contents: string): string {\n // Update kotlinVersion\n const kotlinVersion = '2.0.21';\n let newContents = contents.replace(\n /\\b(kotlinVersion\\s*=\\s*findProperty\\('android.kotlinVersion'\\)\\s*\\?: ['\"])(1\\.9\\.\\d+)(['\"])/g,\n `$1${kotlinVersion}$3`\n );\n\n // Update ndkVersion\n const ndkVersion = '27.1.12297006';\n newContents = newContents.replace(\n /\\b(ndkVersion\\s*=\\s*['\"])(26.1.10909125)(['\"])/g,\n `$1${ndkVersion}$3`\n );\n\n return newContents;\n}\n\nasync function queryReactNativeVersionAsync(projectRoot: string): Promise<semver.SemVer | null> {\n const packageJsonPath = resolveFrom.silent(projectRoot, 'react-native/package.json');\n if (packageJsonPath) {\n const packageJson = await JsonFile.readAsync(packageJsonPath);\n const version = packageJson.version;\n if (typeof version === 'string') {\n return semver.parse(version);\n }\n }\n return null;\n}\n"],"mappings":";;;;;;AAAA,SAAAA,eAAA;EAAA,MAAAC,IAAA,GAAAC,OAAA;EAAAF,cAAA,YAAAA,CAAA;IAAA,OAAAC,IAAA;EAAA;EAAA,OAAAA,IAAA;AAAA;AACA,SAAAE,UAAA;EAAA,MAAAF,IAAA,GAAAG,sBAAA,CAAAF,OAAA;EAAAC,SAAA,YAAAA,CAAA;IAAA,OAAAF,IAAA;EAAA;EAAA,OAAAA,IAAA;AAAA;AACA,SAAAI,aAAA;EAAA,MAAAJ,IAAA,GAAAG,sBAAA,CAAAF,OAAA;EAAAG,YAAA,YAAAA,CAAA;IAAA,OAAAJ,IAAA;EAAA;EAAA,OAAAA,IAAA;AAAA;AACA,SAAAK,QAAA;EAAA,MAAAL,IAAA,GAAAG,sBAAA,CAAAF,OAAA;EAAAI,OAAA,YAAAA,CAAA;IAAA,OAAAL,IAAA;EAAA;EAAA,OAAAA,IAAA;AAAA;AAA4B,SAAAG,uBAAAG,CAAA,WAAAA,CAAA,IAAAA,CAAA,CAAAC,UAAA,GAAAD,CAAA,KAAAE,OAAA,EAAAF,CAAA;AAE5B;AACO,MAAMG,mCAAiD,GAAIC,MAAM,IAAK;EAC3E,OAAO,IAAAC,uCAAsB,EAACD,MAAM,EAAE,MAAOA,MAAM,IAAK;IACtD,IAAIA,MAAM,CAACE,UAAU,KAAK,QAAQ,EAAE;MAClC,OAAOF,MAAM;IACf;IACA,MAAMG,kBAAkB,GAAG,MAAMC,4BAA4B,CAACJ,MAAM,CAACK,UAAU,CAACC,WAAW,CAAC;IAC5F,IAAI,CAACH,kBAAkB,IAAII,iBAAM,CAACC,EAAE,CAACL,kBAAkB,EAAE,QAAQ,CAAC,EAAE;MAClE,OAAOH,MAAM;IACf;IAEA,IAAIA,MAAM,CAACS,UAAU,CAACC,QAAQ,KAAK,QAAQ,EAAE;MAC3CV,MAAM,CAACS,UAAU,CAACE,QAAQ,GAAGC,qBAAqB,CAACZ,MAAM,CAACS,UAAU,CAACE,QAAQ,CAAC;IAChF,CAAC,MAAM;MACLE,kCAAiB,CAACC,iBAAiB,CACjC,2BAA2B,EAC3B,wEACF,CAAC;IACH;IACA,OAAOd,MAAM;EACf,CAAC,CAAC;AACJ,CAAC;AAACe,OAAA,CAAAhB,mCAAA,GAAAA,mCAAA;AAEF,SAASa,qBAAqBA,CAACD,QAAgB,EAAU;EACvD;EACA,MAAMK,aAAa,GAAG,QAAQ;EAC9B,IAAIC,WAAW,GAAGN,QAAQ,CAACO,OAAO,CAChC,8FAA8F,EAC9F,KAAKF,aAAa,IACpB,CAAC;;EAED;EACA,MAAMG,UAAU,GAAG,eAAe;EAClCF,WAAW,GAAGA,WAAW,CAACC,OAAO,CAC/B,iDAAiD,EACjD,KAAKC,UAAU,IACjB,CAAC;EAED,OAAOF,WAAW;AACpB;AAEA,eAAeb,4BAA4BA,CAACE,WAAmB,EAAiC;EAC9F,MAAMc,eAAe,GAAGC,sBAAW,CAACC,MAAM,CAAChB,WAAW,EAAE,2BAA2B,CAAC;EACpF,IAAIc,eAAe,EAAE;IACnB,MAAMG,WAAW,GAAG,MAAMC,mBAAQ,CAACC,SAAS,CAACL,eAAe,CAAC;IAC7D,MAAMM,OAAO,GAAGH,WAAW,CAACG,OAAO;IACnC,IAAI,OAAOA,OAAO,KAAK,QAAQ,EAAE;MAC/B,OAAOnB,iBAAM,CAACoB,KAAK,CAACD,OAAO,CAAC;IAC9B;EACF;EACA,OAAO,IAAI;AACb","ignoreList":[]}
@@ -0,0 +1,2 @@
import { type ConfigPlugin } from '@expo/config-plugins';
export declare const withSdk52ReactNative78CompatAndroid: ConfigPlugin;
@@ -0,0 +1,88 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.withSdk52ReactNative78CompatAndroid = void 0;
function _configPlugins() {
const data = require("@expo/config-plugins");
_configPlugins = function () {
return data;
};
return data;
}
function _jsonFile() {
const data = _interopRequireDefault(require("@expo/json-file"));
_jsonFile = function () {
return data;
};
return data;
}
function _resolveFrom() {
const data = _interopRequireDefault(require("resolve-from"));
_resolveFrom = function () {
return data;
};
return data;
}
function _semver() {
const data = _interopRequireDefault(require("semver"));
_semver = function () {
return data;
};
return data;
}
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
let cachedIsTargetSdkVersion = undefined;
// TODO(kudo,20241210): Remove this plugin when we drop support for SDK 52.
const withSdk52ReactNative78CompatAndroid = config => {
config = withSdk52ReactNative78CompatAndroidAppGradle(config);
config = withSdk52ReactNative78CompatAndroidProjectGradle(config);
return config;
};
exports.withSdk52ReactNative78CompatAndroid = withSdk52ReactNative78CompatAndroid;
const withSdk52ReactNative78CompatAndroidAppGradle = config => {
return (0, _configPlugins().withAppBuildGradle)(config, async config => {
if (!(await isTargetSdkVersionAsync(config.modRequest.projectRoot, config.sdkVersion))) {
return config;
}
config.modResults.contents = config.modResults.contents.replace(/jscFlavor = ['"]org\.webkit:android-jsc(-intl)?:\+['"]/gm, `jscFlavor = 'io.github.react-native-community:jsc-android$1:2026004.+'`);
return config;
});
};
const withSdk52ReactNative78CompatAndroidProjectGradle = config => {
return (0, _configPlugins().withProjectBuildGradle)(config, async config => {
if (!(await isTargetSdkVersionAsync(config.modRequest.projectRoot, config.sdkVersion))) {
return config;
}
config.modResults.contents = config.modResults.contents.replace(/\ndef jscAndroidDir = new File\([\s\S]+?^\)\n/gm, '');
config.modResults.contents = config.modResults.contents.replace(/^\s+maven \{\n\s+\/\/ Android JSC.*\n\s+url\(jscAndroidDir\)[\s\S]+?\}\n/gm, '');
return config;
});
};
async function isTargetSdkVersionAsync(projectRoot, sdkVersion) {
if (cachedIsTargetSdkVersion !== undefined) {
return cachedIsTargetSdkVersion;
}
cachedIsTargetSdkVersion = false;
if (sdkVersion === '52.0.0') {
const reactNativeVersion = await queryReactNativeVersionAsync(projectRoot);
if (reactNativeVersion && _semver().default.gte(reactNativeVersion, '0.78.0')) {
cachedIsTargetSdkVersion = true;
}
}
return cachedIsTargetSdkVersion;
}
async function queryReactNativeVersionAsync(projectRoot) {
const packageJsonPath = _resolveFrom().default.silent(projectRoot, 'react-native/package.json');
if (packageJsonPath) {
const packageJson = await _jsonFile().default.readAsync(packageJsonPath);
const version = packageJson.version;
if (typeof version === 'string') {
return _semver().default.parse(version);
}
}
return null;
}
//# sourceMappingURL=ReactNative78CompatPlugin.js.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1,5 @@
import { ConfigPlugin, PluginParameters, withPlugins } from '@expo/config-plugins';
export declare function createLegacyPlugin({ packageName, fallback, }: {
packageName: string;
fallback: ConfigPlugin | PluginParameters<typeof withPlugins>;
}): ConfigPlugin;
@@ -0,0 +1,49 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.createLegacyPlugin = createLegacyPlugin;
function _configPlugins() {
const data = require("@expo/config-plugins");
_configPlugins = function () {
return data;
};
return data;
}
const toCamelCase = s => s.replace(/-./g, x => x.toUpperCase()[1]);
function isModuleExcluded(config, packageName) {
// Skip using the versioned plugin when autolinking is enabled
// and doesn't link the native module.
return config._internal?.autolinkedModules && !config._internal.autolinkedModules.includes(packageName);
}
function createLegacyPlugin({
packageName,
fallback
}) {
let withFallback;
if (Array.isArray(fallback)) {
withFallback = config => (0, _configPlugins().withPlugins)(config, fallback);
} else {
withFallback = fallback;
}
const withUnknown = config => {
// Skip using the versioned plugin when autolinking is enabled
// and doesn't link the native module.
if (isModuleExcluded(config, packageName)) {
return (0, _configPlugins().createRunOncePlugin)(withFallback, packageName)(config);
}
return (0, _configPlugins().withStaticPlugin)(config, {
_isLegacyPlugin: true,
plugin: packageName,
// If the static plugin isn't found, use the unversioned one.
fallback: (0, _configPlugins().createRunOncePlugin)(withFallback, packageName)
});
};
const methodName = toCamelCase(`with-${packageName}`);
Object.defineProperty(withUnknown, 'name', {
value: methodName
});
return withUnknown;
}
//# sourceMappingURL=createLegacyPlugin.js.map
@@ -0,0 +1 @@
{"version":3,"file":"createLegacyPlugin.js","names":["_configPlugins","data","require","toCamelCase","s","replace","x","toUpperCase","isModuleExcluded","config","packageName","_internal","autolinkedModules","includes","createLegacyPlugin","fallback","withFallback","Array","isArray","withPlugins","withUnknown","createRunOncePlugin","withStaticPlugin","_isLegacyPlugin","plugin","methodName","Object","defineProperty","value"],"sources":["../../../src/plugins/unversioned/createLegacyPlugin.ts"],"sourcesContent":["import {\n ConfigPlugin,\n createRunOncePlugin,\n PluginParameters,\n withPlugins,\n withStaticPlugin,\n} from '@expo/config-plugins';\nimport { ExpoConfig } from '@expo/config-types';\n\nconst toCamelCase = (s: string) => s.replace(/-./g, (x) => x.toUpperCase()[1]);\n\nfunction isModuleExcluded(config: Pick<ExpoConfig, '_internal'>, packageName: string): boolean {\n // Skip using the versioned plugin when autolinking is enabled\n // and doesn't link the native module.\n return (\n config._internal?.autolinkedModules && !config._internal.autolinkedModules.includes(packageName)\n );\n}\n\nexport function createLegacyPlugin({\n packageName,\n fallback,\n}: {\n packageName: string;\n fallback: ConfigPlugin | PluginParameters<typeof withPlugins>;\n}): ConfigPlugin {\n let withFallback: ConfigPlugin;\n\n if (Array.isArray(fallback)) {\n withFallback = (config) => withPlugins(config, fallback);\n } else {\n withFallback = fallback;\n }\n\n const withUnknown: ConfigPlugin = (config) => {\n // Skip using the versioned plugin when autolinking is enabled\n // and doesn't link the native module.\n if (isModuleExcluded(config, packageName)) {\n return createRunOncePlugin(withFallback, packageName)(config);\n }\n\n return withStaticPlugin(config, {\n _isLegacyPlugin: true,\n plugin: packageName,\n // If the static plugin isn't found, use the unversioned one.\n fallback: createRunOncePlugin(withFallback, packageName),\n });\n };\n\n const methodName = toCamelCase(`with-${packageName}`);\n Object.defineProperty(withUnknown, 'name', {\n value: methodName,\n });\n\n return withUnknown;\n}\n"],"mappings":";;;;;;AAAA,SAAAA,eAAA;EAAA,MAAAC,IAAA,GAAAC,OAAA;EAAAF,cAAA,YAAAA,CAAA;IAAA,OAAAC,IAAA;EAAA;EAAA,OAAAA,IAAA;AAAA;AASA,MAAME,WAAW,GAAIC,CAAS,IAAKA,CAAC,CAACC,OAAO,CAAC,KAAK,EAAGC,CAAC,IAAKA,CAAC,CAACC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAE9E,SAASC,gBAAgBA,CAACC,MAAqC,EAAEC,WAAmB,EAAW;EAC7F;EACA;EACA,OACED,MAAM,CAACE,SAAS,EAAEC,iBAAiB,IAAI,CAACH,MAAM,CAACE,SAAS,CAACC,iBAAiB,CAACC,QAAQ,CAACH,WAAW,CAAC;AAEpG;AAEO,SAASI,kBAAkBA,CAAC;EACjCJ,WAAW;EACXK;AAIF,CAAC,EAAgB;EACf,IAAIC,YAA0B;EAE9B,IAAIC,KAAK,CAACC,OAAO,CAACH,QAAQ,CAAC,EAAE;IAC3BC,YAAY,GAAIP,MAAM,IAAK,IAAAU,4BAAW,EAACV,MAAM,EAAEM,QAAQ,CAAC;EAC1D,CAAC,MAAM;IACLC,YAAY,GAAGD,QAAQ;EACzB;EAEA,MAAMK,WAAyB,GAAIX,MAAM,IAAK;IAC5C;IACA;IACA,IAAID,gBAAgB,CAACC,MAAM,EAAEC,WAAW,CAAC,EAAE;MACzC,OAAO,IAAAW,oCAAmB,EAACL,YAAY,EAAEN,WAAW,CAAC,CAACD,MAAM,CAAC;IAC/D;IAEA,OAAO,IAAAa,iCAAgB,EAACb,MAAM,EAAE;MAC9Bc,eAAe,EAAE,IAAI;MACrBC,MAAM,EAAEd,WAAW;MACnB;MACAK,QAAQ,EAAE,IAAAM,oCAAmB,EAACL,YAAY,EAAEN,WAAW;IACzD,CAAC,CAAC;EACJ,CAAC;EAED,MAAMe,UAAU,GAAGtB,WAAW,CAAC,QAAQO,WAAW,EAAE,CAAC;EACrDgB,MAAM,CAACC,cAAc,CAACP,WAAW,EAAE,MAAM,EAAE;IACzCQ,KAAK,EAAEH;EACT,CAAC,CAAC;EAEF,OAAOL,WAAW;AACpB","ignoreList":[]}
@@ -0,0 +1,6 @@
import { ConfigPlugin } from '@expo/config-plugins';
import { ResourceXMLConfig } from './withEdgeToEdge';
export declare const withConfigureEdgeToEdgeEnforcement: ConfigPlugin<{
disableEdgeToEdgeEnforcement: boolean;
}>;
export declare function configureEdgeToEdgeEnforcement(config: ResourceXMLConfig, disableEdgeToEdgeEnforcement: boolean): ResourceXMLConfig;
@@ -0,0 +1,53 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.configureEdgeToEdgeEnforcement = configureEdgeToEdgeEnforcement;
exports.withConfigureEdgeToEdgeEnforcement = void 0;
function _configPlugins() {
const data = require("@expo/config-plugins");
_configPlugins = function () {
return data;
};
return data;
}
const OPT_OUT_EDGE_TO_EDGE_ATTRIBUTE = 'android:windowOptOutEdgeToEdgeEnforcement';
const withConfigureEdgeToEdgeEnforcement = (config, {
disableEdgeToEdgeEnforcement
}) => {
return (0, _configPlugins().withAndroidStyles)(config, config => {
return configureEdgeToEdgeEnforcement(config, disableEdgeToEdgeEnforcement);
});
};
exports.withConfigureEdgeToEdgeEnforcement = withConfigureEdgeToEdgeEnforcement;
function configureEdgeToEdgeEnforcement(config, disableEdgeToEdgeEnforcement) {
const {
style = []
} = config.modResults.resources;
const disableEdgeToEdgeEnforcementItem = {
_: 'true',
$: {
name: OPT_OUT_EDGE_TO_EDGE_ATTRIBUTE,
'tools:targetApi': '35'
}
};
const mainThemeIndex = style.findIndex(({
$
}) => $.name === 'AppTheme');
if (mainThemeIndex === -1) {
return config;
}
const existingItem = style[mainThemeIndex].item.filter(({
$
}) => $.name !== OPT_OUT_EDGE_TO_EDGE_ATTRIBUTE);
if (disableEdgeToEdgeEnforcement) {
existingItem.push(disableEdgeToEdgeEnforcementItem);
}
if (!config.modResults.resources.style) {
return config;
}
config.modResults.resources.style[mainThemeIndex].item = existingItem;
return config;
}
//# sourceMappingURL=withConfigureEdgeToEdgeEnforcement.js.map
@@ -0,0 +1 @@
{"version":3,"file":"withConfigureEdgeToEdgeEnforcement.js","names":["_configPlugins","data","require","OPT_OUT_EDGE_TO_EDGE_ATTRIBUTE","withConfigureEdgeToEdgeEnforcement","config","disableEdgeToEdgeEnforcement","withAndroidStyles","configureEdgeToEdgeEnforcement","exports","style","modResults","resources","disableEdgeToEdgeEnforcementItem","_","$","name","mainThemeIndex","findIndex","existingItem","item","filter","push"],"sources":["../../../../src/plugins/unversioned/edge-to-edge/withConfigureEdgeToEdgeEnforcement.ts"],"sourcesContent":["import { ConfigPlugin, withAndroidStyles } from '@expo/config-plugins';\n\nimport { ResourceXMLConfig } from './withEdgeToEdge';\n\nconst OPT_OUT_EDGE_TO_EDGE_ATTRIBUTE = 'android:windowOptOutEdgeToEdgeEnforcement';\n\nexport const withConfigureEdgeToEdgeEnforcement: ConfigPlugin<{\n disableEdgeToEdgeEnforcement: boolean;\n}> = (config, { disableEdgeToEdgeEnforcement }) => {\n return withAndroidStyles(config, (config) => {\n return configureEdgeToEdgeEnforcement(config, disableEdgeToEdgeEnforcement);\n });\n};\n\nexport function configureEdgeToEdgeEnforcement(\n config: ResourceXMLConfig,\n disableEdgeToEdgeEnforcement: boolean\n): ResourceXMLConfig {\n const { style = [] } = config.modResults.resources;\n\n const disableEdgeToEdgeEnforcementItem = {\n _: 'true',\n $: {\n name: OPT_OUT_EDGE_TO_EDGE_ATTRIBUTE,\n 'tools:targetApi': '35',\n },\n };\n\n const mainThemeIndex = style.findIndex(({ $ }) => $.name === 'AppTheme');\n\n if (mainThemeIndex === -1) {\n return config;\n }\n\n const existingItem = style[mainThemeIndex].item.filter(\n ({ $ }) => $.name !== OPT_OUT_EDGE_TO_EDGE_ATTRIBUTE\n );\n\n if (disableEdgeToEdgeEnforcement) {\n existingItem.push(disableEdgeToEdgeEnforcementItem);\n }\n if (!config.modResults.resources.style) {\n return config;\n }\n\n config.modResults.resources.style[mainThemeIndex].item = existingItem;\n return config;\n}\n"],"mappings":";;;;;;;AAAA,SAAAA,eAAA;EAAA,MAAAC,IAAA,GAAAC,OAAA;EAAAF,cAAA,YAAAA,CAAA;IAAA,OAAAC,IAAA;EAAA;EAAA,OAAAA,IAAA;AAAA;AAIA,MAAME,8BAA8B,GAAG,2CAA2C;AAE3E,MAAMC,kCAEX,GAAGA,CAACC,MAAM,EAAE;EAAEC;AAA6B,CAAC,KAAK;EACjD,OAAO,IAAAC,kCAAiB,EAACF,MAAM,EAAGA,MAAM,IAAK;IAC3C,OAAOG,8BAA8B,CAACH,MAAM,EAAEC,4BAA4B,CAAC;EAC7E,CAAC,CAAC;AACJ,CAAC;AAACG,OAAA,CAAAL,kCAAA,GAAAA,kCAAA;AAEK,SAASI,8BAA8BA,CAC5CH,MAAyB,EACzBC,4BAAqC,EAClB;EACnB,MAAM;IAAEI,KAAK,GAAG;EAAG,CAAC,GAAGL,MAAM,CAACM,UAAU,CAACC,SAAS;EAElD,MAAMC,gCAAgC,GAAG;IACvCC,CAAC,EAAE,MAAM;IACTC,CAAC,EAAE;MACDC,IAAI,EAAEb,8BAA8B;MACpC,iBAAiB,EAAE;IACrB;EACF,CAAC;EAED,MAAMc,cAAc,GAAGP,KAAK,CAACQ,SAAS,CAAC,CAAC;IAAEH;EAAE,CAAC,KAAKA,CAAC,CAACC,IAAI,KAAK,UAAU,CAAC;EAExE,IAAIC,cAAc,KAAK,CAAC,CAAC,EAAE;IACzB,OAAOZ,MAAM;EACf;EAEA,MAAMc,YAAY,GAAGT,KAAK,CAACO,cAAc,CAAC,CAACG,IAAI,CAACC,MAAM,CACpD,CAAC;IAAEN;EAAE,CAAC,KAAKA,CAAC,CAACC,IAAI,KAAKb,8BACxB,CAAC;EAED,IAAIG,4BAA4B,EAAE;IAChCa,YAAY,CAACG,IAAI,CAACT,gCAAgC,CAAC;EACrD;EACA,IAAI,CAACR,MAAM,CAACM,UAAU,CAACC,SAAS,CAACF,KAAK,EAAE;IACtC,OAAOL,MAAM;EACf;EAEAA,MAAM,CAACM,UAAU,CAACC,SAAS,CAACF,KAAK,CAACO,cAAc,CAAC,CAACG,IAAI,GAAGD,YAAY;EACrE,OAAOd,MAAM;AACf","ignoreList":[]}
@@ -0,0 +1,9 @@
import { ConfigPlugin, ExportedConfigWithProps, AndroidConfig } from '@expo/config-plugins';
import { type ExpoConfig } from '@expo/config-types';
export type ResourceXMLConfig = ExportedConfigWithProps<AndroidConfig.Resources.ResourceXML>;
export type GradlePropertiesConfig = ExportedConfigWithProps<AndroidConfig.Properties.PropertiesItem[]>;
export declare const withEdgeToEdge: ConfigPlugin<{
projectRoot: string;
}>;
export declare function applyEdgeToEdge(config: ExpoConfig, projectRoot: string): ExpoConfig;
export default withEdgeToEdge;
@@ -0,0 +1,71 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.applyEdgeToEdge = applyEdgeToEdge;
exports.withEdgeToEdge = exports.default = void 0;
function _configPlugins() {
const data = require("@expo/config-plugins");
_configPlugins = function () {
return data;
};
return data;
}
function _withConfigureEdgeToEdgeEnforcement() {
const data = require("./withConfigureEdgeToEdgeEnforcement");
_withConfigureEdgeToEdgeEnforcement = function () {
return data;
};
return data;
}
function _withEdgeToEdgeEnabledGradleProperties() {
const data = require("./withEdgeToEdgeEnabledGradleProperties");
_withEdgeToEdgeEnabledGradleProperties = function () {
return data;
};
return data;
}
function _withEnforceNavigationBarContrast() {
const data = require("./withEnforceNavigationBarContrast");
_withEnforceNavigationBarContrast = function () {
return data;
};
return data;
}
function _withRestoreDefaultTheme() {
const data = require("./withRestoreDefaultTheme");
_withRestoreDefaultTheme = function () {
return data;
};
return data;
}
const TAG = 'EDGE_TO_EDGE_PLUGIN';
const withEdgeToEdge = (config, {
projectRoot
}) => {
return applyEdgeToEdge(config, projectRoot);
};
exports.withEdgeToEdge = withEdgeToEdge;
function applyEdgeToEdge(config, projectRoot) {
// NOTE(@kitten): Override for SDK 54 only. This is deprecated/removed but `false` is still technically accepted just for SDK 54
const raw_edgeToEdgeEnabled = config.android?.edgeToEdgeEnabled;
if (raw_edgeToEdgeEnabled === false) {
_configPlugins().WarningAggregator.addWarningAndroid(TAG, '`edgeToEdgeEnabled` field is explicitly set to false in the project app config. In Android 16+ (targetSdkVersion 36) it is no longer be possible to disable edge-to-edge. Learn more:', 'https://expo.fyi/edge-to-edge-rollout');
}
const edgeToEdgeEnabled = raw_edgeToEdgeEnabled !== false;
config = (0, _withEdgeToEdgeEnabledGradleProperties().withEdgeToEdgeEnabledGradleProperties)(config, {
edgeToEdgeEnabled
});
// Enable/disable edge-to-edge enforcement
config = (0, _withConfigureEdgeToEdgeEnforcement().withConfigureEdgeToEdgeEnforcement)(config, {
disableEdgeToEdgeEnforcement: !edgeToEdgeEnabled
});
config = (0, _withEnforceNavigationBarContrast().withEnforceNavigationBarContrast)(config, config.androidNavigationBar?.enforceContrast !== false);
// We always restore the default theme in case the project has a leftover react-native-edge-to-edge theme from SDK 53.
// If they are using react-native-edge-to-edge config plugin it'll be reapplied later.
return (0, _withRestoreDefaultTheme().withRestoreDefaultTheme)(config);
}
var _default = exports.default = withEdgeToEdge;
//# sourceMappingURL=withEdgeToEdge.js.map
@@ -0,0 +1 @@
{"version":3,"file":"withEdgeToEdge.js","names":["_configPlugins","data","require","_withConfigureEdgeToEdgeEnforcement","_withEdgeToEdgeEnabledGradleProperties","_withEnforceNavigationBarContrast","_withRestoreDefaultTheme","TAG","withEdgeToEdge","config","projectRoot","applyEdgeToEdge","exports","raw_edgeToEdgeEnabled","android","edgeToEdgeEnabled","WarningAggregator","addWarningAndroid","withEdgeToEdgeEnabledGradleProperties","withConfigureEdgeToEdgeEnforcement","disableEdgeToEdgeEnforcement","withEnforceNavigationBarContrast","androidNavigationBar","enforceContrast","withRestoreDefaultTheme","_default","default"],"sources":["../../../../src/plugins/unversioned/edge-to-edge/withEdgeToEdge.ts"],"sourcesContent":["import {\n ConfigPlugin,\n ExportedConfigWithProps,\n WarningAggregator,\n AndroidConfig,\n} from '@expo/config-plugins';\nimport { type ExpoConfig } from '@expo/config-types';\n\nimport { withConfigureEdgeToEdgeEnforcement } from './withConfigureEdgeToEdgeEnforcement';\nimport { withEdgeToEdgeEnabledGradleProperties } from './withEdgeToEdgeEnabledGradleProperties';\nimport { withEnforceNavigationBarContrast } from './withEnforceNavigationBarContrast';\nimport { withRestoreDefaultTheme } from './withRestoreDefaultTheme';\n\nconst TAG = 'EDGE_TO_EDGE_PLUGIN';\n\nexport type ResourceXMLConfig = ExportedConfigWithProps<AndroidConfig.Resources.ResourceXML>;\nexport type GradlePropertiesConfig = ExportedConfigWithProps<\n AndroidConfig.Properties.PropertiesItem[]\n>;\n\nexport const withEdgeToEdge: ConfigPlugin<{ projectRoot: string }> = (config, { projectRoot }) => {\n return applyEdgeToEdge(config, projectRoot);\n};\n\nexport function applyEdgeToEdge(config: ExpoConfig, projectRoot: string): ExpoConfig {\n // NOTE(@kitten): Override for SDK 54 only. This is deprecated/removed but `false` is still technically accepted just for SDK 54\n const raw_edgeToEdgeEnabled = config.android?.edgeToEdgeEnabled as boolean | undefined;\n\n if (raw_edgeToEdgeEnabled === false) {\n WarningAggregator.addWarningAndroid(\n TAG,\n '`edgeToEdgeEnabled` field is explicitly set to false in the project app config. In Android 16+ (targetSdkVersion 36) it is no longer be possible to disable edge-to-edge. Learn more:',\n 'https://expo.fyi/edge-to-edge-rollout'\n );\n }\n\n const edgeToEdgeEnabled = raw_edgeToEdgeEnabled !== false;\n\n config = withEdgeToEdgeEnabledGradleProperties(config, { edgeToEdgeEnabled });\n // Enable/disable edge-to-edge enforcement\n config = withConfigureEdgeToEdgeEnforcement(config, {\n disableEdgeToEdgeEnforcement: !edgeToEdgeEnabled,\n });\n\n config = withEnforceNavigationBarContrast(\n config,\n config.androidNavigationBar?.enforceContrast !== false\n );\n\n // We always restore the default theme in case the project has a leftover react-native-edge-to-edge theme from SDK 53.\n // If they are using react-native-edge-to-edge config plugin it'll be reapplied later.\n return withRestoreDefaultTheme(config);\n}\n\nexport default withEdgeToEdge;\n"],"mappings":";;;;;;;AAAA,SAAAA,eAAA;EAAA,MAAAC,IAAA,GAAAC,OAAA;EAAAF,cAAA,YAAAA,CAAA;IAAA,OAAAC,IAAA;EAAA;EAAA,OAAAA,IAAA;AAAA;AAQA,SAAAE,oCAAA;EAAA,MAAAF,IAAA,GAAAC,OAAA;EAAAC,mCAAA,YAAAA,CAAA;IAAA,OAAAF,IAAA;EAAA;EAAA,OAAAA,IAAA;AAAA;AACA,SAAAG,uCAAA;EAAA,MAAAH,IAAA,GAAAC,OAAA;EAAAE,sCAAA,YAAAA,CAAA;IAAA,OAAAH,IAAA;EAAA;EAAA,OAAAA,IAAA;AAAA;AACA,SAAAI,kCAAA;EAAA,MAAAJ,IAAA,GAAAC,OAAA;EAAAG,iCAAA,YAAAA,CAAA;IAAA,OAAAJ,IAAA;EAAA;EAAA,OAAAA,IAAA;AAAA;AACA,SAAAK,yBAAA;EAAA,MAAAL,IAAA,GAAAC,OAAA;EAAAI,wBAAA,YAAAA,CAAA;IAAA,OAAAL,IAAA;EAAA;EAAA,OAAAA,IAAA;AAAA;AAEA,MAAMM,GAAG,GAAG,qBAAqB;AAO1B,MAAMC,cAAqD,GAAGA,CAACC,MAAM,EAAE;EAAEC;AAAY,CAAC,KAAK;EAChG,OAAOC,eAAe,CAACF,MAAM,EAAEC,WAAW,CAAC;AAC7C,CAAC;AAACE,OAAA,CAAAJ,cAAA,GAAAA,cAAA;AAEK,SAASG,eAAeA,CAACF,MAAkB,EAAEC,WAAmB,EAAc;EACnF;EACA,MAAMG,qBAAqB,GAAGJ,MAAM,CAACK,OAAO,EAAEC,iBAAwC;EAEtF,IAAIF,qBAAqB,KAAK,KAAK,EAAE;IACnCG,kCAAiB,CAACC,iBAAiB,CACjCV,GAAG,EACH,uLAAuL,EACvL,uCACF,CAAC;EACH;EAEA,MAAMQ,iBAAiB,GAAGF,qBAAqB,KAAK,KAAK;EAEzDJ,MAAM,GAAG,IAAAS,8EAAqC,EAACT,MAAM,EAAE;IAAEM;EAAkB,CAAC,CAAC;EAC7E;EACAN,MAAM,GAAG,IAAAU,wEAAkC,EAACV,MAAM,EAAE;IAClDW,4BAA4B,EAAE,CAACL;EACjC,CAAC,CAAC;EAEFN,MAAM,GAAG,IAAAY,oEAAgC,EACvCZ,MAAM,EACNA,MAAM,CAACa,oBAAoB,EAAEC,eAAe,KAAK,KACnD,CAAC;;EAED;EACA;EACA,OAAO,IAAAC,kDAAuB,EAACf,MAAM,CAAC;AACxC;AAAC,IAAAgB,QAAA,GAAAb,OAAA,CAAAc,OAAA,GAEclB,cAAc","ignoreList":[]}
@@ -0,0 +1,6 @@
import type { ExpoConfig } from '@expo/config-types';
import { GradlePropertiesConfig } from './withEdgeToEdge';
export declare function withEdgeToEdgeEnabledGradleProperties(config: ExpoConfig, props: {
edgeToEdgeEnabled: boolean;
}): ExpoConfig;
export declare function configureEdgeToEdgeEnabledGradleProperties(config: GradlePropertiesConfig, edgeToEdgeEnabled: boolean): GradlePropertiesConfig;
@@ -0,0 +1,59 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.configureEdgeToEdgeEnabledGradleProperties = configureEdgeToEdgeEnabledGradleProperties;
exports.withEdgeToEdgeEnabledGradleProperties = withEdgeToEdgeEnabledGradleProperties;
function _configPlugins() {
const data = require("@expo/config-plugins");
_configPlugins = function () {
return data;
};
return data;
}
const OLD_EXPO_EDGE_TO_EDGE_ENABLED_GRADLE_PROPERTY_COMMENT = 'Whether the app is configured to use edge-to-edge via the app config or `react-native-edge-to-edge` plugin';
const EXPO_EDGE_TO_EDGE_ENABLED_GRADLE_PROPERTY_KEY = 'expo.edgeToEdgeEnabled';
const EXPO_EDGE_TO_EDGE_ENABLED_GRADLE_PROPERTY_COMMENT = 'Specifies whether the app is configured to use edge-to-edge via the app config or plugin\n' + '# WARNING: This property has been deprecated and will be removed in Expo SDK 55. Use `edgeToEdgeEnabled` or `react.edgeToEdgeEnabled` to determine whether the project is using edge-to-edge.';
const REACT_EDGE_TO_EDGE_ENABLED_GRADLE_PROPERTY_KEY = 'edgeToEdgeEnabled';
const REACT_EDGE_TO_EDGE_ENABLED_GRADLE_PROPERTY_COMMENT = 'Use this property to enable edge-to-edge display support.\n' + '# This allows your app to draw behind system bars for an immersive UI.\n' + '# Note: Only works with ReactActivity and should not be used with custom Activity.';
function withEdgeToEdgeEnabledGradleProperties(config, props) {
return (0, _configPlugins().withGradleProperties)(config, config => {
return configureEdgeToEdgeEnabledGradleProperties(config, props.edgeToEdgeEnabled);
});
}
function configureEdgeToEdgeEnabledGradleProperties(config, edgeToEdgeEnabled) {
// TODO: Remove for SDK 55
config = removeOldExpoEdgeToEdgeEnabledComment(config);
// TODO: Remove for SDK 55
config = configureGradleProperty(config, EXPO_EDGE_TO_EDGE_ENABLED_GRADLE_PROPERTY_KEY, edgeToEdgeEnabled ? 'true' : 'false', EXPO_EDGE_TO_EDGE_ENABLED_GRADLE_PROPERTY_COMMENT);
return configureGradleProperty(config, REACT_EDGE_TO_EDGE_ENABLED_GRADLE_PROPERTY_KEY, edgeToEdgeEnabled ? 'true' : 'false', REACT_EDGE_TO_EDGE_ENABLED_GRADLE_PROPERTY_COMMENT);
}
// TODO: Remove for SDK 55
function removeOldExpoEdgeToEdgeEnabledComment(config) {
const commentIndex = config.modResults.findIndex(item => item.type === 'comment' && item.value === OLD_EXPO_EDGE_TO_EDGE_ENABLED_GRADLE_PROPERTY_COMMENT);
if (commentIndex !== -1) {
config.modResults.splice(commentIndex, 1);
}
return config;
}
function configureGradleProperty(config, key, value, comment, addNewLine = true) {
const propertyIndex = config.modResults.findIndex(item => item.type === 'property' && item.key === key);
if (propertyIndex !== -1 && config.modResults[propertyIndex].type === 'property') {
config.modResults[propertyIndex].value = value;
} else {
config.modResults.push({
type: 'comment',
value: comment
});
config.modResults.push({
type: 'property',
key,
value: addNewLine ? value + '\n' : value
});
}
return config;
}
//# sourceMappingURL=withEdgeToEdgeEnabledGradleProperties.js.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1,4 @@
import { ConfigPlugin } from '@expo/config-plugins';
import { ResourceXMLConfig } from './withEdgeToEdge';
export declare const withEnforceNavigationBarContrast: ConfigPlugin<boolean>;
export declare function applyEnforceNavigationBarContrast(config: ResourceXMLConfig, enforceNavigationBarContrast: boolean): ResourceXMLConfig;
@@ -0,0 +1,54 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.applyEnforceNavigationBarContrast = applyEnforceNavigationBarContrast;
exports.withEnforceNavigationBarContrast = void 0;
function _configPlugins() {
const data = require("@expo/config-plugins");
_configPlugins = function () {
return data;
};
return data;
}
const withEnforceNavigationBarContrast = (config, enforceNavigationBarContrast) => {
return (0, _configPlugins().withAndroidStyles)(config, config => {
return applyEnforceNavigationBarContrast(config, enforceNavigationBarContrast);
});
};
exports.withEnforceNavigationBarContrast = withEnforceNavigationBarContrast;
function applyEnforceNavigationBarContrast(config, enforceNavigationBarContrast) {
const enforceNavigationBarContrastItem = {
_: enforceNavigationBarContrast ? 'true' : 'false',
$: {
name: 'android:enforceNavigationBarContrast',
'tools:targetApi': '29'
}
};
const {
style = []
} = config.modResults.resources;
const mainThemeIndex = style.findIndex(({
$
}) => $.name === 'AppTheme');
if (mainThemeIndex === -1) {
return config;
}
const mainTheme = style[mainThemeIndex];
const enforceIndex = mainTheme.item.findIndex(({
$
}) => $.name === 'android:enforceNavigationBarContrast');
if (enforceIndex !== -1) {
style[mainThemeIndex].item[enforceIndex] = enforceNavigationBarContrastItem;
return config;
}
config.modResults.resources.style = [{
$: style[mainThemeIndex].$,
item: [enforceNavigationBarContrastItem, ...mainTheme.item]
}, ...style.filter(({
$
}) => $.name !== 'AppTheme')];
return config;
}
//# sourceMappingURL=withEnforceNavigationBarContrast.js.map
@@ -0,0 +1 @@
{"version":3,"file":"withEnforceNavigationBarContrast.js","names":["_configPlugins","data","require","withEnforceNavigationBarContrast","config","enforceNavigationBarContrast","withAndroidStyles","applyEnforceNavigationBarContrast","exports","enforceNavigationBarContrastItem","_","$","name","style","modResults","resources","mainThemeIndex","findIndex","mainTheme","enforceIndex","item","filter"],"sources":["../../../../src/plugins/unversioned/edge-to-edge/withEnforceNavigationBarContrast.ts"],"sourcesContent":["import { ConfigPlugin, withAndroidStyles } from '@expo/config-plugins';\n\nimport { ResourceXMLConfig } from './withEdgeToEdge';\n\nexport const withEnforceNavigationBarContrast: ConfigPlugin<boolean> = (\n config,\n enforceNavigationBarContrast: boolean\n) => {\n return withAndroidStyles(config, (config) => {\n return applyEnforceNavigationBarContrast(config, enforceNavigationBarContrast);\n });\n};\n\nexport function applyEnforceNavigationBarContrast(\n config: ResourceXMLConfig,\n enforceNavigationBarContrast: boolean\n): ResourceXMLConfig {\n const enforceNavigationBarContrastItem = {\n _: enforceNavigationBarContrast ? 'true' : 'false',\n $: {\n name: 'android:enforceNavigationBarContrast',\n 'tools:targetApi': '29',\n },\n };\n const { style = [] } = config.modResults.resources;\n const mainThemeIndex = style.findIndex(({ $ }) => $.name === 'AppTheme');\n if (mainThemeIndex === -1) {\n return config;\n }\n const mainTheme = style[mainThemeIndex];\n const enforceIndex = mainTheme.item.findIndex(\n ({ $ }) => $.name === 'android:enforceNavigationBarContrast'\n );\n if (enforceIndex !== -1) {\n style[mainThemeIndex].item[enforceIndex] = enforceNavigationBarContrastItem;\n return config;\n }\n\n config.modResults.resources.style = [\n {\n $: style[mainThemeIndex].$,\n item: [enforceNavigationBarContrastItem, ...mainTheme.item],\n },\n ...style.filter(({ $ }) => $.name !== 'AppTheme'),\n ];\n\n return config;\n}\n"],"mappings":";;;;;;;AAAA,SAAAA,eAAA;EAAA,MAAAC,IAAA,GAAAC,OAAA;EAAAF,cAAA,YAAAA,CAAA;IAAA,OAAAC,IAAA;EAAA;EAAA,OAAAA,IAAA;AAAA;AAIO,MAAME,gCAAuD,GAAGA,CACrEC,MAAM,EACNC,4BAAqC,KAClC;EACH,OAAO,IAAAC,kCAAiB,EAACF,MAAM,EAAGA,MAAM,IAAK;IAC3C,OAAOG,iCAAiC,CAACH,MAAM,EAAEC,4BAA4B,CAAC;EAChF,CAAC,CAAC;AACJ,CAAC;AAACG,OAAA,CAAAL,gCAAA,GAAAA,gCAAA;AAEK,SAASI,iCAAiCA,CAC/CH,MAAyB,EACzBC,4BAAqC,EAClB;EACnB,MAAMI,gCAAgC,GAAG;IACvCC,CAAC,EAAEL,4BAA4B,GAAG,MAAM,GAAG,OAAO;IAClDM,CAAC,EAAE;MACDC,IAAI,EAAE,sCAAsC;MAC5C,iBAAiB,EAAE;IACrB;EACF,CAAC;EACD,MAAM;IAAEC,KAAK,GAAG;EAAG,CAAC,GAAGT,MAAM,CAACU,UAAU,CAACC,SAAS;EAClD,MAAMC,cAAc,GAAGH,KAAK,CAACI,SAAS,CAAC,CAAC;IAAEN;EAAE,CAAC,KAAKA,CAAC,CAACC,IAAI,KAAK,UAAU,CAAC;EACxE,IAAII,cAAc,KAAK,CAAC,CAAC,EAAE;IACzB,OAAOZ,MAAM;EACf;EACA,MAAMc,SAAS,GAAGL,KAAK,CAACG,cAAc,CAAC;EACvC,MAAMG,YAAY,GAAGD,SAAS,CAACE,IAAI,CAACH,SAAS,CAC3C,CAAC;IAAEN;EAAE,CAAC,KAAKA,CAAC,CAACC,IAAI,KAAK,sCACxB,CAAC;EACD,IAAIO,YAAY,KAAK,CAAC,CAAC,EAAE;IACvBN,KAAK,CAACG,cAAc,CAAC,CAACI,IAAI,CAACD,YAAY,CAAC,GAAGV,gCAAgC;IAC3E,OAAOL,MAAM;EACf;EAEAA,MAAM,CAACU,UAAU,CAACC,SAAS,CAACF,KAAK,GAAG,CAClC;IACEF,CAAC,EAAEE,KAAK,CAACG,cAAc,CAAC,CAACL,CAAC;IAC1BS,IAAI,EAAE,CAACX,gCAAgC,EAAE,GAAGS,SAAS,CAACE,IAAI;EAC5D,CAAC,EACD,GAAGP,KAAK,CAACQ,MAAM,CAAC,CAAC;IAAEV;EAAE,CAAC,KAAKA,CAAC,CAACC,IAAI,KAAK,UAAU,CAAC,CAClD;EAED,OAAOR,MAAM;AACf","ignoreList":[]}
@@ -0,0 +1,4 @@
import { ConfigPlugin } from '@expo/config-plugins';
import { ResourceXMLConfig } from './withEdgeToEdge';
export declare const withRestoreDefaultTheme: ConfigPlugin;
export declare function restoreDefaultTheme(config: ResourceXMLConfig): ResourceXMLConfig;
@@ -0,0 +1,46 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.restoreDefaultTheme = restoreDefaultTheme;
exports.withRestoreDefaultTheme = void 0;
function _configPlugins() {
const data = require("@expo/config-plugins");
_configPlugins = function () {
return data;
};
return data;
}
const withRestoreDefaultTheme = config => {
// Default theme for SDK 53 and onwards projects
return (0, _configPlugins().withAndroidStyles)(config, config => {
return restoreDefaultTheme(config);
});
};
exports.withRestoreDefaultTheme = withRestoreDefaultTheme;
function restoreDefaultTheme(config) {
const DEFAULT_THEME = 'Theme.AppCompat.DayNight.NoActionBar';
const {
style = []
} = config.modResults.resources;
const mainThemeIndex = style.findIndex(({
$
}) => $.name === 'AppTheme');
if (mainThemeIndex === -1) {
return config;
}
if (style[mainThemeIndex].$?.parent.includes('EdgeToEdge')) {
config.modResults.resources.style = [{
$: {
name: 'AppTheme',
parent: DEFAULT_THEME
},
item: style[mainThemeIndex].item
}, ...style.filter(({
$
}) => $.name !== 'AppTheme')];
}
return config;
}
//# sourceMappingURL=withRestoreDefaultTheme.js.map
@@ -0,0 +1 @@
{"version":3,"file":"withRestoreDefaultTheme.js","names":["_configPlugins","data","require","withRestoreDefaultTheme","config","withAndroidStyles","restoreDefaultTheme","exports","DEFAULT_THEME","style","modResults","resources","mainThemeIndex","findIndex","$","name","parent","includes","item","filter"],"sources":["../../../../src/plugins/unversioned/edge-to-edge/withRestoreDefaultTheme.ts"],"sourcesContent":["import { ConfigPlugin, withAndroidStyles } from '@expo/config-plugins';\n\nimport { ResourceXMLConfig } from './withEdgeToEdge';\n\nexport const withRestoreDefaultTheme: ConfigPlugin = (config) => {\n // Default theme for SDK 53 and onwards projects\n return withAndroidStyles(config, (config) => {\n return restoreDefaultTheme(config);\n });\n};\n\nexport function restoreDefaultTheme(config: ResourceXMLConfig): ResourceXMLConfig {\n const DEFAULT_THEME = 'Theme.AppCompat.DayNight.NoActionBar';\n\n const { style = [] } = config.modResults.resources;\n const mainThemeIndex = style.findIndex(({ $ }) => $.name === 'AppTheme');\n if (mainThemeIndex === -1) {\n return config;\n }\n\n if (style[mainThemeIndex].$?.parent.includes('EdgeToEdge')) {\n config.modResults.resources.style = [\n {\n $: {\n name: 'AppTheme',\n parent: DEFAULT_THEME,\n },\n item: style[mainThemeIndex].item,\n },\n ...style.filter(({ $ }) => $.name !== 'AppTheme'),\n ];\n }\n return config;\n}\n"],"mappings":";;;;;;;AAAA,SAAAA,eAAA;EAAA,MAAAC,IAAA,GAAAC,OAAA;EAAAF,cAAA,YAAAA,CAAA;IAAA,OAAAC,IAAA;EAAA;EAAA,OAAAA,IAAA;AAAA;AAIO,MAAME,uBAAqC,GAAIC,MAAM,IAAK;EAC/D;EACA,OAAO,IAAAC,kCAAiB,EAACD,MAAM,EAAGA,MAAM,IAAK;IAC3C,OAAOE,mBAAmB,CAACF,MAAM,CAAC;EACpC,CAAC,CAAC;AACJ,CAAC;AAACG,OAAA,CAAAJ,uBAAA,GAAAA,uBAAA;AAEK,SAASG,mBAAmBA,CAACF,MAAyB,EAAqB;EAChF,MAAMI,aAAa,GAAG,sCAAsC;EAE5D,MAAM;IAAEC,KAAK,GAAG;EAAG,CAAC,GAAGL,MAAM,CAACM,UAAU,CAACC,SAAS;EAClD,MAAMC,cAAc,GAAGH,KAAK,CAACI,SAAS,CAAC,CAAC;IAAEC;EAAE,CAAC,KAAKA,CAAC,CAACC,IAAI,KAAK,UAAU,CAAC;EACxE,IAAIH,cAAc,KAAK,CAAC,CAAC,EAAE;IACzB,OAAOR,MAAM;EACf;EAEA,IAAIK,KAAK,CAACG,cAAc,CAAC,CAACE,CAAC,EAAEE,MAAM,CAACC,QAAQ,CAAC,YAAY,CAAC,EAAE;IAC1Db,MAAM,CAACM,UAAU,CAACC,SAAS,CAACF,KAAK,GAAG,CAClC;MACEK,CAAC,EAAE;QACDC,IAAI,EAAE,UAAU;QAChBC,MAAM,EAAER;MACV,CAAC;MACDU,IAAI,EAAET,KAAK,CAACG,cAAc,CAAC,CAACM;IAC9B,CAAC,EACD,GAAGT,KAAK,CAACU,MAAM,CAAC,CAAC;MAAEL;IAAE,CAAC,KAAKA,CAAC,CAACC,IAAI,KAAK,UAAU,CAAC,CAClD;EACH;EACA,OAAOX,MAAM;AACf","ignoreList":[]}
@@ -0,0 +1,2 @@
declare const _default: import("@expo/config-plugins").ConfigPlugin;
export default _default;
@@ -0,0 +1,32 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
function _withAndroidAdMob() {
const data = require("./withAndroidAdMob");
_withAndroidAdMob = function () {
return data;
};
return data;
}
function _withIosAdMob() {
const data = require("./withIosAdMob");
_withIosAdMob = function () {
return data;
};
return data;
}
function _createLegacyPlugin() {
const data = require("../createLegacyPlugin");
_createLegacyPlugin = function () {
return data;
};
return data;
}
var _default = exports.default = (0, _createLegacyPlugin().createLegacyPlugin)({
packageName: 'expo-ads-admob',
fallback: [_withAndroidAdMob().withAndroidAdMob, _withIosAdMob().withIosAdMob]
});
//# sourceMappingURL=expo-ads-admob.js.map
@@ -0,0 +1 @@
{"version":3,"file":"expo-ads-admob.js","names":["_withAndroidAdMob","data","require","_withIosAdMob","_createLegacyPlugin","_default","exports","default","createLegacyPlugin","packageName","fallback","withAndroidAdMob","withIosAdMob"],"sources":["../../../../src/plugins/unversioned/expo-ads-admob/expo-ads-admob.ts"],"sourcesContent":["import { withAndroidAdMob } from './withAndroidAdMob';\nimport { withIosAdMob } from './withIosAdMob';\nimport { createLegacyPlugin } from '../createLegacyPlugin';\n\nexport default createLegacyPlugin({\n packageName: 'expo-ads-admob',\n fallback: [withAndroidAdMob, withIosAdMob],\n});\n"],"mappings":";;;;;;AAAA,SAAAA,kBAAA;EAAA,MAAAC,IAAA,GAAAC,OAAA;EAAAF,iBAAA,YAAAA,CAAA;IAAA,OAAAC,IAAA;EAAA;EAAA,OAAAA,IAAA;AAAA;AACA,SAAAE,cAAA;EAAA,MAAAF,IAAA,GAAAC,OAAA;EAAAC,aAAA,YAAAA,CAAA;IAAA,OAAAF,IAAA;EAAA;EAAA,OAAAA,IAAA;AAAA;AACA,SAAAG,oBAAA;EAAA,MAAAH,IAAA,GAAAC,OAAA;EAAAE,mBAAA,YAAAA,CAAA;IAAA,OAAAH,IAAA;EAAA;EAAA,OAAAA,IAAA;AAAA;AAA2D,IAAAI,QAAA,GAAAC,OAAA,CAAAC,OAAA,GAE5C,IAAAC,wCAAkB,EAAC;EAChCC,WAAW,EAAE,gBAAgB;EAC7BC,QAAQ,EAAE,CAACC,oCAAgB,EAAEC,4BAAY;AAC3C,CAAC,CAAC","ignoreList":[]}
@@ -0,0 +1,6 @@
import { AndroidConfig, ConfigPlugin } from '@expo/config-plugins';
import { ExpoConfig } from '@expo/config-types';
export declare const withAndroidAdMob: ConfigPlugin;
export declare function getGoogleMobileAdsAppId(config: Pick<ExpoConfig, 'android'>): string | null;
export declare function getGoogleMobileAdsAutoInit(config: Pick<ExpoConfig, 'android'>): boolean;
export declare function setAdMobConfig(config: Pick<ExpoConfig, 'android'>, androidManifest: AndroidConfig.Manifest.AndroidManifest): AndroidConfig.Manifest.AndroidManifest;
@@ -0,0 +1,50 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.getGoogleMobileAdsAppId = getGoogleMobileAdsAppId;
exports.getGoogleMobileAdsAutoInit = getGoogleMobileAdsAutoInit;
exports.setAdMobConfig = setAdMobConfig;
exports.withAndroidAdMob = void 0;
function _configPlugins() {
const data = require("@expo/config-plugins");
_configPlugins = function () {
return data;
};
return data;
}
const {
addMetaDataItemToMainApplication,
getMainApplicationOrThrow,
removeMetaDataItemFromMainApplication
} = _configPlugins().AndroidConfig.Manifest;
const META_APPLICATION_ID = 'com.google.android.gms.ads.APPLICATION_ID';
const META_DELAY_APP_MEASUREMENT_INIT = 'com.google.android.gms.ads.DELAY_APP_MEASUREMENT_INIT';
const withAndroidAdMob = config => {
return (0, _configPlugins().withAndroidManifest)(config, config => {
config.modResults = setAdMobConfig(config, config.modResults);
return config;
});
};
exports.withAndroidAdMob = withAndroidAdMob;
function getGoogleMobileAdsAppId(config) {
return config.android?.config?.googleMobileAdsAppId ?? null;
}
function getGoogleMobileAdsAutoInit(config) {
return config.android?.config?.googleMobileAdsAutoInit ?? false;
}
function setAdMobConfig(config, androidManifest) {
const appId = getGoogleMobileAdsAppId(config);
const autoInit = getGoogleMobileAdsAutoInit(config);
const mainApplication = getMainApplicationOrThrow(androidManifest);
if (appId) {
addMetaDataItemToMainApplication(mainApplication, META_APPLICATION_ID, appId);
addMetaDataItemToMainApplication(mainApplication, META_DELAY_APP_MEASUREMENT_INIT, String(!autoInit));
} else {
removeMetaDataItemFromMainApplication(mainApplication, META_APPLICATION_ID);
removeMetaDataItemFromMainApplication(mainApplication, META_DELAY_APP_MEASUREMENT_INIT);
}
return androidManifest;
}
//# sourceMappingURL=withAndroidAdMob.js.map
@@ -0,0 +1 @@
{"version":3,"file":"withAndroidAdMob.js","names":["_configPlugins","data","require","addMetaDataItemToMainApplication","getMainApplicationOrThrow","removeMetaDataItemFromMainApplication","AndroidConfig","Manifest","META_APPLICATION_ID","META_DELAY_APP_MEASUREMENT_INIT","withAndroidAdMob","config","withAndroidManifest","modResults","setAdMobConfig","exports","getGoogleMobileAdsAppId","android","googleMobileAdsAppId","getGoogleMobileAdsAutoInit","googleMobileAdsAutoInit","androidManifest","appId","autoInit","mainApplication","String"],"sources":["../../../../src/plugins/unversioned/expo-ads-admob/withAndroidAdMob.ts"],"sourcesContent":["import { AndroidConfig, ConfigPlugin, withAndroidManifest } from '@expo/config-plugins';\nimport { ExpoConfig } from '@expo/config-types';\n\nconst {\n addMetaDataItemToMainApplication,\n getMainApplicationOrThrow,\n removeMetaDataItemFromMainApplication,\n} = AndroidConfig.Manifest;\n\nconst META_APPLICATION_ID = 'com.google.android.gms.ads.APPLICATION_ID';\nconst META_DELAY_APP_MEASUREMENT_INIT = 'com.google.android.gms.ads.DELAY_APP_MEASUREMENT_INIT';\n\nexport const withAndroidAdMob: ConfigPlugin = (config) => {\n return withAndroidManifest(config, (config) => {\n config.modResults = setAdMobConfig(config, config.modResults);\n return config;\n });\n};\n\nexport function getGoogleMobileAdsAppId(config: Pick<ExpoConfig, 'android'>) {\n return config.android?.config?.googleMobileAdsAppId ?? null;\n}\n\nexport function getGoogleMobileAdsAutoInit(config: Pick<ExpoConfig, 'android'>) {\n return config.android?.config?.googleMobileAdsAutoInit ?? false;\n}\n\nexport function setAdMobConfig(\n config: Pick<ExpoConfig, 'android'>,\n androidManifest: AndroidConfig.Manifest.AndroidManifest\n) {\n const appId = getGoogleMobileAdsAppId(config);\n const autoInit = getGoogleMobileAdsAutoInit(config);\n const mainApplication = getMainApplicationOrThrow(androidManifest);\n\n if (appId) {\n addMetaDataItemToMainApplication(mainApplication, META_APPLICATION_ID, appId);\n addMetaDataItemToMainApplication(\n mainApplication,\n META_DELAY_APP_MEASUREMENT_INIT,\n String(!autoInit)\n );\n } else {\n removeMetaDataItemFromMainApplication(mainApplication, META_APPLICATION_ID);\n removeMetaDataItemFromMainApplication(mainApplication, META_DELAY_APP_MEASUREMENT_INIT);\n }\n\n return androidManifest;\n}\n"],"mappings":";;;;;;;;;AAAA,SAAAA,eAAA;EAAA,MAAAC,IAAA,GAAAC,OAAA;EAAAF,cAAA,YAAAA,CAAA;IAAA,OAAAC,IAAA;EAAA;EAAA,OAAAA,IAAA;AAAA;AAGA,MAAM;EACJE,gCAAgC;EAChCC,yBAAyB;EACzBC;AACF,CAAC,GAAGC,8BAAa,CAACC,QAAQ;AAE1B,MAAMC,mBAAmB,GAAG,2CAA2C;AACvE,MAAMC,+BAA+B,GAAG,uDAAuD;AAExF,MAAMC,gBAA8B,GAAIC,MAAM,IAAK;EACxD,OAAO,IAAAC,oCAAmB,EAACD,MAAM,EAAGA,MAAM,IAAK;IAC7CA,MAAM,CAACE,UAAU,GAAGC,cAAc,CAACH,MAAM,EAAEA,MAAM,CAACE,UAAU,CAAC;IAC7D,OAAOF,MAAM;EACf,CAAC,CAAC;AACJ,CAAC;AAACI,OAAA,CAAAL,gBAAA,GAAAA,gBAAA;AAEK,SAASM,uBAAuBA,CAACL,MAAmC,EAAE;EAC3E,OAAOA,MAAM,CAACM,OAAO,EAAEN,MAAM,EAAEO,oBAAoB,IAAI,IAAI;AAC7D;AAEO,SAASC,0BAA0BA,CAACR,MAAmC,EAAE;EAC9E,OAAOA,MAAM,CAACM,OAAO,EAAEN,MAAM,EAAES,uBAAuB,IAAI,KAAK;AACjE;AAEO,SAASN,cAAcA,CAC5BH,MAAmC,EACnCU,eAAuD,EACvD;EACA,MAAMC,KAAK,GAAGN,uBAAuB,CAACL,MAAM,CAAC;EAC7C,MAAMY,QAAQ,GAAGJ,0BAA0B,CAACR,MAAM,CAAC;EACnD,MAAMa,eAAe,GAAGpB,yBAAyB,CAACiB,eAAe,CAAC;EAElE,IAAIC,KAAK,EAAE;IACTnB,gCAAgC,CAACqB,eAAe,EAAEhB,mBAAmB,EAAEc,KAAK,CAAC;IAC7EnB,gCAAgC,CAC9BqB,eAAe,EACff,+BAA+B,EAC/BgB,MAAM,CAAC,CAACF,QAAQ,CAClB,CAAC;EACH,CAAC,MAAM;IACLlB,qCAAqC,CAACmB,eAAe,EAAEhB,mBAAmB,CAAC;IAC3EH,qCAAqC,CAACmB,eAAe,EAAEf,+BAA+B,CAAC;EACzF;EAEA,OAAOY,eAAe;AACxB","ignoreList":[]}
@@ -0,0 +1,5 @@
import { ConfigPlugin, InfoPlist } from '@expo/config-plugins';
import { ExpoConfig } from '@expo/config-types';
export declare const withIosAdMob: ConfigPlugin;
export declare function getGoogleMobileAdsAppId(config: Pick<ExpoConfig, 'ios'>): string | null;
export declare function setGoogleMobileAdsAppId(config: Pick<ExpoConfig, 'ios'>, { GADApplicationIdentifier, ...infoPlist }: InfoPlist): InfoPlist;
@@ -0,0 +1,51 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.getGoogleMobileAdsAppId = getGoogleMobileAdsAppId;
exports.setGoogleMobileAdsAppId = setGoogleMobileAdsAppId;
exports.withIosAdMob = void 0;
function _configPlugins() {
const data = require("@expo/config-plugins");
_configPlugins = function () {
return data;
};
return data;
}
const withIosAdMob = config => {
return (0, _configPlugins().withInfoPlist)(config, config => {
config.modResults = setAdMobConfig(config, config.modResults);
return config;
});
};
// NOTE(brentvatne): if the developer has installed the google ads sdk and does
// not provide an app id their app will crash. Standalone apps get around this by
// providing some default value, we will instead here assume that the user can
// do the right thing if they have installed the package. This is a slight discrepancy
// that arises in ejecting because it's possible for the package to be installed and
// not crashing in the managed workflow, then you eject and the app crashes because
// you don't have an id to fall back to.
exports.withIosAdMob = withIosAdMob;
function getGoogleMobileAdsAppId(config) {
return config.ios?.config?.googleMobileAdsAppId ?? null;
}
function setGoogleMobileAdsAppId(config, {
GADApplicationIdentifier,
...infoPlist
}) {
const appId = getGoogleMobileAdsAppId(config);
if (appId === null) {
return infoPlist;
}
return {
...infoPlist,
GADApplicationIdentifier: appId
};
}
function setAdMobConfig(config, infoPlist) {
infoPlist = setGoogleMobileAdsAppId(config, infoPlist);
return infoPlist;
}
//# sourceMappingURL=withIosAdMob.js.map
@@ -0,0 +1 @@
{"version":3,"file":"withIosAdMob.js","names":["_configPlugins","data","require","withIosAdMob","config","withInfoPlist","modResults","setAdMobConfig","exports","getGoogleMobileAdsAppId","ios","googleMobileAdsAppId","setGoogleMobileAdsAppId","GADApplicationIdentifier","infoPlist","appId"],"sources":["../../../../src/plugins/unversioned/expo-ads-admob/withIosAdMob.ts"],"sourcesContent":["import { ConfigPlugin, InfoPlist, withInfoPlist } from '@expo/config-plugins';\nimport { ExpoConfig } from '@expo/config-types';\n\nexport const withIosAdMob: ConfigPlugin = (config) => {\n return withInfoPlist(config, (config) => {\n config.modResults = setAdMobConfig(config, config.modResults);\n return config;\n });\n};\n\n// NOTE(brentvatne): if the developer has installed the google ads sdk and does\n// not provide an app id their app will crash. Standalone apps get around this by\n// providing some default value, we will instead here assume that the user can\n// do the right thing if they have installed the package. This is a slight discrepancy\n// that arises in ejecting because it's possible for the package to be installed and\n// not crashing in the managed workflow, then you eject and the app crashes because\n// you don't have an id to fall back to.\nexport function getGoogleMobileAdsAppId(config: Pick<ExpoConfig, 'ios'>) {\n return config.ios?.config?.googleMobileAdsAppId ?? null;\n}\n\nexport function setGoogleMobileAdsAppId(\n config: Pick<ExpoConfig, 'ios'>,\n { GADApplicationIdentifier, ...infoPlist }: InfoPlist\n): InfoPlist {\n const appId = getGoogleMobileAdsAppId(config);\n\n if (appId === null) {\n return infoPlist;\n }\n\n return {\n ...infoPlist,\n GADApplicationIdentifier: appId,\n };\n}\n\nfunction setAdMobConfig(config: Pick<ExpoConfig, 'ios'>, infoPlist: InfoPlist): InfoPlist {\n infoPlist = setGoogleMobileAdsAppId(config, infoPlist);\n return infoPlist;\n}\n"],"mappings":";;;;;;;;AAAA,SAAAA,eAAA;EAAA,MAAAC,IAAA,GAAAC,OAAA;EAAAF,cAAA,YAAAA,CAAA;IAAA,OAAAC,IAAA;EAAA;EAAA,OAAAA,IAAA;AAAA;AAGO,MAAME,YAA0B,GAAIC,MAAM,IAAK;EACpD,OAAO,IAAAC,8BAAa,EAACD,MAAM,EAAGA,MAAM,IAAK;IACvCA,MAAM,CAACE,UAAU,GAAGC,cAAc,CAACH,MAAM,EAAEA,MAAM,CAACE,UAAU,CAAC;IAC7D,OAAOF,MAAM;EACf,CAAC,CAAC;AACJ,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AAAAI,OAAA,CAAAL,YAAA,GAAAA,YAAA;AACO,SAASM,uBAAuBA,CAACL,MAA+B,EAAE;EACvE,OAAOA,MAAM,CAACM,GAAG,EAAEN,MAAM,EAAEO,oBAAoB,IAAI,IAAI;AACzD;AAEO,SAASC,uBAAuBA,CACrCR,MAA+B,EAC/B;EAAES,wBAAwB;EAAE,GAAGC;AAAqB,CAAC,EAC1C;EACX,MAAMC,KAAK,GAAGN,uBAAuB,CAACL,MAAM,CAAC;EAE7C,IAAIW,KAAK,KAAK,IAAI,EAAE;IAClB,OAAOD,SAAS;EAClB;EAEA,OAAO;IACL,GAAGA,SAAS;IACZD,wBAAwB,EAAEE;EAC5B,CAAC;AACH;AAEA,SAASR,cAAcA,CAACH,MAA+B,EAAEU,SAAoB,EAAa;EACxFA,SAAS,GAAGF,uBAAuB,CAACR,MAAM,EAAEU,SAAS,CAAC;EACtD,OAAOA,SAAS;AAClB","ignoreList":[]}
@@ -0,0 +1,3 @@
import { ConfigPlugin } from '@expo/config-plugins';
declare const _default: ConfigPlugin;
export default _default;
@@ -0,0 +1,33 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
function _configPlugins() {
const data = require("@expo/config-plugins");
_configPlugins = function () {
return data;
};
return data;
}
function _createLegacyPlugin() {
const data = require("./createLegacyPlugin");
_createLegacyPlugin = function () {
return data;
};
return data;
}
const withAppleSignInWarning = config => {
return (0, _configPlugins().withEntitlementsPlist)(config, config => {
if (config.ios?.usesAppleSignIn) {
_configPlugins().WarningAggregator.addWarningIOS('ios.usesAppleSignIn', 'Install expo-apple-authentication to enable this feature', 'https://docs.expo.dev/versions/latest/sdk/apple-authentication/#eas-build');
}
return config;
});
};
var _default = exports.default = (0, _createLegacyPlugin().createLegacyPlugin)({
packageName: 'expo-apple-authentication',
fallback: withAppleSignInWarning
});
//# sourceMappingURL=expo-apple-authentication.js.map
@@ -0,0 +1 @@
{"version":3,"file":"expo-apple-authentication.js","names":["_configPlugins","data","require","_createLegacyPlugin","withAppleSignInWarning","config","withEntitlementsPlist","ios","usesAppleSignIn","WarningAggregator","addWarningIOS","_default","exports","default","createLegacyPlugin","packageName","fallback"],"sources":["../../../src/plugins/unversioned/expo-apple-authentication.ts"],"sourcesContent":["import { ConfigPlugin, WarningAggregator, withEntitlementsPlist } from '@expo/config-plugins';\n\nimport { createLegacyPlugin } from './createLegacyPlugin';\n\nconst withAppleSignInWarning: ConfigPlugin = (config) => {\n return withEntitlementsPlist(config, (config) => {\n if (config.ios?.usesAppleSignIn) {\n WarningAggregator.addWarningIOS(\n 'ios.usesAppleSignIn',\n 'Install expo-apple-authentication to enable this feature',\n 'https://docs.expo.dev/versions/latest/sdk/apple-authentication/#eas-build'\n );\n }\n\n return config;\n });\n};\n\nexport default createLegacyPlugin({\n packageName: 'expo-apple-authentication',\n fallback: withAppleSignInWarning,\n});\n"],"mappings":";;;;;;AAAA,SAAAA,eAAA;EAAA,MAAAC,IAAA,GAAAC,OAAA;EAAAF,cAAA,YAAAA,CAAA;IAAA,OAAAC,IAAA;EAAA;EAAA,OAAAA,IAAA;AAAA;AAEA,SAAAE,oBAAA;EAAA,MAAAF,IAAA,GAAAC,OAAA;EAAAC,mBAAA,YAAAA,CAAA;IAAA,OAAAF,IAAA;EAAA;EAAA,OAAAA,IAAA;AAAA;AAEA,MAAMG,sBAAoC,GAAIC,MAAM,IAAK;EACvD,OAAO,IAAAC,sCAAqB,EAACD,MAAM,EAAGA,MAAM,IAAK;IAC/C,IAAIA,MAAM,CAACE,GAAG,EAAEC,eAAe,EAAE;MAC/BC,kCAAiB,CAACC,aAAa,CAC7B,qBAAqB,EACrB,0DAA0D,EAC1D,2EACF,CAAC;IACH;IAEA,OAAOL,MAAM;EACf,CAAC,CAAC;AACJ,CAAC;AAAC,IAAAM,QAAA,GAAAC,OAAA,CAAAC,OAAA,GAEa,IAAAC,wCAAkB,EAAC;EAChCC,WAAW,EAAE,2BAA2B;EACxCC,QAAQ,EAAEZ;AACZ,CAAC,CAAC","ignoreList":[]}
@@ -0,0 +1,3 @@
import { ConfigPlugin } from '@expo/config-plugins';
declare const _default: ConfigPlugin;
export default _default;
@@ -0,0 +1,40 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
function _configPlugins() {
const data = require("@expo/config-plugins");
_configPlugins = function () {
return data;
};
return data;
}
function _createLegacyPlugin() {
const data = require("./createLegacyPlugin");
_createLegacyPlugin = function () {
return data;
};
return data;
}
const withAccessesContactNotes = config => {
return (0, _configPlugins().withEntitlementsPlist)(config, config => {
config.modResults = setAccessesContactNotes(config, config.modResults);
return config;
});
};
function setAccessesContactNotes(config, entitlementsPlist) {
if (config.ios?.accessesContactNotes) {
return {
...entitlementsPlist,
'com.apple.developer.contacts.notes': true
};
}
return entitlementsPlist;
}
var _default = exports.default = (0, _createLegacyPlugin().createLegacyPlugin)({
packageName: 'expo-contacts',
fallback: withAccessesContactNotes
});
//# sourceMappingURL=expo-contacts.js.map
@@ -0,0 +1 @@
{"version":3,"file":"expo-contacts.js","names":["_configPlugins","data","require","_createLegacyPlugin","withAccessesContactNotes","config","withEntitlementsPlist","modResults","setAccessesContactNotes","entitlementsPlist","ios","accessesContactNotes","_default","exports","default","createLegacyPlugin","packageName","fallback"],"sources":["../../../src/plugins/unversioned/expo-contacts.ts"],"sourcesContent":["import { ConfigPlugin, withEntitlementsPlist } from '@expo/config-plugins';\nimport { ExpoConfig } from '@expo/config-types';\nimport { JSONObject } from '@expo/json-file';\n\nimport { createLegacyPlugin } from './createLegacyPlugin';\n\nconst withAccessesContactNotes: ConfigPlugin = (config) => {\n return withEntitlementsPlist(config, (config) => {\n config.modResults = setAccessesContactNotes(config, config.modResults);\n return config;\n });\n};\n\nfunction setAccessesContactNotes(config: ExpoConfig, entitlementsPlist: JSONObject): JSONObject {\n if (config.ios?.accessesContactNotes) {\n return {\n ...entitlementsPlist,\n 'com.apple.developer.contacts.notes': true,\n };\n }\n\n return entitlementsPlist;\n}\n\nexport default createLegacyPlugin({\n packageName: 'expo-contacts',\n fallback: withAccessesContactNotes,\n});\n"],"mappings":";;;;;;AAAA,SAAAA,eAAA;EAAA,MAAAC,IAAA,GAAAC,OAAA;EAAAF,cAAA,YAAAA,CAAA;IAAA,OAAAC,IAAA;EAAA;EAAA,OAAAA,IAAA;AAAA;AAIA,SAAAE,oBAAA;EAAA,MAAAF,IAAA,GAAAC,OAAA;EAAAC,mBAAA,YAAAA,CAAA;IAAA,OAAAF,IAAA;EAAA;EAAA,OAAAA,IAAA;AAAA;AAEA,MAAMG,wBAAsC,GAAIC,MAAM,IAAK;EACzD,OAAO,IAAAC,sCAAqB,EAACD,MAAM,EAAGA,MAAM,IAAK;IAC/CA,MAAM,CAACE,UAAU,GAAGC,uBAAuB,CAACH,MAAM,EAAEA,MAAM,CAACE,UAAU,CAAC;IACtE,OAAOF,MAAM;EACf,CAAC,CAAC;AACJ,CAAC;AAED,SAASG,uBAAuBA,CAACH,MAAkB,EAAEI,iBAA6B,EAAc;EAC9F,IAAIJ,MAAM,CAACK,GAAG,EAAEC,oBAAoB,EAAE;IACpC,OAAO;MACL,GAAGF,iBAAiB;MACpB,oCAAoC,EAAE;IACxC,CAAC;EACH;EAEA,OAAOA,iBAAiB;AAC1B;AAAC,IAAAG,QAAA,GAAAC,OAAA,CAAAC,OAAA,GAEc,IAAAC,wCAAkB,EAAC;EAChCC,WAAW,EAAE,eAAe;EAC5BC,QAAQ,EAAEb;AACZ,CAAC,CAAC","ignoreList":[]}
@@ -0,0 +1,2 @@
declare const _default: import("@expo/config-plugins").ConfigPlugin;
export default _default;
@@ -0,0 +1,32 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
function _configPlugins() {
const data = require("@expo/config-plugins");
_configPlugins = function () {
return data;
};
return data;
}
function _createLegacyPlugin() {
const data = require("./createLegacyPlugin");
_createLegacyPlugin = function () {
return data;
};
return data;
}
var _default = exports.default = (0, _createLegacyPlugin().createLegacyPlugin)({
packageName: 'expo-document-picker',
fallback(config) {
if (config.ios?.usesIcloudStorage) {
_configPlugins().WarningAggregator.addWarningIOS('ios.usesIcloudStorage', 'Install expo-document-picker to enable the ios.usesIcloudStorage feature'
// TODO: add a link to a docs page with more information on how to do this
);
}
return config;
}
});
//# sourceMappingURL=expo-document-picker.js.map
@@ -0,0 +1 @@
{"version":3,"file":"expo-document-picker.js","names":["_configPlugins","data","require","_createLegacyPlugin","_default","exports","default","createLegacyPlugin","packageName","fallback","config","ios","usesIcloudStorage","WarningAggregator","addWarningIOS"],"sources":["../../../src/plugins/unversioned/expo-document-picker.ts"],"sourcesContent":["import { WarningAggregator } from '@expo/config-plugins';\n\nimport { createLegacyPlugin } from './createLegacyPlugin';\n\nexport default createLegacyPlugin({\n packageName: 'expo-document-picker',\n fallback(config) {\n if (config.ios?.usesIcloudStorage) {\n WarningAggregator.addWarningIOS(\n 'ios.usesIcloudStorage',\n 'Install expo-document-picker to enable the ios.usesIcloudStorage feature'\n // TODO: add a link to a docs page with more information on how to do this\n );\n }\n return config;\n },\n});\n"],"mappings":";;;;;;AAAA,SAAAA,eAAA;EAAA,MAAAC,IAAA,GAAAC,OAAA;EAAAF,cAAA,YAAAA,CAAA;IAAA,OAAAC,IAAA;EAAA;EAAA,OAAAA,IAAA;AAAA;AAEA,SAAAE,oBAAA;EAAA,MAAAF,IAAA,GAAAC,OAAA;EAAAC,mBAAA,YAAAA,CAAA;IAAA,OAAAF,IAAA;EAAA;EAAA,OAAAA,IAAA;AAAA;AAA0D,IAAAG,QAAA,GAAAC,OAAA,CAAAC,OAAA,GAE3C,IAAAC,wCAAkB,EAAC;EAChCC,WAAW,EAAE,sBAAsB;EACnCC,QAAQA,CAACC,MAAM,EAAE;IACf,IAAIA,MAAM,CAACC,GAAG,EAAEC,iBAAiB,EAAE;MACjCC,kCAAiB,CAACC,aAAa,CAC7B,uBAAuB,EACvB;MACA;MACF,CAAC;IACH;IACA,OAAOJ,MAAM;EACf;AACF,CAAC,CAAC","ignoreList":[]}
@@ -0,0 +1,2 @@
declare const _default: import("@expo/config-plugins").ConfigPlugin;
export default _default;
@@ -0,0 +1,27 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
function _withAndroidNavigationBar() {
const data = require("./withAndroidNavigationBar");
_withAndroidNavigationBar = function () {
return data;
};
return data;
}
function _createLegacyPlugin() {
const data = require("../createLegacyPlugin");
_createLegacyPlugin = function () {
return data;
};
return data;
}
var _default = exports.default = (0, _createLegacyPlugin().createLegacyPlugin)({
packageName: 'expo-navigation-bar',
fallback: [
// Android
_withAndroidNavigationBar().withNavigationBar]
});
//# sourceMappingURL=expo-navigation-bar.js.map
@@ -0,0 +1 @@
{"version":3,"file":"expo-navigation-bar.js","names":["_withAndroidNavigationBar","data","require","_createLegacyPlugin","_default","exports","default","createLegacyPlugin","packageName","fallback","withNavigationBar"],"sources":["../../../../src/plugins/unversioned/expo-navigation-bar/expo-navigation-bar.ts"],"sourcesContent":["import { withNavigationBar } from './withAndroidNavigationBar';\nimport { createLegacyPlugin } from '../createLegacyPlugin';\n\nexport default createLegacyPlugin({\n packageName: 'expo-navigation-bar',\n fallback: [\n // Android\n withNavigationBar,\n ],\n});\n"],"mappings":";;;;;;AAAA,SAAAA,0BAAA;EAAA,MAAAC,IAAA,GAAAC,OAAA;EAAAF,yBAAA,YAAAA,CAAA;IAAA,OAAAC,IAAA;EAAA;EAAA,OAAAA,IAAA;AAAA;AACA,SAAAE,oBAAA;EAAA,MAAAF,IAAA,GAAAC,OAAA;EAAAC,mBAAA,YAAAA,CAAA;IAAA,OAAAF,IAAA;EAAA;EAAA,OAAAA,IAAA;AAAA;AAA2D,IAAAG,QAAA,GAAAC,OAAA,CAAAC,OAAA,GAE5C,IAAAC,wCAAkB,EAAC;EAChCC,WAAW,EAAE,qBAAqB;EAClCC,QAAQ,EAAE;EACR;EACAC,6CAAiB;AAErB,CAAC,CAAC","ignoreList":[]}
@@ -0,0 +1,8 @@
import { AndroidConfig, ConfigPlugin } from '@expo/config-plugins';
import { ExpoConfig } from '@expo/config-types';
export declare const withNavigationBar: ConfigPlugin;
export declare function setNavigationBarColors(config: Pick<ExpoConfig, 'androidNavigationBar'>, colors: AndroidConfig.Resources.ResourceXML): AndroidConfig.Resources.ResourceXML;
export declare function setNavigationBarStyles(config: Pick<ExpoConfig, 'androidNavigationBar'>, styles: AndroidConfig.Resources.ResourceXML): AndroidConfig.Resources.ResourceXML;
export declare function getNavigationBarImmersiveMode(config: Pick<ExpoConfig, 'androidNavigationBar'>): "leanback" | "immersive" | "sticky-immersive" | null;
export declare function getNavigationBarColor(config: Pick<ExpoConfig, 'androidNavigationBar'>): string | null;
export declare function getNavigationBarStyle(config: Pick<ExpoConfig, 'androidNavigationBar'>): "light-content" | "dark-content";
@@ -0,0 +1,77 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.getNavigationBarColor = getNavigationBarColor;
exports.getNavigationBarImmersiveMode = getNavigationBarImmersiveMode;
exports.getNavigationBarStyle = getNavigationBarStyle;
exports.setNavigationBarColors = setNavigationBarColors;
exports.setNavigationBarStyles = setNavigationBarStyles;
exports.withNavigationBar = void 0;
function _configPlugins() {
const data = require("@expo/config-plugins");
_configPlugins = function () {
return data;
};
return data;
}
const NAVIGATION_BAR_COLOR = 'navigationBarColor';
const withNavigationBar = config => {
const immersiveMode = getNavigationBarImmersiveMode(config);
if (immersiveMode) {
// Immersive mode needs to be set programmatically
_configPlugins().WarningAggregator.addWarningAndroid('androidNavigationBar.visible', 'Property is deprecated in Android 11 (API 30) and will be removed from Expo SDK.', 'https://expo.fyi/android-navigation-bar-visible-deprecated');
}
config = withNavigationBarColors(config);
config = withNavigationBarStyles(config);
return config;
};
exports.withNavigationBar = withNavigationBar;
const withNavigationBarColors = config => {
return (0, _configPlugins().withAndroidColors)(config, config => {
config.modResults = setNavigationBarColors(config, config.modResults);
return config;
});
};
const withNavigationBarStyles = config => {
return (0, _configPlugins().withAndroidStyles)(config, config => {
config.modResults = setNavigationBarStyles(config, config.modResults);
return config;
});
};
function setNavigationBarColors(config, colors) {
const hexString = getNavigationBarColor(config);
if (hexString) {
colors = _configPlugins().AndroidConfig.Colors.setColorItem(_configPlugins().AndroidConfig.Resources.buildResourceItem({
name: NAVIGATION_BAR_COLOR,
value: hexString
}), colors);
}
return colors;
}
function setNavigationBarStyles(config, styles) {
styles = _configPlugins().AndroidConfig.Styles.assignStylesValue(styles, {
add: getNavigationBarStyle(config) === 'dark-content',
parent: _configPlugins().AndroidConfig.Styles.getAppThemeGroup(),
name: 'android:windowLightNavigationBar',
value: 'true'
});
styles = _configPlugins().AndroidConfig.Styles.assignStylesValue(styles, {
add: !!getNavigationBarColor(config),
parent: _configPlugins().AndroidConfig.Styles.getAppThemeGroup(),
name: `android:${NAVIGATION_BAR_COLOR}`,
value: `@color/${NAVIGATION_BAR_COLOR}`
});
return styles;
}
function getNavigationBarImmersiveMode(config) {
return config.androidNavigationBar?.visible || null;
}
function getNavigationBarColor(config) {
return config.androidNavigationBar?.backgroundColor || null;
}
function getNavigationBarStyle(config) {
return config.androidNavigationBar?.barStyle || 'light-content';
}
//# sourceMappingURL=withAndroidNavigationBar.js.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1,2 @@
declare const _default: import("@expo/config-plugins").ConfigPlugin;
export default _default;
@@ -0,0 +1,30 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
function _withAndroidNotifications() {
const data = require("./withAndroidNotifications");
_withAndroidNotifications = function () {
return data;
};
return data;
}
function _createLegacyPlugin() {
const data = require("../createLegacyPlugin");
_createLegacyPlugin = function () {
return data;
};
return data;
}
var _default = exports.default = (0, _createLegacyPlugin().createLegacyPlugin)({
packageName: 'expo-notifications',
fallback: [
// Android
_withAndroidNotifications().withNotificationManifest, _withAndroidNotifications().withNotificationIconColor, _withAndroidNotifications().withNotificationIcons
// iOS
// Automatic setting of APNS entitlement is no longer needed
]
});
//# sourceMappingURL=expo-notifications.js.map
@@ -0,0 +1 @@
{"version":3,"file":"expo-notifications.js","names":["_withAndroidNotifications","data","require","_createLegacyPlugin","_default","exports","default","createLegacyPlugin","packageName","fallback","withNotificationManifest","withNotificationIconColor","withNotificationIcons"],"sources":["../../../../src/plugins/unversioned/expo-notifications/expo-notifications.ts"],"sourcesContent":["import {\n withNotificationIconColor,\n withNotificationIcons,\n withNotificationManifest,\n} from './withAndroidNotifications';\nimport { createLegacyPlugin } from '../createLegacyPlugin';\n\nexport default createLegacyPlugin({\n packageName: 'expo-notifications',\n fallback: [\n // Android\n withNotificationManifest,\n withNotificationIconColor,\n withNotificationIcons,\n // iOS\n // Automatic setting of APNS entitlement is no longer needed\n ],\n});\n"],"mappings":";;;;;;AAAA,SAAAA,0BAAA;EAAA,MAAAC,IAAA,GAAAC,OAAA;EAAAF,yBAAA,YAAAA,CAAA;IAAA,OAAAC,IAAA;EAAA;EAAA,OAAAA,IAAA;AAAA;AAKA,SAAAE,oBAAA;EAAA,MAAAF,IAAA,GAAAC,OAAA;EAAAC,mBAAA,YAAAA,CAAA;IAAA,OAAAF,IAAA;EAAA;EAAA,OAAAA,IAAA;AAAA;AAA2D,IAAAG,QAAA,GAAAC,OAAA,CAAAC,OAAA,GAE5C,IAAAC,wCAAkB,EAAC;EAChCC,WAAW,EAAE,oBAAoB;EACjCC,QAAQ,EAAE;EACR;EACAC,oDAAwB,EACxBC,qDAAyB,EACzBC;EACA;EACA;EAAA;AAEJ,CAAC,CAAC","ignoreList":[]}
@@ -0,0 +1,22 @@
import { AndroidConfig, ConfigPlugin } from '@expo/config-plugins';
import { ExpoConfig } from '@expo/config-types';
type AndroidManifest = AndroidConfig.Manifest.AndroidManifest;
export declare const META_DATA_NOTIFICATION_ICON = "expo.modules.notifications.default_notification_icon";
export declare const META_DATA_NOTIFICATION_ICON_COLOR = "expo.modules.notifications.default_notification_color";
export declare const NOTIFICATION_ICON = "notification_icon";
export declare const NOTIFICATION_ICON_RESOURCE = "@drawable/notification_icon";
export declare const NOTIFICATION_ICON_COLOR = "notification_icon_color";
export declare const NOTIFICATION_ICON_COLOR_RESOURCE = "@color/notification_icon_color";
export declare const withNotificationIcons: ConfigPlugin;
export declare const withNotificationIconColor: ConfigPlugin;
export declare const withNotificationManifest: ConfigPlugin;
export declare function getNotificationIcon(config: ExpoConfig): string | null;
export declare function getNotificationColor(config: ExpoConfig): string | null;
/**
* Applies configuration for expo-notifications, including
* the notification icon and notification color.
*/
export declare function setNotificationIconAsync(config: ExpoConfig, projectRoot: string): Promise<void>;
export declare function setNotificationConfig(config: ExpoConfig, manifest: AndroidManifest): AndroidConfig.Manifest.AndroidManifest;
export declare function setNotificationIconColor(config: ExpoConfig, colors: AndroidConfig.Resources.ResourceXML): AndroidConfig.Resources.ResourceXML;
export {};
@@ -0,0 +1,168 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.NOTIFICATION_ICON_RESOURCE = exports.NOTIFICATION_ICON_COLOR_RESOURCE = exports.NOTIFICATION_ICON_COLOR = exports.NOTIFICATION_ICON = exports.META_DATA_NOTIFICATION_ICON_COLOR = exports.META_DATA_NOTIFICATION_ICON = void 0;
exports.getNotificationColor = getNotificationColor;
exports.getNotificationIcon = getNotificationIcon;
exports.setNotificationConfig = setNotificationConfig;
exports.setNotificationIconAsync = setNotificationIconAsync;
exports.setNotificationIconColor = setNotificationIconColor;
exports.withNotificationManifest = exports.withNotificationIcons = exports.withNotificationIconColor = void 0;
function _configPlugins() {
const data = require("@expo/config-plugins");
_configPlugins = function () {
return data;
};
return data;
}
function _imageUtils() {
const data = require("@expo/image-utils");
_imageUtils = function () {
return data;
};
return data;
}
function _fs() {
const data = _interopRequireDefault(require("fs"));
_fs = function () {
return data;
};
return data;
}
function _path() {
const data = _interopRequireDefault(require("path"));
_path = function () {
return data;
};
return data;
}
function _withAndroidIcons() {
const data = require("../../icons/withAndroidIcons");
_withAndroidIcons = function () {
return data;
};
return data;
}
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
const {
Colors
} = _configPlugins().AndroidConfig;
const {
addMetaDataItemToMainApplication,
getMainApplicationOrThrow,
removeMetaDataItemFromMainApplication
} = _configPlugins().AndroidConfig.Manifest;
const BASELINE_PIXEL_SIZE = 24;
const META_DATA_NOTIFICATION_ICON = exports.META_DATA_NOTIFICATION_ICON = 'expo.modules.notifications.default_notification_icon';
const META_DATA_NOTIFICATION_ICON_COLOR = exports.META_DATA_NOTIFICATION_ICON_COLOR = 'expo.modules.notifications.default_notification_color';
const NOTIFICATION_ICON = exports.NOTIFICATION_ICON = 'notification_icon';
const NOTIFICATION_ICON_RESOURCE = exports.NOTIFICATION_ICON_RESOURCE = `@drawable/${NOTIFICATION_ICON}`;
const NOTIFICATION_ICON_COLOR = exports.NOTIFICATION_ICON_COLOR = 'notification_icon_color';
const NOTIFICATION_ICON_COLOR_RESOURCE = exports.NOTIFICATION_ICON_COLOR_RESOURCE = `@color/${NOTIFICATION_ICON_COLOR}`;
const withNotificationIcons = config => {
return (0, _configPlugins().withDangerousMod)(config, ['android', async config => {
await setNotificationIconAsync(config, config.modRequest.projectRoot);
return config;
}]);
};
exports.withNotificationIcons = withNotificationIcons;
const withNotificationIconColor = config => {
return (0, _configPlugins().withAndroidColors)(config, config => {
config.modResults = setNotificationIconColor(config, config.modResults);
return config;
});
};
exports.withNotificationIconColor = withNotificationIconColor;
const withNotificationManifest = config => {
return (0, _configPlugins().withAndroidManifest)(config, config => {
config.modResults = setNotificationConfig(config, config.modResults);
return config;
});
};
exports.withNotificationManifest = withNotificationManifest;
function getNotificationIcon(config) {
return config.notification?.icon || null;
}
function getNotificationColor(config) {
return config.notification?.color || null;
}
/**
* Applies configuration for expo-notifications, including
* the notification icon and notification color.
*/
async function setNotificationIconAsync(config, projectRoot) {
const icon = getNotificationIcon(config);
if (icon) {
await writeNotificationIconImageFilesAsync(icon, projectRoot);
} else {
await removeNotificationIconImageFilesAsync(projectRoot);
}
}
function setNotificationConfig(config, manifest) {
const icon = getNotificationIcon(config);
const color = getNotificationColor(config);
if (config.notification) {
_configPlugins().WarningAggregator.addWarningAndroid('config.notification', 'The `notification` property in app config is deprecated. Use the `expo-notifications` config plugin instead.');
}
const mainApplication = getMainApplicationOrThrow(manifest);
if (icon) {
addMetaDataItemToMainApplication(mainApplication, META_DATA_NOTIFICATION_ICON, NOTIFICATION_ICON_RESOURCE, 'resource');
} else {
removeMetaDataItemFromMainApplication(mainApplication, META_DATA_NOTIFICATION_ICON);
}
if (color) {
addMetaDataItemToMainApplication(mainApplication, META_DATA_NOTIFICATION_ICON_COLOR, NOTIFICATION_ICON_COLOR_RESOURCE, 'resource');
} else {
removeMetaDataItemFromMainApplication(mainApplication, META_DATA_NOTIFICATION_ICON_COLOR);
}
return manifest;
}
function setNotificationIconColor(config, colors) {
return Colors.assignColorValue(colors, {
name: NOTIFICATION_ICON_COLOR,
value: getNotificationColor(config)
});
}
async function writeNotificationIconImageFilesAsync(icon, projectRoot) {
await Promise.all(Object.values(_withAndroidIcons().dpiValues).map(async ({
folderName,
scale
}) => {
const drawableFolderName = folderName.replace('mipmap', 'drawable');
const dpiFolderPath = _path().default.resolve(projectRoot, _withAndroidIcons().ANDROID_RES_PATH, drawableFolderName);
await _fs().default.promises.mkdir(dpiFolderPath, {
recursive: true
});
const iconSizePx = BASELINE_PIXEL_SIZE * scale;
try {
const resizedIcon = (await (0, _imageUtils().generateImageAsync)({
projectRoot,
cacheType: 'android-notification'
}, {
src: icon,
width: iconSizePx,
height: iconSizePx,
resizeMode: 'cover',
backgroundColor: 'transparent'
})).source;
await _fs().default.promises.writeFile(_path().default.resolve(dpiFolderPath, NOTIFICATION_ICON + '.png'), resizedIcon);
} catch (e) {
throw new Error('Encountered an issue resizing Android notification icon: ' + e);
}
}));
}
async function removeNotificationIconImageFilesAsync(projectRoot) {
await Promise.all(Object.values(_withAndroidIcons().dpiValues).map(async ({
folderName
}) => {
const drawableFolderName = folderName.replace('mipmap', 'drawable');
const dpiFolderPath = _path().default.resolve(projectRoot, _withAndroidIcons().ANDROID_RES_PATH, drawableFolderName);
await _fs().default.promises.rm(_path().default.resolve(dpiFolderPath, NOTIFICATION_ICON + '.png'), {
force: true
});
}));
}
//# sourceMappingURL=withAndroidNotifications.js.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1,257 @@
export type IBBoolean = 'YES' | 'NO' | boolean;
export type IBItem<H extends Record<string, any>, B extends Record<string, any[]> = {
[key: string]: any;
}> = {
$: H;
} & B;
export type Rect = {
key: string;
x: number;
y: number;
width: number;
height: number;
};
export type IBRect = IBItem<Rect>;
export type IBAutoresizingMask = IBItem<{
/** @example `autoresizingMask` */
key: string;
flexibleMaxX: IBBoolean;
flexibleMaxY: IBBoolean;
}>;
/** @example `<color key="textColor" systemColor="linkColor"/>` */
export type IBColor = IBItem<{
/** @example `textColor` */
key: string;
} & (/** Custom color */ {
/** @example `0.86584504117670746` */
red: number;
/** @example `0.26445041990630447` */
green: number;
/** @example `0.3248577810203549` */
blue: number;
/** @example `1` */
alpha: number;
colorSpace: 'custom' | string;
customColorSpace: 'displayP3' | 'sRGB' | string;
}
/** Built-in color */
| {
systemColor: 'linkColor' | string;
})>;
export type IBFontDescription = IBItem<{
/** @example `fontDescription` */
key: string;
/** Font size */
pointSize: number;
/** Custom font */
name?: 'HelveticaNeue' | string;
family?: 'Helvetica Neue' | string;
/** Built-in font */
type?: 'system' | 'boldSystem' | 'UICTFontTextStyleCallout' | 'UICTFontTextStyleBody' | string;
}>;
export type ImageContentMode = 'scaleAspectFit' | 'scaleAspectFill';
export type ConstraintAttribute = 'top' | 'bottom' | 'trailing' | 'leading' | 'centerX' | 'centerY';
export type IBImageView = IBItem<{
id: string;
userLabel: string;
image: string;
clipsSubviews?: IBBoolean;
userInteractionEnabled: IBBoolean;
contentMode: IBContentMode;
horizontalHuggingPriority?: number;
verticalHuggingPriority?: number;
insetsLayoutMarginsFromSafeArea?: IBBoolean;
translatesAutoresizingMaskIntoConstraints?: IBBoolean;
}, {
rect: IBRect[];
}>;
export type IBLabel = IBItem<{
id: string;
/** The main value. */
text: string;
opaque: IBBoolean;
fixedFrame: IBBoolean;
textAlignment?: IBTextAlignment;
lineBreakMode: 'clip' | 'characterWrap' | 'wordWrap' | 'headTruncation' | 'middleTruncation' | 'tailTruncation';
baselineAdjustment?: 'none' | 'alignBaselines';
adjustsFontSizeToFit: IBBoolean;
userInteractionEnabled: IBBoolean;
contentMode: IBContentMode;
horizontalHuggingPriority: number;
verticalHuggingPriority: number;
translatesAutoresizingMaskIntoConstraints?: IBBoolean;
}, {
/** @example `<rect key="frame" x="175" y="670" width="35" height="17"/>` */
rect: IBRect[];
/** @example `<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>` */
autoresizingMask?: IBAutoresizingMask[];
/** @example `<fontDescription key="fontDescription" type="system" pointSize="19"/>` */
fontDescription?: IBFontDescription[];
/** @example `<color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>` */
color?: IBColor[];
nil?: IBItem<{
/** @example `textColor` `highlightedColor` */
key: string;
}>[];
}>;
export type IBTextAlignment = 'left' | 'center' | 'right' | 'justified' | 'natural';
export type IBContentMode = string | 'left' | 'scaleAspectFill';
export type IBConstraint = IBItem<{
firstItem: string;
firstAttribute: ConstraintAttribute;
secondItem: string;
secondAttribute: ConstraintAttribute;
constant?: number;
id: string;
}>;
export type IBViewController = IBItem<{
id: string;
placeholderIdentifier?: string;
userLabel: string;
sceneMemberID: string;
}, {
view: IBItem<{
id: string;
key: string;
userInteractionEnabled: IBBoolean;
contentMode: string | 'scaleToFill';
insetsLayoutMarginsFromSafeArea: IBBoolean;
userLabel: string;
}, {
rect: IBRect[];
autoresizingMask: IBItem<{
key: string;
flexibleMaxX: IBBoolean;
flexibleMaxY: IBBoolean;
}>[];
subviews: IBItem<object, {
imageView: IBImageView[];
label: IBLabel[];
}>[];
color: IBItem<{
key: string | 'backgroundColor';
name?: string;
systemColor?: string | 'systemBackgroundColor';
red?: string;
green?: string;
blue?: string;
alpha?: string;
colorSpace?: string;
customColorSpace?: string;
}>[];
constraints: IBItem<object, {
constraint: IBConstraint[];
}>[];
viewLayoutGuide: IBItem<{
id: string;
key: string | 'safeArea';
}>[];
}>[];
}>;
export type IBPoint = IBItem<{
key: string | 'canvasLocation';
x: number;
y: number;
}>;
export type IBScene = IBItem<{
sceneID: string;
}, {
objects: {
viewController: IBViewController[];
placeholder: IBItem<{
id: string;
placeholderIdentifier?: string;
userLabel: string;
sceneMemberID: string;
}>[];
}[];
point: IBPoint[];
}>;
export type IBResourceImage = IBItem<{
name: string;
width: number;
height: number;
}>;
export type IBResourceNamedColor = IBItem<{
name?: string;
systemColor?: string | 'systemBackgroundColor';
red?: string;
green?: string;
blue?: string;
alpha?: string;
colorSpace?: string;
customColorSpace?: string;
}>;
export type IBDevice = IBItem<{
id: string;
orientation: string | 'portrait';
appearance: string | 'light';
}>;
export type IBSplashScreenDocument = {
document: IBItem<{
type: 'com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB' | string;
version: '3.0' | string;
toolsVersion: number;
targetRuntime: 'iOS.CocoaTouch' | string;
propertyAccessControl: 'none' | string;
useAutolayout: IBBoolean;
launchScreen: IBBoolean;
useTraitCollections: IBBoolean;
useSafeAreas: IBBoolean;
colorMatched: IBBoolean;
initialViewController: string;
}, {
device: IBDevice[];
dependencies: unknown[];
scenes: {
scene: IBScene[];
}[];
resources: {
image: IBResourceImage[];
namedColor?: IBItem<{
name: string;
}, {
color: IBResourceNamedColor[];
}>[];
}[];
}>;
};
export declare function createConstraint([firstItem, firstAttribute]: [string, ConstraintAttribute], [secondItem, secondAttribute]: [string, ConstraintAttribute], constant?: number): IBConstraint;
export declare function createConstraintId(...attributes: string[]): string;
export declare function removeImageFromSplashScreen(xml: IBSplashScreenDocument, { imageName }: {
imageName: string;
}): IBSplashScreenDocument;
export declare function applyImageToSplashScreenXML(xml: IBSplashScreenDocument, { imageName, contentMode, backgroundColor, enableFullScreenImage, imageWidth, }: {
imageName: string;
contentMode: ImageContentMode;
backgroundColor: string;
enableFullScreenImage: boolean;
imageWidth?: number;
}): IBSplashScreenDocument;
/**
* IB does not allow two items to have the same ID.
* This method will add an item by first removing any existing item with the same `$.id`.
*/
export declare function ensureUniquePush<TItem extends {
$: {
id: string;
};
}>(array: TItem[], item: TItem): TItem[];
export declare function removeExisting<TItem extends {
$: {
id: string;
};
}>(array: TItem[], item: TItem | string): TItem[];
export declare function toString(xml: any): string;
/** Parse string contents into an object. */
export declare function toObjectAsync(contents: string): Promise<any>;
export declare const parseColor: (value: string) => Color;
type Color = {
hex: string;
rgb: {
red: string;
green: string;
blue: string;
};
};
export {};
@@ -0,0 +1,232 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.applyImageToSplashScreenXML = applyImageToSplashScreenXML;
exports.createConstraint = createConstraint;
exports.createConstraintId = createConstraintId;
exports.ensureUniquePush = ensureUniquePush;
exports.parseColor = void 0;
exports.removeExisting = removeExisting;
exports.removeImageFromSplashScreen = removeImageFromSplashScreen;
exports.toObjectAsync = toObjectAsync;
exports.toString = toString;
function _crypto() {
const data = _interopRequireDefault(require("crypto"));
_crypto = function () {
return data;
};
return data;
}
function _xml2js() {
const data = require("xml2js");
_xml2js = function () {
return data;
};
return data;
}
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
const debug = require('debug')('expo:prebuild-config:expo-splash-screen:ios:InterfaceBuilder');
/** @example `<color key="textColor" systemColor="linkColor"/>` */
function createConstraint([firstItem, firstAttribute], [secondItem, secondAttribute], constant) {
return {
$: {
firstItem,
firstAttribute,
secondItem,
secondAttribute,
constant,
// Prevent updating between runs
id: createConstraintId(firstItem, firstAttribute, secondItem, secondAttribute)
}
};
}
function createConstraintId(...attributes) {
return _crypto().default.createHash('sha1').update(attributes.join('-')).digest('hex');
}
const IMAGE_ID = 'EXPO-SplashScreen';
const CONTAINER_ID = 'EXPO-ContainerView';
function removeImageFromSplashScreen(xml, {
imageName
}) {
const mainView = xml.document.scenes[0].scene[0].objects[0].viewController[0].view[0];
debug(`Remove all splash screen image elements`);
removeExisting(mainView.subviews[0].imageView, IMAGE_ID);
// Remove Constraints
getAbsoluteConstraints(IMAGE_ID, CONTAINER_ID).forEach(constraint => {
// <constraint firstItem="EXPO-SplashScreen" firstAttribute="top" secondItem="EXPO-ContainerView" secondAttribute="top" id="2VS-Uz-0LU"/>
const constrainsArray = mainView.constraints[0].constraint;
removeExisting(constrainsArray, constraint);
});
// Remove resource
xml.document.resources[0].image = xml.document.resources[0].image ?? [];
const imageSection = xml.document.resources[0].image;
const existingImageIndex = imageSection.findIndex(image => image.$.name === imageName);
if (existingImageIndex && existingImageIndex > -1) {
imageSection?.splice(existingImageIndex, 1);
}
return xml;
}
function getAbsoluteConstraints(childId, parentId, legacy = false) {
if (legacy) {
return [createConstraint([childId, 'top'], [parentId, 'top']), createConstraint([childId, 'leading'], [parentId, 'leading']), createConstraint([childId, 'trailing'], [parentId, 'trailing']), createConstraint([childId, 'bottom'], [parentId, 'bottom'])];
}
return [createConstraint([childId, 'centerX'], [parentId, 'centerX']), createConstraint([childId, 'centerY'], [parentId, 'centerY'])];
}
function applyImageToSplashScreenXML(xml, {
imageName,
contentMode,
backgroundColor,
enableFullScreenImage,
imageWidth = 100
}) {
const mainView = xml.document.scenes[0].scene[0].objects[0].viewController[0].view[0];
const width = enableFullScreenImage ? 414 : imageWidth;
const height = enableFullScreenImage ? 736 : imageWidth;
const x = enableFullScreenImage ? 0 : (mainView.rect[0].$.width - width) / 2;
const y = enableFullScreenImage ? 0 : (mainView.rect[0].$.height - height) / 2;
const imageView = {
$: {
id: IMAGE_ID,
userLabel: imageName,
image: imageName,
contentMode,
clipsSubviews: true,
userInteractionEnabled: false,
translatesAutoresizingMaskIntoConstraints: false
},
rect: [{
$: {
key: 'frame',
x,
y,
width,
height
}
}]
};
// Add ImageView
ensureUniquePush(mainView.subviews[0].imageView, imageView);
mainView.constraints[0].constraint = [];
// Add Constraints
getAbsoluteConstraints(IMAGE_ID, CONTAINER_ID, enableFullScreenImage).forEach(constraint => {
const constrainsArray = mainView.constraints[0].constraint;
ensureUniquePush(constrainsArray, constraint);
});
// Clear existing images
xml.document.resources[0].image = [];
// Add resource
const imageSection = xml.document.resources[0].image;
imageSection.push({
$: {
name: imageName,
width,
height
}
});
// Clear existing color
mainView.color = [];
// Add background color
const colorSection = mainView.color;
colorSection.push({
$: {
key: 'backgroundColor',
name: 'SplashScreenBackground'
}
});
// Clear existing named colors
xml.document.resources[0].namedColor = [];
const namedColorSection = xml.document.resources[0].namedColor;
// Add background named color reference
const color = parseColor(backgroundColor);
namedColorSection.push({
$: {
name: 'SplashScreenBackground'
},
color: [{
$: {
alpha: '1.000',
blue: color.rgb.blue,
green: color.rgb.green,
red: color.rgb.red,
customColorSpace: 'sRGB',
colorSpace: 'custom'
}
}]
});
return xml;
}
/**
* IB does not allow two items to have the same ID.
* This method will add an item by first removing any existing item with the same `$.id`.
*/
function ensureUniquePush(array, item) {
if (!array) return array;
removeExisting(array, item);
array.push(item);
return array;
}
function removeExisting(array, item) {
const id = typeof item === 'string' ? item : item.$?.id;
const existingItem = array?.findIndex(existingItem => existingItem.$.id === id);
if (existingItem > -1) {
debug(`Removing existing IB item with id ${id}, from: %O`, array);
array.splice(existingItem, 1);
}
return array;
}
// Attempt to copy Xcode formatting.
function toString(xml) {
const builder = new (_xml2js().Builder)({
// @ts-expect-error: untyped
preserveChildrenOrder: true,
xmldec: {
version: '1.0',
encoding: 'UTF-8'
},
renderOpts: {
pretty: true,
indent: ' '
}
});
return builder.buildObject(xml);
}
/** Parse string contents into an object. */
function toObjectAsync(contents) {
return new (_xml2js().Parser)().parseStringPromise(contents);
}
// Function taken from react-native-bootsplash
const parseColor = value => {
const color = value.toUpperCase().replace(/[^0-9A-F]/g, '');
if (color.length !== 3 && color.length !== 6) {
console.error(`"${value}" value is not a valid hexadecimal color.`);
process.exit(1);
}
const hex = color.length === 3 ? '#' + color[0] + color[0] + color[1] + color[1] + color[2] + color[2] : '#' + color;
const rgb = {
red: (parseInt('' + hex[1] + hex[2], 16) / 255).toPrecision(15),
green: (parseInt('' + hex[3] + hex[4], 16) / 255).toPrecision(15),
blue: (parseInt('' + hex[5] + hex[6], 16) / 255).toPrecision(15)
};
return {
hex,
rgb
};
};
exports.parseColor = parseColor;
//# sourceMappingURL=InterfaceBuilder.js.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1,2 @@
declare const _default: import("@expo/config-plugins").ConfigPlugin;
export default _default;
@@ -0,0 +1,32 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
function _withAndroidSplashScreen() {
const data = require("./withAndroidSplashScreen");
_withAndroidSplashScreen = function () {
return data;
};
return data;
}
function _withIosSplashScreen() {
const data = require("./withIosSplashScreen");
_withIosSplashScreen = function () {
return data;
};
return data;
}
function _createLegacyPlugin() {
const data = require("../createLegacyPlugin");
_createLegacyPlugin = function () {
return data;
};
return data;
}
var _default = exports.default = (0, _createLegacyPlugin().createLegacyPlugin)({
packageName: 'expo-splash-screen',
fallback: [_withAndroidSplashScreen().withAndroidSplashScreen, _withIosSplashScreen().withIosSplashScreen]
});
//# sourceMappingURL=expo-splash-screen.js.map
@@ -0,0 +1 @@
{"version":3,"file":"expo-splash-screen.js","names":["_withAndroidSplashScreen","data","require","_withIosSplashScreen","_createLegacyPlugin","_default","exports","default","createLegacyPlugin","packageName","fallback","withAndroidSplashScreen","withIosSplashScreen"],"sources":["../../../../src/plugins/unversioned/expo-splash-screen/expo-splash-screen.ts"],"sourcesContent":["import { withAndroidSplashScreen } from './withAndroidSplashScreen';\nimport { withIosSplashScreen } from './withIosSplashScreen';\nimport { createLegacyPlugin } from '../createLegacyPlugin';\n\nexport default createLegacyPlugin({\n packageName: 'expo-splash-screen',\n fallback: [withAndroidSplashScreen, withIosSplashScreen],\n});\n"],"mappings":";;;;;;AAAA,SAAAA,yBAAA;EAAA,MAAAC,IAAA,GAAAC,OAAA;EAAAF,wBAAA,YAAAA,CAAA;IAAA,OAAAC,IAAA;EAAA;EAAA,OAAAA,IAAA;AAAA;AACA,SAAAE,qBAAA;EAAA,MAAAF,IAAA,GAAAC,OAAA;EAAAC,oBAAA,YAAAA,CAAA;IAAA,OAAAF,IAAA;EAAA;EAAA,OAAAA,IAAA;AAAA;AACA,SAAAG,oBAAA;EAAA,MAAAH,IAAA,GAAAC,OAAA;EAAAE,mBAAA,YAAAA,CAAA;IAAA,OAAAH,IAAA;EAAA;EAAA,OAAAA,IAAA;AAAA;AAA2D,IAAAI,QAAA,GAAAC,OAAA,CAAAC,OAAA,GAE5C,IAAAC,wCAAkB,EAAC;EAChCC,WAAW,EAAE,oBAAoB;EACjCC,QAAQ,EAAE,CAACC,kDAAuB,EAAEC,0CAAmB;AACzD,CAAC,CAAC","ignoreList":[]}
@@ -0,0 +1,30 @@
import { ExpoConfig } from '@expo/config-types';
export type SplashScreenConfig = {
xxxhdpi?: string;
xxhdpi?: string;
xhdpi?: string;
hdpi?: string;
mdpi?: string;
image?: string;
backgroundColor?: string;
resizeMode: 'contain' | 'cover' | 'native';
drawable?: {
icon: string;
darkIcon?: string;
};
dark?: {
backgroundColor?: string;
xxxhdpi?: string;
xxhdpi?: string;
xhdpi?: string;
hdpi?: string;
mdpi?: string;
image?: string;
resizeMode?: 'contain' | 'cover' | 'native';
};
};
export type AndroidSplashConfig = {
imageWidth?: number;
} & SplashScreenConfig;
export declare function getAndroidSplashConfig(config: Pick<ExpoConfig, 'splash' | 'android'>, props?: AndroidSplashConfig | null): AndroidSplashConfig | null;
export declare function getAndroidDarkSplashConfig(config: Pick<ExpoConfig, 'splash' | 'android'>, props?: AndroidSplashConfig | null): SplashScreenConfig | null;
@@ -0,0 +1,96 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.getAndroidDarkSplashConfig = getAndroidDarkSplashConfig;
exports.getAndroidSplashConfig = getAndroidSplashConfig;
const defaultResizeMode = 'contain';
function getAndroidSplashConfig(config, props) {
// Respect the splash screen object, don't mix and match across different splash screen objects
// in case the user wants the top level splash to apply to every platform except android.
if (props) {
const splash = props;
return {
xxxhdpi: splash.xxxhdpi ?? splash.image,
xxhdpi: splash.xxhdpi ?? splash.image,
xhdpi: splash.xhdpi ?? splash.image,
hdpi: splash.hdpi ?? splash.image,
mdpi: splash.mdpi ?? splash.image,
backgroundColor: splash.backgroundColor,
resizeMode: splash.resizeMode ?? defaultResizeMode,
image: splash.image,
imageWidth: splash.imageWidth ?? 100,
dark: splash.dark,
drawable: splash.drawable
};
}
if (config.android?.splash) {
const splash = config.android?.splash;
return {
xxxhdpi: splash.xxxhdpi ?? splash.image,
xxhdpi: splash.xxhdpi ?? splash.image,
xhdpi: splash.xhdpi ?? splash.image,
hdpi: splash.hdpi ?? splash.image,
mdpi: splash.mdpi ?? splash.image,
backgroundColor: splash.backgroundColor,
image: splash.image,
resizeMode: splash.resizeMode ?? defaultResizeMode,
imageWidth: 200,
dark: splash.dark
};
}
if (config.splash) {
const splash = config.splash;
return {
xxxhdpi: splash.image,
xxhdpi: splash.image,
xhdpi: splash.image,
hdpi: splash.image,
mdpi: splash.image,
image: splash.image,
backgroundColor: splash.backgroundColor,
resizeMode: splash.resizeMode ?? defaultResizeMode,
imageWidth: 200,
dark: splash.dark
};
}
return null;
}
function getAndroidDarkSplashConfig(config, props) {
if (props?.dark) {
const splash = props.dark;
const lightTheme = getAndroidSplashConfig(config, props);
return {
xxxhdpi: splash.xxxhdpi ?? splash.image,
xxhdpi: splash.xxhdpi ?? splash.image,
xhdpi: splash.xhdpi ?? splash.image,
hdpi: splash.hdpi ?? splash.image,
mdpi: splash.mdpi ?? splash.image,
image: splash.image,
backgroundColor: splash.backgroundColor,
resizeMode: lightTheme?.resizeMode ?? defaultResizeMode,
drawable: props.drawable
};
}
// Respect the splash screen object, don't mix and match across different splash screen objects
// in case the user wants the top level splash to apply to every platform except android.
if (config.android?.splash?.dark) {
const splash = config.android?.splash?.dark;
const lightTheme = getAndroidSplashConfig(config, props);
return {
xxxhdpi: splash.xxxhdpi ?? splash.image,
xxhdpi: splash.xxhdpi ?? splash.image,
xhdpi: splash.xhdpi ?? splash.image,
hdpi: splash.hdpi ?? splash.image,
mdpi: splash.mdpi ?? splash.image,
image: splash.image,
backgroundColor: splash.backgroundColor,
// Can't support dark resizeMode because the resize mode is hardcoded into the MainActivity.java
resizeMode: lightTheme?.resizeMode ?? defaultResizeMode
};
}
return null;
}
//# sourceMappingURL=getAndroidSplashConfig.js.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1,19 @@
import { ExpoConfig } from '@expo/config-types';
type ExpoConfigIosSplash = NonNullable<NonNullable<ExpoConfig['ios']>['splash']>;
export interface IOSSplashConfig {
imageWidth?: number;
image?: string;
backgroundColor: string;
enableFullScreenImage_legacy?: boolean;
resizeMode: NonNullable<ExpoConfigIosSplash['resizeMode']>;
tabletImage?: string;
tabletBackgroundColor?: string;
dark?: {
image?: string;
backgroundColor?: string;
tabletImage?: string;
tabletBackgroundColor?: string;
};
}
export declare function getIosSplashConfig(config: ExpoConfig, props: IOSSplashConfig | null): IOSSplashConfig | null;
export {};
@@ -0,0 +1,70 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.getIosSplashConfig = getIosSplashConfig;
const defaultResizeMode = 'contain';
const defaultBackgroundColor = '#ffffff';
// TODO: Maybe use an array on splash with theme value. Then remove the array in serialization for legacy and manifest.
function getIosSplashConfig(config, props) {
// Respect the splash screen object, don't mix and match across different splash screen objects
// in case the user wants the top level splash to apply to every platform except iOS.
// We are using the config plugin
if (props) {
const splash = props;
return {
image: splash.image,
resizeMode: splash.resizeMode ?? defaultResizeMode,
backgroundColor: splash.backgroundColor ?? defaultBackgroundColor,
tabletImage: splash.tabletImage,
tabletBackgroundColor: splash.tabletBackgroundColor,
enableFullScreenImage_legacy: splash.enableFullScreenImage_legacy,
dark: {
image: splash.dark?.image,
backgroundColor: splash.dark?.backgroundColor,
tabletImage: splash.dark?.tabletImage,
tabletBackgroundColor: splash.dark?.tabletBackgroundColor
},
imageWidth: splash.imageWidth
};
}
if (config.ios?.splash) {
const splash = config.ios?.splash;
const image = splash.image;
return {
image,
resizeMode: splash.resizeMode ?? defaultResizeMode,
backgroundColor: splash.backgroundColor ?? defaultBackgroundColor,
tabletImage: splash.tabletImage,
tabletBackgroundColor: splash.tabletBackgroundColor,
enableFullScreenImage_legacy: true,
dark: {
image: splash.dark?.image,
backgroundColor: splash.dark?.backgroundColor,
tabletImage: splash.dark?.tabletImage,
tabletBackgroundColor: splash.dark?.tabletBackgroundColor
},
imageWidth: 200
};
}
if (config.splash) {
const splash = config.splash;
const image = splash.image;
return {
image,
resizeMode: splash.resizeMode ?? defaultResizeMode,
backgroundColor: splash.backgroundColor ?? defaultBackgroundColor,
enableFullScreenImage_legacy: true,
imageWidth: 200
};
}
return {
backgroundColor: '#ffffff',
resizeMode: 'contain',
enableFullScreenImage_legacy: true,
imageWidth: 200
};
}
//# sourceMappingURL=getIosSplashConfig.js.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1,4 @@
import { ConfigPlugin } from '@expo/config-plugins';
import { SplashScreenConfig } from './getAndroidSplashConfig';
export declare const withAndroidSplashDrawables: ConfigPlugin<Pick<SplashScreenConfig, 'resizeMode'>>;
export declare function setSplashDrawableAsync({ image }: SplashScreenConfig, projectRoot: string): Promise<void>;
@@ -0,0 +1,59 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.setSplashDrawableAsync = setSplashDrawableAsync;
exports.withAndroidSplashDrawables = void 0;
function _configPlugins() {
const data = require("@expo/config-plugins");
_configPlugins = function () {
return data;
};
return data;
}
const withAndroidSplashDrawables = (config, splash) => {
return (0, _configPlugins().withDangerousMod)(config, ['android', async config => {
if (splash) {
await setSplashDrawableAsync(splash, config.modRequest.projectRoot);
}
return config;
}]);
};
exports.withAndroidSplashDrawables = withAndroidSplashDrawables;
async function setSplashDrawableAsync({
image
}, projectRoot) {
const filePath = await _configPlugins().AndroidConfig.Paths.getResourceXMLPathAsync(projectRoot, {
name: 'ic_launcher_background',
kind: 'drawable'
});
// Nuke and rewrite the splashscreen.xml drawable
const xmlContent = {
'layer-list': {
$: {
'xmlns:android': 'http://schemas.android.com/apk/res/android'
},
item: [{
$: {
// TODO: Ensure these keys don't get out of sync
'android:drawable': '@color/splashscreen_background'
}
}, image && {
bitmap: [{
$: {
'android:gravity': 'center',
// TODO: Ensure these keys don't get out of sync
'android:src': '@drawable/splashscreen_logo'
}
}]
}].filter(Boolean)
}
};
await _configPlugins().XML.writeXMLAsync({
path: filePath,
xml: xmlContent
});
}
//# sourceMappingURL=withAndroidSplashDrawables.js.map
@@ -0,0 +1 @@
{"version":3,"file":"withAndroidSplashDrawables.js","names":["_configPlugins","data","require","withAndroidSplashDrawables","config","splash","withDangerousMod","setSplashDrawableAsync","modRequest","projectRoot","exports","image","filePath","AndroidConfig","Paths","getResourceXMLPathAsync","name","kind","xmlContent","$","item","bitmap","filter","Boolean","XML","writeXMLAsync","path","xml"],"sources":["../../../../src/plugins/unversioned/expo-splash-screen/withAndroidSplashDrawables.ts"],"sourcesContent":["import { AndroidConfig, ConfigPlugin, withDangerousMod, XML } from '@expo/config-plugins';\n\nimport { SplashScreenConfig } from './getAndroidSplashConfig';\n\nexport const withAndroidSplashDrawables: ConfigPlugin<Pick<SplashScreenConfig, 'resizeMode'>> = (\n config,\n splash\n) => {\n return withDangerousMod(config, [\n 'android',\n async (config) => {\n if (splash) {\n await setSplashDrawableAsync(splash, config.modRequest.projectRoot);\n }\n return config;\n },\n ]);\n};\n\nexport async function setSplashDrawableAsync({ image }: SplashScreenConfig, projectRoot: string) {\n const filePath = (await AndroidConfig.Paths.getResourceXMLPathAsync(projectRoot, {\n name: 'ic_launcher_background',\n kind: 'drawable',\n }))!;\n\n // Nuke and rewrite the splashscreen.xml drawable\n const xmlContent = {\n 'layer-list': {\n $: {\n 'xmlns:android': 'http://schemas.android.com/apk/res/android',\n },\n item: [\n {\n $: {\n // TODO: Ensure these keys don't get out of sync\n 'android:drawable': '@color/splashscreen_background',\n },\n },\n image && {\n bitmap: [\n {\n $: {\n 'android:gravity': 'center',\n // TODO: Ensure these keys don't get out of sync\n 'android:src': '@drawable/splashscreen_logo',\n },\n },\n ],\n },\n ].filter(Boolean),\n },\n };\n await XML.writeXMLAsync({ path: filePath, xml: xmlContent });\n}\n"],"mappings":";;;;;;;AAAA,SAAAA,eAAA;EAAA,MAAAC,IAAA,GAAAC,OAAA;EAAAF,cAAA,YAAAA,CAAA;IAAA,OAAAC,IAAA;EAAA;EAAA,OAAAA,IAAA;AAAA;AAIO,MAAME,0BAAgF,GAAGA,CAC9FC,MAAM,EACNC,MAAM,KACH;EACH,OAAO,IAAAC,iCAAgB,EAACF,MAAM,EAAE,CAC9B,SAAS,EACT,MAAOA,MAAM,IAAK;IAChB,IAAIC,MAAM,EAAE;MACV,MAAME,sBAAsB,CAACF,MAAM,EAAED,MAAM,CAACI,UAAU,CAACC,WAAW,CAAC;IACrE;IACA,OAAOL,MAAM;EACf,CAAC,CACF,CAAC;AACJ,CAAC;AAACM,OAAA,CAAAP,0BAAA,GAAAA,0BAAA;AAEK,eAAeI,sBAAsBA,CAAC;EAAEI;AAA0B,CAAC,EAAEF,WAAmB,EAAE;EAC/F,MAAMG,QAAQ,GAAI,MAAMC,8BAAa,CAACC,KAAK,CAACC,uBAAuB,CAACN,WAAW,EAAE;IAC/EO,IAAI,EAAE,wBAAwB;IAC9BC,IAAI,EAAE;EACR,CAAC,CAAG;;EAEJ;EACA,MAAMC,UAAU,GAAG;IACjB,YAAY,EAAE;MACZC,CAAC,EAAE;QACD,eAAe,EAAE;MACnB,CAAC;MACDC,IAAI,EAAE,CACJ;QACED,CAAC,EAAE;UACD;UACA,kBAAkB,EAAE;QACtB;MACF,CAAC,EACDR,KAAK,IAAI;QACPU,MAAM,EAAE,CACN;UACEF,CAAC,EAAE;YACD,iBAAiB,EAAE,QAAQ;YAC3B;YACA,aAAa,EAAE;UACjB;QACF,CAAC;MAEL,CAAC,CACF,CAACG,MAAM,CAACC,OAAO;IAClB;EACF,CAAC;EACD,MAAMC,oBAAG,CAACC,aAAa,CAAC;IAAEC,IAAI,EAAEd,QAAQ;IAAEe,GAAG,EAAET;EAAW,CAAC,CAAC;AAC9D","ignoreList":[]}
@@ -0,0 +1,13 @@
import { ConfigPlugin } from '@expo/config-plugins';
import { ExpoConfig } from '@expo/config-types';
import { AndroidSplashConfig, SplashScreenConfig } from './getAndroidSplashConfig';
export declare const withAndroidSplashImages: ConfigPlugin<AndroidSplashConfig | null>;
/**
* Deletes all previous splash_screen_images and copies new one to desired drawable directory.
* If path isn't provided then no new image is placed in drawable directories.
* @see https://developer.android.com/training/multiscreen/screendensities
*
* @param androidMainPath Absolute path to the main directory containing code and resources in Android project. In general that would be `android/app/src/main`.
*/
export declare function setSplashImageDrawablesAsync(config: Pick<ExpoConfig, 'android' | 'splash'>, props: AndroidSplashConfig | null, projectRoot: string, imageWidth: number): Promise<void>;
export declare function setSplashImageDrawablesForThemeAsync(config: SplashScreenConfig | null, theme: 'dark' | 'light', projectRoot: string, imageWidth?: number): Promise<void>;
@@ -0,0 +1,224 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.setSplashImageDrawablesAsync = setSplashImageDrawablesAsync;
exports.setSplashImageDrawablesForThemeAsync = setSplashImageDrawablesForThemeAsync;
exports.withAndroidSplashImages = void 0;
function _configPlugins() {
const data = require("@expo/config-plugins");
_configPlugins = function () {
return data;
};
return data;
}
function _imageUtils() {
const data = require("@expo/image-utils");
_imageUtils = function () {
return data;
};
return data;
}
function _fs() {
const data = _interopRequireDefault(require("fs"));
_fs = function () {
return data;
};
return data;
}
function _path() {
const data = _interopRequireDefault(require("path"));
_path = function () {
return data;
};
return data;
}
function _getAndroidSplashConfig() {
const data = require("./getAndroidSplashConfig");
_getAndroidSplashConfig = function () {
return data;
};
return data;
}
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
const IMAGE_CACHE_NAME = 'splash-android';
const SPLASH_SCREEN_FILENAME = 'splashscreen_logo.png';
const SPLASH_SCREEN_DRAWABLE_NAME = 'splashscreen_logo.xml';
const DRAWABLES_CONFIGS = {
default: {
modes: {
light: {
path: `./res/drawable/${SPLASH_SCREEN_DRAWABLE_NAME}`
},
dark: {
path: `./res/drawable-night/${SPLASH_SCREEN_DRAWABLE_NAME}`
}
},
dimensionsMultiplier: 1
},
mdpi: {
modes: {
light: {
path: `./res/drawable-mdpi/${SPLASH_SCREEN_FILENAME}`
},
dark: {
path: `./res/drawable-night-mdpi/${SPLASH_SCREEN_FILENAME}`
}
},
dimensionsMultiplier: 1
},
hdpi: {
modes: {
light: {
path: `./res/drawable-hdpi/${SPLASH_SCREEN_FILENAME}`
},
dark: {
path: `./res/drawable-night-hdpi/${SPLASH_SCREEN_FILENAME}`
}
},
dimensionsMultiplier: 1.5
},
xhdpi: {
modes: {
light: {
path: `./res/drawable-xhdpi/${SPLASH_SCREEN_FILENAME}`
},
dark: {
path: `./res/drawable-night-xhdpi/${SPLASH_SCREEN_FILENAME}`
}
},
dimensionsMultiplier: 2
},
xxhdpi: {
modes: {
light: {
path: `./res/drawable-xxhdpi/${SPLASH_SCREEN_FILENAME}`
},
dark: {
path: `./res/drawable-night-xxhdpi/${SPLASH_SCREEN_FILENAME}`
}
},
dimensionsMultiplier: 3
},
xxxhdpi: {
modes: {
light: {
path: `./res/drawable-xxxhdpi/${SPLASH_SCREEN_FILENAME}`
},
dark: {
path: `./res/drawable-night-xxxhdpi/${SPLASH_SCREEN_FILENAME}`
}
},
dimensionsMultiplier: 4
}
};
const withAndroidSplashImages = (config, splash) => {
return (0, _configPlugins().withDangerousMod)(config, ['android', async config => {
if (splash) {
await setSplashImageDrawablesAsync(config, splash, config.modRequest.projectRoot, splash?.imageWidth ?? 200);
}
return config;
}]);
};
/**
* Deletes all previous splash_screen_images and copies new one to desired drawable directory.
* If path isn't provided then no new image is placed in drawable directories.
* @see https://developer.android.com/training/multiscreen/screendensities
*
* @param androidMainPath Absolute path to the main directory containing code and resources in Android project. In general that would be `android/app/src/main`.
*/
exports.withAndroidSplashImages = withAndroidSplashImages;
async function setSplashImageDrawablesAsync(config, props, projectRoot, imageWidth) {
await clearAllExistingSplashImagesAsync(projectRoot);
const splash = (0, _getAndroidSplashConfig().getAndroidSplashConfig)(config, props);
const darkSplash = (0, _getAndroidSplashConfig().getAndroidDarkSplashConfig)(config, props);
await Promise.all([setSplashImageDrawablesForThemeAsync(splash, 'light', projectRoot, imageWidth), setSplashImageDrawablesForThemeAsync(darkSplash, 'dark', projectRoot, imageWidth)]);
}
async function clearAllExistingSplashImagesAsync(projectRoot) {
const androidMainPath = _path().default.join(projectRoot, 'android/app/src/main');
await Promise.all(Object.values(DRAWABLES_CONFIGS).map(async ({
modes
}) => {
await Promise.all(Object.values(modes).map(async ({
path: filePath
}) => {
await _fs().default.promises.rm(_path().default.resolve(androidMainPath, filePath), {
force: true,
recursive: true
});
}));
}));
}
async function setSplashImageDrawablesForThemeAsync(config, theme, projectRoot, imageWidth = 100) {
if (!config) return;
const androidMainPath = _path().default.join(projectRoot, 'android/app/src/main');
if (config.drawable) {
await writeSplashScreenDrawablesAsync(androidMainPath, projectRoot, config.drawable);
return;
}
const sizes = ['mdpi', 'hdpi', 'xhdpi', 'xxhdpi', 'xxxhdpi'];
await Promise.all(sizes.map(async imageKey => {
// @ts-ignore
const image = config[imageKey];
if (image) {
const multiplier = DRAWABLES_CONFIGS[imageKey].dimensionsMultiplier;
const size = imageWidth * multiplier; // "imageWidth" must be replaced by the logo width chosen by the user in its config file
const canvasSize = 288 * multiplier;
const background = await (0, _imageUtils().generateImageBackgroundAsync)({
width: canvasSize,
height: canvasSize,
backgroundColor: config.backgroundColor ?? 'transparent',
resizeMode: 'cover'
});
const {
source: foreground
} = await (0, _imageUtils().generateImageAsync)({
projectRoot,
cacheType: IMAGE_CACHE_NAME
}, {
src: image,
resizeMode: 'contain',
width: size,
height: size
});
const composedImage = await (0, _imageUtils().compositeImagesAsync)({
background,
foreground,
x: (canvasSize - size) / 2,
y: (canvasSize - size) / 2
});
// Get output path for drawable.
const outputPath = _path().default.join(androidMainPath, DRAWABLES_CONFIGS[imageKey].modes[theme].path);
const folder = _path().default.dirname(outputPath);
// Ensure directory exists.
await _fs().default.promises.mkdir(folder, {
recursive: true
});
await _fs().default.promises.writeFile(outputPath, composedImage);
}
return null;
}));
}
async function writeSplashScreenDrawablesAsync(drawablePath, projectRoot, drawable) {
if (!drawable) {
return;
}
const lightDrawablePath = _path().default.join(drawablePath, DRAWABLES_CONFIGS.default.modes.light.path);
const darkDrawablePath = _path().default.join(drawablePath, DRAWABLES_CONFIGS.default.modes.dark.path);
const lightFolder = _path().default.dirname(lightDrawablePath);
await _fs().default.promises.mkdir(lightFolder, {
recursive: true
});
await _fs().default.promises.copyFile(_path().default.join(projectRoot, drawable.icon), lightDrawablePath);
if (drawable.darkIcon) {
const darkFolder = _path().default.dirname(darkDrawablePath);
await _fs().default.promises.mkdir(darkFolder, {
recursive: true
});
await _fs().default.promises.copyFile(_path().default.join(projectRoot, drawable.darkIcon), darkDrawablePath);
}
}
//# sourceMappingURL=withAndroidSplashImages.js.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1,5 @@
import { ConfigPlugin } from '@expo/config-plugins';
import { ExpoConfig } from '@expo/config-types';
import { AndroidSplashConfig } from './getAndroidSplashConfig';
export declare const withAndroidSplashLegacyMainActivity: ConfigPlugin<AndroidSplashConfig>;
export declare function setSplashScreenLegacyMainActivity(config: Pick<ExpoConfig, 'android' | 'androidStatusBar' | 'userInterfaceStyle'>, props: AndroidSplashConfig, mainActivity: string, language: 'java' | 'kt'): string;
@@ -0,0 +1,117 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.setSplashScreenLegacyMainActivity = setSplashScreenLegacyMainActivity;
exports.withAndroidSplashLegacyMainActivity = void 0;
function _configPlugins() {
const data = require("@expo/config-plugins");
_configPlugins = function () {
return data;
};
return data;
}
function _codeMod() {
const data = require("@expo/config-plugins/build/android/codeMod");
_codeMod = function () {
return data;
};
return data;
}
function _generateCode() {
const data = require("@expo/config-plugins/build/utils/generateCode");
_generateCode = function () {
return data;
};
return data;
}
function _debug() {
const data = _interopRequireDefault(require("debug"));
_debug = function () {
return data;
};
return data;
}
function _getAndroidSplashConfig() {
const data = require("./getAndroidSplashConfig");
_getAndroidSplashConfig = function () {
return data;
};
return data;
}
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
const debug = (0, _debug().default)('expo:prebuild-config:expo-splash-screen:android:mainActivity');
// DO NOT CHANGE
const SHOW_SPLASH_ID = 'expo-splash-screen-mainActivity-onCreate-show-splash';
const withAndroidSplashLegacyMainActivity = (config, props) => {
return (0, _configPlugins().withMainActivity)(config, config => {
config.modResults.contents = setSplashScreenLegacyMainActivity(config, props, config.modResults.contents, config.modResults.language);
return config;
});
};
exports.withAndroidSplashLegacyMainActivity = withAndroidSplashLegacyMainActivity;
function setSplashScreenLegacyMainActivity(config, props, mainActivity, language) {
debug(`Modify with language: "${language}"`);
const splashConfig = (0, _getAndroidSplashConfig().getAndroidSplashConfig)(config, props);
if (!splashConfig) {
// Remove our generated code safely...
const mod = (0, _generateCode().removeContents)({
src: mainActivity,
tag: SHOW_SPLASH_ID
});
mainActivity = mod.contents;
if (mod.didClear) {
debug('Removed SplashScreen.show()');
}
return mainActivity;
}
// TODO: Translucent is weird
const statusBarTranslucent = !!config.androidStatusBar?.translucent;
const {
resizeMode
} = splashConfig;
const isJava = language === 'java';
const LE = isJava ? ';' : '';
mainActivity = (0, _codeMod().addImports)(mainActivity, ['host.exp.exponent.experience.splashscreen.legacy.singletons.SplashScreen', 'host.exp.exponent.experience.splashscreen.legacy.SplashScreenImageResizeMode', 'com.facebook.react.ReactRootView', 'android.os.Bundle'], isJava);
if (!mainActivity.match(/(?<=^.*super\.onCreate.*$)/m)) {
const onCreateBlock = isJava ? [' @Override', ' protected void onCreate(Bundle savedInstanceState) {', ' super.onCreate(savedInstanceState);', ' }'] : [' override fun onCreate(savedInstanceState: Bundle?) {', ' super.onCreate(savedInstanceState)', ' }'];
mainActivity = (0, _generateCode().mergeContents)({
src: mainActivity,
// insert just below super.onCreate
anchor: isJava ? /(?<=public\s+class\s+.*\s+extends\s+.*\s+{.*$)/m : /(?<=class\s+.*\s+:\s+.*\s+{.*$)/m,
offset: 1,
comment: '//',
tag: 'expo-splash-screen-mainActivity-onCreate',
newSrc: onCreateBlock.join('\n')
}).contents;
}
// Remove our generated code safely...
mainActivity = (0, _generateCode().removeContents)({
src: mainActivity,
tag: SHOW_SPLASH_ID
}).contents;
// Remove code from `@expo/configure-splash-screen`
mainActivity = mainActivity.split('\n').filter(line => {
return !/SplashScreen\.show\(this,\s?SplashScreenImageResizeMode\./.test(line);
}).join('\n');
// Reapply generated code.
mainActivity = (0, _generateCode().mergeContents)({
src: mainActivity,
// insert just below super.onCreate
anchor: /(?<=^.*super\.onCreate.*$)/m,
offset: 1,
comment: '//',
tag: SHOW_SPLASH_ID,
newSrc: ` SplashScreen.show(this, SplashScreenImageResizeMode.${resizeMode.toUpperCase()}, ReactRootView${isJava ? '.class' : '::class.java'}, ${statusBarTranslucent})${LE}`
}).contents;
// TODO: Remove old `SplashScreen.show`
return mainActivity;
}
//# sourceMappingURL=withAndroidSplashLegacyMainActivity.js.map
@@ -0,0 +1,4 @@
import { ConfigPlugin } from '@expo/config-plugins';
export declare const withAndroidSplashMainActivity: ConfigPlugin<{
isLegacyConfig: boolean;
}>;
@@ -0,0 +1,60 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.withAndroidSplashMainActivity = void 0;
function _configPlugins() {
const data = require("@expo/config-plugins");
_configPlugins = function () {
return data;
};
return data;
}
function _codeMod() {
const data = require("@expo/config-plugins/build/android/codeMod");
_codeMod = function () {
return data;
};
return data;
}
function _generateCode() {
const data = require("@expo/config-plugins/build/utils/generateCode");
_generateCode = function () {
return data;
};
return data;
}
const withAndroidSplashMainActivity = (config, {
isLegacyConfig
}) => {
if (isLegacyConfig) {
return config;
}
return (0, _configPlugins().withMainActivity)(config, config => {
const {
modResults
} = config;
const {
language
} = modResults;
const withImports = (0, _codeMod().addImports)(modResults.contents.replace(/(\/\/ )?setTheme\(R\.style\.AppTheme\)/, '// setTheme(R.style.AppTheme)'), ['expo.modules.splashscreen.SplashScreenManager'], language === 'java');
const init = (0, _generateCode().mergeContents)({
src: withImports,
comment: ' //',
tag: 'expo-splashscreen',
offset: 0,
anchor: /super\.onCreate\(null\)/,
newSrc: ' SplashScreenManager.registerOnActivity(this)' + (language === 'java' ? ';' : '')
});
return {
...config,
modResults: {
...modResults,
contents: init.contents
}
};
});
};
exports.withAndroidSplashMainActivity = withAndroidSplashMainActivity;
//# sourceMappingURL=withAndroidSplashMainActivity.js.map

Some files were not shown because too many files have changed in this diff Show More