shiplint 0.1.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 +107 -0
- package/dist/cli/index.d.ts +3 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +101 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/core/index.d.ts +5 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js +21 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/scanner.d.ts +27 -0
- package/dist/core/scanner.d.ts.map +1 -0
- package/dist/core/scanner.js +104 -0
- package/dist/core/scanner.js.map +1 -0
- package/dist/formatters/index.d.ts +13 -0
- package/dist/formatters/index.d.ts.map +1 -0
- package/dist/formatters/index.js +29 -0
- package/dist/formatters/index.js.map +1 -0
- package/dist/formatters/json.d.ts +13 -0
- package/dist/formatters/json.d.ts.map +1 -0
- package/dist/formatters/json.js +17 -0
- package/dist/formatters/json.js.map +1 -0
- package/dist/formatters/sarif.d.ts +14 -0
- package/dist/formatters/sarif.d.ts.map +1 -0
- package/dist/formatters/sarif.js +108 -0
- package/dist/formatters/sarif.js.map +1 -0
- package/dist/formatters/text.d.ts +9 -0
- package/dist/formatters/text.d.ts.map +1 -0
- package/dist/formatters/text.js +128 -0
- package/dist/formatters/text.js.map +1 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +49 -0
- package/dist/index.js.map +1 -0
- package/dist/parsers/entitlements-parser.d.ts +26 -0
- package/dist/parsers/entitlements-parser.d.ts.map +1 -0
- package/dist/parsers/entitlements-parser.js +105 -0
- package/dist/parsers/entitlements-parser.js.map +1 -0
- package/dist/parsers/framework-detector.d.ts +76 -0
- package/dist/parsers/framework-detector.d.ts.map +1 -0
- package/dist/parsers/framework-detector.js +501 -0
- package/dist/parsers/framework-detector.js.map +1 -0
- package/dist/parsers/index.d.ts +10 -0
- package/dist/parsers/index.d.ts.map +1 -0
- package/dist/parsers/index.js +26 -0
- package/dist/parsers/index.js.map +1 -0
- package/dist/parsers/pbxproj-parser.d.ts +166 -0
- package/dist/parsers/pbxproj-parser.d.ts.map +1 -0
- package/dist/parsers/pbxproj-parser.js +423 -0
- package/dist/parsers/pbxproj-parser.js.map +1 -0
- package/dist/parsers/plist-parser.d.ts +26 -0
- package/dist/parsers/plist-parser.d.ts.map +1 -0
- package/dist/parsers/plist-parser.js +166 -0
- package/dist/parsers/plist-parser.js.map +1 -0
- package/dist/parsers/project-parser.d.ts +57 -0
- package/dist/parsers/project-parser.d.ts.map +1 -0
- package/dist/parsers/project-parser.js +618 -0
- package/dist/parsers/project-parser.js.map +1 -0
- package/dist/parsers/workspace-parser.d.ts +82 -0
- package/dist/parsers/workspace-parser.d.ts.map +1 -0
- package/dist/parsers/workspace-parser.js +287 -0
- package/dist/parsers/workspace-parser.js.map +1 -0
- package/dist/rules/auth/index.d.ts +5 -0
- package/dist/rules/auth/index.d.ts.map +1 -0
- package/dist/rules/auth/index.js +9 -0
- package/dist/rules/auth/index.js.map +1 -0
- package/dist/rules/auth/third-party-login-no-siwa.d.ts +11 -0
- package/dist/rules/auth/third-party-login-no-siwa.d.ts.map +1 -0
- package/dist/rules/auth/third-party-login-no-siwa.js +119 -0
- package/dist/rules/auth/third-party-login-no-siwa.js.map +1 -0
- package/dist/rules/base.d.ts +25 -0
- package/dist/rules/base.d.ts.map +1 -0
- package/dist/rules/base.js +37 -0
- package/dist/rules/base.js.map +1 -0
- package/dist/rules/config/ats-exception-without-justification.d.ts +12 -0
- package/dist/rules/config/ats-exception-without-justification.d.ts.map +1 -0
- package/dist/rules/config/ats-exception-without-justification.js +152 -0
- package/dist/rules/config/ats-exception-without-justification.js.map +1 -0
- package/dist/rules/config/index.d.ts +5 -0
- package/dist/rules/config/index.d.ts.map +1 -0
- package/dist/rules/config/index.js +9 -0
- package/dist/rules/config/index.js.map +1 -0
- package/dist/rules/index.d.ts +43 -0
- package/dist/rules/index.d.ts.map +1 -0
- package/dist/rules/index.js +103 -0
- package/dist/rules/index.js.map +1 -0
- package/dist/rules/metadata/index.d.ts +5 -0
- package/dist/rules/metadata/index.d.ts.map +1 -0
- package/dist/rules/metadata/index.js +9 -0
- package/dist/rules/metadata/index.js.map +1 -0
- package/dist/rules/metadata/missing-privacy-manifest.d.ts +12 -0
- package/dist/rules/metadata/missing-privacy-manifest.d.ts.map +1 -0
- package/dist/rules/metadata/missing-privacy-manifest.js +186 -0
- package/dist/rules/metadata/missing-privacy-manifest.js.map +1 -0
- package/dist/rules/privacy/att-tracking-mismatch.d.ts +12 -0
- package/dist/rules/privacy/att-tracking-mismatch.d.ts.map +1 -0
- package/dist/rules/privacy/att-tracking-mismatch.js +113 -0
- package/dist/rules/privacy/att-tracking-mismatch.js.map +1 -0
- package/dist/rules/privacy/index.d.ts +11 -0
- package/dist/rules/privacy/index.d.ts.map +1 -0
- package/dist/rules/privacy/index.js +21 -0
- package/dist/rules/privacy/index.js.map +1 -0
- package/dist/rules/privacy/location-always-unjustified.d.ts +11 -0
- package/dist/rules/privacy/location-always-unjustified.d.ts.map +1 -0
- package/dist/rules/privacy/location-always-unjustified.js +102 -0
- package/dist/rules/privacy/location-always-unjustified.js.map +1 -0
- package/dist/rules/privacy/missing-camera-purpose.d.ts +11 -0
- package/dist/rules/privacy/missing-camera-purpose.d.ts.map +1 -0
- package/dist/rules/privacy/missing-camera-purpose.js +83 -0
- package/dist/rules/privacy/missing-camera-purpose.js.map +1 -0
- package/dist/rules/privacy/missing-contacts-purpose.d.ts +11 -0
- package/dist/rules/privacy/missing-contacts-purpose.d.ts.map +1 -0
- package/dist/rules/privacy/missing-contacts-purpose.js +85 -0
- package/dist/rules/privacy/missing-contacts-purpose.js.map +1 -0
- package/dist/rules/privacy/missing-location-purpose.d.ts +12 -0
- package/dist/rules/privacy/missing-location-purpose.d.ts.map +1 -0
- package/dist/rules/privacy/missing-location-purpose.js +137 -0
- package/dist/rules/privacy/missing-location-purpose.js.map +1 -0
- package/dist/rules/privacy/missing-microphone-purpose.d.ts +11 -0
- package/dist/rules/privacy/missing-microphone-purpose.d.ts.map +1 -0
- package/dist/rules/privacy/missing-microphone-purpose.js +132 -0
- package/dist/rules/privacy/missing-microphone-purpose.js.map +1 -0
- package/dist/rules/privacy/missing-photo-library-purpose.d.ts +11 -0
- package/dist/rules/privacy/missing-photo-library-purpose.d.ts.map +1 -0
- package/dist/rules/privacy/missing-photo-library-purpose.js +102 -0
- package/dist/rules/privacy/missing-photo-library-purpose.js.map +1 -0
- package/dist/types/index.d.ts +140 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +59 -0
- package/dist/types/index.js.map +1 -0
- package/package.json +68 -0
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Product types in priority order (highest first)
|
|
3
|
+
*/
|
|
4
|
+
export declare enum ProductType {
|
|
5
|
+
Application = "com.apple.product-type.application",
|
|
6
|
+
ApplicationOnDemandInstall = "com.apple.product-type.application.on-demand-install-capable",
|
|
7
|
+
AppExtension = "com.apple.product-type.app-extension",
|
|
8
|
+
ExtensionKitExtension = "com.apple.product-type.extensionkit-extension",
|
|
9
|
+
WatchApp = "com.apple.product-type.application.watchapp2",
|
|
10
|
+
WatchExtension = "com.apple.product-type.watchkit2-extension",
|
|
11
|
+
TVExtension = "com.apple.product-type.tv-app-extension",
|
|
12
|
+
UnitTest = "com.apple.product-type.bundle.unit-test",
|
|
13
|
+
UITest = "com.apple.product-type.bundle.ui-testing",
|
|
14
|
+
Framework = "com.apple.product-type.framework",
|
|
15
|
+
StaticFramework = "com.apple.product-type.framework.static",
|
|
16
|
+
StaticLibrary = "com.apple.product-type.library.static",
|
|
17
|
+
DynamicLibrary = "com.apple.product-type.library.dynamic",
|
|
18
|
+
Bundle = "com.apple.product-type.bundle",
|
|
19
|
+
XPCService = "com.apple.product-type.xpc-service"
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* A native target parsed from pbxproj
|
|
23
|
+
*/
|
|
24
|
+
export interface PbxprojTarget {
|
|
25
|
+
/** The unique ID in the pbxproj (e.g., "ABC123DEF456") */
|
|
26
|
+
id: string;
|
|
27
|
+
/** Target name (e.g., "MyApp") */
|
|
28
|
+
name: string;
|
|
29
|
+
/** Product type (e.g., "com.apple.product-type.application") */
|
|
30
|
+
productType: string;
|
|
31
|
+
/** Reference to the build configuration list */
|
|
32
|
+
buildConfigurationListId: string;
|
|
33
|
+
/** Product name if specified */
|
|
34
|
+
productName?: string;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Build configuration parsed from pbxproj
|
|
38
|
+
*/
|
|
39
|
+
export interface PbxprojBuildConfig {
|
|
40
|
+
/** The unique ID */
|
|
41
|
+
id: string;
|
|
42
|
+
/** Config name (e.g., "Debug", "Release") */
|
|
43
|
+
name: string;
|
|
44
|
+
/** Raw build settings */
|
|
45
|
+
buildSettings: Record<string, string>;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Build configuration list parsed from pbxproj
|
|
49
|
+
*/
|
|
50
|
+
export interface PbxprojConfigList {
|
|
51
|
+
/** The unique ID */
|
|
52
|
+
id: string;
|
|
53
|
+
/** Config IDs in this list */
|
|
54
|
+
buildConfigurationIds: string[];
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Artifact paths extracted from build settings
|
|
58
|
+
*/
|
|
59
|
+
export interface TargetBuildSettings {
|
|
60
|
+
/** INFOPLIST_FILE path */
|
|
61
|
+
infoPlistPath?: string;
|
|
62
|
+
/** CODE_SIGN_ENTITLEMENTS path */
|
|
63
|
+
entitlementsPath?: string;
|
|
64
|
+
/** PRODUCT_NAME */
|
|
65
|
+
productName?: string;
|
|
66
|
+
/** TARGET_NAME */
|
|
67
|
+
targetName?: string;
|
|
68
|
+
/** The config name these came from */
|
|
69
|
+
configName?: string;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Parse all PBXNativeTarget entries from pbxproj content
|
|
73
|
+
*
|
|
74
|
+
* @param content The raw pbxproj file content
|
|
75
|
+
* @returns Array of parsed targets
|
|
76
|
+
*/
|
|
77
|
+
export declare function parsePbxprojTargets(content: string): PbxprojTarget[];
|
|
78
|
+
/**
|
|
79
|
+
* Get the priority score for a product type
|
|
80
|
+
* Higher = better candidate for main app
|
|
81
|
+
*/
|
|
82
|
+
export declare function getProductTypePriority(productType: string): number;
|
|
83
|
+
/**
|
|
84
|
+
* Check if a product type is an application
|
|
85
|
+
*/
|
|
86
|
+
export declare function isApplicationType(productType: string): boolean;
|
|
87
|
+
/**
|
|
88
|
+
* Check if a product type is a test target
|
|
89
|
+
*/
|
|
90
|
+
export declare function isTestType(productType: string): boolean;
|
|
91
|
+
/**
|
|
92
|
+
* Get the main app target from a list of targets
|
|
93
|
+
*
|
|
94
|
+
* Selection criteria:
|
|
95
|
+
* 1. Product type priority (application > extension > test)
|
|
96
|
+
* 2. Name matching project name (tie-breaker)
|
|
97
|
+
* 3. First in list (final fallback)
|
|
98
|
+
*
|
|
99
|
+
* @param targets List of parsed targets
|
|
100
|
+
* @param projectName Optional project name for name-matching tie-breaker
|
|
101
|
+
* @returns The best target, or undefined if no targets
|
|
102
|
+
*/
|
|
103
|
+
export declare function getMainAppTarget(targets: PbxprojTarget[], projectName?: string): PbxprojTarget | undefined;
|
|
104
|
+
/**
|
|
105
|
+
* Parse XCBuildConfiguration entries from pbxproj content
|
|
106
|
+
*
|
|
107
|
+
* @param content The raw pbxproj file content
|
|
108
|
+
* @returns Map of config ID to config object
|
|
109
|
+
*/
|
|
110
|
+
export declare function parseBuildConfigurations(content: string): Map<string, PbxprojBuildConfig>;
|
|
111
|
+
/**
|
|
112
|
+
* Parse XCConfigurationList entries from pbxproj content
|
|
113
|
+
*
|
|
114
|
+
* @param content The raw pbxproj file content
|
|
115
|
+
* @returns Map of list ID to list object
|
|
116
|
+
*/
|
|
117
|
+
export declare function parseConfigurationLists(content: string): Map<string, PbxprojConfigList>;
|
|
118
|
+
/**
|
|
119
|
+
* Get build settings for a specific target
|
|
120
|
+
*
|
|
121
|
+
* @param content The raw pbxproj file content
|
|
122
|
+
* @param target The target to get settings for
|
|
123
|
+
* @param preferRelease Whether to prefer Release config (default true)
|
|
124
|
+
* @returns Build settings with artifact paths
|
|
125
|
+
*/
|
|
126
|
+
export declare function getTargetBuildSettings(content: string, target: PbxprojTarget, preferRelease?: boolean): TargetBuildSettings;
|
|
127
|
+
/**
|
|
128
|
+
* Normalize a path by expanding Xcode variables
|
|
129
|
+
*
|
|
130
|
+
* @param rawPath The path with potential variables
|
|
131
|
+
* @param context Variable substitution context
|
|
132
|
+
* @returns Normalized path
|
|
133
|
+
*/
|
|
134
|
+
export declare function normalizeXcodePath(rawPath: string, context?: {
|
|
135
|
+
srcRoot?: string;
|
|
136
|
+
projectDir?: string;
|
|
137
|
+
targetName?: string;
|
|
138
|
+
productName?: string;
|
|
139
|
+
}): string;
|
|
140
|
+
/**
|
|
141
|
+
* Get the main app target's build settings with normalized paths
|
|
142
|
+
*
|
|
143
|
+
* This is the main entry point for P1/P2 fix.
|
|
144
|
+
*
|
|
145
|
+
* @param content The raw pbxproj file content
|
|
146
|
+
* @param projectName Optional project name for target selection
|
|
147
|
+
* @param projectDir Directory containing the project (for path resolution)
|
|
148
|
+
* @returns Target info and normalized artifact paths
|
|
149
|
+
*/
|
|
150
|
+
export declare function getMainTargetArtifacts(content: string, projectName?: string, projectDir?: string): {
|
|
151
|
+
target?: PbxprojTarget;
|
|
152
|
+
settings: TargetBuildSettings;
|
|
153
|
+
infoPlistPath?: string;
|
|
154
|
+
entitlementsPath?: string;
|
|
155
|
+
};
|
|
156
|
+
/**
|
|
157
|
+
* Get the product type of the main target in a project
|
|
158
|
+
*
|
|
159
|
+
* Useful for workspace-level scoring.
|
|
160
|
+
*
|
|
161
|
+
* @param content The raw pbxproj file content
|
|
162
|
+
* @param projectName Optional project name
|
|
163
|
+
* @returns Product type string, or undefined if no target found
|
|
164
|
+
*/
|
|
165
|
+
export declare function getMainTargetProductType(content: string, projectName?: string): string | undefined;
|
|
166
|
+
//# sourceMappingURL=pbxproj-parser.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pbxproj-parser.d.ts","sourceRoot":"","sources":["../../src/parsers/pbxproj-parser.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,423 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.ProductType = void 0;
|
|
37
|
+
exports.parsePbxprojTargets = parsePbxprojTargets;
|
|
38
|
+
exports.getProductTypePriority = getProductTypePriority;
|
|
39
|
+
exports.isApplicationType = isApplicationType;
|
|
40
|
+
exports.isTestType = isTestType;
|
|
41
|
+
exports.getMainAppTarget = getMainAppTarget;
|
|
42
|
+
exports.parseBuildConfigurations = parseBuildConfigurations;
|
|
43
|
+
exports.parseConfigurationLists = parseConfigurationLists;
|
|
44
|
+
exports.getTargetBuildSettings = getTargetBuildSettings;
|
|
45
|
+
exports.normalizeXcodePath = normalizeXcodePath;
|
|
46
|
+
exports.getMainTargetArtifacts = getMainTargetArtifacts;
|
|
47
|
+
exports.getMainTargetProductType = getMainTargetProductType;
|
|
48
|
+
/**
|
|
49
|
+
* Parser for Xcode project.pbxproj files
|
|
50
|
+
*
|
|
51
|
+
* P1/P2 Fix: Parses the target graph to correctly identify the main app target
|
|
52
|
+
* instead of relying on first-match or name-based heuristics.
|
|
53
|
+
*
|
|
54
|
+
* Key insight: productType is the reliable way to distinguish:
|
|
55
|
+
* - com.apple.product-type.application (iOS/macOS app)
|
|
56
|
+
* - com.apple.product-type.app-extension (extensions)
|
|
57
|
+
* - com.apple.product-type.bundle.unit-test (unit tests)
|
|
58
|
+
* - com.apple.product-type.bundle.ui-testing (UI tests)
|
|
59
|
+
* - com.apple.product-type.framework (frameworks)
|
|
60
|
+
*/
|
|
61
|
+
const path = __importStar(require("path"));
|
|
62
|
+
/**
|
|
63
|
+
* Product types in priority order (highest first)
|
|
64
|
+
*/
|
|
65
|
+
var ProductType;
|
|
66
|
+
(function (ProductType) {
|
|
67
|
+
ProductType["Application"] = "com.apple.product-type.application";
|
|
68
|
+
ProductType["ApplicationOnDemandInstall"] = "com.apple.product-type.application.on-demand-install-capable";
|
|
69
|
+
ProductType["AppExtension"] = "com.apple.product-type.app-extension";
|
|
70
|
+
ProductType["ExtensionKitExtension"] = "com.apple.product-type.extensionkit-extension";
|
|
71
|
+
ProductType["WatchApp"] = "com.apple.product-type.application.watchapp2";
|
|
72
|
+
ProductType["WatchExtension"] = "com.apple.product-type.watchkit2-extension";
|
|
73
|
+
ProductType["TVExtension"] = "com.apple.product-type.tv-app-extension";
|
|
74
|
+
ProductType["UnitTest"] = "com.apple.product-type.bundle.unit-test";
|
|
75
|
+
ProductType["UITest"] = "com.apple.product-type.bundle.ui-testing";
|
|
76
|
+
ProductType["Framework"] = "com.apple.product-type.framework";
|
|
77
|
+
ProductType["StaticFramework"] = "com.apple.product-type.framework.static";
|
|
78
|
+
ProductType["StaticLibrary"] = "com.apple.product-type.library.static";
|
|
79
|
+
ProductType["DynamicLibrary"] = "com.apple.product-type.library.dynamic";
|
|
80
|
+
ProductType["Bundle"] = "com.apple.product-type.bundle";
|
|
81
|
+
ProductType["XPCService"] = "com.apple.product-type.xpc-service";
|
|
82
|
+
})(ProductType || (exports.ProductType = ProductType = {}));
|
|
83
|
+
/**
|
|
84
|
+
* Product type priority for target selection
|
|
85
|
+
* Higher number = higher priority = prefer this target
|
|
86
|
+
*/
|
|
87
|
+
const PRODUCT_TYPE_PRIORITY = {
|
|
88
|
+
[ProductType.Application]: 100,
|
|
89
|
+
[ProductType.ApplicationOnDemandInstall]: 95, // App Clip
|
|
90
|
+
[ProductType.WatchApp]: 50, // Watch app is secondary
|
|
91
|
+
[ProductType.AppExtension]: 30,
|
|
92
|
+
[ProductType.ExtensionKitExtension]: 30,
|
|
93
|
+
[ProductType.WatchExtension]: 25,
|
|
94
|
+
[ProductType.TVExtension]: 25,
|
|
95
|
+
[ProductType.Framework]: 20,
|
|
96
|
+
[ProductType.StaticFramework]: 20,
|
|
97
|
+
[ProductType.StaticLibrary]: 15,
|
|
98
|
+
[ProductType.DynamicLibrary]: 15,
|
|
99
|
+
[ProductType.Bundle]: 10,
|
|
100
|
+
[ProductType.XPCService]: 10,
|
|
101
|
+
[ProductType.UnitTest]: 5,
|
|
102
|
+
[ProductType.UITest]: 5,
|
|
103
|
+
};
|
|
104
|
+
/**
|
|
105
|
+
* Parse all PBXNativeTarget entries from pbxproj content
|
|
106
|
+
*
|
|
107
|
+
* @param content The raw pbxproj file content
|
|
108
|
+
* @returns Array of parsed targets
|
|
109
|
+
*/
|
|
110
|
+
function parsePbxprojTargets(content) {
|
|
111
|
+
const targets = [];
|
|
112
|
+
// Match PBXNativeTarget section entries
|
|
113
|
+
// Format: ID /* Name */ = { isa = PBXNativeTarget; ... };
|
|
114
|
+
// This regex captures the full target block
|
|
115
|
+
const targetRegex = /([A-Fa-f0-9]{24})\s*\/\*\s*([^*]+?)\s*\*\/\s*=\s*\{([^}]*isa\s*=\s*PBXNativeTarget[^}]*(?:\{[^}]*\}[^}]*)*)\};/g;
|
|
116
|
+
let match;
|
|
117
|
+
while ((match = targetRegex.exec(content)) !== null) {
|
|
118
|
+
const id = match[1];
|
|
119
|
+
const name = match[2].trim();
|
|
120
|
+
const block = match[3];
|
|
121
|
+
// Extract productType
|
|
122
|
+
const productTypeMatch = block.match(/productType\s*=\s*"([^"]+)"/);
|
|
123
|
+
const productType = productTypeMatch ? productTypeMatch[1] : '';
|
|
124
|
+
// Extract buildConfigurationList
|
|
125
|
+
const configListMatch = block.match(/buildConfigurationList\s*=\s*([A-Fa-f0-9]{24})/);
|
|
126
|
+
const buildConfigurationListId = configListMatch ? configListMatch[1] : '';
|
|
127
|
+
// Extract productName if present
|
|
128
|
+
const productNameMatch = block.match(/productName\s*=\s*"?([^";]+)"?\s*;/);
|
|
129
|
+
const productName = productNameMatch ? productNameMatch[1].trim() : undefined;
|
|
130
|
+
if (productType) {
|
|
131
|
+
targets.push({
|
|
132
|
+
id,
|
|
133
|
+
name,
|
|
134
|
+
productType,
|
|
135
|
+
buildConfigurationListId,
|
|
136
|
+
productName,
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
return targets;
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Get the priority score for a product type
|
|
144
|
+
* Higher = better candidate for main app
|
|
145
|
+
*/
|
|
146
|
+
function getProductTypePriority(productType) {
|
|
147
|
+
return PRODUCT_TYPE_PRIORITY[productType] ?? 0;
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Check if a product type is an application
|
|
151
|
+
*/
|
|
152
|
+
function isApplicationType(productType) {
|
|
153
|
+
return productType === ProductType.Application ||
|
|
154
|
+
productType === ProductType.ApplicationOnDemandInstall;
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* Check if a product type is a test target
|
|
158
|
+
*/
|
|
159
|
+
function isTestType(productType) {
|
|
160
|
+
return productType === ProductType.UnitTest ||
|
|
161
|
+
productType === ProductType.UITest;
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* Get the main app target from a list of targets
|
|
165
|
+
*
|
|
166
|
+
* Selection criteria:
|
|
167
|
+
* 1. Product type priority (application > extension > test)
|
|
168
|
+
* 2. Name matching project name (tie-breaker)
|
|
169
|
+
* 3. First in list (final fallback)
|
|
170
|
+
*
|
|
171
|
+
* @param targets List of parsed targets
|
|
172
|
+
* @param projectName Optional project name for name-matching tie-breaker
|
|
173
|
+
* @returns The best target, or undefined if no targets
|
|
174
|
+
*/
|
|
175
|
+
function getMainAppTarget(targets, projectName) {
|
|
176
|
+
if (targets.length === 0) {
|
|
177
|
+
return undefined;
|
|
178
|
+
}
|
|
179
|
+
// Sort by priority (highest first), then by name match
|
|
180
|
+
const sorted = [...targets].sort((a, b) => {
|
|
181
|
+
const priorityA = getProductTypePriority(a.productType);
|
|
182
|
+
const priorityB = getProductTypePriority(b.productType);
|
|
183
|
+
// Primary sort: product type priority
|
|
184
|
+
if (priorityA !== priorityB) {
|
|
185
|
+
return priorityB - priorityA;
|
|
186
|
+
}
|
|
187
|
+
// Secondary sort: name matching project name
|
|
188
|
+
if (projectName) {
|
|
189
|
+
const normalizedProject = projectName.toLowerCase().replace(/[^a-z0-9]/g, '');
|
|
190
|
+
const normalizedA = a.name.toLowerCase().replace(/[^a-z0-9]/g, '');
|
|
191
|
+
const normalizedB = b.name.toLowerCase().replace(/[^a-z0-9]/g, '');
|
|
192
|
+
const matchA = normalizedA.includes(normalizedProject) || normalizedProject.includes(normalizedA);
|
|
193
|
+
const matchB = normalizedB.includes(normalizedProject) || normalizedProject.includes(normalizedB);
|
|
194
|
+
if (matchA && !matchB)
|
|
195
|
+
return -1;
|
|
196
|
+
if (matchB && !matchA)
|
|
197
|
+
return 1;
|
|
198
|
+
}
|
|
199
|
+
// Tertiary: prefer shorter names (less likely to be "MyAppTests", "MyAppUITests")
|
|
200
|
+
return a.name.length - b.name.length;
|
|
201
|
+
});
|
|
202
|
+
return sorted[0];
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* Parse XCBuildConfiguration entries from pbxproj content
|
|
206
|
+
*
|
|
207
|
+
* @param content The raw pbxproj file content
|
|
208
|
+
* @returns Map of config ID to config object
|
|
209
|
+
*/
|
|
210
|
+
function parseBuildConfigurations(content) {
|
|
211
|
+
const configs = new Map();
|
|
212
|
+
// Match XCBuildConfiguration entries
|
|
213
|
+
// Format: ID /* Name */ = { isa = XCBuildConfiguration; buildSettings = { ... }; name = Name; };
|
|
214
|
+
const configRegex = /([A-Fa-f0-9]{24})\s*\/\*\s*([^*]+?)\s*\*\/\s*=\s*\{[^}]*isa\s*=\s*XCBuildConfiguration[^}]*buildSettings\s*=\s*\{([^}]*)\}[^}]*name\s*=\s*"?([^";]+)"?\s*;[^}]*\};/g;
|
|
215
|
+
let match;
|
|
216
|
+
while ((match = configRegex.exec(content)) !== null) {
|
|
217
|
+
const id = match[1];
|
|
218
|
+
// match[2] is the comment name (unused)
|
|
219
|
+
const settingsBlock = match[3];
|
|
220
|
+
const name = match[4].trim();
|
|
221
|
+
// Parse build settings
|
|
222
|
+
const buildSettings = {};
|
|
223
|
+
const settingRegex = /(\w+)\s*=\s*"?([^";]+)"?\s*;/g;
|
|
224
|
+
let settingMatch;
|
|
225
|
+
while ((settingMatch = settingRegex.exec(settingsBlock)) !== null) {
|
|
226
|
+
buildSettings[settingMatch[1]] = settingMatch[2].trim();
|
|
227
|
+
}
|
|
228
|
+
configs.set(id, {
|
|
229
|
+
id,
|
|
230
|
+
name,
|
|
231
|
+
buildSettings,
|
|
232
|
+
});
|
|
233
|
+
}
|
|
234
|
+
return configs;
|
|
235
|
+
}
|
|
236
|
+
/**
|
|
237
|
+
* Parse XCConfigurationList entries from pbxproj content
|
|
238
|
+
*
|
|
239
|
+
* @param content The raw pbxproj file content
|
|
240
|
+
* @returns Map of list ID to list object
|
|
241
|
+
*/
|
|
242
|
+
function parseConfigurationLists(content) {
|
|
243
|
+
const lists = new Map();
|
|
244
|
+
// Match XCConfigurationList entries
|
|
245
|
+
// Format: ID /* ... */ = { isa = XCConfigurationList; buildConfigurations = ( ID1, ID2, ); ... };
|
|
246
|
+
const listRegex = /([A-Fa-f0-9]{24})\s*\/\*[^*]*\*\/\s*=\s*\{[^}]*isa\s*=\s*XCConfigurationList[^}]*buildConfigurations\s*=\s*\(([^)]+)\)/g;
|
|
247
|
+
let match;
|
|
248
|
+
while ((match = listRegex.exec(content)) !== null) {
|
|
249
|
+
const id = match[1];
|
|
250
|
+
const configsBlock = match[2];
|
|
251
|
+
// Extract config IDs
|
|
252
|
+
const configIds = [];
|
|
253
|
+
const idRegex = /([A-Fa-f0-9]{24})/g;
|
|
254
|
+
let idMatch;
|
|
255
|
+
while ((idMatch = idRegex.exec(configsBlock)) !== null) {
|
|
256
|
+
configIds.push(idMatch[1]);
|
|
257
|
+
}
|
|
258
|
+
lists.set(id, {
|
|
259
|
+
id,
|
|
260
|
+
buildConfigurationIds: configIds,
|
|
261
|
+
});
|
|
262
|
+
}
|
|
263
|
+
return lists;
|
|
264
|
+
}
|
|
265
|
+
/**
|
|
266
|
+
* Get build settings for a specific target
|
|
267
|
+
*
|
|
268
|
+
* @param content The raw pbxproj file content
|
|
269
|
+
* @param target The target to get settings for
|
|
270
|
+
* @param preferRelease Whether to prefer Release config (default true)
|
|
271
|
+
* @returns Build settings with artifact paths
|
|
272
|
+
*/
|
|
273
|
+
function getTargetBuildSettings(content, target, preferRelease = true) {
|
|
274
|
+
const result = {
|
|
275
|
+
targetName: target.name,
|
|
276
|
+
productName: target.productName,
|
|
277
|
+
};
|
|
278
|
+
if (!target.buildConfigurationListId) {
|
|
279
|
+
return result;
|
|
280
|
+
}
|
|
281
|
+
const configLists = parseConfigurationLists(content);
|
|
282
|
+
const configs = parseBuildConfigurations(content);
|
|
283
|
+
const configList = configLists.get(target.buildConfigurationListId);
|
|
284
|
+
if (!configList) {
|
|
285
|
+
return result;
|
|
286
|
+
}
|
|
287
|
+
// Find the preferred config (Release > Debug > first available)
|
|
288
|
+
let selectedConfig;
|
|
289
|
+
for (const configId of configList.buildConfigurationIds) {
|
|
290
|
+
const config = configs.get(configId);
|
|
291
|
+
if (!config)
|
|
292
|
+
continue;
|
|
293
|
+
const configNameLower = config.name.toLowerCase();
|
|
294
|
+
if (preferRelease && configNameLower === 'release') {
|
|
295
|
+
selectedConfig = config;
|
|
296
|
+
break;
|
|
297
|
+
}
|
|
298
|
+
else if (configNameLower === 'debug') {
|
|
299
|
+
if (!selectedConfig || !preferRelease) {
|
|
300
|
+
selectedConfig = config;
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
else if (!selectedConfig) {
|
|
304
|
+
selectedConfig = config;
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
if (!selectedConfig) {
|
|
308
|
+
return result;
|
|
309
|
+
}
|
|
310
|
+
result.configName = selectedConfig.name;
|
|
311
|
+
// Extract artifact paths
|
|
312
|
+
const settings = selectedConfig.buildSettings;
|
|
313
|
+
if (settings.INFOPLIST_FILE) {
|
|
314
|
+
result.infoPlistPath = settings.INFOPLIST_FILE;
|
|
315
|
+
}
|
|
316
|
+
if (settings.CODE_SIGN_ENTITLEMENTS) {
|
|
317
|
+
result.entitlementsPath = settings.CODE_SIGN_ENTITLEMENTS;
|
|
318
|
+
}
|
|
319
|
+
if (settings.PRODUCT_NAME) {
|
|
320
|
+
result.productName = settings.PRODUCT_NAME;
|
|
321
|
+
}
|
|
322
|
+
return result;
|
|
323
|
+
}
|
|
324
|
+
/**
|
|
325
|
+
* Normalize a path by expanding Xcode variables
|
|
326
|
+
*
|
|
327
|
+
* @param rawPath The path with potential variables
|
|
328
|
+
* @param context Variable substitution context
|
|
329
|
+
* @returns Normalized path
|
|
330
|
+
*/
|
|
331
|
+
function normalizeXcodePath(rawPath, context = {}) {
|
|
332
|
+
let result = rawPath;
|
|
333
|
+
// Strip surrounding quotes (e.g., "My App/Info.plist" -> My App/Info.plist)
|
|
334
|
+
if ((result.startsWith('"') && result.endsWith('"')) ||
|
|
335
|
+
(result.startsWith("'") && result.endsWith("'"))) {
|
|
336
|
+
result = result.slice(1, -1);
|
|
337
|
+
}
|
|
338
|
+
// Iteratively expand variables until no more $() or ${} patterns remain
|
|
339
|
+
// This handles nested variables like $(PRODUCT_NAME) -> $(TARGET_NAME) -> actual value
|
|
340
|
+
const maxIterations = 10; // Prevent infinite loops
|
|
341
|
+
for (let i = 0; i < maxIterations; i++) {
|
|
342
|
+
const before = result;
|
|
343
|
+
// Remove $(SRCROOT)/ or ${SRCROOT}/
|
|
344
|
+
result = result.replace(/\$[({]SRCROOT[)}]\/?/g, '');
|
|
345
|
+
// Remove $(PROJECT_DIR)/ or ${PROJECT_DIR}/
|
|
346
|
+
result = result.replace(/\$[({]PROJECT_DIR[)}]\/?/g, '');
|
|
347
|
+
// Replace $(TARGET_NAME) or ${TARGET_NAME}
|
|
348
|
+
if (context.targetName) {
|
|
349
|
+
result = result.replace(/\$[({]TARGET_NAME[)}]/g, context.targetName);
|
|
350
|
+
}
|
|
351
|
+
// Replace $(PRODUCT_NAME) or ${PRODUCT_NAME}
|
|
352
|
+
if (context.productName) {
|
|
353
|
+
result = result.replace(/\$[({]PRODUCT_NAME[)}]/g, context.productName);
|
|
354
|
+
}
|
|
355
|
+
// Replace $(inherited) - usually in arrays, remove it
|
|
356
|
+
result = result.replace(/\$[({]inherited[)}]/g, '');
|
|
357
|
+
// If no changes were made, we're done
|
|
358
|
+
if (result === before) {
|
|
359
|
+
break;
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
// Clean up any double slashes
|
|
363
|
+
result = result.replace(/\/\//g, '/');
|
|
364
|
+
// Remove leading slash if we stripped $(SRCROOT)
|
|
365
|
+
if (result.startsWith('/') && !rawPath.startsWith('/')) {
|
|
366
|
+
result = result.substring(1);
|
|
367
|
+
}
|
|
368
|
+
return result.trim();
|
|
369
|
+
}
|
|
370
|
+
/**
|
|
371
|
+
* Get the main app target's build settings with normalized paths
|
|
372
|
+
*
|
|
373
|
+
* This is the main entry point for P1/P2 fix.
|
|
374
|
+
*
|
|
375
|
+
* @param content The raw pbxproj file content
|
|
376
|
+
* @param projectName Optional project name for target selection
|
|
377
|
+
* @param projectDir Directory containing the project (for path resolution)
|
|
378
|
+
* @returns Target info and normalized artifact paths
|
|
379
|
+
*/
|
|
380
|
+
function getMainTargetArtifacts(content, projectName, projectDir) {
|
|
381
|
+
const targets = parsePbxprojTargets(content);
|
|
382
|
+
const target = getMainAppTarget(targets, projectName);
|
|
383
|
+
if (!target) {
|
|
384
|
+
return { settings: {} };
|
|
385
|
+
}
|
|
386
|
+
const settings = getTargetBuildSettings(content, target);
|
|
387
|
+
// Normalize paths
|
|
388
|
+
const context = {
|
|
389
|
+
targetName: settings.targetName || target.name,
|
|
390
|
+
productName: settings.productName || target.productName,
|
|
391
|
+
};
|
|
392
|
+
let infoPlistPath;
|
|
393
|
+
let entitlementsPath;
|
|
394
|
+
if (settings.infoPlistPath) {
|
|
395
|
+
const normalized = normalizeXcodePath(settings.infoPlistPath, context);
|
|
396
|
+
infoPlistPath = projectDir ? path.resolve(projectDir, normalized) : normalized;
|
|
397
|
+
}
|
|
398
|
+
if (settings.entitlementsPath) {
|
|
399
|
+
const normalized = normalizeXcodePath(settings.entitlementsPath, context);
|
|
400
|
+
entitlementsPath = projectDir ? path.resolve(projectDir, normalized) : normalized;
|
|
401
|
+
}
|
|
402
|
+
return {
|
|
403
|
+
target,
|
|
404
|
+
settings,
|
|
405
|
+
infoPlistPath,
|
|
406
|
+
entitlementsPath,
|
|
407
|
+
};
|
|
408
|
+
}
|
|
409
|
+
/**
|
|
410
|
+
* Get the product type of the main target in a project
|
|
411
|
+
*
|
|
412
|
+
* Useful for workspace-level scoring.
|
|
413
|
+
*
|
|
414
|
+
* @param content The raw pbxproj file content
|
|
415
|
+
* @param projectName Optional project name
|
|
416
|
+
* @returns Product type string, or undefined if no target found
|
|
417
|
+
*/
|
|
418
|
+
function getMainTargetProductType(content, projectName) {
|
|
419
|
+
const targets = parsePbxprojTargets(content);
|
|
420
|
+
const target = getMainAppTarget(targets, projectName);
|
|
421
|
+
return target?.productType;
|
|
422
|
+
}
|
|
423
|
+
//# sourceMappingURL=pbxproj-parser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pbxproj-parser.js","sourceRoot":"","sources":["../../src/parsers/pbxproj-parser.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { ParsedInfoPlist } from '../types/index.js';
|
|
2
|
+
/**
|
|
3
|
+
* Parses an Info.plist file at the given path
|
|
4
|
+
*/
|
|
5
|
+
export declare function parsePlist(filePath: string): Record<string, unknown>;
|
|
6
|
+
/**
|
|
7
|
+
* Parses Info.plist from a string
|
|
8
|
+
*/
|
|
9
|
+
export declare function parsePlistString(content: string): Record<string, unknown>;
|
|
10
|
+
/**
|
|
11
|
+
* Parses Info.plist and returns structured data
|
|
12
|
+
*/
|
|
13
|
+
export declare function parseStructuredPlist(filePath: string): ParsedInfoPlist;
|
|
14
|
+
/**
|
|
15
|
+
* Converts raw plist dict to structured format
|
|
16
|
+
*/
|
|
17
|
+
export declare function structurePlistData(raw: Record<string, unknown>): ParsedInfoPlist;
|
|
18
|
+
/**
|
|
19
|
+
* Known usage description keys and their associated frameworks
|
|
20
|
+
*/
|
|
21
|
+
export declare const knownUsageDescriptionKeys: Record<string, string[]>;
|
|
22
|
+
/**
|
|
23
|
+
* Checks if a usage description appears to be a placeholder
|
|
24
|
+
*/
|
|
25
|
+
export declare function isPlaceholder(value: string): boolean;
|
|
26
|
+
//# sourceMappingURL=plist-parser.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plist-parser.d.ts","sourceRoot":"","sources":["../../src/parsers/plist-parser.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAEzD;;GAEG;AACH,wBAAgB,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAgBpE;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAUzE;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,GAAG,eAAe,CAGtE;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,eAAe,CAqBhF;AAED;;GAEG;AACH,eAAO,MAAM,yBAAyB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAsB9D,CAAC;AAEF;;GAEG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAyBpD"}
|