@bacons/apple-targets 0.1.8 → 0.1.10

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
@@ -11,48 +11,47 @@ An experimental Expo Config Plugin that generates native Apple Targets like Widg
11
11
 
12
12
  > This plugin requires at least CocoaPods 1.16.2, Xcode 16, and Expo SDK +52.
13
13
 
14
- Run the following command in your Expo project:
14
+ 1. Run `npx create-target` in your Expo project to generate an Apple target.
15
+ 2. Select a target to generate, I recommend starting with a `widget` (e.g. `npx create-target widget`). This will generate the required widget files in the root `/targets` directory, install `@bacons/apple-targets`, and add the Expo Config Plugin to your project.
16
+ 3. If you already know your Apple Team ID, then set it under the `ios.appleTeamId` property in your `app.json`. You can find this in Xcode under the Signing & Capabilities tab and set it later if needed.
17
+ 4. Run `npx expo prebuild -p ios --clean` to generate the Xcode project.
18
+ 5. You can now open your project in Xcode (`xed ios`) and develop the widget inside the `expo:targets/<target>` folder.
19
+ 6. When you're ready to build, select the target in Xcode and build it.
15
20
 
16
- ```
17
- npx create-target
18
- ```
21
+ ### How it works
19
22
 
20
- Select a target to generate, I recommend starting with a `widget`.
23
+ The root `/targets` folder is magic, each sub-directory should have a `expo-target.config.js` file that defines the target settings. When you run `npx expo prebuild --clean`, the plugin will generate the Xcode project and link the target files to the project. The plugin will also generate an `Info.plist` file if one doesn't exist.
21
24
 
22
- This will generate the required widget files in the `targets` directory.
25
+ The Config Plugin will link the subfolder (e.g. `targets/widget`) to Xcode, and all files inside of it will be part of the target. This means you can develop the target inside the `expo:targets` folder and the changes will be saved outside of the generated `ios` directory.
23
26
 
24
- Ensure the `ios.appleTeamId` property is set in your `app.json`, then run `npx expo prebuild -p ios --clean` to generate the Xcode project.
27
+ The root `Info.plist` file in each target directory is not managed and can be freely modified.
25
28
 
26
- You can now open Xcode and develop the widget inside the `expo:targets` folder. When you're ready to build, run:
29
+ Any files in a top-level `target/{name}/assets` directory will be linked as resources of the target. This rule was added to support Safari Extensions.
27
30
 
28
- ### Manual usage
31
+ ### Entitlements
29
32
 
30
- - Add targets to `targets/` directory with an `expo-target.config.json` file.
31
- - If you don't have an `Info.plist`, it'll be generated on `npx expo prebuild`. This may be changed in the future so if you have an `Info.plist` it'll be used, otherwise, it'll be generated.
32
- - Any files in a top-level `target/*/assets` directory will be linked as resources of the target. This was added to support Safari Extensions.
33
- - A single top-level `*.entitlements` file will be linked as the entitlements of the target. This is not currently used in EAS Capability signing, but may be in the future.
34
- - All Swift files will be linked as build sources of the target. There is currently no support for storyboard or `.xib` files because I can't be bothered.
35
- - All `*.xcassets` files will be linked as resources, and accessible in the targets. If you add files outside of Xcode, you'll need to re-run `npx expo prebuild` to link them.
36
- - In Expo SDK +52, set the `ios.appleTeamId`, for SDK 51 and below, set the `appleTeamId` prop in the Config Plugin in `app.config.js`:
33
+ If the `expo-target.config` file defines an `entitlements: {}` object, then a `generated.entitlements` will be added. Avoid using this file directly, and instead update the `expo-target.config.js` file. If the `entitlements` object is not defined, you can manually add any top-level `*.entitlements` file to the target directory—re-running `npx expo prebuild` will link this file to the target as the entitlements file. Only one top-level `*.entitlements` file is supported per target.
37
34
 
38
- ```json
39
- {
40
- "plugins": [
41
- [
42
- "@bacons/apple-targets",
43
- {
44
- "appleTeamId": "XXXXXXXXXX"
45
- }
46
- ]
47
- ]
48
- }
49
- ```
35
+ Some targets have special entitlements behavior:
36
+
37
+ - App Clips (`clip`) automatically set the required `com.apple.developer.parent-application-identifiers` to `$(AppIdentifierPrefix)${config.ios.bundleIdentifier}`
38
+ - Targets that can utilize App Groups will automatically mirror the `ios.entitlements['com.apple.security.application-groups']` array from the `app.json` if it's defined. This can be overwritten by specifying an `entitlements['com.apple.security.application-groups']` array in the `expo-target.config.js` file.
39
+
40
+ ### Development
41
+
42
+ Any changes you make outside of the `expo:targets` directory in Xcode are subject to being overwritten by the next `npx expo prebuild --clean`. Check to see if the settings you want to toggle are available in the Info.plist or the `expo-target.config.js` file.
43
+ If you modify the `expo-target.config.js` or your root `app.json`, you will need to re-run `npx expo prebuild --clean` to sync the changes.
44
+
45
+ You can use the custom Prebuild template `--template node_modules/@bacons/apple-targets/prebuild-blank.tgz` to create a build without React Native, this can make development a bit faster since there's less to compile.
46
+
47
+ ## Target config
50
48
 
51
- ## `expo-target.config.js`
49
+ The target config can be a `expo-target.config.js`, or `expo-target.config.json` file.
52
50
 
53
51
  This file can have the following properties:
54
52
 
55
53
  ```js
54
+ /** @type {import('@bacons/apple-targets/app.plugin').Config} */
56
55
  module.exports = {
57
56
  type: "widget",
58
57
 
@@ -67,7 +66,7 @@ module.exports = {
67
66
  icon: "../assets/icon.png",
68
67
  // Can also be a URL
69
68
  frameworks: [
70
- // Frameworks without the extension, these will be added to the target.
69
+ // Frameworks with or without the `.frameworks` extension, these will be added to the target.
71
70
  "SwiftUI",
72
71
  ],
73
72
  entitlements: {
@@ -84,26 +83,16 @@ module.exports = {
84
83
  // Optional bundle identifier for the target. Will default to a sanitized version of the root project bundle id + target name.
85
84
  // If the specified bundle identifier is prefixed with a dot (.), the bundle identifier will be appended to the main app's bundle identifier.
86
85
  bundleIdentifier: ".mywidget",
87
- };
88
- ```
89
86
 
90
- You can also use `.js` with the typedoc for autocomplete:
91
-
92
- ```js
93
- /** @type {import('@bacons/apple-targets').Config} */
94
- module.exports = {
95
- type: "watch",
96
- colors: {
97
- $accent: "steelblue",
98
- },
99
- deploymentTarget: "9.4",
87
+ // Should the release build export the JS bundle and embed. Intended for App Clips and Share Extensions where you may want to use React Native.
88
+ exportJs: false,
100
89
  };
101
90
  ```
102
91
 
103
- Finally, you can return a function that accepts the Expo Config and returns a target function for syncing app groups:
92
+ You can also return a function that accepts the Expo Config and returns a target function for syncing entitlements and other values:
104
93
 
105
94
  ```js
106
- /** @type {import('@bacons/apple-targets').ConfigFunction} */
95
+ /** @type {import('@bacons/apple-targets/app.plugin').ConfigFunction} */
107
96
  module.exports = (config) => ({
108
97
  type: "widget",
109
98
  colors: {
@@ -192,7 +181,7 @@ The name of the target must match the name of the target directory.
192
181
  > I wrote a blog about this one and used it in production. Learn more: [Expo x Apple Widgets](https://evanbacon.dev/blog/apple-home-screen-widgets).
193
182
 
194
183
  ```js
195
- /** @type {import('@bacons/apple-targets').Config} */
184
+ /** @type {import('@bacons/apple-targets/app.plugin').Config} */
196
185
  module.exports = {
197
186
  type: "widget",
198
187
  icon: "../../icons/widget.png",
@@ -224,7 +213,7 @@ module.exports = {
224
213
  These show up in the share sheet. The icon should be transparent as it will be masked by the system.
225
214
 
226
215
  ```js
227
- /** @type {import('@bacons/apple-targets').Config} */
216
+ /** @type {import('@bacons/apple-targets/app.plugin').Config} */
228
217
  module.exports = {
229
218
  type: "action",
230
219
  name: "Inspect Element",
@@ -269,7 +258,7 @@ Ensure `NSExtensionJavaScriptPreprocessingFile: "index"` in the Info.plist.
269
258
  Populate the Spotlight search results with your app's content.
270
259
 
271
260
  ```js
272
- /** @type {import('@bacons/apple-targets').Config} */
261
+ /** @type {import('@bacons/apple-targets/app.plugin').Config} */
273
262
  module.exports = {
274
263
  type: "spotlight",
275
264
  };
@@ -308,9 +297,7 @@ The codesigning is theoretically handled entirely by [EAS Build](https://docs.ex
308
297
 
309
298
  You can also manually sign all sub-targets if you want, I'll light a candle for you.
310
299
 
311
- ## Xcode parsing
312
-
313
- This plugin makes use of my proprietary Xcode parsing library, [`@bacons/xcode`](https://github.com/evanbacon/xcode). It's mostly typed, very untested, and possibly full of bugs––however, it's still 10x nicer than the alternative.
300
+ > I haven't gotten App Clip codesigning to be fully automated yet. PRs welcome.
314
301
 
315
302
  ## Building Widgets
316
303
 
@@ -349,7 +336,7 @@ First, define your main App Group entitlement in your `app.json`:
349
336
  Second, define the same App Group in your target's `expo-target.config.js`:
350
337
 
351
338
  ```js
352
- /** @type {import('@bacons/apple-targets').ConfigFunction} */
339
+ /** @type {import('@bacons/apple-targets/app.plugin').ConfigFunction} */
353
340
  module.exports = (config) => ({
354
341
  type: "widget",
355
342
  entitlements: {
@@ -402,6 +389,6 @@ let defaults = UserDefaults(suiteName:
402
389
  let index = defaults?.string(forKey: "myKey")
403
390
  ```
404
391
 
405
- ## Using React Native in Targets
392
+ ## Xcode parsing
406
393
 
407
- I'm not sure, that's not the purpose of this plugin. I built this so I could easily build iOS widgets and other minor targets with SwiftUI. I imagine it would be straightforward to use React Native in share, notification, iMessage, Safari, and photo editing extensions, you can build that on top of this plugin if you want. Look at the App Clip example for a starting point.
394
+ This plugin makes use of my proprietary Xcode parsing library, [`@bacons/xcode`](https://github.com/evanbacon/xcode). It's mostly typed, very untested, and possibly full of bugs––however, it's still 10x nicer than the alternative.
@@ -0,0 +1 @@
1
+ export * from "./build/config-plugin";
@@ -6,16 +6,20 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.withTargetsDir = void 0;
7
7
  const glob_1 = require("glob");
8
8
  const path_1 = __importDefault(require("path"));
9
+ const chalk_1 = __importDefault(require("chalk"));
9
10
  const withPodTargetExtension_1 = require("./withPodTargetExtension");
10
11
  const withWidget_1 = __importDefault(require("./withWidget"));
11
12
  const withXcparse_1 = require("./withXcparse");
13
+ let hasWarned = false;
12
14
  const withTargetsDir = (config, _props) => {
13
15
  var _a;
14
- const { appleTeamId = (_a = config === null || config === void 0 ? void 0 : config.ios) === null || _a === void 0 ? void 0 : _a.appleTeamId, root = "./targets", match = "*", } = _props || {};
15
- if (!appleTeamId) {
16
- throw new Error(`You must specify an \`appleTeamId\` in your app config to use the \`withTargetsDir\` plugin.`);
17
- }
16
+ let { appleTeamId = (_a = config === null || config === void 0 ? void 0 : config.ios) === null || _a === void 0 ? void 0 : _a.appleTeamId } = _props || {};
17
+ const { root = "./targets", match = "*" } = _props || {};
18
18
  const projectRoot = config._internal.projectRoot;
19
+ if (!appleTeamId && !hasWarned) {
20
+ hasWarned = true;
21
+ console.warn((0, chalk_1.default) `{yellow [bacons/apple-targets]} Expo config is missing required {cyan ios.appleTeamId} property. Find this in Xcode and add to the Expo Config to correct. iOS builds may fail until this is corrected.`);
22
+ }
19
23
  const targets = (0, glob_1.sync)(`${root}/${match}/expo-target.config.@(json|js)`, {
20
24
  // const targets = globSync(`./targets/action/expo-target.config.@(json|js)`, {
21
25
  cwd: projectRoot,
package/build/target.d.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  import { PBXNativeTarget, XcodeProject } from "@bacons/xcode";
2
2
  export type ExtensionType = "widget" | "notification-content" | "notification-service" | "share" | "intent" | "bg-download" | "intent-ui" | "spotlight" | "matter" | "quicklook-thumbnail" | "imessage" | "clip" | "watch" | "location-push" | "credentials-provider" | "account-auth" | "action" | "safari" | "app-intent" | "device-activity-monitor";
3
3
  export declare const KNOWN_EXTENSION_POINT_IDENTIFIERS: Record<string, ExtensionType>;
4
+ export declare const SHOULD_USE_APP_GROUPS_BY_DEFAULT: Record<ExtensionType, boolean>;
4
5
  export declare function getTargetInfoPlistForType(type: ExtensionType): string;
5
6
  export declare function productTypeForType(type: ExtensionType): "com.apple.product-type.application.on-demand-install-capable" | "com.apple.product-type.application" | "com.apple.product-type.extensionkit-extension" | "com.apple.product-type.app-extension";
6
7
  export declare function needsEmbeddedSwift(type: ExtensionType): boolean;
package/build/target.js CHANGED
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.getAuxiliaryTargets = exports.getMainAppTarget = exports.isNativeTargetOfType = exports.getFrameworksForType = exports.needsEmbeddedSwift = exports.productTypeForType = exports.getTargetInfoPlistForType = exports.KNOWN_EXTENSION_POINT_IDENTIFIERS = void 0;
6
+ exports.getAuxiliaryTargets = exports.getMainAppTarget = exports.isNativeTargetOfType = exports.getFrameworksForType = exports.needsEmbeddedSwift = exports.productTypeForType = exports.getTargetInfoPlistForType = exports.SHOULD_USE_APP_GROUPS_BY_DEFAULT = exports.KNOWN_EXTENSION_POINT_IDENTIFIERS = void 0;
7
7
  const plist_1 = __importDefault(require("@expo/plist"));
8
8
  exports.KNOWN_EXTENSION_POINT_IDENTIFIERS = {
9
9
  "com.apple.message-payload-provider": "imessage",
@@ -26,12 +26,37 @@ exports.KNOWN_EXTENSION_POINT_IDENTIFIERS = {
26
26
  "com.apple.deviceactivity.monitor-extension": "device-activity-monitor",
27
27
  // "com.apple.intents-service": "intents",
28
28
  };
29
+ // An exhaustive list of extension types that should sync app groups from the main target by default when
30
+ // no app groups are specified.
31
+ exports.SHOULD_USE_APP_GROUPS_BY_DEFAULT = {
32
+ share: true,
33
+ "bg-download": true,
34
+ clip: true,
35
+ widget: true,
36
+ "account-auth": false,
37
+ "credentials-provider": false,
38
+ "device-activity-monitor": false,
39
+ "app-intent": false,
40
+ "intent-ui": false,
41
+ "location-push": false,
42
+ "notification-content": false,
43
+ "notification-service": false,
44
+ "quicklook-thumbnail": false,
45
+ action: false,
46
+ imessage: false,
47
+ intent: false,
48
+ matter: false,
49
+ safari: false,
50
+ spotlight: false,
51
+ watch: false,
52
+ };
29
53
  // TODO: Maybe we can replace `NSExtensionPrincipalClass` with the `@main` annotation that newer extensions use?
30
54
  function getTargetInfoPlistForType(type) {
55
+ // TODO: Use exhaustive switch to ensure external contributors don't forget to add this.
31
56
  if (type === "watch") {
32
57
  return plist_1.default.build({});
33
58
  }
34
- if (type === "action") {
59
+ else if (type === "action") {
35
60
  return plist_1.default.build({
36
61
  NSExtension: {
37
62
  NSExtensionAttributes: {
@@ -93,7 +118,7 @@ function getTargetInfoPlistForType(type) {
93
118
  },
94
119
  });
95
120
  }
96
- if (type === "account-auth") {
121
+ else if (type === "account-auth") {
97
122
  return plist_1.default.build({
98
123
  NSExtension: {
99
124
  NSExtensionPointIdentifier,
@@ -105,7 +130,7 @@ function getTargetInfoPlistForType(type) {
105
130
  },
106
131
  });
107
132
  }
108
- if (type === "credentials-provider") {
133
+ else if (type === "credentials-provider") {
109
134
  return plist_1.default.build({
110
135
  NSExtension: {
111
136
  NSExtensionPointIdentifier,
@@ -113,7 +138,7 @@ function getTargetInfoPlistForType(type) {
113
138
  },
114
139
  });
115
140
  }
116
- if (type === "notification-service") {
141
+ else if (type === "notification-service") {
117
142
  return plist_1.default.build({
118
143
  NSExtension: {
119
144
  NSExtensionAttributes: {
@@ -8,21 +8,51 @@ const plist_1 = __importDefault(require("@expo/plist"));
8
8
  const fs_1 = __importDefault(require("fs"));
9
9
  const glob_1 = require("glob");
10
10
  const path_1 = __importDefault(require("path"));
11
+ const chalk_1 = __importDefault(require("chalk"));
11
12
  const withIosColorset_1 = require("./colorset/withIosColorset");
12
13
  const withImageAsset_1 = require("./icon/withImageAsset");
13
14
  const withIosIcon_1 = require("./icon/withIosIcon");
14
15
  const target_1 = require("./target");
15
16
  const withEasCredentials_1 = require("./withEasCredentials");
16
17
  const withXcodeChanges_1 = require("./withXcodeChanges");
17
- let hasWarned = false;
18
+ function memoize(fn) {
19
+ const cache = new Map();
20
+ return ((...args) => {
21
+ const key = JSON.stringify(args);
22
+ if (cache.has(key)) {
23
+ return cache.get(key);
24
+ }
25
+ const result = fn(...args);
26
+ cache.set(key, result);
27
+ return result;
28
+ });
29
+ }
30
+ const warnOnce = memoize(console.warn);
31
+ const logOnce = memoize(console.log);
32
+ function createLogQueue() {
33
+ const queue = [];
34
+ const flush = () => {
35
+ queue.forEach((fn) => fn());
36
+ queue.length = 0;
37
+ };
38
+ return {
39
+ flush,
40
+ add: (fn) => {
41
+ queue.push(fn);
42
+ },
43
+ };
44
+ }
45
+ // Queue up logs so they only run when prebuild is actually running and not during standard config reads.
46
+ const prebuildLogQueue = createLogQueue();
18
47
  function kebabToCamelCase(str) {
19
48
  return str.replace(/-([a-z])/g, function (g) {
20
49
  return g[1].toUpperCase();
21
50
  });
22
51
  }
23
52
  const withWidget = (config, props) => {
24
- // TODO: Magically based on the top-level folders in the `ios-widgets/` folder
25
53
  var _a, _b, _c, _d, _e, _f, _g, _h, _j;
54
+ prebuildLogQueue.add(() => warnOnce((0, chalk_1.default) `\nUsing experimental Config Plugin {bold @bacons/apple-targets} that is subject to breaking changes.`));
55
+ // TODO: Magically based on the top-level folders in the `ios-widgets/` folder
26
56
  if (props.icon && !/https?:\/\//.test(props.icon)) {
27
57
  props.icon = path_1.default.join(props.directory, props.icon);
28
58
  }
@@ -37,21 +67,49 @@ const withWidget = (config, props) => {
37
67
  cwd: widgetFolderAbsolutePath,
38
68
  });
39
69
  if (entitlementsFiles.length > 1) {
40
- throw new Error(`Found multiple entitlements files in ${widgetFolderAbsolutePath}`);
70
+ throw new Error(`[bacons/apple-targets][${props.type}] Found more than one '*.entitlements' file in ${widgetFolderAbsolutePath}`);
41
71
  }
42
72
  let entitlementsJson = props.entitlements;
43
- // Apply default entitlements that must be present for a target to work.
44
- function applyDefaultEntitlements(entitlements) {
45
- if (props.type === "clip") {
46
- entitlements["com.apple.developer.parent-application-identifiers"] = [
47
- `$(AppIdentifierPrefix)${config.ios.bundleIdentifier}`,
48
- ];
49
- // NOTE: This doesn't seem to be required anymore (Oct 12 2024):
50
- // entitlements["com.apple.developer.on-demand-install-capable"] = true;
51
- }
52
- return entitlements;
53
- }
54
73
  if (entitlementsJson) {
74
+ // Apply default entitlements that must be present for a target to work.
75
+ const applyDefaultEntitlements = (entitlements) => {
76
+ var _a, _b, _c, _d;
77
+ if (props.type === "clip") {
78
+ entitlements["com.apple.developer.parent-application-identifiers"] = [
79
+ `$(AppIdentifierPrefix)${config.ios.bundleIdentifier}`,
80
+ ];
81
+ // NOTE: This doesn't seem to be required anymore (Oct 12 2024):
82
+ // entitlements["com.apple.developer.on-demand-install-capable"] = true;
83
+ }
84
+ const APP_GROUP_KEY = "com.apple.security.application-groups";
85
+ const hasDefinedAppGroupsManually = APP_GROUP_KEY in entitlements;
86
+ if (
87
+ // If the user hasn't manually defined the app groups array.
88
+ !hasDefinedAppGroupsManually &&
89
+ // And the target is part of a predefined list of types that benefit from app groups that match the main app...
90
+ target_1.SHOULD_USE_APP_GROUPS_BY_DEFAULT[props.type]) {
91
+ const mainAppGroups = (_b = (_a = config.ios) === null || _a === void 0 ? void 0 : _a.entitlements) === null || _b === void 0 ? void 0 : _b[APP_GROUP_KEY];
92
+ if (Array.isArray(mainAppGroups) && mainAppGroups.length > 0) {
93
+ // Then set the target app groups to match the main app.
94
+ entitlements[APP_GROUP_KEY] = mainAppGroups;
95
+ prebuildLogQueue.add(() => {
96
+ logOnce((0, chalk_1.default) `[${widget}] Syncing app groups with main app. {dim Define entitlements[${JSON.stringify(APP_GROUP_KEY)}] in the {bold expo-target.config} file to override.}`);
97
+ });
98
+ }
99
+ else {
100
+ config_plugins_1.WarningAggregator.addWarningIOS(`ios.entitlements["${APP_GROUP_KEY}"]`, `[${props.type}] Apple target may require the App Groups entitlement but none were found in the Expo config.\nExample:\n${JSON.stringify({
101
+ ios: {
102
+ entitlements: {
103
+ [APP_GROUP_KEY]: [
104
+ `group.${(_d = (_c = config.ios) === null || _c === void 0 ? void 0 : _c.bundleIdentifier) !== null && _d !== void 0 ? _d : `com.example.${config.slug}`}`,
105
+ ],
106
+ },
107
+ },
108
+ }, null, 2)}`);
109
+ }
110
+ }
111
+ return entitlements;
112
+ };
55
113
  entitlementsJson = applyDefaultEntitlements(entitlementsJson);
56
114
  }
57
115
  // If the user defined entitlements, then overwrite any existing entitlements file
@@ -60,11 +118,15 @@ const withWidget = (config, props) => {
60
118
  "ios",
61
119
  async (config) => {
62
120
  var _a;
121
+ const GENERATED_ENTITLEMENTS_FILE_NAME = "generated.entitlements";
63
122
  const entitlementsFilePath = (_a = entitlementsFiles[0]) !== null && _a !== void 0 ? _a :
64
123
  // Use the name `generated` to help indicate that this file should be in sync with the config
65
- path_1.default.join(widgetFolderAbsolutePath, `generated.entitlements`);
124
+ path_1.default.join(widgetFolderAbsolutePath, GENERATED_ENTITLEMENTS_FILE_NAME);
66
125
  if (entitlementsFiles[0]) {
67
- console.log(`[${widget}] Replacing ${path_1.default.relative(widgetFolderAbsolutePath, entitlementsFiles[0])} with entitlements JSON from config`);
126
+ const relativeName = path_1.default.relative(widgetFolderAbsolutePath, entitlementsFiles[0]);
127
+ if (relativeName !== GENERATED_ENTITLEMENTS_FILE_NAME) {
128
+ console.log(`[${widget}] Replacing ${path_1.default.relative(widgetFolderAbsolutePath, entitlementsFiles[0])} with entitlements JSON from config`);
129
+ }
68
130
  }
69
131
  fs_1.default.writeFileSync(entitlementsFilePath, plist_1.default.build(entitlementsJson));
70
132
  return config;
@@ -80,10 +142,7 @@ const withWidget = (config, props) => {
80
142
  (0, config_plugins_1.withDangerousMod)(config, [
81
143
  "ios",
82
144
  async (config) => {
83
- if (!hasWarned) {
84
- hasWarned = true;
85
- console.warn("You're using an experimental Config Plugin that is subject to breaking changes and has no E2E tests.");
86
- }
145
+ prebuildLogQueue.flush();
87
146
  fs_1.default.mkdirSync(widgetFolderAbsolutePath, { recursive: true });
88
147
  const files = [
89
148
  ["Info.plist", (0, target_1.getTargetInfoPlistForType)(props.type)],
@@ -179,6 +238,7 @@ const withConfigColors = (config, props) => {
179
238
  });
180
239
  });
181
240
  }
241
+ // TODO: Add clean-up maybe? This would possibly restrict the ability to create native colors outside of the Expo target config.
182
242
  return config;
183
243
  };
184
244
  exports.default = withWidget;
@@ -634,7 +634,7 @@ function createConfigurationListForType(project, props) {
634
634
  }
635
635
  }
636
636
  async function applyXcodeChanges(config, project, props) {
637
- var _a, _b;
637
+ var _a;
638
638
  const mainAppTarget = (0, target_1.getMainAppTarget)(project);
639
639
  // Special setting for share extensions.
640
640
  if ((0, target_1.needsEmbeddedSwift)(props.type)) {
@@ -653,20 +653,11 @@ async function applyXcodeChanges(config, project, props) {
653
653
  console.log(`Target "${targetToUpdate.props.productName}" already exists, updating instead of creating a new one`);
654
654
  }
655
655
  const magicCwd = path_1.default.join(config._internal.projectRoot, "ios", props.cwd);
656
- let developmentTeamId = (_b = props.teamId) !== null && _b !== void 0 ? _b : mainAppTarget.getDefaultBuildSetting("DEVELOPMENT_TEAM");
657
- if (!developmentTeamId) {
658
- console.error("Couldn't find DEVELOPMENT_TEAM in Xcode project and none were provided in the Expo config. Using placeholder value.");
659
- // Using a placeholder gives users a chance to see the value in Xcode.
660
- developmentTeamId = "XXXXXXXXXX";
661
- // throw new Error(
662
- // "Couldn't find DEVELOPMENT_TEAM in Xcode project and none were provided in the Expo config."
663
- // );
664
- }
665
656
  function applyDevelopmentTeamIdToTargets() {
666
657
  var _a, _b;
667
658
  var _c, _d, _e;
668
659
  // Set to the provided value or any value.
669
- const devTeamId = developmentTeamId ||
660
+ const devTeamId = props.teamId ||
670
661
  project.rootObject.props.targets
671
662
  .map((target) => target.getDefaultBuildSetting("DEVELOPMENT_TEAM"))
672
663
  .find(Boolean);
package/package.json CHANGED
@@ -1,11 +1,12 @@
1
1
  {
2
2
  "name": "@bacons/apple-targets",
3
- "version": "0.1.8",
3
+ "version": "0.1.10",
4
4
  "description": "Generate Apple Targets with Expo Prebuild",
5
5
  "main": "build/ExtensionStorage.js",
6
6
  "types": "build/ExtensionStorage.d.ts",
7
7
  "files": [
8
8
  "app.plugin.js",
9
+ "app.plugin.d.ts",
9
10
  "build",
10
11
  "ios",
11
12
  "expo-module.config.json",