1interface pbxFile {
2  basename: string;
3  lastKnownFileType?: string;
4  group?: string;
5  path?: string;
6  fileEncoding?: number;
7  defaultEncoding?: number;
8  sourceTree: string;
9  includeInIndex?: number;
10  explicitFileType?: unknown;
11  settings?: object;
12  uuid?: string;
13  fileRef: string;
14  target?: string;
15}
16
17declare module 'xcode' {
18  /**
19   * UUID that is a key to each fragment of PBXProject.
20   */
21  type UUID = string;
22
23  /**
24   * if has following format `${UUID}_comment`
25   */
26  type UUIDComment = string;
27
28  type XCObjectType =
29    | 'PBXBuildFile'
30    | 'PBXFileReference'
31    | 'PBXFrameworksBuildPhase'
32    | 'PBXGroup'
33    | 'PBXNativeTarget'
34    | 'PBXProject'
35    | 'PBXResourcesBuildPhase'
36    | 'PBXShellScriptBuildPhase'
37    | 'PBXSourcesBuildPhase'
38    | 'PBXVariantGroup'
39    | 'PBXTargetDependency'
40    | 'XCBuildConfiguration'
41    | 'XCConfigurationList';
42
43  type PBXFile = pbxFile;
44
45  interface PBXProject {
46    isa: 'PBXProject';
47    attributes: {
48      LastUpgradeCheck: number;
49      TargetAttributes: Record<
50        UUID,
51        {
52          CreatedOnToolsVersion?: string;
53          TestTargetID?: UUID;
54          LastSwiftMigration?: number;
55          ProvisioningStyle?: string;
56        } & Record<string, undefined | number | string>
57      >;
58    };
59    buildConfigurationList: UUID;
60    buildConfigurationList_comment: string;
61    compatibilityVersion: string;
62    developmentRegion: string;
63    hasScannedForEncodings: number;
64    knownRegions: string[];
65    mainGroup: UUID;
66    productRefGroup: UUID;
67    productRefGroup_comment: string;
68    projectDirPath: string;
69    projectRoot: string;
70    targets: {
71      value: UUID;
72      comment: string;
73    }[];
74  }
75
76  interface PBXNativeTarget {
77    isa: 'PBXNativeTarget';
78    buildConfigurationList: UUID;
79    buildConfigurationList_comment: string;
80    buildPhases: {
81      value: UUID;
82      comment: string;
83    }[];
84    buildRules: [];
85    dependencies: {
86      value: UUID;
87      comment: string;
88    }[];
89    name: string;
90    productName: string;
91    productReference: UUID;
92    productReference_comment: string;
93    productType: string;
94  }
95
96  interface PBXBuildFile {
97    isa: 'PBXBuildFile';
98    fileRef: UUID;
99    // "AppDelegate.m"
100    fileRef_comment: string;
101  }
102
103  interface PBXTargetDependency {
104    isa: 'PBXTargetDependency';
105    target: UUID;
106    targetProxy: UUID;
107  }
108
109  interface XCConfigurationList {
110    isa: 'XCConfigurationList';
111    buildConfigurations: {
112      value: UUID;
113      comment: string | 'Release' | 'Debug';
114    }[];
115    defaultConfigurationIsVisible: number;
116    defaultConfigurationName: string;
117  }
118
119  interface XCBuildConfiguration {
120    isa: 'XCBuildConfiguration';
121    baseConfigurationReference: UUID;
122    baseConfigurationReference_comment: string;
123    buildSettings: Record<string, string | undefined | number | unknown[]> & {
124      // '"$(TARGET_NAME)"',
125      PRODUCT_NAME?: string;
126      // '"io.expo.demo.$(PRODUCT_NAME:rfc1034identifier)"',
127      PRODUCT_BUNDLE_IDENTIFIER?: string;
128      PROVISIONING_PROFILE_SPECIFIER?: string;
129      // '"$(BUILT_PRODUCTS_DIR)/rni.app/rni"'
130      TEST_HOST?: any;
131      DEVELOPMENT_TEAM?: string;
132      CODE_SIGN_IDENTITY?: string;
133      CODE_SIGN_STYLE?: string;
134      // '"$(TEST_HOST)"'
135      BUNDLE_LOADER?: string;
136      GCC_PREPROCESSOR_DEFINITIONS?: unknown[];
137      INFOPLIST_FILE?: string;
138      IPHONEOS_DEPLOYMENT_TARGET?: string;
139      LD_RUNPATH_SEARCH_PATHS?: string;
140      OTHER_LDFLAGS?: unknown[];
141      ASSETCATALOG_COMPILER_APPICON_NAME?: string;
142      ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME?: string;
143      CLANG_ANALYZER_NONNULL?: string;
144      CLANG_WARN_DOCUMENTATION_COMMENTS?: string;
145      CLANG_WARN_INFINITE_RECURSION?: string;
146      CLANG_WARN_SUSPICIOUS_MOVE?: string;
147      DEBUG_INFORMATION_FORMAT?: string;
148      ENABLE_TESTABILITY?: string;
149      GCC_NO_COMMON_BLOCKS?: string;
150      // 'appletvos'
151      SDKROOT?: string;
152      TARGETED_DEVICE_FAMILY?: number | string;
153      // '10.0'
154      TVOS_DEPLOYMENT_TARGET?: string;
155    };
156    name: string;
157  }
158
159  type ProductType =
160    | 'com.apple.product-type.application'
161    | 'com.apple.product-type.app-extension'
162    | 'com.apple.product-type.bundle'
163    | 'com.apple.product-type.tool'
164    | 'com.apple.product-type.library.dynamic'
165    | 'com.apple.product-type.framework'
166    | 'com.apple.product-type.library.static'
167    | 'com.apple.product-type.bundle.unit-test'
168    | 'com.apple.product-type.application.watchapp'
169    | 'com.apple.product-type.application.watchapp2'
170    | 'com.apple.product-type.watchkit-extension'
171    | 'com.apple.product-type.watchkit2-extension';
172
173  interface PBXGroup {
174    isa: 'PBXGroup';
175    children: {
176      value: UUID;
177      comment?: string;
178    }[];
179    name: string;
180    path?: string;
181    sourceTree: '"<group>"' | unknown;
182  }
183
184  export class XcodeProject {
185    constructor(pbxprojPath: string);
186
187    /**
188     * `.pbxproj` file path.
189     */
190    filepath: string;
191
192    // Ex: '$(TARGET_NAME)'
193    productName: string;
194
195    hash: {
196      headComment: string;
197      project: {
198        archiveVersion: number;
199        objectVersion: number;
200        objects: {
201          [T in XCObjectType]: Record<
202            string,
203            {
204              isa: T;
205              name: string;
206              [key: string]: any;
207            }
208          >;
209        };
210        rootObject: string;
211        rootObject_comment: string;
212      };
213    };
214
215    // ------------------------------------------------------------------------
216    //
217    // `.pbxproj` related operation - starting & ending point.
218    //
219    // ------------------------------------------------------------------------
220
221    /**
222     * First step to be executed while working with `.pbxproj` file.
223     */
224    parse(callback?: (err: Error | null, results?: string) => void): this;
225
226    parseSync(): void;
227
228    /**
229     * @returns Content of .pbxproj file.
230     */
231    writeSync(options?: { omitEmptyValues?: boolean }): string;
232
233    allUuids(): UUID[];
234    generateUuid(): UUID;
235
236    addPluginFile(path: unknown, opt: unknown): unknown;
237    removePluginFile(path: unknown, opt: unknown): unknown;
238    addProductFile(targetPath: unknown, opt: unknown): unknown;
239    removeProductFile(path: unknown, opt: unknown): unknown;
240    addSourceFile(path: string, opt: unknown, group: string): unknown;
241    removeSourceFile(path: string, opt: unknown, group: string): unknown;
242    addHeaderFile(path: string, opt: unknown, group: string): unknown;
243    removeHeaderFile(path: string, opt: unknown, group: string): unknown;
244    addResourceFile(path: string, opt: unknown, group: string): unknown;
245    removeResourceFile(path: string, opt: unknown, group: string): unknown;
246    addFramework(fpath: string, opt: unknown): unknown;
247    removeFramework(fpath: unknown, opt: unknown): unknown;
248    addCopyfile(fpath: unknown, opt: unknown): unknown;
249    pbxCopyfilesBuildPhaseObj(target: unknown): unknown;
250    addToPbxCopyfilesBuildPhase(file: unknown): void;
251    removeCopyfile(fpath: unknown, opt: unknown): unknown;
252    removeFromPbxCopyfilesBuildPhase(file: unknown): void;
253    addStaticLibrary(path: unknown, opt: unknown): unknown;
254    /**
255     * Adds to `PBXBuildFile` section
256     */
257    addToPbxBuildFileSection(file: PBXFile): void;
258    removeFromPbxBuildFileSection(file: unknown): void;
259    addPbxGroup(
260      filePathsArray: string[],
261      name: string,
262      path: string,
263      sourceTree?: string
264    ): { uuid: UUID; pbxGroup: PBXGroup };
265    removePbxGroup(groupName: unknown): void;
266    addToPbxProjectSection(target: unknown): void;
267    addToPbxNativeTargetSection(target: unknown): void;
268    addToPbxFileReferenceSection(file: any): void;
269    removeFromPbxFileReferenceSection(file: unknown): unknown;
270    addToXcVersionGroupSection(file: unknown): void;
271    addToPluginsPbxGroup(file: unknown): void;
272    removeFromPluginsPbxGroup(file: unknown): unknown;
273    addToResourcesPbxGroup(file: unknown): void;
274    removeFromResourcesPbxGroup(file: unknown): unknown;
275    addToFrameworksPbxGroup(file: unknown): void;
276    removeFromFrameworksPbxGroup(file: unknown): unknown;
277    addToPbxEmbedFrameworksBuildPhase(file: unknown): void;
278    removeFromPbxEmbedFrameworksBuildPhase(file: unknown): void;
279    addToProductsPbxGroup(file: unknown): void;
280    removeFromProductsPbxGroup(file: unknown): unknown;
281    addToPbxSourcesBuildPhase(file: unknown): void;
282    removeFromPbxSourcesBuildPhase(file: unknown): void;
283    /**
284     * Adds to PBXResourcesBuildPhase` section
285     * @param resourcesBuildPhaseSectionKey Because there's might more than one `Resources` build phase we need to ensure file is placed under correct one.
286     */
287    addToPbxResourcesBuildPhase(file: PBXFile): void;
288    removeFromPbxResourcesBuildPhase(file: unknown): void;
289    addToPbxFrameworksBuildPhase(file: unknown): void;
290    removeFromPbxFrameworksBuildPhase(file: unknown): void;
291    addXCConfigurationList(
292      configurationObjectsArray: unknown,
293      defaultConfigurationName: unknown,
294      comment: unknown
295    ): {
296      uuid: unknown;
297      xcConfigurationList: {
298        isa: string;
299        buildConfigurations: unknown[];
300        defaultConfigurationIsVisible: number;
301        defaultConfigurationName: unknown;
302      };
303    };
304    addTargetDependency(
305      target: unknown,
306      dependencyTargets: unknown
307    ): {
308      uuid: unknown;
309      target: unknown;
310    };
311    addBuildPhase(
312      filePathsArray: unknown,
313      buildPhaseType: unknown,
314      comment: unknown,
315      target: unknown,
316      optionsOrFolderType: unknown,
317      subfolderPath: unknown
318    ): {
319      uuid: unknown;
320      buildPhase: {
321        isa: unknown;
322        buildActionMask: number;
323        files: unknown[];
324        runOnlyForDeploymentPostprocessing: number;
325      };
326    };
327    /**
328     * Retrieves main part describing PBXProjects that are available in `.pbxproj` file.
329     */
330    pbxProjectSection(): Record<UUID, PBXProject> & Record<UUIDComment, string>;
331    pbxBuildFileSection(): Record<UUID, PBXBuildFile> & Record<UUIDComment, string>;
332    pbxXCBuildConfigurationSection(): Record<UUID, XCBuildConfiguration> &
333      Record<UUIDComment, string>;
334    pbxFileReferenceSection(): Record<UUID, PBXFile> & Record<UUIDComment, string>;
335    pbxNativeTargetSection(): Record<UUID, PBXNativeTarget> & Record<UUIDComment, string>;
336    xcVersionGroupSection(): unknown;
337    pbxXCConfigurationList(): Record<UUID, XCConfigurationList> & Record<UUIDComment, string>;
338    pbxGroupByName(name: string): PBXGroup | undefined;
339    /**
340     * @param targetName in most cases it's the name of the application
341     */
342    pbxTargetByName(targetName: string): PBXNativeTarget | undefined;
343    findTargetKey(name: string): string;
344    pbxItemByComment(name: string, pbxSectionName: XCObjectType): unknown;
345    pbxSourcesBuildPhaseObj(target: unknown): unknown;
346    pbxResourcesBuildPhaseObj(target: unknown): unknown;
347    pbxFrameworksBuildPhaseObj(target: unknown): unknown;
348    pbxEmbedFrameworksBuildPhaseObj(target: unknown): unknown;
349    buildPhase(group: unknown, target: unknown): string;
350    buildPhaseObject(name: string, group: unknown, target: unknown): unknown;
351    addBuildProperty(prop: unknown, value: unknown, buildName?: string): void;
352    removeBuildProperty(prop: unknown, build_name: unknown): void;
353    updateBuildProperty(prop: string, value: unknown, build: string): void;
354    updateProductName(name: string): void;
355    removeFromFrameworkSearchPaths(file: unknown): void;
356    addToFrameworkSearchPaths(file: unknown): void;
357    removeFromLibrarySearchPaths(file: unknown): void;
358    addToLibrarySearchPaths(file: unknown): void;
359    removeFromHeaderSearchPaths(file: unknown): void;
360    addToHeaderSearchPaths(file: unknown): void;
361    addToOtherLinkerFlags(flag: unknown): void;
362    removeFromOtherLinkerFlags(flag: unknown): void;
363    addToBuildSettings(buildSetting: unknown, value: unknown): void;
364    removeFromBuildSettings(buildSetting: unknown): void;
365    /**
366     * Checks whether there is a file with given `filePath` in the project.
367     */
368    hasFile(filePath): PBXFile | false;
369    addTarget(
370      name: unknown,
371      type: unknown,
372      subfolder: unknown
373    ): {
374      uuid: unknown;
375      pbxNativeTarget: {
376        isa: string;
377        name: string;
378        productName: string;
379        productReference: unknown;
380        productType: string;
381        buildConfigurationList: unknown;
382        buildPhases: unknown[];
383        buildRules: unknown[];
384        dependencies: unknown[];
385      };
386    };
387    /**
388     * Get First PBXProject that can be found in `.pbxproj` file.
389     */
390    getFirstProject(): { uuid: UUID; firstProject: PBXProject };
391    getFirstTarget(): {
392      uuid: UUID;
393      firstTarget: PBXNativeTarget;
394    };
395    /**
396     * Retrieves PBXNativeTarget by the type
397     */
398    getTarget(productType: ProductType): { uuid: UUID; target: PBXNativeTarget } | null;
399    addToPbxGroupType(file: unknown, groupKey: unknown, groupType: unknown): void;
400    addToPbxVariantGroup(file: unknown, groupKey: unknown): void;
401    addToPbxGroup(file: PBXFile, groupKey: UUID): void;
402    pbxCreateGroupWithType(name: unknown, pathName: unknown, groupType: unknown): unknown;
403    pbxCreateVariantGroup(name: unknown): unknown;
404    pbxCreateGroup(name: string, pathName: string): UUID;
405    removeFromPbxGroupAndType(file: unknown, groupKey: unknown, groupType: unknown): void;
406    removeFromPbxGroup(file: unknown, groupKey: unknown): void;
407    removeFromPbxVariantGroup(file: unknown, groupKey: unknown): void;
408    getPBXGroupByKeyAndType(key: unknown, groupType: unknown): unknown;
409    /**
410     * @param groupKey UUID.
411     */
412    getPBXGroupByKey(groupKey: string): PBXGroup | undefined;
413    getPBXVariantGroupByKey(key: unknown): unknown;
414    findPBXGroupKeyAndType(criteria: unknown, groupType: unknown): string;
415    /**
416     * @param criteria Params that should be used to locate desired PBXGroup.
417     */
418    findPBXGroupKey(criteria: { name?: string; path?: string }): UUID | undefined;
419    findPBXVariantGroupKey(criteria: unknown): string;
420    addLocalizationVariantGroup(
421      name: unknown
422    ): {
423      uuid: unknown;
424      fileRef: unknown;
425      basename: unknown;
426    };
427    addKnownRegion(name: string): void;
428    removeKnownRegion(name: string): void;
429    hasKnownRegion(name: string): boolean;
430    getPBXObject(name: string): unknown;
431    /**
432     * - creates `PBXFile`
433     * - adds to `PBXFileReference` section
434     * - adds to `PBXGroup` or `PBXVariantGroup` if applicable
435     * @returns `null` if file is already in `pbxproj`.
436     */
437    addFile(
438      path: string,
439      group?: string,
440      opt?: {
441        plugin?: string;
442        target?: string;
443        variantGroup?: string;
444        lastKnownFileType?: string;
445        defaultEncoding?: 4;
446        customFramework?: true;
447        explicitFileType?: number;
448        weak?: true;
449        compilerFLags?: string;
450        embed?: boolean;
451        sign?: boolean;
452      }
453    ): PBXFile | null;
454    removeFile(path: unknown, group: unknown, opt: unknown): unknown;
455    getBuildProperty(prop: unknown, build: unknown): unknown;
456    getBuildConfigByName(name: unknown): object;
457    addDataModelDocument(filePath: unknown, group: unknown, opt: unknown): unknown;
458    addTargetAttribute(prop: unknown, value: unknown, target: unknown): void;
459    removeTargetAttribute(prop: unknown, target: unknown): void;
460  }
461
462  export function project(projectPath: string): XcodeProject;
463}
464
465declare module 'xcode/lib/pbxFile' {
466  export default class PBXFile implements pbxFile {
467    constructor(file: string);
468    basename: string;
469    lastKnownFileType?: string;
470    group?: string;
471    path?: string;
472    fileEncoding?: number;
473    defaultEncoding?: number;
474    sourceTree: string;
475    includeInIndex?: number;
476    explicitFileType?: unknown;
477    settings?: object;
478    uuid?: string;
479    fileRef: string;
480    target?: string;
481  }
482}
483