@depup/react-native 0.87.0-depup.0 → 0.87.1-depup.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/Libraries/Animated/AnimatedEvent.js +1 -1
- package/Libraries/Animated/AnimatedImplementation.js +6 -2
- package/Libraries/Animated/nodes/AnimatedNode.js +1 -1
- package/Libraries/Animated/nodes/AnimatedValue.js +2 -2
- package/Libraries/Core/ReactNativeVersion.js +1 -1
- package/README.md +3 -3
- package/React/Base/RCTVersion.m +1 -1
- package/ReactAndroid/gradle.properties +1 -1
- package/ReactAndroid/src/main/java/com/facebook/react/modules/intent/IntentModule.kt +7 -3
- package/ReactAndroid/src/main/java/com/facebook/react/modules/systeminfo/ReactNativeVersion.kt +1 -1
- package/ReactCommon/cxxreact/ReactNativeVersion.h +2 -2
- package/ReactCommon/react/renderer/textlayoutmanager/platform/ios/react/renderer/textlayoutmanager/RCTFontUtils.mm +1 -1
- package/changes.json +2 -2
- package/package.json +12 -12
- package/scripts/cocoapods/rndependencies.rb +31 -25
- package/scripts/replace-rncore-version.js +18 -2
- package/scripts/setup-apple-spm.js +28 -12
- package/scripts/spm/autolinking-plugins.js +80 -0
- package/scripts/spm/download-spm-artifacts.js +64 -6
- package/scripts/spm/expand-spm-dependencies.js +249 -30
- package/scripts/spm/generate-spm-autolinking.js +157 -40
- package/scripts/spm/generate-spm-package.js +30 -18
- package/scripts/spm/generate-spm-xcodeproj.js +595 -71
- package/scripts/spm/scaffold-package-swift.js +65 -24
- package/scripts/spm/spm-pbxproj.js +158 -28
- package/scripts/spm/spm-types.js +29 -3
- package/scripts/spm/spm-utils.js +117 -2
- package/sdks/.hermesv1version +1 -1
- package/sdks/hermes-engine/version.properties +1 -1
- package/types_generated/Libraries/Animated/AnimatedImplementation.d.ts +2 -2
- package/types_generated/Libraries/Animated/nodes/AnimatedNode.d.ts +4 -1
- package/types_generated/Libraries/Animated/nodes/AnimatedValue.d.ts +3 -3
- package/scripts/spm/__doc__/rfc-spm-xcframework.md +0 -707
- package/scripts/spm/__doc__/spm-autolinking-plugins.md +0 -244
- package/scripts/spm/__doc__/spm-header-paths-contract.md +0 -97
- package/scripts/spm/__doc__/spm-plugins-assessment.md +0 -128
- package/scripts/spm/__doc__/spm-scripts.md +0 -486
|
@@ -19,6 +19,7 @@
|
|
|
19
19
|
PluginFlavoredFramework,
|
|
20
20
|
PluginPackageDep,
|
|
21
21
|
PluginProductDep,
|
|
22
|
+
PluginScriptPhase,
|
|
22
23
|
ReactDescriptor,
|
|
23
24
|
RawAutolinkingJson,
|
|
24
25
|
SpmModuleConfig,
|
|
@@ -58,17 +59,24 @@
|
|
|
58
59
|
|
|
59
60
|
const {discoverPlugins, invokePlugins} = require('./autolinking-plugins');
|
|
60
61
|
const {
|
|
62
|
+
SpmNameCollisionError,
|
|
63
|
+
assertSwiftNameNotReserved,
|
|
61
64
|
defaultReadConfig,
|
|
62
65
|
defaultResolveDep,
|
|
63
66
|
expandSpmDependencies,
|
|
67
|
+
isValidSwiftName,
|
|
64
68
|
} = require('./expand-spm-dependencies');
|
|
65
69
|
const {readPodspec} = require('./read-podspec');
|
|
66
70
|
const {
|
|
71
|
+
AUTOLINKED_PACKAGE_NAME,
|
|
72
|
+
REACT_CODEGEN_PACKAGE_NAME,
|
|
73
|
+
REACT_CODEGEN_PRODUCTS,
|
|
74
|
+
REACT_NATIVE_PACKAGE_NAME,
|
|
75
|
+
REACT_NATIVE_PRODUCTS,
|
|
67
76
|
RemoteVersionError,
|
|
68
77
|
findProjectRoot,
|
|
69
78
|
makeLogger,
|
|
70
79
|
remotePackageConfig,
|
|
71
|
-
toSwiftName,
|
|
72
80
|
} = require('./spm-utils');
|
|
73
81
|
const fs = require('fs');
|
|
74
82
|
const path = require('path');
|
|
@@ -89,7 +97,12 @@ const {log, warn} = makeLogger('generate-spm-autolinking');
|
|
|
89
97
|
let remoteCfg /*: ?{url: string, version: string, identity: string} */ = null;
|
|
90
98
|
|
|
91
99
|
function reactNativePackageLabel() /*: string */ {
|
|
92
|
-
return remoteCfg != null ? remoteCfg.identity :
|
|
100
|
+
return remoteCfg != null ? remoteCfg.identity : REACT_NATIVE_PACKAGE_NAME;
|
|
101
|
+
}
|
|
102
|
+
// In remote mode the RN package is labelled with the remote identity, so that
|
|
103
|
+
// name is reserved for this run too.
|
|
104
|
+
function reservedNamesForRun() /*: ?Array<string> */ {
|
|
105
|
+
return remoteCfg != null ? [remoteCfg.identity] : undefined;
|
|
93
106
|
}
|
|
94
107
|
function reactNativePackageDecl(localDecl /*: string */) /*: string */ {
|
|
95
108
|
return remoteCfg != null
|
|
@@ -104,10 +117,11 @@ function reactNativePackageDecl(localDecl /*: string */) /*: string */ {
|
|
|
104
117
|
function reactProducts() /*: Array<{name: string, package: string}> */ {
|
|
105
118
|
const rn = reactNativePackageLabel();
|
|
106
119
|
return [
|
|
107
|
-
{name
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
120
|
+
...REACT_NATIVE_PRODUCTS.map(name => ({name, package: rn})),
|
|
121
|
+
...REACT_CODEGEN_PRODUCTS.map(name => ({
|
|
122
|
+
name,
|
|
123
|
+
package: REACT_CODEGEN_PACKAGE_NAME,
|
|
124
|
+
})),
|
|
111
125
|
];
|
|
112
126
|
}
|
|
113
127
|
function reactProductDeps() /*: string */ {
|
|
@@ -146,7 +160,7 @@ function reactDescriptor(
|
|
|
146
160
|
};
|
|
147
161
|
} else if (absXcframeworks != null) {
|
|
148
162
|
packageRef = {
|
|
149
|
-
name:
|
|
163
|
+
name: REACT_NATIVE_PACKAGE_NAME,
|
|
150
164
|
path: toPosix(absXcframeworks),
|
|
151
165
|
relPath:
|
|
152
166
|
xcframeworksRelPath != null ? toPosix(xcframeworksRelPath) : undefined,
|
|
@@ -155,7 +169,7 @@ function reactDescriptor(
|
|
|
155
169
|
return null;
|
|
156
170
|
}
|
|
157
171
|
const products = reactProducts().filter(
|
|
158
|
-
p => p.package !==
|
|
172
|
+
p => p.package !== REACT_CODEGEN_PACKAGE_NAME || codegenPackageExists,
|
|
159
173
|
);
|
|
160
174
|
return {packageRef, products};
|
|
161
175
|
}
|
|
@@ -231,7 +245,6 @@ function readAutolinkingJson(
|
|
|
231
245
|
* name: "MyNativeModule",
|
|
232
246
|
* path: "ios/MyNativeModule", // relative to appRoot
|
|
233
247
|
* exclude: ["*.js", "*.podspec"], // optional
|
|
234
|
-
* publicHeadersPath: ".", // optional
|
|
235
248
|
* }
|
|
236
249
|
* ]
|
|
237
250
|
* }
|
|
@@ -254,6 +267,41 @@ function readSpmModulesFromConfig(
|
|
|
254
267
|
}
|
|
255
268
|
}
|
|
256
269
|
|
|
270
|
+
/**
|
|
271
|
+
* Validates one app-local `spm.modules` name against the same rules a library's
|
|
272
|
+
* `spm.name` gets: a usable Swift identifier, not a name React Native reserves,
|
|
273
|
+
* and not one already taken by another module or an autolinked dep.
|
|
274
|
+
* `taken` maps lower-cased name → the name as written.
|
|
275
|
+
*/
|
|
276
|
+
function assertSpmModuleName(
|
|
277
|
+
name /*: unknown */,
|
|
278
|
+
taken /*: Map<string, string> */,
|
|
279
|
+
) /*: void */ {
|
|
280
|
+
const remedy =
|
|
281
|
+
"Rename it in this app's react-native.config.js 'spm.modules'.";
|
|
282
|
+
if (typeof name !== 'string' || !isValidSwiftName(name)) {
|
|
283
|
+
throw new Error(
|
|
284
|
+
`react-native autolinking: invalid 'spm.modules' name ${JSON.stringify(name) ?? 'undefined'}: must start with a letter or underscore and contain only letters, digits, underscores, or hyphens.`,
|
|
285
|
+
);
|
|
286
|
+
}
|
|
287
|
+
const moduleName = name;
|
|
288
|
+
assertSwiftNameNotReserved(moduleName, {
|
|
289
|
+
label: `the 'spm.modules' entry '${moduleName}'`,
|
|
290
|
+
remedy,
|
|
291
|
+
extraReservedNames: reservedNamesForRun(),
|
|
292
|
+
});
|
|
293
|
+
const clash = taken.get(moduleName.toLowerCase());
|
|
294
|
+
if (clash != null) {
|
|
295
|
+
throw new SpmNameCollisionError(
|
|
296
|
+
`react-native autolinking: SPM Swift name collision: the 'spm.modules' entry '${moduleName}' ` +
|
|
297
|
+
(clash === moduleName
|
|
298
|
+
? `is already the name of another autolinked target.`
|
|
299
|
+
: `differs from the existing target '${clash}' only in case, which collides on case-insensitive filesystems.`) +
|
|
300
|
+
` ${remedy}`,
|
|
301
|
+
);
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
|
|
257
305
|
/**
|
|
258
306
|
* Reads the app's `spm.denyPlugins` — npm names of autolinking plugins to
|
|
259
307
|
* skip. The escape hatch for the transitive plugin discovery (an app opts a
|
|
@@ -730,9 +778,9 @@ function expandSpmSourceGlobs(
|
|
|
730
778
|
* Returns null if the dependency doesn't have iOS support.
|
|
731
779
|
*
|
|
732
780
|
* `swiftNameByNpm` maps each autolinked dep's npm name to its resolved Swift
|
|
733
|
-
* name (populated by expandSpmDependencies,
|
|
734
|
-
*
|
|
735
|
-
*
|
|
781
|
+
* name (populated by expandSpmDependencies, honoring the dep's `spm.name`
|
|
782
|
+
* config and scope disambiguation). Every name this function emits comes from
|
|
783
|
+
* there — see requireSwiftName.
|
|
736
784
|
*/
|
|
737
785
|
/**
|
|
738
786
|
* Read the dep's podspec (if any) and extract its declared
|
|
@@ -789,11 +837,27 @@ function extractPodspecHeaderSearchPaths(
|
|
|
789
837
|
return out;
|
|
790
838
|
}
|
|
791
839
|
|
|
840
|
+
/**
|
|
841
|
+
* The Swift name expandSpmDependencies resolved for `npmName`, or a hard error:
|
|
842
|
+
* re-deriving one here would emit a reference nothing in the graph matches.
|
|
843
|
+
*/
|
|
844
|
+
function requireSwiftName(
|
|
845
|
+
npmName /*: string */,
|
|
846
|
+
resolved /*: ?string */,
|
|
847
|
+
) /*: string */ {
|
|
848
|
+
if (resolved == null) {
|
|
849
|
+
throw new Error(
|
|
850
|
+
`react-native autolinking: no resolved Swift name for '${npmName}'. expandSpmDependencies must resolve every autolinked dep's name before SPM targets are generated.`,
|
|
851
|
+
);
|
|
852
|
+
}
|
|
853
|
+
return resolved;
|
|
854
|
+
}
|
|
855
|
+
|
|
792
856
|
function autolinkingDepToSpmTarget(
|
|
793
857
|
depName /*: string */,
|
|
794
858
|
dep /*: AutolinkedDep */,
|
|
795
859
|
outputDir /*: string */,
|
|
796
|
-
swiftNameByNpm /*:
|
|
860
|
+
swiftNameByNpm /*: Map<string, string> */,
|
|
797
861
|
) /*: SpmTarget | null */ {
|
|
798
862
|
const iosPlatform = dep.platforms.ios;
|
|
799
863
|
const sourceDir = iosPlatform.sourceDir ?? dep.root;
|
|
@@ -806,10 +870,7 @@ function autolinkingDepToSpmTarget(
|
|
|
806
870
|
// same convention the spmModule branch in main() follows.
|
|
807
871
|
const relSourcePath = path.relative(outputDir, sourceDir);
|
|
808
872
|
|
|
809
|
-
|
|
810
|
-
// the dep's react-native.config.js). Fall back to toSwiftName(depName) when
|
|
811
|
-
// the caller didn't run expandSpmDependencies.
|
|
812
|
-
const targetName = dep.swiftName ?? toSwiftName(depName);
|
|
873
|
+
const targetName = requireSwiftName(depName, dep.swiftName);
|
|
813
874
|
|
|
814
875
|
// No exclude inference — main()'s emission loop emits `sources:` (an
|
|
815
876
|
// explicit allowlist). User-supplied excludes still work.
|
|
@@ -819,13 +880,11 @@ function autolinkingDepToSpmTarget(
|
|
|
819
880
|
const resources = privacyManifest != null ? [privacyManifest] : undefined;
|
|
820
881
|
|
|
821
882
|
// Map declared spm.dependencies (npm names) to Swift target names so the
|
|
822
|
-
// synth's .product(...) deps list reaches the consuming target.
|
|
823
|
-
// transitive npm name's Swift name comes from the map (honoring overrides);
|
|
824
|
-
// toSwiftName fallback handles entries the map doesn't know about.
|
|
883
|
+
// synth's .product(...) deps list reaches the consuming target.
|
|
825
884
|
const spmDeps /*: Array<string> */ = dep.spmDependencies ?? [];
|
|
826
885
|
const spmTargetDependencies =
|
|
827
886
|
spmDeps.length > 0
|
|
828
|
-
? spmDeps.map(n =>
|
|
887
|
+
? spmDeps.map(n => requireSwiftName(n, swiftNameByNpm.get(n)))
|
|
829
888
|
: undefined;
|
|
830
889
|
|
|
831
890
|
const headerSearchPaths = extractPodspecHeaderSearchPaths(sourceDir);
|
|
@@ -899,12 +958,14 @@ function generateAutolinkedPackageSwift(
|
|
|
899
958
|
) {
|
|
900
959
|
packageDeps.push(
|
|
901
960
|
reactNativePackageDecl(
|
|
902
|
-
`.package(name: "
|
|
961
|
+
`.package(name: "${REACT_NATIVE_PACKAGE_NAME}", path: "${xcframeworksRelPath}")`,
|
|
903
962
|
),
|
|
904
963
|
);
|
|
905
964
|
// Per-app generated headers come from the ReactAppHeaders product in
|
|
906
965
|
// the codegen package (sibling of the autolinking dir).
|
|
907
|
-
packageDeps.push(
|
|
966
|
+
packageDeps.push(
|
|
967
|
+
`.package(name: "${REACT_CODEGEN_PACKAGE_NAME}", path: "../ios")`,
|
|
968
|
+
);
|
|
908
969
|
}
|
|
909
970
|
|
|
910
971
|
// AutolinkedAggregate's target dependencies: .product(...) for npm sub-package
|
|
@@ -1007,10 +1068,10 @@ import PackageDescription
|
|
|
1007
1068
|
import Foundation
|
|
1008
1069
|
|
|
1009
1070
|
${guardBlock}let package = Package(
|
|
1010
|
-
name: "
|
|
1071
|
+
name: "${AUTOLINKED_PACKAGE_NAME}",
|
|
1011
1072
|
platforms: [.iOS(.v15)],
|
|
1012
1073
|
products: [
|
|
1013
|
-
.library(name: "
|
|
1074
|
+
.library(name: "${AUTOLINKED_PACKAGE_NAME}", targets: ["AutolinkedAggregate"]),
|
|
1014
1075
|
],
|
|
1015
1076
|
${packageDepsBlock} targets: [
|
|
1016
1077
|
.target(
|
|
@@ -1074,13 +1135,13 @@ function generateSynthPackageSwift(spec /*: SynthPackageSpec */) /*: string */ {
|
|
|
1074
1135
|
spec.codegenPackagePath ?? '../../../ios';
|
|
1075
1136
|
packageDeps.push(
|
|
1076
1137
|
reactNativePackageDecl(
|
|
1077
|
-
`.package(name: "
|
|
1138
|
+
`.package(name: "${REACT_NATIVE_PACKAGE_NAME}", path: "${reactNativePackagePath}")`,
|
|
1078
1139
|
),
|
|
1079
1140
|
);
|
|
1080
1141
|
// Per-app generated headers come from the ReactAppHeaders product in
|
|
1081
1142
|
// the codegen package.
|
|
1082
1143
|
packageDeps.push(
|
|
1083
|
-
`.package(name: "
|
|
1144
|
+
`.package(name: "${REACT_CODEGEN_PACKAGE_NAME}", path: "${codegenPackagePath}")`,
|
|
1084
1145
|
);
|
|
1085
1146
|
}
|
|
1086
1147
|
for (const dep of spmDependencies) {
|
|
@@ -1251,11 +1312,13 @@ function main(argv /*:: ?: Array<string> */) /*: void */ {
|
|
|
1251
1312
|
const allDeps = expandSpmDependencies(directDeps, {
|
|
1252
1313
|
readConfig: defaultReadConfig,
|
|
1253
1314
|
resolveDep: defaultResolveDep,
|
|
1315
|
+
extraReservedNames: reservedNamesForRun(),
|
|
1316
|
+
log,
|
|
1254
1317
|
});
|
|
1255
1318
|
|
|
1256
|
-
// Map every autolinked npm name to its resolved Swift name
|
|
1257
|
-
//
|
|
1258
|
-
//
|
|
1319
|
+
// Map every autolinked npm name to its resolved Swift name so transitive
|
|
1320
|
+
// references inside autolinkingDepToSpmTarget find the right target
|
|
1321
|
+
// identifier.
|
|
1259
1322
|
const swiftNameByNpm /*: Map<string, string> */ = new Map();
|
|
1260
1323
|
for (const dep of allDeps) {
|
|
1261
1324
|
if (dep.swiftName != null) {
|
|
@@ -1287,8 +1350,39 @@ function main(argv /*:: ?: Array<string> */) /*: void */ {
|
|
|
1287
1350
|
discoveredPlugins.map(p => p.depName),
|
|
1288
1351
|
);
|
|
1289
1352
|
|
|
1353
|
+
// Skipped means no sibling package is created for the host either, so a
|
|
1354
|
+
// dep declaring it in `spm.dependencies` gets a package reference to a
|
|
1355
|
+
// path this run never writes — SPM then reports only the missing path.
|
|
1356
|
+
// Only manifests React Native emits can carry that reference: a dep
|
|
1357
|
+
// shipping its own Package.swift declares its package references itself,
|
|
1358
|
+
// and the classification loop below would treat it as self-managed.
|
|
1359
|
+
const pluginHostDependents /*: Map<string, Array<string>> */ = new Map();
|
|
1360
|
+
for (const dep of allDeps) {
|
|
1361
|
+
const declaredHosts = (dep.spmDependencies ?? []).filter(name =>
|
|
1362
|
+
pluginHostDeps.has(name),
|
|
1363
|
+
);
|
|
1364
|
+
if (declaredHosts.length === 0) {
|
|
1365
|
+
continue;
|
|
1366
|
+
}
|
|
1367
|
+
const sourceDir = dep.platforms.ios.sourceDir ?? dep.root;
|
|
1368
|
+
if (sourceDir == null || findSelfManagedPackageDir(sourceDir) != null) {
|
|
1369
|
+
continue;
|
|
1370
|
+
}
|
|
1371
|
+
for (const host of declaredHosts) {
|
|
1372
|
+
const dependents = pluginHostDependents.get(host) ?? [];
|
|
1373
|
+
dependents.push(dep.name);
|
|
1374
|
+
pluginHostDependents.set(host, dependents);
|
|
1375
|
+
}
|
|
1376
|
+
}
|
|
1377
|
+
|
|
1290
1378
|
for (const dep of allDeps) {
|
|
1291
1379
|
if (pluginHostDeps.has(dep.name)) {
|
|
1380
|
+
const dependents = pluginHostDependents.get(dep.name);
|
|
1381
|
+
if (dependents != null) {
|
|
1382
|
+
throw new Error(
|
|
1383
|
+
`react-native autolinking: '${dep.name}' ships an SPM autolinking plugin, which owns its native contribution — so React Native does not build it as a sibling target for anything to depend on. It is declared in 'spm.dependencies' by ${dependents.map(name => `'${name}'`).join(', ')}. Remove it there; nothing is lost. Its plugin links its products into the app and resolves its own ecosystem's dependencies, so a library that builds against it does not declare it here.`,
|
|
1384
|
+
);
|
|
1385
|
+
}
|
|
1292
1386
|
log(
|
|
1293
1387
|
`Skipping ${dep.name} target generation — provided by its SPM autolinking plugin`,
|
|
1294
1388
|
);
|
|
@@ -1321,7 +1415,15 @@ function main(argv /*:: ?: Array<string> */) /*: void */ {
|
|
|
1321
1415
|
// the globs now relative to its dir and attach the file list to the target
|
|
1322
1416
|
// so the emission loop below renders `sources: [...]` literally.
|
|
1323
1417
|
const configModules = readSpmModulesFromConfig(appRoot);
|
|
1418
|
+
// Module names land in the manifest exactly as written, so they get the same
|
|
1419
|
+
// checks a dep's Swift name gets. Seeded with the dep target names already
|
|
1420
|
+
// emitted so a module can't shadow an autolinked library either.
|
|
1421
|
+
const takenSwiftNames /*: Map<string, string> */ = new Map(
|
|
1422
|
+
entries.map(entry => [entry.target.name.toLowerCase(), entry.target.name]),
|
|
1423
|
+
);
|
|
1324
1424
|
for (const mod of configModules) {
|
|
1425
|
+
assertSpmModuleName(mod.name, takenSwiftNames);
|
|
1426
|
+
takenSwiftNames.set(mod.name.toLowerCase(), mod.name);
|
|
1325
1427
|
const absPath = path.resolve(appRoot, mod.path);
|
|
1326
1428
|
const relPath = path.relative(outputDir, absPath);
|
|
1327
1429
|
const userSources =
|
|
@@ -1333,7 +1435,9 @@ function main(argv /*:: ?: Array<string> */) /*: void */ {
|
|
|
1333
1435
|
name: mod.name,
|
|
1334
1436
|
path: relPath,
|
|
1335
1437
|
exclude: mod.exclude ?? [],
|
|
1336
|
-
|
|
1438
|
+
// The synth wrapper owns the module's public interface: it declares
|
|
1439
|
+
// publicHeadersPath: "include", a symlink to the module's header tree.
|
|
1440
|
+
publicHeadersPath: null,
|
|
1337
1441
|
sources: userSources,
|
|
1338
1442
|
},
|
|
1339
1443
|
origin: 'spmModule',
|
|
@@ -1402,8 +1506,9 @@ function main(argv /*:: ?: Array<string> */) /*: void */ {
|
|
|
1402
1506
|
// longer silently synthesize one for them (that duplicated the scaffolder and
|
|
1403
1507
|
// hid the gap from the developer and the library author) — collect them and
|
|
1404
1508
|
// fail with an actionable message after the classification pass. spmModules
|
|
1405
|
-
// (app-local,
|
|
1406
|
-
//
|
|
1509
|
+
// (app-local, explicitly declared in react-native.config.js) keep their synth
|
|
1510
|
+
// wrappers: an app-local dir has no npm identity, so there is no package for
|
|
1511
|
+
// the aggregator to reference until one is written for it.
|
|
1407
1512
|
const missingManifests /*: Array<{name: string, npmName: string, hasPodspec: boolean, mixed?: boolean}> */ =
|
|
1408
1513
|
[];
|
|
1409
1514
|
|
|
@@ -1455,11 +1560,14 @@ function main(argv /*:: ?: Array<string> */) /*: void */ {
|
|
|
1455
1560
|
}
|
|
1456
1561
|
continue;
|
|
1457
1562
|
}
|
|
1458
|
-
// spmModule: synth wrapper is the
|
|
1459
|
-
//
|
|
1460
|
-
//
|
|
1461
|
-
//
|
|
1462
|
-
//
|
|
1563
|
+
// spmModule: the synth wrapper is the mechanism, not a fallback — an
|
|
1564
|
+
// app-local dir has no npm identity, so the wrapper is the only package the
|
|
1565
|
+
// aggregator can reference. No podspec is read on this route by design:
|
|
1566
|
+
// app-local native code isn't required to carry one. (A hand-written
|
|
1567
|
+
// Package.swift still wins — the self-managed check above claims it first.)
|
|
1568
|
+
// But a mixed-language module can't be wrapped either — SPM can't compile
|
|
1569
|
+
// Swift + C-family sources in one target, and a synth wrapper would fail
|
|
1570
|
+
// with a cryptic SPM resolve error. Surface the same friendly diagnostic the
|
|
1463
1571
|
// community-dep path uses instead of letting SPM emit the cryptic one.
|
|
1464
1572
|
if (hasMixedLanguageSources(absSource)) {
|
|
1465
1573
|
throw new Error(
|
|
@@ -1686,6 +1794,7 @@ function main(argv /*:: ?: Array<string> */) /*: void */ {
|
|
|
1686
1794
|
let pluginGeneratedSources /*: Array<{path: string}> */ = [];
|
|
1687
1795
|
let pluginFlavoredFrameworks /*: Array<PluginFlavoredFramework> */ = [];
|
|
1688
1796
|
let pluginWatchPaths /*: Array<string> */ = [];
|
|
1797
|
+
let pluginScriptPhases /*: Array<PluginScriptPhase> */ = [];
|
|
1689
1798
|
if (discoveredPlugins.length > 0) {
|
|
1690
1799
|
// React-GeneratedCode is the per-app codegen package (referenced as
|
|
1691
1800
|
// `../ios` from outputDir). It may be absent (no codegen this run), so the
|
|
@@ -1714,15 +1823,17 @@ function main(argv /*:: ?: Array<string> */) /*: void */ {
|
|
|
1714
1823
|
pluginGeneratedSources = result.generatedSources;
|
|
1715
1824
|
pluginFlavoredFrameworks = result.flavoredFrameworks;
|
|
1716
1825
|
pluginWatchPaths = result.watchPaths;
|
|
1826
|
+
pluginScriptPhases = result.scriptPhases;
|
|
1717
1827
|
log(
|
|
1718
1828
|
`SPM plugins contributed ${pluginPackageDeps.length} package(s), ` +
|
|
1719
1829
|
`${pluginProductDeps.length} product(s), ` +
|
|
1720
1830
|
`${pluginGeneratedSources.length} generated source(s), ` +
|
|
1721
|
-
`${pluginFlavoredFrameworks.length} flavored framework(s)
|
|
1831
|
+
`${pluginFlavoredFrameworks.length} flavored framework(s), ` +
|
|
1832
|
+
`${pluginScriptPhases.length} script phase(s)`,
|
|
1722
1833
|
);
|
|
1723
1834
|
}
|
|
1724
1835
|
|
|
1725
|
-
// Plugin sidecars.
|
|
1836
|
+
// Plugin sidecars. All are ALWAYS written — even `[]` — so removing a
|
|
1726
1837
|
// plugin (or dropping its declaration) clears stale entries. Machine-local
|
|
1727
1838
|
// absolute paths; gitignored + regenerated every sync.
|
|
1728
1839
|
fs.mkdirSync(outputDir, {recursive: true});
|
|
@@ -1741,6 +1852,11 @@ function main(argv /*:: ?: Array<string> */) /*: void */ {
|
|
|
1741
1852
|
JSON.stringify(pluginFlavoredFrameworks, null, 2) + '\n',
|
|
1742
1853
|
'utf8',
|
|
1743
1854
|
);
|
|
1855
|
+
fs.writeFileSync(
|
|
1856
|
+
path.join(outputDir, '.spm-plugin-script-phases.json'),
|
|
1857
|
+
JSON.stringify(pluginScriptPhases, null, 2) + '\n',
|
|
1858
|
+
'utf8',
|
|
1859
|
+
);
|
|
1744
1860
|
|
|
1745
1861
|
// Top-level aggregator: references every entry as .package(path:) and
|
|
1746
1862
|
// depends on each via .product(...). No more inline targets — every
|
|
@@ -1873,6 +1989,7 @@ if (require.main === module) {
|
|
|
1873
1989
|
|
|
1874
1990
|
module.exports = {
|
|
1875
1991
|
main,
|
|
1992
|
+
autolinkingDepToSpmTarget,
|
|
1876
1993
|
generateAutolinkedPackageSwift,
|
|
1877
1994
|
generateSynthPackageSwift,
|
|
1878
1995
|
reactDescriptor,
|
|
@@ -37,6 +37,12 @@
|
|
|
37
37
|
|
|
38
38
|
const {prepareFlavoredFrameworks} = require('./flavored-frameworks');
|
|
39
39
|
const {
|
|
40
|
+
REACT_HEADERS_TARGET_DIR,
|
|
41
|
+
REACT_NATIVE_HEADERS_PRODUCT,
|
|
42
|
+
REACT_NATIVE_PACKAGE_NAME,
|
|
43
|
+
REACT_NATIVE_PRODUCTS,
|
|
44
|
+
REACT_NATIVE_UMBRELLA_PRODUCT,
|
|
45
|
+
REACT_NATIVE_XCFRAMEWORK_PRODUCTS,
|
|
40
46
|
deriveAppName,
|
|
41
47
|
displayPath,
|
|
42
48
|
findProjectRoot,
|
|
@@ -166,32 +172,38 @@ function findSourcePath(
|
|
|
166
172
|
* Package.swift also imports it as a named package dependency.
|
|
167
173
|
*/
|
|
168
174
|
function generateXCFrameworksPackageSwift() /*: string */ {
|
|
175
|
+
// Each product's target follows from its KIND, not from its position in the
|
|
176
|
+
// list: the umbrella is a Clang target over the staged headers, and every
|
|
177
|
+
// xcframework-backed product gets a binaryTarget of the same name.
|
|
178
|
+
const products = REACT_NATIVE_PRODUCTS.map(
|
|
179
|
+
product => ` .library(name: "${product}", targets: ["${product}"]),`,
|
|
180
|
+
);
|
|
181
|
+
const targets = [
|
|
182
|
+
` .target(
|
|
183
|
+
name: "${REACT_NATIVE_UMBRELLA_PRODUCT}",
|
|
184
|
+
dependencies: ["${REACT_NATIVE_HEADERS_PRODUCT}"],
|
|
185
|
+
path: "${REACT_HEADERS_TARGET_DIR}",
|
|
186
|
+
publicHeadersPath: "include"
|
|
187
|
+
),`,
|
|
188
|
+
...REACT_NATIVE_XCFRAMEWORK_PRODUCTS.map(
|
|
189
|
+
product => ` .binaryTarget(
|
|
190
|
+
name: "${product}",
|
|
191
|
+
path: "${product}.xcframework"
|
|
192
|
+
),`,
|
|
193
|
+
),
|
|
194
|
+
];
|
|
195
|
+
|
|
169
196
|
return `// swift-tools-version: 6.0
|
|
170
197
|
// AUTO-GENERATED by scripts/generate-spm-package.js – do not edit manually.
|
|
171
198
|
import PackageDescription
|
|
172
199
|
|
|
173
200
|
let package = Package(
|
|
174
|
-
name: "
|
|
201
|
+
name: "${REACT_NATIVE_PACKAGE_NAME}",
|
|
175
202
|
products: [
|
|
176
|
-
|
|
177
|
-
.library(name: "ReactNativeHeaders", targets: ["ReactNativeHeaders"]),
|
|
178
|
-
.library(name: "ReactNativeDependenciesHeaders", targets: ["ReactNativeDependenciesHeaders"]),
|
|
203
|
+
${products.join('\n')}
|
|
179
204
|
],
|
|
180
205
|
targets: [
|
|
181
|
-
|
|
182
|
-
name: "ReactHeaders",
|
|
183
|
-
dependencies: ["ReactNativeHeaders"],
|
|
184
|
-
path: "ReactHeadersTarget",
|
|
185
|
-
publicHeadersPath: "include"
|
|
186
|
-
),
|
|
187
|
-
.binaryTarget(
|
|
188
|
-
name: "ReactNativeHeaders",
|
|
189
|
-
path: "ReactNativeHeaders.xcframework"
|
|
190
|
-
),
|
|
191
|
-
.binaryTarget(
|
|
192
|
-
name: "ReactNativeDependenciesHeaders",
|
|
193
|
-
path: "ReactNativeDependenciesHeaders.xcframework"
|
|
194
|
-
),
|
|
206
|
+
${targets.join('\n')}
|
|
195
207
|
]
|
|
196
208
|
)
|
|
197
209
|
`;
|