@xcodekit/xcode-wasm 0.4.0 → 0.5.1

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
@@ -98,6 +98,7 @@ const targets = project.getNativeTargets(); // UUID[]
98
98
  const mainApp = project.findMainAppTarget("ios"); // UUID | null
99
99
  project.getTargetName(mainApp); // "MyApp"
100
100
  project.setTargetName(mainApp, "NewName");
101
+ project.renameTarget(mainApp, "OldName", "NewName"); // cascades to groups, product refs, proxies
101
102
 
102
103
  // Build settings
103
104
  project.getBuildSetting(targetUuid, "PRODUCT_BUNDLE_IDENTIFIER");
@@ -154,13 +155,13 @@ All `XcodeProject` methods operate in Rust/WASM — only primitive strings cross
154
155
 
155
156
  ### WASM
156
157
 
157
- The WASM build (`@xcodekit/xcode-wasm`) has the same API with two differences:
158
+ The WASM build (`@xcodekit/xcode-wasm`) has the same API with minor differences:
158
159
 
159
160
  - `parse()` / `build()` work with JSON **strings** (not JS objects) — call `JSON.parse()` / `JSON.stringify()` on your side
160
161
  - `XcodeProject` is created with `new XcodeProject(content)` instead of factory methods
161
- - No `open()` / `save()` — no filesystem in WASM
162
162
 
163
163
  ```js
164
+ // Browser / Deno / Cloudflare Workers
164
165
  import { parse, build, XcodeProject } from "@xcodekit/xcode-wasm";
165
166
 
166
167
  // Low-level
@@ -174,6 +175,32 @@ xcode.setBuildSetting(target, "SWIFT_VERSION", "6.0");
174
175
  const pbxproj = xcode.toBuild();
175
176
  ```
176
177
 
178
+ ### WASM on Node.js
179
+
180
+ Use the `/node` subpath to get `open()` and `save()`:
181
+
182
+ ```js
183
+ // ESM
184
+ import { XcodeProject } from "@xcodekit/xcode-wasm/node";
185
+
186
+ // CJS
187
+ const { XcodeProject } = require("@xcodekit/xcode-wasm/node");
188
+
189
+ const project = XcodeProject.open("project.pbxproj");
190
+ project.setBuildSetting(target, "SWIFT_VERSION", "6.0");
191
+ project.save();
192
+ ```
193
+
194
+ ### Shared Types
195
+
196
+ Both packages ship `types.d.ts` with rich TypeScript types for the parsed JSON structure:
197
+
198
+ ```ts
199
+ import type { ParsedProject, PBXNativeTarget, BuildSettings, ISA } from "@xcodekit/xcode-wasm/types";
200
+ // or
201
+ import type { ParsedProject, PBXNativeTarget, BuildSettings, ISA } from "@xcodekit/xcode/types";
202
+ ```
203
+
177
204
  ## Performance
178
205
 
179
206
  Benchmarked on Apple M4 Pro, Node.js v24. Median of 200 iterations.
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Type declarations for @xcodekit/xcode-wasm/node.
3
+ * Extends the base WASM XcodeProject with filesystem methods.
4
+ */
5
+
6
+ export { build, parse, parseAndBuild } from "./pkg/node/xcode";
7
+
8
+ import { XcodeProject as BaseXcodeProject } from "./pkg/node/xcode";
9
+
10
+ export declare class XcodeProject extends BaseXcodeProject {
11
+ /** Open and parse a .pbxproj file from disk. */
12
+ static open(filePath: string): XcodeProject;
13
+
14
+ /** Parse a .pbxproj string (no file on disk needed). */
15
+ static fromString(content: string): XcodeProject;
16
+
17
+ /** The file path this project was opened from, or null if fromString/constructor. */
18
+ get filePath(): string | null;
19
+
20
+ /** Write the project back to its original file. */
21
+ save(): void;
22
+ }
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Node.js wrapper for @xcodekit/xcode-wasm/node.
3
+ * Adds open() and save() methods using the filesystem.
4
+ *
5
+ * Usage:
6
+ * const { XcodeProject } = require("@xcodekit/xcode-wasm/node");
7
+ */
8
+
9
+ const { readFileSync, writeFileSync } = require("fs");
10
+ const wasm = require("./xcode");
11
+
12
+ class XcodeProject extends wasm.XcodeProject {
13
+ #filePath = null;
14
+
15
+ static open(filePath) {
16
+ const content = readFileSync(filePath, "utf8");
17
+ const project = new XcodeProject(content);
18
+ project.#filePath = filePath;
19
+ return project;
20
+ }
21
+
22
+ static fromString(content) {
23
+ return new XcodeProject(content);
24
+ }
25
+
26
+ get filePath() {
27
+ return this.#filePath;
28
+ }
29
+
30
+ save() {
31
+ if (!this.#filePath) throw new Error("No file path set — use open() or save(path)");
32
+ writeFileSync(this.#filePath, this.toBuild());
33
+ }
34
+ }
35
+
36
+ module.exports = { ...wasm, XcodeProject };
@@ -0,0 +1,40 @@
1
+ /**
2
+ * ESM wrapper for @xcodekit/xcode-wasm/node.
3
+ * Adds open() and save() methods using the filesystem.
4
+ *
5
+ * Usage:
6
+ * import { XcodeProject } from "@xcodekit/xcode-wasm/node";
7
+ */
8
+
9
+ import { readFileSync, writeFileSync } from "fs";
10
+ import { createRequire } from "module";
11
+
12
+ const require = createRequire(import.meta.url);
13
+ const wasm = require("./xcode.js");
14
+
15
+ class XcodeProject extends wasm.XcodeProject {
16
+ #filePath = null;
17
+
18
+ static open(filePath) {
19
+ const content = readFileSync(filePath, "utf8");
20
+ const project = new XcodeProject(content);
21
+ project.#filePath = filePath;
22
+ return project;
23
+ }
24
+
25
+ static fromString(content) {
26
+ return new XcodeProject(content);
27
+ }
28
+
29
+ get filePath() {
30
+ return this.#filePath;
31
+ }
32
+
33
+ save() {
34
+ if (!this.#filePath) throw new Error("No file path set — use open() or save(path)");
35
+ writeFileSync(this.#filePath, this.toBuild());
36
+ }
37
+ }
38
+
39
+ export { XcodeProject };
40
+ export const { parse, build, parseAndBuild } = wasm;
package/package.json CHANGED
@@ -2,13 +2,17 @@
2
2
  "name": "@xcodekit/xcode-wasm",
3
3
  "type": "module",
4
4
  "description": "Parse, manipulate, and serialize Xcode .pbxproj files (WASM build)",
5
- "version": "0.4.0",
5
+ "version": "0.5.1",
6
6
  "license": "MIT",
7
7
  "files": [
8
8
  "xcode_bg.wasm",
9
9
  "xcode.js",
10
10
  "xcode_bg.js",
11
- "xcode.d.ts"
11
+ "xcode.d.ts",
12
+ "types.d.ts",
13
+ "node-wrapper.js",
14
+ "node-wrapper.mjs",
15
+ "node-wrapper.d.ts"
12
16
  ],
13
17
  "main": "xcode.js",
14
18
  "types": "xcode.d.ts",
@@ -28,5 +32,20 @@
28
32
  "parser",
29
33
  "wasm",
30
34
  "rust"
31
- ]
35
+ ],
36
+ "exports": {
37
+ "./types": {
38
+ "types": "./types.d.ts"
39
+ },
40
+ ".": {
41
+ "import": "./xcode.js",
42
+ "require": "./xcode.js",
43
+ "types": "./xcode.d.ts"
44
+ },
45
+ "./node": {
46
+ "import": "./node-wrapper.mjs",
47
+ "require": "./node-wrapper.js",
48
+ "types": "./node-wrapper.d.ts"
49
+ }
50
+ }
32
51
  }
package/types.d.ts ADDED
@@ -0,0 +1,252 @@
1
+ /**
2
+ * Supplemental type definitions for @xcodekit/xcode.
3
+ *
4
+ * These provide rich types for the parsed .pbxproj JSON structure
5
+ * beyond what napi-rs auto-generates.
6
+ */
7
+
8
+ /** ISA types for all known Xcode project object types. */
9
+ export type ISA =
10
+ | "PBXBuildFile"
11
+ | "PBXAppleScriptBuildPhase"
12
+ | "PBXCopyFilesBuildPhase"
13
+ | "PBXFrameworksBuildPhase"
14
+ | "PBXHeadersBuildPhase"
15
+ | "PBXResourcesBuildPhase"
16
+ | "PBXShellScriptBuildPhase"
17
+ | "PBXSourcesBuildPhase"
18
+ | "PBXRezBuildPhase"
19
+ | "PBXContainerItemProxy"
20
+ | "PBXFileReference"
21
+ | "PBXGroup"
22
+ | "PBXVariantGroup"
23
+ | "XCVersionGroup"
24
+ | "PBXFileSystemSynchronizedRootGroup"
25
+ | "PBXFileSystemSynchronizedBuildFileExceptionSet"
26
+ | "PBXFileSystemSynchronizedGroupBuildPhaseMembershipExceptionSet"
27
+ | "PBXNativeTarget"
28
+ | "PBXAggregateTarget"
29
+ | "PBXLegacyTarget"
30
+ | "PBXProject"
31
+ | "PBXTargetDependency"
32
+ | "XCBuildConfiguration"
33
+ | "XCConfigurationList"
34
+ | "PBXBuildRule"
35
+ | "PBXReferenceProxy"
36
+ | "XCSwiftPackageProductDependency"
37
+ | "XCRemoteSwiftPackageReference"
38
+ | "XCLocalSwiftPackageReference";
39
+
40
+ /** A 24-character hexadecimal UUID string. */
41
+ export type UUID = string;
42
+
43
+ /** Boolean as 0 | 1 integer. */
44
+ export type BoolNumber = 0 | 1;
45
+
46
+ /** Boolean as YES/NO string. */
47
+ export type BoolString = "YES" | "NO" | "YES_ERROR" | "YES_AGGRESSIVE";
48
+
49
+ /** Source tree reference types. */
50
+ export type SourceTree = "BUILT_PRODUCTS_DIR" | "DEVELOPER_DIR" | "SOURCE_ROOT" | "SDKROOT" | "<group>" | "<absolute>";
51
+
52
+ /** CopyFilesBuildPhase destination subfolder spec. */
53
+ export enum SubFolder {
54
+ absolutePath = 0,
55
+ wrapper = 1,
56
+ executables = 6,
57
+ resources = 7,
58
+ frameworks = 10,
59
+ sharedFrameworks = 11,
60
+ sharedSupport = 12,
61
+ plugins = 13,
62
+ javaResources = 15,
63
+ productsDirectory = 16,
64
+ }
65
+
66
+ /** Container item proxy type. */
67
+ export enum ProxyType {
68
+ targetReference = 1,
69
+ reference = 2,
70
+ }
71
+
72
+ /** Common file type UTIs. */
73
+ export type FileType =
74
+ | "sourcecode.swift"
75
+ | "sourcecode.c.c"
76
+ | "sourcecode.c.h"
77
+ | "sourcecode.c.objc"
78
+ | "sourcecode.cpp.cpp"
79
+ | "sourcecode.cpp.objcpp"
80
+ | "sourcecode.javascript"
81
+ | "wrapper.application"
82
+ | "wrapper.framework"
83
+ | "wrapper.app-extension"
84
+ | "wrapper.plug-in"
85
+ | "wrapper.xcframework"
86
+ | "compiled.mach-o.dylib"
87
+ | "archive.ar"
88
+ | "folder.assetcatalog"
89
+ | "text.plist.xml"
90
+ | "text.plist.strings"
91
+ | "text.plist.entitlements"
92
+ | "text.xcconfig"
93
+ | "file.storyboard"
94
+ | "file.xib"
95
+ | "file.intentdefinition"
96
+ | "image.png"
97
+ | "image.jpeg"
98
+ | "net.daringfireball.markdown"
99
+ | string;
100
+
101
+ /** Common product type UTIs. */
102
+ export type ProductType =
103
+ | "com.apple.product-type.application"
104
+ | "com.apple.product-type.application.on-demand-install-capable"
105
+ | "com.apple.product-type.app-extension"
106
+ | "com.apple.product-type.bundle"
107
+ | "com.apple.product-type.framework"
108
+ | "com.apple.product-type.library.dynamic"
109
+ | "com.apple.product-type.library.static"
110
+ | "com.apple.product-type.tool"
111
+ | "com.apple.product-type.unit-test-bundle"
112
+ | "com.apple.product-type.ui-testing-bundle"
113
+ | "com.apple.product-type.application.watchapp"
114
+ | "com.apple.product-type.application.watchapp2"
115
+ | "com.apple.product-type.watchkit-extension"
116
+ | "com.apple.product-type.extensionkit-extension"
117
+ | string;
118
+
119
+ /** Build settings dictionary. */
120
+ export interface BuildSettings {
121
+ ALWAYS_SEARCH_USER_PATHS?: BoolString;
122
+ ASSETCATALOG_COMPILER_APPICON_NAME?: string;
123
+ CLANG_ENABLE_MODULES?: BoolString;
124
+ CLANG_ENABLE_OBJC_ARC?: BoolString;
125
+ CODE_SIGN_ENTITLEMENTS?: string;
126
+ CODE_SIGN_IDENTITY?: string;
127
+ CODE_SIGN_STYLE?: "Automatic" | "Manual";
128
+ CURRENT_PROJECT_VERSION?: string;
129
+ DEBUG_INFORMATION_FORMAT?: "dwarf" | "dwarf-with-dsym";
130
+ DEVELOPMENT_TEAM?: string;
131
+ GCC_OPTIMIZATION_LEVEL?: string;
132
+ GCC_PREPROCESSOR_DEFINITIONS?: string | string[];
133
+ GENERATE_INFOPLIST_FILE?: BoolString;
134
+ INFOPLIST_FILE?: string;
135
+ INFOPLIST_KEY_CFBundleDisplayName?: string;
136
+ IPHONEOS_DEPLOYMENT_TARGET?: string;
137
+ MACOSX_DEPLOYMENT_TARGET?: string;
138
+ TVOS_DEPLOYMENT_TARGET?: string;
139
+ WATCHOS_DEPLOYMENT_TARGET?: string;
140
+ MARKETING_VERSION?: string;
141
+ PRODUCT_BUNDLE_IDENTIFIER?: string;
142
+ PRODUCT_NAME?: string;
143
+ SWIFT_VERSION?: string;
144
+ TARGETED_DEVICE_FAMILY?: string;
145
+ [key: string]: string | string[] | number | undefined;
146
+ }
147
+
148
+ /** Base object with isa field. */
149
+ export interface PBXObjectBase {
150
+ isa: ISA;
151
+ [key: string]: any;
152
+ }
153
+
154
+ /** PBXBuildFile object. */
155
+ export interface PBXBuildFile extends PBXObjectBase {
156
+ isa: "PBXBuildFile";
157
+ fileRef?: UUID;
158
+ productRef?: UUID;
159
+ settings?: Record<string, any>;
160
+ platformFilter?: string;
161
+ platformFilters?: string[];
162
+ }
163
+
164
+ /** PBXFileReference object. */
165
+ export interface PBXFileReference extends PBXObjectBase {
166
+ isa: "PBXFileReference";
167
+ fileEncoding?: number;
168
+ lastKnownFileType?: FileType;
169
+ explicitFileType?: FileType;
170
+ includeInIndex?: BoolNumber;
171
+ name?: string;
172
+ path?: string;
173
+ sourceTree?: SourceTree;
174
+ }
175
+
176
+ /** PBXGroup object. */
177
+ export interface PBXGroup extends PBXObjectBase {
178
+ isa: "PBXGroup";
179
+ children: UUID[];
180
+ name?: string;
181
+ path?: string;
182
+ sourceTree?: SourceTree;
183
+ }
184
+
185
+ /** Build phase (shared fields for all 8 types). */
186
+ export interface AbstractBuildPhase extends PBXObjectBase {
187
+ buildActionMask?: number;
188
+ files: UUID[];
189
+ runOnlyForDeploymentPostprocessing?: BoolNumber;
190
+ }
191
+
192
+ /** PBXNativeTarget object. */
193
+ export interface PBXNativeTarget extends PBXObjectBase {
194
+ isa: "PBXNativeTarget";
195
+ buildConfigurationList: UUID;
196
+ buildPhases: UUID[];
197
+ buildRules: UUID[];
198
+ dependencies: UUID[];
199
+ name: string;
200
+ productName?: string;
201
+ productReference?: UUID;
202
+ productType: ProductType;
203
+ packageProductDependencies?: UUID[];
204
+ fileSystemSynchronizedGroups?: UUID[];
205
+ }
206
+
207
+ /** PBXProject (root object). */
208
+ export interface PBXProject extends PBXObjectBase {
209
+ isa: "PBXProject";
210
+ buildConfigurationList: UUID;
211
+ compatibilityVersion: string;
212
+ developmentRegion: string;
213
+ hasScannedForEncodings: BoolNumber;
214
+ knownRegions: string[];
215
+ mainGroup: UUID;
216
+ productRefGroup?: UUID;
217
+ projectDirPath: string;
218
+ projectRoot: string;
219
+ targets: UUID[];
220
+ packageReferences?: UUID[];
221
+ attributes?: {
222
+ LastSwiftUpdateCheck?: string;
223
+ LastUpgradeCheck?: string;
224
+ TargetAttributes?: Record<UUID, Record<string, any>>;
225
+ [key: string]: any;
226
+ };
227
+ }
228
+
229
+ /** XCBuildConfiguration object. */
230
+ export interface XCBuildConfiguration extends PBXObjectBase {
231
+ isa: "XCBuildConfiguration";
232
+ name: string;
233
+ buildSettings: BuildSettings;
234
+ baseConfigurationReference?: UUID;
235
+ }
236
+
237
+ /** XCConfigurationList object. */
238
+ export interface XCConfigurationList extends PBXObjectBase {
239
+ isa: "XCConfigurationList";
240
+ buildConfigurations: UUID[];
241
+ defaultConfigurationIsVisible?: BoolNumber;
242
+ defaultConfigurationName?: string;
243
+ }
244
+
245
+ /** The top-level parsed .pbxproj structure. */
246
+ export interface ParsedProject {
247
+ archiveVersion: number;
248
+ classes: Record<string, any>;
249
+ objectVersion: number;
250
+ objects: Record<UUID, PBXObjectBase>;
251
+ rootObject: UUID;
252
+ }
package/xcode.d.ts CHANGED
@@ -30,6 +30,10 @@ export class XcodeProject {
30
30
  */
31
31
  constructor(content: string);
32
32
  removeBuildSetting(target_uuid: string, key: string): boolean;
33
+ /**
34
+ * Rename a target and cascade through the project (group paths, product refs, proxies).
35
+ */
36
+ renameTarget(target_uuid: string, old_name: string, new_name: string): boolean;
33
37
  setBuildSetting(target_uuid: string, key: string, value: string): boolean;
34
38
  setObjectProperty(uuid: string, key: string, value: string): boolean;
35
39
  setTargetName(target_uuid: string, name: string): boolean;
package/xcode_bg.js CHANGED
@@ -498,6 +498,23 @@ export class XcodeProject {
498
498
  const ret = wasm.xcodeproject_removeBuildSetting(this.__wbg_ptr, ptr0, len0, ptr1, len1);
499
499
  return ret !== 0;
500
500
  }
501
+ /**
502
+ * Rename a target and cascade through the project (group paths, product refs, proxies).
503
+ * @param {string} target_uuid
504
+ * @param {string} old_name
505
+ * @param {string} new_name
506
+ * @returns {boolean}
507
+ */
508
+ renameTarget(target_uuid, old_name, new_name) {
509
+ const ptr0 = passStringToWasm0(target_uuid, wasm.__wbindgen_export, wasm.__wbindgen_export2);
510
+ const len0 = WASM_VECTOR_LEN;
511
+ const ptr1 = passStringToWasm0(old_name, wasm.__wbindgen_export, wasm.__wbindgen_export2);
512
+ const len1 = WASM_VECTOR_LEN;
513
+ const ptr2 = passStringToWasm0(new_name, wasm.__wbindgen_export, wasm.__wbindgen_export2);
514
+ const len2 = WASM_VECTOR_LEN;
515
+ const ret = wasm.xcodeproject_renameTarget(this.__wbg_ptr, ptr0, len0, ptr1, len1, ptr2, len2);
516
+ return ret !== 0;
517
+ }
501
518
  /**
502
519
  * @param {string} target_uuid
503
520
  * @param {string} key
package/xcode_bg.wasm CHANGED
Binary file