@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.
@@ -22,7 +22,7 @@ export interface HarmonyRuntimeContract {
22
22
  modules: HarmonyNativeModule[];
23
23
  config: {
24
24
  nativeCompiler: string;
25
- targetApiVersion: number | string;
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 token(value) {
23
- return typeof value === 'string' && /^[A-Za-z0-9@][A-Za-z0-9@._+:()/-]{0,199}$/.test(value)
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(token) && new Set(value).size === value.length;
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
- if (typeof value === 'number' && Number.isSafeInteger(value) && value >= 13 && value < 26)
33
- return [value, 0, 0];
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 (field === 'runtimeVersion' ? typeof value[field] !== 'string' || !value[field] : !token(value[field])) {
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) || !token(module.packageName) || !token(module.packageVersion)
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) ? apiVersion(config.targetApiVersion, value.schemaVersion) : undefined;
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) || !token(config.nativeCompiler) || !Settings.every(field => strings(config[field]))
95
- || !target || !compatible || compareApiVersions(compatible, target) > 0
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) || settings.abiFilters.length === 0
192
- || settings.abiFilters.some(abi => !['arm64-v8a', 'x86_64'].includes(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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@expo-harmony/expo-modules-autolinking",
3
- "version": "55.0.27-harmony.2",
3
+ "version": "55.0.27-harmony.3",
4
4
  "description": "HarmonyOS port of expo-modules-autolinking",
5
5
  "keywords": [
6
6
  "react-native",
package/runtime.ts CHANGED
@@ -23,7 +23,7 @@ export interface HarmonyRuntimeContract {
23
23
  modules: HarmonyNativeModule[];
24
24
  config: {
25
25
  nativeCompiler: string;
26
- targetApiVersion: number | string;
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 token(value: unknown): value is string {
57
- return typeof value === 'string' && /^[A-Za-z0-9@][A-Za-z0-9@._+:()/-]{0,199}$/.test(value)
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(token) && new Set(value).size === value.length;
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): number[] | undefined {
69
- if (typeof value === 'number' && Number.isSafeInteger(value) && value >= 13 && value < 26) return [value, 0, 0];
70
- 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)) {
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 (field === 'runtimeVersion' ? typeof value[field] !== 'string' || !value[field] : !token(value[field])) {
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) || !token(module.packageName) || !token(module.packageVersion)
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) ? apiVersion(config.targetApiVersion, value.schemaVersion) : undefined;
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) || !token(config.nativeCompiler) || !Settings.every(field => strings(config[field]))
138
- || !target || !compatible || compareApiVersions(compatible, target) > 0
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) || settings.abiFilters.length === 0
207
- || settings.abiFilters.some(abi => !['arm64-v8a', 'x86_64'].includes(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',