vxrn 2.0.0-beta.117.1 → 2.0.0-beta.123.1

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.
@@ -5,6 +5,7 @@ import { pathToFileURL } from "node:url";
5
5
  import { validateNativeApp } from "@vxrn/utils/nativeAppManifest";
6
6
  import FSExtra from "fs-extra";
7
7
  import sharp from "sharp";
8
+ import { kotlinSourceId, renderKotlinSourceGlue, swiftPodManifest, writeNativeSourceDeclaration, writeSwiftPackageArtifacts } from "../utils/nativeSourceContract.mjs";
8
9
  import { swiftPackageDirectories } from "../utils/swiftPackageId.mjs";
9
10
 
10
11
  const nativeProjectPatches = module.createRequire(import.meta.url)("../../native-project-patches.cjs");
@@ -1294,18 +1295,28 @@ ${schemes.map((scheme) => ` <data android:scheme="${scheme}" />`).joi
1294
1295
  }
1295
1296
  }
1296
1297
  if (platform === "ios" && relativePath.endsWith("/Info.plist")) {
1297
- const usage = [];
1298
+ const usage = /* @__PURE__ */ new Map();
1298
1299
  if (app.imagePicker?.camera !== void 0) {
1299
- usage.push(["NSCameraUsageDescription", app.imagePicker.camera]);
1300
+ usage.set("NSCameraUsageDescription", app.imagePicker.camera);
1301
+ }
1302
+ if (app.photoLibrary !== void 0) {
1303
+ usage.set("NSPhotoLibraryAddUsageDescription", app.photoLibrary.addOnly);
1304
+ }
1305
+ if (app.contacts !== void 0) {
1306
+ usage.set("NSContactsUsageDescription", app.contacts.usage);
1300
1307
  }
1301
1308
  if (app.location !== void 0) {
1302
- usage.push(["NSLocationWhenInUseUsageDescription", app.location.whenInUse]);
1309
+ usage.set("NSLocationWhenInUseUsageDescription", app.location.whenInUse);
1303
1310
  }
1304
1311
  if (app.ios?.faceIdUsageDescription !== void 0) {
1305
- usage.push(["NSFaceIDUsageDescription", app.ios.faceIdUsageDescription]);
1312
+ usage.set("NSFaceIDUsageDescription", app.ios.faceIdUsageDescription);
1306
1313
  }
1307
1314
  if (app.speech !== void 0) {
1308
- usage.push(["NSSpeechRecognitionUsageDescription", app.speech.recognition], ["NSMicrophoneUsageDescription", app.speech.microphone]);
1315
+ usage.set("NSSpeechRecognitionUsageDescription", app.speech.recognition);
1316
+ usage.set("NSMicrophoneUsageDescription", app.speech.microphone);
1317
+ }
1318
+ if (app.audio !== void 0) {
1319
+ usage.set("NSMicrophoneUsageDescription", app.audio.microphone);
1309
1320
  }
1310
1321
  const additions = [];
1311
1322
  for (const [key, text] of usage) {
@@ -1473,7 +1484,42 @@ const generateForPlatform = async (root, platform, app, outDir = path.resolve(ro
1473
1484
  root,
1474
1485
  dest
1475
1486
  });
1487
+ if (platform === "android") generateKotlinSources({
1488
+ root,
1489
+ dest
1490
+ });
1476
1491
  };
1492
+ function generateKotlinSources({ root, dest }) {
1493
+ const skip = /* @__PURE__ */ new Set([
1494
+ "node_modules",
1495
+ "ios",
1496
+ "android",
1497
+ "dist",
1498
+ "types",
1499
+ "build",
1500
+ "tests",
1501
+ "__tests__",
1502
+ "scripts"
1503
+ ]);
1504
+ const collect = (dir) => {
1505
+ for (const entry of FSExtra.readdirSync(dir, { withFileTypes: true })) {
1506
+ if (entry.name.startsWith(".") || skip.has(entry.name)) continue;
1507
+ const source = path.join(dir, entry.name);
1508
+ if (entry.isDirectory()) collect(source);
1509
+ else if (entry.isFile() && entry.name.endsWith(".kt")) {
1510
+ const id = kotlinSourceId(root, source);
1511
+ const target = path.join(dest, "app/src/main/java/one/source", id);
1512
+ FSExtra.mkdirSync(target, { recursive: true });
1513
+ FSExtra.copyFileSync(source, path.join(target, entry.name));
1514
+ const contract = writeNativeSourceDeclaration(source);
1515
+ if (contract.modules.length > 0) {
1516
+ FSExtra.writeFileSync(path.join(target, `OneNativeSource_${id}.kt`), renderKotlinSourceGlue(id, contract).source);
1517
+ }
1518
+ }
1519
+ }
1520
+ };
1521
+ collect(root);
1522
+ }
1477
1523
  function generateSwiftPackages({ root, dest }) {
1478
1524
  const skip = /* @__PURE__ */ new Set([
1479
1525
  "node_modules",
@@ -1485,6 +1531,7 @@ function generateSwiftPackages({ root, dest }) {
1485
1531
  ]);
1486
1532
  for (const [id, packageDir] of swiftPackageDirectories(root)) {
1487
1533
  const podDir = path.join(dest, "OneSwiftPackages", id);
1534
+ const manifest = swiftPodManifest(path.join(packageDir, "Package.swift"), FSExtra.readFileSync(path.join(packageDir, "Package.swift"), "utf8"));
1488
1535
  const sources = [];
1489
1536
  const collect = (dir) => {
1490
1537
  for (const entry of FSExtra.readdirSync(dir, { withFileTypes: true })) {
@@ -1495,11 +1542,20 @@ function generateSwiftPackages({ root, dest }) {
1495
1542
  }
1496
1543
  };
1497
1544
  collect(packageDir);
1545
+ const artifacts = writeSwiftPackageArtifacts(packageDir);
1546
+ const contracts = artifacts.contracts;
1547
+ const hasView = contracts.some((contract) => contract.defaultView);
1548
+ if (contracts.filter((contract) => contract.defaultView).length > 1) {
1549
+ throw new Error(`[vxrn] swift package ${packageDir} has more than one @main type`);
1550
+ }
1498
1551
  for (const source of sources) {
1499
1552
  const link = path.join(podDir, "Sources", path.relative(packageDir, source));
1500
1553
  FSExtra.mkdirSync(path.dirname(link), { recursive: true });
1501
1554
  FSExtra.symlinkSync(FSExtra.realpathSync(source), link);
1502
1555
  }
1556
+ if (contracts.some((contract) => contract.modules.length > 0)) {
1557
+ FSExtra.writeFileSync(path.join(podDir, "Sources", "OneNativeSource.generated.swift"), artifacts.glue);
1558
+ }
1503
1559
  FSExtra.writeFileSync(path.join(podDir, `${id}.podspec`), `Pod::Spec.new do |s|
1504
1560
  s.name = '${id}'
1505
1561
  s.version = '0.0.0'
@@ -1508,15 +1564,15 @@ function generateSwiftPackages({ root, dest }) {
1508
1564
  s.license = 'MIT'
1509
1565
  s.author = 'one'
1510
1566
  s.source = { :path => '.' }
1511
- s.swift_version = '6.0'
1567
+ s.swift_version = '${manifest.languageMode}.0'
1512
1568
  s.source_files = 'Sources/**/*.swift', 'Register.m'
1513
1569
  s.dependency 'One'
1514
1570
  s.pod_target_xcconfig = {
1515
- 'OTHER_SWIFT_FLAGS' => '$(inherited) -cxx-interoperability-mode=default -Xcc -std=c++20 -Xfrontend -import-module -Xfrontend One -Xfrontend -entry-point-function-name -Xfrontend ${id}_main',
1571
+ 'OTHER_SWIFT_FLAGS' => '$(inherited) -cxx-interoperability-mode=default -Xcc -std=c++20 -Xfrontend -import-module -Xfrontend One${manifest.mainActorIsolation ? " -default-isolation MainActor" : ""}${hasView ? ` -Xfrontend -entry-point-function-name -Xfrontend ${id}_main` : ""}',
1516
1572
  }
1517
1573
  end
1518
1574
  `);
1519
- FSExtra.writeFileSync(path.join(podDir, "Register.m"), `#import <Foundation/Foundation.h>
1575
+ FSExtra.writeFileSync(path.join(podDir, "Register.m"), hasView ? `#import <Foundation/Foundation.h>
1520
1576
 
1521
1577
  extern int ${id}_main(int argc, char **argv);
1522
1578
  extern void OneSwiftRegisterPackage(const char *name, int (*entry)(int, char **));
@@ -1529,7 +1585,7 @@ extern void OneSwiftRegisterPackage(const char *name, int (*entry)(int, char **)
1529
1585
  OneSwiftRegisterPackage("${id}", ${id}_main);
1530
1586
  }
1531
1587
  @end
1532
- `);
1588
+ ` : "#import <Foundation/Foundation.h>\n");
1533
1589
  }
1534
1590
  }
1535
1591
  function applyAndroidDependencyPatches(args) {