File "plugins.js"
Full Path: /home/buyiwexj/public_html/wp-content/plugins/extendify/src/AutoLaunch/functions/plugins.js
File size: 4.62 KB
MIME-type: text/x-java
Charset: utf-8
import { recordPluginActivity } from '@shared/api/DataApi';
import { digest } from '@shared/api/digest';
import { enableAutoUpdate } from '@shared/api/wp';
import apiFetch from '@wordpress/api-fetch';
import { addQueryArgs } from '@wordpress/url';
export const getActivePlugins = () =>
apiFetch({ path: 'extendify/v1/auto-launch/active-plugins' });
export const alreadyActive = (activePlugins, pluginSlug) =>
activePlugins?.filter((p) => p.includes(pluginSlug))?.length;
export const installPlugin = async (slug) => {
const fn = async () => {
const p = await apiFetch({
path: '/wp/v2/plugins',
method: 'POST',
data: { slug },
});
await recordPluginActivity({ slug, source: 'auto-launch' });
await enableAutoUpdate(p?.plugin);
return p;
};
try {
return await fn();
} catch (error) {
if (error?.code === 'folder_exists') {
// Already on disk — fetch its record so the caller can activate it.
return await getPlugin(slug);
}
try {
return await fn();
} catch (error) {
digest({
error,
details: { source: 'auto-launch', caller: 'installPlugin' },
});
return null;
}
}
};
export const getPlugin = async (slug) => {
const response = await apiFetch({
path: addQueryArgs('/wp/v2/plugins', { search: slug }),
});
return response?.find((p) => p.plugin?.split('/')[0] === slug);
};
export const activatePlugin = async (slug) => {
const fn = (s) =>
apiFetch({
path: `/wp/v2/plugins/${s}`,
method: 'POST',
data: { status: 'active' },
});
try {
await fn(slug);
return true;
} catch (_) {
try {
// try once more but get the slug first
const { plugin } = await getPlugin(slug);
await fn(plugin);
return true;
} catch (error) {
digest({
error,
details: { source: 'auto-launch', caller: 'activatePlugin' },
});
return false;
}
}
};
// Isolates per-plugin failures so one bad plugin can't block the rest;
// returns the slugs that never went active.
export const ensurePluginsActive = async (
slugs,
{ installedSlugs = [] } = {},
) => {
const failed = [];
for (const slug of slugs) {
try {
const plugin = installedSlugs.includes(slug)
? null
: await installPlugin(slug);
const activated = await activatePlugin(plugin?.plugin ?? slug);
if (!activated) failed.push(slug);
} catch (_) {
failed.push(slug);
}
}
return { failed };
};
// Last-chance guarantee before dependent work builds on these plugins: the
// optimistic install pass is best-effort and unverified.
export const verifyPluginsActive = async (
slugs,
{ installedSlugs = [] } = {},
) => {
const activePlugins = await getActivePlugins();
// Exact slug match here (not alreadyActive's substring test): matching
// woocommerce against an active woocommerce-payments would skip a real miss.
const missing = slugs.filter(
(slug) => !activePlugins?.some((path) => path.split('/')[0] === slug),
);
if (!missing.length) return;
const { failed } = await ensurePluginsActive(missing, { installedSlugs });
if (!failed.length) return;
digest({
error: { message: `Plugins inactive after verify: ${failed.join(', ')}` },
details: { source: 'auto-launch', caller: 'verifyPluginsActive', failed },
});
};
// Currently this only processes patterns with placeholders
// by swapping out the placeholders with the actual code
// returns the patterns as blocks with the placeholders replaced
export const replacePlaceholderPatterns = async (patterns) => {
// Directly replace "blog-section" patterns using their replacement code, skipping the API call
patterns = patterns.map((pattern) => {
if (
pattern.patternTypes.includes('blog-section') &&
pattern.patternReplacementCode
) {
return {
...pattern,
code: pattern.patternReplacementCode,
};
}
return pattern;
});
const hasPlaceholders = patterns.filter((p) => p.patternReplacementCode);
if (!hasPlaceholders?.length) return patterns;
const activePlugins =
(await getActivePlugins())?.data?.map((path) => path.split('/')[0]) || [];
const pluginsActivity = patterns
.filter((p) => p.pluginDependency)
.map((p) => p.pluginDependency)
.filter((p) => !activePlugins.includes(p));
for (const plugin of pluginsActivity) {
recordPluginActivity({
slug: plugin,
source: 'auto-launch',
});
}
try {
return await processPlaceholders(patterns);
} catch (_e) {
// Try one more time (plugins installed may not be fully loaded)
return await processPlaceholders(patterns)
// If this fails, just return the original patterns
.catch(() => patterns);
}
};
export const processPlaceholders = (patterns) =>
apiFetch({
path: '/extendify/v1/shared/process-placeholders',
method: 'POST',
data: { patterns },
});