rork-xcode 0.4.0 → 0.5.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/dist/index.js CHANGED
@@ -808,20 +808,26 @@ function buildPbxproj(root) {
808
808
  */
809
809
  const Isa = {
810
810
  aggregateTarget: "PBXAggregateTarget",
811
+ appleScriptBuildPhase: "PBXAppleScriptBuildPhase",
811
812
  buildFile: "PBXBuildFile",
812
813
  buildRule: "PBXBuildRule",
814
+ buildStyle: "PBXBuildStyle",
813
815
  containerItemProxy: "PBXContainerItemProxy",
814
816
  copyFilesBuildPhase: "PBXCopyFilesBuildPhase",
815
817
  fileReference: "PBXFileReference",
816
818
  fileSystemSynchronizedBuildFileExceptionSet: "PBXFileSystemSynchronizedBuildFileExceptionSet",
819
+ fileSystemSynchronizedGroupBuildPhaseMembershipExceptionSet: "PBXFileSystemSynchronizedGroupBuildPhaseMembershipExceptionSet",
817
820
  fileSystemSynchronizedRootGroup: "PBXFileSystemSynchronizedRootGroup",
818
821
  frameworksBuildPhase: "PBXFrameworksBuildPhase",
819
822
  group: "PBXGroup",
823
+ headersBuildPhase: "PBXHeadersBuildPhase",
820
824
  legacyTarget: "PBXLegacyTarget",
821
825
  nativeTarget: "PBXNativeTarget",
822
826
  project: "PBXProject",
823
827
  referenceProxy: "PBXReferenceProxy",
824
828
  resourcesBuildPhase: "PBXResourcesBuildPhase",
829
+ rezBuildPhase: "PBXRezBuildPhase",
830
+ shellScriptBuildPhase: "PBXShellScriptBuildPhase",
825
831
  sourcesBuildPhase: "PBXSourcesBuildPhase",
826
832
  targetDependency: "PBXTargetDependency",
827
833
  variantGroup: "PBXVariantGroup",
@@ -1025,6 +1031,14 @@ function stringItems(value) {
1025
1031
  * itself always reads through the narrowing accessors.
1026
1032
  */
1027
1033
  var XcodeObject = class {
1034
+ /**
1035
+ * The `isa` name this view class models. Each concrete view declares
1036
+ * its own, and the project's view factory dispatches on it, so the
1037
+ * class itself is the source of truth for which objects it covers.
1038
+ * Classes that only share behavior, like this base class and the
1039
+ * abstract target and phase bases, declare `null` and never route.
1040
+ */
1041
+ static isa = null;
1028
1042
  /** The project this object belongs to. */
1029
1043
  project;
1030
1044
  /** The object's 24-character identifier (its key in `objects`). */
@@ -1135,11 +1149,11 @@ var XcodeObject = class {
1135
1149
  */
1136
1150
  /**
1137
1151
  * A `PBXGroup` is a folder in Xcode's navigator, holding references to
1138
- * files and other groups. Variant groups (`PBXVariantGroup`) share this
1139
- * view. The type parameter lets subclasses carry a more specific property
1140
- * shape.
1152
+ * files and other groups. The type parameter lets subclasses carry a more
1153
+ * specific property shape.
1141
1154
  */
1142
1155
  var Group = class Group extends XcodeObject {
1156
+ static isa = Isa.group;
1143
1157
  /**
1144
1158
  * Ids of the group's children, in navigator order. Non-string entries of
1145
1159
  * a malformed document are skipped.
@@ -1211,8 +1225,18 @@ var Group = class Group extends XcodeObject {
1211
1225
  }
1212
1226
  };
1213
1227
  /**
1228
+ * A `PBXVariantGroup` holds the localized variants of one file, one child
1229
+ * per language. Everything else behaves like a plain group.
1230
+ */
1231
+ var VariantGroup = class extends Group {
1232
+ static isa = Isa.variantGroup;
1233
+ };
1234
+ /**
1214
1235
  * A build phase is an ordered list of build files processed by one step
1215
- * of a target's build. Every `PBX*BuildPhase` kind shares this view.
1236
+ * of a target's build. Every `PBX*BuildPhase` kind extends this view, and
1237
+ * kinds without a class of their own still map here through the factory's
1238
+ * suffix fallback. The type parameter lets subclasses carry a more
1239
+ * specific property shape.
1216
1240
  */
1217
1241
  var BuildPhase = class extends XcodeObject {
1218
1242
  /**
@@ -1268,7 +1292,7 @@ var BuildPhase = class extends XcodeObject {
1268
1292
  const referenceKey = options.referenceKey ?? "fileRef";
1269
1293
  for (const buildFileId of this.buildFileIds) {
1270
1294
  const existing = this.project.get(buildFileId);
1271
- if (existing?.getString(referenceKey) === reference.id) return existing;
1295
+ if (BuildFile.is(existing) && existing.getString(referenceKey) === reference.id) return existing;
1272
1296
  }
1273
1297
  const buildFile = this.project.add(Isa.buildFile, {
1274
1298
  [referenceKey]: reference.id,
@@ -1279,10 +1303,110 @@ var BuildPhase = class extends XcodeObject {
1279
1303
  }
1280
1304
  };
1281
1305
  /**
1306
+ * A `PBXSourcesBuildPhase` compiles the target's source files.
1307
+ */
1308
+ var SourcesBuildPhase = class extends BuildPhase {
1309
+ static isa = Isa.sourcesBuildPhase;
1310
+ };
1311
+ /**
1312
+ * A `PBXFrameworksBuildPhase` links the target against frameworks,
1313
+ * libraries, and Swift package products.
1314
+ */
1315
+ var FrameworksBuildPhase = class extends BuildPhase {
1316
+ static isa = Isa.frameworksBuildPhase;
1317
+ };
1318
+ /**
1319
+ * A `PBXResourcesBuildPhase` copies the target's resources into the
1320
+ * built product.
1321
+ */
1322
+ var ResourcesBuildPhase = class extends BuildPhase {
1323
+ static isa = Isa.resourcesBuildPhase;
1324
+ };
1325
+ /**
1326
+ * A `PBXHeadersBuildPhase` installs a framework target's headers with
1327
+ * their public, private, or project visibility.
1328
+ */
1329
+ var HeadersBuildPhase = class extends BuildPhase {
1330
+ static isa = Isa.headersBuildPhase;
1331
+ };
1332
+ /**
1333
+ * A `PBXCopyFilesBuildPhase` copies its build files to a destination
1334
+ * inside the built product, which is how extensions and watch apps embed.
1335
+ */
1336
+ var CopyFilesBuildPhase = class extends BuildPhase {
1337
+ static isa = Isa.copyFilesBuildPhase;
1338
+ /**
1339
+ * The destination path inside the folder `dstSubfolderSpec` selects,
1340
+ * when present.
1341
+ */
1342
+ get dstPath() {
1343
+ return this.getString("dstPath");
1344
+ }
1345
+ };
1346
+ /**
1347
+ * A `PBXShellScriptBuildPhase` runs a script during the build.
1348
+ */
1349
+ var ShellScriptBuildPhase = class extends BuildPhase {
1350
+ static isa = Isa.shellScriptBuildPhase;
1351
+ /**
1352
+ * The script's source text, when present.
1353
+ */
1354
+ get shellScript() {
1355
+ return this.getString("shellScript");
1356
+ }
1357
+ /**
1358
+ * The interpreter the script runs under, when present. Xcode's default
1359
+ * is `/bin/sh`.
1360
+ */
1361
+ get shellPath() {
1362
+ return this.getString("shellPath");
1363
+ }
1364
+ };
1365
+ /**
1366
+ * A `PBXRezBuildPhase` runs Rez, the classic Mac OS resource compiler,
1367
+ * over `.r` files. Xcode's UI called it "Build Carbon Resources".
1368
+ * Current Xcode no longer creates these phases, but old documents still
1369
+ * carry them.
1370
+ */
1371
+ var RezBuildPhase = class extends BuildPhase {
1372
+ static isa = Isa.rezBuildPhase;
1373
+ };
1374
+ /**
1375
+ * A `PBXAppleScriptBuildPhase` compiles AppleScript sources. Current
1376
+ * Xcode no longer creates these, but old documents still carry them.
1377
+ */
1378
+ var AppleScriptBuildPhase = class extends BuildPhase {
1379
+ static isa = Isa.appleScriptBuildPhase;
1380
+ };
1381
+ /**
1382
+ * A `PBXBuildFile` places one file reference or package product inside
1383
+ * one build phase, optionally with per-file settings.
1384
+ */
1385
+ var BuildFile = class extends XcodeObject {
1386
+ static isa = Isa.buildFile;
1387
+ /**
1388
+ * The view of the file reference the build file points at, when it
1389
+ * points at one. Build files for Swift package products carry a
1390
+ * `productRef` instead; see {@link productDependency}.
1391
+ */
1392
+ fileReference() {
1393
+ return this.project.get(this.getString("fileRef"));
1394
+ }
1395
+ /**
1396
+ * The view of the Swift package product dependency the build file
1397
+ * points at, when it points at one.
1398
+ */
1399
+ productDependency() {
1400
+ const view = this.project.get(this.getString("productRef"));
1401
+ return SwiftPackageProductDependency.is(view) ? view : void 0;
1402
+ }
1403
+ };
1404
+ /**
1282
1405
  * A `PBXFileSystemSynchronizedRootGroup` is an Xcode 16 folder whose
1283
1406
  * members are synchronized from disk instead of listed individually.
1284
1407
  */
1285
1408
  var SyncRootGroup = class extends XcodeObject {
1409
+ static isa = Isa.fileSystemSynchronizedRootGroup;
1286
1410
  /**
1287
1411
  * The group's on-disk folder path, when present.
1288
1412
  */
@@ -1310,7 +1434,7 @@ var SyncRootGroup = class extends XcodeObject {
1310
1434
  addMembershipExceptions(target, membershipExceptions) {
1311
1435
  for (const id of stringItems(this.properties["exceptions"])) {
1312
1436
  const existing = this.project.get(id);
1313
- if (existing?.isa === Isa.fileSystemSynchronizedBuildFileExceptionSet && existing.getString("target") === target.id) {
1437
+ if (BuildFileExceptionSet.is(existing) && existing.getString("target") === target.id) {
1314
1438
  const names = ensureArray(existing.properties, "membershipExceptions");
1315
1439
  for (const name of membershipExceptions) if (!names.includes(name)) names.push(name);
1316
1440
  return existing;
@@ -1325,10 +1449,55 @@ var SyncRootGroup = class extends XcodeObject {
1325
1449
  }
1326
1450
  };
1327
1451
  /**
1452
+ * Behavior shared by the synchronized-folder exception set kinds, which
1453
+ * carve files out of a folder's automatic membership for one target. The
1454
+ * type parameter lets subclasses carry a more specific property shape.
1455
+ */
1456
+ var ExceptionSet = class extends XcodeObject {
1457
+ /**
1458
+ * The file names the set excludes, in declaration order. Non-string
1459
+ * entries of a malformed document are skipped.
1460
+ */
1461
+ get membershipExceptions() {
1462
+ return stringItems(this.properties["membershipExceptions"]);
1463
+ }
1464
+ /**
1465
+ * The view of the target whose membership the set restricts, when the
1466
+ * reference resolves.
1467
+ */
1468
+ target() {
1469
+ return this.project.get(this.getString("target"));
1470
+ }
1471
+ };
1472
+ /**
1473
+ * A `PBXFileSystemSynchronizedBuildFileExceptionSet` excludes files from
1474
+ * a synchronized folder's automatic target membership.
1475
+ */
1476
+ var BuildFileExceptionSet = class extends ExceptionSet {
1477
+ static isa = Isa.fileSystemSynchronizedBuildFileExceptionSet;
1478
+ };
1479
+ /**
1480
+ * A `PBXFileSystemSynchronizedGroupBuildPhaseMembershipExceptionSet`
1481
+ * assigns some of a synchronized folder's files to a different build
1482
+ * phase than the automatic one.
1483
+ */
1484
+ var BuildPhaseMembershipExceptionSet = class extends ExceptionSet {
1485
+ static isa = Isa.fileSystemSynchronizedGroupBuildPhaseMembershipExceptionSet;
1486
+ /**
1487
+ * The view of the build phase the listed files belong to, when the
1488
+ * reference resolves.
1489
+ */
1490
+ buildPhase() {
1491
+ const view = this.project.get(this.getString("buildPhase"));
1492
+ return BuildPhase.is(view) ? view : void 0;
1493
+ }
1494
+ };
1495
+ /**
1328
1496
  * A `PBXBuildRule` tells a target which compiler or script processes a
1329
1497
  * kind of file.
1330
1498
  */
1331
1499
  var BuildRule = class extends XcodeObject {
1500
+ static isa = Isa.buildRule;
1332
1501
  /**
1333
1502
  * The rule's script, when it is a script rule rather than a reference
1334
1503
  * to a compiler specification.
@@ -1343,6 +1512,7 @@ var BuildRule = class extends XcodeObject {
1343
1512
  * `currentVersion` names the active one.
1344
1513
  */
1345
1514
  var VersionGroup = class extends Group {
1515
+ static isa = Isa.versionGroup;
1346
1516
  /**
1347
1517
  * The view of the active model version's file reference, when the group
1348
1518
  * names one.
@@ -1365,6 +1535,7 @@ var VersionGroup = class extends Group {
1365
1535
  * target or of the project, for example Debug or Release.
1366
1536
  */
1367
1537
  var BuildConfiguration = class extends XcodeObject {
1538
+ static isa = Isa.buildConfiguration;
1368
1539
  /**
1369
1540
  * The configuration's name, when present.
1370
1541
  */
@@ -1382,10 +1553,33 @@ var BuildConfiguration = class extends XcodeObject {
1382
1553
  }
1383
1554
  };
1384
1555
  /**
1556
+ * A `PBXBuildStyle` is the pre-Xcode-2 predecessor of
1557
+ * `XCBuildConfiguration`. Current Xcode neither creates nor reads them,
1558
+ * but old documents still carry them.
1559
+ */
1560
+ var BuildStyle = class extends XcodeObject {
1561
+ static isa = Isa.buildStyle;
1562
+ /**
1563
+ * The style's name, when present.
1564
+ */
1565
+ get name() {
1566
+ return this.getString("name");
1567
+ }
1568
+ /**
1569
+ * The style's settings dictionary, or `undefined` when the style
1570
+ * carries none. The dictionary is live. Writes through it land in the
1571
+ * document.
1572
+ */
1573
+ get buildSettings() {
1574
+ return asDictionary(this.properties["buildSettings"]);
1575
+ }
1576
+ };
1577
+ /**
1385
1578
  * A `PBXFileReference` names one file on disk, from source files to the
1386
1579
  * built products themselves.
1387
1580
  */
1388
1581
  var FileReference = class extends XcodeObject {
1582
+ static isa = Isa.fileReference;
1389
1583
  /**
1390
1584
  * The reference's path, relative to its `sourceTree`, when present.
1391
1585
  */
@@ -1405,6 +1599,7 @@ var FileReference = class extends XcodeObject {
1405
1599
  * target dependency and the target it points at.
1406
1600
  */
1407
1601
  var ContainerItemProxy = class extends XcodeObject {
1602
+ static isa = Isa.containerItemProxy;
1408
1603
  /**
1409
1604
  * The display name of the object the proxy points at, when present.
1410
1605
  * For target dependencies this is the target's name.
@@ -1414,10 +1609,111 @@ var ContainerItemProxy = class extends XcodeObject {
1414
1609
  }
1415
1610
  };
1416
1611
  /**
1612
+ * A `PBXTargetDependency` records that one target must build before
1613
+ * another, through a container item proxy naming the prerequisite.
1614
+ */
1615
+ var TargetDependency = class extends XcodeObject {
1616
+ static isa = Isa.targetDependency;
1617
+ /**
1618
+ * The view of the target this dependency points at, when the reference
1619
+ * resolves to one inside this document.
1620
+ */
1621
+ target() {
1622
+ return this.project.get(this.getString("target"));
1623
+ }
1624
+ /**
1625
+ * The view of the dependency's container item proxy, when the reference
1626
+ * resolves.
1627
+ */
1628
+ targetProxy() {
1629
+ const view = this.project.get(this.getString("targetProxy"));
1630
+ return ContainerItemProxy.is(view) ? view : void 0;
1631
+ }
1632
+ };
1633
+ /**
1634
+ * An `XCConfigurationList` owns the named build configurations of one
1635
+ * target or of the project, plus the default configuration choice.
1636
+ */
1637
+ var ConfigurationList = class extends XcodeObject {
1638
+ static isa = Isa.configurationList;
1639
+ /**
1640
+ * The name of the configuration builds use when none is specified, when
1641
+ * present.
1642
+ */
1643
+ get defaultConfigurationName() {
1644
+ return this.getString("defaultConfigurationName");
1645
+ }
1646
+ /**
1647
+ * The views of the list's build configurations, in list order. Dangling
1648
+ * ids and objects of other kinds are skipped.
1649
+ */
1650
+ configurations() {
1651
+ const configurations = [];
1652
+ for (const id of stringItems(this.properties["buildConfigurations"])) {
1653
+ const view = this.project.get(id);
1654
+ if (BuildConfiguration.is(view)) configurations.push(view);
1655
+ }
1656
+ return configurations;
1657
+ }
1658
+ };
1659
+ /**
1660
+ * Behavior shared by the Swift package reference kinds. The type
1661
+ * parameter lets subclasses carry a more specific property shape.
1662
+ */
1663
+ var SwiftPackageReference = class extends XcodeObject {};
1664
+ /**
1665
+ * An `XCRemoteSwiftPackageReference` names a package repository and a
1666
+ * version requirement.
1667
+ */
1668
+ var RemoteSwiftPackageReference = class extends SwiftPackageReference {
1669
+ static isa = Isa.remoteSwiftPackageReference;
1670
+ /**
1671
+ * The package's repository URL, when present.
1672
+ */
1673
+ get repositoryURL() {
1674
+ return this.getString("repositoryURL");
1675
+ }
1676
+ };
1677
+ /**
1678
+ * An `XCLocalSwiftPackageReference` names a package directory relative
1679
+ * to the project.
1680
+ */
1681
+ var LocalSwiftPackageReference = class extends SwiftPackageReference {
1682
+ static isa = Isa.localSwiftPackageReference;
1683
+ /**
1684
+ * The package's path relative to the project, when present.
1685
+ */
1686
+ get relativePath() {
1687
+ return this.getString("relativePath");
1688
+ }
1689
+ };
1690
+ /**
1691
+ * An `XCSwiftPackageProductDependency` links one product of a Swift
1692
+ * package to the target that consumes it.
1693
+ */
1694
+ var SwiftPackageProductDependency = class extends XcodeObject {
1695
+ static isa = Isa.swiftPackageProductDependency;
1696
+ /**
1697
+ * The product's name as the package manifest declares it, when present.
1698
+ */
1699
+ get productName() {
1700
+ return this.getString("productName");
1701
+ }
1702
+ /**
1703
+ * The view of the package reference the product comes from, when the
1704
+ * reference resolves. Products of local packages can omit it.
1705
+ */
1706
+ packageReference() {
1707
+ const view = this.project.get(this.getString("package"));
1708
+ return SwiftPackageReference.is(view) ? view : void 0;
1709
+ }
1710
+ };
1711
+ /**
1417
1712
  * A `PBXReferenceProxy` stands in for a product built by a target of
1418
1713
  * another project referenced from this one.
1419
1714
  */
1420
1715
  var ReferenceProxy = class extends XcodeObject {
1716
+ static isa = Isa.referenceProxy;
1421
1717
  /**
1422
1718
  * The proxy's product path inside the other project's build directory,
1423
1719
  * when present.
@@ -1430,8 +1726,8 @@ var ReferenceProxy = class extends XcodeObject {
1430
1726
  * when the reference resolves.
1431
1727
  */
1432
1728
  remoteReference() {
1433
- const id = this.getString("remoteRef");
1434
- return id == null ? void 0 : this.project.get(id);
1729
+ const view = this.project.get(this.getString("remoteRef"));
1730
+ return ContainerItemProxy.is(view) ? view : void 0;
1435
1731
  }
1436
1732
  };
1437
1733
  //#endregion
@@ -2408,6 +2704,7 @@ const LIST_REFERENCE_PROPERTIES = [
2408
2704
  "buildConfigurations",
2409
2705
  "buildPhases",
2410
2706
  "buildRules",
2707
+ "buildStyles",
2411
2708
  "children",
2412
2709
  "dependencies",
2413
2710
  "exceptions",
@@ -2534,7 +2831,7 @@ function pruneOrphanObjects(project) {
2534
2831
  */
2535
2832
  /**
2536
2833
  * The views of a configuration list's build configurations, in list order.
2537
- * Dangling ids and non-dictionary entries of malformed documents are
2834
+ * Dangling ids and objects of other kinds in malformed documents are
2538
2835
  * skipped.
2539
2836
  */
2540
2837
  function configurationsOf(project, configurationListId) {
@@ -2542,7 +2839,7 @@ function configurationsOf(project, configurationListId) {
2542
2839
  const configurations = [];
2543
2840
  for (const id of stringItems(list?.["buildConfigurations"])) {
2544
2841
  const configuration = project.get(id);
2545
- if (configuration != null) configurations.push(configuration);
2842
+ if (BuildConfiguration.is(configuration)) configurations.push(configuration);
2546
2843
  }
2547
2844
  return configurations;
2548
2845
  }
@@ -2588,16 +2885,24 @@ var Target = class extends XcodeObject {
2588
2885
  return this.getString("name");
2589
2886
  }
2590
2887
  /**
2888
+ * The view of the target's configuration list, when the reference
2889
+ * resolves.
2890
+ */
2891
+ configurationList() {
2892
+ const view = this.project.get(this.getString("buildConfigurationList"));
2893
+ return ConfigurationList.is(view) ? view : void 0;
2894
+ }
2895
+ /**
2591
2896
  * The views of the target's build configurations, in list order.
2592
2897
  */
2593
2898
  buildConfigurations() {
2594
2899
  return configurationsOf(this.project, this.getString("buildConfigurationList"));
2595
2900
  }
2596
2901
  /**
2597
- * The settings dictionary of the target's default configuration: the one
2598
- * named by the list's `defaultConfigurationName`, falling back to the
2599
- * first configuration. Returns `undefined` when the target has no
2600
- * configurations or the default carries no settings dictionary.
2902
+ * The settings dictionary of the target's default configuration, which
2903
+ * is the one named by the list's `defaultConfigurationName`, falling
2904
+ * back to the first configuration. Returns `undefined` when the target
2905
+ * has no configurations or the default carries no settings dictionary.
2601
2906
  */
2602
2907
  defaultConfigurationSettings() {
2603
2908
  return defaultConfigurationSettingsOf(this.project, this.getString("buildConfigurationList"));
@@ -2623,8 +2928,8 @@ var Target = class extends XcodeObject {
2623
2928
  */
2624
2929
  setBuildSetting(key, value) {
2625
2930
  for (const configuration of this.buildConfigurations()) {
2626
- const settings = asDictionary(configuration.properties["buildSettings"]);
2627
- if (settings == null) configuration.properties["buildSettings"] = { [key]: value };
2931
+ const settings = configuration.buildSettings;
2932
+ if (settings == null) configuration.properties.buildSettings = { [key]: value };
2628
2933
  else settings[key] = value;
2629
2934
  }
2630
2935
  }
@@ -2633,17 +2938,16 @@ var Target = class extends XcodeObject {
2633
2938
  */
2634
2939
  removeBuildSetting(key) {
2635
2940
  for (const configuration of this.buildConfigurations()) {
2636
- const settings = asDictionary(configuration.properties["buildSettings"]);
2941
+ const settings = configuration.buildSettings;
2637
2942
  if (settings != null) delete settings[key];
2638
2943
  }
2639
2944
  }
2640
2945
  /**
2641
- * The views of the target's dependency objects
2642
- * (`PBXTargetDependency`), in declaration order. Resolve a dependency's
2643
- * target through its `target` property.
2946
+ * The views of the target's dependencies, in declaration order. Resolve
2947
+ * a dependency's target through {@link TargetDependency.target}.
2644
2948
  */
2645
2949
  dependencies() {
2646
- return this.referencedViews("dependencies");
2950
+ return this.referencedViews("dependencies").filter((view) => TargetDependency.is(view));
2647
2951
  }
2648
2952
  /**
2649
2953
  * The views of the target's build phases, in build order.
@@ -2694,7 +2998,7 @@ var Target = class extends XcodeObject {
2694
2998
  * @param properties Phase properties, most usefully `shellScript`.
2695
2999
  */
2696
3000
  ensureShellScriptPhase(name, properties = {}) {
2697
- return this.ensureBuildPhase("PBXShellScriptBuildPhase", {
3001
+ return this.ensureBuildPhase(Isa.shellScriptBuildPhase, {
2698
3002
  inputFileListPaths: [],
2699
3003
  inputPaths: [],
2700
3004
  name,
@@ -2713,10 +3017,7 @@ var Target = class extends XcodeObject {
2713
3017
  * @returns The view of the target dependency object.
2714
3018
  */
2715
3019
  addDependency(dependency) {
2716
- for (const id of stringItems(this.properties["dependencies"])) {
2717
- const existing = this.project.get(id);
2718
- if (existing?.getString("target") === dependency.id) return existing;
2719
- }
3020
+ for (const dependencyView of this.dependencies()) if (dependencyView.getString("target") === dependency.id) return dependencyView;
2720
3021
  const proxy = this.project.add(Isa.containerItemProxy, {
2721
3022
  containerPortal: this.project.rootProject.id,
2722
3023
  proxyType: 1,
@@ -2736,6 +3037,7 @@ var Target = class extends XcodeObject {
2736
3037
  * itself, such as an application or an app extension.
2737
3038
  */
2738
3039
  var NativeTarget = class extends Target {
3040
+ static isa = Isa.nativeTarget;
2739
3041
  /**
2740
3042
  * The target's product type identifier, for example
2741
3043
  * `com.apple.product-type.application`.
@@ -2755,8 +3057,8 @@ var NativeTarget = class extends Target {
2755
3057
  * one.
2756
3058
  */
2757
3059
  get productReference() {
2758
- const id = this.getString("productReference");
2759
- return id == null ? void 0 : this.project.get(id);
3060
+ const view = this.project.get(this.getString("productReference"));
3061
+ return FileReference.is(view) ? view : void 0;
2760
3062
  }
2761
3063
  /**
2762
3064
  * Whether the target builds for watchOS, decided by its product type or
@@ -2772,21 +3074,21 @@ var NativeTarget = class extends Target {
2772
3074
  * declaration order.
2773
3075
  */
2774
3076
  packageProductDependencies() {
2775
- return this.referencedViews("packageProductDependencies");
3077
+ return this.referencedViews("packageProductDependencies").filter((view) => SwiftPackageProductDependency.is(view));
2776
3078
  }
2777
3079
  /**
2778
3080
  * The views of the target's file-system-synchronized folders, in
2779
3081
  * declaration order.
2780
3082
  */
2781
3083
  syncGroups() {
2782
- return this.referencedViews("fileSystemSynchronizedGroups").filter((view) => view instanceof SyncRootGroup);
3084
+ return this.referencedViews("fileSystemSynchronizedGroups").filter((view) => SyncRootGroup.is(view));
2783
3085
  }
2784
3086
  /**
2785
3087
  * The views of the target's build rules, in evaluation order. Empty for
2786
3088
  * targets without custom rules, which is nearly all of them.
2787
3089
  */
2788
3090
  buildRules() {
2789
- return this.referencedViews("buildRules").filter((view) => view instanceof BuildRule);
3091
+ return this.referencedViews("buildRules").filter((view) => BuildRule.is(view));
2790
3092
  }
2791
3093
  /**
2792
3094
  * The target's sources phase, created when missing.
@@ -2836,9 +3138,8 @@ var NativeTarget = class extends Target {
2836
3138
  */
2837
3139
  syncGroupPaths() {
2838
3140
  const paths = [];
2839
- for (const id of stringItems(this.properties["fileSystemSynchronizedGroups"])) {
2840
- const group = this.project.get(id);
2841
- const path = group instanceof SyncRootGroup ? group.path : void 0;
3141
+ for (const group of this.syncGroups()) {
3142
+ const path = group.path;
2842
3143
  if (path != null) paths.push(path);
2843
3144
  }
2844
3145
  return paths;
@@ -2855,10 +3156,7 @@ var NativeTarget = class extends Target {
2855
3156
  * @returns The view of the target's synchronized folder for the path.
2856
3157
  */
2857
3158
  addSyncGroup(path) {
2858
- for (const id of stringItems(this.properties["fileSystemSynchronizedGroups"])) {
2859
- const existing = this.project.get(id);
2860
- if (existing instanceof SyncRootGroup && existing.path === path) return existing;
2861
- }
3159
+ for (const existing of this.syncGroups()) if (existing.path === path) return existing;
2862
3160
  const group = this.project.add(Isa.fileSystemSynchronizedRootGroup, {
2863
3161
  path,
2864
3162
  sourceTree: "<group>"
@@ -2881,10 +3179,7 @@ var NativeTarget = class extends Target {
2881
3179
  * @returns The view of the product dependency.
2882
3180
  */
2883
3181
  addSwiftPackageProduct(options) {
2884
- for (const id of stringItems(this.properties["packageProductDependencies"])) {
2885
- const existing = this.project.get(id);
2886
- if (existing?.getString("productName") === options.productName && existing.getString("package") === options.packageReference.id) return existing;
2887
- }
3182
+ for (const existing of this.packageProductDependencies()) if (existing.productName === options.productName && existing.getString("package") === options.packageReference.id) return existing;
2888
3183
  const productDependency = this.project.add(Isa.swiftPackageProductDependency, {
2889
3184
  package: options.packageReference.id,
2890
3185
  productName: options.productName
@@ -2905,7 +3200,7 @@ var NativeTarget = class extends Target {
2905
3200
  addSystemFramework(name) {
2906
3201
  const path = `System/Library/Frameworks/${name}.framework`;
2907
3202
  let reference;
2908
- for (const [, view] of this.project.objects()) if (view.isa === Isa.fileReference && view.getString("path") === path) {
3203
+ for (const [, view] of this.project.objects()) if (FileReference.is(view) && view.path === path) {
2909
3204
  reference = view;
2910
3205
  break;
2911
3206
  }
@@ -2924,12 +3219,15 @@ var NativeTarget = class extends Target {
2924
3219
  * targets through its dependencies and to run script or copy-files
2925
3220
  * phases, and the shared target surface covers everything it carries.
2926
3221
  */
2927
- var AggregateTarget = class extends Target {};
3222
+ var AggregateTarget = class extends Target {
3223
+ static isa = Isa.aggregateTarget;
3224
+ };
2928
3225
  /**
2929
3226
  * A legacy target shells out to an external build tool such as make
2930
3227
  * instead of using Xcode's build system.
2931
3228
  */
2932
3229
  var LegacyTarget = class extends Target {
3230
+ static isa = Isa.legacyTarget;
2933
3231
  /**
2934
3232
  * The build tool the target invokes, as an absolute path.
2935
3233
  */
@@ -2970,6 +3268,7 @@ var LegacyTarget = class extends Target {
2970
3268
  * the main group, and the project-level configurations.
2971
3269
  */
2972
3270
  var RootProject = class extends XcodeObject {
3271
+ static isa = Isa.project;
2973
3272
  /**
2974
3273
  * Ids of the project's targets, in project order.
2975
3274
  */
@@ -2982,7 +3281,7 @@ var RootProject = class extends XcodeObject {
2982
3281
  */
2983
3282
  mainGroup() {
2984
3283
  const group = this.project.get(this.getString("mainGroup"));
2985
- return group instanceof Group ? group : void 0;
3284
+ return Group.is(group) ? group : void 0;
2986
3285
  }
2987
3286
  /**
2988
3287
  * The settings dictionary of the project-level default configuration.
@@ -2997,7 +3296,7 @@ var RootProject = class extends XcodeObject {
2997
3296
  * in declaration order.
2998
3297
  */
2999
3298
  packageReferences() {
3000
- return this.referencedViews("packageReferences");
3299
+ return this.referencedViews("packageReferences").filter((view) => SwiftPackageReference.is(view));
3001
3300
  }
3002
3301
  /**
3003
3302
  * The group product references live in, creating it (and registering it
@@ -3005,7 +3304,7 @@ var RootProject = class extends XcodeObject {
3005
3304
  */
3006
3305
  ensureProductsGroup() {
3007
3306
  const existing = this.project.get(this.getString("productRefGroup"));
3008
- if (existing instanceof Group) return existing;
3307
+ if (Group.is(existing)) return existing;
3009
3308
  const group = this.project.add(Isa.group, {
3010
3309
  children: [],
3011
3310
  name: "Products",
@@ -3239,10 +3538,7 @@ var XcodeProject = class XcodeProject {
3239
3538
  * Finds the remote Swift package reference for a repository URL.
3240
3539
  */
3241
3540
  findSwiftPackage(repositoryUrl) {
3242
- for (const id of stringItems(this.rootProject.properties["packageReferences"])) {
3243
- const reference = this.get(id);
3244
- if (reference?.getString("repositoryURL") === repositoryUrl) return reference;
3245
- }
3541
+ return this.rootProject.packageReferences().filter((reference) => RemoteSwiftPackageReference.is(reference)).find((reference) => reference.repositoryURL === repositoryUrl);
3246
3542
  }
3247
3543
  /**
3248
3544
  * Adds a remote Swift package reference and registers it on the project.
@@ -3271,7 +3567,7 @@ var XcodeProject = class XcodeProject {
3271
3567
  * Finds the local Swift package reference for a directory path.
3272
3568
  */
3273
3569
  findLocalSwiftPackage(relativePath) {
3274
- return this.rootProject.packageReferences().find((reference) => reference.isa === Isa.localSwiftPackageReference && reference.getString("relativePath") === relativePath);
3570
+ return this.rootProject.packageReferences().filter((reference) => LocalSwiftPackageReference.is(reference)).find((reference) => reference.relativePath === relativePath);
3275
3571
  }
3276
3572
  /**
3277
3573
  * Adds a local (path-based) Swift package reference and registers it on
@@ -3296,7 +3592,7 @@ var XcodeProject = class XcodeProject {
3296
3592
  */
3297
3593
  buildFilesReferencing(reference) {
3298
3594
  const buildFiles = [];
3299
- for (const [, view] of this.objects()) if (view.isa === Isa.buildFile && (view.getString("fileRef") === reference.id || view.getString("productRef") === reference.id)) buildFiles.push(view);
3595
+ for (const [, view] of this.objects()) if (BuildFile.is(view) && (view.getString("fileRef") === reference.id || view.getString("productRef") === reference.id)) buildFiles.push(view);
3300
3596
  return buildFiles;
3301
3597
  }
3302
3598
  /**
@@ -3428,29 +3724,61 @@ var XcodeProject = class XcodeProject {
3428
3724
  return search(mainGroup, "");
3429
3725
  }
3430
3726
  /**
3431
- * Creates the typed view for an object, dispatching on its isa. Objects
3432
- * outside the typed vocabulary get the generic base view.
3727
+ * Creates the typed view for an object, dispatching on the isa each
3728
+ * view class declares. Unknown `PBX*BuildPhase` kinds still map to
3729
+ * {@link BuildPhase}, and everything else outside the vocabulary gets
3730
+ * the generic base view.
3433
3731
  */
3434
3732
  createView(id, isa) {
3435
- switch (isa) {
3436
- case Isa.nativeTarget: return new NativeTarget(this, id);
3437
- case Isa.aggregateTarget: return new AggregateTarget(this, id);
3438
- case Isa.legacyTarget: return new LegacyTarget(this, id);
3439
- case Isa.project: return new RootProject(this, id);
3440
- case Isa.group:
3441
- case Isa.variantGroup: return new Group(this, id);
3442
- case Isa.versionGroup: return new VersionGroup(this, id);
3443
- case Isa.fileSystemSynchronizedRootGroup: return new SyncRootGroup(this, id);
3444
- case Isa.buildRule: return new BuildRule(this, id);
3445
- case Isa.buildConfiguration: return new BuildConfiguration(this, id);
3446
- case Isa.fileReference: return new FileReference(this, id);
3447
- case Isa.containerItemProxy: return new ContainerItemProxy(this, id);
3448
- case Isa.referenceProxy: return new ReferenceProxy(this, id);
3449
- default: return isa.endsWith("BuildPhase") ? new BuildPhase(this, id) : new XcodeObject(this, id);
3450
- }
3733
+ const View = VIEW_BY_ISA.get(isa);
3734
+ if (View != null) return new View(this, id);
3735
+ return isa.endsWith("BuildPhase") ? new BuildPhase(this, id) : new XcodeObject(this, id);
3451
3736
  }
3452
3737
  };
3453
3738
  /**
3739
+ * Every concrete view class of the object model. The registry below is
3740
+ * derived from this list, so adding a view class with its `isa` is all
3741
+ * it takes to route objects of that kind to it.
3742
+ */
3743
+ const VIEW_CLASSES = [
3744
+ AggregateTarget,
3745
+ AppleScriptBuildPhase,
3746
+ BuildConfiguration,
3747
+ BuildFile,
3748
+ BuildFileExceptionSet,
3749
+ BuildPhaseMembershipExceptionSet,
3750
+ BuildRule,
3751
+ BuildStyle,
3752
+ ConfigurationList,
3753
+ ContainerItemProxy,
3754
+ CopyFilesBuildPhase,
3755
+ FileReference,
3756
+ FrameworksBuildPhase,
3757
+ Group,
3758
+ HeadersBuildPhase,
3759
+ LegacyTarget,
3760
+ LocalSwiftPackageReference,
3761
+ NativeTarget,
3762
+ ReferenceProxy,
3763
+ RemoteSwiftPackageReference,
3764
+ ResourcesBuildPhase,
3765
+ RezBuildPhase,
3766
+ RootProject,
3767
+ ShellScriptBuildPhase,
3768
+ SourcesBuildPhase,
3769
+ SwiftPackageProductDependency,
3770
+ SyncRootGroup,
3771
+ TargetDependency,
3772
+ VariantGroup,
3773
+ VersionGroup
3774
+ ];
3775
+ /**
3776
+ * View constructors by the isa they model, built from each class's own
3777
+ * `isa` declaration.
3778
+ */
3779
+ const VIEW_BY_ISA = /* @__PURE__ */ new Map();
3780
+ for (const viewClass of VIEW_CLASSES) if (viewClass.isa != null) VIEW_BY_ISA.set(viewClass.isa, viewClass);
3781
+ /**
3454
3782
  * Joins two path segments with a `/`, treating an empty prefix as the
3455
3783
  * project root.
3456
3784
  */
@@ -4161,4 +4489,4 @@ function createXcscheme(options) {
4161
4489
  };
4162
4490
  }
4163
4491
  //#endregion
4164
- export { AggregateTarget, BuildConfiguration, BuildPhase, BuildRule, BuildableReference, ContainerItemProxy, CopyFilesDestination, FileReference, Group, Isa, LegacyTarget, NativeTarget, PbxprojBuildError, PbxprojParseError, ProductType, ReferenceProxy, RootProject, SyncRootGroup, Target, VersionGroup, XcodeModelError, XcodeObject, XcodeProject, Xcscheme, XcschemeBuildError, XcschemeParseError, buildPbxproj, buildXcscheme, createXcscheme, generateObjectId, isXcschemeElement, parsePbxproj, parseXcscheme, xcschemeElements };
4492
+ export { AggregateTarget, AppleScriptBuildPhase, BuildConfiguration, BuildFile, BuildFileExceptionSet, BuildPhase, BuildPhaseMembershipExceptionSet, BuildRule, BuildStyle, BuildableReference, ConfigurationList, ContainerItemProxy, CopyFilesBuildPhase, CopyFilesDestination, ExceptionSet, FileReference, FrameworksBuildPhase, Group, HeadersBuildPhase, Isa, LegacyTarget, LocalSwiftPackageReference, NativeTarget, PbxprojBuildError, PbxprojParseError, ProductType, ReferenceProxy, RemoteSwiftPackageReference, ResourcesBuildPhase, RezBuildPhase, RootProject, ShellScriptBuildPhase, SourcesBuildPhase, SwiftPackageProductDependency, SwiftPackageReference, SyncRootGroup, Target, TargetDependency, VariantGroup, VersionGroup, XcodeModelError, XcodeObject, XcodeProject, Xcscheme, XcschemeBuildError, XcschemeParseError, buildPbxproj, buildXcscheme, createXcscheme, generateObjectId, isXcschemeElement, parsePbxproj, parseXcscheme, xcschemeElements };