@bacons/apple-targets 3.0.7 → 4.0.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
@@ -285,33 +285,67 @@ module.exports = {
285
285
 
286
286
  Ideally, this would be generated automatically based on a fully qualified Xcode project, but for now it's a manual process. The currently supported types are based on static analysis of the most commonly used targets in the iOS App Store. I haven't tested all of these and they may not work.
287
287
 
288
- | Type | Description |
289
- | ----------------------- | ---------------------------------- |
290
- | action | Share Action |
291
- | app-intent | App Intent Extension |
292
- | widget | Widget / Live Activity |
293
- | watch | Watch App (with companion iOS App) |
294
- | clip | App Clip |
295
- | safari | Safari Extension |
296
- | share | Share Extension |
297
- | notification-content | Notification Content Extension |
298
- | notification-service | Notification Service Extension |
299
- | intent | Siri Intent Extension |
300
- | intent-ui | Siri Intent UI Extension |
301
- | spotlight | Spotlight Index Extension |
302
- | bg-download | Background Download Extension |
303
- | quicklook-thumbnail | Quick Look Thumbnail Extension |
304
- | location-push | Location Push Service Extension |
305
- | credentials-provider | Credentials Provider Extension |
306
- | account-auth | Account Authentication Extension |
307
- | network-packet-tunnel | Packet Tunnel Network Extension |
308
- | network-app-proxy | App Proxy Network Extension |
309
- | network-dns-proxy | DNS Proxy Network Extension |
310
- | network-filter-data | Filter Data Network Extension |
288
+ | Type | Description |
289
+ | ------------------------- | ---------------------------------- |
290
+ | action | Share Action |
291
+ | app-intent | App Intent Extension |
292
+ | widget | Widget / Live Activity |
293
+ | watch | Watch App (with companion iOS App) |
294
+ | watch-widget | Watch Face Complication |
295
+ | clip | App Clip |
296
+ | safari | Safari Extension |
297
+ | share | Share Extension |
298
+ | notification-content | Notification Content Extension |
299
+ | notification-service | Notification Service Extension |
300
+ | intent | Siri Intent Extension |
301
+ | intent-ui | Siri Intent UI Extension |
302
+ | spotlight | Spotlight Index Extension |
303
+ | bg-download | Background Download Extension |
304
+ | quicklook-thumbnail | Quick Look Thumbnail Extension |
305
+ | location-push | Location Push Service Extension |
306
+ | credentials-provider | Credentials Provider Extension |
307
+ | account-auth | Account Authentication Extension |
308
+ | device-activity-monitor | Device Activity Monitor Extension |
309
+ | keyboard | Custom Keyboard Extension |
310
+ | matter | Matter Device Setup Extension |
311
+ | network-packet-tunnel | Packet Tunnel Network Extension |
312
+ | network-app-proxy | App Proxy Network Extension |
313
+ | network-dns-proxy | DNS Proxy Network Extension |
314
+ | network-filter-data | Filter Data Network Extension |
315
+ | content-blocker | Safari Content Blocker Extension |
316
+ | file-provider | File Provider Extension |
317
+ | broadcast-upload | Broadcast Upload Extension |
318
+ | call-directory | Call Directory Extension |
319
+ | message-filter | Message Filter Extension |
320
+ | file-provider-ui | File Provider UI Extension |
321
+ | broadcast-setup-ui | Broadcast Setup UI Extension |
322
+ | classkit-context | ClassKit Context Provider Extension|
323
+ | unwanted-communication | Unwanted Communication Reporting |
324
+ | photo-editing | Photo Editing Extension |
325
+ | quicklook-preview | Quick Look Preview Extension |
326
+ | spotlight-delegate | CoreSpotlight Delegate Extension |
327
+ | virtual-conference | Virtual Conference Provider |
328
+ | shield-action | Shield Action Extension |
329
+ | shield-config | Shield Configuration Extension |
330
+ | print-service | Print Service Extension |
331
+ | smart-card | Smart Card / Persistent Token |
332
+ | authentication-services | Authentication Services Extension |
311
333
 
312
334
 
313
335
  <!-- | imessage | iMessage Extension | -->
314
336
 
337
+ ### Not yet supported
338
+
339
+ 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.
340
+
341
+ | Extension Point Identifier | Xcode Template Name |
342
+ | --- | --- |
343
+ | `com.apple.tv-top-shelf` | TV Top Shelf Extension (tvOS) |
344
+ | `com.apple.FinderSync` | Finder Sync Extension (macOS) |
345
+ | `com.apple.email.extension` | Mail Extension (macOS) |
346
+
347
+ > Run `bun scripts/scan-xcode-targets.ts --diff` to regenerate this list from your local Xcode installation.
348
+
315
349
  ## Code Signing
316
350
 
317
351
  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.
@@ -1,4 +1,4 @@
1
- import { ConfigPlugin } from "@expo/config-plugins";
1
+ import { ConfigPlugin } from "expo/config-plugins";
2
2
  import type { Config, ConfigFunction } from "./config";
3
3
  export declare const withTargetsDir: ConfigPlugin<{
4
4
  appleTeamId?: string;
@@ -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 createNotificationContentConfigurationList({ name, displayName, cwd, bundleId, deploymentTarget, currentProjectVersion, }) {
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",
@@ -320,6 +320,54 @@ function createWatchAppConfigurationList(project, { name, displayName, cwd, bund
320
320
  },
321
321
  };
322
322
  }
323
+ function createWatchWidgetConfigurationList(project, { name, displayName, cwd, bundleId, deploymentTarget, currentProjectVersion, icon, }) {
324
+ const common = {
325
+ ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME: "$accent",
326
+ ASSETCATALOG_COMPILER_WIDGET_BACKGROUND_COLOR_NAME: "$widgetBackground",
327
+ ...(icon && { ASSETCATALOG_COMPILER_APPICON_NAME: "AppIcon" }),
328
+ CLANG_ANALYZER_NONNULL: "YES",
329
+ CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION: "YES_AGGRESSIVE",
330
+ CLANG_CXX_LANGUAGE_STANDARD: "gnu++20",
331
+ CLANG_ENABLE_OBJC_WEAK: "YES",
332
+ CLANG_WARN_DOCUMENTATION_COMMENTS: "YES",
333
+ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER: "YES",
334
+ CLANG_WARN_UNGUARDED_AVAILABILITY: "YES_AGGRESSIVE",
335
+ CODE_SIGN_STYLE: "Automatic",
336
+ CURRENT_PROJECT_VERSION: currentProjectVersion,
337
+ GCC_C_LANGUAGE_STANDARD: "gnu11",
338
+ GENERATE_INFOPLIST_FILE: "YES",
339
+ INFOPLIST_FILE: cwd + "/Info.plist",
340
+ INFOPLIST_KEY_CFBundleDisplayName: displayName !== null && displayName !== void 0 ? displayName : name,
341
+ INFOPLIST_KEY_NSHumanReadableCopyright: "",
342
+ LD_RUNPATH_SEARCH_PATHS: ["$(inherited)", "@executable_path/Frameworks"],
343
+ MARKETING_VERSION: "1.0",
344
+ MTL_FAST_MATH: "YES",
345
+ PRODUCT_BUNDLE_IDENTIFIER: bundleId,
346
+ PRODUCT_NAME: "$(TARGET_NAME)",
347
+ SDKROOT: "watchos",
348
+ SKIP_INSTALL: "YES",
349
+ SWIFT_EMIT_LOC_STRINGS: "YES",
350
+ SWIFT_VERSION: "5.0",
351
+ TARGETED_DEVICE_FAMILY: "4",
352
+ WATCHOS_DEPLOYMENT_TARGET: deploymentTarget !== null && deploymentTarget !== void 0 ? deploymentTarget : "9.4",
353
+ };
354
+ return {
355
+ debug: {
356
+ ...common,
357
+ DEBUG_INFORMATION_FORMAT: "dwarf",
358
+ MTL_ENABLE_DEBUG_INFO: "INCLUDE_SOURCE",
359
+ SWIFT_ACTIVE_COMPILATION_CONDITIONS: "DEBUG",
360
+ SWIFT_OPTIMIZATION_LEVEL: "-Onone",
361
+ },
362
+ release: {
363
+ ...common,
364
+ COPY_PHASE_STRIP: "NO",
365
+ DEBUG_INFORMATION_FORMAT: "dwarf-with-dsym",
366
+ SWIFT_COMPILATION_MODE: "wholemodule",
367
+ SWIFT_OPTIMIZATION_LEVEL: "-O",
368
+ },
369
+ };
370
+ }
323
371
  function createSafariConfigurationList({ name, displayName, cwd, bundleId, deploymentTarget, currentProjectVersion, }) {
324
372
  const common = {
325
373
  CLANG_ANALYZER_NONNULL: "YES",
@@ -484,6 +532,8 @@ function createWidgetConfigurationList({ name, displayName, cwd, bundleId, deplo
484
532
  debug: {
485
533
  ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME: "$accent",
486
534
  ASSETCATALOG_COMPILER_WIDGET_BACKGROUND_COLOR_NAME: "$widgetBackground",
535
+ // Add app icon name when icon is provided to prevent inheriting main app's icon setting
536
+ ...(icon && { ASSETCATALOG_COMPILER_APPICON_NAME: "AppIcon" }),
487
537
  CLANG_ANALYZER_NONNULL: "YES",
488
538
  CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION: "YES_AGGRESSIVE",
489
539
  CLANG_CXX_LANGUAGE_STANDARD: "gnu++20",
@@ -520,6 +570,8 @@ function createWidgetConfigurationList({ name, displayName, cwd, bundleId, deplo
520
570
  release: {
521
571
  ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME: "$accent",
522
572
  ASSETCATALOG_COMPILER_WIDGET_BACKGROUND_COLOR_NAME: "$widgetBackground",
573
+ // Add app icon name when icon is provided to prevent inheriting main app's icon setting
574
+ ...(icon && { ASSETCATALOG_COMPILER_APPICON_NAME: "AppIcon" }),
523
575
  CLANG_ANALYZER_NONNULL: "YES",
524
576
  CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION: "YES_AGGRESSIVE",
525
577
  CLANG_CXX_LANGUAGE_STANDARD: "gnu++20",
@@ -611,6 +663,8 @@ function getConfigurationListBuildSettingsForType(project, props) {
611
663
  return createAppClipConfigurationList(props);
612
664
  case "watch":
613
665
  return createWatchAppConfigurationList(project, props);
666
+ case "watch-widget":
667
+ return createWatchWidgetConfigurationList(project, props);
614
668
  case "app-intent":
615
669
  return createAppIntentConfigurationList(props);
616
670
  case "notification-content":
@@ -630,7 +684,25 @@ function getConfigurationListBuildSettingsForType(project, props) {
630
684
  case "network-packet-tunnel":
631
685
  case "quicklook-thumbnail":
632
686
  case "spotlight":
633
- return createNotificationContentConfigurationList(props);
687
+ case "content-blocker":
688
+ case "file-provider":
689
+ case "broadcast-upload":
690
+ case "call-directory":
691
+ case "message-filter":
692
+ case "file-provider-ui":
693
+ case "broadcast-setup-ui":
694
+ case "classkit-context":
695
+ case "unwanted-communication":
696
+ case "photo-editing":
697
+ case "quicklook-preview":
698
+ case "spotlight-delegate":
699
+ case "virtual-conference":
700
+ case "shield-action":
701
+ case "shield-config":
702
+ case "print-service":
703
+ case "smart-card":
704
+ case "authentication-services":
705
+ return createDefaultConfigurationList(props);
634
706
  default:
635
707
  const exhaustiveCheck = props.type;
636
708
  throw new Error(`Unhandled case: ${exhaustiveCheck}`);
@@ -1,4 +1,4 @@
1
- import { ConfigPlugin } from "@expo/config-plugins";
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("@expo/config-plugins");
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
- // Finally, write the Config.json
47
- await (0, AssetContents_1.writeContentsJsonAsync)((0, path_1.join)(iosNamedProjectRoot, imgPath), {
48
- images: await generateResizedImageAsync(Object.fromEntries(Object.entries(userDefinedIcon).map(([key, value]) => [
49
- key,
50
- (value === null || value === void 0 ? void 0 : value.match(/^[./]/)) ? path_1.default.join(cwd, value) : value,
51
- ])), name, projectRoot, iosNamedProjectRoot, path_1.default.join(cwd, "gen-image", name)),
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 "@expo/config-plugins";
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("@expo/config-plugins");
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
- if (type === "watch") {
40
- // Ensure the Images.xcassets/AppIcon.appiconset path exists
41
- await fs.promises.mkdir((0, path_1.join)(namedProjectRoot, IMAGESET_PATH), {
42
- recursive: true,
43
- });
44
- // Finally, write the Config.json
45
- await (0, AssetContents_1.writeContentsJsonAsync)((0, path_1.join)(namedProjectRoot, IMAGESET_PATH), {
46
- images: await generateWatchIconsInternalAsync(iconFilePath, projectRoot, namedProjectRoot, cwd, isTransparent),
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
- else {
50
- await setIconsAsync(iconFilePath, projectRoot, (0, path_1.join)(projectRoot, cwd), cwd, isTransparent);
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
  },