| 1 | "use strict"; |
| 2 | |
| 3 | // Ships the knife silhouette to the Live Activity / widget extension. |
| 4 | // |
| 5 | // expo-widgets generates ExpoWidgetsTarget without a Resources build phase and |
| 6 | // has no asset support, so this plugin (a) writes a template image set into |
| 7 | // the generated widget asset catalog and (b) wires that catalog into the widget |
| 8 | // target with an actool build phase. |
| 9 | // |
| 10 | // ORDERING: must be listed BEFORE "expo-widgets" in the plugins array. Expo |
| 11 | // chains same-type mods so the last-registered runs FIRST; registering this |
| 12 | // plugin earlier makes its mods run AFTER expo-widgets' mods. That matters |
| 13 | // twice: expo-widgets' dangerous mod rmSync's ios/ExpoWidgetsTarget/ (deleting |
| 14 | // any catalog written before it), and its xcodeproj mod is what creates the |
| 15 | // widget target. Listed after expo-widgets, both steps silently no-op on a |
| 16 | // fresh prebuild — which is how prod build 8 shipped without the logo. |
| 17 | |
| 18 | const path = require("path"); |
| 19 | const fs = require("fs"); |
| 20 | const { withDangerousMod, withXcodeProject } = require("expo/config-plugins"); |
| 21 | const { addWidgetAssetCatalog } = require("./lib/addWidgetAssetCatalog.cjs"); |
| 22 | |
| 23 | const TARGET_NAME = "ExpoWidgetsTarget"; |
| 24 | const CATALOG_NAME = "Assets.xcassets"; |
| 25 | const IMAGE_SET = "KnifeMark.imageset"; |
| 26 | const IMAGE_NAME = "knife.png"; |
| 27 | |
| 28 | const CATALOG_CONTENTS = JSON.stringify({ info: { author: "expo", version: 1 } }, null, 2) + "\n"; |
| 29 | const IMAGE_SET_CONTENTS = |
| 30 | JSON.stringify( |
| 31 | { |
| 32 | images: [{ idiom: "universal", filename: IMAGE_NAME }], |
| 33 | info: { author: "expo", version: 1 }, |
| 34 | properties: { |
| 35 | "template-rendering-intent": "template", |
| 36 | }, |
| 37 | }, |
| 38 | null, |
| 39 | 2, |
| 40 | ) + "\n"; |
| 41 | |
| 42 | function withAssetFiles(config) { |
| 43 | return withDangerousMod(config, [ |
| 44 | "ios", |
| 45 | (cfg) => { |
| 46 | const source = path.resolve( |
| 47 | cfg.modRequest.projectRoot, |
| 48 | "../../assets/knife/android-foreground.png", |
| 49 | ); |
| 50 | const catalogDir = path.join(cfg.modRequest.platformProjectRoot, TARGET_NAME, CATALOG_NAME); |
| 51 | const imageSetDir = path.join(catalogDir, IMAGE_SET); |
| 52 | fs.mkdirSync(imageSetDir, { recursive: true }); |
| 53 | fs.writeFileSync(path.join(catalogDir, "Contents.json"), CATALOG_CONTENTS); |
| 54 | fs.writeFileSync(path.join(imageSetDir, "Contents.json"), IMAGE_SET_CONTENTS); |
| 55 | fs.copyFileSync(source, path.join(imageSetDir, IMAGE_NAME)); |
| 56 | return cfg; |
| 57 | }, |
| 58 | ]); |
| 59 | } |
| 60 | |
| 61 | function withAssetWiring(config) { |
| 62 | return withXcodeProject(config, (cfg) => { |
| 63 | addWidgetAssetCatalog(cfg.modResults, { targetName: TARGET_NAME }); |
| 64 | return cfg; |
| 65 | }); |
| 66 | } |
| 67 | |
| 68 | module.exports = function withWidgetLogoAsset(config) { |
| 69 | return withAssetWiring(withAssetFiles(config)); |
| 70 | }; |