@bacons/apple-targets 0.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/LICENSE +21 -0
- package/README.md +218 -0
- package/app.plugin.js +1 -0
- package/build/colorset/customColorFromCSS.d.ts +10 -0
- package/build/colorset/customColorFromCSS.js +23 -0
- package/build/colorset/withIosColorset.d.ts +11 -0
- package/build/colorset/withIosColorset.js +65 -0
- package/build/config.d.ts +103 -0
- package/build/config.js +2 -0
- package/build/icon/withImageAsset.d.ts +26 -0
- package/build/icon/withImageAsset.js +250 -0
- package/build/icon/withIosIcon.d.ts +19 -0
- package/build/icon/withIosIcon.js +211 -0
- package/build/index.d.ts +8 -0
- package/build/index.js +29 -0
- package/build/target.d.ts +10 -0
- package/build/target.js +322 -0
- package/build/template/XCBuildConfiguration.json +759 -0
- package/build/withEasCredentials.d.ts +17 -0
- package/build/withEasCredentials.js +95 -0
- package/build/withWidget.d.ts +7 -0
- package/build/withWidget.js +158 -0
- package/build/withXcodeChanges.d.ts +17 -0
- package/build/withXcodeChanges.js +975 -0
- package/build/withXcparse.d.ts +4 -0
- package/build/withXcparse.js +77 -0
- package/package.json +41 -0
|
@@ -0,0 +1,250 @@
|
|
|
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 (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
25
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
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");
|
|
28
|
+
const image_utils_1 = require("@expo/image-utils");
|
|
29
|
+
const AssetContents_1 = require("@expo/prebuild-config/build/plugins/icons/AssetContents");
|
|
30
|
+
const fs = __importStar(require("fs-extra"));
|
|
31
|
+
const path_1 = __importStar(require("path"));
|
|
32
|
+
const withImageAsset = (config, { cwd, name, image }) => {
|
|
33
|
+
return (0, config_plugins_1.withDangerousMod)(config, [
|
|
34
|
+
"ios",
|
|
35
|
+
async (config) => {
|
|
36
|
+
const projectRoot = config.modRequest.projectRoot;
|
|
37
|
+
const iosNamedProjectRoot = (0, path_1.join)(projectRoot, cwd);
|
|
38
|
+
const imgPath = `Assets.xcassets/${name}.imageset`;
|
|
39
|
+
// Ensure the Images.xcassets/AppIcon.appiconset path exists
|
|
40
|
+
await fs.ensureDir((0, path_1.join)(iosNamedProjectRoot, imgPath));
|
|
41
|
+
const userDefinedIcon = typeof image === "string"
|
|
42
|
+
? { "1x": image, "2x": undefined, "3x": undefined }
|
|
43
|
+
: image;
|
|
44
|
+
// Finally, write the Config.json
|
|
45
|
+
await (0, AssetContents_1.writeContentsJsonAsync)((0, path_1.join)(iosNamedProjectRoot, imgPath), {
|
|
46
|
+
images: await generateResizedImageAsync(Object.fromEntries(Object.entries(userDefinedIcon).map(([key, value]) => [
|
|
47
|
+
key,
|
|
48
|
+
(value === null || value === void 0 ? void 0 : value.match(/^[./]/)) ? path_1.default.join(cwd, value) : value,
|
|
49
|
+
])), name, projectRoot, iosNamedProjectRoot, path_1.default.join(cwd, "gen-image", name)),
|
|
50
|
+
});
|
|
51
|
+
return config;
|
|
52
|
+
},
|
|
53
|
+
]);
|
|
54
|
+
};
|
|
55
|
+
exports.withImageAsset = withImageAsset;
|
|
56
|
+
const IMAGE_CACHE_NAME = "widget-icons-";
|
|
57
|
+
const IMAGESET_PATH = "Assets.xcassets/AppIcon.appiconset";
|
|
58
|
+
// Hard-coding seemed like the clearest and safest way to implement the sizes.
|
|
59
|
+
exports.ICON_CONTENTS = [
|
|
60
|
+
{
|
|
61
|
+
idiom: "iphone",
|
|
62
|
+
sizes: [
|
|
63
|
+
{
|
|
64
|
+
size: 20,
|
|
65
|
+
scales: [2, 3],
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
size: 29,
|
|
69
|
+
scales: [1, 2, 3],
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
size: 40,
|
|
73
|
+
scales: [2, 3],
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
size: 60,
|
|
77
|
+
scales: [2, 3],
|
|
78
|
+
},
|
|
79
|
+
// TODO: 76x76@2x seems unused now
|
|
80
|
+
// {
|
|
81
|
+
// size: 76,
|
|
82
|
+
// scales: [2],
|
|
83
|
+
// },
|
|
84
|
+
],
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
idiom: "ipad",
|
|
88
|
+
sizes: [
|
|
89
|
+
{
|
|
90
|
+
size: 20,
|
|
91
|
+
scales: [1, 2],
|
|
92
|
+
},
|
|
93
|
+
{
|
|
94
|
+
size: 29,
|
|
95
|
+
scales: [1, 2],
|
|
96
|
+
},
|
|
97
|
+
{
|
|
98
|
+
size: 40,
|
|
99
|
+
scales: [1, 2],
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
size: 76,
|
|
103
|
+
scales: [1, 2],
|
|
104
|
+
},
|
|
105
|
+
{
|
|
106
|
+
size: 83.5,
|
|
107
|
+
scales: [2],
|
|
108
|
+
},
|
|
109
|
+
],
|
|
110
|
+
},
|
|
111
|
+
{
|
|
112
|
+
idiom: "ios-marketing",
|
|
113
|
+
sizes: [
|
|
114
|
+
{
|
|
115
|
+
size: 1024,
|
|
116
|
+
scales: [1],
|
|
117
|
+
},
|
|
118
|
+
],
|
|
119
|
+
},
|
|
120
|
+
];
|
|
121
|
+
async function setIconsAsync(icon, projectRoot, iosNamedProjectRoot, cacheComponent) {
|
|
122
|
+
// Ensure the Images.xcassets/AppIcon.appiconset path exists
|
|
123
|
+
await fs.ensureDir((0, path_1.join)(iosNamedProjectRoot, IMAGESET_PATH));
|
|
124
|
+
// Finally, write the Config.json
|
|
125
|
+
await (0, AssetContents_1.writeContentsJsonAsync)((0, path_1.join)(iosNamedProjectRoot, IMAGESET_PATH), {
|
|
126
|
+
images: await generateIconsInternalAsync(icon, projectRoot, iosNamedProjectRoot, cacheComponent),
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
exports.setIconsAsync = setIconsAsync;
|
|
130
|
+
async function generateResizedImageAsync(icon, name, projectRoot, iosNamedProjectRoot, cacheComponent) {
|
|
131
|
+
// Store the image JSON data for assigning via the Contents.json
|
|
132
|
+
const imagesJson = [];
|
|
133
|
+
// If the user provided a single image, then assume it's the 3x image and generate the 1x and 2x images.
|
|
134
|
+
// const shouldResize = typeof icon === "string";
|
|
135
|
+
const userDefinedIcon = typeof icon === "string"
|
|
136
|
+
? { "1x": icon, "2x": undefined, "3x": undefined }
|
|
137
|
+
: icon;
|
|
138
|
+
for (const icon of Object.entries(userDefinedIcon)) {
|
|
139
|
+
const [scale, iconPath] = icon;
|
|
140
|
+
const filename = `${scale}.png`;
|
|
141
|
+
const imgEntry = {
|
|
142
|
+
idiom: "universal",
|
|
143
|
+
// @ts-ignore: template types not supported in TS yet
|
|
144
|
+
scale,
|
|
145
|
+
};
|
|
146
|
+
if (iconPath) {
|
|
147
|
+
// Using this method will cache the images in `.expo` based on the properties used to generate them.
|
|
148
|
+
// this method also supports remote URLs and using the global sharp instance.
|
|
149
|
+
const { source } = await (0, image_utils_1.generateImageAsync)({ projectRoot, cacheType: IMAGE_CACHE_NAME + cacheComponent },
|
|
150
|
+
// @ts-expect-error
|
|
151
|
+
{
|
|
152
|
+
src: iconPath,
|
|
153
|
+
name: filename,
|
|
154
|
+
});
|
|
155
|
+
// Write image buffer to the file system.
|
|
156
|
+
const assetPath = (0, path_1.join)(iosNamedProjectRoot, `Assets.xcassets/${name}.imageset`, filename);
|
|
157
|
+
await fs.writeFile(assetPath, source);
|
|
158
|
+
if (filename) {
|
|
159
|
+
imgEntry.filename = filename;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
imagesJson.push(imgEntry);
|
|
163
|
+
}
|
|
164
|
+
return imagesJson;
|
|
165
|
+
}
|
|
166
|
+
exports.generateResizedImageAsync = generateResizedImageAsync;
|
|
167
|
+
async function generateIconsInternalAsync(icon, projectRoot, iosNamedProjectRoot, cacheComponent) {
|
|
168
|
+
// Store the image JSON data for assigning via the Contents.json
|
|
169
|
+
const imagesJson = [];
|
|
170
|
+
// keep track of icons that have been generated so we can reuse them in the Contents.json
|
|
171
|
+
const generatedIcons = {};
|
|
172
|
+
for (const platform of exports.ICON_CONTENTS) {
|
|
173
|
+
const isMarketing = platform.idiom === "ios-marketing";
|
|
174
|
+
for (const { size, scales } of platform.sizes) {
|
|
175
|
+
for (const scale of scales) {
|
|
176
|
+
// The marketing icon is special because it makes no sense.
|
|
177
|
+
const filename = isMarketing
|
|
178
|
+
? "ItunesArtwork@2x.png"
|
|
179
|
+
: getAppleIconName(size, scale);
|
|
180
|
+
// Only create an image that hasn't already been generated.
|
|
181
|
+
if (!(filename in generatedIcons)) {
|
|
182
|
+
const iconSizePx = size * scale;
|
|
183
|
+
// Using this method will cache the images in `.expo` based on the properties used to generate them.
|
|
184
|
+
// this method also supports remote URLs and using the global sharp instance.
|
|
185
|
+
const { source } = await (0, image_utils_1.generateImageAsync)({ projectRoot, cacheType: IMAGE_CACHE_NAME + cacheComponent }, {
|
|
186
|
+
src: icon,
|
|
187
|
+
name: filename,
|
|
188
|
+
width: iconSizePx,
|
|
189
|
+
height: iconSizePx,
|
|
190
|
+
removeTransparency: true,
|
|
191
|
+
// The icon should be square, but if it's not then it will be cropped.
|
|
192
|
+
resizeMode: "cover",
|
|
193
|
+
// Force the background color to solid white to prevent any transparency.
|
|
194
|
+
// TODO: Maybe use a more adaptive option based on the icon color?
|
|
195
|
+
backgroundColor: "#ffffff",
|
|
196
|
+
});
|
|
197
|
+
// Write image buffer to the file system.
|
|
198
|
+
const assetPath = (0, path_1.join)(iosNamedProjectRoot, IMAGESET_PATH, filename);
|
|
199
|
+
await fs.writeFile(assetPath, source);
|
|
200
|
+
// Save a reference to the generated image so we don't create a duplicate.
|
|
201
|
+
generatedIcons[filename] = true;
|
|
202
|
+
}
|
|
203
|
+
imagesJson.push({
|
|
204
|
+
idiom: platform.idiom,
|
|
205
|
+
size: `${size}x${size}`,
|
|
206
|
+
// @ts-ignore: template types not supported in TS yet
|
|
207
|
+
scale: `${scale}x`,
|
|
208
|
+
filename,
|
|
209
|
+
});
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
return imagesJson;
|
|
214
|
+
}
|
|
215
|
+
exports.generateIconsInternalAsync = generateIconsInternalAsync;
|
|
216
|
+
async function generateWatchIconsInternalAsync(icon, projectRoot, iosNamedProjectRoot, cacheComponent) {
|
|
217
|
+
// Store the image JSON data for assigning via the Contents.json
|
|
218
|
+
const imagesJson = [];
|
|
219
|
+
const size = 1024;
|
|
220
|
+
const filename = getAppleIconName(size, 1);
|
|
221
|
+
// Using this method will cache the images in `.expo` based on the properties used to generate them.
|
|
222
|
+
// this method also supports remote URLs and using the global sharp instance.
|
|
223
|
+
const { source } = await (0, image_utils_1.generateImageAsync)({ projectRoot, cacheType: IMAGE_CACHE_NAME + cacheComponent }, {
|
|
224
|
+
src: icon,
|
|
225
|
+
name: filename,
|
|
226
|
+
width: size,
|
|
227
|
+
height: size,
|
|
228
|
+
removeTransparency: true,
|
|
229
|
+
// The icon should be square, but if it's not then it will be cropped.
|
|
230
|
+
resizeMode: "cover",
|
|
231
|
+
// Force the background color to solid white to prevent any transparency.
|
|
232
|
+
// TODO: Maybe use a more adaptive option based on the icon color?
|
|
233
|
+
backgroundColor: "#ffffff",
|
|
234
|
+
});
|
|
235
|
+
// Write image buffer to the file system.
|
|
236
|
+
const assetPath = (0, path_1.join)(iosNamedProjectRoot, IMAGESET_PATH, filename);
|
|
237
|
+
await fs.writeFile(assetPath, source);
|
|
238
|
+
imagesJson.push({
|
|
239
|
+
filename: getAppleIconName(size, 1),
|
|
240
|
+
idiom: "universal",
|
|
241
|
+
// @ts-expect-error
|
|
242
|
+
platform: "watchos",
|
|
243
|
+
size: `${size}x${size}`,
|
|
244
|
+
});
|
|
245
|
+
return imagesJson;
|
|
246
|
+
}
|
|
247
|
+
exports.generateWatchIconsInternalAsync = generateWatchIconsInternalAsync;
|
|
248
|
+
function getAppleIconName(size, scale) {
|
|
249
|
+
return `App-Icon-${size}x${size}@${scale}x.png`;
|
|
250
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { ConfigPlugin } from "@expo/config-plugins";
|
|
2
|
+
import { ContentsJsonImageIdiom } from "@expo/prebuild-config/build/plugins/icons/AssetContents";
|
|
3
|
+
import { ExtensionType } from "../target";
|
|
4
|
+
export declare const withIosIcon: ConfigPlugin<{
|
|
5
|
+
cwd: string;
|
|
6
|
+
type: ExtensionType;
|
|
7
|
+
iconFilePath: string;
|
|
8
|
+
isTransparent?: boolean;
|
|
9
|
+
}>;
|
|
10
|
+
export declare const ICON_CONTENTS: {
|
|
11
|
+
idiom: ContentsJsonImageIdiom;
|
|
12
|
+
sizes: {
|
|
13
|
+
size: number;
|
|
14
|
+
scales: (1 | 2 | 3)[];
|
|
15
|
+
}[];
|
|
16
|
+
}[];
|
|
17
|
+
export declare function setIconsAsync(icon: string, projectRoot: string, iosNamedProjectRoot: string, cacheComponent: string, isTransparent: boolean): Promise<void>;
|
|
18
|
+
export declare function generateIconsInternalAsync(icon: string, projectRoot: string, iosNamedProjectRoot: string, cacheComponent: string, isTransparent: boolean): Promise<import("@expo/prebuild-config/build/plugins/icons/AssetContents").ContentsJsonImage[]>;
|
|
19
|
+
export declare function generateWatchIconsInternalAsync(icon: string, projectRoot: string, iosNamedProjectRoot: string, cacheComponent: string, isTransparent: boolean): Promise<import("@expo/prebuild-config/build/plugins/icons/AssetContents").ContentsJsonImage[]>;
|
|
@@ -0,0 +1,211 @@
|
|
|
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 (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
25
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
+
exports.generateWatchIconsInternalAsync = exports.generateIconsInternalAsync = exports.setIconsAsync = exports.ICON_CONTENTS = exports.withIosIcon = void 0;
|
|
27
|
+
const config_plugins_1 = require("@expo/config-plugins");
|
|
28
|
+
const image_utils_1 = require("@expo/image-utils");
|
|
29
|
+
const AssetContents_1 = require("@expo/prebuild-config/build/plugins/icons/AssetContents");
|
|
30
|
+
const fs = __importStar(require("fs-extra"));
|
|
31
|
+
const path_1 = require("path");
|
|
32
|
+
const withIosIcon = (config, { cwd, type, iconFilePath, isTransparent = false }) => {
|
|
33
|
+
return (0, config_plugins_1.withDangerousMod)(config, [
|
|
34
|
+
"ios",
|
|
35
|
+
async (config) => {
|
|
36
|
+
const projectRoot = config.modRequest.projectRoot;
|
|
37
|
+
const namedProjectRoot = (0, path_1.join)(projectRoot, cwd);
|
|
38
|
+
if (type === "watch") {
|
|
39
|
+
// Ensure the Images.xcassets/AppIcon.appiconset path exists
|
|
40
|
+
await fs.ensureDir((0, path_1.join)(namedProjectRoot, IMAGESET_PATH));
|
|
41
|
+
// Finally, write the Config.json
|
|
42
|
+
await (0, AssetContents_1.writeContentsJsonAsync)((0, path_1.join)(namedProjectRoot, IMAGESET_PATH), {
|
|
43
|
+
images: await generateWatchIconsInternalAsync(iconFilePath, projectRoot, namedProjectRoot, cwd, isTransparent),
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
else {
|
|
47
|
+
await setIconsAsync(iconFilePath, projectRoot, (0, path_1.join)(projectRoot, cwd), cwd, isTransparent);
|
|
48
|
+
}
|
|
49
|
+
return config;
|
|
50
|
+
},
|
|
51
|
+
]);
|
|
52
|
+
};
|
|
53
|
+
exports.withIosIcon = withIosIcon;
|
|
54
|
+
const IMAGE_CACHE_NAME = "widget-icons-";
|
|
55
|
+
const IMAGESET_PATH = "Assets.xcassets/AppIcon.appiconset";
|
|
56
|
+
// Hard-coding seemed like the clearest and safest way to implement the sizes.
|
|
57
|
+
exports.ICON_CONTENTS = [
|
|
58
|
+
{
|
|
59
|
+
idiom: "iphone",
|
|
60
|
+
sizes: [
|
|
61
|
+
{
|
|
62
|
+
size: 20,
|
|
63
|
+
scales: [2, 3],
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
size: 29,
|
|
67
|
+
scales: [1, 2, 3],
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
size: 40,
|
|
71
|
+
scales: [2, 3],
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
size: 60,
|
|
75
|
+
scales: [2, 3],
|
|
76
|
+
},
|
|
77
|
+
// TODO: 76x76@2x seems unused now
|
|
78
|
+
// {
|
|
79
|
+
// size: 76,
|
|
80
|
+
// scales: [2],
|
|
81
|
+
// },
|
|
82
|
+
],
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
idiom: "ipad",
|
|
86
|
+
sizes: [
|
|
87
|
+
{
|
|
88
|
+
size: 20,
|
|
89
|
+
scales: [1, 2],
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
size: 29,
|
|
93
|
+
scales: [1, 2],
|
|
94
|
+
},
|
|
95
|
+
{
|
|
96
|
+
size: 40,
|
|
97
|
+
scales: [1, 2],
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
size: 76,
|
|
101
|
+
scales: [1, 2],
|
|
102
|
+
},
|
|
103
|
+
{
|
|
104
|
+
size: 83.5,
|
|
105
|
+
scales: [2],
|
|
106
|
+
},
|
|
107
|
+
],
|
|
108
|
+
},
|
|
109
|
+
{
|
|
110
|
+
idiom: "ios-marketing",
|
|
111
|
+
sizes: [
|
|
112
|
+
{
|
|
113
|
+
size: 1024,
|
|
114
|
+
scales: [1],
|
|
115
|
+
},
|
|
116
|
+
],
|
|
117
|
+
},
|
|
118
|
+
];
|
|
119
|
+
async function setIconsAsync(icon, projectRoot, iosNamedProjectRoot, cacheComponent, isTransparent) {
|
|
120
|
+
// Ensure the Images.xcassets/AppIcon.appiconset path exists
|
|
121
|
+
await fs.ensureDir((0, path_1.join)(iosNamedProjectRoot, IMAGESET_PATH));
|
|
122
|
+
// Finally, write the Config.json
|
|
123
|
+
await (0, AssetContents_1.writeContentsJsonAsync)((0, path_1.join)(iosNamedProjectRoot, IMAGESET_PATH), {
|
|
124
|
+
images: await generateIconsInternalAsync(icon, projectRoot, iosNamedProjectRoot, cacheComponent, isTransparent),
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
exports.setIconsAsync = setIconsAsync;
|
|
128
|
+
async function generateIconsInternalAsync(icon, projectRoot, iosNamedProjectRoot, cacheComponent, isTransparent) {
|
|
129
|
+
// Store the image JSON data for assigning via the Contents.json
|
|
130
|
+
const imagesJson = [];
|
|
131
|
+
// keep track of icons that have been generated so we can reuse them in the Contents.json
|
|
132
|
+
const generatedIcons = {};
|
|
133
|
+
for (const platform of exports.ICON_CONTENTS) {
|
|
134
|
+
const isMarketing = platform.idiom === "ios-marketing";
|
|
135
|
+
for (const { size, scales } of platform.sizes) {
|
|
136
|
+
for (const scale of scales) {
|
|
137
|
+
// The marketing icon is special because it makes no sense.
|
|
138
|
+
const filename = isMarketing
|
|
139
|
+
? "ItunesArtwork@2x.png"
|
|
140
|
+
: getAppleIconName(size, scale);
|
|
141
|
+
// Only create an image that hasn't already been generated.
|
|
142
|
+
if (!(filename in generatedIcons)) {
|
|
143
|
+
const iconSizePx = size * scale;
|
|
144
|
+
// Using this method will cache the images in `.expo` based on the properties used to generate them.
|
|
145
|
+
// this method also supports remote URLs and using the global sharp instance.
|
|
146
|
+
const { source } = await (0, image_utils_1.generateImageAsync)({ projectRoot, cacheType: IMAGE_CACHE_NAME + cacheComponent }, {
|
|
147
|
+
src: icon,
|
|
148
|
+
name: filename,
|
|
149
|
+
width: iconSizePx,
|
|
150
|
+
height: iconSizePx,
|
|
151
|
+
removeTransparency: !isTransparent,
|
|
152
|
+
// The icon should be square, but if it's not then it will be cropped.
|
|
153
|
+
resizeMode: "cover",
|
|
154
|
+
// Force the background color to solid white to prevent any transparency.
|
|
155
|
+
// TODO: Maybe use a more adaptive option based on the icon color?
|
|
156
|
+
backgroundColor: isTransparent ? "#ffffff00" : "#ffffff",
|
|
157
|
+
});
|
|
158
|
+
// Write image buffer to the file system.
|
|
159
|
+
const assetPath = (0, path_1.join)(iosNamedProjectRoot, IMAGESET_PATH, filename);
|
|
160
|
+
await fs.writeFile(assetPath, source);
|
|
161
|
+
// Save a reference to the generated image so we don't create a duplicate.
|
|
162
|
+
generatedIcons[filename] = true;
|
|
163
|
+
}
|
|
164
|
+
imagesJson.push({
|
|
165
|
+
idiom: platform.idiom,
|
|
166
|
+
size: `${size}x${size}`,
|
|
167
|
+
// @ts-ignore: template types not supported in TS yet
|
|
168
|
+
scale: `${scale}x`,
|
|
169
|
+
filename,
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
return imagesJson;
|
|
175
|
+
}
|
|
176
|
+
exports.generateIconsInternalAsync = generateIconsInternalAsync;
|
|
177
|
+
async function generateWatchIconsInternalAsync(icon, projectRoot, iosNamedProjectRoot, cacheComponent, isTransparent) {
|
|
178
|
+
// Store the image JSON data for assigning via the Contents.json
|
|
179
|
+
const imagesJson = [];
|
|
180
|
+
const size = 1024;
|
|
181
|
+
const filename = getAppleIconName(size, 1);
|
|
182
|
+
// Using this method will cache the images in `.expo` based on the properties used to generate them.
|
|
183
|
+
// this method also supports remote URLs and using the global sharp instance.
|
|
184
|
+
const { source } = await (0, image_utils_1.generateImageAsync)({ projectRoot, cacheType: IMAGE_CACHE_NAME + cacheComponent }, {
|
|
185
|
+
src: icon,
|
|
186
|
+
name: filename,
|
|
187
|
+
width: size,
|
|
188
|
+
height: size,
|
|
189
|
+
removeTransparency: !isTransparent,
|
|
190
|
+
// The icon should be square, but if it's not then it will be cropped.
|
|
191
|
+
resizeMode: "cover",
|
|
192
|
+
// Force the background color to solid white to prevent any transparency.
|
|
193
|
+
// TODO: Maybe use a more adaptive option based on the icon color?
|
|
194
|
+
backgroundColor: isTransparent ? "#ffffff00" : "#ffffff",
|
|
195
|
+
});
|
|
196
|
+
// Write image buffer to the file system.
|
|
197
|
+
const assetPath = (0, path_1.join)(iosNamedProjectRoot, IMAGESET_PATH, filename);
|
|
198
|
+
await fs.writeFile(assetPath, source);
|
|
199
|
+
imagesJson.push({
|
|
200
|
+
filename: getAppleIconName(size, 1),
|
|
201
|
+
idiom: "universal",
|
|
202
|
+
// @ts-expect-error
|
|
203
|
+
platform: "watchos",
|
|
204
|
+
size: `${size}x${size}`,
|
|
205
|
+
});
|
|
206
|
+
return imagesJson;
|
|
207
|
+
}
|
|
208
|
+
exports.generateWatchIconsInternalAsync = generateWatchIconsInternalAsync;
|
|
209
|
+
function getAppleIconName(size, scale) {
|
|
210
|
+
return `App-Icon-${size}x${size}@${scale}x.png`;
|
|
211
|
+
}
|
package/build/index.d.ts
ADDED
package/build/index.js
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.withTargetsDir = void 0;
|
|
7
|
+
const glob_1 = require("glob");
|
|
8
|
+
const path_1 = __importDefault(require("path"));
|
|
9
|
+
const withWidget_1 = __importDefault(require("./withWidget"));
|
|
10
|
+
const withXcparse_1 = require("./withXcparse");
|
|
11
|
+
const withTargetsDir = (config, { appleTeamId, root = "./targets", match = "*" }) => {
|
|
12
|
+
console.warn("You're using an experimental Config Plugin that is subject to breaking changes and has no E2E tests.");
|
|
13
|
+
const projectRoot = config._internal.projectRoot;
|
|
14
|
+
const targets = (0, glob_1.sync)(`${root}/${match}/expo-target.config.@(json|js)`, {
|
|
15
|
+
// const targets = globSync(`./targets/action/expo-target.config.@(json|js)`, {
|
|
16
|
+
cwd: projectRoot,
|
|
17
|
+
absolute: true,
|
|
18
|
+
});
|
|
19
|
+
targets.forEach((configPath) => {
|
|
20
|
+
config = (0, withWidget_1.default)(config, {
|
|
21
|
+
appleTeamId,
|
|
22
|
+
...require(configPath),
|
|
23
|
+
directory: path_1.default.relative(projectRoot, path_1.default.dirname(configPath)),
|
|
24
|
+
});
|
|
25
|
+
});
|
|
26
|
+
return (0, withXcparse_1.withXcodeProjectBetaBaseMod)(config);
|
|
27
|
+
};
|
|
28
|
+
exports.withTargetsDir = withTargetsDir;
|
|
29
|
+
module.exports = exports.withTargetsDir;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { PBXNativeTarget, XcodeProject } from "@bacons/xcode";
|
|
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";
|
|
3
|
+
export declare const KNOWN_EXTENSION_POINT_IDENTIFIERS: Record<string, ExtensionType>;
|
|
4
|
+
export declare function getTargetInfoPlistForType(type: ExtensionType): string;
|
|
5
|
+
export declare function productTypeForType(type: ExtensionType): "com.apple.product-type.application.on-demand-install-capable" | "com.apple.product-type.application" | "com.apple.product-type.app-extension";
|
|
6
|
+
export declare function needsEmbeddedSwift(type: ExtensionType): boolean;
|
|
7
|
+
export declare function getFrameworksForType(type: ExtensionType): string[];
|
|
8
|
+
export declare function isNativeTargetOfType(target: PBXNativeTarget, type: ExtensionType): boolean;
|
|
9
|
+
export declare function getMainAppTarget(project: XcodeProject): PBXNativeTarget;
|
|
10
|
+
export declare function getAuxiliaryTargets(project: XcodeProject): PBXNativeTarget[];
|