@capgo/cli
Version:
A CLI to upload to capgo servers
118 lines (117 loc) • 5.4 kB
TypeScript
export type BundleIdSource = 'pbxproj-release' | 'pbxproj-debug' | 'pbxproj-fallback' | 'plist' | 'capacitor-config';
export interface BundleIdCandidate {
value: string;
source: BundleIdSource;
/** Short human-readable label for the picker, e.g. "project.pbxproj (Release)". */
label: string;
}
export interface DetectedBundleIds {
/** PRODUCT_BUNDLE_IDENTIFIER from project.pbxproj, preferring Release config. */
pbxproj: BundleIdCandidate | null;
/**
* The Debug-config PRODUCT_BUNDLE_IDENTIFIER from project.pbxproj, when a
* literal value exists. Exposed for the awareness note only — never used to
* gate. Null when no Debug-config literal value is present.
*/
debug: BundleIdCandidate | null;
/**
* Info.plist CFBundleIdentifier when it's a literal value (not the common
* `$(PRODUCT_BUNDLE_IDENTIFIER)` placeholder, which we drop because it
* adds nothing the pbxproj source doesn't already cover).
*/
plist: BundleIdCandidate | null;
/** capacitor.config.ts/json's appId — always present (it's a required arg). */
capacitor: BundleIdCandidate;
/**
* The best-guess Apple-side bundle ID, picked in priority order:
* pbxproj-release > pbxproj-fallback > plist > capacitor. Returned for
* convenience so callers don't have to re-implement the precedence.
*/
recommended: BundleIdCandidate;
/**
* True when the recommended value differs from capacitor.config.appId.
* Used by redirectIfMismatch to decide whether to adopt the Release id —
* when they match, capacitor.config.appId is already the build id.
*/
mismatch: boolean;
/**
* True only when BOTH a Release-config and a Debug-config literal bundle id
* were found AND they differ. Drives the "Debug ≠ Release" awareness note;
* never gates. False when either value is missing or they match.
*/
debugReleaseDiffer: boolean;
/**
* True when a Release-config PRODUCT_BUNDLE_IDENTIFIER was resolved from
* pbxproj. When false, the authoritative build ID could not be determined
* from Release and callers should warn/skip gating rather than gate on a
* Debug or plist fallback.
*/
releaseResolved: boolean;
/**
* Deduplicated, ordered list of candidates ready to render as Select
* options. Empty list is impossible (capacitor is always included).
*/
candidates: BundleIdCandidate[];
}
/**
* Parse `PRODUCT_BUNDLE_IDENTIFIER = "..."` lines from pbxproj content,
* returning the Release and Debug candidates separately.
*
* Release is authoritative: when ANY Release-config value exists, `release`
* is populated and `releaseResolved` is true. The Debug value (when present)
* is returned alongside via `debug` for the awareness note — it is never
* promoted to `release`.
*
* When no Release config exists, `release` is null and `releaseResolved` is
* false so callers can detect the no-Release case.
*/
export declare function parsePbxprojBundleIds(pbxprojContent: string): {
release: BundleIdCandidate | null;
debug: BundleIdCandidate | null;
releaseResolved: boolean;
};
/**
* Parse `PRODUCT_BUNDLE_IDENTIFIER = "..."` lines from pbxproj content.
* Returns the Release-config value if present, else the shortest non-Release
* value as a `pbxproj-fallback`. Returns null when no bundle id can be
* extracted.
*
* Release stays authoritative here: a Release value is never overridden by a
* Debug value. The no-Release fallback is preserved for backward
* compatibility — callers that need to distinguish "Release resolved" from
* "fell back to Debug" should use `parsePbxprojBundleIds` (or the
* `releaseResolved` flag on `detectIosBundleIds`).
*
* Looks like a re-implementation of pbxproj-parser.ts's resolveBundleId, but
* that one needs an XCConfigurationList id (it walks from a target). This
* one needs to work standalone given only the file contents — so it
* collects all PRODUCT_BUNDLE_IDENTIFIER values, groups by adjacent
* `name = Release`/`name = Debug` markers, and prefers Release. Less
* accurate for multi-target projects but good enough for the "what should
* we pre-fill" use case here.
*/
export declare function parsePbxprojBundleId(pbxprojContent: string): BundleIdCandidate | null;
/**
* Parse Info.plist's CFBundleIdentifier from raw XML.
* Returns null when the file is empty, when CFBundleIdentifier is absent,
* or when it's a `$(PRODUCT_BUNDLE_IDENTIFIER)` variable reference (we drop
* the placeholder so the picker doesn't list a non-actionable option).
*/
export declare function parseInfoPlistBundleId(plistContent: string): BundleIdCandidate | null;
/**
* Read project.pbxproj and Info.plist from the iOS dir and return all
* available bundle id candidates, plus the recommended one and a
* mismatch flag.
*
* Filesystem reads are best-effort — when either file is missing or
* unreadable, we silently skip that source. The capacitor candidate is
* always present.
*/
export declare function detectIosBundleIds(opts: {
/** Project root (typically `process.cwd()`). */
cwd: string;
/** Subdirectory under cwd holding the iOS project (typically "ios"). */
iosDir: string;
/** Bundle id read from capacitor.config.ts/json — always known. */
capacitorAppId: string;
}): DetectedBundleIds;