@wwdrew/expo-apple-music 1.1.0 → 1.1.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wwdrew/expo-apple-music",
3
- "version": "1.1.0",
3
+ "version": "1.1.1",
4
4
  "description": "Apple MusicKit wrapper for Expo",
5
5
  "main": "build/index.js",
6
6
  "types": "build/index.d.ts",
@@ -11,7 +11,7 @@
11
11
  "test": "jest --watchman=false",
12
12
  "test:expo": "expo-module test",
13
13
  "prepare": "expo-module prepare",
14
- "prepublishOnly": "node scripts/npm-prepublish.mjs && expo-module prepublishOnly",
14
+ "prepublishOnly": "node scripts/npm-prepublish.mjs && expo-module prepublishOnly && expo-module build plugin",
15
15
  "pack:check": "npm run build && node scripts/verify-npm-pack.mjs",
16
16
  "expo-module": "expo-module",
17
17
  "dev-token": "node scripts/generate-developer-token.mjs",
@@ -0,0 +1,14 @@
1
+ /** Filenames must match `expo-module.config.json` → `gradleAarProjects`. */
2
+ export declare const ANDROID_MUSICKIT_AAR_FILES: readonly ["musickitauth-release-1.1.2.aar", "mediaplayback-release-1.1.1.aar"];
3
+ export type AndroidMusicKitAarFile = (typeof ANDROID_MUSICKIT_AAR_FILES)[number];
4
+ export declare function getModuleAndroidLibsDir(moduleRoot: string): string;
5
+ export declare class MissingAndroidMusicKitAarsError extends Error {
6
+ readonly sourceDir: string;
7
+ readonly missingFiles: readonly string[];
8
+ constructor(sourceDir: string, missingFiles: readonly string[]);
9
+ }
10
+ export declare function formatMissingAndroidMusicKitAarsMessage(sourceDir: string, missingFiles: readonly string[]): string;
11
+ export declare function copyAndroidMusicKitAars(options: {
12
+ sourceDir: string;
13
+ moduleRoot: string;
14
+ }): void;
@@ -0,0 +1,58 @@
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.MissingAndroidMusicKitAarsError = exports.ANDROID_MUSICKIT_AAR_FILES = void 0;
7
+ exports.getModuleAndroidLibsDir = getModuleAndroidLibsDir;
8
+ exports.formatMissingAndroidMusicKitAarsMessage = formatMissingAndroidMusicKitAarsMessage;
9
+ exports.copyAndroidMusicKitAars = copyAndroidMusicKitAars;
10
+ const fs_1 = __importDefault(require("fs"));
11
+ const path_1 = __importDefault(require("path"));
12
+ /** Filenames must match `expo-module.config.json` → `gradleAarProjects`. */
13
+ exports.ANDROID_MUSICKIT_AAR_FILES = [
14
+ "musickitauth-release-1.1.2.aar",
15
+ "mediaplayback-release-1.1.1.aar",
16
+ ];
17
+ function getModuleAndroidLibsDir(moduleRoot) {
18
+ return path_1.default.join(moduleRoot, "android", "libs");
19
+ }
20
+ class MissingAndroidMusicKitAarsError extends Error {
21
+ sourceDir;
22
+ missingFiles;
23
+ constructor(sourceDir, missingFiles) {
24
+ super(formatMissingAndroidMusicKitAarsMessage(sourceDir, missingFiles));
25
+ this.sourceDir = sourceDir;
26
+ this.missingFiles = missingFiles;
27
+ this.name = "MissingAndroidMusicKitAarsError";
28
+ }
29
+ }
30
+ exports.MissingAndroidMusicKitAarsError = MissingAndroidMusicKitAarsError;
31
+ function formatMissingAndroidMusicKitAarsMessage(sourceDir, missingFiles) {
32
+ const fileList = missingFiles.map((file) => ` - ${file}`).join("\n");
33
+ return (`[expo-apple-music] Missing Apple MusicKit Android AAR file(s) in ${sourceDir}:\n` +
34
+ `${fileList}\n\n` +
35
+ "Download the MusicKit SDK for Android from https://developer.apple.com/musickit/ " +
36
+ "(Apple Developer account required), place both .aar files in the directory " +
37
+ "configured as `androidMusicKitAarDir`, then run `npx expo prebuild` again.");
38
+ }
39
+ function copyAndroidMusicKitAars(options) {
40
+ const { sourceDir, moduleRoot } = options;
41
+ const targetDir = getModuleAndroidLibsDir(moduleRoot);
42
+ if (!fs_1.default.existsSync(sourceDir)) {
43
+ throw new MissingAndroidMusicKitAarsError(sourceDir, [...exports.ANDROID_MUSICKIT_AAR_FILES]);
44
+ }
45
+ fs_1.default.mkdirSync(targetDir, { recursive: true });
46
+ const missingFiles = [];
47
+ for (const fileName of exports.ANDROID_MUSICKIT_AAR_FILES) {
48
+ const sourcePath = path_1.default.join(sourceDir, fileName);
49
+ if (!fs_1.default.existsSync(sourcePath)) {
50
+ missingFiles.push(fileName);
51
+ continue;
52
+ }
53
+ fs_1.default.copyFileSync(sourcePath, path_1.default.join(targetDir, fileName));
54
+ }
55
+ if (missingFiles.length > 0) {
56
+ throw new MissingAndroidMusicKitAarsError(sourceDir, missingFiles);
57
+ }
58
+ }
@@ -0,0 +1,5 @@
1
+ import type { ExpoAppleMusicPluginProps } from "./with-expo-apple-music";
2
+ export type { ExpoAppleMusicPluginProps } from "./with-expo-apple-music";
3
+ export { DEFAULT_MUSIC_USAGE } from "./with-expo-apple-music";
4
+ /** Typed `app.config` plugin entry (Expo SDK 56+). */
5
+ export default function expoAppleMusic(props?: ExpoAppleMusicPluginProps): ["@wwdrew/expo-apple-music", ExpoAppleMusicPluginProps | void];
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DEFAULT_MUSIC_USAGE = void 0;
4
+ exports.default = expoAppleMusic;
5
+ var with_expo_apple_music_1 = require("./with-expo-apple-music");
6
+ Object.defineProperty(exports, "DEFAULT_MUSIC_USAGE", { enumerable: true, get: function () { return with_expo_apple_music_1.DEFAULT_MUSIC_USAGE; } });
7
+ /** Typed `app.config` plugin entry (Expo SDK 56+). */
8
+ function expoAppleMusic(props) {
9
+ return ["@wwdrew/expo-apple-music", props];
10
+ }
@@ -0,0 +1,18 @@
1
+ import { type ConfigPlugin } from "@expo/config-plugins";
2
+ export declare const DEFAULT_MUSIC_USAGE = "Allow $(PRODUCT_NAME) to access Apple Music.";
3
+ export type ExpoAppleMusicPluginProps = {
4
+ /**
5
+ * Sets `NSAppleMusicUsageDescription` in the generated iOS Info.plist.
6
+ */
7
+ musicUsageDescription?: string;
8
+ /**
9
+ * Directory containing Apple's MusicKit Android `.aar` files (path relative to
10
+ * the app project root). Required when running `expo prebuild` for Android.
11
+ *
12
+ * The plugin copies the AARs into this package at prebuild time — they are not
13
+ * shipped on npm and cannot be redistributed by this library.
14
+ */
15
+ androidMusicKitAarDir?: string;
16
+ };
17
+ declare const withExpoAppleMusic: ConfigPlugin<ExpoAppleMusicPluginProps | void>;
18
+ export default withExpoAppleMusic;
@@ -0,0 +1,79 @@
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.DEFAULT_MUSIC_USAGE = void 0;
7
+ const path_1 = __importDefault(require("path"));
8
+ const config_plugins_1 = require("@expo/config-plugins");
9
+ const apple_music_aars_1 = require("./apple-music-aars");
10
+ /** plugin/build/*.js → package root */
11
+ function getExpoAppleMusicModuleRoot() {
12
+ return path_1.default.join(__dirname, "..", "..");
13
+ }
14
+ /** MusicKit APIs used by this module require iOS 16.4+ (Expo SDK 56 minimum). */
15
+ const IOS_DEPLOYMENT_TARGET = "16.4";
16
+ const withIosDeploymentTargetPodfile = config_plugins_1.IOSConfig.BuildProperties.createBuildPodfilePropsConfigPlugin([
17
+ {
18
+ propName: "ios.deploymentTarget",
19
+ propValueGetter: () => IOS_DEPLOYMENT_TARGET,
20
+ },
21
+ ], "withExpoAppleMusicIosDeploymentTargetPodfile");
22
+ const withIosDeploymentTargetXcodeProject = (config) => {
23
+ return (0, config_plugins_1.withXcodeProject)(config, (c) => {
24
+ const { Target, XcodeUtils } = config_plugins_1.IOSConfig;
25
+ const project = c.modResults;
26
+ const targetBuildConfigListIds = Target.getNativeTargets(project)
27
+ .filter(([_, target]) => Target.isTargetOfType(target, Target.TargetType.APPLICATION))
28
+ .map(([_, target]) => target.buildConfigurationList);
29
+ for (const buildConfigListId of targetBuildConfigListIds) {
30
+ for (const [, configurations] of XcodeUtils.getBuildConfigurationsForListId(project, buildConfigListId)) {
31
+ const { buildSettings } = configurations;
32
+ if (buildSettings?.IPHONEOS_DEPLOYMENT_TARGET) {
33
+ buildSettings.IPHONEOS_DEPLOYMENT_TARGET = IOS_DEPLOYMENT_TARGET;
34
+ }
35
+ }
36
+ }
37
+ return c;
38
+ });
39
+ };
40
+ exports.DEFAULT_MUSIC_USAGE = "Allow $(PRODUCT_NAME) to access Apple Music.";
41
+ const withAndroidMusicKitAars = (config, { androidMusicKitAarDir } = {}) => {
42
+ return (0, config_plugins_1.withDangerousMod)(config, [
43
+ "android",
44
+ async (config) => {
45
+ const configuredDir = androidMusicKitAarDir?.trim();
46
+ if (!configuredDir) {
47
+ throw new Error("[expo-apple-music] `androidMusicKitAarDir` is required for Android builds. " +
48
+ "Download Apple's MusicKit SDK for Android, place the .aar files in a directory " +
49
+ "in your app (for example `./vendor/apple-musickit-android`), and pass that path " +
50
+ "to the expo-apple-music config plugin. See docs/GETTING_STARTED.md.");
51
+ }
52
+ const projectRoot = config.modRequest.projectRoot;
53
+ const sourceDir = path_1.default.resolve(projectRoot, configuredDir);
54
+ const moduleRoot = getExpoAppleMusicModuleRoot();
55
+ (0, apple_music_aars_1.copyAndroidMusicKitAars)({ sourceDir, moduleRoot });
56
+ return config;
57
+ },
58
+ ]);
59
+ };
60
+ const withExpoAppleMusic = (config, props) => {
61
+ const { musicUsageDescription, androidMusicKitAarDir } = props ?? {};
62
+ config = withIosDeploymentTargetPodfile(config);
63
+ config = withIosDeploymentTargetXcodeProject(config);
64
+ config = withAndroidMusicKitAars(config, { androidMusicKitAarDir });
65
+ return (0, config_plugins_1.withInfoPlist)(config, (c) => {
66
+ const current = c.modResults.NSAppleMusicUsageDescription;
67
+ const hasCurrent = typeof current === "string" && current.trim().length > 0;
68
+ const hasOption = typeof musicUsageDescription === "string" &&
69
+ musicUsageDescription.trim().length > 0;
70
+ if (hasOption) {
71
+ c.modResults.NSAppleMusicUsageDescription = musicUsageDescription;
72
+ }
73
+ else if (!hasCurrent) {
74
+ c.modResults.NSAppleMusicUsageDescription = exports.DEFAULT_MUSIC_USAGE;
75
+ }
76
+ return c;
77
+ });
78
+ };
79
+ exports.default = withExpoAppleMusic;