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
---

Fix bundle extension loading by updating extension settings table
paescuj marked this conversation as resolved.
Show resolved Hide resolved
71 changes: 60 additions & 11 deletions api/src/extensions/lib/get-extensions-settings.ts
Original file line number Diff line number Diff line change
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 = (
extensionSettings: ExtensionSettings,
extension: Extension,
settings: ExtensionSettings[],
br41nslug marked this conversation as resolved.
Show resolved Hide resolved
) => {
if (extension.type !== 'bundle') return;

br41nslug marked this conversation as resolved.
Show resolved Hide resolved
const bundleEntriesSettings = settings.filter(({ bundle }) => bundle === extensionSettings.id);

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

removedSettingIds.push(entry.id);
}

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

newSettings.push({
id: randomUUID(),
enabled: true,
source: extensionSettings.source,
bundle: extensionSettings.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,12 @@ 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) {
br41nslug marked this conversation as resolved.
Show resolved Hide resolved
updateBundleEntriesSettings(existingSettings, extension, localSettings);
continue;
}

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

Expand All @@ -85,24 +122,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(existingSettings, extension, 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(existingSettings, extension, 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];
};