@ankhorage/expo-runtime 2.6.0 → 3.0.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/CHANGELOG.md +12 -0
- package/README.md +1 -2
- package/dist/ExpoBarcodeScannerAdapter.d.ts.map +1 -1
- package/dist/ExpoBarcodeScannerAdapter.js +4 -16
- package/dist/ExpoBarcodeScannerAdapter.js.map +1 -1
- package/dist/barcodeScanRuntime.d.ts +4 -1
- package/dist/barcodeScanRuntime.d.ts.map +1 -1
- package/dist/barcodeScanRuntime.js +15 -1
- package/dist/barcodeScanRuntime.js.map +1 -1
- package/dist/expoRuntimePlanningMetadata.d.ts +59 -0
- package/dist/expoRuntimePlanningMetadata.d.ts.map +1 -0
- package/dist/expoRuntimePlanningMetadata.js +133 -0
- package/dist/expoRuntimePlanningMetadata.js.map +1 -0
- package/dist/mediaPicker/documentPicker.d.ts +1 -2
- package/dist/mediaPicker/documentPicker.d.ts.map +1 -1
- package/dist/mediaPicker/documentPicker.js +1 -1
- package/dist/mediaPicker/documentPicker.js.map +1 -1
- package/dist/mediaPicker/photoLibraryPicker.d.ts +1 -2
- package/dist/mediaPicker/photoLibraryPicker.d.ts.map +1 -1
- package/dist/mediaPicker/photoLibraryPicker.js +1 -1
- package/dist/mediaPicker/photoLibraryPicker.js.map +1 -1
- package/dist/mediaPicker/readSelectedBytes.d.ts +1 -4
- package/dist/mediaPicker/readSelectedBytes.d.ts.map +1 -1
- package/dist/mediaPicker/readSelectedBytes.js +7 -1
- package/dist/mediaPicker/readSelectedBytes.js.map +1 -1
- package/dist/platform.d.ts +83 -0
- package/dist/platform.d.ts.map +1 -0
- package/dist/platform.js +81 -0
- package/dist/platform.js.map +1 -0
- package/dist/resolveExpoRuntimePlan.d.ts +3 -23
- package/dist/resolveExpoRuntimePlan.d.ts.map +1 -1
- package/dist/resolveExpoRuntimePlan.js +155 -187
- package/dist/resolveExpoRuntimePlan.js.map +1 -1
- package/package.json +74 -29
- package/src/ExpoBarcodeScannerAdapter.test.tsx +47 -4
- package/src/ExpoBarcodeScannerAdapter.tsx +10 -19
- package/src/barcodeScanRuntime.ts +27 -2
- package/src/expoRuntimePlanningMetadata.ts +190 -0
- package/src/generatedAppOutput.test.ts +29 -7
- package/src/mediaPicker/documentPicker.ts +1 -6
- package/src/mediaPicker/photoLibraryPicker.ts +1 -6
- package/src/mediaPicker/readSelectedBytes.ts +12 -3
- package/src/oauthBrowserRuntime.test.ts +1 -1
- package/src/platform.test.ts +34 -0
- package/src/platform.ts +88 -0
- package/src/resolveExpoRuntimePlan.test.ts +130 -6
- package/src/resolveExpoRuntimePlan.ts +214 -244
|
@@ -11,6 +11,24 @@ import {
|
|
|
11
11
|
type PermissionSupport,
|
|
12
12
|
} from '@ankhorage/permissions/expo/manifest';
|
|
13
13
|
|
|
14
|
+
import {
|
|
15
|
+
EXPO_CAPABILITY_RUNTIME_REGISTRY,
|
|
16
|
+
EXPO_RUNTIME_PROVIDER_PACKAGES,
|
|
17
|
+
type ExpoRuntimeAdapterId,
|
|
18
|
+
type ExpoRuntimeCapabilityMetadata,
|
|
19
|
+
type ExpoRuntimeConfigPlugin,
|
|
20
|
+
type ExpoRuntimeDiagnostic,
|
|
21
|
+
type ExpoRuntimeProviderId,
|
|
22
|
+
findCapabilityMetadata,
|
|
23
|
+
findConfigHintMetadata,
|
|
24
|
+
GENERATED_RUNTIME_DEPENDENCY_VERSIONS,
|
|
25
|
+
unknownCapabilityDiagnostic,
|
|
26
|
+
unknownPermissionDiagnostic,
|
|
27
|
+
unsupportedPermissionDiagnostic,
|
|
28
|
+
} from './expoRuntimePlanningMetadata';
|
|
29
|
+
|
|
30
|
+
export type { ExpoRuntimeAdapterId, ExpoRuntimeProviderId };
|
|
31
|
+
|
|
14
32
|
export interface ExpoRuntimePlanningScreen {
|
|
15
33
|
readonly requires?: {
|
|
16
34
|
readonly capabilities?: readonly ScreenCapabilityRequirement[];
|
|
@@ -28,22 +46,6 @@ interface ExpoRuntimeDependency {
|
|
|
28
46
|
readonly reasons: readonly string[];
|
|
29
47
|
}
|
|
30
48
|
|
|
31
|
-
interface ExpoRuntimeConfigPlugin {
|
|
32
|
-
readonly name: string;
|
|
33
|
-
readonly options?: Readonly<Record<string, boolean | string>>;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
export type ExpoRuntimeProviderId = 'permissions';
|
|
37
|
-
export type ExpoRuntimeAdapterId = 'ExpoBarcodeScannerAdapter';
|
|
38
|
-
|
|
39
|
-
interface ExpoRuntimeDiagnostic {
|
|
40
|
-
readonly severity: 'error' | 'warning';
|
|
41
|
-
readonly requirementType: 'capability' | 'configHint' | 'package' | 'permission';
|
|
42
|
-
readonly requirement: string;
|
|
43
|
-
readonly message: string;
|
|
44
|
-
readonly support?: PermissionSupport;
|
|
45
|
-
}
|
|
46
|
-
|
|
47
49
|
export interface ExpoRuntimePlan {
|
|
48
50
|
readonly permissions: readonly ScreenPermissionRequirement[];
|
|
49
51
|
readonly capabilities: readonly ScreenCapabilityRequirement[];
|
|
@@ -61,20 +63,6 @@ export interface ExpoRuntimePlan {
|
|
|
61
63
|
readonly diagnostics: readonly ExpoRuntimeDiagnostic[];
|
|
62
64
|
}
|
|
63
65
|
|
|
64
|
-
interface ExpoRuntimeCapabilityMetadata {
|
|
65
|
-
readonly impliedPermissions?: readonly ScreenPermissionRequirement[];
|
|
66
|
-
readonly requiredPackages?: readonly string[];
|
|
67
|
-
readonly providers?: readonly ExpoRuntimeProviderId[];
|
|
68
|
-
readonly runtimeAdapters?: readonly ExpoRuntimeAdapterId[];
|
|
69
|
-
readonly androidPermissions?: readonly string[];
|
|
70
|
-
readonly plugins?: readonly ExpoRuntimeConfigPlugin[];
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
interface ExpoRuntimeHintMetadata {
|
|
74
|
-
readonly androidPermissions?: readonly string[];
|
|
75
|
-
readonly plugin?: ExpoRuntimeConfigPlugin;
|
|
76
|
-
}
|
|
77
|
-
|
|
78
66
|
interface ResolveExpoRuntimePlanOptions {
|
|
79
67
|
readonly capabilityRegistry?: Readonly<
|
|
80
68
|
Partial<Record<AnkhorageCapabilityName, ExpoRuntimeCapabilityMetadata>>
|
|
@@ -83,263 +71,245 @@ interface ResolveExpoRuntimePlanOptions {
|
|
|
83
71
|
readonly permissionSupport?: Readonly<Record<Permission, ExpoPermissionMetadata>>;
|
|
84
72
|
}
|
|
85
73
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
}
|
|
74
|
+
interface PlanningState {
|
|
75
|
+
readonly permissions: Map<string, ScreenPermissionRequirement>;
|
|
76
|
+
readonly impliedPermissions: Map<string, ScreenPermissionRequirement>;
|
|
77
|
+
readonly capabilities: Map<string, ScreenCapabilityRequirement>;
|
|
78
|
+
readonly diagnostics: ExpoRuntimeDiagnostic[];
|
|
79
|
+
readonly dependencies: Map<string, ExpoRuntimeDependency>;
|
|
80
|
+
readonly pluginOptions: Map<string, Record<string, boolean | string>>;
|
|
81
|
+
readonly configHints: Set<string>;
|
|
82
|
+
readonly androidPermissions: Set<string>;
|
|
83
|
+
readonly providers: Set<ExpoRuntimeProviderId>;
|
|
84
|
+
readonly runtimeAdapters: Set<ExpoRuntimeAdapterId>;
|
|
85
|
+
}
|
|
98
86
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
},
|
|
108
|
-
},
|
|
109
|
-
} as const satisfies Readonly<Record<string, ExpoRuntimeHintMetadata>>;
|
|
87
|
+
interface PlanningContext {
|
|
88
|
+
readonly state: PlanningState;
|
|
89
|
+
readonly capabilityRegistry: Readonly<
|
|
90
|
+
Partial<Record<AnkhorageCapabilityName, ExpoRuntimeCapabilityMetadata>>
|
|
91
|
+
>;
|
|
92
|
+
readonly dependencyVersions: Readonly<Record<string, string>>;
|
|
93
|
+
readonly permissionSupport: Readonly<Record<Permission, ExpoPermissionMetadata>>;
|
|
94
|
+
}
|
|
110
95
|
|
|
111
|
-
const
|
|
112
|
-
barcodeScanner: {
|
|
113
|
-
impliedPermissions: [{ permission: 'camera' }],
|
|
114
|
-
requiredPackages: ['expo-camera'],
|
|
115
|
-
providers: ['permissions'],
|
|
116
|
-
runtimeAdapters: ['ExpoBarcodeScannerAdapter'],
|
|
117
|
-
androidPermissions: [CAMERA_ANDROID_PERMISSION],
|
|
118
|
-
plugins: [
|
|
119
|
-
{
|
|
120
|
-
name: 'expo-camera',
|
|
121
|
-
options: {
|
|
122
|
-
cameraPermission: 'Allow camera access to scan barcodes.',
|
|
123
|
-
},
|
|
124
|
-
},
|
|
125
|
-
],
|
|
126
|
-
},
|
|
127
|
-
} as const satisfies Readonly<
|
|
128
|
-
Partial<Record<AnkhorageCapabilityName, ExpoRuntimeCapabilityMetadata>>
|
|
129
|
-
>;
|
|
96
|
+
const EXPO_RUNTIME_PACKAGE_NAME = '@ankhorage/expo-runtime';
|
|
130
97
|
|
|
131
98
|
export function resolveExpoRuntimePlan(
|
|
132
99
|
manifest: ExpoRuntimePlanningManifest,
|
|
133
100
|
options: ResolveExpoRuntimePlanOptions = {},
|
|
134
101
|
): ExpoRuntimePlan {
|
|
135
|
-
const
|
|
136
|
-
const
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
const capabilityRegistry: Readonly<
|
|
149
|
-
Partial<Record<AnkhorageCapabilityName, ExpoRuntimeCapabilityMetadata>>
|
|
150
|
-
> = options.capabilityRegistry ?? EXPO_CAPABILITY_RUNTIME_REGISTRY;
|
|
151
|
-
|
|
152
|
-
for (const capabilityRequirement of capabilitiesByName.values()) {
|
|
153
|
-
capabilityRegistry[capabilityRequirement.capability]?.impliedPermissions?.forEach(
|
|
154
|
-
(permissionRequirement: ScreenPermissionRequirement) => {
|
|
155
|
-
if (!permissionsByName.has(permissionRequirement.permission)) {
|
|
156
|
-
permissionsByName.set(permissionRequirement.permission, permissionRequirement);
|
|
157
|
-
impliedPermissionsByName.set(permissionRequirement.permission, permissionRequirement);
|
|
158
|
-
}
|
|
159
|
-
},
|
|
160
|
-
);
|
|
102
|
+
const state = createPlanningState(manifest);
|
|
103
|
+
const context: PlanningContext = {
|
|
104
|
+
state,
|
|
105
|
+
capabilityRegistry: options.capabilityRegistry ?? EXPO_CAPABILITY_RUNTIME_REGISTRY,
|
|
106
|
+
dependencyVersions: options.dependencyVersions ?? GENERATED_RUNTIME_DEPENDENCY_VERSIONS,
|
|
107
|
+
permissionSupport: options.permissionSupport ?? EXPO_PERMISSION_SUPPORT,
|
|
108
|
+
};
|
|
109
|
+
addImpliedPermissions(context);
|
|
110
|
+
planPermissions(context);
|
|
111
|
+
planCapabilities(context);
|
|
112
|
+
if (state.providers.size > 0 || state.runtimeAdapters.size > 0) {
|
|
113
|
+
addDependency(context, EXPO_RUNTIME_PACKAGE_NAME, 'runtime:expo');
|
|
161
114
|
}
|
|
115
|
+
return buildPlan(state);
|
|
116
|
+
}
|
|
162
117
|
|
|
163
|
-
|
|
164
|
-
const
|
|
165
|
-
const
|
|
166
|
-
const
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
const runtimeAdapters = new Set<ExpoRuntimeAdapterId>();
|
|
170
|
-
const dependencyVersions: Readonly<Record<string, string>> =
|
|
171
|
-
options.dependencyVersions ?? GENERATED_EXPO_DEPENDENCY_VERSIONS;
|
|
172
|
-
const permissionSupport = options.permissionSupport ?? EXPO_PERMISSION_SUPPORT;
|
|
173
|
-
const configHintRegistry: Readonly<Record<string, ExpoRuntimeHintMetadata>> =
|
|
174
|
-
EXPO_RUNTIME_CONFIG_HINTS;
|
|
175
|
-
|
|
176
|
-
const addDependency = (name: string, reason: string) => {
|
|
177
|
-
const version = dependencyVersions[name];
|
|
178
|
-
if (version === undefined) {
|
|
179
|
-
diagnostics.push({
|
|
180
|
-
severity: 'warning',
|
|
181
|
-
requirementType: 'package',
|
|
182
|
-
requirement: name,
|
|
183
|
-
message: `No generated-app dependency version is registered for '${name}'.`,
|
|
184
|
-
});
|
|
185
|
-
return;
|
|
118
|
+
function createPlanningState(manifest: ExpoRuntimePlanningManifest): PlanningState {
|
|
119
|
+
const permissions = new Map<string, ScreenPermissionRequirement>();
|
|
120
|
+
const capabilities = new Map<string, ScreenCapabilityRequirement>();
|
|
121
|
+
for (const screen of Object.values(manifest.screens)) {
|
|
122
|
+
for (const requirement of screen.requires?.permissions ?? []) {
|
|
123
|
+
permissions.set(requirement.permission, requirement);
|
|
186
124
|
}
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
if (existing) {
|
|
190
|
-
dependencies.set(name, {
|
|
191
|
-
...existing,
|
|
192
|
-
reasons: Array.from(new Set([...existing.reasons, reason])),
|
|
193
|
-
});
|
|
194
|
-
return;
|
|
125
|
+
for (const requirement of screen.requires?.capabilities ?? []) {
|
|
126
|
+
capabilities.set(requirement.capability, requirement);
|
|
195
127
|
}
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
const addPlugin = (plugin: ExpoRuntimeConfigPlugin) => {
|
|
210
|
-
const existingOptions = pluginOptions.get(plugin.name) ?? {};
|
|
211
|
-
pluginOptions.set(plugin.name, {
|
|
212
|
-
...existingOptions,
|
|
213
|
-
...(plugin.options ?? {}),
|
|
214
|
-
});
|
|
128
|
+
}
|
|
129
|
+
return {
|
|
130
|
+
permissions,
|
|
131
|
+
capabilities,
|
|
132
|
+
impliedPermissions: new Map(),
|
|
133
|
+
diagnostics: [],
|
|
134
|
+
dependencies: new Map(),
|
|
135
|
+
pluginOptions: new Map(),
|
|
136
|
+
configHints: new Set(),
|
|
137
|
+
androidPermissions: new Set(),
|
|
138
|
+
providers: new Set(),
|
|
139
|
+
runtimeAdapters: new Set(),
|
|
215
140
|
};
|
|
141
|
+
}
|
|
216
142
|
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
const supportMetadata = permissionSupport[permissionRequirement.permission];
|
|
229
|
-
if (
|
|
230
|
-
supportMetadata.support === 'unsupported' ||
|
|
231
|
-
supportMetadata.support === 'notImplemented' ||
|
|
232
|
-
supportMetadata.support === 'limited'
|
|
233
|
-
) {
|
|
234
|
-
diagnostics.push({
|
|
235
|
-
severity: supportMetadata.support === 'limited' ? 'warning' : 'error',
|
|
236
|
-
requirementType: 'permission',
|
|
237
|
-
requirement: permissionRequirement.permission,
|
|
238
|
-
message: `Expo runtime support for '${permissionRequirement.permission}' is '${supportMetadata.support}'.`,
|
|
239
|
-
support: supportMetadata.support,
|
|
240
|
-
});
|
|
241
|
-
continue;
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
if (supportMetadata.support === 'notRequired') {
|
|
245
|
-
continue;
|
|
143
|
+
function addImpliedPermissions(context: PlanningContext): void {
|
|
144
|
+
const { state } = context;
|
|
145
|
+
for (const capability of state.capabilities.values()) {
|
|
146
|
+
const metadata = findCapabilityMetadata(context.capabilityRegistry, capability);
|
|
147
|
+
for (const permission of metadata?.impliedPermissions ?? []) {
|
|
148
|
+
if (!state.permissions.has(permission.permission)) {
|
|
149
|
+
state.permissions.set(permission.permission, permission);
|
|
150
|
+
state.impliedPermissions.set(permission.permission, permission);
|
|
151
|
+
}
|
|
246
152
|
}
|
|
153
|
+
}
|
|
154
|
+
}
|
|
247
155
|
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
supportMetadata.configHints.forEach((configHint) => {
|
|
254
|
-
configHints.add(configHint);
|
|
255
|
-
const configHintMetadata = configHintRegistry[configHint];
|
|
256
|
-
if (!configHintMetadata) {
|
|
257
|
-
diagnostics.push({
|
|
258
|
-
severity: 'warning',
|
|
259
|
-
requirementType: 'configHint',
|
|
260
|
-
requirement: configHint,
|
|
261
|
-
message: `Config hint '${configHint}' is not translated into generated Expo config yet.`,
|
|
262
|
-
});
|
|
263
|
-
return;
|
|
264
|
-
}
|
|
156
|
+
function planPermissions(context: PlanningContext): void {
|
|
157
|
+
for (const requirement of context.state.permissions.values()) {
|
|
158
|
+
planPermission(context, requirement);
|
|
159
|
+
}
|
|
160
|
+
}
|
|
265
161
|
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
162
|
+
function planPermission(context: PlanningContext, requirement: ScreenPermissionRequirement): void {
|
|
163
|
+
if (!isPermission(requirement.permission)) {
|
|
164
|
+
context.state.diagnostics.push(unknownPermissionDiagnostic(requirement.permission));
|
|
165
|
+
return;
|
|
166
|
+
}
|
|
167
|
+
const metadata = findPermissionSupport(context.permissionSupport, requirement.permission);
|
|
168
|
+
if (isUnsupported(metadata.support)) {
|
|
169
|
+
context.state.diagnostics.push(
|
|
170
|
+
unsupportedPermissionDiagnostic(requirement.permission, metadata.support),
|
|
171
|
+
);
|
|
172
|
+
return;
|
|
173
|
+
}
|
|
174
|
+
if (metadata.support === 'notRequired') {
|
|
175
|
+
return;
|
|
273
176
|
}
|
|
177
|
+
const reason = `permission:${requirement.permission}`;
|
|
178
|
+
addProvider(context, 'permissions', reason);
|
|
179
|
+
metadata.requiredPackages.forEach((name) => addDependency(context, name, reason));
|
|
180
|
+
metadata.configHints.forEach((hint) => applyConfigHint(context.state, hint));
|
|
181
|
+
}
|
|
274
182
|
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
requirementType: 'capability',
|
|
281
|
-
requirement: capabilityRequirement.capability,
|
|
282
|
-
message: `No Expo runtime metadata is registered for capability '${capabilityRequirement.capability}'.`,
|
|
283
|
-
});
|
|
183
|
+
function planCapabilities(context: PlanningContext): void {
|
|
184
|
+
for (const requirement of context.state.capabilities.values()) {
|
|
185
|
+
const metadata = findCapabilityMetadata(context.capabilityRegistry, requirement);
|
|
186
|
+
if (metadata === undefined) {
|
|
187
|
+
context.state.diagnostics.push(unknownCapabilityDiagnostic(requirement.capability));
|
|
284
188
|
continue;
|
|
285
189
|
}
|
|
190
|
+
const reason = `capability:${requirement.capability}`;
|
|
191
|
+
metadata.requiredPackages?.forEach((name) => addDependency(context, name, reason));
|
|
192
|
+
metadata.providers?.forEach((provider) => addProvider(context, provider, reason));
|
|
193
|
+
metadata.runtimeAdapters?.forEach((adapter) => context.state.runtimeAdapters.add(adapter));
|
|
194
|
+
metadata.androidPermissions?.forEach((permission) =>
|
|
195
|
+
context.state.androidPermissions.add(permission),
|
|
196
|
+
);
|
|
197
|
+
metadata.plugins?.forEach((plugin) => addPlugin(context.state, plugin));
|
|
198
|
+
}
|
|
199
|
+
}
|
|
286
200
|
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
201
|
+
function applyConfigHint(state: PlanningState, configHint: string): void {
|
|
202
|
+
state.configHints.add(configHint);
|
|
203
|
+
const metadata = findConfigHintMetadata(configHint);
|
|
204
|
+
if (metadata === undefined) {
|
|
205
|
+
state.diagnostics.push({
|
|
206
|
+
severity: 'warning',
|
|
207
|
+
requirementType: 'configHint',
|
|
208
|
+
requirement: configHint,
|
|
209
|
+
message: `Config hint '${configHint}' is not translated into generated Expo config yet.`,
|
|
295
210
|
});
|
|
296
|
-
|
|
297
|
-
|
|
211
|
+
return;
|
|
212
|
+
}
|
|
213
|
+
metadata.androidPermissions?.forEach((permission) => state.androidPermissions.add(permission));
|
|
214
|
+
if (metadata.plugin !== undefined) {
|
|
215
|
+
addPlugin(state, metadata.plugin);
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
function addDependency(context: PlanningContext, name: string, reason: string): void {
|
|
220
|
+
const version = findDependencyVersion(context.dependencyVersions, name);
|
|
221
|
+
if (version === undefined) {
|
|
222
|
+
context.state.diagnostics.push({
|
|
223
|
+
severity: 'warning',
|
|
224
|
+
requirementType: 'package',
|
|
225
|
+
requirement: name,
|
|
226
|
+
message: `No generated-app dependency version is registered for '${name}'.`,
|
|
298
227
|
});
|
|
299
|
-
|
|
228
|
+
return;
|
|
300
229
|
}
|
|
230
|
+
const existing = context.state.dependencies.get(name);
|
|
231
|
+
context.state.dependencies.set(name, {
|
|
232
|
+
name,
|
|
233
|
+
version,
|
|
234
|
+
reasons: existing === undefined ? [reason] : Array.from(new Set([...existing.reasons, reason])),
|
|
235
|
+
});
|
|
236
|
+
}
|
|
301
237
|
|
|
302
|
-
|
|
303
|
-
|
|
238
|
+
function addProvider(
|
|
239
|
+
context: PlanningContext,
|
|
240
|
+
provider: ExpoRuntimeProviderId,
|
|
241
|
+
reason: string,
|
|
242
|
+
): void {
|
|
243
|
+
context.state.providers.add(provider);
|
|
244
|
+
const packageName = Object.entries(EXPO_RUNTIME_PROVIDER_PACKAGES).find(
|
|
245
|
+
([name]) => name === String(provider),
|
|
246
|
+
)?.[1];
|
|
247
|
+
if (packageName === undefined) {
|
|
248
|
+
throw new Error(`Runtime package metadata is missing for provider '${provider}'.`);
|
|
304
249
|
}
|
|
250
|
+
addDependency(context, packageName, reason);
|
|
251
|
+
}
|
|
305
252
|
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
}))
|
|
311
|
-
.sort((left, right) => left.name.localeCompare(right.name));
|
|
253
|
+
function addPlugin(state: PlanningState, plugin: ExpoRuntimeConfigPlugin): void {
|
|
254
|
+
const existingOptions = state.pluginOptions.get(plugin.name) ?? {};
|
|
255
|
+
state.pluginOptions.set(plugin.name, { ...existingOptions, ...(plugin.options ?? {}) });
|
|
256
|
+
}
|
|
312
257
|
|
|
258
|
+
function buildPlan(state: PlanningState): ExpoRuntimePlan {
|
|
259
|
+
const plugins = Array.from(state.pluginOptions, ([name, options]) => ({
|
|
260
|
+
name,
|
|
261
|
+
options: Object.keys(options).length > 0 ? options : undefined,
|
|
262
|
+
})).sort((left, right) => left.name.localeCompare(right.name));
|
|
313
263
|
return {
|
|
314
|
-
permissions: Array.from(
|
|
315
|
-
capabilities: Array.from(
|
|
316
|
-
impliedPermissions: Array.from(
|
|
317
|
-
|
|
318
|
-
),
|
|
319
|
-
dependencies: Array.from(dependencies.values()).sort((left, right) =>
|
|
264
|
+
permissions: Array.from(state.permissions.values()).sort(comparePermissions),
|
|
265
|
+
capabilities: Array.from(state.capabilities.values()).sort(compareCapabilities),
|
|
266
|
+
impliedPermissions: Array.from(state.impliedPermissions.values()).sort(comparePermissions),
|
|
267
|
+
dependencies: Array.from(state.dependencies.values()).sort((left, right) =>
|
|
320
268
|
left.name.localeCompare(right.name),
|
|
321
269
|
),
|
|
322
270
|
nativeConfig: {
|
|
323
|
-
androidPermissions: Array.from(androidPermissions).sort(),
|
|
324
|
-
configHints: Array.from(configHints).sort(),
|
|
271
|
+
androidPermissions: Array.from(state.androidPermissions).sort(),
|
|
272
|
+
configHints: Array.from(state.configHints).sort(),
|
|
325
273
|
plugins,
|
|
326
274
|
},
|
|
327
|
-
providers: Array.from(providers).sort(),
|
|
328
|
-
runtimeAdapters: Array.from(runtimeAdapters).sort(),
|
|
329
|
-
usesExpoRuntimeRegistry: runtimeAdapters.size > 0,
|
|
330
|
-
needsPermissionsProvider: providers.has('permissions'),
|
|
331
|
-
diagnostics,
|
|
275
|
+
providers: Array.from(state.providers).sort(),
|
|
276
|
+
runtimeAdapters: Array.from(state.runtimeAdapters).sort(),
|
|
277
|
+
usesExpoRuntimeRegistry: state.runtimeAdapters.size > 0,
|
|
278
|
+
needsPermissionsProvider: state.providers.has('permissions'),
|
|
279
|
+
diagnostics: state.diagnostics,
|
|
332
280
|
};
|
|
333
281
|
}
|
|
334
282
|
|
|
335
|
-
function
|
|
283
|
+
function findPermissionSupport(
|
|
284
|
+
registry: Readonly<Record<Permission, ExpoPermissionMetadata>>,
|
|
285
|
+
permission: Permission,
|
|
286
|
+
): ExpoPermissionMetadata {
|
|
287
|
+
const metadata = Object.entries(registry).find(([name]) => name === String(permission))?.[1];
|
|
288
|
+
if (metadata === undefined) {
|
|
289
|
+
throw new Error(`Permission metadata is missing for '${permission}'.`);
|
|
290
|
+
}
|
|
291
|
+
return metadata;
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
function findDependencyVersion(
|
|
295
|
+
versions: Readonly<Record<string, string>>,
|
|
296
|
+
name: string,
|
|
297
|
+
): string | undefined {
|
|
298
|
+
return Object.entries(versions).find(([candidate]) => candidate === name)?.[1];
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
function isUnsupported(support: PermissionSupport): boolean {
|
|
302
|
+
return support === 'unsupported' || support === 'notImplemented' || support === 'limited';
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
function compareCapabilities(
|
|
336
306
|
left: ScreenCapabilityRequirement,
|
|
337
307
|
right: ScreenCapabilityRequirement,
|
|
338
308
|
): number {
|
|
339
309
|
return left.capability.localeCompare(right.capability);
|
|
340
310
|
}
|
|
341
311
|
|
|
342
|
-
function
|
|
312
|
+
function comparePermissions(
|
|
343
313
|
left: ScreenPermissionRequirement,
|
|
344
314
|
right: ScreenPermissionRequirement,
|
|
345
315
|
): number {
|