expo-native-variants 0.1.0-alpha.0 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +56 -4
- package/dist/config/index.d.mts +1 -1
- package/dist/config/index.d.ts +1 -1
- package/dist/config/index.js +82 -2
- package/dist/config/index.js.map +1 -1
- package/dist/config/index.mjs +82 -2
- package/dist/config/index.mjs.map +1 -1
- package/dist/index.d.mts +3 -3
- package/dist/index.d.ts +3 -3
- package/dist/index.js +252 -46
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +251 -46
- package/dist/index.mjs.map +1 -1
- package/dist/{types-BEqszr6O.d.mts → types-CJFxZDYt.d.mts} +13 -1
- package/dist/{types-BEqszr6O.d.ts → types-CJFxZDYt.d.ts} +13 -1
- package/package.json +3 -1
package/README.md
CHANGED
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
Generate every native app variant in one Expo prebuild. Switch between development, preview, and production in Xcode or Android Studio while keeping `ios/` and `android/` generated and ignored by Git.
|
|
4
4
|
|
|
5
|
-
The
|
|
5
|
+
The first stable release is available as `0.1.0` under the `latest` tag.
|
|
6
6
|
|
|
7
|
-
This community-maintained package targets Expo SDK 57. It is an early release for the standard Expo native templates with one iOS application target and one Android flavor dimension. See [compatibility](#compatibility) before adding it to an existing app.
|
|
7
|
+
This community-maintained package targets Expo SDK 57. It is an early release for the standard Expo native templates with one iOS application target, optional explicitly configured iOS extension targets, and one Android flavor dimension. See [compatibility](#compatibility) before adding it to an existing app.
|
|
8
8
|
|
|
9
9
|
See the [validation record](./VALIDATION.md) for tested toolchain versions and results.
|
|
10
10
|
|
|
@@ -12,6 +12,10 @@ See the [validation record](./VALIDATION.md) for tested toolchain versions and r
|
|
|
12
12
|
|
|
13
13
|
Install `expo-native-variants` in your Expo project and add it to the `plugins` array in your app config. Use complete application identifiers so the variants can be installed together.
|
|
14
14
|
|
|
15
|
+
```sh
|
|
16
|
+
bun add expo-native-variants@next
|
|
17
|
+
```
|
|
18
|
+
|
|
15
19
|
```json
|
|
16
20
|
{
|
|
17
21
|
"expo": {
|
|
@@ -87,6 +91,52 @@ On iOS, use Xcode for custom configurations. Expo CLI 57 defaults to the ordinar
|
|
|
87
91
|
| `ios.xcodeScheme` | Optional Xcode build-scheme name |
|
|
88
92
|
| `android.applicationId` | Optional replacement for the shared identifier on Android |
|
|
89
93
|
|
|
94
|
+
### iOS extension targets
|
|
95
|
+
|
|
96
|
+
The plugin can add the variant matrix to extension targets created by another config plugin. List each extension by its exact Xcode target name and give it a bundle identifier suffix:
|
|
97
|
+
|
|
98
|
+
```ts
|
|
99
|
+
import type {NativeVariantsConfigInput} from 'expo-native-variants/config';
|
|
100
|
+
|
|
101
|
+
const options = {
|
|
102
|
+
defaultVariant: 'production',
|
|
103
|
+
ios: {
|
|
104
|
+
targets: {
|
|
105
|
+
AcmeShare: {bundleIdentifierSuffix: '.share'},
|
|
106
|
+
AcmeWidget: {bundleIdentifierSuffix: '.widget'},
|
|
107
|
+
},
|
|
108
|
+
},
|
|
109
|
+
variants: {
|
|
110
|
+
development: {
|
|
111
|
+
displayName: 'Acme Dev',
|
|
112
|
+
applicationId: 'com.acme.app.dev',
|
|
113
|
+
urlScheme: 'acme-dev',
|
|
114
|
+
},
|
|
115
|
+
production: {
|
|
116
|
+
displayName: 'Acme',
|
|
117
|
+
applicationId: 'com.acme.app',
|
|
118
|
+
urlScheme: 'acme',
|
|
119
|
+
},
|
|
120
|
+
},
|
|
121
|
+
} satisfies NativeVariantsConfigInput;
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
This produces `com.acme.app.dev.share` and `com.acme.app.share` for `AcmeShare`, plus the corresponding widget identifiers. The target-generating plugin remains responsible for creating targets, source files, build phases, frameworks, plist files, and entitlements. Register that plugin before `expo-native-variants`. The `createNativeVariantsConfig` helper already places `expo-native-variants` last.
|
|
125
|
+
|
|
126
|
+
Keep each suffix equal to the suffix in the target generator's own configuration. `expo-native-variants` validates and applies the resulting identifiers but does not rewrite that plugin's configuration.
|
|
127
|
+
|
|
128
|
+
The extension's standard `Debug` and `Release` configurations are the templates for every generated variant configuration. Their Swift version, deployment target, plist path, signing settings, entitlements path, frameworks, and build phases remain intact. The application alone receives the variant display name and URL scheme.
|
|
129
|
+
|
|
130
|
+
For a shared app group, use the generated application-identifier build setting in both the app and extension entitlements:
|
|
131
|
+
|
|
132
|
+
```ts
|
|
133
|
+
const applicationGroups = [
|
|
134
|
+
'group.$(EXPO_NATIVE_VARIANT_BUNDLE_IDENTIFIER)',
|
|
135
|
+
];
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
For example, pass that array through `ios.entitlements` for the app and through the extension generator's entitlements configuration. Xcode expands it to the main application bundle identifier for each configuration, so an extension and its containing app share `group.com.acme.app.dev` in development and `group.com.acme.app` in production.
|
|
139
|
+
|
|
90
140
|
Variant keys determine the Android flavor names and generated iOS configuration names. Identifiers must be unique on each platform. The plugin rejects invalid names and collisions before generating native settings.
|
|
91
141
|
|
|
92
142
|
The plugin changes the display name while keeping the native target, product name, and Android source namespace stable. It owns its generated files and configuration sections. Repeated prebuilds update them, including renamed or removed variants. If you remove the plugin itself, perform a clean prebuild to remove its native output.
|
|
@@ -148,7 +198,9 @@ The [example profiles](./example/eas.json) select Android Gradle tasks and ordin
|
|
|
148
198
|
|
|
149
199
|
## Compatibility
|
|
150
200
|
|
|
151
|
-
The
|
|
201
|
+
The current release supports Expo's generated Android Groovy template, exactly one iOS application target, and explicitly configured iOS app-extension or ExtensionKit-extension targets. Existing Android product flavors, additional flavor dimensions, Kotlin DSL projects, native test targets, App Clips, watch applications, and other target product types remain outside its supported layout. Every additional native target must appear in `ios.targets`; the plugin rejects an unconfigured target rather than generating an incomplete configuration matrix.
|
|
202
|
+
|
|
203
|
+
Extension support has been tested with `@bacons/apple-targets@5.0.0` using clean Expo prebuilds. That package currently fails while updating its own target during a repeated `expo prebuild --no-clean` on this toolchain, before `expo-native-variants` runs. Use clean prebuilds when combining these versions.
|
|
152
204
|
|
|
153
205
|
Expo SDK 57's default iOS template does not enable scene lifecycle support. A build linked with the iOS 27 SDK can crash on iOS 27 before JavaScript starts. Use Expo's [official scene-support configuration](https://github.com/expo/fyi/blob/main/ios-scene-lifecycle.md) when targeting that combination. The example's launch tests use iOS 26.5.
|
|
154
206
|
|
|
@@ -162,7 +214,7 @@ EAS support remains experimental until its credential preflight and cloud artifa
|
|
|
162
214
|
|
|
163
215
|
The [example](./example) contains three variants and displays the installed identifier, resolved variant, and debug/release mode. Install the repository dependencies, build the package, generate the example's native projects, and open its iOS workspace or Android project.
|
|
164
216
|
|
|
165
|
-
The root package scripts provide `build`, `typecheck`, `test`, `test:integration`, and `verify:package`. After generating the example and installing native dependencies, `build:native:android` and `build:native:ios` build every debug/release combination without another prebuild. Native build validation requires Xcode with CocoaPods on macOS, or an Android SDK and compatible Java installation. Keep the example's generated native folders out of commits.
|
|
217
|
+
This repository uses Bun 1.3.1. The root package scripts provide `build`, `typecheck`, `test`, `test:integration`, and `verify:package`. After generating the example and installing native dependencies, `build:native:android` and `build:native:ios` build every debug/release combination without another prebuild. Native build validation requires Xcode with CocoaPods on macOS, or an Android SDK and compatible Java installation. Keep the example's generated native folders out of commits.
|
|
166
218
|
|
|
167
219
|
## License
|
|
168
220
|
|
package/dist/config/index.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ExpoConfig } from 'expo/config';
|
|
2
|
-
import { N as NativeVariantsOptions, a as NativeVariantOptions } from '../types-
|
|
2
|
+
import { N as NativeVariantsOptions, a as NativeVariantOptions } from '../types-CJFxZDYt.mjs';
|
|
3
3
|
|
|
4
4
|
type CreateNativeVariantsConfigArgs = Readonly<{
|
|
5
5
|
config: ExpoConfig;
|
package/dist/config/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ExpoConfig } from 'expo/config';
|
|
2
|
-
import { N as NativeVariantsOptions, a as NativeVariantOptions } from '../types-
|
|
2
|
+
import { N as NativeVariantsOptions, a as NativeVariantOptions } from '../types-CJFxZDYt.js';
|
|
3
3
|
|
|
4
4
|
type CreateNativeVariantsConfigArgs = Readonly<{
|
|
5
5
|
config: ExpoConfig;
|
package/dist/config/index.js
CHANGED
|
@@ -25,7 +25,9 @@ __export(config_exports, {
|
|
|
25
25
|
module.exports = __toCommonJS(config_exports);
|
|
26
26
|
|
|
27
27
|
// src/options/normalize.ts
|
|
28
|
-
var ROOT_KEYS = /* @__PURE__ */ new Set(["canonicalVariant", "defaultVariant", "variants"]);
|
|
28
|
+
var ROOT_KEYS = /* @__PURE__ */ new Set(["canonicalVariant", "defaultVariant", "ios", "variants"]);
|
|
29
|
+
var ROOT_IOS_KEYS = /* @__PURE__ */ new Set(["targets"]);
|
|
30
|
+
var IOS_TARGET_KEYS = /* @__PURE__ */ new Set(["bundleIdentifierSuffix"]);
|
|
29
31
|
var VARIANT_KEYS = /* @__PURE__ */ new Set([
|
|
30
32
|
"android",
|
|
31
33
|
"applicationId",
|
|
@@ -91,7 +93,35 @@ function normalizeNativeVariants({
|
|
|
91
93
|
throw new Error(`canonicalVariant references unknown variant "${canonicalVariant}".`);
|
|
92
94
|
}
|
|
93
95
|
const variants = Object.freeze(normalizedVariants);
|
|
94
|
-
|
|
96
|
+
const iosTargets = normalizeIosTargets({
|
|
97
|
+
value: optionsRecord.ios,
|
|
98
|
+
variants
|
|
99
|
+
});
|
|
100
|
+
return Object.freeze({ canonicalVariant: canonical, iosTargets, variants });
|
|
101
|
+
}
|
|
102
|
+
function normalizeIosTargets({
|
|
103
|
+
value,
|
|
104
|
+
variants
|
|
105
|
+
}) {
|
|
106
|
+
if (value === void 0) {
|
|
107
|
+
return Object.freeze([]);
|
|
108
|
+
}
|
|
109
|
+
const ios = requireRecord(value, "Plugin options ios");
|
|
110
|
+
assertKnownKeys(ios, ROOT_IOS_KEYS, "Plugin options ios");
|
|
111
|
+
const targets = requireRecord(ios.targets, "Plugin options ios.targets");
|
|
112
|
+
const normalizedTargets = Object.entries(targets).map(([name, target]) => {
|
|
113
|
+
validateFileLabel(name, `iOS target name "${name}"`);
|
|
114
|
+
const targetRecord = requireRecord(target, `iOS target "${name}"`);
|
|
115
|
+
assertKnownKeys(targetRecord, IOS_TARGET_KEYS, `iOS target "${name}"`);
|
|
116
|
+
const bundleIdentifierSuffix = requireNonemptyString(
|
|
117
|
+
targetRecord.bundleIdentifierSuffix,
|
|
118
|
+
`iOS target "${name}" bundleIdentifierSuffix`
|
|
119
|
+
);
|
|
120
|
+
validateBundleIdentifierSuffix({ bundleIdentifierSuffix, name, variants });
|
|
121
|
+
return Object.freeze({ bundleIdentifierSuffix, name });
|
|
122
|
+
});
|
|
123
|
+
assertUniqueIosTargets(normalizedTargets, variants);
|
|
124
|
+
return Object.freeze(normalizedTargets);
|
|
95
125
|
}
|
|
96
126
|
function normalizeVariant({
|
|
97
127
|
configName,
|
|
@@ -231,6 +261,56 @@ function validateUniqueValues(variants) {
|
|
|
231
261
|
variants
|
|
232
262
|
});
|
|
233
263
|
}
|
|
264
|
+
function validateBundleIdentifierSuffix({
|
|
265
|
+
bundleIdentifierSuffix,
|
|
266
|
+
name,
|
|
267
|
+
variants
|
|
268
|
+
}) {
|
|
269
|
+
if (!bundleIdentifierSuffix.startsWith(".") || bundleIdentifierSuffix === ".") {
|
|
270
|
+
throw new Error(
|
|
271
|
+
`iOS target "${name}" bundleIdentifierSuffix must start with a period followed by a valid bundle identifier segment.`
|
|
272
|
+
);
|
|
273
|
+
}
|
|
274
|
+
for (const variant of variants) {
|
|
275
|
+
validateIosIdentifier(
|
|
276
|
+
`${variant.iosBundleIdentifier}${bundleIdentifierSuffix}`,
|
|
277
|
+
`iOS target "${name}" bundle identifier for variant "${variant.key}"`
|
|
278
|
+
);
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
function assertUniqueIosTargets(targets, variants) {
|
|
282
|
+
const targetByName = /* @__PURE__ */ new Map();
|
|
283
|
+
const identifierOwnerByValue = new Map(
|
|
284
|
+
variants.map((variant) => [
|
|
285
|
+
variant.iosBundleIdentifier.toLowerCase(),
|
|
286
|
+
`variant "${variant.key}" application target`
|
|
287
|
+
])
|
|
288
|
+
);
|
|
289
|
+
for (const target of targets) {
|
|
290
|
+
const normalizedName = target.name.toLowerCase();
|
|
291
|
+
const existingName = targetByName.get(normalizedName);
|
|
292
|
+
if (existingName !== void 0) {
|
|
293
|
+
throw new Error(
|
|
294
|
+
`iOS targets "${existingName}" and "${target.name}" have the same case-insensitive name.`
|
|
295
|
+
);
|
|
296
|
+
}
|
|
297
|
+
targetByName.set(normalizedName, target.name);
|
|
298
|
+
for (const variant of variants) {
|
|
299
|
+
const identifier = `${variant.iosBundleIdentifier}${target.bundleIdentifierSuffix}`;
|
|
300
|
+
const normalizedIdentifier = identifier.toLowerCase();
|
|
301
|
+
const owner = identifierOwnerByValue.get(normalizedIdentifier);
|
|
302
|
+
if (owner !== void 0) {
|
|
303
|
+
throw new Error(
|
|
304
|
+
`iOS target "${target.name}" and ${owner} produce the same bundle identifier "${identifier}".`
|
|
305
|
+
);
|
|
306
|
+
}
|
|
307
|
+
identifierOwnerByValue.set(
|
|
308
|
+
normalizedIdentifier,
|
|
309
|
+
`iOS target "${target.name}" for variant "${variant.key}"`
|
|
310
|
+
);
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
}
|
|
234
314
|
function assertNoCrossVariantRouteCollision({
|
|
235
315
|
identifierLabel,
|
|
236
316
|
selectIdentifier,
|
package/dist/config/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/config/index.ts","../../src/options/normalize.ts"],"sourcesContent":["import type {ExpoConfig} from 'expo/config';\n\nimport {normalizeNativeVariants} from '../options';\nimport type {NativeVariantOptions, NativeVariantsOptions} from '../options';\n\nconst PLUGIN_NAME = 'expo-native-variants';\nconst PLUGIN_SPECIFIERS = new Set([\n PLUGIN_NAME,\n `${PLUGIN_NAME}/app.plugin.js`,\n]);\n\nexport type CreateNativeVariantsConfigArgs = Readonly<{\n config: ExpoConfig;\n options: NativeVariantsConfigInput;\n variant?: string;\n}>;\n\ntype NativeVariantConfigInput = Readonly<\n Omit<NativeVariantOptions, 'runMode'> & {runMode?: string}\n>;\n\nexport type NativeVariantsConfigInput = Readonly<\n Omit<NativeVariantsOptions, 'variants'> & {\n variants: Readonly<Record<string, NativeVariantConfigInput>>;\n }\n>;\n\n/**\n * Projects one variant's identifiers into app config before EAS reads them,\n * while registering the plugin with the complete native variant matrix.\n * This helper remains experimental until cloud builds are verified.\n */\nexport function createNativeVariantsConfig({\n config,\n options,\n variant,\n}: CreateNativeVariantsConfigArgs): ExpoConfig {\n assertPluginIsNotRegistered(config.plugins);\n const canonicalVariant =\n variant ?? options.canonicalVariant ?? options.defaultVariant;\n const normalized = normalizeNativeVariants({\n canonicalVariant,\n configName: config.name,\n options,\n });\n const selected = normalized.canonicalVariant;\n const pluginOptions: NativeVariantsConfigInput = {\n ...options,\n canonicalVariant: selected.key,\n };\n\n return {\n ...config,\n android: {\n ...config.android,\n package: selected.androidApplicationId,\n },\n ios: {\n ...config.ios,\n bundleIdentifier: selected.iosBundleIdentifier,\n },\n plugins: [...(config.plugins ?? []), [PLUGIN_NAME, pluginOptions]],\n };\n}\n\nfunction assertPluginIsNotRegistered(plugins: ExpoConfig['plugins']): void {\n const existingRegistration = plugins?.find(\n (plugin) =>\n (typeof plugin === 'string' && PLUGIN_SPECIFIERS.has(plugin)) ||\n (Array.isArray(plugin) && PLUGIN_SPECIFIERS.has(plugin[0] ?? '')),\n );\n if (existingRegistration !== undefined) {\n throw new Error(\n 'expo-native-variants is already registered in config.plugins. Remove the existing entry before using createNativeVariantsConfig.',\n );\n }\n}\n","import type {\n NativeVariantRunMode,\n NormalizedNativeVariant,\n NormalizedNativeVariantsOptions,\n NormalizeNativeVariantsArgs,\n} from './types';\n\nconst ROOT_KEYS = new Set(['canonicalVariant', 'defaultVariant', 'variants']);\nconst VARIANT_KEYS = new Set([\n 'android',\n 'applicationId',\n 'displayName',\n 'ios',\n 'runMode',\n 'urlScheme',\n]);\nconst IOS_KEYS = new Set(['bundleIdentifier', 'xcodeScheme']);\nconst ANDROID_KEYS = new Set(['applicationId']);\nconst RESERVED_VARIANT_NAMES = new Set([\n 'androidtest',\n 'aux',\n 'con',\n 'debug',\n 'main',\n 'nul',\n 'prn',\n 'release',\n 'test',\n 'unittest',\n]);\nconst WINDOWS_DEVICE_NAME = /^(?:com|lpt)[0-9]$/i;\nconst VARIANT_KEY = /^[A-Za-z][A-Za-z0-9_-]*$/;\nconst SAFE_FILE_LABEL = /^[A-Za-z0-9][A-Za-z0-9 ._-]*$/;\nconst URL_SCHEME = /^[A-Za-z][A-Za-z0-9+.-]*$/;\nconst IOS_IDENTIFIER_SEGMENT = /^[A-Za-z0-9][A-Za-z0-9-]*$/;\nconst ANDROID_IDENTIFIER_SEGMENT = /^[A-Za-z][A-Za-z0-9_]*$/;\n\nexport function normalizeNativeVariants({\n configName,\n options,\n canonicalVariant: canonicalOverride,\n}: NormalizeNativeVariantsArgs): NormalizedNativeVariantsOptions {\n validateFileLabel(configName, 'Expo config name');\n const optionsRecord = requireRecord(options, 'Plugin options');\n assertKnownKeys(optionsRecord, ROOT_KEYS, 'Plugin options');\n\n const defaultVariant = requireNonemptyString(\n optionsRecord.defaultVariant,\n 'defaultVariant',\n );\n const configuredCanonicalVariant = optionalNonemptyString(\n optionsRecord.canonicalVariant,\n 'canonicalVariant',\n );\n const canonicalVariant = canonicalOverride ?? configuredCanonicalVariant ?? defaultVariant;\n validateVariantKey(defaultVariant, 'defaultVariant');\n validateVariantKey(canonicalVariant, 'canonicalVariant');\n\n const variantsRecord = requireRecord(optionsRecord.variants, 'variants');\n const variantEntries = Object.entries(variantsRecord);\n if (variantEntries.length === 0) {\n throw new Error('variants must contain at least one variant.');\n }\n\n const normalizedVariants = variantEntries.map(([key, variant]) =>\n normalizeVariant({configName, key, variant}),\n );\n validateGeneratedNames(normalizedVariants);\n validateUniqueValues(normalizedVariants);\n\n if (!Object.hasOwn(variantsRecord, defaultVariant)) {\n throw new Error(`defaultVariant references unknown variant \"${defaultVariant}\".`);\n }\n\n const canonical = normalizedVariants.find(({key}) => key === canonicalVariant);\n if (canonical === undefined) {\n throw new Error(`canonicalVariant references unknown variant \"${canonicalVariant}\".`);\n }\n\n const variants = Object.freeze(normalizedVariants);\n return Object.freeze({canonicalVariant: canonical, variants});\n}\n\nfunction normalizeVariant({\n configName,\n key,\n variant,\n}: Readonly<{\n configName: string;\n key: string;\n variant: unknown;\n}>): NormalizedNativeVariant {\n validateVariantKey(key, `Variant key \"${key}\"`);\n const variantRecord = requireRecord(variant, `Variant \"${key}\"`);\n assertKnownKeys(variantRecord, VARIANT_KEYS, `Variant \"${key}\"`);\n\n const displayName = requireNonemptyString(\n variantRecord.displayName,\n `Variant \"${key}\" displayName`,\n );\n validateText(displayName, `Variant \"${key}\" displayName`);\n const applicationId = requireNonemptyString(\n variantRecord.applicationId,\n `Variant \"${key}\" applicationId`,\n );\n const urlScheme = requireNonemptyString(\n variantRecord.urlScheme,\n `Variant \"${key}\" urlScheme`,\n );\n validateUrlScheme(urlScheme, `Variant \"${key}\" urlScheme`);\n const runMode = readRunMode(variantRecord.runMode, key);\n const ios = readIosOptions(variantRecord.ios, key);\n const android = readAndroidOptions(variantRecord.android, key);\n const iosBundleIdentifier = ios.bundleIdentifier ?? applicationId;\n const androidApplicationId = android.applicationId ?? applicationId;\n validateIosIdentifier(iosBundleIdentifier, `Variant \"${key}\" iOS bundle identifier`);\n validateAndroidIdentifier(\n androidApplicationId,\n `Variant \"${key}\" Android application ID`,\n );\n\n const configLabel = toPascalConfigLabel(key);\n const generatedIosScheme = `${configName}-${configLabel}`;\n const iosScheme = ios.xcodeScheme ?? generatedIosScheme;\n validateFileLabel(iosScheme, `Variant \"${key}\" iOS scheme`);\n\n return Object.freeze({\n key,\n displayName,\n iosBundleIdentifier,\n androidApplicationId,\n urlScheme,\n runMode,\n iosScheme,\n debugConfiguration: `Debug-${configLabel}`,\n releaseConfiguration: `Release-${configLabel}`,\n androidFlavor: lowerFirst(configLabel),\n });\n}\n\nfunction readIosOptions(\n value: unknown,\n variantKey: string,\n): Readonly<{bundleIdentifier?: string; xcodeScheme?: string}> {\n if (value === undefined) {\n return {};\n }\n\n const record = requireRecord(value, `Variant \"${variantKey}\" ios`);\n assertKnownKeys(record, IOS_KEYS, `Variant \"${variantKey}\" ios`);\n const bundleIdentifier = optionalNonemptyString(\n record.bundleIdentifier,\n `Variant \"${variantKey}\" ios.bundleIdentifier`,\n );\n const xcodeScheme = optionalNonemptyString(\n record.xcodeScheme,\n `Variant \"${variantKey}\" ios.xcodeScheme`,\n );\n return compactOptionalStrings({bundleIdentifier, xcodeScheme});\n}\n\nfunction readAndroidOptions(\n value: unknown,\n variantKey: string,\n): Readonly<{applicationId?: string}> {\n if (value === undefined) {\n return {};\n }\n\n const record = requireRecord(value, `Variant \"${variantKey}\" android`);\n assertKnownKeys(record, ANDROID_KEYS, `Variant \"${variantKey}\" android`);\n const applicationId = optionalNonemptyString(\n record.applicationId,\n `Variant \"${variantKey}\" android.applicationId`,\n );\n return applicationId === undefined ? {} : {applicationId};\n}\n\nfunction compactOptionalStrings({\n bundleIdentifier,\n xcodeScheme,\n}: Readonly<{\n bundleIdentifier: string | undefined;\n xcodeScheme: string | undefined;\n}>): Readonly<{bundleIdentifier?: string; xcodeScheme?: string}> {\n if (bundleIdentifier === undefined) {\n if (xcodeScheme === undefined) {\n return {};\n }\n return {xcodeScheme};\n }\n if (xcodeScheme === undefined) {\n return {bundleIdentifier};\n }\n return {bundleIdentifier, xcodeScheme};\n}\n\nfunction readRunMode(value: unknown, variantKey: string): NativeVariantRunMode {\n if (value === undefined) {\n return 'debug';\n }\n if (value === 'debug' || value === 'release') {\n return value;\n }\n throw new Error(`Variant \"${variantKey}\" runMode must be \"debug\" or \"release\".`);\n}\n\nfunction validateGeneratedNames(variants: readonly NormalizedNativeVariant[]): void {\n for (const variant of variants) {\n const generatedName = variant.androidFlavor.toLowerCase();\n if (\n RESERVED_VARIANT_NAMES.has(generatedName) ||\n WINDOWS_DEVICE_NAME.test(generatedName)\n ) {\n throw new Error(\n `Variant key \"${variant.key}\" produces reserved name \"${variant.androidFlavor}\".`,\n );\n }\n }\n assertUnique(variants, ({key}) => key.toLowerCase(), 'variant key');\n assertUnique(variants, ({debugConfiguration}) => debugConfiguration.toLowerCase(), 'iOS configuration');\n assertUnique(variants, ({iosScheme}) => iosScheme.toLowerCase(), 'iOS scheme');\n assertUnique(variants, ({androidFlavor}) => androidFlavor.toLowerCase(), 'Android flavor');\n}\n\nfunction validateUniqueValues(variants: readonly NormalizedNativeVariant[]): void {\n assertUnique(\n variants,\n ({iosBundleIdentifier}) => iosBundleIdentifier.toLowerCase(),\n 'iOS bundle identifier',\n );\n assertUnique(\n variants,\n ({androidApplicationId}) => androidApplicationId.toLowerCase(),\n 'Android application ID',\n );\n assertUnique(variants, ({urlScheme}) => urlScheme.toLowerCase(), 'URL scheme');\n assertNoCrossVariantRouteCollision({\n identifierLabel: 'iOS bundle identifier',\n selectIdentifier: ({iosBundleIdentifier}) => iosBundleIdentifier,\n variants,\n });\n assertNoCrossVariantRouteCollision({\n identifierLabel: 'Android application ID',\n selectIdentifier: ({androidApplicationId}) => androidApplicationId,\n variants,\n });\n}\n\nfunction assertNoCrossVariantRouteCollision({\n identifierLabel,\n selectIdentifier,\n variants,\n}: Readonly<{\n identifierLabel: string;\n selectIdentifier: (variant: NormalizedNativeVariant) => string;\n variants: readonly NormalizedNativeVariant[];\n}>): void {\n const identifierOwnerByValue = new Map(\n variants.map((variant) => [\n selectIdentifier(variant).toLowerCase(),\n variant.key,\n ]),\n );\n\n for (const variant of variants) {\n const identifierOwner = identifierOwnerByValue.get(variant.urlScheme.toLowerCase());\n if (identifierOwner !== undefined && identifierOwner !== variant.key) {\n throw new Error(\n `Variant \"${variant.key}\" URL scheme \"${variant.urlScheme}\" matches variant \"${identifierOwner}\" ${identifierLabel}.`,\n );\n }\n }\n}\n\nfunction assertUnique(\n variants: readonly NormalizedNativeVariant[],\n select: (variant: NormalizedNativeVariant) => string,\n label: string,\n): void {\n const ownerByValue = new Map<string, string>();\n for (const variant of variants) {\n const value = select(variant);\n const owner = ownerByValue.get(value);\n if (owner !== undefined) {\n throw new Error(\n `Variants \"${owner}\" and \"${variant.key}\" produce the same ${label} \"${value}\".`,\n );\n }\n ownerByValue.set(value, variant.key);\n }\n}\n\nfunction validateVariantKey(value: string, label: string): void {\n if (!VARIANT_KEY.test(value)) {\n throw new Error(\n `${label} must start with a letter and contain only letters, numbers, hyphens, or underscores.`,\n );\n }\n const normalized = value.toLowerCase();\n if (RESERVED_VARIANT_NAMES.has(normalized) || WINDOWS_DEVICE_NAME.test(normalized)) {\n throw new Error(`${label} uses reserved name \"${value}\".`);\n }\n}\n\nfunction validateFileLabel(value: string, label: string): void {\n if (value !== value.trim() || !SAFE_FILE_LABEL.test(value) || value === '.' || value === '..') {\n throw new Error(\n `${label} must be a path-safe name containing only letters, numbers, spaces, periods, hyphens, or underscores.`,\n );\n }\n}\n\nfunction validateText(value: string, label: string): void {\n if (/\\p{Cc}/u.test(value)) {\n throw new Error(`${label} must not contain control characters.`);\n }\n}\n\nfunction validateUrlScheme(value: string, label: string): void {\n if (!URL_SCHEME.test(value)) {\n throw new Error(\n `${label} must start with a letter and contain only letters, numbers, plus signs, periods, or hyphens.`,\n );\n }\n}\n\nfunction validateIosIdentifier(value: string, label: string): void {\n const segments = value.split('.');\n if (segments.length < 2 || segments.some((segment) => !IOS_IDENTIFIER_SEGMENT.test(segment))) {\n throw new Error(`${label} must be a valid reverse-DNS bundle identifier.`);\n }\n}\n\nfunction validateAndroidIdentifier(value: string, label: string): void {\n const segments = value.split('.');\n if (segments.length < 2 || segments.some((segment) => !ANDROID_IDENTIFIER_SEGMENT.test(segment))) {\n throw new Error(`${label} must be a valid reverse-DNS application ID.`);\n }\n}\n\nfunction toPascalConfigLabel(value: string): string {\n const words = value\n .replace(/([a-z0-9])([A-Z])/g, '$1-$2')\n .split(/[-_]+/)\n .filter((word) => word.length > 0);\n return words.map(capitalize).join('');\n}\n\nfunction capitalize(value: string): string {\n return `${value[0]?.toUpperCase() ?? ''}${value.slice(1).toLowerCase()}`;\n}\n\nfunction lowerFirst(value: string): string {\n return `${value[0]?.toLowerCase() ?? ''}${value.slice(1)}`;\n}\n\nfunction requireNonemptyString(value: unknown, label: string): string {\n if (typeof value !== 'string' || value.trim().length === 0) {\n throw new Error(`${label} must be a nonempty string.`);\n }\n return value;\n}\n\nfunction optionalNonemptyString(value: unknown, label: string): string | undefined {\n if (value === undefined) {\n return undefined;\n }\n return requireNonemptyString(value, label);\n}\n\nfunction requireRecord(value: unknown, label: string): Record<string, unknown> {\n if (!isRecord(value)) {\n throw new Error(`${label} must be an object.`);\n }\n return value;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction assertKnownKeys(\n record: Readonly<Record<string, unknown>>,\n knownKeys: ReadonlySet<string>,\n label: string,\n): void {\n const unknownKey = Object.keys(record).find((key) => !knownKeys.has(key));\n if (unknownKey !== undefined) {\n throw new Error(`${label} contains unknown key \"${unknownKey}\".`);\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACOA,IAAM,YAAY,oBAAI,IAAI,CAAC,oBAAoB,kBAAkB,UAAU,CAAC;AAC5E,IAAM,eAAe,oBAAI,IAAI;AAAA,EAC3B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AACD,IAAM,WAAW,oBAAI,IAAI,CAAC,oBAAoB,aAAa,CAAC;AAC5D,IAAM,eAAe,oBAAI,IAAI,CAAC,eAAe,CAAC;AAC9C,IAAM,yBAAyB,oBAAI,IAAI;AAAA,EACrC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AACD,IAAM,sBAAsB;AAC5B,IAAM,cAAc;AACpB,IAAM,kBAAkB;AACxB,IAAM,aAAa;AACnB,IAAM,yBAAyB;AAC/B,IAAM,6BAA6B;AAE5B,SAAS,wBAAwB;AAAA,EACtC;AAAA,EACA;AAAA,EACA,kBAAkB;AACpB,GAAiE;AAC/D,oBAAkB,YAAY,kBAAkB;AAChD,QAAM,gBAAgB,cAAc,SAAS,gBAAgB;AAC7D,kBAAgB,eAAe,WAAW,gBAAgB;AAE1D,QAAM,iBAAiB;AAAA,IACrB,cAAc;AAAA,IACd;AAAA,EACF;AACA,QAAM,6BAA6B;AAAA,IACjC,cAAc;AAAA,IACd;AAAA,EACF;AACA,QAAM,mBAAmB,qBAAqB,8BAA8B;AAC5E,qBAAmB,gBAAgB,gBAAgB;AACnD,qBAAmB,kBAAkB,kBAAkB;AAEvD,QAAM,iBAAiB,cAAc,cAAc,UAAU,UAAU;AACvE,QAAM,iBAAiB,OAAO,QAAQ,cAAc;AACpD,MAAI,eAAe,WAAW,GAAG;AAC/B,UAAM,IAAI,MAAM,6CAA6C;AAAA,EAC/D;AAEA,QAAM,qBAAqB,eAAe;AAAA,IAAI,CAAC,CAAC,KAAK,OAAO,MAC1D,iBAAiB,EAAC,YAAY,KAAK,QAAO,CAAC;AAAA,EAC7C;AACA,yBAAuB,kBAAkB;AACzC,uBAAqB,kBAAkB;AAEvC,MAAI,CAAC,OAAO,OAAO,gBAAgB,cAAc,GAAG;AAClD,UAAM,IAAI,MAAM,8CAA8C,cAAc,IAAI;AAAA,EAClF;AAEA,QAAM,YAAY,mBAAmB,KAAK,CAAC,EAAC,IAAG,MAAM,QAAQ,gBAAgB;AAC7E,MAAI,cAAc,QAAW;AAC3B,UAAM,IAAI,MAAM,gDAAgD,gBAAgB,IAAI;AAAA,EACtF;AAEA,QAAM,WAAW,OAAO,OAAO,kBAAkB;AACjD,SAAO,OAAO,OAAO,EAAC,kBAAkB,WAAW,SAAQ,CAAC;AAC9D;AAEA,SAAS,iBAAiB;AAAA,EACxB;AAAA,EACA;AAAA,EACA;AACF,GAI6B;AAC3B,qBAAmB,KAAK,gBAAgB,GAAG,GAAG;AAC9C,QAAM,gBAAgB,cAAc,SAAS,YAAY,GAAG,GAAG;AAC/D,kBAAgB,eAAe,cAAc,YAAY,GAAG,GAAG;AAE/D,QAAM,cAAc;AAAA,IAClB,cAAc;AAAA,IACd,YAAY,GAAG;AAAA,EACjB;AACA,eAAa,aAAa,YAAY,GAAG,eAAe;AACxD,QAAM,gBAAgB;AAAA,IACpB,cAAc;AAAA,IACd,YAAY,GAAG;AAAA,EACjB;AACA,QAAM,YAAY;AAAA,IAChB,cAAc;AAAA,IACd,YAAY,GAAG;AAAA,EACjB;AACA,oBAAkB,WAAW,YAAY,GAAG,aAAa;AACzD,QAAM,UAAU,YAAY,cAAc,SAAS,GAAG;AACtD,QAAM,MAAM,eAAe,cAAc,KAAK,GAAG;AACjD,QAAM,UAAU,mBAAmB,cAAc,SAAS,GAAG;AAC7D,QAAM,sBAAsB,IAAI,oBAAoB;AACpD,QAAM,uBAAuB,QAAQ,iBAAiB;AACtD,wBAAsB,qBAAqB,YAAY,GAAG,yBAAyB;AACnF;AAAA,IACE;AAAA,IACA,YAAY,GAAG;AAAA,EACjB;AAEA,QAAM,cAAc,oBAAoB,GAAG;AAC3C,QAAM,qBAAqB,GAAG,UAAU,IAAI,WAAW;AACvD,QAAM,YAAY,IAAI,eAAe;AACrC,oBAAkB,WAAW,YAAY,GAAG,cAAc;AAE1D,SAAO,OAAO,OAAO;AAAA,IACnB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,oBAAoB,SAAS,WAAW;AAAA,IACxC,sBAAsB,WAAW,WAAW;AAAA,IAC5C,eAAe,WAAW,WAAW;AAAA,EACvC,CAAC;AACH;AAEA,SAAS,eACP,OACA,YAC6D;AAC7D,MAAI,UAAU,QAAW;AACvB,WAAO,CAAC;AAAA,EACV;AAEA,QAAM,SAAS,cAAc,OAAO,YAAY,UAAU,OAAO;AACjE,kBAAgB,QAAQ,UAAU,YAAY,UAAU,OAAO;AAC/D,QAAM,mBAAmB;AAAA,IACvB,OAAO;AAAA,IACP,YAAY,UAAU;AAAA,EACxB;AACA,QAAM,cAAc;AAAA,IAClB,OAAO;AAAA,IACP,YAAY,UAAU;AAAA,EACxB;AACA,SAAO,uBAAuB,EAAC,kBAAkB,YAAW,CAAC;AAC/D;AAEA,SAAS,mBACP,OACA,YACoC;AACpC,MAAI,UAAU,QAAW;AACvB,WAAO,CAAC;AAAA,EACV;AAEA,QAAM,SAAS,cAAc,OAAO,YAAY,UAAU,WAAW;AACrE,kBAAgB,QAAQ,cAAc,YAAY,UAAU,WAAW;AACvE,QAAM,gBAAgB;AAAA,IACpB,OAAO;AAAA,IACP,YAAY,UAAU;AAAA,EACxB;AACA,SAAO,kBAAkB,SAAY,CAAC,IAAI,EAAC,cAAa;AAC1D;AAEA,SAAS,uBAAuB;AAAA,EAC9B;AAAA,EACA;AACF,GAGiE;AAC/D,MAAI,qBAAqB,QAAW;AAClC,QAAI,gBAAgB,QAAW;AAC7B,aAAO,CAAC;AAAA,IACV;AACA,WAAO,EAAC,YAAW;AAAA,EACrB;AACA,MAAI,gBAAgB,QAAW;AAC7B,WAAO,EAAC,iBAAgB;AAAA,EAC1B;AACA,SAAO,EAAC,kBAAkB,YAAW;AACvC;AAEA,SAAS,YAAY,OAAgB,YAA0C;AAC7E,MAAI,UAAU,QAAW;AACvB,WAAO;AAAA,EACT;AACA,MAAI,UAAU,WAAW,UAAU,WAAW;AAC5C,WAAO;AAAA,EACT;AACA,QAAM,IAAI,MAAM,YAAY,UAAU,yCAAyC;AACjF;AAEA,SAAS,uBAAuB,UAAoD;AAClF,aAAW,WAAW,UAAU;AAC9B,UAAM,gBAAgB,QAAQ,cAAc,YAAY;AACxD,QACE,uBAAuB,IAAI,aAAa,KACxC,oBAAoB,KAAK,aAAa,GACtC;AACA,YAAM,IAAI;AAAA,QACR,gBAAgB,QAAQ,GAAG,6BAA6B,QAAQ,aAAa;AAAA,MAC/E;AAAA,IACF;AAAA,EACF;AACA,eAAa,UAAU,CAAC,EAAC,IAAG,MAAM,IAAI,YAAY,GAAG,aAAa;AAClE,eAAa,UAAU,CAAC,EAAC,mBAAkB,MAAM,mBAAmB,YAAY,GAAG,mBAAmB;AACtG,eAAa,UAAU,CAAC,EAAC,UAAS,MAAM,UAAU,YAAY,GAAG,YAAY;AAC7E,eAAa,UAAU,CAAC,EAAC,cAAa,MAAM,cAAc,YAAY,GAAG,gBAAgB;AAC3F;AAEA,SAAS,qBAAqB,UAAoD;AAChF;AAAA,IACE;AAAA,IACA,CAAC,EAAC,oBAAmB,MAAM,oBAAoB,YAAY;AAAA,IAC3D;AAAA,EACF;AACA;AAAA,IACE;AAAA,IACA,CAAC,EAAC,qBAAoB,MAAM,qBAAqB,YAAY;AAAA,IAC7D;AAAA,EACF;AACA,eAAa,UAAU,CAAC,EAAC,UAAS,MAAM,UAAU,YAAY,GAAG,YAAY;AAC7E,qCAAmC;AAAA,IACjC,iBAAiB;AAAA,IACjB,kBAAkB,CAAC,EAAC,oBAAmB,MAAM;AAAA,IAC7C;AAAA,EACF,CAAC;AACD,qCAAmC;AAAA,IACjC,iBAAiB;AAAA,IACjB,kBAAkB,CAAC,EAAC,qBAAoB,MAAM;AAAA,IAC9C;AAAA,EACF,CAAC;AACH;AAEA,SAAS,mCAAmC;AAAA,EAC1C;AAAA,EACA;AAAA,EACA;AACF,GAIU;AACR,QAAM,yBAAyB,IAAI;AAAA,IACjC,SAAS,IAAI,CAAC,YAAY;AAAA,MACxB,iBAAiB,OAAO,EAAE,YAAY;AAAA,MACtC,QAAQ;AAAA,IACV,CAAC;AAAA,EACH;AAEA,aAAW,WAAW,UAAU;AAC9B,UAAM,kBAAkB,uBAAuB,IAAI,QAAQ,UAAU,YAAY,CAAC;AAClF,QAAI,oBAAoB,UAAa,oBAAoB,QAAQ,KAAK;AACpE,YAAM,IAAI;AAAA,QACR,YAAY,QAAQ,GAAG,iBAAiB,QAAQ,SAAS,sBAAsB,eAAe,KAAK,eAAe;AAAA,MACpH;AAAA,IACF;AAAA,EACF;AACF;AAEA,SAAS,aACP,UACA,QACA,OACM;AACN,QAAM,eAAe,oBAAI,IAAoB;AAC7C,aAAW,WAAW,UAAU;AAC9B,UAAM,QAAQ,OAAO,OAAO;AAC5B,UAAM,QAAQ,aAAa,IAAI,KAAK;AACpC,QAAI,UAAU,QAAW;AACvB,YAAM,IAAI;AAAA,QACR,aAAa,KAAK,UAAU,QAAQ,GAAG,sBAAsB,KAAK,KAAK,KAAK;AAAA,MAC9E;AAAA,IACF;AACA,iBAAa,IAAI,OAAO,QAAQ,GAAG;AAAA,EACrC;AACF;AAEA,SAAS,mBAAmB,OAAe,OAAqB;AAC9D,MAAI,CAAC,YAAY,KAAK,KAAK,GAAG;AAC5B,UAAM,IAAI;AAAA,MACR,GAAG,KAAK;AAAA,IACV;AAAA,EACF;AACA,QAAM,aAAa,MAAM,YAAY;AACrC,MAAI,uBAAuB,IAAI,UAAU,KAAK,oBAAoB,KAAK,UAAU,GAAG;AAClF,UAAM,IAAI,MAAM,GAAG,KAAK,wBAAwB,KAAK,IAAI;AAAA,EAC3D;AACF;AAEA,SAAS,kBAAkB,OAAe,OAAqB;AAC7D,MAAI,UAAU,MAAM,KAAK,KAAK,CAAC,gBAAgB,KAAK,KAAK,KAAK,UAAU,OAAO,UAAU,MAAM;AAC7F,UAAM,IAAI;AAAA,MACR,GAAG,KAAK;AAAA,IACV;AAAA,EACF;AACF;AAEA,SAAS,aAAa,OAAe,OAAqB;AACxD,MAAI,WAAC,WAAO,GAAC,EAAC,KAAK,KAAK,GAAG;AACzB,UAAM,IAAI,MAAM,GAAG,KAAK,uCAAuC;AAAA,EACjE;AACF;AAEA,SAAS,kBAAkB,OAAe,OAAqB;AAC7D,MAAI,CAAC,WAAW,KAAK,KAAK,GAAG;AAC3B,UAAM,IAAI;AAAA,MACR,GAAG,KAAK;AAAA,IACV;AAAA,EACF;AACF;AAEA,SAAS,sBAAsB,OAAe,OAAqB;AACjE,QAAM,WAAW,MAAM,MAAM,GAAG;AAChC,MAAI,SAAS,SAAS,KAAK,SAAS,KAAK,CAAC,YAAY,CAAC,uBAAuB,KAAK,OAAO,CAAC,GAAG;AAC5F,UAAM,IAAI,MAAM,GAAG,KAAK,iDAAiD;AAAA,EAC3E;AACF;AAEA,SAAS,0BAA0B,OAAe,OAAqB;AACrE,QAAM,WAAW,MAAM,MAAM,GAAG;AAChC,MAAI,SAAS,SAAS,KAAK,SAAS,KAAK,CAAC,YAAY,CAAC,2BAA2B,KAAK,OAAO,CAAC,GAAG;AAChG,UAAM,IAAI,MAAM,GAAG,KAAK,8CAA8C;AAAA,EACxE;AACF;AAEA,SAAS,oBAAoB,OAAuB;AAClD,QAAM,QAAQ,MACX,QAAQ,sBAAsB,OAAO,EACrC,MAAM,OAAO,EACb,OAAO,CAAC,SAAS,KAAK,SAAS,CAAC;AACnC,SAAO,MAAM,IAAI,UAAU,EAAE,KAAK,EAAE;AACtC;AAEA,SAAS,WAAW,OAAuB;AACzC,SAAO,GAAG,MAAM,CAAC,GAAG,YAAY,KAAK,EAAE,GAAG,MAAM,MAAM,CAAC,EAAE,YAAY,CAAC;AACxE;AAEA,SAAS,WAAW,OAAuB;AACzC,SAAO,GAAG,MAAM,CAAC,GAAG,YAAY,KAAK,EAAE,GAAG,MAAM,MAAM,CAAC,CAAC;AAC1D;AAEA,SAAS,sBAAsB,OAAgB,OAAuB;AACpE,MAAI,OAAO,UAAU,YAAY,MAAM,KAAK,EAAE,WAAW,GAAG;AAC1D,UAAM,IAAI,MAAM,GAAG,KAAK,6BAA6B;AAAA,EACvD;AACA,SAAO;AACT;AAEA,SAAS,uBAAuB,OAAgB,OAAmC;AACjF,MAAI,UAAU,QAAW;AACvB,WAAO;AAAA,EACT;AACA,SAAO,sBAAsB,OAAO,KAAK;AAC3C;AAEA,SAAS,cAAc,OAAgB,OAAwC;AAC7E,MAAI,CAAC,SAAS,KAAK,GAAG;AACpB,UAAM,IAAI,MAAM,GAAG,KAAK,qBAAqB;AAAA,EAC/C;AACA,SAAO;AACT;AAEA,SAAS,SAAS,OAAkD;AAClE,SAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,KAAK;AAC5E;AAEA,SAAS,gBACP,QACA,WACA,OACM;AACN,QAAM,aAAa,OAAO,KAAK,MAAM,EAAE,KAAK,CAAC,QAAQ,CAAC,UAAU,IAAI,GAAG,CAAC;AACxE,MAAI,eAAe,QAAW;AAC5B,UAAM,IAAI,MAAM,GAAG,KAAK,0BAA0B,UAAU,IAAI;AAAA,EAClE;AACF;;;ADlYA,IAAM,cAAc;AACpB,IAAM,oBAAoB,oBAAI,IAAI;AAAA,EAChC;AAAA,EACA,GAAG,WAAW;AAChB,CAAC;AAuBM,SAAS,2BAA2B;AAAA,EACzC;AAAA,EACA;AAAA,EACA;AACF,GAA+C;AAC7C,8BAA4B,OAAO,OAAO;AAC1C,QAAM,mBACJ,WAAW,QAAQ,oBAAoB,QAAQ;AACjD,QAAM,aAAa,wBAAwB;AAAA,IACzC;AAAA,IACA,YAAY,OAAO;AAAA,IACnB;AAAA,EACF,CAAC;AACD,QAAM,WAAW,WAAW;AAC5B,QAAM,gBAA2C;AAAA,IAC/C,GAAG;AAAA,IACH,kBAAkB,SAAS;AAAA,EAC7B;AAEA,SAAO;AAAA,IACL,GAAG;AAAA,IACH,SAAS;AAAA,MACP,GAAG,OAAO;AAAA,MACV,SAAS,SAAS;AAAA,IACpB;AAAA,IACA,KAAK;AAAA,MACH,GAAG,OAAO;AAAA,MACV,kBAAkB,SAAS;AAAA,IAC7B;AAAA,IACA,SAAS,CAAC,GAAI,OAAO,WAAW,CAAC,GAAI,CAAC,aAAa,aAAa,CAAC;AAAA,EACnE;AACF;AAEA,SAAS,4BAA4B,SAAsC;AACzE,QAAM,uBAAuB,SAAS;AAAA,IACpC,CAAC,WACE,OAAO,WAAW,YAAY,kBAAkB,IAAI,MAAM,KAC1D,MAAM,QAAQ,MAAM,KAAK,kBAAkB,IAAI,OAAO,CAAC,KAAK,EAAE;AAAA,EACnE;AACA,MAAI,yBAAyB,QAAW;AACtC,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AACF;","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../src/config/index.ts","../../src/options/normalize.ts"],"sourcesContent":["import type {ExpoConfig} from 'expo/config';\n\nimport {normalizeNativeVariants} from '../options';\nimport type {NativeVariantOptions, NativeVariantsOptions} from '../options';\n\nconst PLUGIN_NAME = 'expo-native-variants';\nconst PLUGIN_SPECIFIERS = new Set([\n PLUGIN_NAME,\n `${PLUGIN_NAME}/app.plugin.js`,\n]);\n\nexport type CreateNativeVariantsConfigArgs = Readonly<{\n config: ExpoConfig;\n options: NativeVariantsConfigInput;\n variant?: string;\n}>;\n\ntype NativeVariantConfigInput = Readonly<\n Omit<NativeVariantOptions, 'runMode'> & {runMode?: string}\n>;\n\nexport type NativeVariantsConfigInput = Readonly<\n Omit<NativeVariantsOptions, 'variants'> & {\n variants: Readonly<Record<string, NativeVariantConfigInput>>;\n }\n>;\n\n/**\n * Projects one variant's identifiers into app config before EAS reads them,\n * while registering the plugin with the complete native variant matrix.\n * This helper remains experimental until cloud builds are verified.\n */\nexport function createNativeVariantsConfig({\n config,\n options,\n variant,\n}: CreateNativeVariantsConfigArgs): ExpoConfig {\n assertPluginIsNotRegistered(config.plugins);\n const canonicalVariant =\n variant ?? options.canonicalVariant ?? options.defaultVariant;\n const normalized = normalizeNativeVariants({\n canonicalVariant,\n configName: config.name,\n options,\n });\n const selected = normalized.canonicalVariant;\n const pluginOptions: NativeVariantsConfigInput = {\n ...options,\n canonicalVariant: selected.key,\n };\n\n return {\n ...config,\n android: {\n ...config.android,\n package: selected.androidApplicationId,\n },\n ios: {\n ...config.ios,\n bundleIdentifier: selected.iosBundleIdentifier,\n },\n plugins: [...(config.plugins ?? []), [PLUGIN_NAME, pluginOptions]],\n };\n}\n\nfunction assertPluginIsNotRegistered(plugins: ExpoConfig['plugins']): void {\n const existingRegistration = plugins?.find(\n (plugin) =>\n (typeof plugin === 'string' && PLUGIN_SPECIFIERS.has(plugin)) ||\n (Array.isArray(plugin) && PLUGIN_SPECIFIERS.has(plugin[0] ?? '')),\n );\n if (existingRegistration !== undefined) {\n throw new Error(\n 'expo-native-variants is already registered in config.plugins. Remove the existing entry before using createNativeVariantsConfig.',\n );\n }\n}\n","import type {\n NativeVariantRunMode,\n NormalizedNativeVariant,\n NormalizedNativeVariantsIosTarget,\n NormalizedNativeVariantsOptions,\n NormalizeNativeVariantsArgs,\n} from './types';\n\nconst ROOT_KEYS = new Set(['canonicalVariant', 'defaultVariant', 'ios', 'variants']);\nconst ROOT_IOS_KEYS = new Set(['targets']);\nconst IOS_TARGET_KEYS = new Set(['bundleIdentifierSuffix']);\nconst VARIANT_KEYS = new Set([\n 'android',\n 'applicationId',\n 'displayName',\n 'ios',\n 'runMode',\n 'urlScheme',\n]);\nconst IOS_KEYS = new Set(['bundleIdentifier', 'xcodeScheme']);\nconst ANDROID_KEYS = new Set(['applicationId']);\nconst RESERVED_VARIANT_NAMES = new Set([\n 'androidtest',\n 'aux',\n 'con',\n 'debug',\n 'main',\n 'nul',\n 'prn',\n 'release',\n 'test',\n 'unittest',\n]);\nconst WINDOWS_DEVICE_NAME = /^(?:com|lpt)[0-9]$/i;\nconst VARIANT_KEY = /^[A-Za-z][A-Za-z0-9_-]*$/;\nconst SAFE_FILE_LABEL = /^[A-Za-z0-9][A-Za-z0-9 ._-]*$/;\nconst URL_SCHEME = /^[A-Za-z][A-Za-z0-9+.-]*$/;\nconst IOS_IDENTIFIER_SEGMENT = /^[A-Za-z0-9][A-Za-z0-9-]*$/;\nconst ANDROID_IDENTIFIER_SEGMENT = /^[A-Za-z][A-Za-z0-9_]*$/;\n\nexport function normalizeNativeVariants({\n configName,\n options,\n canonicalVariant: canonicalOverride,\n}: NormalizeNativeVariantsArgs): NormalizedNativeVariantsOptions {\n validateFileLabel(configName, 'Expo config name');\n const optionsRecord = requireRecord(options, 'Plugin options');\n assertKnownKeys(optionsRecord, ROOT_KEYS, 'Plugin options');\n\n const defaultVariant = requireNonemptyString(\n optionsRecord.defaultVariant,\n 'defaultVariant',\n );\n const configuredCanonicalVariant = optionalNonemptyString(\n optionsRecord.canonicalVariant,\n 'canonicalVariant',\n );\n const canonicalVariant = canonicalOverride ?? configuredCanonicalVariant ?? defaultVariant;\n validateVariantKey(defaultVariant, 'defaultVariant');\n validateVariantKey(canonicalVariant, 'canonicalVariant');\n\n const variantsRecord = requireRecord(optionsRecord.variants, 'variants');\n const variantEntries = Object.entries(variantsRecord);\n if (variantEntries.length === 0) {\n throw new Error('variants must contain at least one variant.');\n }\n\n const normalizedVariants = variantEntries.map(([key, variant]) =>\n normalizeVariant({configName, key, variant}),\n );\n validateGeneratedNames(normalizedVariants);\n validateUniqueValues(normalizedVariants);\n\n if (!Object.hasOwn(variantsRecord, defaultVariant)) {\n throw new Error(`defaultVariant references unknown variant \"${defaultVariant}\".`);\n }\n\n const canonical = normalizedVariants.find(({key}) => key === canonicalVariant);\n if (canonical === undefined) {\n throw new Error(`canonicalVariant references unknown variant \"${canonicalVariant}\".`);\n }\n\n const variants = Object.freeze(normalizedVariants);\n const iosTargets = normalizeIosTargets({\n value: optionsRecord.ios,\n variants,\n });\n return Object.freeze({canonicalVariant: canonical, iosTargets, variants});\n}\n\nfunction normalizeIosTargets({\n value,\n variants,\n}: Readonly<{\n value: unknown;\n variants: readonly NormalizedNativeVariant[];\n}>): readonly NormalizedNativeVariantsIosTarget[] {\n if (value === undefined) {\n return Object.freeze([]);\n }\n\n const ios = requireRecord(value, 'Plugin options ios');\n assertKnownKeys(ios, ROOT_IOS_KEYS, 'Plugin options ios');\n const targets = requireRecord(ios.targets, 'Plugin options ios.targets');\n const normalizedTargets = Object.entries(targets).map(([name, target]) => {\n validateFileLabel(name, `iOS target name \"${name}\"`);\n const targetRecord = requireRecord(target, `iOS target \"${name}\"`);\n assertKnownKeys(targetRecord, IOS_TARGET_KEYS, `iOS target \"${name}\"`);\n const bundleIdentifierSuffix = requireNonemptyString(\n targetRecord.bundleIdentifierSuffix,\n `iOS target \"${name}\" bundleIdentifierSuffix`,\n );\n validateBundleIdentifierSuffix({bundleIdentifierSuffix, name, variants});\n return Object.freeze({bundleIdentifierSuffix, name});\n });\n\n assertUniqueIosTargets(normalizedTargets, variants);\n return Object.freeze(normalizedTargets);\n}\n\nfunction normalizeVariant({\n configName,\n key,\n variant,\n}: Readonly<{\n configName: string;\n key: string;\n variant: unknown;\n}>): NormalizedNativeVariant {\n validateVariantKey(key, `Variant key \"${key}\"`);\n const variantRecord = requireRecord(variant, `Variant \"${key}\"`);\n assertKnownKeys(variantRecord, VARIANT_KEYS, `Variant \"${key}\"`);\n\n const displayName = requireNonemptyString(\n variantRecord.displayName,\n `Variant \"${key}\" displayName`,\n );\n validateText(displayName, `Variant \"${key}\" displayName`);\n const applicationId = requireNonemptyString(\n variantRecord.applicationId,\n `Variant \"${key}\" applicationId`,\n );\n const urlScheme = requireNonemptyString(\n variantRecord.urlScheme,\n `Variant \"${key}\" urlScheme`,\n );\n validateUrlScheme(urlScheme, `Variant \"${key}\" urlScheme`);\n const runMode = readRunMode(variantRecord.runMode, key);\n const ios = readIosOptions(variantRecord.ios, key);\n const android = readAndroidOptions(variantRecord.android, key);\n const iosBundleIdentifier = ios.bundleIdentifier ?? applicationId;\n const androidApplicationId = android.applicationId ?? applicationId;\n validateIosIdentifier(iosBundleIdentifier, `Variant \"${key}\" iOS bundle identifier`);\n validateAndroidIdentifier(\n androidApplicationId,\n `Variant \"${key}\" Android application ID`,\n );\n\n const configLabel = toPascalConfigLabel(key);\n const generatedIosScheme = `${configName}-${configLabel}`;\n const iosScheme = ios.xcodeScheme ?? generatedIosScheme;\n validateFileLabel(iosScheme, `Variant \"${key}\" iOS scheme`);\n\n return Object.freeze({\n key,\n displayName,\n iosBundleIdentifier,\n androidApplicationId,\n urlScheme,\n runMode,\n iosScheme,\n debugConfiguration: `Debug-${configLabel}`,\n releaseConfiguration: `Release-${configLabel}`,\n androidFlavor: lowerFirst(configLabel),\n });\n}\n\nfunction readIosOptions(\n value: unknown,\n variantKey: string,\n): Readonly<{bundleIdentifier?: string; xcodeScheme?: string}> {\n if (value === undefined) {\n return {};\n }\n\n const record = requireRecord(value, `Variant \"${variantKey}\" ios`);\n assertKnownKeys(record, IOS_KEYS, `Variant \"${variantKey}\" ios`);\n const bundleIdentifier = optionalNonemptyString(\n record.bundleIdentifier,\n `Variant \"${variantKey}\" ios.bundleIdentifier`,\n );\n const xcodeScheme = optionalNonemptyString(\n record.xcodeScheme,\n `Variant \"${variantKey}\" ios.xcodeScheme`,\n );\n return compactOptionalStrings({bundleIdentifier, xcodeScheme});\n}\n\nfunction readAndroidOptions(\n value: unknown,\n variantKey: string,\n): Readonly<{applicationId?: string}> {\n if (value === undefined) {\n return {};\n }\n\n const record = requireRecord(value, `Variant \"${variantKey}\" android`);\n assertKnownKeys(record, ANDROID_KEYS, `Variant \"${variantKey}\" android`);\n const applicationId = optionalNonemptyString(\n record.applicationId,\n `Variant \"${variantKey}\" android.applicationId`,\n );\n return applicationId === undefined ? {} : {applicationId};\n}\n\nfunction compactOptionalStrings({\n bundleIdentifier,\n xcodeScheme,\n}: Readonly<{\n bundleIdentifier: string | undefined;\n xcodeScheme: string | undefined;\n}>): Readonly<{bundleIdentifier?: string; xcodeScheme?: string}> {\n if (bundleIdentifier === undefined) {\n if (xcodeScheme === undefined) {\n return {};\n }\n return {xcodeScheme};\n }\n if (xcodeScheme === undefined) {\n return {bundleIdentifier};\n }\n return {bundleIdentifier, xcodeScheme};\n}\n\nfunction readRunMode(value: unknown, variantKey: string): NativeVariantRunMode {\n if (value === undefined) {\n return 'debug';\n }\n if (value === 'debug' || value === 'release') {\n return value;\n }\n throw new Error(`Variant \"${variantKey}\" runMode must be \"debug\" or \"release\".`);\n}\n\nfunction validateGeneratedNames(variants: readonly NormalizedNativeVariant[]): void {\n for (const variant of variants) {\n const generatedName = variant.androidFlavor.toLowerCase();\n if (\n RESERVED_VARIANT_NAMES.has(generatedName) ||\n WINDOWS_DEVICE_NAME.test(generatedName)\n ) {\n throw new Error(\n `Variant key \"${variant.key}\" produces reserved name \"${variant.androidFlavor}\".`,\n );\n }\n }\n assertUnique(variants, ({key}) => key.toLowerCase(), 'variant key');\n assertUnique(variants, ({debugConfiguration}) => debugConfiguration.toLowerCase(), 'iOS configuration');\n assertUnique(variants, ({iosScheme}) => iosScheme.toLowerCase(), 'iOS scheme');\n assertUnique(variants, ({androidFlavor}) => androidFlavor.toLowerCase(), 'Android flavor');\n}\n\nfunction validateUniqueValues(variants: readonly NormalizedNativeVariant[]): void {\n assertUnique(\n variants,\n ({iosBundleIdentifier}) => iosBundleIdentifier.toLowerCase(),\n 'iOS bundle identifier',\n );\n assertUnique(\n variants,\n ({androidApplicationId}) => androidApplicationId.toLowerCase(),\n 'Android application ID',\n );\n assertUnique(variants, ({urlScheme}) => urlScheme.toLowerCase(), 'URL scheme');\n assertNoCrossVariantRouteCollision({\n identifierLabel: 'iOS bundle identifier',\n selectIdentifier: ({iosBundleIdentifier}) => iosBundleIdentifier,\n variants,\n });\n assertNoCrossVariantRouteCollision({\n identifierLabel: 'Android application ID',\n selectIdentifier: ({androidApplicationId}) => androidApplicationId,\n variants,\n });\n}\n\nfunction validateBundleIdentifierSuffix({\n bundleIdentifierSuffix,\n name,\n variants,\n}: Readonly<{\n bundleIdentifierSuffix: string;\n name: string;\n variants: readonly NormalizedNativeVariant[];\n}>): void {\n if (!bundleIdentifierSuffix.startsWith('.') || bundleIdentifierSuffix === '.') {\n throw new Error(\n `iOS target \"${name}\" bundleIdentifierSuffix must start with a period followed by a valid bundle identifier segment.`,\n );\n }\n for (const variant of variants) {\n validateIosIdentifier(\n `${variant.iosBundleIdentifier}${bundleIdentifierSuffix}`,\n `iOS target \"${name}\" bundle identifier for variant \"${variant.key}\"`,\n );\n }\n}\n\nfunction assertUniqueIosTargets(\n targets: readonly NormalizedNativeVariantsIosTarget[],\n variants: readonly NormalizedNativeVariant[],\n): void {\n const targetByName = new Map<string, string>();\n const identifierOwnerByValue = new Map(\n variants.map((variant) => [\n variant.iosBundleIdentifier.toLowerCase(),\n `variant \"${variant.key}\" application target`,\n ]),\n );\n\n for (const target of targets) {\n const normalizedName = target.name.toLowerCase();\n const existingName = targetByName.get(normalizedName);\n if (existingName !== undefined) {\n throw new Error(\n `iOS targets \"${existingName}\" and \"${target.name}\" have the same case-insensitive name.`,\n );\n }\n targetByName.set(normalizedName, target.name);\n\n for (const variant of variants) {\n const identifier = `${variant.iosBundleIdentifier}${target.bundleIdentifierSuffix}`;\n const normalizedIdentifier = identifier.toLowerCase();\n const owner = identifierOwnerByValue.get(normalizedIdentifier);\n if (owner !== undefined) {\n throw new Error(\n `iOS target \"${target.name}\" and ${owner} produce the same bundle identifier \"${identifier}\".`,\n );\n }\n identifierOwnerByValue.set(\n normalizedIdentifier,\n `iOS target \"${target.name}\" for variant \"${variant.key}\"`,\n );\n }\n }\n}\n\nfunction assertNoCrossVariantRouteCollision({\n identifierLabel,\n selectIdentifier,\n variants,\n}: Readonly<{\n identifierLabel: string;\n selectIdentifier: (variant: NormalizedNativeVariant) => string;\n variants: readonly NormalizedNativeVariant[];\n}>): void {\n const identifierOwnerByValue = new Map(\n variants.map((variant) => [\n selectIdentifier(variant).toLowerCase(),\n variant.key,\n ]),\n );\n\n for (const variant of variants) {\n const identifierOwner = identifierOwnerByValue.get(variant.urlScheme.toLowerCase());\n if (identifierOwner !== undefined && identifierOwner !== variant.key) {\n throw new Error(\n `Variant \"${variant.key}\" URL scheme \"${variant.urlScheme}\" matches variant \"${identifierOwner}\" ${identifierLabel}.`,\n );\n }\n }\n}\n\nfunction assertUnique(\n variants: readonly NormalizedNativeVariant[],\n select: (variant: NormalizedNativeVariant) => string,\n label: string,\n): void {\n const ownerByValue = new Map<string, string>();\n for (const variant of variants) {\n const value = select(variant);\n const owner = ownerByValue.get(value);\n if (owner !== undefined) {\n throw new Error(\n `Variants \"${owner}\" and \"${variant.key}\" produce the same ${label} \"${value}\".`,\n );\n }\n ownerByValue.set(value, variant.key);\n }\n}\n\nfunction validateVariantKey(value: string, label: string): void {\n if (!VARIANT_KEY.test(value)) {\n throw new Error(\n `${label} must start with a letter and contain only letters, numbers, hyphens, or underscores.`,\n );\n }\n const normalized = value.toLowerCase();\n if (RESERVED_VARIANT_NAMES.has(normalized) || WINDOWS_DEVICE_NAME.test(normalized)) {\n throw new Error(`${label} uses reserved name \"${value}\".`);\n }\n}\n\nfunction validateFileLabel(value: string, label: string): void {\n if (value !== value.trim() || !SAFE_FILE_LABEL.test(value) || value === '.' || value === '..') {\n throw new Error(\n `${label} must be a path-safe name containing only letters, numbers, spaces, periods, hyphens, or underscores.`,\n );\n }\n}\n\nfunction validateText(value: string, label: string): void {\n if (/\\p{Cc}/u.test(value)) {\n throw new Error(`${label} must not contain control characters.`);\n }\n}\n\nfunction validateUrlScheme(value: string, label: string): void {\n if (!URL_SCHEME.test(value)) {\n throw new Error(\n `${label} must start with a letter and contain only letters, numbers, plus signs, periods, or hyphens.`,\n );\n }\n}\n\nfunction validateIosIdentifier(value: string, label: string): void {\n const segments = value.split('.');\n if (segments.length < 2 || segments.some((segment) => !IOS_IDENTIFIER_SEGMENT.test(segment))) {\n throw new Error(`${label} must be a valid reverse-DNS bundle identifier.`);\n }\n}\n\nfunction validateAndroidIdentifier(value: string, label: string): void {\n const segments = value.split('.');\n if (segments.length < 2 || segments.some((segment) => !ANDROID_IDENTIFIER_SEGMENT.test(segment))) {\n throw new Error(`${label} must be a valid reverse-DNS application ID.`);\n }\n}\n\nfunction toPascalConfigLabel(value: string): string {\n const words = value\n .replace(/([a-z0-9])([A-Z])/g, '$1-$2')\n .split(/[-_]+/)\n .filter((word) => word.length > 0);\n return words.map(capitalize).join('');\n}\n\nfunction capitalize(value: string): string {\n return `${value[0]?.toUpperCase() ?? ''}${value.slice(1).toLowerCase()}`;\n}\n\nfunction lowerFirst(value: string): string {\n return `${value[0]?.toLowerCase() ?? ''}${value.slice(1)}`;\n}\n\nfunction requireNonemptyString(value: unknown, label: string): string {\n if (typeof value !== 'string' || value.trim().length === 0) {\n throw new Error(`${label} must be a nonempty string.`);\n }\n return value;\n}\n\nfunction optionalNonemptyString(value: unknown, label: string): string | undefined {\n if (value === undefined) {\n return undefined;\n }\n return requireNonemptyString(value, label);\n}\n\nfunction requireRecord(value: unknown, label: string): Record<string, unknown> {\n if (!isRecord(value)) {\n throw new Error(`${label} must be an object.`);\n }\n return value;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction assertKnownKeys(\n record: Readonly<Record<string, unknown>>,\n knownKeys: ReadonlySet<string>,\n label: string,\n): void {\n const unknownKey = Object.keys(record).find((key) => !knownKeys.has(key));\n if (unknownKey !== undefined) {\n throw new Error(`${label} contains unknown key \"${unknownKey}\".`);\n }\n}\n"],"mappings":"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","names":[]}
|
package/dist/config/index.mjs
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
// src/options/normalize.ts
|
|
2
|
-
var ROOT_KEYS = /* @__PURE__ */ new Set(["canonicalVariant", "defaultVariant", "variants"]);
|
|
2
|
+
var ROOT_KEYS = /* @__PURE__ */ new Set(["canonicalVariant", "defaultVariant", "ios", "variants"]);
|
|
3
|
+
var ROOT_IOS_KEYS = /* @__PURE__ */ new Set(["targets"]);
|
|
4
|
+
var IOS_TARGET_KEYS = /* @__PURE__ */ new Set(["bundleIdentifierSuffix"]);
|
|
3
5
|
var VARIANT_KEYS = /* @__PURE__ */ new Set([
|
|
4
6
|
"android",
|
|
5
7
|
"applicationId",
|
|
@@ -65,7 +67,35 @@ function normalizeNativeVariants({
|
|
|
65
67
|
throw new Error(`canonicalVariant references unknown variant "${canonicalVariant}".`);
|
|
66
68
|
}
|
|
67
69
|
const variants = Object.freeze(normalizedVariants);
|
|
68
|
-
|
|
70
|
+
const iosTargets = normalizeIosTargets({
|
|
71
|
+
value: optionsRecord.ios,
|
|
72
|
+
variants
|
|
73
|
+
});
|
|
74
|
+
return Object.freeze({ canonicalVariant: canonical, iosTargets, variants });
|
|
75
|
+
}
|
|
76
|
+
function normalizeIosTargets({
|
|
77
|
+
value,
|
|
78
|
+
variants
|
|
79
|
+
}) {
|
|
80
|
+
if (value === void 0) {
|
|
81
|
+
return Object.freeze([]);
|
|
82
|
+
}
|
|
83
|
+
const ios = requireRecord(value, "Plugin options ios");
|
|
84
|
+
assertKnownKeys(ios, ROOT_IOS_KEYS, "Plugin options ios");
|
|
85
|
+
const targets = requireRecord(ios.targets, "Plugin options ios.targets");
|
|
86
|
+
const normalizedTargets = Object.entries(targets).map(([name, target]) => {
|
|
87
|
+
validateFileLabel(name, `iOS target name "${name}"`);
|
|
88
|
+
const targetRecord = requireRecord(target, `iOS target "${name}"`);
|
|
89
|
+
assertKnownKeys(targetRecord, IOS_TARGET_KEYS, `iOS target "${name}"`);
|
|
90
|
+
const bundleIdentifierSuffix = requireNonemptyString(
|
|
91
|
+
targetRecord.bundleIdentifierSuffix,
|
|
92
|
+
`iOS target "${name}" bundleIdentifierSuffix`
|
|
93
|
+
);
|
|
94
|
+
validateBundleIdentifierSuffix({ bundleIdentifierSuffix, name, variants });
|
|
95
|
+
return Object.freeze({ bundleIdentifierSuffix, name });
|
|
96
|
+
});
|
|
97
|
+
assertUniqueIosTargets(normalizedTargets, variants);
|
|
98
|
+
return Object.freeze(normalizedTargets);
|
|
69
99
|
}
|
|
70
100
|
function normalizeVariant({
|
|
71
101
|
configName,
|
|
@@ -205,6 +235,56 @@ function validateUniqueValues(variants) {
|
|
|
205
235
|
variants
|
|
206
236
|
});
|
|
207
237
|
}
|
|
238
|
+
function validateBundleIdentifierSuffix({
|
|
239
|
+
bundleIdentifierSuffix,
|
|
240
|
+
name,
|
|
241
|
+
variants
|
|
242
|
+
}) {
|
|
243
|
+
if (!bundleIdentifierSuffix.startsWith(".") || bundleIdentifierSuffix === ".") {
|
|
244
|
+
throw new Error(
|
|
245
|
+
`iOS target "${name}" bundleIdentifierSuffix must start with a period followed by a valid bundle identifier segment.`
|
|
246
|
+
);
|
|
247
|
+
}
|
|
248
|
+
for (const variant of variants) {
|
|
249
|
+
validateIosIdentifier(
|
|
250
|
+
`${variant.iosBundleIdentifier}${bundleIdentifierSuffix}`,
|
|
251
|
+
`iOS target "${name}" bundle identifier for variant "${variant.key}"`
|
|
252
|
+
);
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
function assertUniqueIosTargets(targets, variants) {
|
|
256
|
+
const targetByName = /* @__PURE__ */ new Map();
|
|
257
|
+
const identifierOwnerByValue = new Map(
|
|
258
|
+
variants.map((variant) => [
|
|
259
|
+
variant.iosBundleIdentifier.toLowerCase(),
|
|
260
|
+
`variant "${variant.key}" application target`
|
|
261
|
+
])
|
|
262
|
+
);
|
|
263
|
+
for (const target of targets) {
|
|
264
|
+
const normalizedName = target.name.toLowerCase();
|
|
265
|
+
const existingName = targetByName.get(normalizedName);
|
|
266
|
+
if (existingName !== void 0) {
|
|
267
|
+
throw new Error(
|
|
268
|
+
`iOS targets "${existingName}" and "${target.name}" have the same case-insensitive name.`
|
|
269
|
+
);
|
|
270
|
+
}
|
|
271
|
+
targetByName.set(normalizedName, target.name);
|
|
272
|
+
for (const variant of variants) {
|
|
273
|
+
const identifier = `${variant.iosBundleIdentifier}${target.bundleIdentifierSuffix}`;
|
|
274
|
+
const normalizedIdentifier = identifier.toLowerCase();
|
|
275
|
+
const owner = identifierOwnerByValue.get(normalizedIdentifier);
|
|
276
|
+
if (owner !== void 0) {
|
|
277
|
+
throw new Error(
|
|
278
|
+
`iOS target "${target.name}" and ${owner} produce the same bundle identifier "${identifier}".`
|
|
279
|
+
);
|
|
280
|
+
}
|
|
281
|
+
identifierOwnerByValue.set(
|
|
282
|
+
normalizedIdentifier,
|
|
283
|
+
`iOS target "${target.name}" for variant "${variant.key}"`
|
|
284
|
+
);
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
}
|
|
208
288
|
function assertNoCrossVariantRouteCollision({
|
|
209
289
|
identifierLabel,
|
|
210
290
|
selectIdentifier,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/options/normalize.ts","../../src/config/index.ts"],"sourcesContent":["import type {\n NativeVariantRunMode,\n NormalizedNativeVariant,\n NormalizedNativeVariantsOptions,\n NormalizeNativeVariantsArgs,\n} from './types';\n\nconst ROOT_KEYS = new Set(['canonicalVariant', 'defaultVariant', 'variants']);\nconst VARIANT_KEYS = new Set([\n 'android',\n 'applicationId',\n 'displayName',\n 'ios',\n 'runMode',\n 'urlScheme',\n]);\nconst IOS_KEYS = new Set(['bundleIdentifier', 'xcodeScheme']);\nconst ANDROID_KEYS = new Set(['applicationId']);\nconst RESERVED_VARIANT_NAMES = new Set([\n 'androidtest',\n 'aux',\n 'con',\n 'debug',\n 'main',\n 'nul',\n 'prn',\n 'release',\n 'test',\n 'unittest',\n]);\nconst WINDOWS_DEVICE_NAME = /^(?:com|lpt)[0-9]$/i;\nconst VARIANT_KEY = /^[A-Za-z][A-Za-z0-9_-]*$/;\nconst SAFE_FILE_LABEL = /^[A-Za-z0-9][A-Za-z0-9 ._-]*$/;\nconst URL_SCHEME = /^[A-Za-z][A-Za-z0-9+.-]*$/;\nconst IOS_IDENTIFIER_SEGMENT = /^[A-Za-z0-9][A-Za-z0-9-]*$/;\nconst ANDROID_IDENTIFIER_SEGMENT = /^[A-Za-z][A-Za-z0-9_]*$/;\n\nexport function normalizeNativeVariants({\n configName,\n options,\n canonicalVariant: canonicalOverride,\n}: NormalizeNativeVariantsArgs): NormalizedNativeVariantsOptions {\n validateFileLabel(configName, 'Expo config name');\n const optionsRecord = requireRecord(options, 'Plugin options');\n assertKnownKeys(optionsRecord, ROOT_KEYS, 'Plugin options');\n\n const defaultVariant = requireNonemptyString(\n optionsRecord.defaultVariant,\n 'defaultVariant',\n );\n const configuredCanonicalVariant = optionalNonemptyString(\n optionsRecord.canonicalVariant,\n 'canonicalVariant',\n );\n const canonicalVariant = canonicalOverride ?? configuredCanonicalVariant ?? defaultVariant;\n validateVariantKey(defaultVariant, 'defaultVariant');\n validateVariantKey(canonicalVariant, 'canonicalVariant');\n\n const variantsRecord = requireRecord(optionsRecord.variants, 'variants');\n const variantEntries = Object.entries(variantsRecord);\n if (variantEntries.length === 0) {\n throw new Error('variants must contain at least one variant.');\n }\n\n const normalizedVariants = variantEntries.map(([key, variant]) =>\n normalizeVariant({configName, key, variant}),\n );\n validateGeneratedNames(normalizedVariants);\n validateUniqueValues(normalizedVariants);\n\n if (!Object.hasOwn(variantsRecord, defaultVariant)) {\n throw new Error(`defaultVariant references unknown variant \"${defaultVariant}\".`);\n }\n\n const canonical = normalizedVariants.find(({key}) => key === canonicalVariant);\n if (canonical === undefined) {\n throw new Error(`canonicalVariant references unknown variant \"${canonicalVariant}\".`);\n }\n\n const variants = Object.freeze(normalizedVariants);\n return Object.freeze({canonicalVariant: canonical, variants});\n}\n\nfunction normalizeVariant({\n configName,\n key,\n variant,\n}: Readonly<{\n configName: string;\n key: string;\n variant: unknown;\n}>): NormalizedNativeVariant {\n validateVariantKey(key, `Variant key \"${key}\"`);\n const variantRecord = requireRecord(variant, `Variant \"${key}\"`);\n assertKnownKeys(variantRecord, VARIANT_KEYS, `Variant \"${key}\"`);\n\n const displayName = requireNonemptyString(\n variantRecord.displayName,\n `Variant \"${key}\" displayName`,\n );\n validateText(displayName, `Variant \"${key}\" displayName`);\n const applicationId = requireNonemptyString(\n variantRecord.applicationId,\n `Variant \"${key}\" applicationId`,\n );\n const urlScheme = requireNonemptyString(\n variantRecord.urlScheme,\n `Variant \"${key}\" urlScheme`,\n );\n validateUrlScheme(urlScheme, `Variant \"${key}\" urlScheme`);\n const runMode = readRunMode(variantRecord.runMode, key);\n const ios = readIosOptions(variantRecord.ios, key);\n const android = readAndroidOptions(variantRecord.android, key);\n const iosBundleIdentifier = ios.bundleIdentifier ?? applicationId;\n const androidApplicationId = android.applicationId ?? applicationId;\n validateIosIdentifier(iosBundleIdentifier, `Variant \"${key}\" iOS bundle identifier`);\n validateAndroidIdentifier(\n androidApplicationId,\n `Variant \"${key}\" Android application ID`,\n );\n\n const configLabel = toPascalConfigLabel(key);\n const generatedIosScheme = `${configName}-${configLabel}`;\n const iosScheme = ios.xcodeScheme ?? generatedIosScheme;\n validateFileLabel(iosScheme, `Variant \"${key}\" iOS scheme`);\n\n return Object.freeze({\n key,\n displayName,\n iosBundleIdentifier,\n androidApplicationId,\n urlScheme,\n runMode,\n iosScheme,\n debugConfiguration: `Debug-${configLabel}`,\n releaseConfiguration: `Release-${configLabel}`,\n androidFlavor: lowerFirst(configLabel),\n });\n}\n\nfunction readIosOptions(\n value: unknown,\n variantKey: string,\n): Readonly<{bundleIdentifier?: string; xcodeScheme?: string}> {\n if (value === undefined) {\n return {};\n }\n\n const record = requireRecord(value, `Variant \"${variantKey}\" ios`);\n assertKnownKeys(record, IOS_KEYS, `Variant \"${variantKey}\" ios`);\n const bundleIdentifier = optionalNonemptyString(\n record.bundleIdentifier,\n `Variant \"${variantKey}\" ios.bundleIdentifier`,\n );\n const xcodeScheme = optionalNonemptyString(\n record.xcodeScheme,\n `Variant \"${variantKey}\" ios.xcodeScheme`,\n );\n return compactOptionalStrings({bundleIdentifier, xcodeScheme});\n}\n\nfunction readAndroidOptions(\n value: unknown,\n variantKey: string,\n): Readonly<{applicationId?: string}> {\n if (value === undefined) {\n return {};\n }\n\n const record = requireRecord(value, `Variant \"${variantKey}\" android`);\n assertKnownKeys(record, ANDROID_KEYS, `Variant \"${variantKey}\" android`);\n const applicationId = optionalNonemptyString(\n record.applicationId,\n `Variant \"${variantKey}\" android.applicationId`,\n );\n return applicationId === undefined ? {} : {applicationId};\n}\n\nfunction compactOptionalStrings({\n bundleIdentifier,\n xcodeScheme,\n}: Readonly<{\n bundleIdentifier: string | undefined;\n xcodeScheme: string | undefined;\n}>): Readonly<{bundleIdentifier?: string; xcodeScheme?: string}> {\n if (bundleIdentifier === undefined) {\n if (xcodeScheme === undefined) {\n return {};\n }\n return {xcodeScheme};\n }\n if (xcodeScheme === undefined) {\n return {bundleIdentifier};\n }\n return {bundleIdentifier, xcodeScheme};\n}\n\nfunction readRunMode(value: unknown, variantKey: string): NativeVariantRunMode {\n if (value === undefined) {\n return 'debug';\n }\n if (value === 'debug' || value === 'release') {\n return value;\n }\n throw new Error(`Variant \"${variantKey}\" runMode must be \"debug\" or \"release\".`);\n}\n\nfunction validateGeneratedNames(variants: readonly NormalizedNativeVariant[]): void {\n for (const variant of variants) {\n const generatedName = variant.androidFlavor.toLowerCase();\n if (\n RESERVED_VARIANT_NAMES.has(generatedName) ||\n WINDOWS_DEVICE_NAME.test(generatedName)\n ) {\n throw new Error(\n `Variant key \"${variant.key}\" produces reserved name \"${variant.androidFlavor}\".`,\n );\n }\n }\n assertUnique(variants, ({key}) => key.toLowerCase(), 'variant key');\n assertUnique(variants, ({debugConfiguration}) => debugConfiguration.toLowerCase(), 'iOS configuration');\n assertUnique(variants, ({iosScheme}) => iosScheme.toLowerCase(), 'iOS scheme');\n assertUnique(variants, ({androidFlavor}) => androidFlavor.toLowerCase(), 'Android flavor');\n}\n\nfunction validateUniqueValues(variants: readonly NormalizedNativeVariant[]): void {\n assertUnique(\n variants,\n ({iosBundleIdentifier}) => iosBundleIdentifier.toLowerCase(),\n 'iOS bundle identifier',\n );\n assertUnique(\n variants,\n ({androidApplicationId}) => androidApplicationId.toLowerCase(),\n 'Android application ID',\n );\n assertUnique(variants, ({urlScheme}) => urlScheme.toLowerCase(), 'URL scheme');\n assertNoCrossVariantRouteCollision({\n identifierLabel: 'iOS bundle identifier',\n selectIdentifier: ({iosBundleIdentifier}) => iosBundleIdentifier,\n variants,\n });\n assertNoCrossVariantRouteCollision({\n identifierLabel: 'Android application ID',\n selectIdentifier: ({androidApplicationId}) => androidApplicationId,\n variants,\n });\n}\n\nfunction assertNoCrossVariantRouteCollision({\n identifierLabel,\n selectIdentifier,\n variants,\n}: Readonly<{\n identifierLabel: string;\n selectIdentifier: (variant: NormalizedNativeVariant) => string;\n variants: readonly NormalizedNativeVariant[];\n}>): void {\n const identifierOwnerByValue = new Map(\n variants.map((variant) => [\n selectIdentifier(variant).toLowerCase(),\n variant.key,\n ]),\n );\n\n for (const variant of variants) {\n const identifierOwner = identifierOwnerByValue.get(variant.urlScheme.toLowerCase());\n if (identifierOwner !== undefined && identifierOwner !== variant.key) {\n throw new Error(\n `Variant \"${variant.key}\" URL scheme \"${variant.urlScheme}\" matches variant \"${identifierOwner}\" ${identifierLabel}.`,\n );\n }\n }\n}\n\nfunction assertUnique(\n variants: readonly NormalizedNativeVariant[],\n select: (variant: NormalizedNativeVariant) => string,\n label: string,\n): void {\n const ownerByValue = new Map<string, string>();\n for (const variant of variants) {\n const value = select(variant);\n const owner = ownerByValue.get(value);\n if (owner !== undefined) {\n throw new Error(\n `Variants \"${owner}\" and \"${variant.key}\" produce the same ${label} \"${value}\".`,\n );\n }\n ownerByValue.set(value, variant.key);\n }\n}\n\nfunction validateVariantKey(value: string, label: string): void {\n if (!VARIANT_KEY.test(value)) {\n throw new Error(\n `${label} must start with a letter and contain only letters, numbers, hyphens, or underscores.`,\n );\n }\n const normalized = value.toLowerCase();\n if (RESERVED_VARIANT_NAMES.has(normalized) || WINDOWS_DEVICE_NAME.test(normalized)) {\n throw new Error(`${label} uses reserved name \"${value}\".`);\n }\n}\n\nfunction validateFileLabel(value: string, label: string): void {\n if (value !== value.trim() || !SAFE_FILE_LABEL.test(value) || value === '.' || value === '..') {\n throw new Error(\n `${label} must be a path-safe name containing only letters, numbers, spaces, periods, hyphens, or underscores.`,\n );\n }\n}\n\nfunction validateText(value: string, label: string): void {\n if (/\\p{Cc}/u.test(value)) {\n throw new Error(`${label} must not contain control characters.`);\n }\n}\n\nfunction validateUrlScheme(value: string, label: string): void {\n if (!URL_SCHEME.test(value)) {\n throw new Error(\n `${label} must start with a letter and contain only letters, numbers, plus signs, periods, or hyphens.`,\n );\n }\n}\n\nfunction validateIosIdentifier(value: string, label: string): void {\n const segments = value.split('.');\n if (segments.length < 2 || segments.some((segment) => !IOS_IDENTIFIER_SEGMENT.test(segment))) {\n throw new Error(`${label} must be a valid reverse-DNS bundle identifier.`);\n }\n}\n\nfunction validateAndroidIdentifier(value: string, label: string): void {\n const segments = value.split('.');\n if (segments.length < 2 || segments.some((segment) => !ANDROID_IDENTIFIER_SEGMENT.test(segment))) {\n throw new Error(`${label} must be a valid reverse-DNS application ID.`);\n }\n}\n\nfunction toPascalConfigLabel(value: string): string {\n const words = value\n .replace(/([a-z0-9])([A-Z])/g, '$1-$2')\n .split(/[-_]+/)\n .filter((word) => word.length > 0);\n return words.map(capitalize).join('');\n}\n\nfunction capitalize(value: string): string {\n return `${value[0]?.toUpperCase() ?? ''}${value.slice(1).toLowerCase()}`;\n}\n\nfunction lowerFirst(value: string): string {\n return `${value[0]?.toLowerCase() ?? ''}${value.slice(1)}`;\n}\n\nfunction requireNonemptyString(value: unknown, label: string): string {\n if (typeof value !== 'string' || value.trim().length === 0) {\n throw new Error(`${label} must be a nonempty string.`);\n }\n return value;\n}\n\nfunction optionalNonemptyString(value: unknown, label: string): string | undefined {\n if (value === undefined) {\n return undefined;\n }\n return requireNonemptyString(value, label);\n}\n\nfunction requireRecord(value: unknown, label: string): Record<string, unknown> {\n if (!isRecord(value)) {\n throw new Error(`${label} must be an object.`);\n }\n return value;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction assertKnownKeys(\n record: Readonly<Record<string, unknown>>,\n knownKeys: ReadonlySet<string>,\n label: string,\n): void {\n const unknownKey = Object.keys(record).find((key) => !knownKeys.has(key));\n if (unknownKey !== undefined) {\n throw new Error(`${label} contains unknown key \"${unknownKey}\".`);\n }\n}\n","import type {ExpoConfig} from 'expo/config';\n\nimport {normalizeNativeVariants} from '../options';\nimport type {NativeVariantOptions, NativeVariantsOptions} from '../options';\n\nconst PLUGIN_NAME = 'expo-native-variants';\nconst PLUGIN_SPECIFIERS = new Set([\n PLUGIN_NAME,\n `${PLUGIN_NAME}/app.plugin.js`,\n]);\n\nexport type CreateNativeVariantsConfigArgs = Readonly<{\n config: ExpoConfig;\n options: NativeVariantsConfigInput;\n variant?: string;\n}>;\n\ntype NativeVariantConfigInput = Readonly<\n Omit<NativeVariantOptions, 'runMode'> & {runMode?: string}\n>;\n\nexport type NativeVariantsConfigInput = Readonly<\n Omit<NativeVariantsOptions, 'variants'> & {\n variants: Readonly<Record<string, NativeVariantConfigInput>>;\n }\n>;\n\n/**\n * Projects one variant's identifiers into app config before EAS reads them,\n * while registering the plugin with the complete native variant matrix.\n * This helper remains experimental until cloud builds are verified.\n */\nexport function createNativeVariantsConfig({\n config,\n options,\n variant,\n}: CreateNativeVariantsConfigArgs): ExpoConfig {\n assertPluginIsNotRegistered(config.plugins);\n const canonicalVariant =\n variant ?? options.canonicalVariant ?? options.defaultVariant;\n const normalized = normalizeNativeVariants({\n canonicalVariant,\n configName: config.name,\n options,\n });\n const selected = normalized.canonicalVariant;\n const pluginOptions: NativeVariantsConfigInput = {\n ...options,\n canonicalVariant: selected.key,\n };\n\n return {\n ...config,\n android: {\n ...config.android,\n package: selected.androidApplicationId,\n },\n ios: {\n ...config.ios,\n bundleIdentifier: selected.iosBundleIdentifier,\n },\n plugins: [...(config.plugins ?? []), [PLUGIN_NAME, pluginOptions]],\n };\n}\n\nfunction assertPluginIsNotRegistered(plugins: ExpoConfig['plugins']): void {\n const existingRegistration = plugins?.find(\n (plugin) =>\n (typeof plugin === 'string' && PLUGIN_SPECIFIERS.has(plugin)) ||\n (Array.isArray(plugin) && PLUGIN_SPECIFIERS.has(plugin[0] ?? '')),\n );\n if (existingRegistration !== undefined) {\n throw new Error(\n 'expo-native-variants is already registered in config.plugins. Remove the existing entry before using createNativeVariantsConfig.',\n );\n }\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../src/options/normalize.ts","../../src/config/index.ts"],"sourcesContent":["import type {\n NativeVariantRunMode,\n NormalizedNativeVariant,\n NormalizedNativeVariantsIosTarget,\n NormalizedNativeVariantsOptions,\n NormalizeNativeVariantsArgs,\n} from './types';\n\nconst ROOT_KEYS = new Set(['canonicalVariant', 'defaultVariant', 'ios', 'variants']);\nconst ROOT_IOS_KEYS = new Set(['targets']);\nconst IOS_TARGET_KEYS = new Set(['bundleIdentifierSuffix']);\nconst VARIANT_KEYS = new Set([\n 'android',\n 'applicationId',\n 'displayName',\n 'ios',\n 'runMode',\n 'urlScheme',\n]);\nconst IOS_KEYS = new Set(['bundleIdentifier', 'xcodeScheme']);\nconst ANDROID_KEYS = new Set(['applicationId']);\nconst RESERVED_VARIANT_NAMES = new Set([\n 'androidtest',\n 'aux',\n 'con',\n 'debug',\n 'main',\n 'nul',\n 'prn',\n 'release',\n 'test',\n 'unittest',\n]);\nconst WINDOWS_DEVICE_NAME = /^(?:com|lpt)[0-9]$/i;\nconst VARIANT_KEY = /^[A-Za-z][A-Za-z0-9_-]*$/;\nconst SAFE_FILE_LABEL = /^[A-Za-z0-9][A-Za-z0-9 ._-]*$/;\nconst URL_SCHEME = /^[A-Za-z][A-Za-z0-9+.-]*$/;\nconst IOS_IDENTIFIER_SEGMENT = /^[A-Za-z0-9][A-Za-z0-9-]*$/;\nconst ANDROID_IDENTIFIER_SEGMENT = /^[A-Za-z][A-Za-z0-9_]*$/;\n\nexport function normalizeNativeVariants({\n configName,\n options,\n canonicalVariant: canonicalOverride,\n}: NormalizeNativeVariantsArgs): NormalizedNativeVariantsOptions {\n validateFileLabel(configName, 'Expo config name');\n const optionsRecord = requireRecord(options, 'Plugin options');\n assertKnownKeys(optionsRecord, ROOT_KEYS, 'Plugin options');\n\n const defaultVariant = requireNonemptyString(\n optionsRecord.defaultVariant,\n 'defaultVariant',\n );\n const configuredCanonicalVariant = optionalNonemptyString(\n optionsRecord.canonicalVariant,\n 'canonicalVariant',\n );\n const canonicalVariant = canonicalOverride ?? configuredCanonicalVariant ?? defaultVariant;\n validateVariantKey(defaultVariant, 'defaultVariant');\n validateVariantKey(canonicalVariant, 'canonicalVariant');\n\n const variantsRecord = requireRecord(optionsRecord.variants, 'variants');\n const variantEntries = Object.entries(variantsRecord);\n if (variantEntries.length === 0) {\n throw new Error('variants must contain at least one variant.');\n }\n\n const normalizedVariants = variantEntries.map(([key, variant]) =>\n normalizeVariant({configName, key, variant}),\n );\n validateGeneratedNames(normalizedVariants);\n validateUniqueValues(normalizedVariants);\n\n if (!Object.hasOwn(variantsRecord, defaultVariant)) {\n throw new Error(`defaultVariant references unknown variant \"${defaultVariant}\".`);\n }\n\n const canonical = normalizedVariants.find(({key}) => key === canonicalVariant);\n if (canonical === undefined) {\n throw new Error(`canonicalVariant references unknown variant \"${canonicalVariant}\".`);\n }\n\n const variants = Object.freeze(normalizedVariants);\n const iosTargets = normalizeIosTargets({\n value: optionsRecord.ios,\n variants,\n });\n return Object.freeze({canonicalVariant: canonical, iosTargets, variants});\n}\n\nfunction normalizeIosTargets({\n value,\n variants,\n}: Readonly<{\n value: unknown;\n variants: readonly NormalizedNativeVariant[];\n}>): readonly NormalizedNativeVariantsIosTarget[] {\n if (value === undefined) {\n return Object.freeze([]);\n }\n\n const ios = requireRecord(value, 'Plugin options ios');\n assertKnownKeys(ios, ROOT_IOS_KEYS, 'Plugin options ios');\n const targets = requireRecord(ios.targets, 'Plugin options ios.targets');\n const normalizedTargets = Object.entries(targets).map(([name, target]) => {\n validateFileLabel(name, `iOS target name \"${name}\"`);\n const targetRecord = requireRecord(target, `iOS target \"${name}\"`);\n assertKnownKeys(targetRecord, IOS_TARGET_KEYS, `iOS target \"${name}\"`);\n const bundleIdentifierSuffix = requireNonemptyString(\n targetRecord.bundleIdentifierSuffix,\n `iOS target \"${name}\" bundleIdentifierSuffix`,\n );\n validateBundleIdentifierSuffix({bundleIdentifierSuffix, name, variants});\n return Object.freeze({bundleIdentifierSuffix, name});\n });\n\n assertUniqueIosTargets(normalizedTargets, variants);\n return Object.freeze(normalizedTargets);\n}\n\nfunction normalizeVariant({\n configName,\n key,\n variant,\n}: Readonly<{\n configName: string;\n key: string;\n variant: unknown;\n}>): NormalizedNativeVariant {\n validateVariantKey(key, `Variant key \"${key}\"`);\n const variantRecord = requireRecord(variant, `Variant \"${key}\"`);\n assertKnownKeys(variantRecord, VARIANT_KEYS, `Variant \"${key}\"`);\n\n const displayName = requireNonemptyString(\n variantRecord.displayName,\n `Variant \"${key}\" displayName`,\n );\n validateText(displayName, `Variant \"${key}\" displayName`);\n const applicationId = requireNonemptyString(\n variantRecord.applicationId,\n `Variant \"${key}\" applicationId`,\n );\n const urlScheme = requireNonemptyString(\n variantRecord.urlScheme,\n `Variant \"${key}\" urlScheme`,\n );\n validateUrlScheme(urlScheme, `Variant \"${key}\" urlScheme`);\n const runMode = readRunMode(variantRecord.runMode, key);\n const ios = readIosOptions(variantRecord.ios, key);\n const android = readAndroidOptions(variantRecord.android, key);\n const iosBundleIdentifier = ios.bundleIdentifier ?? applicationId;\n const androidApplicationId = android.applicationId ?? applicationId;\n validateIosIdentifier(iosBundleIdentifier, `Variant \"${key}\" iOS bundle identifier`);\n validateAndroidIdentifier(\n androidApplicationId,\n `Variant \"${key}\" Android application ID`,\n );\n\n const configLabel = toPascalConfigLabel(key);\n const generatedIosScheme = `${configName}-${configLabel}`;\n const iosScheme = ios.xcodeScheme ?? generatedIosScheme;\n validateFileLabel(iosScheme, `Variant \"${key}\" iOS scheme`);\n\n return Object.freeze({\n key,\n displayName,\n iosBundleIdentifier,\n androidApplicationId,\n urlScheme,\n runMode,\n iosScheme,\n debugConfiguration: `Debug-${configLabel}`,\n releaseConfiguration: `Release-${configLabel}`,\n androidFlavor: lowerFirst(configLabel),\n });\n}\n\nfunction readIosOptions(\n value: unknown,\n variantKey: string,\n): Readonly<{bundleIdentifier?: string; xcodeScheme?: string}> {\n if (value === undefined) {\n return {};\n }\n\n const record = requireRecord(value, `Variant \"${variantKey}\" ios`);\n assertKnownKeys(record, IOS_KEYS, `Variant \"${variantKey}\" ios`);\n const bundleIdentifier = optionalNonemptyString(\n record.bundleIdentifier,\n `Variant \"${variantKey}\" ios.bundleIdentifier`,\n );\n const xcodeScheme = optionalNonemptyString(\n record.xcodeScheme,\n `Variant \"${variantKey}\" ios.xcodeScheme`,\n );\n return compactOptionalStrings({bundleIdentifier, xcodeScheme});\n}\n\nfunction readAndroidOptions(\n value: unknown,\n variantKey: string,\n): Readonly<{applicationId?: string}> {\n if (value === undefined) {\n return {};\n }\n\n const record = requireRecord(value, `Variant \"${variantKey}\" android`);\n assertKnownKeys(record, ANDROID_KEYS, `Variant \"${variantKey}\" android`);\n const applicationId = optionalNonemptyString(\n record.applicationId,\n `Variant \"${variantKey}\" android.applicationId`,\n );\n return applicationId === undefined ? {} : {applicationId};\n}\n\nfunction compactOptionalStrings({\n bundleIdentifier,\n xcodeScheme,\n}: Readonly<{\n bundleIdentifier: string | undefined;\n xcodeScheme: string | undefined;\n}>): Readonly<{bundleIdentifier?: string; xcodeScheme?: string}> {\n if (bundleIdentifier === undefined) {\n if (xcodeScheme === undefined) {\n return {};\n }\n return {xcodeScheme};\n }\n if (xcodeScheme === undefined) {\n return {bundleIdentifier};\n }\n return {bundleIdentifier, xcodeScheme};\n}\n\nfunction readRunMode(value: unknown, variantKey: string): NativeVariantRunMode {\n if (value === undefined) {\n return 'debug';\n }\n if (value === 'debug' || value === 'release') {\n return value;\n }\n throw new Error(`Variant \"${variantKey}\" runMode must be \"debug\" or \"release\".`);\n}\n\nfunction validateGeneratedNames(variants: readonly NormalizedNativeVariant[]): void {\n for (const variant of variants) {\n const generatedName = variant.androidFlavor.toLowerCase();\n if (\n RESERVED_VARIANT_NAMES.has(generatedName) ||\n WINDOWS_DEVICE_NAME.test(generatedName)\n ) {\n throw new Error(\n `Variant key \"${variant.key}\" produces reserved name \"${variant.androidFlavor}\".`,\n );\n }\n }\n assertUnique(variants, ({key}) => key.toLowerCase(), 'variant key');\n assertUnique(variants, ({debugConfiguration}) => debugConfiguration.toLowerCase(), 'iOS configuration');\n assertUnique(variants, ({iosScheme}) => iosScheme.toLowerCase(), 'iOS scheme');\n assertUnique(variants, ({androidFlavor}) => androidFlavor.toLowerCase(), 'Android flavor');\n}\n\nfunction validateUniqueValues(variants: readonly NormalizedNativeVariant[]): void {\n assertUnique(\n variants,\n ({iosBundleIdentifier}) => iosBundleIdentifier.toLowerCase(),\n 'iOS bundle identifier',\n );\n assertUnique(\n variants,\n ({androidApplicationId}) => androidApplicationId.toLowerCase(),\n 'Android application ID',\n );\n assertUnique(variants, ({urlScheme}) => urlScheme.toLowerCase(), 'URL scheme');\n assertNoCrossVariantRouteCollision({\n identifierLabel: 'iOS bundle identifier',\n selectIdentifier: ({iosBundleIdentifier}) => iosBundleIdentifier,\n variants,\n });\n assertNoCrossVariantRouteCollision({\n identifierLabel: 'Android application ID',\n selectIdentifier: ({androidApplicationId}) => androidApplicationId,\n variants,\n });\n}\n\nfunction validateBundleIdentifierSuffix({\n bundleIdentifierSuffix,\n name,\n variants,\n}: Readonly<{\n bundleIdentifierSuffix: string;\n name: string;\n variants: readonly NormalizedNativeVariant[];\n}>): void {\n if (!bundleIdentifierSuffix.startsWith('.') || bundleIdentifierSuffix === '.') {\n throw new Error(\n `iOS target \"${name}\" bundleIdentifierSuffix must start with a period followed by a valid bundle identifier segment.`,\n );\n }\n for (const variant of variants) {\n validateIosIdentifier(\n `${variant.iosBundleIdentifier}${bundleIdentifierSuffix}`,\n `iOS target \"${name}\" bundle identifier for variant \"${variant.key}\"`,\n );\n }\n}\n\nfunction assertUniqueIosTargets(\n targets: readonly NormalizedNativeVariantsIosTarget[],\n variants: readonly NormalizedNativeVariant[],\n): void {\n const targetByName = new Map<string, string>();\n const identifierOwnerByValue = new Map(\n variants.map((variant) => [\n variant.iosBundleIdentifier.toLowerCase(),\n `variant \"${variant.key}\" application target`,\n ]),\n );\n\n for (const target of targets) {\n const normalizedName = target.name.toLowerCase();\n const existingName = targetByName.get(normalizedName);\n if (existingName !== undefined) {\n throw new Error(\n `iOS targets \"${existingName}\" and \"${target.name}\" have the same case-insensitive name.`,\n );\n }\n targetByName.set(normalizedName, target.name);\n\n for (const variant of variants) {\n const identifier = `${variant.iosBundleIdentifier}${target.bundleIdentifierSuffix}`;\n const normalizedIdentifier = identifier.toLowerCase();\n const owner = identifierOwnerByValue.get(normalizedIdentifier);\n if (owner !== undefined) {\n throw new Error(\n `iOS target \"${target.name}\" and ${owner} produce the same bundle identifier \"${identifier}\".`,\n );\n }\n identifierOwnerByValue.set(\n normalizedIdentifier,\n `iOS target \"${target.name}\" for variant \"${variant.key}\"`,\n );\n }\n }\n}\n\nfunction assertNoCrossVariantRouteCollision({\n identifierLabel,\n selectIdentifier,\n variants,\n}: Readonly<{\n identifierLabel: string;\n selectIdentifier: (variant: NormalizedNativeVariant) => string;\n variants: readonly NormalizedNativeVariant[];\n}>): void {\n const identifierOwnerByValue = new Map(\n variants.map((variant) => [\n selectIdentifier(variant).toLowerCase(),\n variant.key,\n ]),\n );\n\n for (const variant of variants) {\n const identifierOwner = identifierOwnerByValue.get(variant.urlScheme.toLowerCase());\n if (identifierOwner !== undefined && identifierOwner !== variant.key) {\n throw new Error(\n `Variant \"${variant.key}\" URL scheme \"${variant.urlScheme}\" matches variant \"${identifierOwner}\" ${identifierLabel}.`,\n );\n }\n }\n}\n\nfunction assertUnique(\n variants: readonly NormalizedNativeVariant[],\n select: (variant: NormalizedNativeVariant) => string,\n label: string,\n): void {\n const ownerByValue = new Map<string, string>();\n for (const variant of variants) {\n const value = select(variant);\n const owner = ownerByValue.get(value);\n if (owner !== undefined) {\n throw new Error(\n `Variants \"${owner}\" and \"${variant.key}\" produce the same ${label} \"${value}\".`,\n );\n }\n ownerByValue.set(value, variant.key);\n }\n}\n\nfunction validateVariantKey(value: string, label: string): void {\n if (!VARIANT_KEY.test(value)) {\n throw new Error(\n `${label} must start with a letter and contain only letters, numbers, hyphens, or underscores.`,\n );\n }\n const normalized = value.toLowerCase();\n if (RESERVED_VARIANT_NAMES.has(normalized) || WINDOWS_DEVICE_NAME.test(normalized)) {\n throw new Error(`${label} uses reserved name \"${value}\".`);\n }\n}\n\nfunction validateFileLabel(value: string, label: string): void {\n if (value !== value.trim() || !SAFE_FILE_LABEL.test(value) || value === '.' || value === '..') {\n throw new Error(\n `${label} must be a path-safe name containing only letters, numbers, spaces, periods, hyphens, or underscores.`,\n );\n }\n}\n\nfunction validateText(value: string, label: string): void {\n if (/\\p{Cc}/u.test(value)) {\n throw new Error(`${label} must not contain control characters.`);\n }\n}\n\nfunction validateUrlScheme(value: string, label: string): void {\n if (!URL_SCHEME.test(value)) {\n throw new Error(\n `${label} must start with a letter and contain only letters, numbers, plus signs, periods, or hyphens.`,\n );\n }\n}\n\nfunction validateIosIdentifier(value: string, label: string): void {\n const segments = value.split('.');\n if (segments.length < 2 || segments.some((segment) => !IOS_IDENTIFIER_SEGMENT.test(segment))) {\n throw new Error(`${label} must be a valid reverse-DNS bundle identifier.`);\n }\n}\n\nfunction validateAndroidIdentifier(value: string, label: string): void {\n const segments = value.split('.');\n if (segments.length < 2 || segments.some((segment) => !ANDROID_IDENTIFIER_SEGMENT.test(segment))) {\n throw new Error(`${label} must be a valid reverse-DNS application ID.`);\n }\n}\n\nfunction toPascalConfigLabel(value: string): string {\n const words = value\n .replace(/([a-z0-9])([A-Z])/g, '$1-$2')\n .split(/[-_]+/)\n .filter((word) => word.length > 0);\n return words.map(capitalize).join('');\n}\n\nfunction capitalize(value: string): string {\n return `${value[0]?.toUpperCase() ?? ''}${value.slice(1).toLowerCase()}`;\n}\n\nfunction lowerFirst(value: string): string {\n return `${value[0]?.toLowerCase() ?? ''}${value.slice(1)}`;\n}\n\nfunction requireNonemptyString(value: unknown, label: string): string {\n if (typeof value !== 'string' || value.trim().length === 0) {\n throw new Error(`${label} must be a nonempty string.`);\n }\n return value;\n}\n\nfunction optionalNonemptyString(value: unknown, label: string): string | undefined {\n if (value === undefined) {\n return undefined;\n }\n return requireNonemptyString(value, label);\n}\n\nfunction requireRecord(value: unknown, label: string): Record<string, unknown> {\n if (!isRecord(value)) {\n throw new Error(`${label} must be an object.`);\n }\n return value;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction assertKnownKeys(\n record: Readonly<Record<string, unknown>>,\n knownKeys: ReadonlySet<string>,\n label: string,\n): void {\n const unknownKey = Object.keys(record).find((key) => !knownKeys.has(key));\n if (unknownKey !== undefined) {\n throw new Error(`${label} contains unknown key \"${unknownKey}\".`);\n }\n}\n","import type {ExpoConfig} from 'expo/config';\n\nimport {normalizeNativeVariants} from '../options';\nimport type {NativeVariantOptions, NativeVariantsOptions} from '../options';\n\nconst PLUGIN_NAME = 'expo-native-variants';\nconst PLUGIN_SPECIFIERS = new Set([\n PLUGIN_NAME,\n `${PLUGIN_NAME}/app.plugin.js`,\n]);\n\nexport type CreateNativeVariantsConfigArgs = Readonly<{\n config: ExpoConfig;\n options: NativeVariantsConfigInput;\n variant?: string;\n}>;\n\ntype NativeVariantConfigInput = Readonly<\n Omit<NativeVariantOptions, 'runMode'> & {runMode?: string}\n>;\n\nexport type NativeVariantsConfigInput = Readonly<\n Omit<NativeVariantsOptions, 'variants'> & {\n variants: Readonly<Record<string, NativeVariantConfigInput>>;\n }\n>;\n\n/**\n * Projects one variant's identifiers into app config before EAS reads them,\n * while registering the plugin with the complete native variant matrix.\n * This helper remains experimental until cloud builds are verified.\n */\nexport function createNativeVariantsConfig({\n config,\n options,\n variant,\n}: CreateNativeVariantsConfigArgs): ExpoConfig {\n assertPluginIsNotRegistered(config.plugins);\n const canonicalVariant =\n variant ?? options.canonicalVariant ?? options.defaultVariant;\n const normalized = normalizeNativeVariants({\n canonicalVariant,\n configName: config.name,\n options,\n });\n const selected = normalized.canonicalVariant;\n const pluginOptions: NativeVariantsConfigInput = {\n ...options,\n canonicalVariant: selected.key,\n };\n\n return {\n ...config,\n android: {\n ...config.android,\n package: selected.androidApplicationId,\n },\n ios: {\n ...config.ios,\n bundleIdentifier: selected.iosBundleIdentifier,\n },\n plugins: [...(config.plugins ?? []), [PLUGIN_NAME, pluginOptions]],\n };\n}\n\nfunction assertPluginIsNotRegistered(plugins: ExpoConfig['plugins']): void {\n const existingRegistration = plugins?.find(\n (plugin) =>\n (typeof plugin === 'string' && PLUGIN_SPECIFIERS.has(plugin)) ||\n (Array.isArray(plugin) && PLUGIN_SPECIFIERS.has(plugin[0] ?? '')),\n );\n if (existingRegistration !== undefined) {\n throw new Error(\n 'expo-native-variants is already registered in config.plugins. Remove the existing entry before using createNativeVariantsConfig.',\n );\n }\n}\n"],"mappings":"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","names":[]}
|
package/dist/index.d.mts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { ConfigPlugin } from 'expo/config-plugins
|
|
2
|
-
import { b as NormalizeNativeVariantsArgs, c as NormalizedNativeVariantsOptions, N as NativeVariantsOptions } from './types-
|
|
3
|
-
export { d as NativeVariantAndroidOptions, e as NativeVariantIosOptions, f as NativeVariantMap, a as NativeVariantOptions, g as NativeVariantRunMode, h as NormalizedNativeVariant } from './types-
|
|
1
|
+
import { ConfigPlugin } from 'expo/config-plugins';
|
|
2
|
+
import { b as NormalizeNativeVariantsArgs, c as NormalizedNativeVariantsOptions, N as NativeVariantsOptions } from './types-CJFxZDYt.mjs';
|
|
3
|
+
export { d as NativeVariantAndroidOptions, e as NativeVariantIosOptions, f as NativeVariantMap, a as NativeVariantOptions, g as NativeVariantRunMode, h as NativeVariantsIosOptions, i as NativeVariantsIosTargetOptions, j as NormalizedNativeVariant, k as NormalizedNativeVariantsIosTarget } from './types-CJFxZDYt.mjs';
|
|
4
4
|
|
|
5
5
|
declare function normalizeNativeVariants({ configName, options, canonicalVariant: canonicalOverride, }: NormalizeNativeVariantsArgs): NormalizedNativeVariantsOptions;
|
|
6
6
|
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { ConfigPlugin } from 'expo/config-plugins
|
|
2
|
-
import { b as NormalizeNativeVariantsArgs, c as NormalizedNativeVariantsOptions, N as NativeVariantsOptions } from './types-
|
|
3
|
-
export { d as NativeVariantAndroidOptions, e as NativeVariantIosOptions, f as NativeVariantMap, a as NativeVariantOptions, g as NativeVariantRunMode, h as NormalizedNativeVariant } from './types-
|
|
1
|
+
import { ConfigPlugin } from 'expo/config-plugins';
|
|
2
|
+
import { b as NormalizeNativeVariantsArgs, c as NormalizedNativeVariantsOptions, N as NativeVariantsOptions } from './types-CJFxZDYt.js';
|
|
3
|
+
export { d as NativeVariantAndroidOptions, e as NativeVariantIosOptions, f as NativeVariantMap, a as NativeVariantOptions, g as NativeVariantRunMode, h as NativeVariantsIosOptions, i as NativeVariantsIosTargetOptions, j as NormalizedNativeVariant, k as NormalizedNativeVariantsIosTarget } from './types-CJFxZDYt.js';
|
|
4
4
|
|
|
5
5
|
declare function normalizeNativeVariants({ configName, options, canonicalVariant: canonicalOverride, }: NormalizeNativeVariantsArgs): NormalizedNativeVariantsOptions;
|
|
6
6
|
|