rork-xcode 0.5.0 → 0.7.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/README.md CHANGED
@@ -223,6 +223,7 @@ for (const [id, object] of project.objects()) {
223
223
  ### Semantics
224
224
 
225
225
  - **A view class for every kind.** Every `isa` Xcode writes has its own class, and each class declares its `isa` through a static field the view factory dispatches on. Targets of every kind, groups, variant and version groups, synchronized folders and their exception sets, every build phase kind, build rules, build files, build styles, configurations and configuration lists, file references, target dependencies, container item proxies, reference proxies, and Swift package references and products all come back typed. Kinds outside the vocabulary fall back to a generic `XcodeObject` with the same read and write access, so nothing in a document is out of reach.
226
+ - **Isa literals type the returns.** Creation and lookup take the isa and give back the exact class for it, with no cast at the call site. `project.add(Isa.fileReference, ...)` is a `FileReference`, `target.ensureBuildPhase(Isa.copyFilesBuildPhase, ...)` is a `CopyFilesBuildPhase`, and `target.findBuildPhase(Isa.shellScriptBuildPhase)` is a `ShellScriptBuildPhase | undefined`. A dynamic string falls back to the generic view type.
226
227
  - **`is()` narrowing.** Every view class carries a static type guard for discriminating mixed objects: `if (NativeTarget.is(object))` narrows the way `instanceof` does, subclasses included. Relationships resolve typed too, from `dependency.target()` and `buildFile.productDependency()` to `configuration.buildSettings` as a live typed dictionary.
227
228
  - **Typed, open property shapes.** Known keys autocomplete (`target.properties.productType`) and the shape stays open, so keys like `INFOPLIST_KEY_*` settings remain first-class. The shapes describe well-formed documents. When reading untrusted input, use the narrowing accessors, which never trust them.
228
229
  - **Two verb families.** `add*` wires something to its owner (a dependency, a package, a framework, a synchronized folder) and is idempotent, so re-adding returns the existing wiring. `ensure*` returns a structural container, creating it when missing (a build phase, a group chain, the Products group). Both families can therefore run unconditionally in scaffold and repair flows.
package/dist/index.d.ts CHANGED
@@ -234,6 +234,16 @@ declare const Isa: {
234
234
  readonly swiftPackageProductDependency: "XCSwiftPackageProductDependency";
235
235
  readonly versionGroup: "XCVersionGroup";
236
236
  };
237
+ /**
238
+ * One of the `isa` names of the vocabulary, the union of the values of
239
+ * {@link Isa}.
240
+ */
241
+ type IsaValue = (typeof Isa)[keyof typeof Isa];
242
+ /**
243
+ * The `isa` names of the build phase kinds. The phase helpers on targets
244
+ * accept these, and the literal passed picks the phase class they return.
245
+ */
246
+ type BuildPhaseIsa = typeof Isa.appleScriptBuildPhase | typeof Isa.copyFilesBuildPhase | typeof Isa.frameworksBuildPhase | typeof Isa.headersBuildPhase | typeof Isa.resourcesBuildPhase | typeof Isa.rezBuildPhase | typeof Isa.shellScriptBuildPhase | typeof Isa.sourcesBuildPhase;
237
247
  /**
238
248
  * Product type identifiers of the targets the model creates or reasons
239
249
  * about. Other product types pass through untouched.
@@ -613,18 +623,21 @@ declare class Target<Properties extends TargetProperties = TargetProperties> ext
613
623
  buildPhases(): BuildPhase[];
614
624
  /**
615
625
  * Finds the target's first build phase with the given isa, and, when
616
- * `name` is provided, the given display name.
626
+ * `name` is provided, the given display name. An isa literal of the
627
+ * vocabulary types the result, so `findBuildPhase(Isa.copyFilesBuildPhase)`
628
+ * gives a `CopyFilesBuildPhase | undefined`.
617
629
  */
618
- findBuildPhase(isa: string, name?: string): BuildPhase | undefined;
630
+ findBuildPhase<I extends string>(isa: I, name?: string): BuildPhaseOf<I> | undefined;
619
631
  /**
620
632
  * Returns the target's build phase with the given isa and properties,
621
633
  * creating and appending it when missing. The properties apply only on
622
- * creation; an existing phase is returned as is.
634
+ * creation. An existing phase is returned as is, already typed as the
635
+ * phase class the isa names.
623
636
  *
624
637
  * The match key is the isa plus the `name` property when one is given,
625
638
  * so differently named copy-files phases coexist.
626
639
  */
627
- ensureBuildPhase(isa: string, properties?: PbxprojObject): BuildPhase;
640
+ ensureBuildPhase<I extends BuildPhaseIsa>(isa: I, properties?: PbxprojObject): BuildPhaseOf<I>;
628
641
  /**
629
642
  * The target's shell-script phase with the given name, created with the
630
643
  * usual defaults (`/bin/sh`, empty input and output lists) when missing.
@@ -710,6 +723,14 @@ declare class NativeTarget extends Target<NativeTargetProperties> {
710
723
  * target has no product reference to embed.
711
724
  */
712
725
  embed(extension: NativeTarget): CopyFilesBuildPhase | undefined;
726
+ /**
727
+ * The targets whose products this target's copy-files phases carry,
728
+ * in phase and file order. This is the read-side counterpart of
729
+ * {@link embed}: extensions, watch apps, and App Clips embedded here
730
+ * come back as their target views. Targets embedding further targets
731
+ * of their own can be walked recursively through this accessor.
732
+ */
733
+ embeddedTargets(): NativeTarget[];
713
734
  /**
714
735
  * The on-disk folder paths of the file-system-synchronized groups linked
715
736
  * to this target. Empty for targets without synchronized folders
@@ -929,6 +950,11 @@ declare class CopyFilesBuildPhase extends BuildPhase<CopyFilesBuildPhaseProperti
929
950
  * when present.
930
951
  */
931
952
  get dstPath(): string | undefined;
953
+ /**
954
+ * The destination folder code, when present. Compare against the
955
+ * {@link CopyFilesDestination} constants.
956
+ */
957
+ get dstSubfolderSpec(): number | undefined;
932
958
  }
933
959
  /**
934
960
  * A `PBXShellScriptBuildPhase` runs a script during the build.
@@ -1365,17 +1391,20 @@ declare class XcodeProject {
1365
1391
  */
1366
1392
  generateId(seed: string): string;
1367
1393
  /**
1368
- * Adds an object to the document and returns its view.
1394
+ * Adds an object to the document and returns its view. When the isa is
1395
+ * a literal of the vocabulary, the returned view is already the exact
1396
+ * class for it, so `add(Isa.fileReference, ...)` gives a `FileReference`
1397
+ * with no cast at the call site.
1369
1398
  *
1370
- * @param isa The object's kind; written as the `isa` property.
1399
+ * @param isa The object's kind, written as the `isa` property.
1371
1400
  * @param properties The object's remaining properties. The dictionary is
1372
1401
  * stored as passed (not copied), with `isa` written first so the
1373
1402
  * serialized entry leads with it.
1374
- * @param seed Seed for the deterministic id; defaults to the isa, which
1403
+ * @param seed Seed for the deterministic id. Defaults to the isa, which
1375
1404
  * is only sensible for singleton objects.
1376
1405
  * @returns The view of the created object.
1377
1406
  */
1378
- add(isa: string, properties: PbxprojObject, seed?: string): XcodeObject;
1407
+ add<I extends string>(isa: I, properties: PbxprojObject, seed?: string): ViewOf<I>;
1379
1408
  /**
1380
1409
  * The view of the document's root `PBXProject` object.
1381
1410
  *
@@ -1526,6 +1555,65 @@ declare class XcodeProject {
1526
1555
  */
1527
1556
  private createView;
1528
1557
  }
1558
+ /**
1559
+ * The view class for every isa of the vocabulary. The runtime registry
1560
+ * and the {@link ViewByIsa} type are both derived from this one object,
1561
+ * so the class an object routes to and the class its isa literal promises
1562
+ * are always the same. The `satisfies` clause keeps the object covering
1563
+ * the whole vocabulary, and the model tests check that every entry agrees
1564
+ * with its class's own `isa` declaration.
1565
+ */
1566
+ declare const VIEWS: {
1567
+ readonly PBXAggregateTarget: typeof AggregateTarget;
1568
+ readonly PBXAppleScriptBuildPhase: typeof AppleScriptBuildPhase;
1569
+ readonly XCBuildConfiguration: typeof BuildConfiguration;
1570
+ readonly PBXBuildFile: typeof BuildFile;
1571
+ readonly PBXBuildRule: typeof BuildRule;
1572
+ readonly PBXBuildStyle: typeof BuildStyle;
1573
+ readonly XCConfigurationList: typeof ConfigurationList;
1574
+ readonly PBXContainerItemProxy: typeof ContainerItemProxy;
1575
+ readonly PBXCopyFilesBuildPhase: typeof CopyFilesBuildPhase;
1576
+ readonly PBXFileReference: typeof FileReference;
1577
+ readonly PBXFileSystemSynchronizedBuildFileExceptionSet: typeof BuildFileExceptionSet;
1578
+ readonly PBXFileSystemSynchronizedGroupBuildPhaseMembershipExceptionSet: typeof BuildPhaseMembershipExceptionSet;
1579
+ readonly PBXFileSystemSynchronizedRootGroup: typeof SyncRootGroup;
1580
+ readonly PBXFrameworksBuildPhase: typeof FrameworksBuildPhase;
1581
+ readonly PBXGroup: typeof Group;
1582
+ readonly PBXHeadersBuildPhase: typeof HeadersBuildPhase;
1583
+ readonly PBXLegacyTarget: typeof LegacyTarget;
1584
+ readonly XCLocalSwiftPackageReference: typeof LocalSwiftPackageReference;
1585
+ readonly PBXNativeTarget: typeof NativeTarget;
1586
+ readonly PBXProject: typeof RootProject;
1587
+ readonly PBXReferenceProxy: typeof ReferenceProxy;
1588
+ readonly XCRemoteSwiftPackageReference: typeof RemoteSwiftPackageReference;
1589
+ readonly PBXResourcesBuildPhase: typeof ResourcesBuildPhase;
1590
+ readonly PBXRezBuildPhase: typeof RezBuildPhase;
1591
+ readonly PBXShellScriptBuildPhase: typeof ShellScriptBuildPhase;
1592
+ readonly PBXSourcesBuildPhase: typeof SourcesBuildPhase;
1593
+ readonly XCSwiftPackageProductDependency: typeof SwiftPackageProductDependency;
1594
+ readonly PBXTargetDependency: typeof TargetDependency;
1595
+ readonly PBXVariantGroup: typeof VariantGroup;
1596
+ readonly XCVersionGroup: typeof VersionGroup;
1597
+ };
1598
+ /**
1599
+ * The view class each isa of the vocabulary maps to, as a type. Derived
1600
+ * from the same {@link VIEWS} object the runtime registry is built from,
1601
+ * which is what lets creation and lookup helpers return the exact class
1602
+ * for an isa literal instead of a base class the caller has to cast.
1603
+ */
1604
+ type ViewByIsa = { [I in keyof typeof VIEWS]: InstanceType<(typeof VIEWS)[I]> };
1605
+ /**
1606
+ * The view type an isa literal resolves to. Literals of the vocabulary
1607
+ * give the dedicated class, and anything else gives the generic
1608
+ * `XcodeObject`.
1609
+ */
1610
+ type ViewOf<I extends string> = I extends keyof ViewByIsa ? ViewByIsa[I] : XcodeObject;
1611
+ /**
1612
+ * The build phase view an isa literal resolves to. Isas outside the
1613
+ * vocabulary give the generic `BuildPhase`, matching the view factory's
1614
+ * suffix fallback.
1615
+ */
1616
+ type BuildPhaseOf<I extends string> = I extends keyof ViewByIsa ? Extract<ViewByIsa[I], BuildPhase> : BuildPhase;
1529
1617
  //#endregion
1530
1618
  //#region src/model/object.d.ts
1531
1619
  /**
@@ -1543,10 +1631,11 @@ declare class XcodeProject {
1543
1631
  declare class XcodeObject<Properties extends PbxprojObject = PbxprojObject> {
1544
1632
  /**
1545
1633
  * The `isa` name this view class models. Each concrete view declares
1546
- * its own, and the project's view factory dispatches on it, so the
1547
- * class itself is the source of truth for which objects it covers.
1548
- * Classes that only share behavior, like this base class and the
1549
- * abstract target and phase bases, declare `null` and never route.
1634
+ * its own, the factory registry routes objects of that isa to the
1635
+ * class, and the model tests keep the registry and these declarations
1636
+ * in agreement. Classes that only share behavior, like this base class
1637
+ * and the abstract target and phase bases, declare `null` and never
1638
+ * route.
1550
1639
  */
1551
1640
  static readonly isa: string | null;
1552
1641
  /** The project this object belongs to. */
@@ -1870,4 +1959,4 @@ declare function parseXcscheme(text: string): XcschemeDocument;
1870
1959
  */
1871
1960
  declare function generateObjectId(seed: string, existing: ReadonlySet<string>): string;
1872
1961
  //#endregion
1873
- export { type AddNativeTargetOptions, AggregateTarget, type ApplePlatform, AppleScriptBuildPhase, BuildConfiguration, type BuildConfigurationProperties, BuildFile, BuildFileExceptionSet, type BuildFileProperties, BuildPhase, BuildPhaseMembershipExceptionSet, type BuildPhaseMembershipExceptionSetProperties, type BuildPhaseProperties, BuildRule, type BuildRuleProperties, type BuildSettings, BuildStyle, type BuildStyleProperties, BuildableReference, ConfigurationList, type ConfigurationListProperties, ContainerItemProxy, type ContainerItemProxyProperties, CopyFilesBuildPhase, type CopyFilesBuildPhaseProperties, CopyFilesDestination, type CreateXcschemeOptions, ExceptionSet, type ExceptionSetProperties, FileReference, type FileReferenceProperties, FrameworksBuildPhase, Group, type GroupProperties, HeadersBuildPhase, Isa, LegacyTarget, type LegacyTargetProperties, LocalSwiftPackageReference, type LocalSwiftPackageReferenceProperties, NativeTarget, type NativeTargetProperties, type PbxprojArray, PbxprojBuildError, type PbxprojErrorPosition, type PbxprojObject, PbxprojParseError, type PbxprojValue, ProductType, type ProjectIssue, type ProjectIssueKind, ReferenceProxy, type ReferenceProxyProperties, RemoteSwiftPackageReference, type RemoteSwiftPackageReferenceProperties, ResourcesBuildPhase, RezBuildPhase, RootProject, type RootProjectProperties, ShellScriptBuildPhase, type ShellScriptBuildPhaseProperties, SourcesBuildPhase, SwiftPackageProductDependency, type SwiftPackageProductDependencyProperties, SwiftPackageReference, type SwiftPackageReferenceProperties, SyncRootGroup, type SyncRootGroupProperties, Target, TargetDependency, type TargetDependencyProperties, type TargetProperties, VariantGroup, VersionGroup, type VersionGroupProperties, XcodeModelError, XcodeObject, XcodeProject, Xcscheme, XcschemeBuildError, type XcschemeComment, type XcschemeDocument, type XcschemeElement, type XcschemeNode, XcschemeParseError, buildPbxproj, buildXcscheme, createXcscheme, generateObjectId, isXcschemeElement, parsePbxproj, parseXcscheme, xcschemeElements };
1962
+ export { type AddNativeTargetOptions, AggregateTarget, type ApplePlatform, AppleScriptBuildPhase, BuildConfiguration, type BuildConfigurationProperties, BuildFile, BuildFileExceptionSet, type BuildFileProperties, BuildPhase, type BuildPhaseIsa, BuildPhaseMembershipExceptionSet, type BuildPhaseMembershipExceptionSetProperties, type BuildPhaseOf, type BuildPhaseProperties, BuildRule, type BuildRuleProperties, type BuildSettings, BuildStyle, type BuildStyleProperties, BuildableReference, ConfigurationList, type ConfigurationListProperties, ContainerItemProxy, type ContainerItemProxyProperties, CopyFilesBuildPhase, type CopyFilesBuildPhaseProperties, CopyFilesDestination, type CreateXcschemeOptions, ExceptionSet, type ExceptionSetProperties, FileReference, type FileReferenceProperties, FrameworksBuildPhase, Group, type GroupProperties, HeadersBuildPhase, Isa, type IsaValue, LegacyTarget, type LegacyTargetProperties, LocalSwiftPackageReference, type LocalSwiftPackageReferenceProperties, NativeTarget, type NativeTargetProperties, type PbxprojArray, PbxprojBuildError, type PbxprojErrorPosition, type PbxprojObject, PbxprojParseError, type PbxprojValue, ProductType, type ProjectIssue, type ProjectIssueKind, ReferenceProxy, type ReferenceProxyProperties, RemoteSwiftPackageReference, type RemoteSwiftPackageReferenceProperties, ResourcesBuildPhase, RezBuildPhase, RootProject, type RootProjectProperties, ShellScriptBuildPhase, type ShellScriptBuildPhaseProperties, SourcesBuildPhase, SwiftPackageProductDependency, type SwiftPackageProductDependencyProperties, SwiftPackageReference, type SwiftPackageReferenceProperties, SyncRootGroup, type SyncRootGroupProperties, Target, TargetDependency, type TargetDependencyProperties, type TargetProperties, VariantGroup, VersionGroup, type VersionGroupProperties, type ViewByIsa, type ViewOf, XcodeModelError, XcodeObject, XcodeProject, Xcscheme, XcschemeBuildError, type XcschemeComment, type XcschemeDocument, type XcschemeElement, type XcschemeNode, XcschemeParseError, buildPbxproj, buildXcscheme, createXcscheme, generateObjectId, isXcschemeElement, parsePbxproj, parseXcscheme, xcschemeElements };
package/dist/index.js CHANGED
@@ -1033,10 +1033,11 @@ function stringItems(value) {
1033
1033
  var XcodeObject = class {
1034
1034
  /**
1035
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.
1036
+ * its own, the factory registry routes objects of that isa to the
1037
+ * class, and the model tests keep the registry and these declarations
1038
+ * in agreement. Classes that only share behavior, like this base class
1039
+ * and the abstract target and phase bases, declare `null` and never
1040
+ * route.
1040
1041
  */
1041
1042
  static isa = null;
1042
1043
  /** The project this object belongs to. */
@@ -1342,6 +1343,14 @@ var CopyFilesBuildPhase = class extends BuildPhase {
1342
1343
  get dstPath() {
1343
1344
  return this.getString("dstPath");
1344
1345
  }
1346
+ /**
1347
+ * The destination folder code, when present. Compare against the
1348
+ * {@link CopyFilesDestination} constants.
1349
+ */
1350
+ get dstSubfolderSpec() {
1351
+ const value = this.properties["dstSubfolderSpec"];
1352
+ return typeof value === "number" ? value : void 0;
1353
+ }
1345
1354
  };
1346
1355
  /**
1347
1356
  * A `PBXShellScriptBuildPhase` runs a script during the build.
@@ -2962,7 +2971,9 @@ var Target = class extends XcodeObject {
2962
2971
  }
2963
2972
  /**
2964
2973
  * Finds the target's first build phase with the given isa, and, when
2965
- * `name` is provided, the given display name.
2974
+ * `name` is provided, the given display name. An isa literal of the
2975
+ * vocabulary types the result, so `findBuildPhase(Isa.copyFilesBuildPhase)`
2976
+ * gives a `CopyFilesBuildPhase | undefined`.
2966
2977
  */
2967
2978
  findBuildPhase(isa, name) {
2968
2979
  return this.buildPhases().find((phase) => phase.isa === isa && (name == null || phase.name === name));
@@ -2970,7 +2981,8 @@ var Target = class extends XcodeObject {
2970
2981
  /**
2971
2982
  * Returns the target's build phase with the given isa and properties,
2972
2983
  * creating and appending it when missing. The properties apply only on
2973
- * creation; an existing phase is returned as is.
2984
+ * creation. An existing phase is returned as is, already typed as the
2985
+ * phase class the isa names.
2974
2986
  *
2975
2987
  * The match key is the isa plus the `name` property when one is given,
2976
2988
  * so differently named copy-files phases coexist.
@@ -3132,6 +3144,32 @@ var NativeTarget = class extends Target {
3132
3144
  return phase;
3133
3145
  }
3134
3146
  /**
3147
+ * The targets whose products this target's copy-files phases carry,
3148
+ * in phase and file order. This is the read-side counterpart of
3149
+ * {@link embed}: extensions, watch apps, and App Clips embedded here
3150
+ * come back as their target views. Targets embedding further targets
3151
+ * of their own can be walked recursively through this accessor.
3152
+ */
3153
+ embeddedTargets() {
3154
+ const ownersByProductId = /* @__PURE__ */ new Map();
3155
+ for (const candidate of this.project.nativeTargets()) {
3156
+ const product = candidate.productReference;
3157
+ if (product != null) ownersByProductId.set(product.id, candidate);
3158
+ }
3159
+ const embedded = [];
3160
+ for (const phase of this.buildPhases()) {
3161
+ if (!CopyFilesBuildPhase.is(phase)) continue;
3162
+ for (const buildFileId of phase.buildFileIds) {
3163
+ const buildFile = this.project.get(buildFileId);
3164
+ if (!BuildFile.is(buildFile)) continue;
3165
+ const reference = buildFile.fileReference();
3166
+ const owner = reference == null ? void 0 : ownersByProductId.get(reference.id);
3167
+ if (owner != null && owner !== this && !embedded.includes(owner)) embedded.push(owner);
3168
+ }
3169
+ }
3170
+ return embedded;
3171
+ }
3172
+ /**
3135
3173
  * The on-disk folder paths of the file-system-synchronized groups linked
3136
3174
  * to this target. Empty for targets without synchronized folders
3137
3175
  * (projects predating Xcode 16).
@@ -3419,13 +3457,16 @@ var XcodeProject = class XcodeProject {
3419
3457
  return generateObjectId(seed, new Set(Object.keys(this.objectsDictionary)));
3420
3458
  }
3421
3459
  /**
3422
- * Adds an object to the document and returns its view.
3460
+ * Adds an object to the document and returns its view. When the isa is
3461
+ * a literal of the vocabulary, the returned view is already the exact
3462
+ * class for it, so `add(Isa.fileReference, ...)` gives a `FileReference`
3463
+ * with no cast at the call site.
3423
3464
  *
3424
- * @param isa The object's kind; written as the `isa` property.
3465
+ * @param isa The object's kind, written as the `isa` property.
3425
3466
  * @param properties The object's remaining properties. The dictionary is
3426
3467
  * stored as passed (not copied), with `isa` written first so the
3427
3468
  * serialized entry leads with it.
3428
- * @param seed Seed for the deterministic id; defaults to the isa, which
3469
+ * @param seed Seed for the deterministic id. Defaults to the isa, which
3429
3470
  * is only sensible for singleton objects.
3430
3471
  * @returns The view of the created object.
3431
3472
  */
@@ -3528,11 +3569,10 @@ var XcodeProject = class XcodeProject {
3528
3569
  productType: options.productType
3529
3570
  }, `${Isa.nativeTarget} ${options.name}`);
3530
3571
  ensureArray(this.rootProject.properties, "targets").push(target.id);
3531
- const nativeTarget = target;
3532
- nativeTarget.ensureSourcesPhase();
3533
- nativeTarget.ensureFrameworksPhase();
3534
- nativeTarget.ensureResourcesPhase();
3535
- return nativeTarget;
3572
+ target.ensureSourcesPhase();
3573
+ target.ensureFrameworksPhase();
3574
+ target.ensureResourcesPhase();
3575
+ return target;
3536
3576
  }
3537
3577
  /**
3538
3578
  * Finds the remote Swift package reference for a repository URL.
@@ -3736,48 +3776,49 @@ var XcodeProject = class XcodeProject {
3736
3776
  }
3737
3777
  };
3738
3778
  /**
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
- ];
3779
+ * The view class for every isa of the vocabulary. The runtime registry
3780
+ * and the {@link ViewByIsa} type are both derived from this one object,
3781
+ * so the class an object routes to and the class its isa literal promises
3782
+ * are always the same. The `satisfies` clause keeps the object covering
3783
+ * the whole vocabulary, and the model tests check that every entry agrees
3784
+ * with its class's own `isa` declaration.
3785
+ */
3786
+ const VIEWS = {
3787
+ [Isa.aggregateTarget]: AggregateTarget,
3788
+ [Isa.appleScriptBuildPhase]: AppleScriptBuildPhase,
3789
+ [Isa.buildConfiguration]: BuildConfiguration,
3790
+ [Isa.buildFile]: BuildFile,
3791
+ [Isa.buildRule]: BuildRule,
3792
+ [Isa.buildStyle]: BuildStyle,
3793
+ [Isa.configurationList]: ConfigurationList,
3794
+ [Isa.containerItemProxy]: ContainerItemProxy,
3795
+ [Isa.copyFilesBuildPhase]: CopyFilesBuildPhase,
3796
+ [Isa.fileReference]: FileReference,
3797
+ [Isa.fileSystemSynchronizedBuildFileExceptionSet]: BuildFileExceptionSet,
3798
+ [Isa.fileSystemSynchronizedGroupBuildPhaseMembershipExceptionSet]: BuildPhaseMembershipExceptionSet,
3799
+ [Isa.fileSystemSynchronizedRootGroup]: SyncRootGroup,
3800
+ [Isa.frameworksBuildPhase]: FrameworksBuildPhase,
3801
+ [Isa.group]: Group,
3802
+ [Isa.headersBuildPhase]: HeadersBuildPhase,
3803
+ [Isa.legacyTarget]: LegacyTarget,
3804
+ [Isa.localSwiftPackageReference]: LocalSwiftPackageReference,
3805
+ [Isa.nativeTarget]: NativeTarget,
3806
+ [Isa.project]: RootProject,
3807
+ [Isa.referenceProxy]: ReferenceProxy,
3808
+ [Isa.remoteSwiftPackageReference]: RemoteSwiftPackageReference,
3809
+ [Isa.resourcesBuildPhase]: ResourcesBuildPhase,
3810
+ [Isa.rezBuildPhase]: RezBuildPhase,
3811
+ [Isa.shellScriptBuildPhase]: ShellScriptBuildPhase,
3812
+ [Isa.sourcesBuildPhase]: SourcesBuildPhase,
3813
+ [Isa.swiftPackageProductDependency]: SwiftPackageProductDependency,
3814
+ [Isa.targetDependency]: TargetDependency,
3815
+ [Isa.variantGroup]: VariantGroup,
3816
+ [Isa.versionGroup]: VersionGroup
3817
+ };
3775
3818
  /**
3776
- * View constructors by the isa they model, built from each class's own
3777
- * `isa` declaration.
3819
+ * View constructors by the isa they model, in `Map` form for the factory.
3778
3820
  */
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);
3821
+ const VIEW_BY_ISA = new Map(Object.entries(VIEWS));
3781
3822
  /**
3782
3823
  * Joins two path segments with a `/`, treating an empty prefix as the
3783
3824
  * project root.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rork-xcode",
3
- "version": "0.5.0",
3
+ "version": "0.7.0",
4
4
  "description": "Zero-dependency Xcode project (pbxproj) and scheme (xcscheme) parser, builder, and object model that runs identically in every JavaScript runtime",
5
5
  "keywords": [
6
6
  "apple",