@bacons/apple-targets 3.0.6 → 4.0.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 +34 -4
- package/build/config-plugin.d.ts +1 -1
- package/build/configuration-list.js +24 -2
- package/build/icon/with-image-asset.d.ts +1 -1
- package/build/icon/with-image-asset.js +13 -8
- package/build/icon/with-ios-icon.d.ts +1 -1
- package/build/icon/with-ios-icon.js +17 -12
- package/build/target.d.ts +417 -4
- package/build/target.js +409 -139
- package/build/util.d.ts +2 -8
- package/build/with-bacons-xcode.d.ts +1 -1
- package/build/with-bacons-xcode.js +1 -1
- package/build/with-eas-credentials.d.ts +2 -2
- package/build/with-eas-credentials.js +21 -13
- package/build/with-widget.d.ts +1 -1
- package/build/with-widget.js +1 -1
- package/build/with-xcode-changes.d.ts +1 -1
- package/build/with-xcode-changes.js +17 -13
- package/package.json +12 -1
package/README.md
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
# Apple Targets
|
|
1
|
+
# Apple Targets
|
|
2
2
|
|
|
3
3
|
> [!WARNING]
|
|
4
|
-
> This is
|
|
4
|
+
> This is an experimental Config Plugin not part of any official Expo workflow. Automated testing of targets is seemingly impossible meaning unexpected regressions can occur between versions.
|
|
5
5
|
|
|
6
|
-
|
|
6
|
+
An experimental Expo Config Plugin that generates native Apple Targets like Widgets or App Clips, and links them outside the `/ios` directory. You can open Xcode and develop the targets inside the virtual `expo:targets` folder and the changes will be saved outside of the `ios` directory. This pattern enables building things that fall outside of the scope of React Native while still obtaining all the benefits of [Continuous Native Generation](https://docs.expo.dev/workflow/continuous-native-generation/).
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
<img width="1728" height="963" alt="targets" src="https://github.com/user-attachments/assets/aedaafa0-1ef0-403c-a797-9f4c82cdb9f1" />
|
|
9
9
|
|
|
10
10
|
## 🚀 How to use
|
|
11
11
|
|
|
@@ -308,10 +308,40 @@ Ideally, this would be generated automatically based on a fully qualified Xcode
|
|
|
308
308
|
| network-app-proxy | App Proxy Network Extension |
|
|
309
309
|
| network-dns-proxy | DNS Proxy Network Extension |
|
|
310
310
|
| network-filter-data | Filter Data Network Extension |
|
|
311
|
+
| content-blocker | Safari Content Blocker Extension |
|
|
312
|
+
| file-provider | File Provider Extension |
|
|
313
|
+
| broadcast-upload | Broadcast Upload Extension |
|
|
314
|
+
| call-directory | Call Directory Extension |
|
|
315
|
+
| message-filter | Message Filter Extension |
|
|
316
|
+
| file-provider-ui | File Provider UI Extension |
|
|
317
|
+
| broadcast-setup-ui | Broadcast Setup UI Extension |
|
|
318
|
+
| classkit-context | ClassKit Context Provider Extension|
|
|
319
|
+
| unwanted-communication | Unwanted Communication Reporting |
|
|
320
|
+
| photo-editing | Photo Editing Extension |
|
|
321
|
+
| quicklook-preview | Quick Look Preview Extension |
|
|
322
|
+
| spotlight-delegate | CoreSpotlight Delegate Extension |
|
|
323
|
+
| virtual-conference | Virtual Conference Provider |
|
|
324
|
+
| shield-action | Shield Action Extension |
|
|
325
|
+
| shield-config | Shield Configuration Extension |
|
|
326
|
+
| print-service | Print Service Extension |
|
|
327
|
+
| smart-card | Smart Card / Persistent Token |
|
|
328
|
+
| authentication-services | Authentication Services Extension |
|
|
311
329
|
|
|
312
330
|
|
|
313
331
|
<!-- | imessage | iMessage Extension | -->
|
|
314
332
|
|
|
333
|
+
### Not yet supported
|
|
334
|
+
|
|
335
|
+
The following extension types exist in Xcode but aren't supported yet. Contributions welcome! See `docs/xcode-target-discovery.md` for details on how these were discovered.
|
|
336
|
+
|
|
337
|
+
| Extension Point Identifier | Xcode Template Name |
|
|
338
|
+
| --- | --- |
|
|
339
|
+
| `com.apple.tv-top-shelf` | TV Top Shelf Extension (tvOS) |
|
|
340
|
+
| `com.apple.FinderSync` | Finder Sync Extension (macOS) |
|
|
341
|
+
| `com.apple.email.extension` | Mail Extension (macOS) |
|
|
342
|
+
|
|
343
|
+
> Run `bun scripts/scan-xcode-targets.ts --diff` to regenerate this list from your local Xcode installation.
|
|
344
|
+
|
|
315
345
|
## Code Signing
|
|
316
346
|
|
|
317
347
|
The codesigning is theoretically handled entirely by [EAS Build](https://docs.expo.dev/build/introduction/). This plugin will add the requisite entitlements for target signing to work. I've only tested this end-to-end with my Pillar Valley Widget.
|
package/build/config-plugin.d.ts
CHANGED
|
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.createConfigurationListForType = void 0;
|
|
4
4
|
const xcode_1 = require("@bacons/xcode");
|
|
5
5
|
const target_1 = require("./target");
|
|
6
|
-
function
|
|
6
|
+
function createDefaultConfigurationList({ name, displayName, cwd, bundleId, deploymentTarget, currentProjectVersion, }) {
|
|
7
7
|
const common = {
|
|
8
8
|
CLANG_ANALYZER_NONNULL: "YES",
|
|
9
9
|
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION: "YES_AGGRESSIVE",
|
|
@@ -484,6 +484,8 @@ function createWidgetConfigurationList({ name, displayName, cwd, bundleId, deplo
|
|
|
484
484
|
debug: {
|
|
485
485
|
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME: "$accent",
|
|
486
486
|
ASSETCATALOG_COMPILER_WIDGET_BACKGROUND_COLOR_NAME: "$widgetBackground",
|
|
487
|
+
// Add app icon name when icon is provided to prevent inheriting main app's icon setting
|
|
488
|
+
...(icon && { ASSETCATALOG_COMPILER_APPICON_NAME: "AppIcon" }),
|
|
487
489
|
CLANG_ANALYZER_NONNULL: "YES",
|
|
488
490
|
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION: "YES_AGGRESSIVE",
|
|
489
491
|
CLANG_CXX_LANGUAGE_STANDARD: "gnu++20",
|
|
@@ -520,6 +522,8 @@ function createWidgetConfigurationList({ name, displayName, cwd, bundleId, deplo
|
|
|
520
522
|
release: {
|
|
521
523
|
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME: "$accent",
|
|
522
524
|
ASSETCATALOG_COMPILER_WIDGET_BACKGROUND_COLOR_NAME: "$widgetBackground",
|
|
525
|
+
// Add app icon name when icon is provided to prevent inheriting main app's icon setting
|
|
526
|
+
...(icon && { ASSETCATALOG_COMPILER_APPICON_NAME: "AppIcon" }),
|
|
523
527
|
CLANG_ANALYZER_NONNULL: "YES",
|
|
524
528
|
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION: "YES_AGGRESSIVE",
|
|
525
529
|
CLANG_CXX_LANGUAGE_STANDARD: "gnu++20",
|
|
@@ -630,7 +634,25 @@ function getConfigurationListBuildSettingsForType(project, props) {
|
|
|
630
634
|
case "network-packet-tunnel":
|
|
631
635
|
case "quicklook-thumbnail":
|
|
632
636
|
case "spotlight":
|
|
633
|
-
|
|
637
|
+
case "content-blocker":
|
|
638
|
+
case "file-provider":
|
|
639
|
+
case "broadcast-upload":
|
|
640
|
+
case "call-directory":
|
|
641
|
+
case "message-filter":
|
|
642
|
+
case "file-provider-ui":
|
|
643
|
+
case "broadcast-setup-ui":
|
|
644
|
+
case "classkit-context":
|
|
645
|
+
case "unwanted-communication":
|
|
646
|
+
case "photo-editing":
|
|
647
|
+
case "quicklook-preview":
|
|
648
|
+
case "spotlight-delegate":
|
|
649
|
+
case "virtual-conference":
|
|
650
|
+
case "shield-action":
|
|
651
|
+
case "shield-config":
|
|
652
|
+
case "print-service":
|
|
653
|
+
case "smart-card":
|
|
654
|
+
case "authentication-services":
|
|
655
|
+
return createDefaultConfigurationList(props);
|
|
634
656
|
default:
|
|
635
657
|
const exhaustiveCheck = props.type;
|
|
636
658
|
throw new Error(`Unhandled case: ${exhaustiveCheck}`);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ConfigPlugin } from "
|
|
1
|
+
import { ConfigPlugin } from "expo/config-plugins";
|
|
2
2
|
import { ContentsJsonImageIdiom, ContentsJsonImage } from "@expo/prebuild-config/build/plugins/icons/AssetContents";
|
|
3
3
|
export declare const withImageAsset: ConfigPlugin<{
|
|
4
4
|
cwd: string;
|
|
@@ -24,7 +24,7 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|
|
24
24
|
};
|
|
25
25
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
26
|
exports.generateWatchIconsInternalAsync = exports.generateIconsInternalAsync = exports.generateResizedImageAsync = exports.setIconsAsync = exports.ICON_CONTENTS = exports.withImageAsset = void 0;
|
|
27
|
-
const config_plugins_1 = require("
|
|
27
|
+
const config_plugins_1 = require("expo/config-plugins");
|
|
28
28
|
const image_utils_1 = require("@expo/image-utils");
|
|
29
29
|
const AssetContents_1 = require("@expo/prebuild-config/build/plugins/icons/AssetContents");
|
|
30
30
|
const fs = __importStar(require("fs"));
|
|
@@ -43,13 +43,18 @@ const withImageAsset = (config, { cwd, name, image }) => {
|
|
|
43
43
|
const userDefinedIcon = typeof image === "string"
|
|
44
44
|
? { "1x": image, "2x": undefined, "3x": undefined }
|
|
45
45
|
: image;
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
key,
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
46
|
+
try {
|
|
47
|
+
// Finally, write the Config.json
|
|
48
|
+
await (0, AssetContents_1.writeContentsJsonAsync)((0, path_1.join)(iosNamedProjectRoot, imgPath), {
|
|
49
|
+
images: await generateResizedImageAsync(Object.fromEntries(Object.entries(userDefinedIcon).map(([key, value]) => [
|
|
50
|
+
key,
|
|
51
|
+
(value === null || value === void 0 ? void 0 : value.match(/^[./]/)) ? path_1.default.join(cwd, value) : value,
|
|
52
|
+
])), name, projectRoot, iosNamedProjectRoot, path_1.default.join(cwd, "gen-image", name)),
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
catch (error) {
|
|
56
|
+
console.warn(`Failed to generate image asset "${name}" for target "${cwd}": ${error.message}. Skipping image generation.`);
|
|
57
|
+
}
|
|
53
58
|
return config;
|
|
54
59
|
},
|
|
55
60
|
]);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ConfigPlugin } from "
|
|
1
|
+
import { ConfigPlugin } from "expo/config-plugins";
|
|
2
2
|
import { ContentsJsonImageIdiom } from "@expo/prebuild-config/build/plugins/icons/AssetContents";
|
|
3
3
|
import { ExtensionType } from "../target";
|
|
4
4
|
export declare const withIosIcon: ConfigPlugin<{
|
|
@@ -24,7 +24,7 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|
|
24
24
|
};
|
|
25
25
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
26
|
exports.generateWatchIconsInternalAsync = exports.generateIconsInternalAsync = exports.setIconsAsync = exports.ICON_CONTENTS = exports.withIosIcon = void 0;
|
|
27
|
-
const config_plugins_1 = require("
|
|
27
|
+
const config_plugins_1 = require("expo/config-plugins");
|
|
28
28
|
const image_utils_1 = require("@expo/image-utils");
|
|
29
29
|
const AssetContents_1 = require("@expo/prebuild-config/build/plugins/icons/AssetContents");
|
|
30
30
|
const fs = __importStar(require("fs"));
|
|
@@ -36,18 +36,23 @@ const withIosIcon = (config, { cwd, type, iconFilePath, isTransparent = false })
|
|
|
36
36
|
async (config) => {
|
|
37
37
|
const projectRoot = config.modRequest.projectRoot;
|
|
38
38
|
const namedProjectRoot = (0, path_1.join)(projectRoot, cwd);
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
39
|
+
try {
|
|
40
|
+
if (type === "watch") {
|
|
41
|
+
// Ensure the Images.xcassets/AppIcon.appiconset path exists
|
|
42
|
+
await fs.promises.mkdir((0, path_1.join)(namedProjectRoot, IMAGESET_PATH), {
|
|
43
|
+
recursive: true,
|
|
44
|
+
});
|
|
45
|
+
// Finally, write the Config.json
|
|
46
|
+
await (0, AssetContents_1.writeContentsJsonAsync)((0, path_1.join)(namedProjectRoot, IMAGESET_PATH), {
|
|
47
|
+
images: await generateWatchIconsInternalAsync(iconFilePath, projectRoot, namedProjectRoot, cwd, isTransparent),
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
await setIconsAsync(iconFilePath, projectRoot, (0, path_1.join)(projectRoot, cwd), cwd, isTransparent);
|
|
52
|
+
}
|
|
48
53
|
}
|
|
49
|
-
|
|
50
|
-
|
|
54
|
+
catch (error) {
|
|
55
|
+
console.warn(`Failed to generate icon for target "${cwd}" using "${iconFilePath}": ${error.message}. Skipping icon generation.`);
|
|
51
56
|
}
|
|
52
57
|
return config;
|
|
53
58
|
},
|