rork-xcode 0.10.0 → 0.11.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 +26 -1
- package/dist/index.d.ts +94 -1
- package/dist/index.js +200 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -100,7 +100,7 @@ const text = project.build();
|
|
|
100
100
|
|
|
101
101
|
### Targets and build settings
|
|
102
102
|
|
|
103
|
-
`getBuildSetting` resolves hierarchically the way Xcode does
|
|
103
|
+
`getBuildSetting` resolves hierarchically the way Xcode does, reading the target's default configuration first and the project-level configuration below it. Writes go to every configuration of the target, so Debug and Release stay consistent.
|
|
104
104
|
|
|
105
105
|
```ts
|
|
106
106
|
const app = project.findMainAppTarget("ios"); // "macos" | "tvos" | "watchos" | "visionos"
|
|
@@ -114,6 +114,13 @@ for (const target of project.nativeTargets()) {
|
|
|
114
114
|
}
|
|
115
115
|
```
|
|
116
116
|
|
|
117
|
+
`resolveBuildSetting` reads the same layers and expands the `$(NAME)` and `${NAME}` references in the value. Referenced settings resolve through the chain, `$(inherited)` continues from the next layer down, and `$(TARGET_NAME)` falls back to the target's name, so the template's `PRODUCT_NAME = "$(TARGET_NAME)"` resolves without any setup. References the document cannot answer (build-system paths like `$(BUILT_PRODUCTS_DIR)`) stay verbatim unless a caller-supplied lookup answers them, so nothing is invented.
|
|
118
|
+
|
|
119
|
+
```ts
|
|
120
|
+
app?.resolveBuildSetting("PRODUCT_NAME"); // "DemoApp", from PRODUCT_NAME = "$(TARGET_NAME)"
|
|
121
|
+
app?.resolveBuildSetting("WIDGET_ID"); // "com.example.demo.widget", through PRODUCT_BUNDLE_IDENTIFIER
|
|
122
|
+
```
|
|
123
|
+
|
|
117
124
|
`project.targets()` returns every target kind. Aggregate targets (`PBXAggregateTarget`) and legacy external-build-tool targets (`PBXLegacyTarget`) share the full target surface, from configurations and build settings to phases and dependency wiring.
|
|
118
125
|
|
|
119
126
|
```ts
|
|
@@ -314,6 +321,24 @@ project.registerXcconfig(reference, Xcconfig.parse(text));
|
|
|
314
321
|
app.getBuildSetting("SDKROOT"); // now sees values the xcconfig defines
|
|
315
322
|
```
|
|
316
323
|
|
|
324
|
+
## Build-setting references
|
|
325
|
+
|
|
326
|
+
Values reference other build settings as `$(NAME)` and `${NAME}`, in the pbxproj, in xcconfig files, and in Info.plist templates. The syntax is Xcode's own, down to the `:` operators, and Xcode's app templates write values in exactly this shape, for example `PRODUCT_BUNDLE_IDENTIFIER = com.yourcompany.$(PRODUCT_NAME:rfc1034identifier)`. `expandBuildSettingReferences` evaluates the syntax through a caller-supplied lookup, so the same code serves all three formats. Substituted text expands recursively, names may themselves contain references (`$(SETTING_$(VARIANT))`), cycles stay finite, and a reference the lookup cannot answer stays verbatim, so partial resolution loses no information.
|
|
327
|
+
|
|
328
|
+
```ts
|
|
329
|
+
import { expandBuildSettingReferences } from "rork-xcode";
|
|
330
|
+
|
|
331
|
+
// A value as found in a project file. The references and their operators
|
|
332
|
+
// are part of the document, so the expander takes them from the text
|
|
333
|
+
// rather than from options.
|
|
334
|
+
const found = "com.example.$(PRODUCT_NAME:rfc1034identifier)";
|
|
335
|
+
|
|
336
|
+
expandBuildSettingReferences(found, (name) => (name === "PRODUCT_NAME" ? "My App" : undefined));
|
|
337
|
+
// "com.example.My-App"
|
|
338
|
+
```
|
|
339
|
+
|
|
340
|
+
The `:` operators are honored for `lower`, `upper`, `rfc1034identifier` (the mapping into RFC 1034 host-name characters that bundle identifiers need), `c99extidentifier`, and `default=`. A reference carrying any other operator stays verbatim rather than expanding to a wrongly transformed value. The model composes the expander with settings resolution as `target.resolveBuildSetting(key)`, described under [Targets and build settings](#targets-and-build-settings).
|
|
341
|
+
|
|
317
342
|
## Performance
|
|
318
343
|
|
|
319
344
|
`rork-xcode` is measured against the pbxproj parsers on npm, [`@bacons/xcode`](https://www.npmjs.com/package/@bacons/xcode) (its `/json` parse/build entry point) and [`xcode`](https://www.npmjs.com/package/xcode) (the long-standing package used by native build tooling), on three documents: two real Xcode-written projects from the test suite and a deterministically generated five-target app with 800 source files. It is the fastest at both operations on every document, with zero dependencies.
|
package/dist/index.d.ts
CHANGED
|
@@ -207,6 +207,73 @@ declare class PbxprojBuildError extends Error {
|
|
|
207
207
|
constructor(message: string, path: string);
|
|
208
208
|
}
|
|
209
209
|
//#endregion
|
|
210
|
+
//#region src/expansion.d.ts
|
|
211
|
+
/**
|
|
212
|
+
* Expansion of `$(NAME)` and `${NAME}` build-setting references.
|
|
213
|
+
*
|
|
214
|
+
* Values in the pbxproj, in xcconfig files, and in Info.plist templates
|
|
215
|
+
* reference other build settings, and every consumer that needs the
|
|
216
|
+
* resolved string ends up re-implementing the substitution informally.
|
|
217
|
+
* The expander here is a pure function over a caller-supplied lookup, so
|
|
218
|
+
* the same code serves all three formats. The model composes it with
|
|
219
|
+
* settings resolution in `Target.resolveBuildSetting`.
|
|
220
|
+
*
|
|
221
|
+
* @module
|
|
222
|
+
*/
|
|
223
|
+
/**
|
|
224
|
+
* The value a reference expands to, or `undefined` to leave the
|
|
225
|
+
* reference in place. Returning the empty string expands to nothing,
|
|
226
|
+
* which is how Xcode itself treats settings that exist but are empty.
|
|
227
|
+
*/
|
|
228
|
+
type BuildSettingLookup = (name: string) => string | undefined;
|
|
229
|
+
interface ExpandBuildSettingOptions {
|
|
230
|
+
/**
|
|
231
|
+
* Whether lookup answers are expanded again, which is the default and
|
|
232
|
+
* suits lookups reading raw stored values. A lookup that resolves
|
|
233
|
+
* references itself, like the model's layered resolution, turns this
|
|
234
|
+
* off so text it deliberately left verbatim is not reinterpreted in
|
|
235
|
+
* the outer value's context.
|
|
236
|
+
*/
|
|
237
|
+
expandLookupValues?: boolean;
|
|
238
|
+
}
|
|
239
|
+
/**
|
|
240
|
+
* Expands every `$(NAME)` and `${NAME}` reference in a value through the
|
|
241
|
+
* lookup. Substituted text is expanded again, so references are followed
|
|
242
|
+
* through chains of values, and reference names may themselves contain
|
|
243
|
+
* references (`$(SETTING_$(VARIANT))`), which expand innermost first.
|
|
244
|
+
*
|
|
245
|
+
* A lookup answer of `undefined` leaves the reference in the output
|
|
246
|
+
* verbatim, so partial resolution loses no information. A reference
|
|
247
|
+
* whose expansion would recurse into itself also stays verbatim, which
|
|
248
|
+
* keeps cyclic definitions finite. Xcode's `:` operators are honored for
|
|
249
|
+
* the forms below, and a reference carrying any other operator stays
|
|
250
|
+
* verbatim rather than expanding to a wrongly transformed value.
|
|
251
|
+
*
|
|
252
|
+
* The supported operators are `lower` and `upper` for case mapping,
|
|
253
|
+
* `rfc1034identifier` and `c99extidentifier` for the identifier
|
|
254
|
+
* mappings bundle identifiers and product module names use, and
|
|
255
|
+
* `default=value` for substituting a fallback when the setting resolves
|
|
256
|
+
* empty or is not known to the lookup.
|
|
257
|
+
*/
|
|
258
|
+
declare function expandBuildSettingReferences(value: string, lookup: BuildSettingLookup, options?: ExpandBuildSettingOptions): string;
|
|
259
|
+
/**
|
|
260
|
+
* The transforming operators the expander supports, keyed by the name
|
|
261
|
+
* they are written with. `default=` is not listed because it carries an
|
|
262
|
+
* argument and substitutes rather than transforms, so the reference
|
|
263
|
+
* expansion handles it structurally.
|
|
264
|
+
*/
|
|
265
|
+
declare const OPERATOR_TRANSFORMS: {
|
|
266
|
+
c99extidentifier: (value: string) => string;
|
|
267
|
+
lower: (value: string) => string;
|
|
268
|
+
rfc1034identifier: (value: string) => string;
|
|
269
|
+
upper: (value: string) => string;
|
|
270
|
+
};
|
|
271
|
+
/**
|
|
272
|
+
* A transforming operator name honored in `$(NAME:operator)` references,
|
|
273
|
+
* alongside the structural `default=`.
|
|
274
|
+
*/
|
|
275
|
+
type BuildSettingOperator = keyof typeof OPERATOR_TRANSFORMS;
|
|
276
|
+
//#endregion
|
|
210
277
|
//#region src/model/isa.d.ts
|
|
211
278
|
/**
|
|
212
279
|
* Names and well-known values of the pbxproj object vocabulary.
|
|
@@ -593,6 +660,16 @@ interface BuildStyleProperties extends PbxprojObject {
|
|
|
593
660
|
}
|
|
594
661
|
//#endregion
|
|
595
662
|
//#region src/model/target.d.ts
|
|
663
|
+
interface ResolveBuildSettingOptions {
|
|
664
|
+
/**
|
|
665
|
+
* Answers references the document itself cannot, for example
|
|
666
|
+
* `$(BUILT_PRODUCTS_DIR)` when the caller knows the build layout. The
|
|
667
|
+
* lookup is consulted after the setting layers and before the built-in
|
|
668
|
+
* `$(TARGET_NAME)` fallback, and a reference it leaves unanswered
|
|
669
|
+
* stays verbatim in the result.
|
|
670
|
+
*/
|
|
671
|
+
lookup?: BuildSettingLookup;
|
|
672
|
+
}
|
|
596
673
|
/**
|
|
597
674
|
* The behavior every target kind shares. A target of any kind carries
|
|
598
675
|
* build configurations and settings, build phases, and dependencies, and
|
|
@@ -637,6 +714,22 @@ declare class Target<Properties extends TargetProperties = TargetProperties> ext
|
|
|
637
714
|
* reads as `undefined`.
|
|
638
715
|
*/
|
|
639
716
|
getBuildSetting(key: string): string | undefined;
|
|
717
|
+
/**
|
|
718
|
+
* Reads a build setting like {@link getBuildSetting} and expands the
|
|
719
|
+
* `$(NAME)` and `${NAME}` references in it. Referenced settings resolve
|
|
720
|
+
* through the same layering, `$(inherited)` and a setting referencing
|
|
721
|
+
* itself continue from the next layer down the way Xcode composes
|
|
722
|
+
* values, and `$(TARGET_NAME)` falls back to the target's name, so the
|
|
723
|
+
* common `PRODUCT_NAME = "$(TARGET_NAME)"` resolves without any caller
|
|
724
|
+
* setup.
|
|
725
|
+
*
|
|
726
|
+
* References the model cannot resolve (build-system paths like
|
|
727
|
+
* `$(BUILT_PRODUCTS_DIR)`, environment values) stay in the result
|
|
728
|
+
* verbatim unless the caller's lookup answers them, so no information
|
|
729
|
+
* is invented. See {@link expandBuildSettingReferences} for the
|
|
730
|
+
* operator forms honored during expansion.
|
|
731
|
+
*/
|
|
732
|
+
resolveBuildSetting(key: string, options?: ResolveBuildSettingOptions): string | undefined;
|
|
640
733
|
/**
|
|
641
734
|
* Writes a build setting on every configuration of the target, so Debug
|
|
642
735
|
* and Release stay consistent.
|
|
@@ -2296,4 +2389,4 @@ declare function buildXcconfig(document: XcconfigDocument): string;
|
|
|
2296
2389
|
*/
|
|
2297
2390
|
declare function parseXcconfig(source: string): XcconfigDocument;
|
|
2298
2391
|
//#endregion
|
|
2299
|
-
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, Xcconfig, type XcconfigAssignment, type XcconfigBlank, type XcconfigComment, type XcconfigCondition, type XcconfigDocument, type XcconfigInclude, type XcconfigIncludeResolver, XcconfigParseError, type XcconfigSettingsOptions, type XcconfigStatement, XcodeModelError, XcodeObject, XcodeProject, Xcscheme, XcschemeBuildError, type XcschemeComment, type XcschemeDocument, type XcschemeElement, type XcschemeNode, XcschemeParseError, buildPbxproj, buildXcconfig, buildXcscheme, createXcscheme, generateObjectId, isXcschemeElement, parseApplePlatform, parsePbxproj, parseXcconfig, parseXcscheme, xcschemeElements };
|
|
2392
|
+
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 BuildSettingLookup, type BuildSettingOperator, type BuildSettings, BuildStyle, type BuildStyleProperties, BuildableReference, ConfigurationList, type ConfigurationListProperties, ContainerItemProxy, type ContainerItemProxyProperties, CopyFilesBuildPhase, type CopyFilesBuildPhaseProperties, CopyFilesDestination, type CreateXcschemeOptions, ExceptionSet, type ExceptionSetProperties, type ExpandBuildSettingOptions, 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, type ResolveBuildSettingOptions, 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, Xcconfig, type XcconfigAssignment, type XcconfigBlank, type XcconfigComment, type XcconfigCondition, type XcconfigDocument, type XcconfigInclude, type XcconfigIncludeResolver, XcconfigParseError, type XcconfigSettingsOptions, type XcconfigStatement, XcodeModelError, XcodeObject, XcodeProject, Xcscheme, XcschemeBuildError, type XcschemeComment, type XcschemeDocument, type XcschemeElement, type XcschemeNode, XcschemeParseError, buildPbxproj, buildXcconfig, buildXcscheme, createXcscheme, expandBuildSettingReferences, generateObjectId, isXcschemeElement, parseApplePlatform, parsePbxproj, parseXcconfig, parseXcscheme, xcschemeElements };
|
package/dist/index.js
CHANGED
|
@@ -815,6 +815,154 @@ function buildPbxproj(root) {
|
|
|
815
815
|
return new Writer(root).toString();
|
|
816
816
|
}
|
|
817
817
|
//#endregion
|
|
818
|
+
//#region src/expansion.ts
|
|
819
|
+
/**
|
|
820
|
+
* Expands every `$(NAME)` and `${NAME}` reference in a value through the
|
|
821
|
+
* lookup. Substituted text is expanded again, so references are followed
|
|
822
|
+
* through chains of values, and reference names may themselves contain
|
|
823
|
+
* references (`$(SETTING_$(VARIANT))`), which expand innermost first.
|
|
824
|
+
*
|
|
825
|
+
* A lookup answer of `undefined` leaves the reference in the output
|
|
826
|
+
* verbatim, so partial resolution loses no information. A reference
|
|
827
|
+
* whose expansion would recurse into itself also stays verbatim, which
|
|
828
|
+
* keeps cyclic definitions finite. Xcode's `:` operators are honored for
|
|
829
|
+
* the forms below, and a reference carrying any other operator stays
|
|
830
|
+
* verbatim rather than expanding to a wrongly transformed value.
|
|
831
|
+
*
|
|
832
|
+
* The supported operators are `lower` and `upper` for case mapping,
|
|
833
|
+
* `rfc1034identifier` and `c99extidentifier` for the identifier
|
|
834
|
+
* mappings bundle identifiers and product module names use, and
|
|
835
|
+
* `default=value` for substituting a fallback when the setting resolves
|
|
836
|
+
* empty or is not known to the lookup.
|
|
837
|
+
*/
|
|
838
|
+
function expandBuildSettingReferences(value, lookup, options) {
|
|
839
|
+
return expand(value, lookup, options?.expandLookupValues !== false, /* @__PURE__ */ new Set());
|
|
840
|
+
}
|
|
841
|
+
/** The UTF-16 code unit of `$`, which starts every reference. */
|
|
842
|
+
const CODE_DOLLAR = 36;
|
|
843
|
+
/**
|
|
844
|
+
* One expansion pass over a value. Active names carry the references
|
|
845
|
+
* currently being expanded up the call stack, so a cycle is detected the
|
|
846
|
+
* moment a name would expand inside its own expansion.
|
|
847
|
+
*/
|
|
848
|
+
function expand(value, lookup, expandLookupValues, active) {
|
|
849
|
+
if (!value.includes("$")) return value;
|
|
850
|
+
let out = "";
|
|
851
|
+
let index = 0;
|
|
852
|
+
while (index < value.length) {
|
|
853
|
+
const open = value.charCodeAt(index) === CODE_DOLLAR ? value[index + 1] : void 0;
|
|
854
|
+
if (open !== "(" && open !== "{") {
|
|
855
|
+
out += value[index];
|
|
856
|
+
index++;
|
|
857
|
+
continue;
|
|
858
|
+
}
|
|
859
|
+
const end = findClosingDelimiter(value, index + 2, open === "(" ? ")" : "}");
|
|
860
|
+
if (end === -1) {
|
|
861
|
+
out += value.slice(index);
|
|
862
|
+
break;
|
|
863
|
+
}
|
|
864
|
+
const reference = value.slice(index, end + 1);
|
|
865
|
+
const inner = expand(value.slice(index + 2, end), lookup, expandLookupValues, active);
|
|
866
|
+
out += expandReference(reference, inner, lookup, expandLookupValues, active);
|
|
867
|
+
index = end + 1;
|
|
868
|
+
}
|
|
869
|
+
return out;
|
|
870
|
+
}
|
|
871
|
+
/**
|
|
872
|
+
* Finds the index of the closing delimiter matching an opener at
|
|
873
|
+
* `start - 1`, honoring nested delimiters of the same kind, or -1 when
|
|
874
|
+
* the reference is unterminated.
|
|
875
|
+
*/
|
|
876
|
+
function findClosingDelimiter(value, start, close) {
|
|
877
|
+
const open = close === ")" ? "(" : "{";
|
|
878
|
+
let depth = 0;
|
|
879
|
+
for (let i = start; i < value.length; i++) {
|
|
880
|
+
const ch = value[i];
|
|
881
|
+
if (ch === open) depth++;
|
|
882
|
+
else if (ch === close) {
|
|
883
|
+
if (depth === 0) return i;
|
|
884
|
+
depth--;
|
|
885
|
+
}
|
|
886
|
+
}
|
|
887
|
+
return -1;
|
|
888
|
+
}
|
|
889
|
+
/**
|
|
890
|
+
* Expands one reference whose name and operators have already had their
|
|
891
|
+
* own references resolved. Returns the original reference text whenever
|
|
892
|
+
* the expansion cannot honestly produce a value.
|
|
893
|
+
*/
|
|
894
|
+
function expandReference(reference, inner, lookup, expandLookupValues, active) {
|
|
895
|
+
const colon = inner.indexOf(":");
|
|
896
|
+
const name = colon === -1 ? inner : inner.slice(0, colon);
|
|
897
|
+
if (active.has(name)) return reference;
|
|
898
|
+
const raw = lookup(name);
|
|
899
|
+
const nested = new Set(active);
|
|
900
|
+
nested.add(name);
|
|
901
|
+
let value = raw;
|
|
902
|
+
if (raw != null && expandLookupValues) value = expand(raw, lookup, expandLookupValues, nested);
|
|
903
|
+
if (colon !== -1) {
|
|
904
|
+
for (const operator of splitOperators(inner.slice(colon + 1))) if (operator.startsWith("default=")) {
|
|
905
|
+
if (value == null || value === "") value = operator.slice(8);
|
|
906
|
+
} else if (value != null) {
|
|
907
|
+
const applied = applyOperator(operator, value);
|
|
908
|
+
if (applied == null) return reference;
|
|
909
|
+
value = applied;
|
|
910
|
+
} else if (applyOperator(operator, "") == null) return reference;
|
|
911
|
+
}
|
|
912
|
+
return value ?? reference;
|
|
913
|
+
}
|
|
914
|
+
/**
|
|
915
|
+
* Splits an operator chain at colons, keeping a `default=` value intact
|
|
916
|
+
* even when it contains colons of its own, the way Xcode consumes the
|
|
917
|
+
* rest of the reference as the default.
|
|
918
|
+
*/
|
|
919
|
+
function splitOperators(operators) {
|
|
920
|
+
const parts = [];
|
|
921
|
+
let rest = operators;
|
|
922
|
+
while (rest.length > 0) {
|
|
923
|
+
if (rest.startsWith("default=")) {
|
|
924
|
+
parts.push(rest);
|
|
925
|
+
break;
|
|
926
|
+
}
|
|
927
|
+
const colon = rest.indexOf(":");
|
|
928
|
+
if (colon === -1) {
|
|
929
|
+
parts.push(rest);
|
|
930
|
+
break;
|
|
931
|
+
}
|
|
932
|
+
parts.push(rest.slice(0, colon));
|
|
933
|
+
rest = rest.slice(colon + 1);
|
|
934
|
+
}
|
|
935
|
+
return parts;
|
|
936
|
+
}
|
|
937
|
+
/**
|
|
938
|
+
* The transforming operators the expander supports, keyed by the name
|
|
939
|
+
* they are written with. `default=` is not listed because it carries an
|
|
940
|
+
* argument and substitutes rather than transforms, so the reference
|
|
941
|
+
* expansion handles it structurally.
|
|
942
|
+
*/
|
|
943
|
+
const OPERATOR_TRANSFORMS = {
|
|
944
|
+
c99extidentifier: (value) => value.replaceAll(/[^A-Za-z0-9_]/gu, "_"),
|
|
945
|
+
lower: (value) => value.toLowerCase(),
|
|
946
|
+
rfc1034identifier: (value) => value.replaceAll(/[^A-Za-z0-9-]/gu, "-"),
|
|
947
|
+
upper: (value) => value.toUpperCase()
|
|
948
|
+
};
|
|
949
|
+
/**
|
|
950
|
+
* Whether a parsed operator names one of the supported transforms. The
|
|
951
|
+
* check is an own-property test, so document text like `toString` cannot
|
|
952
|
+
* reach the table's prototype.
|
|
953
|
+
*/
|
|
954
|
+
function isBuildSettingOperator(operator) {
|
|
955
|
+
return Object.hasOwn(OPERATOR_TRANSFORMS, operator);
|
|
956
|
+
}
|
|
957
|
+
/**
|
|
958
|
+
* Applies one operator to a resolved value, or returns `undefined` for
|
|
959
|
+
* operators outside {@link BuildSettingOperator}, which the caller turns
|
|
960
|
+
* into a verbatim reference.
|
|
961
|
+
*/
|
|
962
|
+
function applyOperator(operator, value) {
|
|
963
|
+
return isBuildSettingOperator(operator) ? OPERATOR_TRANSFORMS[operator](value) : void 0;
|
|
964
|
+
}
|
|
965
|
+
//#endregion
|
|
818
966
|
//#region src/model/isa.ts
|
|
819
967
|
/**
|
|
820
968
|
* Names and well-known values of the pbxproj object vocabulary.
|
|
@@ -3034,6 +3182,48 @@ var Target = class extends XcodeObject {
|
|
|
3034
3182
|
return (projectConfiguration == null ? void 0 : this.project.xcconfigSettingsOf(projectConfiguration))?.[key];
|
|
3035
3183
|
}
|
|
3036
3184
|
/**
|
|
3185
|
+
* Reads a build setting like {@link getBuildSetting} and expands the
|
|
3186
|
+
* `$(NAME)` and `${NAME}` references in it. Referenced settings resolve
|
|
3187
|
+
* through the same layering, `$(inherited)` and a setting referencing
|
|
3188
|
+
* itself continue from the next layer down the way Xcode composes
|
|
3189
|
+
* values, and `$(TARGET_NAME)` falls back to the target's name, so the
|
|
3190
|
+
* common `PRODUCT_NAME = "$(TARGET_NAME)"` resolves without any caller
|
|
3191
|
+
* setup.
|
|
3192
|
+
*
|
|
3193
|
+
* References the model cannot resolve (build-system paths like
|
|
3194
|
+
* `$(BUILT_PRODUCTS_DIR)`, environment values) stay in the result
|
|
3195
|
+
* verbatim unless the caller's lookup answers them, so no information
|
|
3196
|
+
* is invented. See {@link expandBuildSettingReferences} for the
|
|
3197
|
+
* operator forms honored during expansion.
|
|
3198
|
+
*/
|
|
3199
|
+
resolveBuildSetting(key, options) {
|
|
3200
|
+
const targetConfiguration = defaultConfigurationOf(this.project, this.getString("buildConfigurationList"));
|
|
3201
|
+
const projectConfiguration = defaultConfigurationOf(this.project, this.project.rootProject.getString("buildConfigurationList"));
|
|
3202
|
+
const layers = [
|
|
3203
|
+
asDictionary(targetConfiguration?.properties["buildSettings"]),
|
|
3204
|
+
targetConfiguration == null ? void 0 : this.project.xcconfigSettingsOf(targetConfiguration),
|
|
3205
|
+
asDictionary(projectConfiguration?.properties["buildSettings"]),
|
|
3206
|
+
projectConfiguration == null ? void 0 : this.project.xcconfigSettingsOf(projectConfiguration)
|
|
3207
|
+
];
|
|
3208
|
+
const resolve = (name, fromLayer, active) => {
|
|
3209
|
+
const guard = `${fromLayer}:${name}`;
|
|
3210
|
+
if (active.has(guard)) return;
|
|
3211
|
+
const nested = new Set(active);
|
|
3212
|
+
nested.add(guard);
|
|
3213
|
+
for (let layer = fromLayer; layer < layers.length; layer++) {
|
|
3214
|
+
const settings = layers[layer];
|
|
3215
|
+
if (settings == null || !(name in settings)) continue;
|
|
3216
|
+
const value = asString(settings[name]);
|
|
3217
|
+
if (value == null) return;
|
|
3218
|
+
return expandBuildSettingReferences(value, (reference) => {
|
|
3219
|
+
if (reference === "inherited" || reference === name) return resolve(name, layer + 1, nested) ?? "";
|
|
3220
|
+
return resolve(reference, 0, nested) ?? options?.lookup?.(reference) ?? builtinSetting(this, reference);
|
|
3221
|
+
}, { expandLookupValues: false });
|
|
3222
|
+
}
|
|
3223
|
+
};
|
|
3224
|
+
return resolve(key, 0, /* @__PURE__ */ new Set());
|
|
3225
|
+
}
|
|
3226
|
+
/**
|
|
3037
3227
|
* Writes a build setting on every configuration of the target, so Debug
|
|
3038
3228
|
* and Release stay consistent.
|
|
3039
3229
|
*/
|
|
@@ -3147,6 +3337,15 @@ var Target = class extends XcodeObject {
|
|
|
3147
3337
|
}
|
|
3148
3338
|
};
|
|
3149
3339
|
/**
|
|
3340
|
+
* The settings the build system defines from the target itself rather
|
|
3341
|
+
* than from the document. `TARGET_NAME` is the one programmatic reads
|
|
3342
|
+
* meet constantly, through the template's `PRODUCT_NAME` of
|
|
3343
|
+
* `$(TARGET_NAME)`.
|
|
3344
|
+
*/
|
|
3345
|
+
function builtinSetting(target, name) {
|
|
3346
|
+
return name === "TARGET_NAME" ? target.name : void 0;
|
|
3347
|
+
}
|
|
3348
|
+
/**
|
|
3150
3349
|
* A `PBXNativeTarget` is a product the project compiles and packages
|
|
3151
3350
|
* itself, such as an application or an app extension.
|
|
3152
3351
|
*/
|
|
@@ -5095,4 +5294,4 @@ var Xcconfig = class Xcconfig {
|
|
|
5095
5294
|
}
|
|
5096
5295
|
};
|
|
5097
5296
|
//#endregion
|
|
5098
|
-
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, Xcconfig, XcconfigParseError, XcodeModelError, XcodeObject, XcodeProject, Xcscheme, XcschemeBuildError, XcschemeParseError, buildPbxproj, buildXcconfig, buildXcscheme, createXcscheme, generateObjectId, isXcschemeElement, parseApplePlatform, parsePbxproj, parseXcconfig, parseXcscheme, xcschemeElements };
|
|
5297
|
+
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, Xcconfig, XcconfigParseError, XcodeModelError, XcodeObject, XcodeProject, Xcscheme, XcschemeBuildError, XcschemeParseError, buildPbxproj, buildXcconfig, buildXcscheme, createXcscheme, expandBuildSettingReferences, generateObjectId, isXcschemeElement, parseApplePlatform, parsePbxproj, parseXcconfig, parseXcscheme, xcschemeElements };
|
package/package.json
CHANGED