first commit

This commit is contained in:
2026-03-10 16:18:05 +00:00
commit 11f9c069b5
31635 changed files with 3187747 additions and 0 deletions

22
node_modules/@expo/config-plugins/LICENSE generated vendored Normal file
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.

34
node_modules/@expo/config-plugins/README.md generated vendored Normal file
View File

@@ -0,0 +1,34 @@
<!-- Title -->
<h1 align="center">
👋 Welcome to <br><code>@expo/config-plugins</code>
</h1>
<p align="center">A powerful tool for generating native app code from a unified JavaScript interface.</p>
<p align="center">
<img src="https://flat.badgen.net/packagephobia/install/@expo/config-plugins">
<a href="https://www.npmjs.com/package/@expo/config-plugins">
<img src="https://flat.badgen.net/npm/dw/@expo/config-plugins" target="_blank" />
</a>
</p>
<!-- Body -->
Most basic functionality can be controlled by using the [static Expo config](https://docs.expo.dev/versions/latest/config/app/), but some features require manipulation of the native project files. To support complex behavior we've created config plugins, and mods (short for modifiers).
For more info, please refer to the official Expo docs: [Config Plugins](https://docs.expo.dev/config-plugins/introduction/).
## Environment Variables
### `EXPO_DEBUG`
Print debug information related to static plugin resolution.
### `EXPO_CONFIG_PLUGIN_VERBOSE_ERRORS`
Show all error info related to static plugin resolution. Requires `EXPO_DEBUG` to be enabled.
### `EXPO_USE_UNVERSIONED_PLUGINS`
Force using the fallback unversioned plugins instead of a local versioned copy from installed packages, this should only be used for testing the CLI.

View File

@@ -0,0 +1,177 @@
import { ExpoConfig } from '@expo/config-types';
import { JSONObject } from '@expo/json-file';
import { XcodeProject } from 'xcode';
import { Properties } from './android';
import { AndroidManifest } from './android/Manifest';
import * as AndroidPaths from './android/Paths';
import { ResourceXML } from './android/Resources';
import { ExpoPlist, InfoPlist } from './ios/IosConfig.types';
import { AppDelegateProjectFile } from './ios/Paths';
type OptionalPromise<T> = Promise<T> | T;
type Plist = JSONObject;
export interface ModProps<T = any> {
/**
* Project root directory for the universal app.
*/
readonly projectRoot: string;
/**
* Project root for the specific platform.
*/
readonly platformProjectRoot: string;
/**
* Name of the mod.
*/
readonly modName: string;
/**
* Name of the platform used in the mods config.
*/
readonly platform: ModPlatform;
/**
* If the mod is being evaluated in introspection mode.
* No file system modifications should be made when introspect is `true`.
*/
readonly introspect: boolean;
/**
* [iOS]: The path component used for querying project files.
*
* @example projectRoot/ios/[projectName]/
*/
readonly projectName?: string;
/**
* Ignore any of the user's local native files and solely rely on the generated files.
* This makes prebuild data, like entitlements, more aligned to what users expects.
* When enabling this, users must be informed and have a way to disable this exclusion.
*/
readonly ignoreExistingNativeFiles?: boolean;
nextMod?: Mod<T>;
}
export interface ExportedConfig extends ExpoConfig {
mods?: ModConfig | null;
}
export interface ExportedConfigWithProps<Data = any> extends ExportedConfig {
/**
* The Object representation of a complex file type.
*/
modResults: Data;
modRequest: ModProps<Data>;
/**
* A frozen representation of the original file contents,
* this can be used as a reference into the user's original intent.
*
* For example, you could infer that the user defined a certain
* value explicitly and disable any automatic changes.
*/
readonly modRawConfig: ExpoConfig;
}
/**
* A helper type to get the properties of a plugin.
*/
export type PluginParameters<T extends ConfigPlugin<any>> = T extends (config: any, props: infer P) => any ? P : never;
export type ConfigPlugin<Props = void> = (config: ExpoConfig, props: Props) => ExpoConfig;
export type StaticPlugin<T = any> = [string | ConfigPlugin<T>, T];
export type Mod<Props = any> = ((config: ExportedConfigWithProps<Props>) => OptionalPromise<ExportedConfigWithProps<Props>>) & {
/**
* Indicates that the mod provides data upstream to other mods.
* This mod should always be the last one added.
*/
isProvider?: boolean;
/**
* If the mod supports introspection, and avoids making any filesystem modifications during compilation.
* By enabling, this mod, and all of its descendants will be run in introspection mode.
* This should only be used for static files like JSON or XML, and not for application files that require regexes,
* or complex static files that require other files to be generated like Xcode `.pbxproj`.
*/
isIntrospective?: boolean;
};
export interface ModConfig {
android?: {
/**
* Dangerously make a modification before any other platform mods have been run.
*/
dangerous?: Mod<unknown>;
/**
* Dangerously make a modification after all the other platform mods have been run.
*/
finalized?: Mod<unknown>;
/**
* Modify the `android/app/src/main/AndroidManifest.xml` as JSON (parsed with [`xml2js`](https://www.npmjs.com/package/xml2js)).
*/
manifest?: Mod<AndroidManifest>;
/**
* Modify the `android/app/src/main/res/values/strings.xml` as JSON (parsed with [`xml2js`](https://www.npmjs.com/package/xml2js)).
*/
strings?: Mod<ResourceXML>;
/**
* Modify the `android/app/src/main/res/values/colors.xml` as JSON (parsed with [`xml2js`](https://www.npmjs.com/package/xml2js)).
*/
colors?: Mod<ResourceXML>;
/**
* Modify the `android/app/src/main/res/values-night/colors.xml` as JSON (parsed with [`xml2js`](https://www.npmjs.com/package/xml2js)).
*/
colorsNight?: Mod<ResourceXML>;
/**
* Modify the `android/app/src/main/res/values/styles.xml` as JSON (parsed with [`xml2js`](https://www.npmjs.com/package/xml2js)).
*/
styles?: Mod<ResourceXML>;
/**
* Modify the `android/app/src/main/<package>/MainActivity.java` as a string.
*/
mainActivity?: Mod<AndroidPaths.ApplicationProjectFile>;
/**
* Modify the `android/app/src/main/<package>/MainApplication.java` as a string.
*/
mainApplication?: Mod<AndroidPaths.ApplicationProjectFile>;
/**
* Modify the `android/app/build.gradle` as a string.
*/
appBuildGradle?: Mod<AndroidPaths.GradleProjectFile>;
/**
* Modify the `android/build.gradle` as a string.
*/
projectBuildGradle?: Mod<AndroidPaths.GradleProjectFile>;
/**
* Modify the `android/settings.gradle` as a string.
*/
settingsGradle?: Mod<AndroidPaths.GradleProjectFile>;
/**
* Modify the `android/gradle.properties` as a `Properties.PropertiesItem[]`.
*/
gradleProperties?: Mod<Properties.PropertiesItem[]>;
};
ios?: {
/**
* Dangerously make a modification before any other platform mods have been run.
*/
dangerous?: Mod<unknown>;
/**
* Dangerously make a modification after all the other platform mods have been run.
*/
finalized?: Mod<unknown>;
/**
* Modify the `ios/<name>/Info.plist` as JSON (parsed with [`@expo/plist`](https://www.npmjs.com/package/@expo/plist)).
*/
infoPlist?: Mod<InfoPlist>;
/**
* Modify the `ios/<name>/<product-name>.entitlements` as JSON (parsed with [`@expo/plist`](https://www.npmjs.com/package/@expo/plist)).
*/
entitlements?: Mod<Plist>;
/**
* Modify the `ios/<name>/Expo.plist` as JSON (Expo updates config for iOS) (parsed with [`@expo/plist`](https://www.npmjs.com/package/@expo/plist)).
*/
expoPlist?: Mod<Plist>;
/**
* Modify the `ios/<name>.xcodeproj` as an `XcodeProject` (parsed with [`xcode`](https://www.npmjs.com/package/xcode))
*/
xcodeproj?: Mod<XcodeProject>;
/**
* Modify the `ios/<name>/AppDelegate.m` as a string (dangerous)
*/
appDelegate?: Mod<AppDelegateProjectFile>;
/**
* Modify the `ios/Podfile.properties.json` as key-value pairs
*/
podfileProperties?: Mod<Record<string, string>>;
};
}
export type ModPlatform = keyof ModConfig;
export { XcodeProject, InfoPlist, ExpoPlist, AndroidManifest };

View File

@@ -0,0 +1,51 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "AndroidManifest", {
enumerable: true,
get: function () {
return _Manifest().AndroidManifest;
}
});
Object.defineProperty(exports, "ExpoPlist", {
enumerable: true,
get: function () {
return _IosConfig().ExpoPlist;
}
});
Object.defineProperty(exports, "InfoPlist", {
enumerable: true,
get: function () {
return _IosConfig().InfoPlist;
}
});
Object.defineProperty(exports, "XcodeProject", {
enumerable: true,
get: function () {
return _xcode().XcodeProject;
}
});
function _xcode() {
const data = require("xcode");
_xcode = function () {
return data;
};
return data;
}
function _Manifest() {
const data = require("./android/Manifest");
_Manifest = function () {
return data;
};
return data;
}
function _IosConfig() {
const data = require("./ios/IosConfig.types");
_IosConfig = function () {
return data;
};
return data;
}
//# sourceMappingURL=Plugin.types.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,6 @@
import { ExpoConfig } from '@expo/config-types';
import { AndroidManifest } from './Manifest';
export declare const withAllowBackup: import("..").ConfigPlugin;
export declare function getAllowBackup(config: Pick<ExpoConfig, 'android'>): boolean;
export declare function setAllowBackup(config: Pick<ExpoConfig, 'android'>, androidManifest: AndroidManifest): AndroidManifest;
export declare function getAllowBackupFromManifest(androidManifest: AndroidManifest): boolean | null;

View File

@@ -0,0 +1,45 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.getAllowBackup = getAllowBackup;
exports.getAllowBackupFromManifest = getAllowBackupFromManifest;
exports.setAllowBackup = setAllowBackup;
exports.withAllowBackup = void 0;
function _Manifest() {
const data = require("./Manifest");
_Manifest = function () {
return data;
};
return data;
}
function _androidPlugins() {
const data = require("../plugins/android-plugins");
_androidPlugins = function () {
return data;
};
return data;
}
const withAllowBackup = exports.withAllowBackup = (0, _androidPlugins().createAndroidManifestPlugin)(setAllowBackup, 'withAllowBackup');
function getAllowBackup(config) {
// Defaults to true.
// https://docs.expo.dev/versions/latest/config/app/#allowbackup
return config.android?.allowBackup ?? true;
}
function setAllowBackup(config, androidManifest) {
const allowBackup = getAllowBackup(config);
const mainApplication = (0, _Manifest().getMainApplication)(androidManifest);
if (mainApplication?.$) {
mainApplication.$['android:allowBackup'] = String(allowBackup);
}
return androidManifest;
}
function getAllowBackupFromManifest(androidManifest) {
const mainApplication = (0, _Manifest().getMainApplication)(androidManifest);
if (mainApplication?.$) {
return String(mainApplication.$['android:allowBackup']) === 'true';
}
return null;
}
//# sourceMappingURL=AllowBackup.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"AllowBackup.js","names":["_Manifest","data","require","_androidPlugins","withAllowBackup","exports","createAndroidManifestPlugin","setAllowBackup","getAllowBackup","config","android","allowBackup","androidManifest","mainApplication","getMainApplication","$","String","getAllowBackupFromManifest"],"sources":["../../src/android/AllowBackup.ts"],"sourcesContent":["import { ExpoConfig } from '@expo/config-types';\n\nimport { AndroidManifest, getMainApplication, StringBoolean } from './Manifest';\nimport { createAndroidManifestPlugin } from '../plugins/android-plugins';\n\nexport const withAllowBackup = createAndroidManifestPlugin(setAllowBackup, 'withAllowBackup');\n\nexport function getAllowBackup(config: Pick<ExpoConfig, 'android'>) {\n // Defaults to true.\n // https://docs.expo.dev/versions/latest/config/app/#allowbackup\n return config.android?.allowBackup ?? true;\n}\n\nexport function setAllowBackup(\n config: Pick<ExpoConfig, 'android'>,\n androidManifest: AndroidManifest\n) {\n const allowBackup = getAllowBackup(config);\n\n const mainApplication = getMainApplication(androidManifest);\n if (mainApplication?.$) {\n mainApplication.$['android:allowBackup'] = String(allowBackup) as StringBoolean;\n }\n\n return androidManifest;\n}\n\nexport function getAllowBackupFromManifest(androidManifest: AndroidManifest): boolean | null {\n const mainApplication = getMainApplication(androidManifest);\n\n if (mainApplication?.$) {\n return String(mainApplication.$['android:allowBackup']) === 'true';\n }\n\n return null;\n}\n"],"mappings":";;;;;;;;;AAEA,SAAAA,UAAA;EAAA,MAAAC,IAAA,GAAAC,OAAA;EAAAF,SAAA,YAAAA,CAAA;IAAA,OAAAC,IAAA;EAAA;EAAA,OAAAA,IAAA;AAAA;AACA,SAAAE,gBAAA;EAAA,MAAAF,IAAA,GAAAC,OAAA;EAAAC,eAAA,YAAAA,CAAA;IAAA,OAAAF,IAAA;EAAA;EAAA,OAAAA,IAAA;AAAA;AAEO,MAAMG,eAAe,GAAAC,OAAA,CAAAD,eAAA,GAAG,IAAAE,6CAA2B,EAACC,cAAc,EAAE,iBAAiB,CAAC;AAEtF,SAASC,cAAcA,CAACC,MAAmC,EAAE;EAClE;EACA;EACA,OAAOA,MAAM,CAACC,OAAO,EAAEC,WAAW,IAAI,IAAI;AAC5C;AAEO,SAASJ,cAAcA,CAC5BE,MAAmC,EACnCG,eAAgC,EAChC;EACA,MAAMD,WAAW,GAAGH,cAAc,CAACC,MAAM,CAAC;EAE1C,MAAMI,eAAe,GAAG,IAAAC,8BAAkB,EAACF,eAAe,CAAC;EAC3D,IAAIC,eAAe,EAAEE,CAAC,EAAE;IACtBF,eAAe,CAACE,CAAC,CAAC,qBAAqB,CAAC,GAAGC,MAAM,CAACL,WAAW,CAAkB;EACjF;EAEA,OAAOC,eAAe;AACxB;AAEO,SAASK,0BAA0BA,CAACL,eAAgC,EAAkB;EAC3F,MAAMC,eAAe,GAAG,IAAAC,8BAAkB,EAACF,eAAe,CAAC;EAE3D,IAAIC,eAAe,EAAEE,CAAC,EAAE;IACtB,OAAOC,MAAM,CAACH,eAAe,CAACE,CAAC,CAAC,qBAAqB,CAAC,CAAC,KAAK,MAAM;EACpE;EAEA,OAAO,IAAI;AACb","ignoreList":[]}

View File

@@ -0,0 +1,28 @@
import type { ExpoConfig } from '@expo/config-types';
import type { PropertiesItem } from './Properties';
import type { ConfigPlugin } from '../Plugin.types';
import { BuildPropertiesConfig, ConfigToPropertyRuleType } from '../utils/BuildProperties.types';
/**
* Creates a `withGradleProperties` config-plugin based on given config to property mapping rules.
*
* The factory supports two modes from generic type inference
* ```ts
* // config-plugin without `props`, it will implicitly use the expo config as source config.
* createBuildGradlePropsConfigPlugin<ExpoConfig>(): ConfigPlugin<void>;
*
* // config-plugin with a parameter `props: CustomType`, it will use the `props` as source config.
* createBuildGradlePropsConfigPlugin<CustomType>(): ConfigPlugin<CustomType>;
* ```
*
* @param configToPropertyRules config to property mapping rules
* @param name the config plugin name
*/
export declare function createBuildGradlePropsConfigPlugin<SourceConfigType extends BuildPropertiesConfig>(configToPropertyRules: ConfigToPropertyRuleType<SourceConfigType>[], name?: string): ConfigPlugin<SourceConfigType extends ExpoConfig ? void : SourceConfigType>;
/**
* A config-plugin to update `android/gradle.properties` from the `jsEngine` in expo config
*/
export declare const withJsEngineGradleProps: ConfigPlugin<void>;
export declare function updateAndroidBuildPropertiesFromConfig<SourceConfigType extends BuildPropertiesConfig>(config: SourceConfigType, gradleProperties: PropertiesItem[], configToPropertyRules: ConfigToPropertyRuleType<SourceConfigType>[]): PropertiesItem[];
export declare function updateAndroidBuildProperty(gradleProperties: PropertiesItem[], name: string, value: string | null | undefined, options?: {
removePropWhenValueIsNull?: boolean;
}): PropertiesItem[];

View File

@@ -0,0 +1,93 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.createBuildGradlePropsConfigPlugin = createBuildGradlePropsConfigPlugin;
exports.updateAndroidBuildPropertiesFromConfig = updateAndroidBuildPropertiesFromConfig;
exports.updateAndroidBuildProperty = updateAndroidBuildProperty;
exports.withJsEngineGradleProps = void 0;
function _androidPlugins() {
const data = require("../plugins/android-plugins");
_androidPlugins = function () {
return data;
};
return data;
}
/**
* Creates a `withGradleProperties` config-plugin based on given config to property mapping rules.
*
* The factory supports two modes from generic type inference
* ```ts
* // config-plugin without `props`, it will implicitly use the expo config as source config.
* createBuildGradlePropsConfigPlugin<ExpoConfig>(): ConfigPlugin<void>;
*
* // config-plugin with a parameter `props: CustomType`, it will use the `props` as source config.
* createBuildGradlePropsConfigPlugin<CustomType>(): ConfigPlugin<CustomType>;
* ```
*
* @param configToPropertyRules config to property mapping rules
* @param name the config plugin name
*/
function createBuildGradlePropsConfigPlugin(configToPropertyRules, name) {
const withUnknown = (config, sourceConfig) => (0, _androidPlugins().withGradleProperties)(config, config => {
config.modResults = updateAndroidBuildPropertiesFromConfig(sourceConfig ?? config, config.modResults, configToPropertyRules);
return config;
});
if (name) {
Object.defineProperty(withUnknown, 'name', {
value: name
});
}
return withUnknown;
}
/**
* A config-plugin to update `android/gradle.properties` from the `jsEngine` in expo config
*/
const withJsEngineGradleProps = exports.withJsEngineGradleProps = createBuildGradlePropsConfigPlugin([{
propName: 'hermesEnabled',
propValueGetter: config => ((config.android?.jsEngine ?? config.jsEngine ?? 'hermes') === 'hermes').toString()
}], 'withJsEngineGradleProps');
function updateAndroidBuildPropertiesFromConfig(config, gradleProperties, configToPropertyRules) {
for (const configToProperty of configToPropertyRules) {
const value = configToProperty.propValueGetter(config);
updateAndroidBuildProperty(gradleProperties, configToProperty.propName, value);
}
return gradleProperties;
}
function updateAndroidBuildProperty(gradleProperties, name, value, options) {
const oldPropIndex = gradleProperties.findIndex(prop => prop.type === 'property' && prop.key === name);
const oldProp = oldPropIndex >= 0 ? gradleProperties[oldPropIndex] : null;
if (value) {
// found the matched value, add or merge new property
const newProp = {
type: 'property',
key: name,
value
};
if (oldProp && oldProp.type === 'property') {
try {
const prevValue = JSON.parse(oldProp.value);
const newValue = JSON.parse(value);
if (Array.isArray(prevValue) && Array.isArray(newValue)) {
const prevArrayWithStringifiedValues = prevValue.map(v => JSON.stringify(v));
const newArrayWithStringifiedValues = newValue.map(v => JSON.stringify(v));
const mergedValues = [...new Set([...prevArrayWithStringifiedValues, ...newArrayWithStringifiedValues])].map(v => JSON.parse(v));
oldProp.value = JSON.stringify(mergedValues);
return gradleProperties;
}
} catch {}
oldProp.value = value;
return gradleProperties;
}
gradleProperties.push(newProp);
return gradleProperties;
}
if (options?.removePropWhenValueIsNull && oldPropIndex >= 0) {
gradleProperties.splice(oldPropIndex, 1);
return gradleProperties;
}
return gradleProperties;
}
//# sourceMappingURL=BuildProperties.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,29 @@
import { ResourceItemXML, ResourceKind, ResourceXML } from './Resources';
export declare function getProjectColorsXMLPathAsync(projectRoot: string, { kind }?: {
kind?: ResourceKind;
}): Promise<string>;
export declare function setColorItem(itemToAdd: ResourceItemXML, colorFileContentsJSON: ResourceXML): ResourceXML;
export declare function removeColorItem(named: string, contents: ResourceXML): ResourceXML;
/**
* Set or remove value in XML based on nullish factor of the `value` property.
*/
export declare function assignColorValue(xml: ResourceXML, { value, name, }: {
value?: string | null;
name: string;
}): ResourceXML;
/**
* Helper to convert a basic XML object into a simple k/v pair.
* `colors.xml` is a very basic XML file so this is pretty safe to do.
* Added for testing purposes.
*
* @param xml
* @returns
*/
export declare function getColorsAsObject(xml: ResourceXML): Record<string, string> | null;
/**
* Helper to convert a basic k/v object to a colors XML object.
*
* @param xml
* @returns
*/
export declare function getObjectAsColorsXml(obj: Record<string, string>): ResourceXML;

View File

@@ -0,0 +1,106 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.assignColorValue = assignColorValue;
exports.getColorsAsObject = getColorsAsObject;
exports.getObjectAsColorsXml = getObjectAsColorsXml;
exports.getProjectColorsXMLPathAsync = getProjectColorsXMLPathAsync;
exports.removeColorItem = removeColorItem;
exports.setColorItem = setColorItem;
function _Paths() {
const data = require("./Paths");
_Paths = function () {
return data;
};
return data;
}
function _Resources() {
const data = require("./Resources");
_Resources = function () {
return data;
};
return data;
}
function getProjectColorsXMLPathAsync(projectRoot, {
kind
} = {}) {
return (0, _Paths().getResourceXMLPathAsync)(projectRoot, {
kind,
name: 'colors'
});
}
function setColorItem(itemToAdd, colorFileContentsJSON) {
if (colorFileContentsJSON.resources?.color) {
const colorNameExists = colorFileContentsJSON.resources.color.filter(e => e.$.name === itemToAdd.$.name)[0];
if (colorNameExists) {
colorNameExists._ = itemToAdd._;
} else {
colorFileContentsJSON.resources.color.push(itemToAdd);
}
} else {
if (!colorFileContentsJSON.resources || typeof colorFileContentsJSON.resources === 'string') {
//file was empty and JSON is `{resources : ''}`
colorFileContentsJSON.resources = {};
}
colorFileContentsJSON.resources.color = [itemToAdd];
}
return colorFileContentsJSON;
}
function removeColorItem(named, contents) {
if (contents.resources?.color) {
const index = contents.resources.color.findIndex(e => e.$.name === named);
if (index > -1) {
// replace the previous value
contents.resources.color.splice(index, 1);
}
}
return contents;
}
/**
* Set or remove value in XML based on nullish factor of the `value` property.
*/
function assignColorValue(xml, {
value,
name
}) {
if (value) {
return setColorItem((0, _Resources().buildResourceItem)({
name,
value
}), xml);
}
return removeColorItem(name, xml);
}
/**
* Helper to convert a basic XML object into a simple k/v pair.
* `colors.xml` is a very basic XML file so this is pretty safe to do.
* Added for testing purposes.
*
* @param xml
* @returns
*/
function getColorsAsObject(xml) {
if (!xml?.resources?.color) {
return null;
}
return (0, _Resources().getResourceItemsAsObject)(xml.resources.color);
}
/**
* Helper to convert a basic k/v object to a colors XML object.
*
* @param xml
* @returns
*/
function getObjectAsColorsXml(obj) {
return {
resources: {
color: (0, _Resources().getObjectAsResourceItems)(obj)
}
};
}
//# sourceMappingURL=Colors.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,3 @@
export declare function getEasBuildGradlePath(projectRoot: string): string;
export declare function configureEasBuildAsync(projectRoot: string): Promise<void>;
export declare function isEasBuildGradleConfiguredAsync(projectRoot: string): Promise<boolean>;

View File

@@ -0,0 +1,67 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.configureEasBuildAsync = configureEasBuildAsync;
exports.getEasBuildGradlePath = getEasBuildGradlePath;
exports.isEasBuildGradleConfiguredAsync = isEasBuildGradleConfiguredAsync;
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 _EasBuildGradleScript() {
const data = _interopRequireDefault(require("./EasBuildGradleScript"));
_EasBuildGradleScript = function () {
return data;
};
return data;
}
function Paths() {
const data = _interopRequireWildcard(require("./Paths"));
Paths = function () {
return data;
};
return data;
}
function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
const APPLY_EAS_GRADLE = 'apply from: "./eas-build.gradle"';
function hasApplyLine(content, applyLine) {
return content.replace(/\r\n/g, '\n').split('\n')
// Check for both single and double quotes
.some(line => line === applyLine || line === applyLine.replace(/"/g, "'"));
}
function getEasBuildGradlePath(projectRoot) {
return _path().default.join(projectRoot, 'android', 'app', 'eas-build.gradle');
}
async function configureEasBuildAsync(projectRoot) {
const buildGradlePath = Paths().getAppBuildGradleFilePath(projectRoot);
const easGradlePath = getEasBuildGradlePath(projectRoot);
await _fs().default.promises.writeFile(easGradlePath, _EasBuildGradleScript().default);
const buildGradleContent = await _fs().default.promises.readFile(_path().default.join(buildGradlePath), 'utf8');
const hasEasGradleApply = hasApplyLine(buildGradleContent, APPLY_EAS_GRADLE);
if (!hasEasGradleApply) {
await _fs().default.promises.writeFile(buildGradlePath, `${buildGradleContent.trim()}\n${APPLY_EAS_GRADLE}\n`);
}
}
async function isEasBuildGradleConfiguredAsync(projectRoot) {
const buildGradlePath = Paths().getAppBuildGradleFilePath(projectRoot);
const easGradlePath = getEasBuildGradlePath(projectRoot);
const hasEasGradleFile = await _fs().default.existsSync(easGradlePath);
const buildGradleContent = await _fs().default.promises.readFile(_path().default.join(buildGradlePath), 'utf8');
const hasEasGradleApply = hasApplyLine(buildGradleContent, APPLY_EAS_GRADLE);
return hasEasGradleApply && hasEasGradleFile;
}
//# sourceMappingURL=EasBuild.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,2 @@
declare const _default: "// Build integration with EAS\n\nimport java.nio.file.Paths\n\nandroid {\n signingConfigs {\n release {\n // This is necessary to avoid needing the user to define a release signing config manually\n // If no release config is defined, and this is not present, build for assembleRelease will crash\n }\n }\n\n buildTypes {\n release {\n // This is necessary to avoid needing the user to define a release build type manually\n }\n }\n}\n\ndef isEasBuildConfigured = false\n\ntasks.whenTaskAdded {\n def debug = gradle.startParameter.taskNames.any { it.toLowerCase().contains('debug') }\n\n if (debug) {\n return\n }\n\n // We only need to configure EAS build once\n if (isEasBuildConfigured) {\n return\n }\n\n isEasBuildConfigured = true;\n\n android.signingConfigs.release {\n def credentialsJson = rootProject.file(\"../credentials.json\");\n\n if (credentialsJson.exists()) {\n if (storeFile && !System.getenv(\"EAS_BUILD\")) {\n println(\"Path to release keystore file is already set, ignoring 'credentials.json'\")\n } else {\n try {\n def credentials = new groovy.json.JsonSlurper().parse(credentialsJson)\n def keystorePath = Paths.get(credentials.android.keystore.keystorePath);\n def storeFilePath = keystorePath.isAbsolute()\n ? keystorePath\n : rootProject.file(\"..\").toPath().resolve(keystorePath);\n\n storeFile storeFilePath.toFile()\n storePassword credentials.android.keystore.keystorePassword\n keyAlias credentials.android.keystore.keyAlias\n if (credentials.android.keystore.containsKey(\"keyPassword\")) {\n keyPassword credentials.android.keystore.keyPassword\n } else {\n // key password is required by Gradle, but PKCS keystores don't have one\n // using the keystore password seems to satisfy the requirement\n keyPassword credentials.android.keystore.keystorePassword\n }\n } catch (Exception e) {\n println(\"An error occurred while parsing 'credentials.json': \" + e.message)\n }\n }\n } else {\n if (storeFile == null) {\n println(\"Couldn't find a 'credentials.json' file, skipping release keystore configuration\")\n }\n }\n }\n\n android.buildTypes.release {\n signingConfig android.signingConfigs.release\n }\n}\n";
export default _default;

View File

@@ -0,0 +1,82 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _default = exports.default = `// Build integration with EAS
import java.nio.file.Paths
android {
signingConfigs {
release {
// This is necessary to avoid needing the user to define a release signing config manually
// If no release config is defined, and this is not present, build for assembleRelease will crash
}
}
buildTypes {
release {
// This is necessary to avoid needing the user to define a release build type manually
}
}
}
def isEasBuildConfigured = false
tasks.whenTaskAdded {
def debug = gradle.startParameter.taskNames.any { it.toLowerCase().contains('debug') }
if (debug) {
return
}
// We only need to configure EAS build once
if (isEasBuildConfigured) {
return
}
isEasBuildConfigured = true;
android.signingConfigs.release {
def credentialsJson = rootProject.file("../credentials.json");
if (credentialsJson.exists()) {
if (storeFile && !System.getenv("EAS_BUILD")) {
println("Path to release keystore file is already set, ignoring 'credentials.json'")
} else {
try {
def credentials = new groovy.json.JsonSlurper().parse(credentialsJson)
def keystorePath = Paths.get(credentials.android.keystore.keystorePath);
def storeFilePath = keystorePath.isAbsolute()
? keystorePath
: rootProject.file("..").toPath().resolve(keystorePath);
storeFile storeFilePath.toFile()
storePassword credentials.android.keystore.keystorePassword
keyAlias credentials.android.keystore.keyAlias
if (credentials.android.keystore.containsKey("keyPassword")) {
keyPassword credentials.android.keystore.keyPassword
} else {
// key password is required by Gradle, but PKCS keystores don't have one
// using the keystore password seems to satisfy the requirement
keyPassword credentials.android.keystore.keystorePassword
}
} catch (Exception e) {
println("An error occurred while parsing 'credentials.json': " + e.message)
}
}
} else {
if (storeFile == null) {
println("Couldn't find a 'credentials.json' file, skipping release keystore configuration")
}
}
}
android.buildTypes.release {
signingConfig android.signingConfigs.release
}
}
`;
//# sourceMappingURL=EasBuildGradleScript.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"EasBuildGradleScript.js","names":[],"sources":["../../src/android/EasBuildGradleScript.ts"],"sourcesContent":["export default `// Build integration with EAS\n\nimport java.nio.file.Paths\n\nandroid {\n signingConfigs {\n release {\n // This is necessary to avoid needing the user to define a release signing config manually\n // If no release config is defined, and this is not present, build for assembleRelease will crash\n }\n }\n\n buildTypes {\n release {\n // This is necessary to avoid needing the user to define a release build type manually\n }\n }\n}\n\ndef isEasBuildConfigured = false\n\ntasks.whenTaskAdded {\n def debug = gradle.startParameter.taskNames.any { it.toLowerCase().contains('debug') }\n\n if (debug) {\n return\n }\n\n // We only need to configure EAS build once\n if (isEasBuildConfigured) {\n return\n }\n\n isEasBuildConfigured = true;\n\n android.signingConfigs.release {\n def credentialsJson = rootProject.file(\"../credentials.json\");\n\n if (credentialsJson.exists()) {\n if (storeFile && !System.getenv(\"EAS_BUILD\")) {\n println(\"Path to release keystore file is already set, ignoring 'credentials.json'\")\n } else {\n try {\n def credentials = new groovy.json.JsonSlurper().parse(credentialsJson)\n def keystorePath = Paths.get(credentials.android.keystore.keystorePath);\n def storeFilePath = keystorePath.isAbsolute()\n ? keystorePath\n : rootProject.file(\"..\").toPath().resolve(keystorePath);\n\n storeFile storeFilePath.toFile()\n storePassword credentials.android.keystore.keystorePassword\n keyAlias credentials.android.keystore.keyAlias\n if (credentials.android.keystore.containsKey(\"keyPassword\")) {\n keyPassword credentials.android.keystore.keyPassword\n } else {\n // key password is required by Gradle, but PKCS keystores don't have one\n // using the keystore password seems to satisfy the requirement\n keyPassword credentials.android.keystore.keystorePassword\n }\n } catch (Exception e) {\n println(\"An error occurred while parsing 'credentials.json': \" + e.message)\n }\n }\n } else {\n if (storeFile == null) {\n println(\"Couldn't find a 'credentials.json' file, skipping release keystore configuration\")\n }\n }\n }\n\n android.buildTypes.release {\n signingConfig android.signingConfigs.release\n }\n}\n`;\n"],"mappings":";;;;;;iCAAe;AACf;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,CAAC","ignoreList":[]}

View File

@@ -0,0 +1,5 @@
import { ExpoConfig } from '@expo/config-types';
import { AndroidManifest } from './Manifest';
export declare const withGoogleMapsApiKey: import("..").ConfigPlugin;
export declare function getGoogleMapsApiKey(config: Pick<ExpoConfig, 'android'>): string | null;
export declare function setGoogleMapsApiKey(config: Pick<ExpoConfig, 'android'>, androidManifest: AndroidManifest): AndroidManifest;

View File

@@ -0,0 +1,46 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.getGoogleMapsApiKey = getGoogleMapsApiKey;
exports.setGoogleMapsApiKey = setGoogleMapsApiKey;
exports.withGoogleMapsApiKey = void 0;
function _Manifest() {
const data = require("./Manifest");
_Manifest = function () {
return data;
};
return data;
}
function _androidPlugins() {
const data = require("../plugins/android-plugins");
_androidPlugins = function () {
return data;
};
return data;
}
const META_API_KEY = 'com.google.android.geo.API_KEY';
const LIB_HTTP = 'org.apache.http.legacy';
const withGoogleMapsApiKey = exports.withGoogleMapsApiKey = (0, _androidPlugins().createAndroidManifestPlugin)(setGoogleMapsApiKey, 'withGoogleMapsApiKey');
function getGoogleMapsApiKey(config) {
return config.android?.config?.googleMaps?.apiKey ?? null;
}
function setGoogleMapsApiKey(config, androidManifest) {
const apiKey = getGoogleMapsApiKey(config);
const mainApplication = (0, _Manifest().getMainApplicationOrThrow)(androidManifest);
if (apiKey) {
// If the item exists, add it back
(0, _Manifest().addMetaDataItemToMainApplication)(mainApplication, META_API_KEY, apiKey);
(0, _Manifest().addUsesLibraryItemToMainApplication)(mainApplication, {
name: LIB_HTTP,
required: false
});
} else {
// Remove any existing item
(0, _Manifest().removeMetaDataItemFromMainApplication)(mainApplication, META_API_KEY);
(0, _Manifest().removeUsesLibraryItemFromMainApplication)(mainApplication, LIB_HTTP);
}
return androidManifest;
}
//# sourceMappingURL=GoogleMapsApiKey.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"GoogleMapsApiKey.js","names":["_Manifest","data","require","_androidPlugins","META_API_KEY","LIB_HTTP","withGoogleMapsApiKey","exports","createAndroidManifestPlugin","setGoogleMapsApiKey","getGoogleMapsApiKey","config","android","googleMaps","apiKey","androidManifest","mainApplication","getMainApplicationOrThrow","addMetaDataItemToMainApplication","addUsesLibraryItemToMainApplication","name","required","removeMetaDataItemFromMainApplication","removeUsesLibraryItemFromMainApplication"],"sources":["../../src/android/GoogleMapsApiKey.ts"],"sourcesContent":["import { ExpoConfig } from '@expo/config-types';\n\nimport {\n addMetaDataItemToMainApplication,\n addUsesLibraryItemToMainApplication,\n AndroidManifest,\n getMainApplicationOrThrow,\n removeMetaDataItemFromMainApplication,\n removeUsesLibraryItemFromMainApplication,\n} from './Manifest';\nimport { createAndroidManifestPlugin } from '../plugins/android-plugins';\n\nconst META_API_KEY = 'com.google.android.geo.API_KEY';\nconst LIB_HTTP = 'org.apache.http.legacy';\n\nexport const withGoogleMapsApiKey = createAndroidManifestPlugin(\n setGoogleMapsApiKey,\n 'withGoogleMapsApiKey'\n);\n\nexport function getGoogleMapsApiKey(config: Pick<ExpoConfig, 'android'>) {\n return config.android?.config?.googleMaps?.apiKey ?? null;\n}\n\nexport function setGoogleMapsApiKey(\n config: Pick<ExpoConfig, 'android'>,\n androidManifest: AndroidManifest\n) {\n const apiKey = getGoogleMapsApiKey(config);\n const mainApplication = getMainApplicationOrThrow(androidManifest);\n\n if (apiKey) {\n // If the item exists, add it back\n addMetaDataItemToMainApplication(mainApplication, META_API_KEY, apiKey);\n addUsesLibraryItemToMainApplication(mainApplication, {\n name: LIB_HTTP,\n required: false,\n });\n } else {\n // Remove any existing item\n removeMetaDataItemFromMainApplication(mainApplication, META_API_KEY);\n removeUsesLibraryItemFromMainApplication(mainApplication, LIB_HTTP);\n }\n\n return androidManifest;\n}\n"],"mappings":";;;;;;;;AAEA,SAAAA,UAAA;EAAA,MAAAC,IAAA,GAAAC,OAAA;EAAAF,SAAA,YAAAA,CAAA;IAAA,OAAAC,IAAA;EAAA;EAAA,OAAAA,IAAA;AAAA;AAQA,SAAAE,gBAAA;EAAA,MAAAF,IAAA,GAAAC,OAAA;EAAAC,eAAA,YAAAA,CAAA;IAAA,OAAAF,IAAA;EAAA;EAAA,OAAAA,IAAA;AAAA;AAEA,MAAMG,YAAY,GAAG,gCAAgC;AACrD,MAAMC,QAAQ,GAAG,wBAAwB;AAElC,MAAMC,oBAAoB,GAAAC,OAAA,CAAAD,oBAAA,GAAG,IAAAE,6CAA2B,EAC7DC,mBAAmB,EACnB,sBACF,CAAC;AAEM,SAASC,mBAAmBA,CAACC,MAAmC,EAAE;EACvE,OAAOA,MAAM,CAACC,OAAO,EAAED,MAAM,EAAEE,UAAU,EAAEC,MAAM,IAAI,IAAI;AAC3D;AAEO,SAASL,mBAAmBA,CACjCE,MAAmC,EACnCI,eAAgC,EAChC;EACA,MAAMD,MAAM,GAAGJ,mBAAmB,CAACC,MAAM,CAAC;EAC1C,MAAMK,eAAe,GAAG,IAAAC,qCAAyB,EAACF,eAAe,CAAC;EAElE,IAAID,MAAM,EAAE;IACV;IACA,IAAAI,4CAAgC,EAACF,eAAe,EAAEZ,YAAY,EAAEU,MAAM,CAAC;IACvE,IAAAK,+CAAmC,EAACH,eAAe,EAAE;MACnDI,IAAI,EAAEf,QAAQ;MACdgB,QAAQ,EAAE;IACZ,CAAC,CAAC;EACJ,CAAC,MAAM;IACL;IACA,IAAAC,iDAAqC,EAACN,eAAe,EAAEZ,YAAY,CAAC;IACpE,IAAAmB,oDAAwC,EAACP,eAAe,EAAEX,QAAQ,CAAC;EACrE;EAEA,OAAOU,eAAe;AACxB","ignoreList":[]}

View File

@@ -0,0 +1,17 @@
import { ExpoConfig } from '@expo/config-types';
import { ConfigPlugin } from '../Plugin.types';
export declare const withClassPath: ConfigPlugin;
export declare const withApplyPlugin: ConfigPlugin;
/**
* Add `google-services.json` to project
*/
export declare const withGoogleServicesFile: ConfigPlugin;
export declare function getGoogleServicesFilePath(config: Pick<ExpoConfig, 'android'>): string | null;
export declare function setGoogleServicesFile(config: Pick<ExpoConfig, 'android'>, projectRoot: string, targetPath?: string): Promise<boolean>;
/**
* Adding the Google Services plugin
* NOTE(brentvatne): string replacement is a fragile approach! we need a
* better solution than this.
*/
export declare function setClassPath(config: Pick<ExpoConfig, 'android'>, buildGradle: string): string;
export declare function applyPlugin(config: Pick<ExpoConfig, 'android'>, appBuildGradle: string): string;

View File

@@ -0,0 +1,138 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.applyPlugin = applyPlugin;
exports.getGoogleServicesFilePath = getGoogleServicesFilePath;
exports.setClassPath = setClassPath;
exports.setGoogleServicesFile = setGoogleServicesFile;
exports.withGoogleServicesFile = exports.withClassPath = exports.withApplyPlugin = void 0;
function _path() {
const data = _interopRequireDefault(require("path"));
_path = function () {
return data;
};
return data;
}
function _androidPlugins() {
const data = require("../plugins/android-plugins");
_androidPlugins = function () {
return data;
};
return data;
}
function _withDangerousMod() {
const data = require("../plugins/withDangerousMod");
_withDangerousMod = function () {
return data;
};
return data;
}
function _fs() {
const data = require("../utils/fs");
_fs = function () {
return data;
};
return data;
}
function _warnings() {
const data = require("../utils/warnings");
_warnings = function () {
return data;
};
return data;
}
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
const DEFAULT_TARGET_PATH = './android/app/google-services.json';
const googleServicesClassPath = 'com.google.gms:google-services';
const googleServicesPlugin = 'com.google.gms.google-services';
// NOTE(brentvatne): This may be annoying to keep up to date...
const googleServicesVersion = '4.4.1';
const withClassPath = config => {
return (0, _androidPlugins().withProjectBuildGradle)(config, config => {
if (config.modResults.language === 'groovy') {
config.modResults.contents = setClassPath(config, config.modResults.contents);
} else {
(0, _warnings().addWarningAndroid)('android.googleServicesFile', `Cannot automatically configure project build.gradle if it's not groovy`);
}
return config;
});
};
exports.withClassPath = withClassPath;
const withApplyPlugin = config => {
return (0, _androidPlugins().withAppBuildGradle)(config, config => {
if (config.modResults.language === 'groovy') {
config.modResults.contents = applyPlugin(config, config.modResults.contents);
} else {
(0, _warnings().addWarningAndroid)('android.googleServicesFile', `Cannot automatically configure app build.gradle if it's not groovy`);
}
return config;
});
};
/**
* Add `google-services.json` to project
*/
exports.withApplyPlugin = withApplyPlugin;
const withGoogleServicesFile = config => {
return (0, _withDangerousMod().withDangerousMod)(config, ['android', async config => {
await setGoogleServicesFile(config, config.modRequest.projectRoot);
return config;
}]);
};
exports.withGoogleServicesFile = withGoogleServicesFile;
function getGoogleServicesFilePath(config) {
return config.android?.googleServicesFile ?? null;
}
async function setGoogleServicesFile(config, projectRoot, targetPath = DEFAULT_TARGET_PATH) {
const partialSourcePath = getGoogleServicesFilePath(config);
if (!partialSourcePath) {
return false;
}
const completeSourcePath = _path().default.resolve(projectRoot, partialSourcePath);
const destinationPath = _path().default.resolve(projectRoot, targetPath);
try {
await (0, _fs().copyFilePathToPathAsync)(completeSourcePath, destinationPath);
} catch (e) {
console.log(e);
throw new Error(`Cannot copy google-services.json from ${completeSourcePath} to ${destinationPath}. Ensure the source and destination paths exist.`);
}
return true;
}
/**
* Adding the Google Services plugin
* NOTE(brentvatne): string replacement is a fragile approach! we need a
* better solution than this.
*/
function setClassPath(config, buildGradle) {
const googleServicesFile = getGoogleServicesFilePath(config);
if (!googleServicesFile) {
return buildGradle;
}
if (buildGradle.includes(googleServicesClassPath)) {
return buildGradle;
}
//
return buildGradle.replace(/dependencies\s?{/, `dependencies {
classpath '${googleServicesClassPath}:${googleServicesVersion}'`);
}
function applyPlugin(config, appBuildGradle) {
const googleServicesFile = getGoogleServicesFilePath(config);
if (!googleServicesFile) {
return appBuildGradle;
}
// Make sure the project does not have the plugin already
const pattern = new RegExp(`apply\\s+plugin:\\s+['"]${googleServicesPlugin}['"]`);
if (appBuildGradle.match(pattern)) {
return appBuildGradle;
}
// Add it to the end of the file
return appBuildGradle + `\napply plugin: '${googleServicesPlugin}'`;
}
//# sourceMappingURL=GoogleServices.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,8 @@
import { Android, ExpoConfig } from '@expo/config-types';
import { AndroidManifest, ManifestIntentFilter } from './Manifest';
type AndroidIntentFilters = NonNullable<Android['intentFilters']>;
export declare const withAndroidIntentFilters: import("..").ConfigPlugin;
export declare function getIntentFilters(config: Pick<ExpoConfig, 'android'>): AndroidIntentFilters;
export declare function setAndroidIntentFilters(config: Pick<ExpoConfig, 'android'>, androidManifest: AndroidManifest): AndroidManifest;
export default function renderIntentFilters(intentFilters: AndroidIntentFilters): ManifestIntentFilter[];
export {};

View File

@@ -0,0 +1,83 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = renderIntentFilters;
exports.getIntentFilters = getIntentFilters;
exports.setAndroidIntentFilters = setAndroidIntentFilters;
exports.withAndroidIntentFilters = void 0;
function _Manifest() {
const data = require("./Manifest");
_Manifest = function () {
return data;
};
return data;
}
function _androidPlugins() {
const data = require("../plugins/android-plugins");
_androidPlugins = function () {
return data;
};
return data;
}
const GENERATED_TAG = 'data-generated';
const withAndroidIntentFilters = exports.withAndroidIntentFilters = (0, _androidPlugins().createAndroidManifestPlugin)(setAndroidIntentFilters, 'withAndroidIntentFilters');
function getIntentFilters(config) {
return config.android?.intentFilters ?? [];
}
function setAndroidIntentFilters(config, androidManifest) {
// Always ensure old tags are removed.
const mainActivity = (0, _Manifest().getMainActivityOrThrow)(androidManifest);
// Remove all generated tags from previous runs...
if (mainActivity['intent-filter']?.length) {
mainActivity['intent-filter'] = mainActivity['intent-filter'].filter(value => value.$?.[GENERATED_TAG] !== 'true');
}
const intentFilters = getIntentFilters(config);
if (!intentFilters.length) {
return androidManifest;
}
mainActivity['intent-filter'] = mainActivity['intent-filter']?.concat(renderIntentFilters(intentFilters));
return androidManifest;
}
function renderIntentFilters(intentFilters) {
return intentFilters.map(intentFilter => {
// <intent-filter>
return {
$: {
'android:autoVerify': intentFilter.autoVerify ? 'true' : undefined,
// Add a custom "generated" tag that we can query later to remove.
[GENERATED_TAG]: 'true'
},
action: [
// <action android:name="android.intent.action.VIEW"/>
{
$: {
'android:name': `android.intent.action.${intentFilter.action}`
}
}],
data: renderIntentFilterData(intentFilter.data),
category: renderIntentFilterCategory(intentFilter.category)
};
});
}
/** Like `<data android:scheme="exp"/>` */
function renderIntentFilterData(data) {
return (Array.isArray(data) ? data : [data]).filter(Boolean).map(datum => ({
$: Object.entries(datum ?? {}).reduce((prev, [key, value]) => ({
...prev,
[`android:${key}`]: value
}), {})
}));
}
/** Like `<category android:name="android.intent.category.DEFAULT"/>` */
function renderIntentFilterCategory(category) {
return (Array.isArray(category) ? category : [category]).filter(Boolean).map(cat => ({
$: {
'android:name': `android.intent.category.${cat}`
}
}));
}
//# sourceMappingURL=IntentFilters.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,8 @@
import { ExpoConfig } from '@expo/config-types';
import { ConfigPlugin } from '../Plugin.types';
import { LocaleJson } from '../utils/locales';
export declare const withLocales: ConfigPlugin;
export declare function getLocales(config: Pick<ExpoConfig, 'locales'>): Record<string, string | LocaleJson> | null;
export declare function setLocalesAsync(config: Pick<ExpoConfig, 'locales'>, { projectRoot }: {
projectRoot: string;
}): Promise<unknown>;

View File

@@ -0,0 +1,78 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.getLocales = getLocales;
exports.setLocalesAsync = setLocalesAsync;
exports.withLocales = void 0;
function _path() {
const data = _interopRequireDefault(require("path"));
_path = function () {
return data;
};
return data;
}
function _() {
const data = require("..");
_ = function () {
return data;
};
return data;
}
function _XML() {
const data = require("../utils/XML");
_XML = function () {
return data;
};
return data;
}
function _locales() {
const data = require("../utils/locales");
_locales = function () {
return data;
};
return data;
}
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
const withLocales = config => {
return (0, _().withDangerousMod)(config, ['android', async config => {
config.modResults = await setLocalesAsync(config, {
projectRoot: config.modRequest.projectRoot
});
return config;
}]);
};
exports.withLocales = withLocales;
function getLocales(config) {
return config.locales ?? null;
}
async function setLocalesAsync(config, {
projectRoot
}) {
const locales = getLocales(config);
if (!locales) {
return config;
}
const {
localesMap
} = await (0, _locales().getResolvedLocalesAsync)(projectRoot, locales, 'android');
for (const [lang, localizationObj] of Object.entries(localesMap)) {
const stringsFilePath = _path().default.join(await _().AndroidConfig.Paths.getResourceFolderAsync(projectRoot), `values-b+${lang.replaceAll('-', '+')}`, 'strings.xml');
(0, _XML().writeXMLAsync)({
path: stringsFilePath,
xml: {
resources: Object.entries(localizationObj).map(([k, v]) => ({
string: {
$: {
name: k
},
_: `"${v}"`
}
}))
}
});
}
return config;
}
//# sourceMappingURL=Locales.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"Locales.js","names":["_path","data","_interopRequireDefault","require","_","_XML","_locales","e","__esModule","default","withLocales","config","withDangerousMod","modResults","setLocalesAsync","projectRoot","modRequest","exports","getLocales","locales","localesMap","getResolvedLocalesAsync","lang","localizationObj","Object","entries","stringsFilePath","path","join","AndroidConfig","Paths","getResourceFolderAsync","replaceAll","writeXMLAsync","xml","resources","map","k","v","string","$","name"],"sources":["../../src/android/Locales.ts"],"sourcesContent":["import { ExpoConfig } from '@expo/config-types';\nimport path from 'path';\n\nimport { AndroidConfig, withDangerousMod } from '..';\nimport { ConfigPlugin } from '../Plugin.types';\nimport { writeXMLAsync } from '../utils/XML';\nimport { getResolvedLocalesAsync, LocaleJson } from '../utils/locales';\n\nexport const withLocales: ConfigPlugin = (config) => {\n return withDangerousMod(config, [\n 'android',\n async (config) => {\n config.modResults = await setLocalesAsync(config, {\n projectRoot: config.modRequest.projectRoot,\n });\n return config;\n },\n ]);\n};\n\nexport function getLocales(\n config: Pick<ExpoConfig, 'locales'>\n): Record<string, string | LocaleJson> | null {\n return config.locales ?? null;\n}\n\nexport async function setLocalesAsync(\n config: Pick<ExpoConfig, 'locales'>,\n { projectRoot }: { projectRoot: string }\n): Promise<unknown> {\n const locales = getLocales(config);\n if (!locales) {\n return config;\n }\n const { localesMap } = await getResolvedLocalesAsync(projectRoot, locales, 'android');\n for (const [lang, localizationObj] of Object.entries(localesMap)) {\n const stringsFilePath = path.join(\n await AndroidConfig.Paths.getResourceFolderAsync(projectRoot),\n `values-b+${lang.replaceAll('-', '+')}`,\n 'strings.xml'\n );\n writeXMLAsync({\n path: stringsFilePath,\n xml: {\n resources: Object.entries(localizationObj).map(([k, v]) => ({\n string: {\n $: {\n name: k,\n },\n _: `\"${v}\"`,\n },\n })),\n },\n });\n }\n\n return config;\n}\n"],"mappings":";;;;;;;;AACA,SAAAA,MAAA;EAAA,MAAAC,IAAA,GAAAC,sBAAA,CAAAC,OAAA;EAAAH,KAAA,YAAAA,CAAA;IAAA,OAAAC,IAAA;EAAA;EAAA,OAAAA,IAAA;AAAA;AAEA,SAAAG,EAAA;EAAA,MAAAH,IAAA,GAAAE,OAAA;EAAAC,CAAA,YAAAA,CAAA;IAAA,OAAAH,IAAA;EAAA;EAAA,OAAAA,IAAA;AAAA;AAEA,SAAAI,KAAA;EAAA,MAAAJ,IAAA,GAAAE,OAAA;EAAAE,IAAA,YAAAA,CAAA;IAAA,OAAAJ,IAAA;EAAA;EAAA,OAAAA,IAAA;AAAA;AACA,SAAAK,SAAA;EAAA,MAAAL,IAAA,GAAAE,OAAA;EAAAG,QAAA,YAAAA,CAAA;IAAA,OAAAL,IAAA;EAAA;EAAA,OAAAA,IAAA;AAAA;AAAuE,SAAAC,uBAAAK,CAAA,WAAAA,CAAA,IAAAA,CAAA,CAAAC,UAAA,GAAAD,CAAA,KAAAE,OAAA,EAAAF,CAAA;AAEhE,MAAMG,WAAyB,GAAIC,MAAM,IAAK;EACnD,OAAO,IAAAC,oBAAgB,EAACD,MAAM,EAAE,CAC9B,SAAS,EACT,MAAOA,MAAM,IAAK;IAChBA,MAAM,CAACE,UAAU,GAAG,MAAMC,eAAe,CAACH,MAAM,EAAE;MAChDI,WAAW,EAAEJ,MAAM,CAACK,UAAU,CAACD;IACjC,CAAC,CAAC;IACF,OAAOJ,MAAM;EACf,CAAC,CACF,CAAC;AACJ,CAAC;AAACM,OAAA,CAAAP,WAAA,GAAAA,WAAA;AAEK,SAASQ,UAAUA,CACxBP,MAAmC,EACS;EAC5C,OAAOA,MAAM,CAACQ,OAAO,IAAI,IAAI;AAC/B;AAEO,eAAeL,eAAeA,CACnCH,MAAmC,EACnC;EAAEI;AAAqC,CAAC,EACtB;EAClB,MAAMI,OAAO,GAAGD,UAAU,CAACP,MAAM,CAAC;EAClC,IAAI,CAACQ,OAAO,EAAE;IACZ,OAAOR,MAAM;EACf;EACA,MAAM;IAAES;EAAW,CAAC,GAAG,MAAM,IAAAC,kCAAuB,EAACN,WAAW,EAAEI,OAAO,EAAE,SAAS,CAAC;EACrF,KAAK,MAAM,CAACG,IAAI,EAAEC,eAAe,CAAC,IAAIC,MAAM,CAACC,OAAO,CAACL,UAAU,CAAC,EAAE;IAChE,MAAMM,eAAe,GAAGC,eAAI,CAACC,IAAI,CAC/B,MAAMC,iBAAa,CAACC,KAAK,CAACC,sBAAsB,CAAChB,WAAW,CAAC,EAC7D,YAAYO,IAAI,CAACU,UAAU,CAAC,GAAG,EAAE,GAAG,CAAC,EAAE,EACvC,aACF,CAAC;IACD,IAAAC,oBAAa,EAAC;MACZN,IAAI,EAAED,eAAe;MACrBQ,GAAG,EAAE;QACHC,SAAS,EAAEX,MAAM,CAACC,OAAO,CAACF,eAAe,CAAC,CAACa,GAAG,CAAC,CAAC,CAACC,CAAC,EAAEC,CAAC,CAAC,MAAM;UAC1DC,MAAM,EAAE;YACNC,CAAC,EAAE;cACDC,IAAI,EAAEJ;YACR,CAAC;YACDjC,CAAC,EAAE,IAAIkC,CAAC;UACV;QACF,CAAC,CAAC;MACJ;IACF,CAAC,CAAC;EACJ;EAEA,OAAO3B,MAAM;AACf","ignoreList":[]}

View File

@@ -0,0 +1,173 @@
export type StringBoolean = 'true' | 'false';
type ManifestMetaDataAttributes = AndroidManifestAttributes & {
'android:value'?: string;
'android:resource'?: string;
};
type AndroidManifestAttributes = {
'android:name': string | 'android.intent.action.VIEW';
'tools:node'?: string | 'remove';
};
type ManifestAction = {
$: AndroidManifestAttributes;
};
type ManifestCategory = {
$: AndroidManifestAttributes;
};
type ManifestData = {
$: {
[key: string]: string | undefined;
'android:host'?: string;
'android:pathPrefix'?: string;
'android:scheme'?: string;
};
};
type ManifestReceiver = {
$: AndroidManifestAttributes & {
'android:exported'?: StringBoolean;
'android:enabled'?: StringBoolean;
};
'intent-filter'?: ManifestIntentFilter[];
};
export type ManifestIntentFilter = {
$?: {
'android:autoVerify'?: StringBoolean;
'data-generated'?: StringBoolean;
};
action?: ManifestAction[];
data?: ManifestData[];
category?: ManifestCategory[];
};
export type ManifestActivityAlias = {
$?: {
'android:name': string;
'android:enabled'?: StringBoolean;
'android:exported'?: StringBoolean;
'android:label'?: string;
'android:permission'?: string;
'android:icon'?: string;
'android:targetActivity': string;
};
'intent-filter'?: ManifestIntentFilter[];
'meta-data'?: ManifestMetaData[];
};
export type ManifestMetaData = {
$: ManifestMetaDataAttributes;
};
type ManifestServiceAttributes = AndroidManifestAttributes & {
'android:enabled'?: StringBoolean;
'android:exported'?: StringBoolean;
'android:permission'?: string;
'android:foregroundServiceType'?: string;
};
type ManifestService = {
$: ManifestServiceAttributes;
'intent-filter'?: ManifestIntentFilter[];
};
type ManifestApplicationAttributes = {
'android:name': string | '.MainApplication';
'android:icon'?: string;
'android:roundIcon'?: string;
'android:label'?: string;
'android:allowBackup'?: StringBoolean;
'android:largeHeap'?: StringBoolean;
'android:requestLegacyExternalStorage'?: StringBoolean;
'android:supportsPictureInPicture'?: StringBoolean;
'android:usesCleartextTraffic'?: StringBoolean;
'android:enableOnBackInvokedCallback'?: StringBoolean;
[key: string]: string | undefined;
};
export type ManifestActivity = {
$: ManifestApplicationAttributes & {
'android:exported'?: StringBoolean;
'android:launchMode'?: string;
'android:theme'?: string;
'android:windowSoftInputMode'?: string | 'stateUnspecified' | 'stateUnchanged' | 'stateHidden' | 'stateAlwaysHidden' | 'stateVisible' | 'stateAlwaysVisible' | 'adjustUnspecified' | 'adjustResize' | 'adjustPan';
[key: string]: string | undefined;
};
'intent-filter'?: ManifestIntentFilter[];
};
export type ManifestUsesLibrary = {
$: AndroidManifestAttributes & {
'android:required'?: StringBoolean;
};
};
export type ManifestApplication = {
$: ManifestApplicationAttributes;
activity?: ManifestActivity[];
service?: ManifestService[];
receiver?: ManifestReceiver[];
'meta-data'?: ManifestMetaData[];
'uses-library'?: ManifestUsesLibrary[];
'activity-alias'?: ManifestActivityAlias[];
};
type ManifestPermission = {
$: AndroidManifestAttributes & {
'android:protectionLevel'?: string | 'signature';
};
};
export type ManifestUsesPermission = {
$: AndroidManifestAttributes;
};
type ManifestUsesFeature = {
$: AndroidManifestAttributes & {
'android:glEsVersion'?: string;
'android:required': StringBoolean;
};
};
export type AndroidManifest = {
manifest: {
$: {
'xmlns:android': string;
'xmlns:tools'?: string;
package?: string;
[key: string]: string | undefined;
};
permission?: ManifestPermission[];
'uses-permission'?: ManifestUsesPermission[];
'uses-permission-sdk-23'?: ManifestUsesPermission[];
'uses-feature'?: ManifestUsesFeature[];
queries: ManifestQuery[];
application?: ManifestApplication[];
};
};
type ManifestQueryIntent = Omit<ManifestIntentFilter, '$'>;
export type ManifestQuery = {
package?: {
$: {
'android:name': string;
};
}[];
intent?: ManifestQueryIntent[];
provider?: {
$: {
'android:authorities': string;
};
}[];
};
export declare function writeAndroidManifestAsync(manifestPath: string, androidManifest: AndroidManifest): Promise<void>;
export declare function readAndroidManifestAsync(manifestPath: string): Promise<AndroidManifest>;
/** Returns the `manifest.application` tag ending in `.MainApplication` */
export declare function getMainApplication(androidManifest: AndroidManifest): ManifestApplication | null;
export declare function getMainApplicationOrThrow(androidManifest: AndroidManifest): ManifestApplication;
export declare function getMainActivityOrThrow(androidManifest: AndroidManifest): ManifestActivity;
export declare function getRunnableActivity(androidManifest: AndroidManifest): ManifestActivity | null;
export declare function getMainActivity(androidManifest: AndroidManifest): ManifestActivity | null;
export declare function addMetaDataItemToMainApplication(mainApplication: ManifestApplication, itemName: string, itemValue: string, itemType?: 'resource' | 'value'): ManifestApplication;
export declare function removeMetaDataItemFromMainApplication(mainApplication: any, itemName: string): any;
export declare function findMetaDataItem(mainApplication: any, itemName: string): number;
export declare function findUsesLibraryItem(mainApplication: any, itemName: string): number;
export declare function getMainApplicationMetaDataValue(androidManifest: AndroidManifest, name: string): string | null;
export declare function addUsesLibraryItemToMainApplication(mainApplication: ManifestApplication, item: {
name: string;
required?: boolean;
}): ManifestApplication;
export declare function removeUsesLibraryItemFromMainApplication(mainApplication: ManifestApplication, itemName: string): ManifestApplication;
export declare function prefixAndroidKeys<T extends Record<string, any> = Record<string, string>>(head: T): Record<string, any>;
/**
* Ensure the `tools:*` namespace is available in the manifest.
*
* @param manifest AndroidManifest.xml
* @returns manifest with the `tools:*` namespace available
*/
export declare function ensureToolsAvailable(manifest: AndroidManifest): AndroidManifest;
export {};

View File

@@ -0,0 +1,250 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.addMetaDataItemToMainApplication = addMetaDataItemToMainApplication;
exports.addUsesLibraryItemToMainApplication = addUsesLibraryItemToMainApplication;
exports.ensureToolsAvailable = ensureToolsAvailable;
exports.findMetaDataItem = findMetaDataItem;
exports.findUsesLibraryItem = findUsesLibraryItem;
exports.getMainActivity = getMainActivity;
exports.getMainActivityOrThrow = getMainActivityOrThrow;
exports.getMainApplication = getMainApplication;
exports.getMainApplicationMetaDataValue = getMainApplicationMetaDataValue;
exports.getMainApplicationOrThrow = getMainApplicationOrThrow;
exports.getRunnableActivity = getRunnableActivity;
exports.prefixAndroidKeys = prefixAndroidKeys;
exports.readAndroidManifestAsync = readAndroidManifestAsync;
exports.removeMetaDataItemFromMainApplication = removeMetaDataItemFromMainApplication;
exports.removeUsesLibraryItemFromMainApplication = removeUsesLibraryItemFromMainApplication;
exports.writeAndroidManifestAsync = writeAndroidManifestAsync;
function _assert() {
const data = _interopRequireDefault(require("assert"));
_assert = 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 XML() {
const data = _interopRequireWildcard(require("../utils/XML"));
XML = function () {
return data;
};
return data;
}
function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
// https://developer.android.com/guide/topics/manifest/activity-alias-element
async function writeAndroidManifestAsync(manifestPath, androidManifest) {
const manifestXml = XML().format(androidManifest);
await _fs().default.promises.mkdir(_path().default.dirname(manifestPath), {
recursive: true
});
await _fs().default.promises.writeFile(manifestPath, manifestXml);
}
async function readAndroidManifestAsync(manifestPath) {
const xml = await XML().readXMLAsync({
path: manifestPath
});
if (!isManifest(xml)) {
throw new Error('Invalid manifest found at: ' + manifestPath);
}
return xml;
}
function isManifest(xml) {
// TODO: Maybe more validation
return !!xml.manifest;
}
/** Returns the `manifest.application` tag ending in `.MainApplication` */
function getMainApplication(androidManifest) {
return androidManifest?.manifest?.application?.filter(e => e?.$?.['android:name'].endsWith('.MainApplication'))[0] ?? null;
}
function getMainApplicationOrThrow(androidManifest) {
const mainApplication = getMainApplication(androidManifest);
(0, _assert().default)(mainApplication, 'AndroidManifest.xml is missing the required MainApplication element');
return mainApplication;
}
function getMainActivityOrThrow(androidManifest) {
const mainActivity = getMainActivity(androidManifest);
(0, _assert().default)(mainActivity, 'AndroidManifest.xml is missing the required MainActivity element');
return mainActivity;
}
function getRunnableActivity(androidManifest) {
const firstApplication = androidManifest?.manifest?.application?.[0] ?? getMainApplication(androidManifest);
if (!firstApplication) {
return null;
}
// Get enabled activities
const enabledActivities = firstApplication.activity?.filter?.(e => e.$['android:enabled'] !== 'false' && e.$['android:enabled'] !== false);
if (!enabledActivities) {
return null;
}
const isIntentFilterRunnable = intentFilter => {
return !!intentFilter.action?.some(action => action.$['android:name'] === 'android.intent.action.MAIN') && !!intentFilter.category?.some(category => category.$['android:name'] === 'android.intent.category.LAUNCHER');
};
// Get the activity that has a runnable intent-filter
for (const activity of enabledActivities) {
if (Array.isArray(activity['intent-filter'])) {
for (const intentFilter of activity['intent-filter']) {
if (isIntentFilterRunnable(intentFilter)) {
return activity;
}
}
}
}
const enabledActivityNames = enabledActivities.map(e => e.$['android:name']);
// If no runnable activity is found, check for matching activity-alias that may be runnable
const aliases = (firstApplication['activity-alias'] ?? []).filter(
// https://developer.android.com/guide/topics/manifest/activity-alias-element
e => e.$['android:enabled'] !== 'false' && enabledActivityNames.includes(e.$['android:targetActivity']));
if (aliases.length) {
for (const alias of aliases) {
if (Array.isArray(alias['intent-filter'])) {
for (const intentFilter of alias['intent-filter']) {
if (isIntentFilterRunnable(intentFilter)) {
const matchingActivity = enabledActivities.find(e => e.$['android:name'] === alias.$['android:targetActivity']);
if (matchingActivity) {
return matchingActivity;
}
}
}
}
}
}
return null;
}
function getMainActivity(androidManifest) {
const mainActivity = androidManifest?.manifest?.application?.[0]?.activity?.filter?.(e => e.$['android:name'] === '.MainActivity');
return mainActivity?.[0] ?? null;
}
function addMetaDataItemToMainApplication(mainApplication, itemName, itemValue, itemType = 'value') {
let existingMetaDataItem;
const newItem = {
$: prefixAndroidKeys({
name: itemName,
[itemType]: itemValue
})
};
if (mainApplication['meta-data']) {
existingMetaDataItem = mainApplication['meta-data'].filter(e => e.$['android:name'] === itemName);
if (existingMetaDataItem.length) {
existingMetaDataItem[0].$[`android:${itemType}`] = itemValue;
} else {
mainApplication['meta-data'].push(newItem);
}
} else {
mainApplication['meta-data'] = [newItem];
}
return mainApplication;
}
function removeMetaDataItemFromMainApplication(mainApplication, itemName) {
const index = findMetaDataItem(mainApplication, itemName);
if (mainApplication?.['meta-data'] && index > -1) {
mainApplication['meta-data'].splice(index, 1);
}
return mainApplication;
}
function findApplicationSubItem(mainApplication, category, itemName) {
const parent = mainApplication[category];
if (Array.isArray(parent)) {
const index = parent.findIndex(e => e.$['android:name'] === itemName);
return index;
}
return -1;
}
function findMetaDataItem(mainApplication, itemName) {
return findApplicationSubItem(mainApplication, 'meta-data', itemName);
}
function findUsesLibraryItem(mainApplication, itemName) {
return findApplicationSubItem(mainApplication, 'uses-library', itemName);
}
function getMainApplicationMetaDataValue(androidManifest, name) {
const mainApplication = getMainApplication(androidManifest);
if (mainApplication?.hasOwnProperty('meta-data')) {
const item = mainApplication?.['meta-data']?.find(e => e.$['android:name'] === name);
return item?.$['android:value'] ?? null;
}
return null;
}
function addUsesLibraryItemToMainApplication(mainApplication, item) {
let existingMetaDataItem;
const newItem = {
$: prefixAndroidKeys(item)
};
if (mainApplication['uses-library']) {
existingMetaDataItem = mainApplication['uses-library'].filter(e => e.$['android:name'] === item.name);
if (existingMetaDataItem.length) {
existingMetaDataItem[0].$ = newItem.$;
} else {
mainApplication['uses-library'].push(newItem);
}
} else {
mainApplication['uses-library'] = [newItem];
}
return mainApplication;
}
function removeUsesLibraryItemFromMainApplication(mainApplication, itemName) {
const index = findUsesLibraryItem(mainApplication, itemName);
if (mainApplication?.['uses-library'] && index > -1) {
mainApplication['uses-library'].splice(index, 1);
}
return mainApplication;
}
function prefixAndroidKeys(head) {
// prefix all keys with `android:`
return Object.entries(head).reduce((prev, [key, curr]) => ({
...prev,
[`android:${key}`]: curr
}), {});
}
/**
* Ensure the `tools:*` namespace is available in the manifest.
*
* @param manifest AndroidManifest.xml
* @returns manifest with the `tools:*` namespace available
*/
function ensureToolsAvailable(manifest) {
return ensureManifestHasNamespace(manifest, {
namespace: 'xmlns:tools',
url: 'http://schemas.android.com/tools'
});
}
/**
* Ensure a particular namespace is available in the manifest.
*
* @param manifest `AndroidManifest.xml`
* @returns manifest with the provided namespace available
*/
function ensureManifestHasNamespace(manifest, {
namespace,
url
}) {
if (manifest?.manifest?.$?.[namespace]) {
return manifest;
}
manifest.manifest.$[namespace] = url;
return manifest;
}
//# sourceMappingURL=Manifest.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,20 @@
import { ExpoConfig } from '@expo/config-types';
import { ConfigPlugin } from '../Plugin.types';
/**
* Sanitize a name, this should be used for files and gradle names.
* - `[/, \, :, <, >, ", ?, *, |]` are not allowed
* https://docs.gradle.org/4.2/release-notes.html#path-separator-characters-in-names-are-deprecated
*
* @param name
*/
export declare function sanitizeNameForGradle(name: string): string;
export declare const withName: ConfigPlugin;
export declare const withNameSettingsGradle: ConfigPlugin;
export declare function getName(config: Pick<ExpoConfig, 'name'>): string | null;
/**
* Regex a name change -- fragile.
*
* @param config
* @param settingsGradle
*/
export declare function applyNameSettingsGradle(config: Pick<ExpoConfig, 'name'>, settingsGradle: string): string;

View File

@@ -0,0 +1,91 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.applyNameSettingsGradle = applyNameSettingsGradle;
exports.getName = getName;
exports.sanitizeNameForGradle = sanitizeNameForGradle;
exports.withNameSettingsGradle = exports.withName = void 0;
function _Resources() {
const data = require("./Resources");
_Resources = function () {
return data;
};
return data;
}
function _Strings() {
const data = require("./Strings");
_Strings = function () {
return data;
};
return data;
}
function _androidPlugins() {
const data = require("../plugins/android-plugins");
_androidPlugins = function () {
return data;
};
return data;
}
function _warnings() {
const data = require("../utils/warnings");
_warnings = function () {
return data;
};
return data;
}
/**
* Sanitize a name, this should be used for files and gradle names.
* - `[/, \, :, <, >, ", ?, *, |]` are not allowed
* https://docs.gradle.org/4.2/release-notes.html#path-separator-characters-in-names-are-deprecated
*
* @param name
*/
function sanitizeNameForGradle(name) {
// Remove escape characters which are valid in XML names but not in gradle.
name = name.replace(/[\n\r\t]/g, '');
// Gradle disallows these:
// The project name 'My-Special 😃 Co/ol_Project' must not contain any of the following characters: [/, \, :, <, >, ", ?, *, |]. Set the 'rootProject.name' or adjust the 'include' statement (see https://docs.gradle.org/6.2/dsl/org.gradle.api.initialization.Settings.html#org.gradle.api.initialization.Settings:include(java.lang.String[]) for more details).
return name.replace(/(\/|\\|:|<|>|"|\?|\*|\|)/g, '');
}
const withName = exports.withName = (0, _androidPlugins().createStringsXmlPlugin)(applyNameFromConfig, 'withName');
const withNameSettingsGradle = config => {
return (0, _androidPlugins().withSettingsGradle)(config, config => {
if (config.modResults.language === 'groovy') {
config.modResults.contents = applyNameSettingsGradle(config, config.modResults.contents);
} else {
(0, _warnings().addWarningAndroid)('name', `Cannot automatically configure settings.gradle if it's not groovy`);
}
return config;
});
};
exports.withNameSettingsGradle = withNameSettingsGradle;
function getName(config) {
return typeof config.name === 'string' ? config.name : null;
}
function applyNameFromConfig(config, stringsJSON) {
const name = getName(config);
if (name) {
return (0, _Strings().setStringItem)([(0, _Resources().buildResourceItem)({
name: 'app_name',
value: name
})], stringsJSON);
}
return (0, _Strings().removeStringItem)('app_name', stringsJSON);
}
/**
* Regex a name change -- fragile.
*
* @param config
* @param settingsGradle
*/
function applyNameSettingsGradle(config, settingsGradle) {
const name = sanitizeNameForGradle(getName(config) ?? '');
// Select rootProject.name = '***' and replace the contents between the quotes.
return settingsGradle.replace(/rootProject.name\s?=\s?(["'])(?:(?=(\\?))\2.)*?\1/g, `rootProject.name = '${name.replace(/'/g, "\\'")}'`);
}
//# sourceMappingURL=Name.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,6 @@
import { ExpoConfig } from '@expo/config-types';
import { AndroidManifest } from './Manifest';
export declare const SCREEN_ORIENTATION_ATTRIBUTE = "android:screenOrientation";
export declare const withOrientation: import("..").ConfigPlugin;
export declare function getOrientation(config: Pick<ExpoConfig, 'orientation'>): "default" | "portrait" | "landscape" | null;
export declare function setAndroidOrientation(config: Pick<ExpoConfig, 'orientation'>, androidManifest: AndroidManifest): AndroidManifest;

View File

@@ -0,0 +1,39 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.SCREEN_ORIENTATION_ATTRIBUTE = void 0;
exports.getOrientation = getOrientation;
exports.setAndroidOrientation = setAndroidOrientation;
exports.withOrientation = void 0;
function _Manifest() {
const data = require("./Manifest");
_Manifest = function () {
return data;
};
return data;
}
function _androidPlugins() {
const data = require("../plugins/android-plugins");
_androidPlugins = function () {
return data;
};
return data;
}
const SCREEN_ORIENTATION_ATTRIBUTE = exports.SCREEN_ORIENTATION_ATTRIBUTE = 'android:screenOrientation';
const withOrientation = exports.withOrientation = (0, _androidPlugins().createAndroidManifestPlugin)(setAndroidOrientation, 'withOrientation');
function getOrientation(config) {
return typeof config.orientation === 'string' ? config.orientation : null;
}
function setAndroidOrientation(config, androidManifest) {
const orientation = getOrientation(config);
// TODO: Remove this if we decide to remove any orientation configuration when not specified
if (!orientation) {
return androidManifest;
}
const mainActivity = (0, _Manifest().getMainActivityOrThrow)(androidManifest);
mainActivity.$[SCREEN_ORIENTATION_ATTRIBUTE] = orientation !== 'default' ? orientation : 'unspecified';
return androidManifest;
}
//# sourceMappingURL=Orientation.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"Orientation.js","names":["_Manifest","data","require","_androidPlugins","SCREEN_ORIENTATION_ATTRIBUTE","exports","withOrientation","createAndroidManifestPlugin","setAndroidOrientation","getOrientation","config","orientation","androidManifest","mainActivity","getMainActivityOrThrow","$"],"sources":["../../src/android/Orientation.ts"],"sourcesContent":["import { ExpoConfig } from '@expo/config-types';\n\nimport { AndroidManifest, getMainActivityOrThrow } from './Manifest';\nimport { createAndroidManifestPlugin } from '../plugins/android-plugins';\n\nexport const SCREEN_ORIENTATION_ATTRIBUTE = 'android:screenOrientation';\n\nexport const withOrientation = createAndroidManifestPlugin(\n setAndroidOrientation,\n 'withOrientation'\n);\n\nexport function getOrientation(config: Pick<ExpoConfig, 'orientation'>) {\n return typeof config.orientation === 'string' ? config.orientation : null;\n}\n\nexport function setAndroidOrientation(\n config: Pick<ExpoConfig, 'orientation'>,\n androidManifest: AndroidManifest\n) {\n const orientation = getOrientation(config);\n // TODO: Remove this if we decide to remove any orientation configuration when not specified\n if (!orientation) {\n return androidManifest;\n }\n\n const mainActivity = getMainActivityOrThrow(androidManifest);\n\n mainActivity.$[SCREEN_ORIENTATION_ATTRIBUTE] =\n orientation !== 'default' ? orientation : 'unspecified';\n\n return androidManifest;\n}\n"],"mappings":";;;;;;;;;AAEA,SAAAA,UAAA;EAAA,MAAAC,IAAA,GAAAC,OAAA;EAAAF,SAAA,YAAAA,CAAA;IAAA,OAAAC,IAAA;EAAA;EAAA,OAAAA,IAAA;AAAA;AACA,SAAAE,gBAAA;EAAA,MAAAF,IAAA,GAAAC,OAAA;EAAAC,eAAA,YAAAA,CAAA;IAAA,OAAAF,IAAA;EAAA;EAAA,OAAAA,IAAA;AAAA;AAEO,MAAMG,4BAA4B,GAAAC,OAAA,CAAAD,4BAAA,GAAG,2BAA2B;AAEhE,MAAME,eAAe,GAAAD,OAAA,CAAAC,eAAA,GAAG,IAAAC,6CAA2B,EACxDC,qBAAqB,EACrB,iBACF,CAAC;AAEM,SAASC,cAAcA,CAACC,MAAuC,EAAE;EACtE,OAAO,OAAOA,MAAM,CAACC,WAAW,KAAK,QAAQ,GAAGD,MAAM,CAACC,WAAW,GAAG,IAAI;AAC3E;AAEO,SAASH,qBAAqBA,CACnCE,MAAuC,EACvCE,eAAgC,EAChC;EACA,MAAMD,WAAW,GAAGF,cAAc,CAACC,MAAM,CAAC;EAC1C;EACA,IAAI,CAACC,WAAW,EAAE;IAChB,OAAOC,eAAe;EACxB;EAEA,MAAMC,YAAY,GAAG,IAAAC,kCAAsB,EAACF,eAAe,CAAC;EAE5DC,YAAY,CAACE,CAAC,CAACX,4BAA4B,CAAC,GAC1CO,WAAW,KAAK,SAAS,GAAGA,WAAW,GAAG,aAAa;EAEzD,OAAOC,eAAe;AACxB","ignoreList":[]}

View File

@@ -0,0 +1,23 @@
import { ExpoConfig } from '@expo/config-types';
import { ConfigPlugin } from '../Plugin.types';
export declare const withPackageGradle: ConfigPlugin;
export declare const withPackageRefactor: ConfigPlugin;
export declare function getPackage(config: Pick<ExpoConfig, 'android'>): string | null;
export declare function renamePackageOnDisk(config: Pick<ExpoConfig, 'android'>, projectRoot: string): Promise<void>;
export declare function renameJniOnDiskForType({ projectRoot, type, packageName, }: {
projectRoot: string;
type: string;
packageName: string;
}): Promise<void>;
export declare function renamePackageOnDiskForType({ projectRoot, type, packageName, }: {
projectRoot: string;
type: string;
packageName: string;
}): Promise<void>;
export declare function setPackageInBuildGradle(config: Pick<ExpoConfig, 'android'>, buildGradle: string): string;
export declare function getApplicationIdAsync(projectRoot: string): Promise<string | null>;
/**
* Make a package name safe to use in a kotlin file,
* e.g. is.pvin.hello -> `is`.pvin.hello
*/
export declare function kotlinSanitized(packageName: string): string;

View File

@@ -0,0 +1,323 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.getApplicationIdAsync = getApplicationIdAsync;
exports.getPackage = getPackage;
exports.kotlinSanitized = kotlinSanitized;
exports.renameJniOnDiskForType = renameJniOnDiskForType;
exports.renamePackageOnDisk = renamePackageOnDisk;
exports.renamePackageOnDiskForType = renamePackageOnDiskForType;
exports.setPackageInBuildGradle = setPackageInBuildGradle;
exports.withPackageRefactor = exports.withPackageGradle = void 0;
function _debug() {
const data = _interopRequireDefault(require("debug"));
_debug = function () {
return data;
};
return data;
}
function _fs() {
const data = _interopRequireDefault(require("fs"));
_fs = function () {
return data;
};
return data;
}
function _glob() {
const data = require("glob");
_glob = function () {
return data;
};
return data;
}
function _path() {
const data = _interopRequireDefault(require("path"));
_path = function () {
return data;
};
return data;
}
function _Paths() {
const data = require("./Paths");
_Paths = function () {
return data;
};
return data;
}
function _androidPlugins() {
const data = require("../plugins/android-plugins");
_androidPlugins = function () {
return data;
};
return data;
}
function _withDangerousMod() {
const data = require("../plugins/withDangerousMod");
_withDangerousMod = function () {
return data;
};
return data;
}
function _modules() {
const data = require("../utils/modules");
_modules = function () {
return data;
};
return data;
}
function _warnings() {
const data = require("../utils/warnings");
_warnings = function () {
return data;
};
return data;
}
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
const debug = (0, _debug().default)('expo:config-plugins:android:package');
const withPackageGradle = config => {
return (0, _androidPlugins().withAppBuildGradle)(config, config => {
if (config.modResults.language === 'groovy') {
config.modResults.contents = setPackageInBuildGradle(config, config.modResults.contents);
} else {
(0, _warnings().addWarningAndroid)('android.package', `Cannot automatically configure app build.gradle if it's not groovy`);
}
return config;
});
};
exports.withPackageGradle = withPackageGradle;
const withPackageRefactor = config => {
return (0, _withDangerousMod().withDangerousMod)(config, ['android', async config => {
await renamePackageOnDisk(config, config.modRequest.projectRoot);
return config;
}]);
};
exports.withPackageRefactor = withPackageRefactor;
function getPackage(config) {
return config.android?.package ?? null;
}
function getPackageRoot(projectRoot, type) {
return _path().default.join(projectRoot, 'android', 'app', 'src', type, 'java');
}
function getCurrentPackageName(projectRoot, packageRoot) {
const mainApplication = (0, _Paths().getProjectFilePath)(projectRoot, 'MainApplication');
const packagePath = _path().default.dirname(mainApplication);
const packagePathParts = _path().default.relative(packageRoot, packagePath).split(_path().default.sep).filter(Boolean);
return packagePathParts.join('.');
}
function getCurrentPackageForProjectFile(projectRoot, packageRoot, fileName, type) {
const filePath = (0, _glob().globSync)(_path().default.join(projectRoot, `android/app/src/${type}/java/**/${fileName}.@(java|kt)`))[0];
if (!filePath) {
return null;
}
const packagePath = _path().default.dirname(filePath);
const packagePathParts = _path().default.relative(packageRoot, packagePath).split(_path().default.sep).filter(Boolean);
return packagePathParts.join('.');
}
function getCurrentPackageNameForType(projectRoot, type) {
const packageRoot = getPackageRoot(projectRoot, type);
if (type === 'main') {
return getCurrentPackageName(projectRoot, packageRoot);
}
// debug, etc..
return getCurrentPackageForProjectFile(projectRoot, packageRoot, '*', type);
}
// NOTE(brentvatne): this assumes that our MainApplication.java file is in the root of the package
// this makes sense for standard react-native projects but may not apply in customized projects, so if
// we want this to be runnable in any app we need to handle other possibilities
async function renamePackageOnDisk(config, projectRoot) {
const newPackageName = getPackage(config);
if (newPackageName === null) {
return;
}
for (const type of ['debug', 'main', 'release']) {
await renameJniOnDiskForType({
projectRoot,
type,
packageName: newPackageName
});
await renamePackageOnDiskForType({
projectRoot,
type,
packageName: newPackageName
});
}
}
async function renameJniOnDiskForType({
projectRoot,
type,
packageName
}) {
if (!packageName) {
return;
}
const currentPackageName = getCurrentPackageNameForType(projectRoot, type);
if (!currentPackageName || !packageName || currentPackageName === packageName) {
return;
}
const jniRoot = _path().default.join(projectRoot, 'android', 'app', 'src', type, 'jni');
const filesToUpdate = [...(0, _glob().globSync)('**/*', {
cwd: jniRoot,
absolute: true
})];
// Replace all occurrences of the path in the project
filesToUpdate.forEach(filepath => {
try {
if (_fs().default.lstatSync(filepath).isFile() && ['.h', '.cpp'].includes(_path().default.extname(filepath))) {
let contents = _fs().default.readFileSync(filepath).toString();
contents = contents.replace(new RegExp(transformJavaClassDescriptor(currentPackageName).replace(/\//g, '\\/'), 'g'), transformJavaClassDescriptor(packageName));
_fs().default.writeFileSync(filepath, contents);
}
} catch {
debug(`Error updating "${filepath}" for type "${type}"`);
}
});
}
async function renamePackageOnDiskForType({
projectRoot,
type,
packageName
}) {
if (!packageName) {
return;
}
const currentPackageName = getCurrentPackageNameForType(projectRoot, type);
debug(`Found package "${currentPackageName}" for type "${type}"`);
if (!currentPackageName || currentPackageName === packageName) {
return;
}
debug(`Refactor "${currentPackageName}" to "${packageName}" for type "${type}"`);
const packageRoot = getPackageRoot(projectRoot, type);
// Set up our paths
if (!(await (0, _modules().directoryExistsAsync)(packageRoot))) {
debug(`- skipping refactor of missing directory: ${packageRoot}`);
return;
}
const currentPackagePath = _path().default.join(packageRoot, ...currentPackageName.split('.'));
const newPackagePath = _path().default.join(packageRoot, ...packageName.split('.'));
// Create the new directory
_fs().default.mkdirSync(newPackagePath, {
recursive: true
});
// Move everything from the old directory over
(0, _glob().globSync)('**/*', {
cwd: currentPackagePath
}).forEach(relativePath => {
const filepath = _path().default.join(currentPackagePath, relativePath);
if (_fs().default.lstatSync(filepath).isFile()) {
moveFileSync(filepath, _path().default.join(newPackagePath, relativePath));
} else {
_fs().default.mkdirSync(filepath, {
recursive: true
});
}
});
// Remove the old directory recursively from com/old/package to com/old and com,
// as long as the directories are empty
const oldPathParts = currentPackageName.split('.');
while (oldPathParts.length) {
const pathToCheck = _path().default.join(packageRoot, ...oldPathParts);
try {
const files = _fs().default.readdirSync(pathToCheck);
if (files.length === 0) {
_fs().default.rmdirSync(pathToCheck);
}
} finally {
oldPathParts.pop();
}
}
const filesToUpdate = [...(0, _glob().globSync)('**/*', {
cwd: newPackagePath,
absolute: true
})];
// Only update the BUCK file to match the main package name
if (type === 'main') {
// NOTE(EvanBacon): We dropped this file in SDK 48 but other templates may still use it.
filesToUpdate.push(_path().default.join(projectRoot, 'android', 'app', 'BUCK'));
}
const kotlinSanitizedPackageName = kotlinSanitized(packageName);
// Replace all occurrences of the path in the project
filesToUpdate.forEach(filepath => {
try {
if (_fs().default.lstatSync(filepath).isFile()) {
let contents = _fs().default.readFileSync(filepath).toString();
if (_path().default.extname(filepath) === '.kt') {
contents = replacePackageName(contents, currentPackageName, kotlinSanitizedPackageName);
} else {
contents = replacePackageName(contents, currentPackageName, packageName);
}
if (['.h', '.cpp'].includes(_path().default.extname(filepath))) {
contents = contents.replace(new RegExp(transformJavaClassDescriptor(currentPackageName).replace(/\//g, '\\'), 'g'), transformJavaClassDescriptor(packageName));
}
_fs().default.writeFileSync(filepath, contents);
}
} catch {
debug(`Error updating "${filepath}" for type "${type}"`);
}
});
}
function moveFileSync(src, dest) {
_fs().default.mkdirSync(_path().default.dirname(dest), {
recursive: true
});
_fs().default.renameSync(src, dest);
}
function setPackageInBuildGradle(config, buildGradle) {
const packageName = getPackage(config);
if (packageName === null) {
return buildGradle;
}
const pattern = new RegExp(`(applicationId|namespace) ['"].*['"]`, 'g');
return buildGradle.replace(pattern, `$1 '${packageName}'`);
}
async function getApplicationIdAsync(projectRoot) {
const buildGradlePath = (0, _Paths().getAppBuildGradleFilePath)(projectRoot);
if (!_fs().default.existsSync(buildGradlePath)) {
return null;
}
const buildGradle = await _fs().default.promises.readFile(buildGradlePath, 'utf8');
const matchResult = buildGradle.match(/applicationId ['"](.*)['"]/);
// TODO add fallback for legacy cases to read from AndroidManifest.xml
return matchResult?.[1] ?? null;
}
/**
* Replace the package name with the new package name, in the given source.
* This has to be limited to avoid accidentally replacing imports when the old package name overlaps.
*/
function replacePackageName(content, oldName, newName) {
const oldNameEscaped = oldName.replace(/\./g, '\\.');
return content
// Replace any quoted instances "com.old" -> "com.new"
.replace(new RegExp(`"${oldNameEscaped}"`, 'g'), `"${newName}"`)
// Replace special non-quoted instances, only when prefixed by package or namespace
.replace(new RegExp(`(package|namespace)(\\s+)${oldNameEscaped}`, 'g'), `$1$2${newName}`)
// Replace special import instances, without overlapping with other imports (trailing `.` to close it off)
.replace(new RegExp(`(import\\s+)${oldNameEscaped}\\.`, 'g'), `$1${newName}.`);
}
/**
* Transform a java package name to java class descriptor,
* e.g. `com.helloworld` -> `Lcom/helloworld`.
*/
function transformJavaClassDescriptor(packageName) {
return `L${packageName.replace(/\./g, '/')}`;
}
/**
* Make a package name safe to use in a kotlin file,
* e.g. is.pvin.hello -> `is`.pvin.hello
*/
function kotlinSanitized(packageName) {
const stringsToWrap = ['is', 'in', 'as', 'fun'];
const parts = packageName.split('.');
const cleanParts = parts.map(part => stringsToWrap.includes(part) ? '`' + part + '`' : part);
const cleanName = cleanParts.join('.');
return cleanName;
}
//# sourceMappingURL=Package.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,30 @@
import { ResourceKind } from './Resources';
export interface ProjectFile<L extends string = string> {
path: string;
language: L;
contents: string;
}
export type ApplicationProjectFile = ProjectFile<'java' | 'kt'>;
export type GradleProjectFile = ProjectFile<'groovy' | 'kt'>;
export declare function getProjectFilePath(projectRoot: string, name: string): string;
export declare function getFileInfo(filePath: string): {
path: string;
contents: string;
language: any;
};
export declare function getMainApplicationAsync(projectRoot: string): Promise<ApplicationProjectFile>;
export declare function getMainActivityAsync(projectRoot: string): Promise<ApplicationProjectFile>;
export declare function getGradleFilePath(projectRoot: string, gradleName: string): string;
export declare function getProjectBuildGradleFilePath(projectRoot: string): string;
export declare function getProjectBuildGradleAsync(projectRoot: string): Promise<GradleProjectFile>;
export declare function getSettingsGradleFilePath(projectRoot: string): string;
export declare function getSettingsGradleAsync(projectRoot: string): Promise<GradleProjectFile>;
export declare function getAppBuildGradleFilePath(projectRoot: string): string;
export declare function getAppBuildGradleAsync(projectRoot: string): Promise<GradleProjectFile>;
export declare function getProjectPathOrThrowAsync(projectRoot: string): Promise<string>;
export declare function getAndroidManifestAsync(projectRoot: string): Promise<string>;
export declare function getResourceFolderAsync(projectRoot: string): Promise<string>;
export declare function getResourceXMLPathAsync(projectRoot: string, { kind, name }: {
kind?: ResourceKind;
name: 'colors' | 'strings' | 'styles' | string;
}): Promise<string>;

View File

@@ -0,0 +1,157 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.getAndroidManifestAsync = getAndroidManifestAsync;
exports.getAppBuildGradleAsync = getAppBuildGradleAsync;
exports.getAppBuildGradleFilePath = getAppBuildGradleFilePath;
exports.getFileInfo = getFileInfo;
exports.getGradleFilePath = getGradleFilePath;
exports.getMainActivityAsync = getMainActivityAsync;
exports.getMainApplicationAsync = getMainApplicationAsync;
exports.getProjectBuildGradleAsync = getProjectBuildGradleAsync;
exports.getProjectBuildGradleFilePath = getProjectBuildGradleFilePath;
exports.getProjectFilePath = getProjectFilePath;
exports.getProjectPathOrThrowAsync = getProjectPathOrThrowAsync;
exports.getResourceFolderAsync = getResourceFolderAsync;
exports.getResourceXMLPathAsync = getResourceXMLPathAsync;
exports.getSettingsGradleAsync = getSettingsGradleAsync;
exports.getSettingsGradleFilePath = getSettingsGradleFilePath;
function _assert() {
const data = _interopRequireDefault(require("assert"));
_assert = function () {
return data;
};
return data;
}
function _fs() {
const data = _interopRequireDefault(require("fs"));
_fs = function () {
return data;
};
return data;
}
function _glob() {
const data = require("glob");
_glob = function () {
return data;
};
return data;
}
function path() {
const data = _interopRequireWildcard(require("path"));
path = function () {
return data;
};
return data;
}
function _errors() {
const data = require("../utils/errors");
_errors = function () {
return data;
};
return data;
}
function _modules() {
const data = require("../utils/modules");
_modules = function () {
return data;
};
return data;
}
function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
function getProjectFilePath(projectRoot, name) {
const filePath = (0, _glob().globSync)(`android/app/src/main/java/**/${name}.@(java|kt)`, {
cwd: projectRoot,
absolute: true
})[0];
(0, _assert().default)(filePath, `Project file "${name}" does not exist in android project for root "${projectRoot}"`);
return filePath;
}
function getLanguage(filePath) {
const extension = path().extname(filePath);
switch (extension) {
case '.java':
return 'java';
case '.kts':
case '.kt':
return 'kt';
case '.groovy':
case '.gradle':
return 'groovy';
default:
throw new (_errors().UnexpectedError)(`Unexpected Android file extension: ${extension}`);
}
}
function getFileInfo(filePath) {
return {
path: path().normalize(filePath),
contents: _fs().default.readFileSync(filePath, 'utf8'),
language: getLanguage(filePath)
};
}
async function getMainApplicationAsync(projectRoot) {
const filePath = getProjectFilePath(projectRoot, 'MainApplication');
return getFileInfo(filePath);
}
async function getMainActivityAsync(projectRoot) {
const filePath = getProjectFilePath(projectRoot, 'MainActivity');
return getFileInfo(filePath);
}
function getGradleFilePath(projectRoot, gradleName) {
const groovyPath = path().resolve(projectRoot, `${gradleName}.gradle`);
const ktPath = path().resolve(projectRoot, `${gradleName}.gradle.kts`);
const isGroovy = _fs().default.existsSync(groovyPath);
const isKotlin = !isGroovy && _fs().default.existsSync(ktPath);
if (!isGroovy && !isKotlin) {
throw new Error(`Failed to find '${gradleName}.gradle' file for project: ${projectRoot}.`);
}
const filePath = isGroovy ? groovyPath : ktPath;
return filePath;
}
function getProjectBuildGradleFilePath(projectRoot) {
return getGradleFilePath(path().join(projectRoot, 'android'), 'build');
}
async function getProjectBuildGradleAsync(projectRoot) {
return getFileInfo(getProjectBuildGradleFilePath(projectRoot));
}
function getSettingsGradleFilePath(projectRoot) {
return getGradleFilePath(path().join(projectRoot, 'android'), 'settings');
}
async function getSettingsGradleAsync(projectRoot) {
return getFileInfo(getSettingsGradleFilePath(projectRoot));
}
function getAppBuildGradleFilePath(projectRoot) {
return getGradleFilePath(path().join(projectRoot, 'android', 'app'), 'build');
}
async function getAppBuildGradleAsync(projectRoot) {
return getFileInfo(getAppBuildGradleFilePath(projectRoot));
}
async function getProjectPathOrThrowAsync(projectRoot) {
const projectPath = path().join(projectRoot, 'android');
if (await (0, _modules().directoryExistsAsync)(projectPath)) {
return projectPath;
}
throw new Error(`Android project folder is missing in project: ${projectRoot}`);
}
async function getAndroidManifestAsync(projectRoot) {
const projectPath = await getProjectPathOrThrowAsync(projectRoot);
const filePath = path().join(projectPath, 'app/src/main/AndroidManifest.xml');
return filePath;
}
async function getResourceFolderAsync(projectRoot) {
const projectPath = await getProjectPathOrThrowAsync(projectRoot);
return path().join(projectPath, `app/src/main/res`);
}
async function getResourceXMLPathAsync(projectRoot, {
kind = 'values',
name
}) {
const resourcePath = await getResourceFolderAsync(projectRoot);
const filePath = path().join(resourcePath, `${kind}/${name}.xml`);
return filePath;
}
//# sourceMappingURL=Paths.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,20 @@
import { ExpoConfig } from '@expo/config-types';
import { AndroidManifest, ManifestUsesPermission } from './Manifest';
import { ConfigPlugin } from '../Plugin.types';
export declare const withPermissions: ConfigPlugin<string[] | void>;
/** Given a permission or list of permissions, block permissions in the final `AndroidManifest.xml` to ensure no installed library or plugin can add them. */
export declare const withBlockedPermissions: ConfigPlugin<string[] | string>;
export declare const withInternalBlockedPermissions: ConfigPlugin;
export declare function addBlockedPermissions(androidManifest: AndroidManifest, permissions: string[]): AndroidManifest;
export declare function getAndroidPermissions(config: Pick<ExpoConfig, 'android'>): string[];
export declare function setAndroidPermissions(config: Pick<ExpoConfig, 'android'>, androidManifest: AndroidManifest): AndroidManifest;
export declare function isPermissionAlreadyRequested(permission: string, manifestPermissions: ManifestUsesPermission[]): boolean;
export declare function addPermissionToManifest(permission: string, manifestPermissions: ManifestUsesPermission[]): ManifestUsesPermission[];
export declare function removePermissions(androidManifest: AndroidManifest, permissionNames?: string[]): void;
export declare function addPermission(androidManifest: AndroidManifest, permissionName: string): void;
export declare function ensurePermissions(androidManifest: AndroidManifest, permissionNames: string[]): {
[permission: string]: boolean;
};
export declare function ensurePermission(androidManifest: AndroidManifest, permissionName: string): boolean;
export declare function ensurePermissionNameFormat(permissionName: string): string;
export declare function getPermissions(androidManifest: AndroidManifest): string[];

View File

@@ -0,0 +1,207 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.addBlockedPermissions = addBlockedPermissions;
exports.addPermission = addPermission;
exports.addPermissionToManifest = addPermissionToManifest;
exports.ensurePermission = ensurePermission;
exports.ensurePermissionNameFormat = ensurePermissionNameFormat;
exports.ensurePermissions = ensurePermissions;
exports.getAndroidPermissions = getAndroidPermissions;
exports.getPermissions = getPermissions;
exports.isPermissionAlreadyRequested = isPermissionAlreadyRequested;
exports.removePermissions = removePermissions;
exports.setAndroidPermissions = setAndroidPermissions;
exports.withPermissions = exports.withInternalBlockedPermissions = exports.withBlockedPermissions = void 0;
function _Manifest() {
const data = require("./Manifest");
_Manifest = function () {
return data;
};
return data;
}
function _androidPlugins() {
const data = require("../plugins/android-plugins");
_androidPlugins = function () {
return data;
};
return data;
}
const USES_PERMISSION = 'uses-permission';
const withPermissions = (config, permissions) => {
if (Array.isArray(permissions)) {
permissions = permissions.filter(Boolean);
if (!config.android) config.android = {};
if (!config.android.permissions) config.android.permissions = [];
config.android.permissions = [
// @ts-ignore
...new Set(config.android.permissions.concat(permissions))];
}
return (0, _androidPlugins().withAndroidManifest)(config, async config => {
config.modResults = await setAndroidPermissions(config, config.modResults);
return config;
});
};
/** Given a permission or list of permissions, block permissions in the final `AndroidManifest.xml` to ensure no installed library or plugin can add them. */
exports.withPermissions = withPermissions;
const withBlockedPermissions = (config, permissions) => {
const resolvedPermissions = prefixAndroidPermissionsIfNecessary((Array.isArray(permissions) ? permissions : [permissions]).filter(Boolean));
if (config?.android?.permissions && Array.isArray(config.android.permissions)) {
// Remove any static config permissions
config.android.permissions = prefixAndroidPermissionsIfNecessary(config.android.permissions).filter(permission => !resolvedPermissions.includes(permission));
}
return (0, _androidPlugins().withAndroidManifest)(config, async config => {
config.modResults = (0, _Manifest().ensureToolsAvailable)(config.modResults);
config.modResults = addBlockedPermissions(config.modResults, resolvedPermissions);
return config;
});
};
exports.withBlockedPermissions = withBlockedPermissions;
const withInternalBlockedPermissions = config => {
// Only add permissions if the user defined the property and added some values
// this ensures we don't add the `tools:*` namespace extraneously.
if (config.android?.blockedPermissions?.length) {
return withBlockedPermissions(config, config.android.blockedPermissions);
}
return config;
};
exports.withInternalBlockedPermissions = withInternalBlockedPermissions;
function addBlockedPermissions(androidManifest, permissions) {
if (!Array.isArray(androidManifest.manifest['uses-permission'])) {
androidManifest.manifest['uses-permission'] = [];
}
for (const permission of prefixAndroidPermissionsIfNecessary(permissions)) {
androidManifest.manifest['uses-permission'] = ensureBlockedPermission(androidManifest.manifest['uses-permission'], permission);
}
return androidManifest;
}
/**
* Filter any existing permissions matching the provided permission name, then add a
* restricted permission to overwrite any extra permissions that may be added in a
* third-party package's AndroidManifest.xml.
*
* @param manifestPermissions manifest `uses-permissions` array.
* @param permission `android:name` of the permission to restrict
* @returns
*/
function ensureBlockedPermission(manifestPermissions, permission) {
// Remove permission if it currently exists
manifestPermissions = manifestPermissions.filter(e => e.$['android:name'] !== permission);
// Add a permission with tools:node to overwrite any existing permission and ensure it's removed upon building.
manifestPermissions.push({
$: {
'android:name': permission,
'tools:node': 'remove'
}
});
return manifestPermissions;
}
function prefixAndroidPermissionsIfNecessary(permissions) {
return permissions.map(permission => {
if (!permission.includes('.')) {
return `android.permission.${permission}`;
}
return permission;
});
}
function getAndroidPermissions(config) {
return config.android?.permissions ?? [];
}
function setAndroidPermissions(config, androidManifest) {
const permissions = getAndroidPermissions(config);
const providedPermissions = prefixAndroidPermissionsIfNecessary(permissions);
const permissionsToAdd = [...providedPermissions];
if (!androidManifest.manifest.hasOwnProperty('uses-permission')) {
androidManifest.manifest['uses-permission'] = [];
}
// manifest.manifest['uses-permission'] = [];
const manifestPermissions = androidManifest.manifest['uses-permission'] ?? [];
permissionsToAdd.forEach(permission => {
if (!isPermissionAlreadyRequested(permission, manifestPermissions)) {
addPermissionToManifest(permission, manifestPermissions);
}
});
return androidManifest;
}
function isPermissionAlreadyRequested(permission, manifestPermissions) {
return manifestPermissions.some(e => e.$['android:name'] === permission);
}
function addPermissionToManifest(permission, manifestPermissions) {
manifestPermissions.push({
$: {
'android:name': permission
}
});
return manifestPermissions;
}
function removePermissions(androidManifest, permissionNames) {
const targetNames = permissionNames ? permissionNames.map(ensurePermissionNameFormat) : null;
const permissions = androidManifest.manifest[USES_PERMISSION] || [];
const nextPermissions = [];
for (const attribute of permissions) {
if (targetNames) {
// @ts-ignore: name isn't part of the type
const value = attribute.$['android:name'] || attribute.$.name;
if (!targetNames.includes(value)) {
nextPermissions.push(attribute);
}
}
}
androidManifest.manifest[USES_PERMISSION] = nextPermissions;
}
function addPermission(androidManifest, permissionName) {
const usesPermissions = androidManifest.manifest[USES_PERMISSION] || [];
usesPermissions.push({
$: {
'android:name': permissionName
}
});
androidManifest.manifest[USES_PERMISSION] = usesPermissions;
}
function ensurePermissions(androidManifest, permissionNames) {
const permissions = getPermissions(androidManifest);
const results = {};
for (const permissionName of permissionNames) {
const targetName = ensurePermissionNameFormat(permissionName);
if (!permissions.includes(targetName)) {
addPermission(androidManifest, targetName);
results[permissionName] = true;
} else {
results[permissionName] = false;
}
}
return results;
}
function ensurePermission(androidManifest, permissionName) {
const permissions = getPermissions(androidManifest);
const targetName = ensurePermissionNameFormat(permissionName);
if (!permissions.includes(targetName)) {
addPermission(androidManifest, targetName);
return true;
}
return false;
}
function ensurePermissionNameFormat(permissionName) {
if (permissionName.includes('.')) {
const com = permissionName.split('.');
const name = com.pop();
return [...com, name.toUpperCase()].join('.');
} else {
// If shorthand form like `WRITE_CONTACTS` is provided, expand it to `android.permission.WRITE_CONTACTS`.
return ensurePermissionNameFormat(`android.permission.${permissionName}`);
}
}
function getPermissions(androidManifest) {
const usesPermissions = androidManifest.manifest[USES_PERMISSION] || [];
const permissions = usesPermissions.map(permissionObject => {
return permissionObject.$['android:name'] || permissionObject.$.name;
});
return permissions;
}
//# sourceMappingURL=Permissions.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,6 @@
import { ExpoConfig } from '@expo/config-types';
import { AndroidManifest } from './Manifest';
import { ConfigPlugin } from '../Plugin.types';
export declare const withPredictiveBackGesture: ConfigPlugin;
export declare function setPredictiveBackGesture(config: Pick<ExpoConfig, 'android'>, androidManifest: AndroidManifest): AndroidManifest;
export declare function getPredictiveBackGestureValue(config: Pick<ExpoConfig, 'android'>): "false" | "true";

View File

@@ -0,0 +1,40 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.getPredictiveBackGestureValue = getPredictiveBackGestureValue;
exports.setPredictiveBackGesture = setPredictiveBackGesture;
exports.withPredictiveBackGesture = void 0;
function _Manifest() {
const data = require("./Manifest");
_Manifest = function () {
return data;
};
return data;
}
function _androidPlugins() {
const data = require("../plugins/android-plugins");
_androidPlugins = function () {
return data;
};
return data;
}
const ANDROID_ENABLE_ON_BACK_INVOKED_CALLBACK = 'android:enableOnBackInvokedCallback';
const withPredictiveBackGesture = config => {
return (0, _androidPlugins().withAndroidManifest)(config, async config => {
config.modResults = setPredictiveBackGesture(config, config.modResults);
return config;
});
};
exports.withPredictiveBackGesture = withPredictiveBackGesture;
function setPredictiveBackGesture(config, androidManifest) {
const app = (0, _Manifest().getMainApplicationOrThrow)(androidManifest);
app.$[ANDROID_ENABLE_ON_BACK_INVOKED_CALLBACK] = getPredictiveBackGestureValue(config);
return androidManifest;
}
function getPredictiveBackGestureValue(config) {
const value = config.android?.predictiveBackGestureEnabled;
return value === true ? 'true' : 'false';
}
//# sourceMappingURL=PredictiveBackGesture.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"PredictiveBackGesture.js","names":["_Manifest","data","require","_androidPlugins","ANDROID_ENABLE_ON_BACK_INVOKED_CALLBACK","withPredictiveBackGesture","config","withAndroidManifest","modResults","setPredictiveBackGesture","exports","androidManifest","app","getMainApplicationOrThrow","$","getPredictiveBackGestureValue","value","android","predictiveBackGestureEnabled"],"sources":["../../src/android/PredictiveBackGesture.ts"],"sourcesContent":["import { ExpoConfig } from '@expo/config-types';\n\nimport { AndroidManifest, getMainApplicationOrThrow } from './Manifest';\nimport { ConfigPlugin } from '../Plugin.types';\nimport { withAndroidManifest } from '../plugins/android-plugins';\n\nconst ANDROID_ENABLE_ON_BACK_INVOKED_CALLBACK = 'android:enableOnBackInvokedCallback';\n\nexport const withPredictiveBackGesture: ConfigPlugin = (config) => {\n return withAndroidManifest(config, async (config) => {\n config.modResults = setPredictiveBackGesture(config, config.modResults);\n return config;\n });\n};\n\nexport function setPredictiveBackGesture(\n config: Pick<ExpoConfig, 'android'>,\n androidManifest: AndroidManifest\n) {\n const app = getMainApplicationOrThrow(androidManifest);\n app.$[ANDROID_ENABLE_ON_BACK_INVOKED_CALLBACK] = getPredictiveBackGestureValue(config);\n return androidManifest;\n}\n\nexport function getPredictiveBackGestureValue(config: Pick<ExpoConfig, 'android'>) {\n const value = config.android?.predictiveBackGestureEnabled;\n return value === true ? 'true' : 'false';\n}\n"],"mappings":";;;;;;;;AAEA,SAAAA,UAAA;EAAA,MAAAC,IAAA,GAAAC,OAAA;EAAAF,SAAA,YAAAA,CAAA;IAAA,OAAAC,IAAA;EAAA;EAAA,OAAAA,IAAA;AAAA;AAEA,SAAAE,gBAAA;EAAA,MAAAF,IAAA,GAAAC,OAAA;EAAAC,eAAA,YAAAA,CAAA;IAAA,OAAAF,IAAA;EAAA;EAAA,OAAAA,IAAA;AAAA;AAEA,MAAMG,uCAAuC,GAAG,qCAAqC;AAE9E,MAAMC,yBAAuC,GAAIC,MAAM,IAAK;EACjE,OAAO,IAAAC,qCAAmB,EAACD,MAAM,EAAE,MAAOA,MAAM,IAAK;IACnDA,MAAM,CAACE,UAAU,GAAGC,wBAAwB,CAACH,MAAM,EAAEA,MAAM,CAACE,UAAU,CAAC;IACvE,OAAOF,MAAM;EACf,CAAC,CAAC;AACJ,CAAC;AAACI,OAAA,CAAAL,yBAAA,GAAAA,yBAAA;AAEK,SAASI,wBAAwBA,CACtCH,MAAmC,EACnCK,eAAgC,EAChC;EACA,MAAMC,GAAG,GAAG,IAAAC,qCAAyB,EAACF,eAAe,CAAC;EACtDC,GAAG,CAACE,CAAC,CAACV,uCAAuC,CAAC,GAAGW,6BAA6B,CAACT,MAAM,CAAC;EACtF,OAAOK,eAAe;AACxB;AAEO,SAASI,6BAA6BA,CAACT,MAAmC,EAAE;EACjF,MAAMU,KAAK,GAAGV,MAAM,CAACW,OAAO,EAAEC,4BAA4B;EAC1D,OAAOF,KAAK,KAAK,IAAI,GAAG,MAAM,GAAG,OAAO;AAC1C","ignoreList":[]}

View File

@@ -0,0 +1,6 @@
import { ExpoConfig } from '@expo/config-types';
import { ConfigPlugin } from '../Plugin.types';
export declare const withPrimaryColor: ConfigPlugin;
export declare const withPrimaryColorColors: ConfigPlugin;
export declare const withPrimaryColorStyles: ConfigPlugin;
export declare function getPrimaryColor(config: Pick<ExpoConfig, 'primaryColor'>): string;

View File

@@ -0,0 +1,62 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.getPrimaryColor = getPrimaryColor;
exports.withPrimaryColorStyles = exports.withPrimaryColorColors = exports.withPrimaryColor = void 0;
function _Colors() {
const data = require("./Colors");
_Colors = function () {
return data;
};
return data;
}
function _Styles() {
const data = require("./Styles");
_Styles = function () {
return data;
};
return data;
}
function _androidPlugins() {
const data = require("../plugins/android-plugins");
_androidPlugins = function () {
return data;
};
return data;
}
const COLOR_PRIMARY_KEY = 'colorPrimary';
const DEFAULT_PRIMARY_COLOR = '#023c69';
const withPrimaryColor = config => {
config = withPrimaryColorColors(config);
config = withPrimaryColorStyles(config);
return config;
};
exports.withPrimaryColor = withPrimaryColor;
const withPrimaryColorColors = config => {
return (0, _androidPlugins().withAndroidColors)(config, config => {
config.modResults = (0, _Colors().assignColorValue)(config.modResults, {
name: COLOR_PRIMARY_KEY,
value: getPrimaryColor(config)
});
return config;
});
};
exports.withPrimaryColorColors = withPrimaryColorColors;
const withPrimaryColorStyles = config => {
return (0, _androidPlugins().withAndroidStyles)(config, config => {
config.modResults = (0, _Styles().assignStylesValue)(config.modResults, {
add: !!getPrimaryColor(config),
parent: (0, _Styles().getAppThemeGroup)(),
name: COLOR_PRIMARY_KEY,
value: `@color/${COLOR_PRIMARY_KEY}`
});
return config;
});
};
exports.withPrimaryColorStyles = withPrimaryColorStyles;
function getPrimaryColor(config) {
return config.primaryColor ?? DEFAULT_PRIMARY_COLOR;
}
//# sourceMappingURL=PrimaryColor.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"PrimaryColor.js","names":["_Colors","data","require","_Styles","_androidPlugins","COLOR_PRIMARY_KEY","DEFAULT_PRIMARY_COLOR","withPrimaryColor","config","withPrimaryColorColors","withPrimaryColorStyles","exports","withAndroidColors","modResults","assignColorValue","name","value","getPrimaryColor","withAndroidStyles","assignStylesValue","add","parent","getAppThemeGroup","primaryColor"],"sources":["../../src/android/PrimaryColor.ts"],"sourcesContent":["import { ExpoConfig } from '@expo/config-types';\n\nimport { assignColorValue } from './Colors';\nimport { assignStylesValue, getAppThemeGroup } from './Styles';\nimport { ConfigPlugin } from '../Plugin.types';\nimport { withAndroidColors, withAndroidStyles } from '../plugins/android-plugins';\n\nconst COLOR_PRIMARY_KEY = 'colorPrimary';\nconst DEFAULT_PRIMARY_COLOR = '#023c69';\n\nexport const withPrimaryColor: ConfigPlugin = (config) => {\n config = withPrimaryColorColors(config);\n config = withPrimaryColorStyles(config);\n return config;\n};\n\nexport const withPrimaryColorColors: ConfigPlugin = (config) => {\n return withAndroidColors(config, (config) => {\n config.modResults = assignColorValue(config.modResults, {\n name: COLOR_PRIMARY_KEY,\n value: getPrimaryColor(config),\n });\n return config;\n });\n};\n\nexport const withPrimaryColorStyles: ConfigPlugin = (config) => {\n return withAndroidStyles(config, (config) => {\n config.modResults = assignStylesValue(config.modResults, {\n add: !!getPrimaryColor(config),\n parent: getAppThemeGroup(),\n name: COLOR_PRIMARY_KEY,\n value: `@color/${COLOR_PRIMARY_KEY}`,\n });\n return config;\n });\n};\n\nexport function getPrimaryColor(config: Pick<ExpoConfig, 'primaryColor'>) {\n return config.primaryColor ?? DEFAULT_PRIMARY_COLOR;\n}\n"],"mappings":";;;;;;;AAEA,SAAAA,QAAA;EAAA,MAAAC,IAAA,GAAAC,OAAA;EAAAF,OAAA,YAAAA,CAAA;IAAA,OAAAC,IAAA;EAAA;EAAA,OAAAA,IAAA;AAAA;AACA,SAAAE,QAAA;EAAA,MAAAF,IAAA,GAAAC,OAAA;EAAAC,OAAA,YAAAA,CAAA;IAAA,OAAAF,IAAA;EAAA;EAAA,OAAAA,IAAA;AAAA;AAEA,SAAAG,gBAAA;EAAA,MAAAH,IAAA,GAAAC,OAAA;EAAAE,eAAA,YAAAA,CAAA;IAAA,OAAAH,IAAA;EAAA;EAAA,OAAAA,IAAA;AAAA;AAEA,MAAMI,iBAAiB,GAAG,cAAc;AACxC,MAAMC,qBAAqB,GAAG,SAAS;AAEhC,MAAMC,gBAA8B,GAAIC,MAAM,IAAK;EACxDA,MAAM,GAAGC,sBAAsB,CAACD,MAAM,CAAC;EACvCA,MAAM,GAAGE,sBAAsB,CAACF,MAAM,CAAC;EACvC,OAAOA,MAAM;AACf,CAAC;AAACG,OAAA,CAAAJ,gBAAA,GAAAA,gBAAA;AAEK,MAAME,sBAAoC,GAAID,MAAM,IAAK;EAC9D,OAAO,IAAAI,mCAAiB,EAACJ,MAAM,EAAGA,MAAM,IAAK;IAC3CA,MAAM,CAACK,UAAU,GAAG,IAAAC,0BAAgB,EAACN,MAAM,CAACK,UAAU,EAAE;MACtDE,IAAI,EAAEV,iBAAiB;MACvBW,KAAK,EAAEC,eAAe,CAACT,MAAM;IAC/B,CAAC,CAAC;IACF,OAAOA,MAAM;EACf,CAAC,CAAC;AACJ,CAAC;AAACG,OAAA,CAAAF,sBAAA,GAAAA,sBAAA;AAEK,MAAMC,sBAAoC,GAAIF,MAAM,IAAK;EAC9D,OAAO,IAAAU,mCAAiB,EAACV,MAAM,EAAGA,MAAM,IAAK;IAC3CA,MAAM,CAACK,UAAU,GAAG,IAAAM,2BAAiB,EAACX,MAAM,CAACK,UAAU,EAAE;MACvDO,GAAG,EAAE,CAAC,CAACH,eAAe,CAACT,MAAM,CAAC;MAC9Ba,MAAM,EAAE,IAAAC,0BAAgB,EAAC,CAAC;MAC1BP,IAAI,EAAEV,iBAAiB;MACvBW,KAAK,EAAE,UAAUX,iBAAiB;IACpC,CAAC,CAAC;IACF,OAAOG,MAAM;EACf,CAAC,CAAC;AACJ,CAAC;AAACG,OAAA,CAAAD,sBAAA,GAAAA,sBAAA;AAEK,SAASO,eAAeA,CAACT,MAAwC,EAAE;EACxE,OAAOA,MAAM,CAACe,YAAY,IAAIjB,qBAAqB;AACrD","ignoreList":[]}

View File

@@ -0,0 +1,12 @@
export type PropertiesItem = {
type: 'comment';
value: string;
} | {
type: 'empty';
} | {
type: 'property';
key: string;
value: string;
};
export declare function parsePropertiesFile(contents: string): PropertiesItem[];
export declare function propertiesListToString(props: PropertiesItem[]): string;

View File

@@ -0,0 +1,55 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.parsePropertiesFile = parsePropertiesFile;
exports.propertiesListToString = propertiesListToString;
function parsePropertiesFile(contents) {
const propertiesList = [];
const lines = contents.split('\n');
for (let i = 0; i < lines.length; i++) {
const line = lines[i].trim();
if (!line) {
propertiesList.push({
type: 'empty'
});
} else if (line.startsWith('#')) {
propertiesList.push({
type: 'comment',
value: line.substring(1).trimStart()
});
} else {
const eok = line.indexOf('=');
const key = line.slice(0, eok);
const value = line.slice(eok + 1, line.length);
propertiesList.push({
type: 'property',
key,
value
});
}
}
return propertiesList;
}
function propertiesListToString(props) {
let output = '';
for (let i = 0; i < props.length; i++) {
const prop = props[i];
if (prop.type === 'empty') {
output += '';
} else if (prop.type === 'comment') {
output += '# ' + prop.value;
} else if (prop.type === 'property') {
output += `${prop.key}=${prop.value}`;
} else {
// @ts-ignore: assertion
throw new Error(`Invalid properties type "${prop.type}"`);
}
if (i < props.length - 1) {
output += '\n';
}
}
return output;
}
//# sourceMappingURL=Properties.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"Properties.js","names":["parsePropertiesFile","contents","propertiesList","lines","split","i","length","line","trim","push","type","startsWith","value","substring","trimStart","eok","indexOf","key","slice","propertiesListToString","props","output","prop","Error"],"sources":["../../src/android/Properties.ts"],"sourcesContent":["export type PropertiesItem =\n | {\n type: 'comment';\n value: string;\n }\n | {\n type: 'empty';\n }\n | {\n type: 'property';\n key: string;\n value: string;\n };\n\nexport function parsePropertiesFile(contents: string): PropertiesItem[] {\n const propertiesList: PropertiesItem[] = [];\n const lines = contents.split('\\n');\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i].trim();\n if (!line) {\n propertiesList.push({ type: 'empty' });\n } else if (line.startsWith('#')) {\n propertiesList.push({ type: 'comment', value: line.substring(1).trimStart() });\n } else {\n const eok = line.indexOf('=');\n const key = line.slice(0, eok);\n const value = line.slice(eok + 1, line.length);\n propertiesList.push({ type: 'property', key, value });\n }\n }\n\n return propertiesList;\n}\n\nexport function propertiesListToString(props: PropertiesItem[]): string {\n let output = '';\n for (let i = 0; i < props.length; i++) {\n const prop = props[i];\n if (prop.type === 'empty') {\n output += '';\n } else if (prop.type === 'comment') {\n output += '# ' + prop.value;\n } else if (prop.type === 'property') {\n output += `${prop.key}=${prop.value}`;\n } else {\n // @ts-ignore: assertion\n throw new Error(`Invalid properties type \"${prop.type}\"`);\n }\n if (i < props.length - 1) {\n output += '\\n';\n }\n }\n return output;\n}\n"],"mappings":";;;;;;;AAcO,SAASA,mBAAmBA,CAACC,QAAgB,EAAoB;EACtE,MAAMC,cAAgC,GAAG,EAAE;EAC3C,MAAMC,KAAK,GAAGF,QAAQ,CAACG,KAAK,CAAC,IAAI,CAAC;EAClC,KAAK,IAAIC,CAAC,GAAG,CAAC,EAAEA,CAAC,GAAGF,KAAK,CAACG,MAAM,EAAED,CAAC,EAAE,EAAE;IACrC,MAAME,IAAI,GAAGJ,KAAK,CAACE,CAAC,CAAC,CAACG,IAAI,CAAC,CAAC;IAC5B,IAAI,CAACD,IAAI,EAAE;MACTL,cAAc,CAACO,IAAI,CAAC;QAAEC,IAAI,EAAE;MAAQ,CAAC,CAAC;IACxC,CAAC,MAAM,IAAIH,IAAI,CAACI,UAAU,CAAC,GAAG,CAAC,EAAE;MAC/BT,cAAc,CAACO,IAAI,CAAC;QAAEC,IAAI,EAAE,SAAS;QAAEE,KAAK,EAAEL,IAAI,CAACM,SAAS,CAAC,CAAC,CAAC,CAACC,SAAS,CAAC;MAAE,CAAC,CAAC;IAChF,CAAC,MAAM;MACL,MAAMC,GAAG,GAAGR,IAAI,CAACS,OAAO,CAAC,GAAG,CAAC;MAC7B,MAAMC,GAAG,GAAGV,IAAI,CAACW,KAAK,CAAC,CAAC,EAAEH,GAAG,CAAC;MAC9B,MAAMH,KAAK,GAAGL,IAAI,CAACW,KAAK,CAACH,GAAG,GAAG,CAAC,EAAER,IAAI,CAACD,MAAM,CAAC;MAC9CJ,cAAc,CAACO,IAAI,CAAC;QAAEC,IAAI,EAAE,UAAU;QAAEO,GAAG;QAAEL;MAAM,CAAC,CAAC;IACvD;EACF;EAEA,OAAOV,cAAc;AACvB;AAEO,SAASiB,sBAAsBA,CAACC,KAAuB,EAAU;EACtE,IAAIC,MAAM,GAAG,EAAE;EACf,KAAK,IAAIhB,CAAC,GAAG,CAAC,EAAEA,CAAC,GAAGe,KAAK,CAACd,MAAM,EAAED,CAAC,EAAE,EAAE;IACrC,MAAMiB,IAAI,GAAGF,KAAK,CAACf,CAAC,CAAC;IACrB,IAAIiB,IAAI,CAACZ,IAAI,KAAK,OAAO,EAAE;MACzBW,MAAM,IAAI,EAAE;IACd,CAAC,MAAM,IAAIC,IAAI,CAACZ,IAAI,KAAK,SAAS,EAAE;MAClCW,MAAM,IAAI,IAAI,GAAGC,IAAI,CAACV,KAAK;IAC7B,CAAC,MAAM,IAAIU,IAAI,CAACZ,IAAI,KAAK,UAAU,EAAE;MACnCW,MAAM,IAAI,GAAGC,IAAI,CAACL,GAAG,IAAIK,IAAI,CAACV,KAAK,EAAE;IACvC,CAAC,MAAM;MACL;MACA,MAAM,IAAIW,KAAK,CAAC,4BAA4BD,IAAI,CAACZ,IAAI,GAAG,CAAC;IAC3D;IACA,IAAIL,CAAC,GAAGe,KAAK,CAACd,MAAM,GAAG,CAAC,EAAE;MACxBe,MAAM,IAAI,IAAI;IAChB;EACF;EACA,OAAOA,MAAM;AACf","ignoreList":[]}

View File

@@ -0,0 +1,87 @@
import { XMLObject } from '../utils/XML';
export type ResourceGroupXML = {
$: {
name: string;
parent: string;
};
item: ResourceItemXML[];
};
export type ResourceXML = {
resources: {
$?: {
'xmlns:tools'?: string;
};
color?: ResourceItemXML[];
string?: ResourceItemXML[];
style?: ResourceGroupXML[];
};
};
export type ResourceItemXML = {
_: string;
$: {
name: string;
'tools:targetApi'?: string;
translatable?: string;
};
};
/**
* Name of the resource folder.
*/
export type ResourceKind = 'values' | 'values-night' | 'values-v23' | 'values-night-v23' | 'drawable';
/**
* Read an XML file while providing a default fallback for resource files.
*
* @param options path to the XML file, returns a fallback XML if the path doesn't exist.
*/
export declare function readResourcesXMLAsync({ path, fallback, }: {
path: string;
fallback?: string | null;
}): Promise<ResourceXML>;
/**
* Ensure the provided xml has a `resources` object (the expected shape).
*
* @param xml
*/
export declare function ensureDefaultResourceXML(xml: XMLObject): ResourceXML;
/**
* Build a `ResourceItemXML` given its `name` and `value`. This makes things a bit more readable.
*
* - JSON: `{ $: { name }, _: value }`
* - XML: `<item name="NAME">VALUE</item>`
*
* @param props name and value strings.
*/
export declare function buildResourceItem({ name, value, targetApi, translatable, }: {
name: string;
value: string;
targetApi?: string;
translatable?: boolean;
}): ResourceItemXML;
export declare function buildResourceGroup(parent: {
name: string;
parent: string;
items?: ResourceItemXML[];
}): ResourceGroupXML;
export declare function findResourceGroup(xml: ResourceGroupXML[] | undefined, group: {
name: string;
parent?: string;
}): ResourceGroupXML | null;
/**
* Helper to convert a basic XML object into a simple k/v pair.
*
* @param xml
* @returns
*/
export declare function getResourceItemsAsObject(xml: ResourceItemXML[]): Record<string, string> | null;
/**
* Helper to convert a basic k/v object to a ResourceItemXML array.
*
* @param xml
* @returns
*/
export declare function getObjectAsResourceItems(obj: Record<string, string>): ResourceItemXML[];
export declare function getObjectAsResourceGroup(group: {
name: string;
parent: string;
item: Record<string, string>;
}): ResourceGroupXML;

View File

@@ -0,0 +1,150 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.buildResourceGroup = buildResourceGroup;
exports.buildResourceItem = buildResourceItem;
exports.ensureDefaultResourceXML = ensureDefaultResourceXML;
exports.findResourceGroup = findResourceGroup;
exports.getObjectAsResourceGroup = getObjectAsResourceGroup;
exports.getObjectAsResourceItems = getObjectAsResourceItems;
exports.getResourceItemsAsObject = getResourceItemsAsObject;
exports.readResourcesXMLAsync = readResourcesXMLAsync;
function _XML() {
const data = require("../utils/XML");
_XML = function () {
return data;
};
return data;
}
/**
* Name of the resource folder.
*/
const fallbackResourceString = `<?xml version="1.0" encoding="utf-8"?><resources></resources>`;
/**
* Read an XML file while providing a default fallback for resource files.
*
* @param options path to the XML file, returns a fallback XML if the path doesn't exist.
*/
async function readResourcesXMLAsync({
path,
fallback = fallbackResourceString
}) {
const xml = await (0, _XML().readXMLAsync)({
path,
fallback
});
// Ensure the type is expected.
if (!xml.resources) {
xml.resources = {};
}
return xml;
}
/**
* Ensure the provided xml has a `resources` object (the expected shape).
*
* @param xml
*/
function ensureDefaultResourceXML(xml) {
if (!xml) {
xml = {
resources: {}
};
}
if (!xml.resources) {
xml.resources = {};
}
return xml;
}
/**
* Build a `ResourceItemXML` given its `name` and `value`. This makes things a bit more readable.
*
* - JSON: `{ $: { name }, _: value }`
* - XML: `<item name="NAME">VALUE</item>`
*
* @param props name and value strings.
*/
function buildResourceItem({
name,
value,
targetApi,
translatable
}) {
const item = {
$: {
name
},
_: value
};
if (targetApi) {
item.$['tools:targetApi'] = targetApi;
}
if (translatable !== undefined) {
item.$['translatable'] = String(translatable);
}
return item;
}
function buildResourceGroup(parent) {
return {
$: {
name: parent.name,
parent: parent.parent
},
item: parent.items ?? []
};
}
function findResourceGroup(xml, group) {
const app = xml?.filter?.(({
$: head
}) => {
let matches = head.name === group.name;
if (group.parent != null && matches) {
matches = head.parent === group.parent;
}
return matches;
})?.[0];
return app ?? null;
}
/**
* Helper to convert a basic XML object into a simple k/v pair.
*
* @param xml
* @returns
*/
function getResourceItemsAsObject(xml) {
return xml.reduce((prev, curr) => ({
...prev,
[curr.$.name]: curr._
}), {});
}
/**
* Helper to convert a basic k/v object to a ResourceItemXML array.
*
* @param xml
* @returns
*/
function getObjectAsResourceItems(obj) {
return Object.entries(obj).map(([name, value]) => ({
$: {
name
},
_: value
}));
}
function getObjectAsResourceGroup(group) {
return {
$: {
name: group.name,
parent: group.parent
},
item: getObjectAsResourceItems(group.item)
};
}
//# sourceMappingURL=Resources.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,20 @@
import { ExpoConfig } from '@expo/config-types';
import { AndroidManifest } from './Manifest';
export type IntentFilterProps = {
actions: string[];
categories: string[];
data: {
scheme: string;
host?: string;
}[];
};
export declare const withScheme: import("..").ConfigPlugin;
export declare function getScheme(config: {
scheme?: string | string[];
}): string[];
export declare function setScheme(config: Pick<ExpoConfig, 'scheme' | 'android'>, androidManifest: AndroidManifest): AndroidManifest;
export declare function getSchemesFromManifest(androidManifest: AndroidManifest, requestedHost?: string | null): string[];
export declare function ensureManifestHasValidIntentFilter(androidManifest: AndroidManifest): boolean;
export declare function hasScheme(scheme: string, androidManifest: AndroidManifest): boolean;
export declare function appendScheme(scheme: string, androidManifest: AndroidManifest): AndroidManifest;
export declare function removeScheme(scheme: string, androidManifest: AndroidManifest): AndroidManifest;

View File

@@ -0,0 +1,215 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.appendScheme = appendScheme;
exports.ensureManifestHasValidIntentFilter = ensureManifestHasValidIntentFilter;
exports.getScheme = getScheme;
exports.getSchemesFromManifest = getSchemesFromManifest;
exports.hasScheme = hasScheme;
exports.removeScheme = removeScheme;
exports.setScheme = setScheme;
exports.withScheme = void 0;
function _androidPlugins() {
const data = require("../plugins/android-plugins");
_androidPlugins = function () {
return data;
};
return data;
}
function _warnings() {
const data = require("../utils/warnings");
_warnings = function () {
return data;
};
return data;
}
const withScheme = exports.withScheme = (0, _androidPlugins().createAndroidManifestPlugin)(setScheme, 'withScheme');
function getScheme(config) {
if (Array.isArray(config.scheme)) {
const validate = value => typeof value === 'string';
return config.scheme.filter(validate);
} else if (typeof config.scheme === 'string') {
return [config.scheme];
}
return [];
}
// This plugin used to remove the unused schemes but this is unpredictable because other plugins could add schemes.
// The only way to reliably remove schemes from the project is to nuke the file and regenerate the code (`npx expo prebuild --clean`).
// Regardless, having extra schemes isn't a fatal issue and therefore a tolerable compromise is to just add new schemes that aren't currently present.
function setScheme(config, androidManifest) {
const schemes = [...getScheme(config), ...getScheme(config.android ?? {})];
if (schemes.length === 0) {
return androidManifest;
}
if (!ensureManifestHasValidIntentFilter(androidManifest)) {
(0, _warnings().addWarningAndroid)('scheme', `Cannot add schemes because the provided manifest does not have a valid Activity with \`android:launchMode="singleTask"\``, 'https://expo.fyi/setup-android-uri-scheme');
return androidManifest;
}
// Get the current schemes and remove them from the list of schemes to add.
const currentSchemes = getSchemesFromManifest(androidManifest);
for (const uri of currentSchemes) {
const index = schemes.indexOf(uri);
if (index > -1) schemes.splice(index, 1);
}
// Now add all of the remaining schemes.
for (const uri of schemes) {
androidManifest = appendScheme(uri, androidManifest);
}
return androidManifest;
}
function isValidRedirectIntentFilter({
actions,
categories
}) {
return actions.includes('android.intent.action.VIEW') && !categories.includes('android.intent.category.LAUNCHER');
}
function propertiesFromIntentFilter(intentFilter) {
const actions = intentFilter?.action?.map(data => data?.$?.['android:name']) ?? [];
const categories = intentFilter?.category?.map(data => data?.$?.['android:name']) ?? [];
const data = intentFilter?.data?.filter(data => data?.$?.['android:scheme'])?.map(data => ({
scheme: data?.$?.['android:scheme'],
host: data?.$?.['android:host']
})) ?? [];
return {
actions,
categories,
data
};
}
function getSingleTaskIntentFilters(androidManifest) {
if (!Array.isArray(androidManifest.manifest.application)) return [];
let outputSchemes = [];
for (const application of androidManifest.manifest.application) {
const {
activity
} = application;
// @ts-ignore
const activities = Array.isArray(activity) ? activity : [activity];
const singleTaskActivities = activities.filter(activity => activity?.$?.['android:launchMode'] === 'singleTask');
for (const activity of singleTaskActivities) {
const intentFilters = activity['intent-filter'];
outputSchemes = outputSchemes.concat(intentFilters);
}
}
return outputSchemes;
}
function getSchemesFromManifest(androidManifest, requestedHost = null) {
const outputSchemes = [];
const singleTaskIntentFilters = getSingleTaskIntentFilters(androidManifest);
for (const intentFilter of singleTaskIntentFilters) {
const properties = propertiesFromIntentFilter(intentFilter);
if (isValidRedirectIntentFilter(properties) && properties.data) {
for (const {
scheme,
host
} of properties.data) {
if (requestedHost === null || !host || host === requestedHost) {
outputSchemes.push(scheme);
}
}
}
}
return outputSchemes;
}
function ensureManifestHasValidIntentFilter(androidManifest) {
if (!Array.isArray(androidManifest.manifest.application)) {
return false;
}
for (const application of androidManifest.manifest.application) {
for (const activity of application.activity || []) {
if (activity?.$?.['android:launchMode'] === 'singleTask') {
for (const intentFilter of activity['intent-filter'] || []) {
// Parse valid intent filters...
const properties = propertiesFromIntentFilter(intentFilter);
if (isValidRedirectIntentFilter(properties)) {
return true;
}
}
if (!activity['intent-filter']) {
activity['intent-filter'] = [];
}
activity['intent-filter'].push({
action: [{
$: {
'android:name': 'android.intent.action.VIEW'
}
}],
category: [{
$: {
'android:name': 'android.intent.category.DEFAULT'
}
}, {
$: {
'android:name': 'android.intent.category.BROWSABLE'
}
}]
});
return true;
}
}
}
return false;
}
function hasScheme(scheme, androidManifest) {
const schemes = getSchemesFromManifest(androidManifest);
return schemes.includes(scheme);
}
function appendScheme(scheme, androidManifest) {
if (!Array.isArray(androidManifest.manifest.application)) {
return androidManifest;
}
if (!ensureManifestHasValidIntentFilter(androidManifest)) {
(0, _warnings().addWarningAndroid)('scheme', `Cannot add schemes because the provided manifest does not have a valid Activity with \`android:launchMode="singleTask"\``, 'https://expo.fyi/setup-android-uri-scheme');
return androidManifest;
}
for (const application of androidManifest.manifest.application) {
for (const activity of application.activity || []) {
if (activity?.$?.['android:launchMode'] === 'singleTask') {
for (const intentFilter of activity['intent-filter'] || []) {
const properties = propertiesFromIntentFilter(intentFilter);
if (isValidRedirectIntentFilter(properties)) {
if (!intentFilter.data) intentFilter.data = [];
intentFilter.data.push({
$: {
'android:scheme': scheme
}
});
}
}
break;
}
}
}
return androidManifest;
}
function removeScheme(scheme, androidManifest) {
if (!Array.isArray(androidManifest.manifest.application)) {
return androidManifest;
}
for (const application of androidManifest.manifest.application) {
for (const activity of application.activity || []) {
if (activity?.$?.['android:launchMode'] === 'singleTask') {
for (const intentFilter of activity['intent-filter'] || []) {
// Parse valid intent filters...
const properties = propertiesFromIntentFilter(intentFilter);
if (isValidRedirectIntentFilter(properties)) {
for (const dataKey in intentFilter?.data || []) {
const data = intentFilter.data?.[dataKey];
if (data?.$?.['android:scheme'] === scheme) {
delete intentFilter.data?.[dataKey];
}
}
}
}
break;
}
}
}
return androidManifest;
}
//# sourceMappingURL=Scheme.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,6 @@
import { ExpoConfig } from '@expo/config-types';
import { ResourceXML } from './Resources';
import { ConfigPlugin } from '../Plugin.types';
export declare const withStatusBar: ConfigPlugin;
export declare function setStatusBarStyles(config: Pick<ExpoConfig, 'androidStatusBar'>, styles: ResourceXML): ResourceXML;
export declare function getStatusBarStyle(config: Pick<ExpoConfig, 'androidStatusBar'>): "light-content" | "dark-content";

View File

@@ -0,0 +1,76 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.getStatusBarStyle = getStatusBarStyle;
exports.setStatusBarStyles = setStatusBarStyles;
exports.withStatusBar = void 0;
function _Styles() {
const data = require("./Styles");
_Styles = function () {
return data;
};
return data;
}
function _androidPlugins() {
const data = require("../plugins/android-plugins");
_androidPlugins = function () {
return data;
};
return data;
}
function WarningAggregator() {
const data = _interopRequireWildcard(require("../utils/warnings"));
WarningAggregator = function () {
return data;
};
return data;
}
function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
const TAG = 'STATUS_BAR_PLUGIN';
// https://developer.android.com/reference/android/R.attr#windowLightStatusBar
const WINDOW_LIGHT_STATUS_BAR = 'android:windowLightStatusBar';
// https://developer.android.com/reference/android/R.attr#statusBarColor
const STATUS_BAR_COLOR = 'android:statusBarColor';
const withStatusBar = config => {
const {
androidStatusBar = {}
} = config;
if ('backgroundColor' in androidStatusBar) {
WarningAggregator().addWarningAndroid(TAG, 'Due to Android edge-to-edge enforcement, `androidStatusBar.backgroundColor` is deprecated and has no effect. This will be removed in a future release.');
}
if ('translucent' in androidStatusBar) {
WarningAggregator().addWarningAndroid(TAG, 'Due to Android edge-to-edge enforcement, `androidStatusBar.translucent` is deprecated and has no effect. This will be removed in a future release.');
}
config = withStatusBarStyles(config);
return config;
};
exports.withStatusBar = withStatusBar;
const withStatusBarStyles = config => {
return (0, _androidPlugins().withAndroidStyles)(config, config => {
config.modResults = setStatusBarStyles(config, config.modResults);
return config;
});
};
function setStatusBarStyles(config, styles) {
styles = (0, _Styles().assignStylesValue)(styles, {
parent: (0, _Styles().getAppThemeGroup)(),
name: WINDOW_LIGHT_STATUS_BAR,
value: 'true',
// Default is light-content, don't need to do anything to set it
add: getStatusBarStyle(config) === 'dark-content'
});
styles = (0, _Styles().assignStylesValue)(styles, {
parent: (0, _Styles().getAppThemeGroup)(),
name: STATUS_BAR_COLOR,
value: '@android:color/transparent',
add: true
});
return styles;
}
function getStatusBarStyle(config) {
return config.androidStatusBar?.barStyle || 'light-content';
}
//# sourceMappingURL=StatusBar.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,6 @@
import { ResourceItemXML, ResourceKind, ResourceXML } from './Resources';
export declare function getProjectStringsXMLPathAsync(projectRoot: string, { kind }?: {
kind?: ResourceKind;
}): Promise<string>;
export declare function setStringItem(itemToAdd: ResourceItemXML[], stringFileContentsJSON: ResourceXML): ResourceXML;
export declare function removeStringItem(named: string, stringFileContentsJSON: ResourceXML): ResourceXML;

View File

@@ -0,0 +1,54 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.getProjectStringsXMLPathAsync = getProjectStringsXMLPathAsync;
exports.removeStringItem = removeStringItem;
exports.setStringItem = setStringItem;
function _Paths() {
const data = require("./Paths");
_Paths = function () {
return data;
};
return data;
}
async function getProjectStringsXMLPathAsync(projectRoot, {
kind
} = {}) {
return (0, _Paths().getResourceXMLPathAsync)(projectRoot, {
kind,
name: 'strings'
});
}
function setStringItem(itemToAdd, stringFileContentsJSON) {
if (!stringFileContentsJSON?.resources?.string) {
if (!stringFileContentsJSON.resources || typeof stringFileContentsJSON.resources === 'string') {
// file was empty and JSON is `{resources : ''}`
stringFileContentsJSON.resources = {};
}
stringFileContentsJSON.resources.string = itemToAdd;
return stringFileContentsJSON;
}
for (const newItem of itemToAdd) {
const stringNameExists = stringFileContentsJSON.resources.string.findIndex(e => e.$.name === newItem.$.name);
if (stringNameExists > -1) {
// replace the previous item
stringFileContentsJSON.resources.string[stringNameExists] = newItem;
} else {
stringFileContentsJSON.resources.string = stringFileContentsJSON.resources.string.concat(newItem);
}
}
return stringFileContentsJSON;
}
function removeStringItem(named, stringFileContentsJSON) {
if (stringFileContentsJSON?.resources?.string) {
const stringNameExists = stringFileContentsJSON.resources.string.findIndex(e => e.$.name === named);
if (stringNameExists > -1) {
// replace the previous value
stringFileContentsJSON.resources.string.splice(stringNameExists, 1);
}
}
return stringFileContentsJSON;
}
//# sourceMappingURL=Strings.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"Strings.js","names":["_Paths","data","require","getProjectStringsXMLPathAsync","projectRoot","kind","getResourceXMLPathAsync","name","setStringItem","itemToAdd","stringFileContentsJSON","resources","string","newItem","stringNameExists","findIndex","e","$","concat","removeStringItem","named","splice"],"sources":["../../src/android/Strings.ts"],"sourcesContent":["import { getResourceXMLPathAsync } from './Paths';\nimport { ResourceItemXML, ResourceKind, ResourceXML } from './Resources';\n\nexport async function getProjectStringsXMLPathAsync(\n projectRoot: string,\n { kind }: { kind?: ResourceKind } = {}\n): Promise<string> {\n return getResourceXMLPathAsync(projectRoot, { kind, name: 'strings' });\n}\n\nexport function setStringItem(\n itemToAdd: ResourceItemXML[],\n stringFileContentsJSON: ResourceXML\n): ResourceXML {\n if (!stringFileContentsJSON?.resources?.string) {\n if (!stringFileContentsJSON.resources || typeof stringFileContentsJSON.resources === 'string') {\n // file was empty and JSON is `{resources : ''}`\n stringFileContentsJSON.resources = {};\n }\n stringFileContentsJSON.resources.string = itemToAdd;\n return stringFileContentsJSON;\n }\n\n for (const newItem of itemToAdd) {\n const stringNameExists = stringFileContentsJSON.resources.string.findIndex(\n (e: ResourceItemXML) => e.$.name === newItem.$.name\n );\n if (stringNameExists > -1) {\n // replace the previous item\n stringFileContentsJSON.resources.string[stringNameExists] = newItem;\n } else {\n stringFileContentsJSON.resources.string =\n stringFileContentsJSON.resources.string.concat(newItem);\n }\n }\n return stringFileContentsJSON;\n}\n\nexport function removeStringItem(named: string, stringFileContentsJSON: ResourceXML): ResourceXML {\n if (stringFileContentsJSON?.resources?.string) {\n const stringNameExists = stringFileContentsJSON.resources.string.findIndex(\n (e: ResourceItemXML) => e.$.name === named\n );\n if (stringNameExists > -1) {\n // replace the previous value\n stringFileContentsJSON.resources.string.splice(stringNameExists, 1);\n }\n }\n return stringFileContentsJSON;\n}\n"],"mappings":";;;;;;;;AAAA,SAAAA,OAAA;EAAA,MAAAC,IAAA,GAAAC,OAAA;EAAAF,MAAA,YAAAA,CAAA;IAAA,OAAAC,IAAA;EAAA;EAAA,OAAAA,IAAA;AAAA;AAGO,eAAeE,6BAA6BA,CACjDC,WAAmB,EACnB;EAAEC;AAA8B,CAAC,GAAG,CAAC,CAAC,EACrB;EACjB,OAAO,IAAAC,gCAAuB,EAACF,WAAW,EAAE;IAAEC,IAAI;IAAEE,IAAI,EAAE;EAAU,CAAC,CAAC;AACxE;AAEO,SAASC,aAAaA,CAC3BC,SAA4B,EAC5BC,sBAAmC,EACtB;EACb,IAAI,CAACA,sBAAsB,EAAEC,SAAS,EAAEC,MAAM,EAAE;IAC9C,IAAI,CAACF,sBAAsB,CAACC,SAAS,IAAI,OAAOD,sBAAsB,CAACC,SAAS,KAAK,QAAQ,EAAE;MAC7F;MACAD,sBAAsB,CAACC,SAAS,GAAG,CAAC,CAAC;IACvC;IACAD,sBAAsB,CAACC,SAAS,CAACC,MAAM,GAAGH,SAAS;IACnD,OAAOC,sBAAsB;EAC/B;EAEA,KAAK,MAAMG,OAAO,IAAIJ,SAAS,EAAE;IAC/B,MAAMK,gBAAgB,GAAGJ,sBAAsB,CAACC,SAAS,CAACC,MAAM,CAACG,SAAS,CACvEC,CAAkB,IAAKA,CAAC,CAACC,CAAC,CAACV,IAAI,KAAKM,OAAO,CAACI,CAAC,CAACV,IACjD,CAAC;IACD,IAAIO,gBAAgB,GAAG,CAAC,CAAC,EAAE;MACzB;MACAJ,sBAAsB,CAACC,SAAS,CAACC,MAAM,CAACE,gBAAgB,CAAC,GAAGD,OAAO;IACrE,CAAC,MAAM;MACLH,sBAAsB,CAACC,SAAS,CAACC,MAAM,GACrCF,sBAAsB,CAACC,SAAS,CAACC,MAAM,CAACM,MAAM,CAACL,OAAO,CAAC;IAC3D;EACF;EACA,OAAOH,sBAAsB;AAC/B;AAEO,SAASS,gBAAgBA,CAACC,KAAa,EAAEV,sBAAmC,EAAe;EAChG,IAAIA,sBAAsB,EAAEC,SAAS,EAAEC,MAAM,EAAE;IAC7C,MAAME,gBAAgB,GAAGJ,sBAAsB,CAACC,SAAS,CAACC,MAAM,CAACG,SAAS,CACvEC,CAAkB,IAAKA,CAAC,CAACC,CAAC,CAACV,IAAI,KAAKa,KACvC,CAAC;IACD,IAAIN,gBAAgB,GAAG,CAAC,CAAC,EAAE;MACzB;MACAJ,sBAAsB,CAACC,SAAS,CAACC,MAAM,CAACS,MAAM,CAACP,gBAAgB,EAAE,CAAC,CAAC;IACrE;EACF;EACA,OAAOJ,sBAAsB;AAC/B","ignoreList":[]}

View File

@@ -0,0 +1,69 @@
import { ResourceGroupXML, ResourceItemXML, ResourceKind, ResourceXML } from './Resources';
export declare function readStylesXMLAsync({ path, fallback, }: {
path: string;
fallback?: string | null;
}): Promise<ResourceXML>;
export declare function getProjectStylesXMLPathAsync(projectRoot: string, { kind }?: {
kind?: ResourceKind;
}): Promise<string>;
export declare function getStyleParent(xml: ResourceXML, group: {
name: string;
parent?: string;
}): ResourceGroupXML | null;
export declare function getStylesItem({ name, xml, parent, }: {
name: string;
xml: ResourceXML;
parent: {
name: string;
parent?: string;
};
}): ResourceItemXML | null;
export declare function setStylesItem({ item, xml, parent, }: {
item: ResourceItemXML;
xml: ResourceXML;
parent: {
name: string;
parent?: string;
};
}): ResourceXML;
export declare function removeStylesItem({ name, xml, parent, }: {
name: string;
xml: ResourceXML;
parent: {
name: string;
parent?: string;
};
}): ResourceXML;
/**
* @deprecated Use `getAppThemeGroup` instead.
* Matching on both style name and parent leads to prebuild issues, as `AppTheme`
* style parent might be changed (when edge-to-edge is enabled, for example).
*/
export declare function getAppThemeLightNoActionBarGroup(): {
name: string;
parent: string;
};
export declare function getAppThemeGroup(): {
name: string;
};
export declare function assignStylesValue(xml: ResourceXML, { add, value, targetApi, name, parent, }: {
add: boolean;
value: string;
targetApi?: string;
name: string;
parent: {
name: string;
parent?: string;
};
}): ResourceXML;
/**
* Helper to convert a styles.xml parent's children into a simple k/v pair.
* Added for testing purposes.
*
* @param xml
* @returns
*/
export declare function getStylesGroupAsObject(xml: ResourceXML, group: {
name: string;
parent?: string;
}): Record<string, string> | null;

View File

@@ -0,0 +1,185 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.assignStylesValue = assignStylesValue;
exports.getAppThemeGroup = getAppThemeGroup;
exports.getAppThemeLightNoActionBarGroup = getAppThemeLightNoActionBarGroup;
exports.getProjectStylesXMLPathAsync = getProjectStylesXMLPathAsync;
exports.getStyleParent = getStyleParent;
exports.getStylesGroupAsObject = getStylesGroupAsObject;
exports.getStylesItem = getStylesItem;
exports.readStylesXMLAsync = readStylesXMLAsync;
exports.removeStylesItem = removeStylesItem;
exports.setStylesItem = setStylesItem;
function _Paths() {
const data = require("./Paths");
_Paths = function () {
return data;
};
return data;
}
function _Resources() {
const data = require("./Resources");
_Resources = function () {
return data;
};
return data;
}
// Adds support for `tools:x`
const fallbackResourceString = `<?xml version="1.0" encoding="utf-8"?><resources xmlns:tools="http://schemas.android.com/tools"></resources>`;
async function readStylesXMLAsync({
path,
fallback = fallbackResourceString
}) {
return (0, _Resources().readResourcesXMLAsync)({
path,
fallback
});
}
async function getProjectStylesXMLPathAsync(projectRoot, {
kind
} = {}) {
return (0, _Paths().getResourceXMLPathAsync)(projectRoot, {
kind,
name: 'styles'
});
}
function ensureDefaultStyleResourceXML(xml) {
xml = (0, _Resources().ensureDefaultResourceXML)(xml);
if (!Array.isArray(xml?.resources?.style)) {
xml.resources.style = [];
}
return xml;
}
function getStyleParent(xml, group) {
return (0, _Resources().findResourceGroup)(xml.resources.style, group);
}
function getStylesItem({
name,
xml,
parent
}) {
xml = ensureDefaultStyleResourceXML(xml);
const appTheme = getStyleParent(xml, parent);
if (!appTheme) {
return null;
}
if (appTheme.item) {
const existingItem = appTheme.item.filter(({
$: head
}) => head.name === name)[0];
// Don't want to 2 of the same item, so if one exists, we overwrite it
if (existingItem) {
return existingItem;
}
}
return null;
}
function setStylesItem({
item,
xml,
parent
}) {
xml = ensureDefaultStyleResourceXML(xml);
let appTheme = getStyleParent(xml, parent);
if (!appTheme) {
appTheme = (0, _Resources().buildResourceGroup)({
parent: 'Theme.AppCompat.Light.NoActionBar',
// Default AppTheme parent
...parent
});
xml.resources.style.push(appTheme);
}
if (appTheme.item) {
const existingItem = appTheme.item.filter(({
$: head
}) => head.name === item.$.name)[0];
// Don't want to 2 of the same item, so if one exists, we overwrite it
if (existingItem) {
existingItem._ = item._;
existingItem.$ = item.$;
} else {
appTheme.item.push(item);
}
} else {
appTheme.item = [item];
}
return xml;
}
function removeStylesItem({
name,
xml,
parent
}) {
xml = ensureDefaultStyleResourceXML(xml);
const appTheme = getStyleParent(xml, parent);
if (appTheme?.item) {
const index = appTheme.item.findIndex(({
$: head
}) => head.name === name);
if (index > -1) {
appTheme.item.splice(index, 1);
}
}
return xml;
}
/**
* @deprecated Use `getAppThemeGroup` instead.
* Matching on both style name and parent leads to prebuild issues, as `AppTheme`
* style parent might be changed (when edge-to-edge is enabled, for example).
*/
function getAppThemeLightNoActionBarGroup() {
return {
name: 'AppTheme',
parent: 'Theme.AppCompat.Light.NoActionBar'
};
}
// This is a very common theme so make it reusable.
function getAppThemeGroup() {
return {
name: 'AppTheme'
};
}
function assignStylesValue(xml, {
add,
value,
targetApi,
name,
parent
}) {
if (add) {
return setStylesItem({
xml,
parent,
item: (0, _Resources().buildResourceItem)({
name,
targetApi,
value
})
});
}
return removeStylesItem({
xml,
parent,
name
});
}
/**
* Helper to convert a styles.xml parent's children into a simple k/v pair.
* Added for testing purposes.
*
* @param xml
* @returns
*/
function getStylesGroupAsObject(xml, group) {
const xmlGroup = getStyleParent(xml, group);
return xmlGroup?.item ? (0, _Resources().getResourceItemsAsObject)(xmlGroup.item) : null;
}
//# sourceMappingURL=Styles.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,23 @@
import { AndroidManifest } from './Manifest';
import { ResourceXML } from './Resources';
import * as Resources from './Resources';
import { ConfigPlugin, ExportedConfigWithProps } from '../Plugin.types';
import { ExpoConfigUpdates } from '../utils/Updates';
export declare enum Config {
ENABLED = "expo.modules.updates.ENABLED",
CHECK_ON_LAUNCH = "expo.modules.updates.EXPO_UPDATES_CHECK_ON_LAUNCH",
LAUNCH_WAIT_MS = "expo.modules.updates.EXPO_UPDATES_LAUNCH_WAIT_MS",
RUNTIME_VERSION = "expo.modules.updates.EXPO_RUNTIME_VERSION",
UPDATE_URL = "expo.modules.updates.EXPO_UPDATE_URL",
UPDATES_CONFIGURATION_REQUEST_HEADERS_KEY = "expo.modules.updates.UPDATES_CONFIGURATION_REQUEST_HEADERS_KEY",
UPDATES_HAS_EMBEDDED_UPDATE = "expo.modules.updates.HAS_EMBEDDED_UPDATE",
CODE_SIGNING_CERTIFICATE = "expo.modules.updates.CODE_SIGNING_CERTIFICATE",
CODE_SIGNING_METADATA = "expo.modules.updates.CODE_SIGNING_METADATA",
DISABLE_ANTI_BRICKING_MEASURES = "expo.modules.updates.DISABLE_ANTI_BRICKING_MEASURES",
BSDIFF_PATCH_SUPPORT = "expo.modules.updates.ENABLE_BSDIFF_PATCH_SUPPORT"
}
export declare const withUpdates: ConfigPlugin;
export declare function applyRuntimeVersionFromConfigAsync(config: ExportedConfigWithProps<Resources.ResourceXML>, stringsJSON: ResourceXML): Promise<ResourceXML>;
export declare function applyRuntimeVersionFromConfigForProjectRootAsync(projectRoot: string, config: ExpoConfigUpdates, stringsJSON: ResourceXML): Promise<ResourceXML>;
export declare function setUpdatesConfigAsync(projectRoot: string, config: ExpoConfigUpdates, androidManifest: AndroidManifest, expoUpdatesPackageVersion?: string | null): Promise<AndroidManifest>;
export declare function setVersionsConfigAsync(projectRoot: string, config: Pick<ExpoConfigUpdates, 'sdkVersion' | 'runtimeVersion'>, androidManifest: AndroidManifest): Promise<AndroidManifest>;

View File

@@ -0,0 +1,188 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.Config = void 0;
exports.applyRuntimeVersionFromConfigAsync = applyRuntimeVersionFromConfigAsync;
exports.applyRuntimeVersionFromConfigForProjectRootAsync = applyRuntimeVersionFromConfigForProjectRootAsync;
exports.setUpdatesConfigAsync = setUpdatesConfigAsync;
exports.setVersionsConfigAsync = setVersionsConfigAsync;
exports.withUpdates = void 0;
function _BuildProperties() {
const data = require("./BuildProperties");
_BuildProperties = function () {
return data;
};
return data;
}
function _Manifest() {
const data = require("./Manifest");
_Manifest = function () {
return data;
};
return data;
}
function _Resources() {
const data = require("./Resources");
_Resources = function () {
return data;
};
return data;
}
function _Strings() {
const data = require("./Strings");
_Strings = function () {
return data;
};
return data;
}
function _androidPlugins() {
const data = require("../plugins/android-plugins");
_androidPlugins = function () {
return data;
};
return data;
}
function _withPlugins() {
const data = require("../plugins/withPlugins");
_withPlugins = function () {
return data;
};
return data;
}
function _Updates() {
const data = require("../utils/Updates");
_Updates = function () {
return data;
};
return data;
}
function _warnings() {
const data = require("../utils/warnings");
_warnings = function () {
return data;
};
return data;
}
let Config = exports.Config = /*#__PURE__*/function (Config) {
Config["ENABLED"] = "expo.modules.updates.ENABLED";
Config["CHECK_ON_LAUNCH"] = "expo.modules.updates.EXPO_UPDATES_CHECK_ON_LAUNCH";
Config["LAUNCH_WAIT_MS"] = "expo.modules.updates.EXPO_UPDATES_LAUNCH_WAIT_MS";
Config["RUNTIME_VERSION"] = "expo.modules.updates.EXPO_RUNTIME_VERSION";
Config["UPDATE_URL"] = "expo.modules.updates.EXPO_UPDATE_URL";
Config["UPDATES_CONFIGURATION_REQUEST_HEADERS_KEY"] = "expo.modules.updates.UPDATES_CONFIGURATION_REQUEST_HEADERS_KEY";
Config["UPDATES_HAS_EMBEDDED_UPDATE"] = "expo.modules.updates.HAS_EMBEDDED_UPDATE";
Config["CODE_SIGNING_CERTIFICATE"] = "expo.modules.updates.CODE_SIGNING_CERTIFICATE";
Config["CODE_SIGNING_METADATA"] = "expo.modules.updates.CODE_SIGNING_METADATA";
Config["DISABLE_ANTI_BRICKING_MEASURES"] = "expo.modules.updates.DISABLE_ANTI_BRICKING_MEASURES";
Config["BSDIFF_PATCH_SUPPORT"] = "expo.modules.updates.ENABLE_BSDIFF_PATCH_SUPPORT";
return Config;
}({}); // when making changes to this config plugin, ensure the same changes are also made in eas-cli and build-tools
// Also ensure the docs are up-to-date: https://docs.expo.dev/bare/installing-updates/
const withUpdates = config => {
return (0, _withPlugins().withPlugins)(config, [withUpdatesManifest, withRuntimeVersionResource, withUpdatesNativeDebugGradleProps]);
};
/**
* A config-plugin to update `android/gradle.properties` from the `updates.useNativeDebug` in expo config
*/
exports.withUpdates = withUpdates;
const withUpdatesNativeDebugGradleProps = (0, _BuildProperties().createBuildGradlePropsConfigPlugin)([{
propName: 'EX_UPDATES_NATIVE_DEBUG',
propValueGetter: config => config?.updates?.useNativeDebug === true ? 'true' : undefined
}], 'withUpdatesNativeDebugGradleProps');
const withUpdatesManifest = config => {
return (0, _androidPlugins().withAndroidManifest)(config, async config => {
const projectRoot = config.modRequest.projectRoot;
const expoUpdatesPackageVersion = (0, _Updates().getExpoUpdatesPackageVersion)(projectRoot);
config.modResults = await setUpdatesConfigAsync(projectRoot, config, config.modResults, expoUpdatesPackageVersion);
return config;
});
};
const withRuntimeVersionResource = (0, _androidPlugins().createStringsXmlPlugin)(applyRuntimeVersionFromConfigAsync, 'withRuntimeVersionResource');
async function applyRuntimeVersionFromConfigAsync(config, stringsJSON) {
const projectRoot = config.modRequest.projectRoot;
return await applyRuntimeVersionFromConfigForProjectRootAsync(projectRoot, config, stringsJSON);
}
async function applyRuntimeVersionFromConfigForProjectRootAsync(projectRoot, config, stringsJSON) {
const runtimeVersion = await (0, _Updates().getRuntimeVersionNullableAsync)(projectRoot, config, 'android');
if (runtimeVersion) {
return (0, _Strings().setStringItem)([(0, _Resources().buildResourceItem)({
name: 'expo_runtime_version',
value: runtimeVersion
})], stringsJSON);
}
return (0, _Strings().removeStringItem)('expo_runtime_version', stringsJSON);
}
async function setUpdatesConfigAsync(projectRoot, config, androidManifest, expoUpdatesPackageVersion) {
const mainApplication = (0, _Manifest().getMainApplicationOrThrow)(androidManifest);
(0, _Manifest().addMetaDataItemToMainApplication)(mainApplication, Config.ENABLED, String((0, _Updates().getUpdatesEnabled)(config)));
const checkOnLaunch = (0, _Updates().getUpdatesCheckOnLaunch)(config, expoUpdatesPackageVersion);
(0, _Manifest().addMetaDataItemToMainApplication)(mainApplication, Config.CHECK_ON_LAUNCH, checkOnLaunch);
const timeout = (0, _Updates().getUpdatesTimeout)(config);
(0, _Manifest().addMetaDataItemToMainApplication)(mainApplication, Config.LAUNCH_WAIT_MS, String(timeout));
const useEmbeddedUpdate = (0, _Updates().getUpdatesUseEmbeddedUpdate)(config);
if (useEmbeddedUpdate) {
(0, _Manifest().removeMetaDataItemFromMainApplication)(mainApplication, Config.UPDATES_HAS_EMBEDDED_UPDATE);
} else {
// TODO: is there a better place for this validation?
if (timeout === 0 && checkOnLaunch !== 'ALWAYS') {
(0, _warnings().addWarningAndroid)('updates.useEmbeddedUpdate', `updates.checkOnLaunch should be set to "ON_LOAD" and updates.fallbackToCacheTimeout should be set to a non-zero value when updates.useEmbeddedUpdate is set to false. This is because an update must be fetched on the initial launch, when no embedded update is available.`);
}
(0, _Manifest().addMetaDataItemToMainApplication)(mainApplication, Config.UPDATES_HAS_EMBEDDED_UPDATE, 'false');
}
const updateUrl = (0, _Updates().getUpdateUrl)(config);
if (updateUrl) {
(0, _Manifest().addMetaDataItemToMainApplication)(mainApplication, Config.UPDATE_URL, updateUrl);
} else {
(0, _Manifest().removeMetaDataItemFromMainApplication)(mainApplication, Config.UPDATE_URL);
}
const codeSigningCertificate = (0, _Updates().getUpdatesCodeSigningCertificate)(projectRoot, config);
if (codeSigningCertificate) {
(0, _Manifest().addMetaDataItemToMainApplication)(mainApplication, Config.CODE_SIGNING_CERTIFICATE, codeSigningCertificate);
} else {
(0, _Manifest().removeMetaDataItemFromMainApplication)(mainApplication, Config.CODE_SIGNING_CERTIFICATE);
}
const codeSigningMetadata = (0, _Updates().getUpdatesCodeSigningMetadataStringified)(config);
if (codeSigningMetadata) {
(0, _Manifest().addMetaDataItemToMainApplication)(mainApplication, Config.CODE_SIGNING_METADATA, codeSigningMetadata);
} else {
(0, _Manifest().removeMetaDataItemFromMainApplication)(mainApplication, Config.CODE_SIGNING_METADATA);
}
const requestHeaders = (0, _Updates().getUpdatesRequestHeadersStringified)(config);
if (requestHeaders) {
(0, _Manifest().addMetaDataItemToMainApplication)(mainApplication, Config.UPDATES_CONFIGURATION_REQUEST_HEADERS_KEY, requestHeaders);
} else {
(0, _Manifest().removeMetaDataItemFromMainApplication)(mainApplication, Config.UPDATES_CONFIGURATION_REQUEST_HEADERS_KEY);
}
const disableAntiBrickingMeasures = (0, _Updates().getDisableAntiBrickingMeasures)(config);
if (disableAntiBrickingMeasures) {
(0, _Manifest().addMetaDataItemToMainApplication)(mainApplication, Config.DISABLE_ANTI_BRICKING_MEASURES, 'true');
} else {
(0, _Manifest().removeMetaDataItemFromMainApplication)(mainApplication, Config.DISABLE_ANTI_BRICKING_MEASURES);
}
const bsPatchSupport = (0, _Updates().getUpdatesBsdiffPatchSupportEnabled)(config);
if (bsPatchSupport) {
(0, _Manifest().addMetaDataItemToMainApplication)(mainApplication, Config.BSDIFF_PATCH_SUPPORT, 'true');
} else {
(0, _Manifest().removeMetaDataItemFromMainApplication)(mainApplication, Config.BSDIFF_PATCH_SUPPORT);
}
return await setVersionsConfigAsync(projectRoot, config, androidManifest);
}
async function setVersionsConfigAsync(projectRoot, config, androidManifest) {
const mainApplication = (0, _Manifest().getMainApplicationOrThrow)(androidManifest);
const runtimeVersion = await (0, _Updates().getRuntimeVersionNullableAsync)(projectRoot, config, 'android');
if (!runtimeVersion && (0, _Manifest().findMetaDataItem)(mainApplication, Config.RUNTIME_VERSION) > -1) {
throw new Error('A runtime version is set in your AndroidManifest.xml, but is missing from your Expo app config (app.json/app.config.js). Either set runtimeVersion in your Expo app config or remove expo.modules.updates.EXPO_RUNTIME_VERSION from your AndroidManifest.xml.');
}
if (runtimeVersion) {
(0, _Manifest().removeMetaDataItemFromMainApplication)(mainApplication, 'expo.modules.updates.EXPO_SDK_VERSION');
(0, _Manifest().addMetaDataItemToMainApplication)(mainApplication, Config.RUNTIME_VERSION, '@string/expo_runtime_version');
} else {
(0, _Manifest().removeMetaDataItemFromMainApplication)(mainApplication, Config.RUNTIME_VERSION);
(0, _Manifest().removeMetaDataItemFromMainApplication)(mainApplication, 'expo.modules.updates.EXPO_SDK_VERSION');
}
return androidManifest;
}
//# sourceMappingURL=Updates.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,16 @@
import { ExpoConfig } from '@expo/config-types';
import { ConfigPlugin } from '../Plugin.types';
export declare const withVersion: ConfigPlugin;
/** Sets a numeric version for a value in the project.gradle buildscript.ext object to be at least the provided props.minVersion, if the existing value is greater then no change will be made. */
export declare const withBuildScriptExtMinimumVersion: ConfigPlugin<{
name: string;
minVersion: number;
}>;
export declare function setMinBuildScriptExtVersion(buildGradle: string, { name, minVersion }: {
name: string;
minVersion: number;
}): string;
export declare function getVersionName(config: Pick<ExpoConfig, 'version' | 'android'>): string | null;
export declare function setVersionName(config: Pick<ExpoConfig, 'version' | 'android'>, buildGradle: string): string;
export declare function getVersionCode(config: Pick<ExpoConfig, 'android'>): number;
export declare function setVersionCode(config: Pick<ExpoConfig, 'android'>, buildGradle: string): string;

View File

@@ -0,0 +1,87 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.getVersionCode = getVersionCode;
exports.getVersionName = getVersionName;
exports.setMinBuildScriptExtVersion = setMinBuildScriptExtVersion;
exports.setVersionCode = setVersionCode;
exports.setVersionName = setVersionName;
exports.withVersion = exports.withBuildScriptExtMinimumVersion = void 0;
function _androidPlugins() {
const data = require("../plugins/android-plugins");
_androidPlugins = function () {
return data;
};
return data;
}
function _warnings() {
const data = require("../utils/warnings");
_warnings = function () {
return data;
};
return data;
}
const withVersion = config => {
return (0, _androidPlugins().withAppBuildGradle)(config, config => {
if (config.modResults.language === 'groovy') {
config.modResults.contents = setVersionCode(config, config.modResults.contents);
config.modResults.contents = setVersionName(config, config.modResults.contents);
} else {
(0, _warnings().addWarningAndroid)('android.versionCode', `Cannot automatically configure app build.gradle if it's not groovy`);
}
return config;
});
};
/** Sets a numeric version for a value in the project.gradle buildscript.ext object to be at least the provided props.minVersion, if the existing value is greater then no change will be made. */
exports.withVersion = withVersion;
const withBuildScriptExtMinimumVersion = (config, props) => {
return (0, _androidPlugins().withProjectBuildGradle)(config, config => {
if (config.modResults.language === 'groovy') {
config.modResults.contents = setMinBuildScriptExtVersion(config.modResults.contents, props);
} else {
(0, _warnings().addWarningAndroid)('withBuildScriptExtVersion', `Cannot automatically configure project build.gradle if it's not groovy`);
}
return config;
});
};
exports.withBuildScriptExtMinimumVersion = withBuildScriptExtMinimumVersion;
function setMinBuildScriptExtVersion(buildGradle, {
name,
minVersion
}) {
const regex = new RegExp(`(${name}\\s?=\\s?)(\\d+(?:\\.\\d+)?)`);
const currentVersion = buildGradle.match(regex)?.[2];
if (!currentVersion) {
(0, _warnings().addWarningAndroid)('withBuildScriptExtVersion', `Cannot set minimum buildscript.ext.${name} version because the property "${name}" cannot be found or does not have a numeric value.`);
// TODO: Maybe just add the property...
return buildGradle;
}
const currentVersionNum = Number(currentVersion);
return buildGradle.replace(regex, `$1${Math.max(minVersion, currentVersionNum)}`);
}
function getVersionName(config) {
return config.android?.version ?? config.version ?? null;
}
function setVersionName(config, buildGradle) {
const versionName = getVersionName(config);
if (versionName === null) {
return buildGradle;
}
const pattern = new RegExp(`versionName ".*"`);
return buildGradle.replace(pattern, `versionName "${versionName}"`);
}
function getVersionCode(config) {
return config.android?.versionCode ?? 1;
}
function setVersionCode(config, buildGradle) {
const versionCode = getVersionCode(config);
if (versionCode === null) {
return buildGradle;
}
const pattern = new RegExp(`versionCode.*`);
return buildGradle.replace(pattern, `versionCode ${versionCode}`);
}
//# sourceMappingURL=Version.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,6 @@
import { ExpoConfig } from '@expo/config-types';
import { AndroidManifest } from './Manifest';
import { ConfigPlugin } from '../Plugin.types';
export declare const withWindowSoftInputMode: ConfigPlugin;
export declare function setWindowSoftInputModeMode(config: Pick<ExpoConfig, 'android' | 'userInterfaceStyle'>, androidManifest: AndroidManifest): AndroidManifest;
export declare function getWindowSoftInputModeMode(config: Pick<ExpoConfig, 'android'>): string;

View File

@@ -0,0 +1,48 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.getWindowSoftInputModeMode = getWindowSoftInputModeMode;
exports.setWindowSoftInputModeMode = setWindowSoftInputModeMode;
exports.withWindowSoftInputMode = void 0;
function _Manifest() {
const data = require("./Manifest");
_Manifest = function () {
return data;
};
return data;
}
function _androidPlugins() {
const data = require("../plugins/android-plugins");
_androidPlugins = function () {
return data;
};
return data;
}
const ANDROID_WINDOW_SOFT_INPUT_MODE = 'android:windowSoftInputMode';
const MAPPING = {
pan: 'adjustPan',
resize: 'adjustResize'
};
const withWindowSoftInputMode = config => {
return (0, _androidPlugins().withAndroidManifest)(config, async config => {
config.modResults = setWindowSoftInputModeMode(config, config.modResults);
return config;
});
};
exports.withWindowSoftInputMode = withWindowSoftInputMode;
function setWindowSoftInputModeMode(config, androidManifest) {
const app = (0, _Manifest().getMainActivityOrThrow)(androidManifest);
app.$[ANDROID_WINDOW_SOFT_INPUT_MODE] = getWindowSoftInputModeMode(config);
return androidManifest;
}
function getWindowSoftInputModeMode(config) {
const value = config.android?.softwareKeyboardLayoutMode;
if (!value) {
// Default to `adjustResize` or `resize`.
return 'adjustResize';
}
return MAPPING[value] ?? value;
}
//# sourceMappingURL=WindowSoftInputMode.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"WindowSoftInputMode.js","names":["_Manifest","data","require","_androidPlugins","ANDROID_WINDOW_SOFT_INPUT_MODE","MAPPING","pan","resize","withWindowSoftInputMode","config","withAndroidManifest","modResults","setWindowSoftInputModeMode","exports","androidManifest","app","getMainActivityOrThrow","$","getWindowSoftInputModeMode","value","android","softwareKeyboardLayoutMode"],"sources":["../../src/android/WindowSoftInputMode.ts"],"sourcesContent":["import { ExpoConfig } from '@expo/config-types';\n\nimport { AndroidManifest, getMainActivityOrThrow } from './Manifest';\nimport { ConfigPlugin } from '../Plugin.types';\nimport { withAndroidManifest } from '../plugins/android-plugins';\n\nconst ANDROID_WINDOW_SOFT_INPUT_MODE = 'android:windowSoftInputMode';\n\nconst MAPPING: Record<string, string> = {\n pan: 'adjustPan',\n resize: 'adjustResize',\n};\n\nexport const withWindowSoftInputMode: ConfigPlugin = (config) => {\n return withAndroidManifest(config, async (config) => {\n config.modResults = setWindowSoftInputModeMode(config, config.modResults);\n return config;\n });\n};\n\nexport function setWindowSoftInputModeMode(\n config: Pick<ExpoConfig, 'android' | 'userInterfaceStyle'>,\n androidManifest: AndroidManifest\n) {\n const app = getMainActivityOrThrow(androidManifest);\n app.$[ANDROID_WINDOW_SOFT_INPUT_MODE] = getWindowSoftInputModeMode(config);\n return androidManifest;\n}\n\nexport function getWindowSoftInputModeMode(config: Pick<ExpoConfig, 'android'>) {\n const value = config.android?.softwareKeyboardLayoutMode;\n\n if (!value) {\n // Default to `adjustResize` or `resize`.\n return 'adjustResize';\n }\n return MAPPING[value] ?? value;\n}\n"],"mappings":";;;;;;;;AAEA,SAAAA,UAAA;EAAA,MAAAC,IAAA,GAAAC,OAAA;EAAAF,SAAA,YAAAA,CAAA;IAAA,OAAAC,IAAA;EAAA;EAAA,OAAAA,IAAA;AAAA;AAEA,SAAAE,gBAAA;EAAA,MAAAF,IAAA,GAAAC,OAAA;EAAAC,eAAA,YAAAA,CAAA;IAAA,OAAAF,IAAA;EAAA;EAAA,OAAAA,IAAA;AAAA;AAEA,MAAMG,8BAA8B,GAAG,6BAA6B;AAEpE,MAAMC,OAA+B,GAAG;EACtCC,GAAG,EAAE,WAAW;EAChBC,MAAM,EAAE;AACV,CAAC;AAEM,MAAMC,uBAAqC,GAAIC,MAAM,IAAK;EAC/D,OAAO,IAAAC,qCAAmB,EAACD,MAAM,EAAE,MAAOA,MAAM,IAAK;IACnDA,MAAM,CAACE,UAAU,GAAGC,0BAA0B,CAACH,MAAM,EAAEA,MAAM,CAACE,UAAU,CAAC;IACzE,OAAOF,MAAM;EACf,CAAC,CAAC;AACJ,CAAC;AAACI,OAAA,CAAAL,uBAAA,GAAAA,uBAAA;AAEK,SAASI,0BAA0BA,CACxCH,MAA0D,EAC1DK,eAAgC,EAChC;EACA,MAAMC,GAAG,GAAG,IAAAC,kCAAsB,EAACF,eAAe,CAAC;EACnDC,GAAG,CAACE,CAAC,CAACb,8BAA8B,CAAC,GAAGc,0BAA0B,CAACT,MAAM,CAAC;EAC1E,OAAOK,eAAe;AACxB;AAEO,SAASI,0BAA0BA,CAACT,MAAmC,EAAE;EAC9E,MAAMU,KAAK,GAAGV,MAAM,CAACW,OAAO,EAAEC,0BAA0B;EAExD,IAAI,CAACF,KAAK,EAAE;IACV;IACA,OAAO,cAAc;EACvB;EACA,OAAOd,OAAO,CAACc,KAAK,CAAC,IAAIA,KAAK;AAChC","ignoreList":[]}

View File

@@ -0,0 +1,36 @@
import { CodeBlock } from '../utils/commonCodeMod';
/**
* Find java or kotlin new class instance code block
*
* @param contents source contents
* @param classDeclaration class declaration or just a class name
* @param language 'java' | 'kt'
* @returns `CodeBlock` for start/end offset and code block contents
*/
export declare function findNewInstanceCodeBlock(contents: string, classDeclaration: string, language: 'java' | 'kt'): CodeBlock | null;
/**
* Append contents to the end of code declaration block, support class or method declarations.
*
* @param srcContents source contents
* @param declaration class declaration or method declaration
* @param insertion code to append
* @returns updated contents
*/
export declare function appendContentsInsideDeclarationBlock(srcContents: string, declaration: string, insertion: string): string;
export declare function addImports(source: string, imports: string[], isJava: boolean): string;
/**
* Find code block of Gradle plugin block, will return only {} part
*
* @param contents source contents
* @param plugin plugin declaration name, e.g. `plugins` or `pluginManagement`
* @returns found CodeBlock, or null if not found.
*/
export declare function findGradlePluginCodeBlock(contents: string, plugin: string): CodeBlock | null;
/**
* Append contents to the end of Gradle plugin block
* @param srcContents source contents
* @param plugin plugin declaration name, e.g. `plugins` or `pluginManagement`
* @param insertion code to append
* @returns updated contents
*/
export declare function appendContentsInsideGradlePluginBlock(srcContents: string, plugin: string, insertion: string): string;

View File

@@ -0,0 +1,132 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.addImports = addImports;
exports.appendContentsInsideDeclarationBlock = appendContentsInsideDeclarationBlock;
exports.appendContentsInsideGradlePluginBlock = appendContentsInsideGradlePluginBlock;
exports.findGradlePluginCodeBlock = findGradlePluginCodeBlock;
exports.findNewInstanceCodeBlock = findNewInstanceCodeBlock;
function _commonCodeMod() {
const data = require("../utils/commonCodeMod");
_commonCodeMod = function () {
return data;
};
return data;
}
function _matchBrackets() {
const data = require("../utils/matchBrackets");
_matchBrackets = function () {
return data;
};
return data;
}
/**
* Find java or kotlin new class instance code block
*
* @param contents source contents
* @param classDeclaration class declaration or just a class name
* @param language 'java' | 'kt'
* @returns `CodeBlock` for start/end offset and code block contents
*/
function findNewInstanceCodeBlock(contents, classDeclaration, language) {
const isJava = language === 'java';
let start = isJava ? contents.indexOf(` new ${classDeclaration}(`) : contents.search(new RegExp(` (object\\s*:\\s*)?${classDeclaration}\\(`));
if (start < 0) {
return null;
}
// `+ 1` for the prefix space
start += 1;
let end = (0, _matchBrackets().findMatchingBracketPosition)(contents, '(', start);
// For anonymous class, should search further to the {} block.
// ```java
// new Foo() {
// @Override
// protected void interfaceMethod {}
// };
// ```
//
// ```kotlin
// object : Foo() {
// override fun interfaceMethod {}
// }
// ```
const nextBrace = contents.indexOf('{', end + 1);
const isAnonymousClass = nextBrace >= end && !!contents.substring(end + 1, nextBrace).match(/^\s*$/);
if (isAnonymousClass) {
end = (0, _matchBrackets().findMatchingBracketPosition)(contents, '{', end);
}
return {
start,
end,
code: contents.substring(start, end + 1)
};
}
/**
* Append contents to the end of code declaration block, support class or method declarations.
*
* @param srcContents source contents
* @param declaration class declaration or method declaration
* @param insertion code to append
* @returns updated contents
*/
function appendContentsInsideDeclarationBlock(srcContents, declaration, insertion) {
const start = srcContents.search(new RegExp(`\\s*${declaration}.*?[\\(\\{]`));
if (start < 0) {
throw new Error(`Unable to find code block - declaration[${declaration}]`);
}
const end = (0, _matchBrackets().findMatchingBracketPosition)(srcContents, '{', start);
return (0, _commonCodeMod().insertContentsAtOffset)(srcContents, insertion, end);
}
function addImports(source, imports, isJava) {
const lines = source.split('\n');
const lineIndexWithPackageDeclaration = lines.findIndex(line => line.match(/^package .*;?$/));
for (const javaImport of imports) {
if (!source.includes(javaImport)) {
const importStatement = `import ${javaImport}${isJava ? ';' : ''}`;
lines.splice(lineIndexWithPackageDeclaration + 1, 0, importStatement);
}
}
return lines.join('\n');
}
/**
* Find code block of Gradle plugin block, will return only {} part
*
* @param contents source contents
* @param plugin plugin declaration name, e.g. `plugins` or `pluginManagement`
* @returns found CodeBlock, or null if not found.
*/
function findGradlePluginCodeBlock(contents, plugin) {
const pluginStart = contents.search(new RegExp(`${plugin}\\s*\\{`, 'm'));
if (pluginStart < 0) {
return null;
}
const codeBlockStart = contents.indexOf('{', pluginStart);
const codeBlockEnd = (0, _matchBrackets().findMatchingBracketPosition)(contents, '{', codeBlockStart);
const codeBlock = contents.substring(codeBlockStart, codeBlockEnd + 1);
return {
start: codeBlockStart,
end: codeBlockEnd,
code: codeBlock
};
}
/**
* Append contents to the end of Gradle plugin block
* @param srcContents source contents
* @param plugin plugin declaration name, e.g. `plugins` or `pluginManagement`
* @param insertion code to append
* @returns updated contents
*/
function appendContentsInsideGradlePluginBlock(srcContents, plugin, insertion) {
const codeBlock = findGradlePluginCodeBlock(srcContents, plugin);
if (!codeBlock) {
throw new Error(`Unable to find Gradle plugin block - plugin[${plugin}]`);
}
return (0, _commonCodeMod().insertContentsAtOffset)(srcContents, insertion, codeBlock.end);
}
//# sourceMappingURL=codeMod.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,28 @@
import * as AllowBackup from './AllowBackup';
import * as BuildProperties from './BuildProperties';
import * as Colors from './Colors';
import * as EasBuild from './EasBuild';
import * as GoogleMapsApiKey from './GoogleMapsApiKey';
import * as GoogleServices from './GoogleServices';
import * as IntentFilters from './IntentFilters';
import * as Locales from './Locales';
import * as Manifest from './Manifest';
import * as Name from './Name';
import * as Orientation from './Orientation';
import * as Package from './Package';
import * as Paths from './Paths';
import * as Permissions from './Permissions';
import * as PredictiveBackGesture from './PredictiveBackGesture';
import * as PrimaryColor from './PrimaryColor';
import * as Properties from './Properties';
import * as Resources from './Resources';
import * as Scheme from './Scheme';
import * as StatusBar from './StatusBar';
import * as Strings from './Strings';
import * as Styles from './Styles';
import * as Updates from './Updates';
import * as Version from './Version';
import * as WindowSoftInputMode from './WindowSoftInputMode';
import * as CodeMod from './codeMod';
export { Manifest, Colors, Paths, Permissions, Properties, Resources, Scheme, Strings, Styles };
export { AllowBackup, BuildProperties, EasBuild, GoogleMapsApiKey, GoogleServices, IntentFilters, Name, Locales, Orientation, Package, PrimaryColor, StatusBar, Updates, Version, WindowSoftInputMode, PredictiveBackGesture, CodeMod, };

View File

@@ -0,0 +1,347 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.WindowSoftInputMode = exports.Version = exports.Updates = exports.Styles = exports.Strings = exports.StatusBar = exports.Scheme = exports.Resources = exports.Properties = exports.PrimaryColor = exports.PredictiveBackGesture = exports.Permissions = exports.Paths = exports.Package = exports.Orientation = exports.Name = exports.Manifest = exports.Locales = exports.IntentFilters = exports.GoogleServices = exports.GoogleMapsApiKey = exports.EasBuild = exports.Colors = exports.CodeMod = exports.BuildProperties = exports.AllowBackup = void 0;
function AllowBackup() {
const data = _interopRequireWildcard(require("./AllowBackup"));
AllowBackup = function () {
return data;
};
return data;
}
Object.defineProperty(exports, "AllowBackup", {
enumerable: true,
get: function () {
return AllowBackup();
}
});
function BuildProperties() {
const data = _interopRequireWildcard(require("./BuildProperties"));
BuildProperties = function () {
return data;
};
return data;
}
Object.defineProperty(exports, "BuildProperties", {
enumerable: true,
get: function () {
return BuildProperties();
}
});
function Colors() {
const data = _interopRequireWildcard(require("./Colors"));
Colors = function () {
return data;
};
return data;
}
Object.defineProperty(exports, "Colors", {
enumerable: true,
get: function () {
return Colors();
}
});
function EasBuild() {
const data = _interopRequireWildcard(require("./EasBuild"));
EasBuild = function () {
return data;
};
return data;
}
Object.defineProperty(exports, "EasBuild", {
enumerable: true,
get: function () {
return EasBuild();
}
});
function GoogleMapsApiKey() {
const data = _interopRequireWildcard(require("./GoogleMapsApiKey"));
GoogleMapsApiKey = function () {
return data;
};
return data;
}
Object.defineProperty(exports, "GoogleMapsApiKey", {
enumerable: true,
get: function () {
return GoogleMapsApiKey();
}
});
function GoogleServices() {
const data = _interopRequireWildcard(require("./GoogleServices"));
GoogleServices = function () {
return data;
};
return data;
}
Object.defineProperty(exports, "GoogleServices", {
enumerable: true,
get: function () {
return GoogleServices();
}
});
function IntentFilters() {
const data = _interopRequireWildcard(require("./IntentFilters"));
IntentFilters = function () {
return data;
};
return data;
}
Object.defineProperty(exports, "IntentFilters", {
enumerable: true,
get: function () {
return IntentFilters();
}
});
function Locales() {
const data = _interopRequireWildcard(require("./Locales"));
Locales = function () {
return data;
};
return data;
}
Object.defineProperty(exports, "Locales", {
enumerable: true,
get: function () {
return Locales();
}
});
function Manifest() {
const data = _interopRequireWildcard(require("./Manifest"));
Manifest = function () {
return data;
};
return data;
}
Object.defineProperty(exports, "Manifest", {
enumerable: true,
get: function () {
return Manifest();
}
});
function Name() {
const data = _interopRequireWildcard(require("./Name"));
Name = function () {
return data;
};
return data;
}
Object.defineProperty(exports, "Name", {
enumerable: true,
get: function () {
return Name();
}
});
function Orientation() {
const data = _interopRequireWildcard(require("./Orientation"));
Orientation = function () {
return data;
};
return data;
}
Object.defineProperty(exports, "Orientation", {
enumerable: true,
get: function () {
return Orientation();
}
});
function Package() {
const data = _interopRequireWildcard(require("./Package"));
Package = function () {
return data;
};
return data;
}
Object.defineProperty(exports, "Package", {
enumerable: true,
get: function () {
return Package();
}
});
function Paths() {
const data = _interopRequireWildcard(require("./Paths"));
Paths = function () {
return data;
};
return data;
}
Object.defineProperty(exports, "Paths", {
enumerable: true,
get: function () {
return Paths();
}
});
function Permissions() {
const data = _interopRequireWildcard(require("./Permissions"));
Permissions = function () {
return data;
};
return data;
}
Object.defineProperty(exports, "Permissions", {
enumerable: true,
get: function () {
return Permissions();
}
});
function PredictiveBackGesture() {
const data = _interopRequireWildcard(require("./PredictiveBackGesture"));
PredictiveBackGesture = function () {
return data;
};
return data;
}
Object.defineProperty(exports, "PredictiveBackGesture", {
enumerable: true,
get: function () {
return PredictiveBackGesture();
}
});
function PrimaryColor() {
const data = _interopRequireWildcard(require("./PrimaryColor"));
PrimaryColor = function () {
return data;
};
return data;
}
Object.defineProperty(exports, "PrimaryColor", {
enumerable: true,
get: function () {
return PrimaryColor();
}
});
function Properties() {
const data = _interopRequireWildcard(require("./Properties"));
Properties = function () {
return data;
};
return data;
}
Object.defineProperty(exports, "Properties", {
enumerable: true,
get: function () {
return Properties();
}
});
function Resources() {
const data = _interopRequireWildcard(require("./Resources"));
Resources = function () {
return data;
};
return data;
}
Object.defineProperty(exports, "Resources", {
enumerable: true,
get: function () {
return Resources();
}
});
function Scheme() {
const data = _interopRequireWildcard(require("./Scheme"));
Scheme = function () {
return data;
};
return data;
}
Object.defineProperty(exports, "Scheme", {
enumerable: true,
get: function () {
return Scheme();
}
});
function StatusBar() {
const data = _interopRequireWildcard(require("./StatusBar"));
StatusBar = function () {
return data;
};
return data;
}
Object.defineProperty(exports, "StatusBar", {
enumerable: true,
get: function () {
return StatusBar();
}
});
function Strings() {
const data = _interopRequireWildcard(require("./Strings"));
Strings = function () {
return data;
};
return data;
}
Object.defineProperty(exports, "Strings", {
enumerable: true,
get: function () {
return Strings();
}
});
function Styles() {
const data = _interopRequireWildcard(require("./Styles"));
Styles = function () {
return data;
};
return data;
}
Object.defineProperty(exports, "Styles", {
enumerable: true,
get: function () {
return Styles();
}
});
function Updates() {
const data = _interopRequireWildcard(require("./Updates"));
Updates = function () {
return data;
};
return data;
}
Object.defineProperty(exports, "Updates", {
enumerable: true,
get: function () {
return Updates();
}
});
function Version() {
const data = _interopRequireWildcard(require("./Version"));
Version = function () {
return data;
};
return data;
}
Object.defineProperty(exports, "Version", {
enumerable: true,
get: function () {
return Version();
}
});
function WindowSoftInputMode() {
const data = _interopRequireWildcard(require("./WindowSoftInputMode"));
WindowSoftInputMode = function () {
return data;
};
return data;
}
Object.defineProperty(exports, "WindowSoftInputMode", {
enumerable: true,
get: function () {
return WindowSoftInputMode();
}
});
function CodeMod() {
const data = _interopRequireWildcard(require("./codeMod"));
CodeMod = function () {
return data;
};
return data;
}
Object.defineProperty(exports, "CodeMod", {
enumerable: true,
get: function () {
return CodeMod();
}
});
function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
//# sourceMappingURL=index.js.map

File diff suppressed because one or more lines are too long

38
node_modules/@expo/config-plugins/build/index.d.ts generated vendored Normal file
View File

@@ -0,0 +1,38 @@
/**
* For internal use in Expo CLI
*/
import * as AndroidConfig from './android';
import * as IOSConfig from './ios';
import { provider, withGeneratedBaseMods } from './plugins/createBaseMod';
import { getAndroidModFileProviders, withAndroidBaseMods } from './plugins/withAndroidBaseMods';
import { getIosModFileProviders, withIosBaseMods } from './plugins/withIosBaseMods';
import * as XML from './utils/XML';
import * as CodeGenerator from './utils/generateCode';
import * as History from './utils/history';
import * as WarningAggregator from './utils/warnings';
export * as Updates from './utils/Updates';
export { IOSConfig, AndroidConfig };
export { WarningAggregator, CodeGenerator, History, XML };
/**
* These are the "config-plugins"
*/
export * from './Plugin.types';
export { withPlugins } from './plugins/withPlugins';
export { withRunOnce, createRunOncePlugin } from './plugins/withRunOnce';
export { withDangerousMod } from './plugins/withDangerousMod';
export { withFinalizedMod } from './plugins/withFinalizedMod';
export { withMod, withBaseMod } from './plugins/withMod';
export { withAppDelegate, withInfoPlist, withEntitlementsPlist, withExpoPlist, withXcodeProject, withPodfile, withPodfileProperties, } from './plugins/ios-plugins';
export { withAndroidManifest, withStringsXml, withAndroidColors, withAndroidColorsNight, withAndroidStyles, withMainActivity, withMainApplication, withProjectBuildGradle, withAppBuildGradle, withSettingsGradle, withGradleProperties, } from './plugins/android-plugins';
export { isValidAndroidAssetName, assertValidAndroidAssetName } from './utils/validations';
export { withStaticPlugin } from './plugins/withStaticPlugin';
export { compileModsAsync, withDefaultBaseMods, evalModsAsync } from './plugins/mod-compiler';
export { PluginError } from './utils/errors';
export declare const BaseMods: {
withGeneratedBaseMods: typeof withGeneratedBaseMods;
provider: typeof provider;
withAndroidBaseMods: typeof withAndroidBaseMods;
getAndroidModFileProviders: typeof getAndroidModFileProviders;
withIosBaseMods: typeof withIosBaseMods;
getIosModFileProviders: typeof getIosModFileProviders;
};

463
node_modules/@expo/config-plugins/build/index.js generated vendored Normal file
View File

@@ -0,0 +1,463 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var _exportNames = {
BaseMods: true,
AndroidConfig: true,
IOSConfig: true,
XML: true,
CodeGenerator: true,
History: true,
WarningAggregator: true,
Updates: true,
withPlugins: true,
withRunOnce: true,
createRunOncePlugin: true,
withDangerousMod: true,
withFinalizedMod: true,
withMod: true,
withBaseMod: true,
withAppDelegate: true,
withInfoPlist: true,
withEntitlementsPlist: true,
withExpoPlist: true,
withXcodeProject: true,
withPodfile: true,
withPodfileProperties: true,
withAndroidManifest: true,
withStringsXml: true,
withAndroidColors: true,
withAndroidColorsNight: true,
withAndroidStyles: true,
withMainActivity: true,
withMainApplication: true,
withProjectBuildGradle: true,
withAppBuildGradle: true,
withSettingsGradle: true,
withGradleProperties: true,
isValidAndroidAssetName: true,
assertValidAndroidAssetName: true,
withStaticPlugin: true,
compileModsAsync: true,
withDefaultBaseMods: true,
evalModsAsync: true,
PluginError: true
};
exports.IOSConfig = exports.History = exports.CodeGenerator = exports.BaseMods = exports.AndroidConfig = void 0;
Object.defineProperty(exports, "PluginError", {
enumerable: true,
get: function () {
return _errors().PluginError;
}
});
exports.XML = exports.WarningAggregator = exports.Updates = void 0;
Object.defineProperty(exports, "assertValidAndroidAssetName", {
enumerable: true,
get: function () {
return _validations().assertValidAndroidAssetName;
}
});
Object.defineProperty(exports, "compileModsAsync", {
enumerable: true,
get: function () {
return _modCompiler().compileModsAsync;
}
});
Object.defineProperty(exports, "createRunOncePlugin", {
enumerable: true,
get: function () {
return _withRunOnce().createRunOncePlugin;
}
});
Object.defineProperty(exports, "evalModsAsync", {
enumerable: true,
get: function () {
return _modCompiler().evalModsAsync;
}
});
Object.defineProperty(exports, "isValidAndroidAssetName", {
enumerable: true,
get: function () {
return _validations().isValidAndroidAssetName;
}
});
Object.defineProperty(exports, "withAndroidColors", {
enumerable: true,
get: function () {
return _androidPlugins().withAndroidColors;
}
});
Object.defineProperty(exports, "withAndroidColorsNight", {
enumerable: true,
get: function () {
return _androidPlugins().withAndroidColorsNight;
}
});
Object.defineProperty(exports, "withAndroidManifest", {
enumerable: true,
get: function () {
return _androidPlugins().withAndroidManifest;
}
});
Object.defineProperty(exports, "withAndroidStyles", {
enumerable: true,
get: function () {
return _androidPlugins().withAndroidStyles;
}
});
Object.defineProperty(exports, "withAppBuildGradle", {
enumerable: true,
get: function () {
return _androidPlugins().withAppBuildGradle;
}
});
Object.defineProperty(exports, "withAppDelegate", {
enumerable: true,
get: function () {
return _iosPlugins().withAppDelegate;
}
});
Object.defineProperty(exports, "withBaseMod", {
enumerable: true,
get: function () {
return _withMod().withBaseMod;
}
});
Object.defineProperty(exports, "withDangerousMod", {
enumerable: true,
get: function () {
return _withDangerousMod().withDangerousMod;
}
});
Object.defineProperty(exports, "withDefaultBaseMods", {
enumerable: true,
get: function () {
return _modCompiler().withDefaultBaseMods;
}
});
Object.defineProperty(exports, "withEntitlementsPlist", {
enumerable: true,
get: function () {
return _iosPlugins().withEntitlementsPlist;
}
});
Object.defineProperty(exports, "withExpoPlist", {
enumerable: true,
get: function () {
return _iosPlugins().withExpoPlist;
}
});
Object.defineProperty(exports, "withFinalizedMod", {
enumerable: true,
get: function () {
return _withFinalizedMod().withFinalizedMod;
}
});
Object.defineProperty(exports, "withGradleProperties", {
enumerable: true,
get: function () {
return _androidPlugins().withGradleProperties;
}
});
Object.defineProperty(exports, "withInfoPlist", {
enumerable: true,
get: function () {
return _iosPlugins().withInfoPlist;
}
});
Object.defineProperty(exports, "withMainActivity", {
enumerable: true,
get: function () {
return _androidPlugins().withMainActivity;
}
});
Object.defineProperty(exports, "withMainApplication", {
enumerable: true,
get: function () {
return _androidPlugins().withMainApplication;
}
});
Object.defineProperty(exports, "withMod", {
enumerable: true,
get: function () {
return _withMod().withMod;
}
});
Object.defineProperty(exports, "withPlugins", {
enumerable: true,
get: function () {
return _withPlugins().withPlugins;
}
});
Object.defineProperty(exports, "withPodfile", {
enumerable: true,
get: function () {
return _iosPlugins().withPodfile;
}
});
Object.defineProperty(exports, "withPodfileProperties", {
enumerable: true,
get: function () {
return _iosPlugins().withPodfileProperties;
}
});
Object.defineProperty(exports, "withProjectBuildGradle", {
enumerable: true,
get: function () {
return _androidPlugins().withProjectBuildGradle;
}
});
Object.defineProperty(exports, "withRunOnce", {
enumerable: true,
get: function () {
return _withRunOnce().withRunOnce;
}
});
Object.defineProperty(exports, "withSettingsGradle", {
enumerable: true,
get: function () {
return _androidPlugins().withSettingsGradle;
}
});
Object.defineProperty(exports, "withStaticPlugin", {
enumerable: true,
get: function () {
return _withStaticPlugin().withStaticPlugin;
}
});
Object.defineProperty(exports, "withStringsXml", {
enumerable: true,
get: function () {
return _androidPlugins().withStringsXml;
}
});
Object.defineProperty(exports, "withXcodeProject", {
enumerable: true,
get: function () {
return _iosPlugins().withXcodeProject;
}
});
function AndroidConfig() {
const data = _interopRequireWildcard(require("./android"));
AndroidConfig = function () {
return data;
};
return data;
}
Object.defineProperty(exports, "AndroidConfig", {
enumerable: true,
get: function () {
return AndroidConfig();
}
});
function IOSConfig() {
const data = _interopRequireWildcard(require("./ios"));
IOSConfig = function () {
return data;
};
return data;
}
Object.defineProperty(exports, "IOSConfig", {
enumerable: true,
get: function () {
return IOSConfig();
}
});
function _createBaseMod() {
const data = require("./plugins/createBaseMod");
_createBaseMod = function () {
return data;
};
return data;
}
function _withAndroidBaseMods() {
const data = require("./plugins/withAndroidBaseMods");
_withAndroidBaseMods = function () {
return data;
};
return data;
}
function _withIosBaseMods() {
const data = require("./plugins/withIosBaseMods");
_withIosBaseMods = function () {
return data;
};
return data;
}
function XML() {
const data = _interopRequireWildcard(require("./utils/XML"));
XML = function () {
return data;
};
return data;
}
Object.defineProperty(exports, "XML", {
enumerable: true,
get: function () {
return XML();
}
});
function CodeGenerator() {
const data = _interopRequireWildcard(require("./utils/generateCode"));
CodeGenerator = function () {
return data;
};
return data;
}
Object.defineProperty(exports, "CodeGenerator", {
enumerable: true,
get: function () {
return CodeGenerator();
}
});
function History() {
const data = _interopRequireWildcard(require("./utils/history"));
History = function () {
return data;
};
return data;
}
Object.defineProperty(exports, "History", {
enumerable: true,
get: function () {
return History();
}
});
function WarningAggregator() {
const data = _interopRequireWildcard(require("./utils/warnings"));
WarningAggregator = function () {
return data;
};
return data;
}
Object.defineProperty(exports, "WarningAggregator", {
enumerable: true,
get: function () {
return WarningAggregator();
}
});
function _Updates() {
const data = _interopRequireWildcard(require("./utils/Updates"));
_Updates = function () {
return data;
};
return data;
}
Object.defineProperty(exports, "Updates", {
enumerable: true,
get: function () {
return _Updates();
}
});
var _Plugin = require("./Plugin.types");
Object.keys(_Plugin).forEach(function (key) {
if (key === "default" || key === "__esModule") return;
if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;
if (key in exports && exports[key] === _Plugin[key]) return;
Object.defineProperty(exports, key, {
enumerable: true,
get: function () {
return _Plugin[key];
}
});
});
function _withPlugins() {
const data = require("./plugins/withPlugins");
_withPlugins = function () {
return data;
};
return data;
}
function _withRunOnce() {
const data = require("./plugins/withRunOnce");
_withRunOnce = function () {
return data;
};
return data;
}
function _withDangerousMod() {
const data = require("./plugins/withDangerousMod");
_withDangerousMod = function () {
return data;
};
return data;
}
function _withFinalizedMod() {
const data = require("./plugins/withFinalizedMod");
_withFinalizedMod = function () {
return data;
};
return data;
}
function _withMod() {
const data = require("./plugins/withMod");
_withMod = function () {
return data;
};
return data;
}
function _iosPlugins() {
const data = require("./plugins/ios-plugins");
_iosPlugins = function () {
return data;
};
return data;
}
function _androidPlugins() {
const data = require("./plugins/android-plugins");
_androidPlugins = function () {
return data;
};
return data;
}
function _validations() {
const data = require("./utils/validations");
_validations = function () {
return data;
};
return data;
}
function _withStaticPlugin() {
const data = require("./plugins/withStaticPlugin");
_withStaticPlugin = function () {
return data;
};
return data;
}
function _modCompiler() {
const data = require("./plugins/mod-compiler");
_modCompiler = function () {
return data;
};
return data;
}
function _errors() {
const data = require("./utils/errors");
_errors = function () {
return data;
};
return data;
}
function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
/**
* For internal use in Expo CLI
*/
// TODO: Remove
/**
* These are the "config-plugins"
*/
const BaseMods = exports.BaseMods = {
withGeneratedBaseMods: _createBaseMod().withGeneratedBaseMods,
provider: _createBaseMod().provider,
withAndroidBaseMods: _withAndroidBaseMods().withAndroidBaseMods,
getAndroidModFileProviders: _withAndroidBaseMods().getAndroidModFileProviders,
withIosBaseMods: _withIosBaseMods().withIosBaseMods,
getIosModFileProviders: _withIosBaseMods().getIosModFileProviders
};
//# sourceMappingURL=index.js.map

1
node_modules/@expo/config-plugins/build/index.js.map generated vendored Normal file

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,33 @@
import { ExpoConfig } from '@expo/config-types';
import { XcodeProject } from 'xcode';
import { ConfigPlugin } from '../Plugin.types';
type Bitcode = NonNullable<ExpoConfig['ios']>['bitcode'];
/**
* Plugin to set a bitcode preference for the Xcode project
* based on the project's Expo config `ios.bitcode` value.
*/
export declare const withBitcode: ConfigPlugin;
/**
* Plugin to set a custom bitcode preference for the Xcode project.
* Does not read from the Expo config `ios.bitcode`.
*
* @param bitcode custom bitcode setting.
*/
export declare const withCustomBitcode: ConfigPlugin<Bitcode>;
/**
* Get the bitcode preference from the Expo config.
*/
export declare function getBitcode(config: Pick<ExpoConfig, 'ios'>): Bitcode;
/**
* Enable or disable the `ENABLE_BITCODE` property of the project configurations.
*/
export declare function setBitcodeWithConfig(config: Pick<ExpoConfig, 'ios'>, { project }: {
project: XcodeProject;
}): XcodeProject;
/**
* Enable or disable the `ENABLE_BITCODE` property.
*/
export declare function setBitcode(bitcode: Bitcode, { project }: {
project: XcodeProject;
}): XcodeProject;
export {};

110
node_modules/@expo/config-plugins/build/ios/Bitcode.js generated vendored Normal file
View File

@@ -0,0 +1,110 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.getBitcode = getBitcode;
exports.setBitcode = setBitcode;
exports.setBitcodeWithConfig = setBitcodeWithConfig;
exports.withCustomBitcode = exports.withBitcode = void 0;
function _Xcodeproj() {
const data = require("./utils/Xcodeproj");
_Xcodeproj = function () {
return data;
};
return data;
}
function _iosPlugins() {
const data = require("../plugins/ios-plugins");
_iosPlugins = function () {
return data;
};
return data;
}
function _warnings() {
const data = require("../utils/warnings");
_warnings = function () {
return data;
};
return data;
}
/**
* Plugin to set a bitcode preference for the Xcode project
* based on the project's Expo config `ios.bitcode` value.
*/
const withBitcode = config => {
return (0, _iosPlugins().withXcodeProject)(config, async config => {
config.modResults = await setBitcodeWithConfig(config, {
project: config.modResults
});
return config;
});
};
/**
* Plugin to set a custom bitcode preference for the Xcode project.
* Does not read from the Expo config `ios.bitcode`.
*
* @param bitcode custom bitcode setting.
*/
exports.withBitcode = withBitcode;
const withCustomBitcode = (config, bitcode) => {
return (0, _iosPlugins().withXcodeProject)(config, async config => {
config.modResults = await setBitcode(bitcode, {
project: config.modResults
});
return config;
});
};
/**
* Get the bitcode preference from the Expo config.
*/
exports.withCustomBitcode = withCustomBitcode;
function getBitcode(config) {
return config.ios?.bitcode;
}
/**
* Enable or disable the `ENABLE_BITCODE` property of the project configurations.
*/
function setBitcodeWithConfig(config, {
project
}) {
const bitcode = getBitcode(config);
return setBitcode(bitcode, {
project
});
}
/**
* Enable or disable the `ENABLE_BITCODE` property.
*/
function setBitcode(bitcode, {
project
}) {
const isDefaultBehavior = bitcode == null;
// If the value is undefined, then do nothing.
if (isDefaultBehavior) {
return project;
}
const targetName = typeof bitcode === 'string' ? bitcode : undefined;
const isBitcodeEnabled = !!bitcode;
if (targetName) {
// Assert if missing
const configs = Object.entries(project.pbxXCBuildConfigurationSection()).filter(_Xcodeproj().isNotComment);
const hasConfiguration = configs.find(([, configuration]) => configuration.name === targetName);
if (hasConfiguration) {
// If targetName is defined then disable bitcode everywhere.
project.addBuildProperty('ENABLE_BITCODE', 'NO');
} else {
const names = [
// Remove duplicates, wrap in double quotes, and sort alphabetically.
...new Set(configs.map(([, configuration]) => `"${configuration.name}"`))].sort();
(0, _warnings().addWarningIOS)('ios.bitcode', `No configuration named "${targetName}". Expected one of: ${names.join(', ')}.`);
}
}
project.addBuildProperty('ENABLE_BITCODE', isBitcodeEnabled ? 'YES' : 'NO', targetName);
return project;
}
//# sourceMappingURL=Bitcode.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,27 @@
import type { ExpoConfig } from '@expo/config-types';
import type { ConfigPlugin } from '../Plugin.types';
import { BuildPropertiesConfig, ConfigToPropertyRuleType } from '../utils/BuildProperties.types';
/**
* Creates a `withPodfileProperties` config-plugin based on given config to property mapping rules.
*
* The factory supports two modes from generic type inference
* ```ts
* // config-plugin without `props`, it will implicitly use the expo config as source config.
* createBuildPodfilePropsConfigPlugin<ExpoConfig>(): ConfigPlugin<void>;
*
* // config-plugin with a parameter `props: CustomType`, it will use the `props` as source config.
* createBuildPodfilePropsConfigPlugin<CustomType>(): ConfigPlugin<CustomType>;
* ```
*
* @param configToPropertyRules config to property mapping rules
* @param name the config plugin name
*/
export declare function createBuildPodfilePropsConfigPlugin<SourceConfigType extends BuildPropertiesConfig>(configToPropertyRules: ConfigToPropertyRuleType<SourceConfigType>[], name?: string): ConfigPlugin<SourceConfigType extends ExpoConfig ? void : SourceConfigType>;
/**
* A config-plugin to update `ios/Podfile.properties.json` from the `jsEngine` in expo config
*/
export declare const withJsEnginePodfileProps: ConfigPlugin<void>;
export declare function updateIosBuildPropertiesFromConfig<SourceConfigType extends BuildPropertiesConfig>(config: SourceConfigType, podfileProperties: Record<string, string>, configToPropertyRules: ConfigToPropertyRuleType<SourceConfigType>[]): Record<string, string>;
export declare function updateIosBuildProperty(podfileProperties: Record<string, string>, name: string, value: string | null | undefined, options?: {
removePropWhenValueIsNull?: boolean;
}): Record<string, string>;

View File

@@ -0,0 +1,67 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.createBuildPodfilePropsConfigPlugin = createBuildPodfilePropsConfigPlugin;
exports.updateIosBuildPropertiesFromConfig = updateIosBuildPropertiesFromConfig;
exports.updateIosBuildProperty = updateIosBuildProperty;
exports.withJsEnginePodfileProps = void 0;
function _iosPlugins() {
const data = require("../plugins/ios-plugins");
_iosPlugins = function () {
return data;
};
return data;
}
/**
* Creates a `withPodfileProperties` config-plugin based on given config to property mapping rules.
*
* The factory supports two modes from generic type inference
* ```ts
* // config-plugin without `props`, it will implicitly use the expo config as source config.
* createBuildPodfilePropsConfigPlugin<ExpoConfig>(): ConfigPlugin<void>;
*
* // config-plugin with a parameter `props: CustomType`, it will use the `props` as source config.
* createBuildPodfilePropsConfigPlugin<CustomType>(): ConfigPlugin<CustomType>;
* ```
*
* @param configToPropertyRules config to property mapping rules
* @param name the config plugin name
*/
function createBuildPodfilePropsConfigPlugin(configToPropertyRules, name) {
const withUnknown = (config, sourceConfig) => (0, _iosPlugins().withPodfileProperties)(config, config => {
config.modResults = updateIosBuildPropertiesFromConfig(sourceConfig ?? config, config.modResults, configToPropertyRules);
return config;
});
if (name) {
Object.defineProperty(withUnknown, 'name', {
value: name
});
}
return withUnknown;
}
/**
* A config-plugin to update `ios/Podfile.properties.json` from the `jsEngine` in expo config
*/
const withJsEnginePodfileProps = exports.withJsEnginePodfileProps = createBuildPodfilePropsConfigPlugin([{
propName: 'expo.jsEngine',
propValueGetter: config => config.ios?.jsEngine ?? config.jsEngine ?? 'hermes'
}], 'withJsEnginePodfileProps');
function updateIosBuildPropertiesFromConfig(config, podfileProperties, configToPropertyRules) {
for (const configToProperty of configToPropertyRules) {
const value = configToProperty.propValueGetter(config);
updateIosBuildProperty(podfileProperties, configToProperty.propName, value);
}
return podfileProperties;
}
function updateIosBuildProperty(podfileProperties, name, value, options) {
if (value) {
podfileProperties[name] = value;
} else if (options?.removePropWhenValueIsNull) {
delete podfileProperties[name];
}
return podfileProperties;
}
//# sourceMappingURL=BuildProperties.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"BuildProperties.js","names":["_iosPlugins","data","require","createBuildPodfilePropsConfigPlugin","configToPropertyRules","name","withUnknown","config","sourceConfig","withPodfileProperties","modResults","updateIosBuildPropertiesFromConfig","Object","defineProperty","value","withJsEnginePodfileProps","exports","propName","propValueGetter","ios","jsEngine","podfileProperties","configToProperty","updateIosBuildProperty","options","removePropWhenValueIsNull"],"sources":["../../src/ios/BuildProperties.ts"],"sourcesContent":["import type { ExpoConfig } from '@expo/config-types';\n\nimport type { ConfigPlugin } from '../Plugin.types';\nimport { withPodfileProperties } from '../plugins/ios-plugins';\nimport { BuildPropertiesConfig, ConfigToPropertyRuleType } from '../utils/BuildProperties.types';\n\n/**\n * Creates a `withPodfileProperties` config-plugin based on given config to property mapping rules.\n *\n * The factory supports two modes from generic type inference\n * ```ts\n * // config-plugin without `props`, it will implicitly use the expo config as source config.\n * createBuildPodfilePropsConfigPlugin<ExpoConfig>(): ConfigPlugin<void>;\n *\n * // config-plugin with a parameter `props: CustomType`, it will use the `props` as source config.\n * createBuildPodfilePropsConfigPlugin<CustomType>(): ConfigPlugin<CustomType>;\n * ```\n *\n * @param configToPropertyRules config to property mapping rules\n * @param name the config plugin name\n */\nexport function createBuildPodfilePropsConfigPlugin<SourceConfigType extends BuildPropertiesConfig>(\n configToPropertyRules: ConfigToPropertyRuleType<SourceConfigType>[],\n name?: string\n) {\n const withUnknown: ConfigPlugin<SourceConfigType extends ExpoConfig ? void : SourceConfigType> = (\n config,\n sourceConfig\n ) =>\n withPodfileProperties(config, (config) => {\n config.modResults = updateIosBuildPropertiesFromConfig(\n (sourceConfig ?? config) as SourceConfigType,\n config.modResults,\n configToPropertyRules\n );\n return config;\n });\n if (name) {\n Object.defineProperty(withUnknown, 'name', {\n value: name,\n });\n }\n return withUnknown;\n}\n\n/**\n * A config-plugin to update `ios/Podfile.properties.json` from the `jsEngine` in expo config\n */\nexport const withJsEnginePodfileProps = createBuildPodfilePropsConfigPlugin<ExpoConfig>(\n [\n {\n propName: 'expo.jsEngine',\n propValueGetter: (config) => config.ios?.jsEngine ?? config.jsEngine ?? 'hermes',\n },\n ],\n 'withJsEnginePodfileProps'\n);\n\nexport function updateIosBuildPropertiesFromConfig<SourceConfigType extends BuildPropertiesConfig>(\n config: SourceConfigType,\n podfileProperties: Record<string, string>,\n configToPropertyRules: ConfigToPropertyRuleType<SourceConfigType>[]\n) {\n for (const configToProperty of configToPropertyRules) {\n const value = configToProperty.propValueGetter(config);\n updateIosBuildProperty(podfileProperties, configToProperty.propName, value);\n }\n return podfileProperties;\n}\n\nexport function updateIosBuildProperty(\n podfileProperties: Record<string, string>,\n name: string,\n value: string | null | undefined,\n options?: { removePropWhenValueIsNull?: boolean }\n) {\n if (value) {\n podfileProperties[name] = value;\n } else if (options?.removePropWhenValueIsNull) {\n delete podfileProperties[name];\n }\n return podfileProperties;\n}\n"],"mappings":";;;;;;;;;AAGA,SAAAA,YAAA;EAAA,MAAAC,IAAA,GAAAC,OAAA;EAAAF,WAAA,YAAAA,CAAA;IAAA,OAAAC,IAAA;EAAA;EAAA,OAAAA,IAAA;AAAA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAASE,mCAAmCA,CACjDC,qBAAmE,EACnEC,IAAa,EACb;EACA,MAAMC,WAAwF,GAAGA,CAC/FC,MAAM,EACNC,YAAY,KAEZ,IAAAC,mCAAqB,EAACF,MAAM,EAAGA,MAAM,IAAK;IACxCA,MAAM,CAACG,UAAU,GAAGC,kCAAkC,CACnDH,YAAY,IAAID,MAAM,EACvBA,MAAM,CAACG,UAAU,EACjBN,qBACF,CAAC;IACD,OAAOG,MAAM;EACf,CAAC,CAAC;EACJ,IAAIF,IAAI,EAAE;IACRO,MAAM,CAACC,cAAc,CAACP,WAAW,EAAE,MAAM,EAAE;MACzCQ,KAAK,EAAET;IACT,CAAC,CAAC;EACJ;EACA,OAAOC,WAAW;AACpB;;AAEA;AACA;AACA;AACO,MAAMS,wBAAwB,GAAAC,OAAA,CAAAD,wBAAA,GAAGZ,mCAAmC,CACzE,CACE;EACEc,QAAQ,EAAE,eAAe;EACzBC,eAAe,EAAGX,MAAM,IAAKA,MAAM,CAACY,GAAG,EAAEC,QAAQ,IAAIb,MAAM,CAACa,QAAQ,IAAI;AAC1E,CAAC,CACF,EACD,0BACF,CAAC;AAEM,SAAST,kCAAkCA,CAChDJ,MAAwB,EACxBc,iBAAyC,EACzCjB,qBAAmE,EACnE;EACA,KAAK,MAAMkB,gBAAgB,IAAIlB,qBAAqB,EAAE;IACpD,MAAMU,KAAK,GAAGQ,gBAAgB,CAACJ,eAAe,CAACX,MAAM,CAAC;IACtDgB,sBAAsB,CAACF,iBAAiB,EAAEC,gBAAgB,CAACL,QAAQ,EAAEH,KAAK,CAAC;EAC7E;EACA,OAAOO,iBAAiB;AAC1B;AAEO,SAASE,sBAAsBA,CACpCF,iBAAyC,EACzChB,IAAY,EACZS,KAAgC,EAChCU,OAAiD,EACjD;EACA,IAAIV,KAAK,EAAE;IACTO,iBAAiB,CAAChB,IAAI,CAAC,GAAGS,KAAK;EACjC,CAAC,MAAM,IAAIU,OAAO,EAAEC,yBAAyB,EAAE;IAC7C,OAAOJ,iBAAiB,CAAChB,IAAI,CAAC;EAChC;EACA,OAAOgB,iBAAiB;AAC1B","ignoreList":[]}

View File

@@ -0,0 +1,10 @@
export declare function getSchemesFromXcodeproj(projectRoot: string): string[];
export declare function getRunnableSchemesFromXcodeproj(projectRoot: string, { configuration }?: {
configuration?: 'Debug' | 'Release';
}): {
name: string;
osType: string;
type: string;
}[];
export declare function getApplicationTargetNameForSchemeAsync(projectRoot: string, scheme: string): Promise<string>;
export declare function getArchiveBuildConfigurationForSchemeAsync(projectRoot: string, scheme: string): Promise<string>;

View File

@@ -0,0 +1,113 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.getApplicationTargetNameForSchemeAsync = getApplicationTargetNameForSchemeAsync;
exports.getArchiveBuildConfigurationForSchemeAsync = getArchiveBuildConfigurationForSchemeAsync;
exports.getRunnableSchemesFromXcodeproj = getRunnableSchemesFromXcodeproj;
exports.getSchemesFromXcodeproj = getSchemesFromXcodeproj;
function _Paths() {
const data = require("./Paths");
_Paths = function () {
return data;
};
return data;
}
function _Target() {
const data = require("./Target");
_Target = function () {
return data;
};
return data;
}
function _Xcodeproj() {
const data = require("./utils/Xcodeproj");
_Xcodeproj = function () {
return data;
};
return data;
}
function _XML() {
const data = require("../utils/XML");
_XML = function () {
return data;
};
return data;
}
function getSchemesFromXcodeproj(projectRoot) {
return (0, _Paths().findSchemeNames)(projectRoot);
}
function getRunnableSchemesFromXcodeproj(projectRoot, {
configuration = 'Debug'
} = {}) {
const project = (0, _Xcodeproj().getPbxproj)(projectRoot);
return (0, _Target().findSignableTargets)(project).map(([, target]) => {
let osType = 'iOS';
const type = (0, _Xcodeproj().unquote)(target.productType);
if (type === _Target().TargetType.WATCH) {
osType = 'watchOS';
} else if (
// (apps) com.apple.product-type.application
// (app clips) com.apple.product-type.application.on-demand-install-capable
// NOTE(EvanBacon): This matches against `watchOS` as well so we check for watch first.
type.startsWith(_Target().TargetType.APPLICATION)) {
// Attempt to resolve the platform SDK for each target so we can filter devices.
const xcConfigurationList = project.hash.project.objects.XCConfigurationList[target.buildConfigurationList];
if (xcConfigurationList) {
const buildConfiguration = xcConfigurationList.buildConfigurations.find(value => value.comment === configuration) || xcConfigurationList.buildConfigurations[0];
if (buildConfiguration?.value) {
const xcBuildConfiguration = project.hash.project.objects.XCBuildConfiguration?.[buildConfiguration.value];
const buildSdkRoot = xcBuildConfiguration.buildSettings.SDKROOT;
if (buildSdkRoot === 'appletvos' || 'TVOS_DEPLOYMENT_TARGET' in xcBuildConfiguration.buildSettings) {
// Is a TV app...
osType = 'tvOS';
} else if (buildSdkRoot === 'iphoneos') {
osType = 'iOS';
}
}
}
}
return {
name: (0, _Xcodeproj().unquote)(target.name),
osType,
type: (0, _Xcodeproj().unquote)(target.productType)
};
});
}
async function readSchemeAsync(projectRoot, scheme) {
const allSchemePaths = (0, _Paths().findSchemePaths)(projectRoot);
// NOTE(cedric): test on POSIX or UNIX separators, where UNIX needs to be double-escaped in the template literal and regex
const re = new RegExp(`[\\\\/]${scheme}.xcscheme`, 'i');
const schemePath = allSchemePaths.find(i => re.exec(i));
if (schemePath) {
return await (0, _XML().readXMLAsync)({
path: schemePath
});
} else {
throw new Error(`scheme '${scheme}' does not exist, make sure it's marked as shared`);
}
}
async function getApplicationTargetNameForSchemeAsync(projectRoot, scheme) {
const schemeXML = await readSchemeAsync(projectRoot, scheme);
const buildActionEntry = schemeXML?.Scheme?.BuildAction?.[0]?.BuildActionEntries?.[0]?.BuildActionEntry;
const targetName = buildActionEntry?.length === 1 ? getBlueprintName(buildActionEntry[0]) : getBlueprintName(buildActionEntry?.find(entry => {
return entry.BuildableReference?.[0]?.['$']?.BuildableName?.endsWith('.app');
}));
if (!targetName) {
throw new Error(`${scheme}.xcscheme seems to be corrupted`);
}
return targetName;
}
async function getArchiveBuildConfigurationForSchemeAsync(projectRoot, scheme) {
const schemeXML = await readSchemeAsync(projectRoot, scheme);
const buildConfiguration = schemeXML?.Scheme?.ArchiveAction?.[0]?.['$']?.buildConfiguration;
if (!buildConfiguration) {
throw new Error(`${scheme}.xcscheme seems to be corrupted`);
}
return buildConfiguration;
}
function getBlueprintName(entry) {
return entry?.BuildableReference?.[0]?.['$']?.BlueprintName;
}
//# sourceMappingURL=BuildScheme.js.map

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