UNPKG

expo-asset

Version:

An Expo universal module to download assets and pass them into other APIs

94 lines (79 loc) 2.98 kB
import { type ImageOptions, generateImageAsync } from '@expo/image-utils'; import type { ExpoConfig } from 'expo/config'; import { type ConfigPlugin, IOSConfig, type XcodeProject, withXcodeProject, } from 'expo/config-plugins'; import fs from 'fs/promises'; import path from 'path'; import { type ContentsJsonImage, writeContentsJsonAsync } from './AssetContents'; import { IMAGE_TYPES, resolveAssetPaths, validateAssets } from './utils'; const IMAGE_DIR = 'Images.xcassets'; export const withAssetsIos: ConfigPlugin<string[]> = (config, assets) => { config = addAssetsToTarget(config, assets); return config; }; function addAssetsToTarget(config: ExpoConfig, assets: string[]) { return withXcodeProject(config, async (config) => { const resolvedAssets = await resolveAssetPaths(assets, config.modRequest.projectRoot); const validAssets = validateAssets(resolvedAssets); const project = config.modResults; const platformProjectRoot = config.modRequest.platformProjectRoot; IOSConfig.XcodeUtils.ensureGroupRecursively(project, 'Resources'); const images = validAssets.filter((asset) => IMAGE_TYPES.includes(path.extname(asset))); const assetsForResourcesDir = validAssets.filter( (asset) => !IMAGE_TYPES.includes(path.extname(asset)) ); await addImageAssets(images, config.modRequest.projectRoot); addResourceFiles(project, platformProjectRoot, assetsForResourcesDir); return config; }); } function addResourceFiles(project: XcodeProject, platformRoot: string, assets: string[]) { for (const asset of assets) { const assetPath = path.relative(platformRoot, asset); IOSConfig.XcodeUtils.addResourceFileToGroup({ filepath: assetPath, groupName: 'Resources', project, isBuildFile: true, verbose: true, }); } } async function addImageAssets(assets: string[], root: string) { const iosNamedProjectRoot = IOSConfig.Paths.getSourceRoot(root); for (const asset of assets) { const name = path.basename(asset, path.extname(asset)); const image = path.basename(asset); const assetPath = path.resolve(iosNamedProjectRoot, `${IMAGE_DIR}/${name}.imageset`); await fs.mkdir(assetPath, { recursive: true }); const buffer = await generateImageAsync({ projectRoot: root }, { src: asset, } as unknown as ImageOptions); await fs.writeFile(path.resolve(assetPath, image), buffer.source); await writeContentsJsonFileAsync({ assetPath, image, }); } } async function writeContentsJsonFileAsync({ assetPath, image, }: { assetPath: string; image: string; }) { const images = buildContentsJsonImages({ image }); await writeContentsJsonAsync(assetPath, { images }); } function buildContentsJsonImages({ image }: { image: string }): ContentsJsonImage[] { return [ { idiom: 'universal', filename: image, scale: '1x' }, { idiom: 'universal', scale: '2x' }, { idiom: 'universal', scale: '3x' }, ]; }