Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix bundle (re-)loading #22013

Merged
merged 13 commits into from
May 7, 2024
5 changes: 5 additions & 0 deletions .changeset/hot-dolphins-shop.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---

Check warning on line 1 in .changeset/hot-dolphins-shop.md

View workflow job for this annotation

GitHub Actions / Lint

File ignored by default.
'@directus/api': patch
---

Fixed bundle extension loading by updating extension settings table
76 changes: 64 additions & 12 deletions api/src/extensions/lib/get-extensions-settings.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { Extension, ExtensionSettings } from '@directus/extensions';
import type { BundleExtension, Extension, ExtensionSettings } from '@directus/extensions';
import { randomUUID } from 'node:crypto';
import getDatabase from '../../database/index.js';
import { ExtensionsService } from '../../services/extensions.js';
Expand Down Expand Up @@ -28,11 +28,44 @@ export const getExtensionsSettings = async ({
const existingSettings = await service.extensionsItemService.readByQuery({ limit: -1 });

const newSettings: ExtensionSettings[] = [];
const removedSettingIds: string[] = [];

const localSettings = existingSettings.filter(({ source }) => source === 'local');
const registrySettings = existingSettings.filter(({ source }) => source === 'registry');
const moduleSettings = existingSettings.filter(({ source }) => source === 'module');

const updateBundleEntriesSettings = (
bundle: BundleExtension,
bundleSettings: ExtensionSettings,
allSettings: ExtensionSettings[],
) => {
const bundleEntriesSettings = allSettings.filter(({ bundle }) => bundle === bundleSettings.id);

// Remove settings of removed bundle entries from the DB
for (const entry of bundleEntriesSettings) {
const entryInBundle = bundle.entries.some(({ name }) => name === entry.folder);

if (entryInBundle) continue;

removedSettingIds.push(entry.id);
}

// Add new bundle entries to the settings
for (const entry of bundle.entries) {
const settingsExist = bundleEntriesSettings.some(({ folder }) => folder === entry.name);

if (settingsExist) continue;

newSettings.push({
id: randomUUID(),
enabled: bundleSettings.enabled,
source: bundleSettings.source,
bundle: bundleSettings.id,
folder: entry.name,
});
}
};

const generateSettingsEntry = (folder: string, extension: Extension, source: 'local' | 'registry' | 'module') => {
if (extension.type === 'bundle') {
const bundleId = randomUUID();
Expand Down Expand Up @@ -66,8 +99,15 @@ export const getExtensionsSettings = async ({
};

for (const [folder, extension] of local.entries()) {
const settingsExist = localSettings.some((settings) => settings.folder === folder);
if (settingsExist) continue;
const existingSettings = localSettings.find((settings) => settings.folder === folder);

if (existingSettings) {
if (extension.type === 'bundle') {
br41nslug marked this conversation as resolved.
Show resolved Hide resolved
updateBundleEntriesSettings(extension, existingSettings, localSettings);
}

continue;
}

const settingsForName = localSettings.find((settings) => settings.folder === extension.name);

Expand All @@ -85,24 +125,36 @@ export const getExtensionsSettings = async ({
continue;
}

if (!settingsExist) generateSettingsEntry(folder, extension, 'local');
generateSettingsEntry(folder, extension, 'local');
}

for (const [folder, extension] of module.entries()) {
const settingsExist = moduleSettings.some((settings) => settings.folder === folder);
if (!settingsExist) generateSettingsEntry(folder, extension, 'module');
const existingSettings = moduleSettings.find((settings) => settings.folder === folder);

if (!existingSettings) {
generateSettingsEntry(folder, extension, 'module');
} else if (extension.type === 'bundle') {
updateBundleEntriesSettings(extension, existingSettings, moduleSettings);
}
}

for (const [folder, extension] of registry.entries()) {
const settingsExist = registrySettings.some((settings) => settings.folder === folder);
if (!settingsExist) generateSettingsEntry(folder, extension, 'registry');
const existingSettings = registrySettings.find((settings) => settings.folder === folder);

if (!existingSettings) {
generateSettingsEntry(folder, extension, 'registry');
} else if (extension.type === 'bundle') {
updateBundleEntriesSettings(extension, existingSettings, registrySettings);
}
}

if (newSettings.length > 0) {
await database.insert(newSettings).into('directus_extensions');
if (removedSettingIds.length > 0) {
await service.extensionsItemService.deleteMany(removedSettingIds);
}

const settings = [...existingSettings, ...newSettings];
if (newSettings.length > 0) {
await service.extensionsItemService.createMany(newSettings);
}

return settings;
return [...existingSettings.filter(({ id }) => !removedSettingIds.includes(id)), ...newSettings];
};