@expo-harmony/expo-modules-autolinking 55.0.27-harmony.2 → 55.0.27-harmony.3
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/build/runtime.d.ts +1 -1
- package/build/runtime.js +15 -26
- package/build/src/harmony/configuredBuild.js +2 -2
- package/package.json +1 -1
- package/runtime.ts +16 -28
- package/src/harmony/configuredBuild.ts +2 -2
package/build/runtime.d.ts
CHANGED
|
@@ -22,7 +22,7 @@ export interface HarmonyRuntimeContract {
|
|
|
22
22
|
modules: HarmonyNativeModule[];
|
|
23
23
|
config: {
|
|
24
24
|
nativeCompiler: string;
|
|
25
|
-
targetApiVersion
|
|
25
|
+
targetApiVersion?: number | string;
|
|
26
26
|
compatibleApiVersion: number | string;
|
|
27
27
|
nativeLibFilterHash?: string;
|
|
28
28
|
permissions: string[];
|
package/build/runtime.js
CHANGED
|
@@ -19,31 +19,17 @@ exports.HarmonyCompatibilityError = HarmonyCompatibilityError;
|
|
|
19
19
|
function record(value) {
|
|
20
20
|
return value !== null && typeof value === 'object' && !Array.isArray(value);
|
|
21
21
|
}
|
|
22
|
-
function
|
|
23
|
-
return typeof value === 'string' &&
|
|
24
|
-
&& !value.includes('://') && !value.includes('..') && !/^[A-Za-z]:/.test(value);
|
|
22
|
+
function nonEmptyString(value) {
|
|
23
|
+
return typeof value === 'string' && value.length > 0;
|
|
25
24
|
}
|
|
26
25
|
function strings(value) {
|
|
27
|
-
return Array.isArray(value) && value.every(
|
|
26
|
+
return Array.isArray(value) && value.every(nonEmptyString) && new Set(value).size === value.length;
|
|
28
27
|
}
|
|
29
28
|
const Versions = ['runtimeVersion', 'expo', 'expoModulesCore', 'rnoh', 'react', 'hermes'];
|
|
30
29
|
const Settings = ['permissions', 'querySchemes', 'backgroundModes', 'abiFilters'];
|
|
31
30
|
function apiVersion(value, schema) {
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
if (schema === 2 && typeof value === 'string' && /^(?:[1-9]\d{1,2})\.(?:0|[1-9]\d{0,2})\.(?:0|[1-9]\d{0,2})$/.test(value)) {
|
|
35
|
-
const parts = value.split('.').map(Number);
|
|
36
|
-
if (parts[0] >= 26)
|
|
37
|
-
return parts;
|
|
38
|
-
}
|
|
39
|
-
return undefined;
|
|
40
|
-
}
|
|
41
|
-
function compareApiVersions(left, right) {
|
|
42
|
-
for (let index = 0; index < 3; index++) {
|
|
43
|
-
if (left[index] !== right[index])
|
|
44
|
-
return left[index] - right[index];
|
|
45
|
-
}
|
|
46
|
-
return 0;
|
|
31
|
+
return (typeof value === 'number' && Number.isSafeInteger(value) && value > 0)
|
|
32
|
+
|| (schema === 2 && typeof value === 'string' && /^\d+\.\d+\.\d+$/.test(value));
|
|
47
33
|
}
|
|
48
34
|
function harmonyRuntimeSchemaVersion(config) {
|
|
49
35
|
return typeof config.targetApiVersion === 'string' || typeof config.compatibleApiVersion === 'string'
|
|
@@ -67,7 +53,7 @@ function validateHarmonyRuntime(value) {
|
|
|
67
53
|
issues.push({ code: 'INVALID_CONTRACT', field: 'development', message: 'development must describe native development support.' });
|
|
68
54
|
}
|
|
69
55
|
for (const field of Versions) {
|
|
70
|
-
if (
|
|
56
|
+
if (!nonEmptyString(value[field])) {
|
|
71
57
|
issues.push({ code: 'INVALID_CONTRACT', field, message: `${field} must be an explicit version.` });
|
|
72
58
|
}
|
|
73
59
|
}
|
|
@@ -77,7 +63,7 @@ function validateHarmonyRuntime(value) {
|
|
|
77
63
|
else {
|
|
78
64
|
const names = new Set();
|
|
79
65
|
for (const module of value.modules) {
|
|
80
|
-
if (!record(module) || !
|
|
66
|
+
if (!record(module) || !nonEmptyString(module.packageName) || !nonEmptyString(module.packageVersion)
|
|
81
67
|
|| !strings(module.modules) || !strings(module.services) || !strings(module.registrations)
|
|
82
68
|
|| !strings(module.artifacts) || module.artifacts.some(hash => !/^[a-f0-9]{64}$/.test(hash))
|
|
83
69
|
|| names.has(module.packageName)) {
|
|
@@ -89,13 +75,13 @@ function validateHarmonyRuntime(value) {
|
|
|
89
75
|
}
|
|
90
76
|
}
|
|
91
77
|
const config = value.config;
|
|
92
|
-
const target = record(config)
|
|
78
|
+
const target = record(config)
|
|
79
|
+
&& (config.targetApiVersion === undefined || apiVersion(config.targetApiVersion, value.schemaVersion));
|
|
93
80
|
const compatible = record(config) ? apiVersion(config.compatibleApiVersion, value.schemaVersion) : undefined;
|
|
94
|
-
if (!record(config) || !
|
|
95
|
-
|| !target || !compatible
|
|
81
|
+
if (!record(config) || !nonEmptyString(config.nativeCompiler) || !Settings.every(field => strings(config[field]))
|
|
82
|
+
|| !target || !compatible
|
|
96
83
|
|| (config.nativeLibFilterHash !== undefined && (value.schemaVersion !== 2
|
|
97
|
-
|| typeof config.nativeLibFilterHash !== 'string' || !/^[a-f0-9]{64}$/.test(config.nativeLibFilterHash)))
|
|
98
|
-
|| (Array.isArray(config.abiFilters) && config.abiFilters.length === 0)) {
|
|
84
|
+
|| typeof config.nativeLibFilterHash !== 'string' || !/^[a-f0-9]{64}$/.test(config.nativeLibFilterHash)))) {
|
|
99
85
|
issues.push({ code: 'INVALID_CONTRACT', field: 'config', message: 'Invalid native build configuration.' });
|
|
100
86
|
}
|
|
101
87
|
return issues;
|
|
@@ -133,6 +119,9 @@ function checkHarmonyCompatibility(client, requirements) {
|
|
|
133
119
|
}
|
|
134
120
|
}
|
|
135
121
|
for (const field of ['nativeCompiler', 'targetApiVersion', 'compatibleApiVersion', 'nativeLibFilterHash']) {
|
|
122
|
+
// Hvigor chooses the target SDK when neither targetSdkVersion nor compileSdkVersion is explicit.
|
|
123
|
+
if (field === 'targetApiVersion' && (available.config[field] === undefined || required.config[field] === undefined))
|
|
124
|
+
continue;
|
|
136
125
|
if (available.config[field] !== required.config[field]) {
|
|
137
126
|
issues.push({ code: 'CONFIG_MISMATCH', field, message: `${field}: project requires ${required.config[field]}, client provides ${available.config[field]}.` });
|
|
138
127
|
}
|
|
@@ -188,8 +188,8 @@ async function buildConfiguredModulesAsync(modules, raw) {
|
|
|
188
188
|
}
|
|
189
189
|
const settings = options.moduleBuildSettings;
|
|
190
190
|
if (settings) {
|
|
191
|
-
if (!Array.isArray(settings.abiFilters)
|
|
192
|
-
|| settings.abiFilters.some(abi =>
|
|
191
|
+
if (!Array.isArray(settings.abiFilters)
|
|
192
|
+
|| settings.abiFilters.some(abi => typeof abi !== 'string' || !abi)
|
|
193
193
|
|| ![settings.compatibleSdkVersion, settings.targetSdkVersion].every(value => typeof value === 'string' && value.length > 0)) {
|
|
194
194
|
throw new errors_1.HarmonyAutolinkingError('INVALID_OPTIONS', 'Invalid moduleBuildSettings; run Harmony prebuild again.', {
|
|
195
195
|
stage: 'configured-module-build',
|
package/package.json
CHANGED
package/runtime.ts
CHANGED
|
@@ -23,7 +23,7 @@ export interface HarmonyRuntimeContract {
|
|
|
23
23
|
modules: HarmonyNativeModule[];
|
|
24
24
|
config: {
|
|
25
25
|
nativeCompiler: string;
|
|
26
|
-
targetApiVersion
|
|
26
|
+
targetApiVersion?: number | string;
|
|
27
27
|
compatibleApiVersion: number | string;
|
|
28
28
|
nativeLibFilterHash?: string;
|
|
29
29
|
permissions: string[];
|
|
@@ -53,34 +53,20 @@ function record(value: unknown): value is Record<string, unknown> {
|
|
|
53
53
|
return value !== null && typeof value === 'object' && !Array.isArray(value);
|
|
54
54
|
}
|
|
55
55
|
|
|
56
|
-
function
|
|
57
|
-
return typeof value === 'string' &&
|
|
58
|
-
&& !value.includes('://') && !value.includes('..') && !/^[A-Za-z]:/.test(value);
|
|
56
|
+
function nonEmptyString(value: unknown): value is string {
|
|
57
|
+
return typeof value === 'string' && value.length > 0;
|
|
59
58
|
}
|
|
60
59
|
|
|
61
60
|
function strings(value: unknown): value is string[] {
|
|
62
|
-
return Array.isArray(value) && value.every(
|
|
61
|
+
return Array.isArray(value) && value.every(nonEmptyString) && new Set(value).size === value.length;
|
|
63
62
|
}
|
|
64
63
|
|
|
65
64
|
const Versions = ['runtimeVersion', 'expo', 'expoModulesCore', 'rnoh', 'react', 'hermes'] as const;
|
|
66
65
|
const Settings = ['permissions', 'querySchemes', 'backgroundModes', 'abiFilters'] as const;
|
|
67
66
|
|
|
68
|
-
function apiVersion(value: unknown, schema: unknown):
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
const parts = value.split('.').map(Number);
|
|
72
|
-
if (parts[0] >= 26) return parts;
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
return undefined;
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
function compareApiVersions(left: number[], right: number[]): number {
|
|
79
|
-
for (let index = 0; index < 3; index++) {
|
|
80
|
-
if (left[index] !== right[index]) return left[index] - right[index];
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
return 0;
|
|
67
|
+
function apiVersion(value: unknown, schema: unknown): boolean {
|
|
68
|
+
return (typeof value === 'number' && Number.isSafeInteger(value) && value > 0)
|
|
69
|
+
|| (schema === 2 && typeof value === 'string' && /^\d+\.\d+\.\d+$/.test(value));
|
|
84
70
|
}
|
|
85
71
|
|
|
86
72
|
export function harmonyRuntimeSchemaVersion(config: HarmonyRuntimeContract['config']): 1 | 2 {
|
|
@@ -109,7 +95,7 @@ export function validateHarmonyRuntime(value: unknown): HarmonyCompatibilityIssu
|
|
|
109
95
|
}
|
|
110
96
|
|
|
111
97
|
for (const field of Versions) {
|
|
112
|
-
if (
|
|
98
|
+
if (!nonEmptyString(value[field])) {
|
|
113
99
|
issues.push({ code: 'INVALID_CONTRACT', field, message: `${field} must be an explicit version.` });
|
|
114
100
|
}
|
|
115
101
|
}
|
|
@@ -119,7 +105,7 @@ export function validateHarmonyRuntime(value: unknown): HarmonyCompatibilityIssu
|
|
|
119
105
|
} else {
|
|
120
106
|
const names = new Set<string>();
|
|
121
107
|
for (const module of value.modules) {
|
|
122
|
-
if (!record(module) || !
|
|
108
|
+
if (!record(module) || !nonEmptyString(module.packageName) || !nonEmptyString(module.packageVersion)
|
|
123
109
|
|| !strings(module.modules) || !strings(module.services) || !strings(module.registrations)
|
|
124
110
|
|| !strings(module.artifacts) || module.artifacts.some(hash => !/^[a-f0-9]{64}$/.test(hash))
|
|
125
111
|
|| names.has(module.packageName)) {
|
|
@@ -131,14 +117,14 @@ export function validateHarmonyRuntime(value: unknown): HarmonyCompatibilityIssu
|
|
|
131
117
|
}
|
|
132
118
|
|
|
133
119
|
const config = value.config;
|
|
134
|
-
const target = record(config)
|
|
120
|
+
const target = record(config)
|
|
121
|
+
&& (config.targetApiVersion === undefined || apiVersion(config.targetApiVersion, value.schemaVersion));
|
|
135
122
|
const compatible = record(config) ? apiVersion(config.compatibleApiVersion, value.schemaVersion) : undefined;
|
|
136
123
|
|
|
137
|
-
if (!record(config) || !
|
|
138
|
-
|| !target || !compatible
|
|
124
|
+
if (!record(config) || !nonEmptyString(config.nativeCompiler) || !Settings.every(field => strings(config[field]))
|
|
125
|
+
|| !target || !compatible
|
|
139
126
|
|| (config.nativeLibFilterHash !== undefined && (value.schemaVersion !== 2
|
|
140
|
-
|| typeof config.nativeLibFilterHash !== 'string' || !/^[a-f0-9]{64}$/.test(config.nativeLibFilterHash)))
|
|
141
|
-
|| (Array.isArray(config.abiFilters) && config.abiFilters.length === 0)) {
|
|
127
|
+
|| typeof config.nativeLibFilterHash !== 'string' || !/^[a-f0-9]{64}$/.test(config.nativeLibFilterHash)))) {
|
|
142
128
|
issues.push({ code: 'INVALID_CONTRACT', field: 'config', message: 'Invalid native build configuration.' });
|
|
143
129
|
}
|
|
144
130
|
|
|
@@ -184,6 +170,8 @@ export function checkHarmonyCompatibility(client: unknown, requirements: unknown
|
|
|
184
170
|
}
|
|
185
171
|
|
|
186
172
|
for (const field of ['nativeCompiler', 'targetApiVersion', 'compatibleApiVersion', 'nativeLibFilterHash'] as const) {
|
|
173
|
+
// Hvigor chooses the target SDK when neither targetSdkVersion nor compileSdkVersion is explicit.
|
|
174
|
+
if (field === 'targetApiVersion' && (available.config[field] === undefined || required.config[field] === undefined)) continue;
|
|
187
175
|
if (available.config[field] !== required.config[field]) {
|
|
188
176
|
issues.push({ code: 'CONFIG_MISMATCH', field, message: `${field}: project requires ${required.config[field]}, client provides ${available.config[field]}.` });
|
|
189
177
|
}
|
|
@@ -203,8 +203,8 @@ export async function buildConfiguredModulesAsync(
|
|
|
203
203
|
|
|
204
204
|
const settings = options.moduleBuildSettings;
|
|
205
205
|
if (settings) {
|
|
206
|
-
if (!Array.isArray(settings.abiFilters)
|
|
207
|
-
|| settings.abiFilters.some(abi =>
|
|
206
|
+
if (!Array.isArray(settings.abiFilters)
|
|
207
|
+
|| settings.abiFilters.some(abi => typeof abi !== 'string' || !abi)
|
|
208
208
|
|| ![settings.compatibleSdkVersion, settings.targetSdkVersion].every(value => typeof value === 'string' && value.length > 0)) {
|
|
209
209
|
throw new HarmonyAutolinkingError('INVALID_OPTIONS', 'Invalid moduleBuildSettings; run Harmony prebuild again.', {
|
|
210
210
|
stage: 'configured-module-build',
|