Files
frontend/plugins/withHuaweiPush.js

202 lines
7.8 KiB
JavaScript
Raw Normal View History

const {
withAppBuildGradle,
withProjectBuildGradle,
withSettingsGradle,
withDangerousMod,
withAndroidManifest,
} = require('@expo/config-plugins');
const fs = require('fs');
const path = require('path');
const withHuaweiPush = (config, options = {}) => {
const { jpushVersion = '5.8.0' } = options;
config = withSettingsGradle(config, (config) => {
const contents = config.modResults.contents;
// Add Huawei Maven repo to pluginManagement.repositories for plugin resolution
if (!contents.includes('developer.huawei.com/repo')) {
if (contents.includes('pluginManagement')) {
config.modResults.contents = contents.replace(
/(pluginManagement\s*\{[\s\S]*?repositories\s*\{)/,
`$1\n maven { url 'https://developer.huawei.com/repo/' }`
);
} else {
// No pluginManagement block at all — create one with the Huawei repo
config.modResults.contents =
`pluginManagement {\n repositories {\n maven { url 'https://developer.huawei.com/repo/' }\n }\n}\n\n` +
config.modResults.contents;
}
}
// Map the plugin ID to its Maven artifact via resolutionStrategy.
// AGConnect is not published as a standard Gradle plugin marker, so Gradle 9+
// cannot resolve it by plugin ID alone. This mapping tells Gradle where to find it.
if (!config.modResults.contents.includes('com.huawei.agconnect:agcp')) {
const pmMatch = config.modResults.contents.match(/pluginManagement\s*\{/);
if (pmMatch) {
config.modResults.contents = config.modResults.contents.replace(
/(pluginManagement\s*\{)/,
`$1\n resolutionStrategy {\n eachPlugin {\n if (requested.id.id == 'com.huawei.agconnect') {\n useModule('com.huawei.agconnect:agcp:1.9.1.301')\n }\n }\n }`
);
}
}
// Ensure Huawei Maven repo also appears in dependencyResolutionManagement (Gradle 9+)
if (!config.modResults.contents.match(/dependencyResolutionManagement[\s\S]*developer\.huawei\.com\/repo/)) {
const depMgmtPattern = /dependencyResolutionManagement\s*\{[\s\S]*?repositories\s*\{/;
if (depMgmtPattern.test(config.modResults.contents)) {
config.modResults.contents = config.modResults.contents.replace(
depMgmtPattern,
`$&\n maven { url 'https://developer.huawei.com/repo/' }`
);
}
}
// Declare the plugin in a top-level plugins {} block (outside pluginManagement).
// In Gradle 9+, plugins declared with `apply false` in settings.gradle are
// available to all subprojects via `apply plugin:` or the plugins DSL.
if (!config.modResults.contents.includes("id 'com.huawei.agconnect'")) {
const pluginsBlockPattern = /^plugins\s*\{/m;
if (pluginsBlockPattern.test(config.modResults.contents)) {
// Add to existing top-level plugins block
config.modResults.contents = config.modResults.contents.replace(
/^plugins\s*\{/m,
`plugins {\n id 'com.huawei.agconnect' version '1.9.1.301' apply false`
);
} else {
// Insert a top-level plugins block after pluginManagement closing brace,
// or at the very beginning if no pluginManagement block exists.
const pmClosePattern = /\n\}\n/;
if (pmClosePattern.test(config.modResults.contents)) {
const firstClosing = config.modResults.contents.indexOf('}', config.modResults.contents.indexOf('pluginManagement')) + 1;
if (firstClosing > 0) {
const insertPos = firstClosing;
config.modResults.contents =
config.modResults.contents.slice(0, insertPos) +
`\n\nplugins {\n id 'com.huawei.agconnect' version '1.9.1.301' apply false\n}` +
config.modResults.contents.slice(insertPos);
}
} else {
// Fallback: prepend after pluginManagement block
config.modResults.contents =
config.modResults.contents.replace(
/(pluginManagement\s*\{[\s\S]*?\})/,
`$1\n\nplugins {\n id 'com.huawei.agconnect' version '1.9.1.301' apply false\n}`
);
}
}
}
return config;
});
config = withProjectBuildGradle(config, (config) => {
const contents = config.modResults.contents;
if (!contents.includes('developer.huawei.com/repo')) {
config.modResults.contents = contents.replace(
/(repositories\s*\{)/g,
(match) => {
return match + `\n maven { url 'https://developer.huawei.com/repo/' }`;
}
);
}
return config;
});
config = withProjectBuildGradle(config, (config) => {
const contents = config.modResults.contents;
if (!contents.includes('com.huawei.agconnect:agcp')) {
if (contents.includes('buildscript')) {
const depsPattern = /(buildscript\s*\{[\s\S]*?dependencies\s*\{)/;
if (depsPattern.test(contents)) {
config.modResults.contents = contents.replace(
depsPattern,
`$1\n classpath 'com.huawei.agconnect:agcp:1.9.1.301'`
);
}
}
}
if (!config.modResults.contents.includes('developer.huawei.com/repo')) {
const bsRepoPattern = /(buildscript\s*\{[\s\S]*?repositories\s*\{)/;
if (bsRepoPattern.test(config.modResults.contents)) {
config.modResults.contents = config.modResults.contents.replace(
bsRepoPattern,
`$1\n maven { url 'https://developer.huawei.com/repo/' }`
);
}
}
return config;
});
config = withAppBuildGradle(config, (config) => {
const contents = config.modResults.contents;
if (!contents.includes('com.huawei.agconnect')) {
const applyPluginPattern = /apply plugin:\s*['"]com\.google\.gms\.google-services['"]/;
if (applyPluginPattern.test(contents)) {
config.modResults.contents = contents.replace(
applyPluginPattern,
`apply plugin: 'com.google.gms.google-services'\napply plugin: 'com.huawei.agconnect'`
);
} else {
const lastApplyPlugin = /apply plugin:[^\n]*(?:\n)/g;
const matches = contents.match(lastApplyPlugin);
if (matches && matches.length > 0) {
const lastMatch = matches[matches.length - 1];
const lastIndex = contents.lastIndexOf(lastMatch);
config.modResults.contents =
contents.slice(0, lastIndex + lastMatch.length) +
"apply plugin: 'com.huawei.agconnect'\n" +
contents.slice(lastIndex + lastMatch.length);
} else {
config.modResults.contents = contents + "\napply plugin: 'com.huawei.agconnect'\n";
}
}
}
if (!contents.includes('cn.jiguang.sdk.plugin:huawei')) {
const depsPattern = /dependencies\s*\{/;
if (depsPattern.test(config.modResults.contents)) {
config.modResults.contents = config.modResults.contents.replace(
depsPattern,
`dependencies {\n implementation 'cn.jiguang.sdk.plugin:huawei:${jpushVersion}'`
);
}
}
return config;
});
config = withDangerousMod(config, [
'android',
async (config) => {
const appDir = path.join(config.modRequest.platformProjectRoot, 'app');
const srcFile = path.join(config.modRequest.projectRoot, 'plugins', 'agconnect-services.json');
const destFile = path.join(appDir, 'agconnect-services.json');
if (fs.existsSync(srcFile)) {
fs.copyFileSync(srcFile, destFile);
console.log('[withHuaweiPush] copied agconnect-services.json to android/app/');
} else {
console.warn('[withHuaweiPush] agconnect-services.json not found at project root');
}
return config;
},
]);
config = withAndroidManifest(config, (config) => {
return config;
});
return config;
};
module.exports = withHuaweiPush;