directus

Форк
0
/
20240204A-marketplace.ts 
126 строк · 3.8 Кб
1
import { resolvePackage } from '@directus/utils/node';
2
import type { Knex } from 'knex';
3
import { randomUUID } from 'node:crypto';
4
import { dirname } from 'node:path';
5
import { fileURLToPath } from 'node:url';
6

7
const __dirname = dirname(fileURLToPath(import.meta.url));
8

9
export async function up(knex: Knex): Promise<void> {
10
	await knex.schema.alterTable('directus_extensions', (table) => {
11
		table.uuid('id').nullable();
12
		table.string('folder');
13
		table.string('source');
14
		table.uuid('bundle');
15
	});
16

17
	const installedExtensions = await knex.select('name').from('directus_extensions');
18

19
	// name: id
20
	const idMap = new Map<string, { id: string; source: 'local' | 'module' }>();
21

22
	for (const { name } of installedExtensions) {
23
		// Delete extension meta status that used the legacy `${name}:${type}` name syntax for
24
		// extension-folder scoped extensions
25
		if (name.includes(':')) {
26
			await knex('directus_extensions').delete().where({ name });
27
		} else {
28
			const id = randomUUID();
29

30
			let source: 'local' | 'module';
31

32
			try {
33
				// The NPM package name is the name used in the database. If we can resolve the
34
				// extension as a node module it's safe to assume it's a npm-module source
35
				resolvePackage(name, __dirname);
36
				source = 'module';
37
			} catch {
38
				source = 'local';
39
			}
40

41
			await knex('directus_extensions').update({ id, source, folder: name }).where({ name });
42
			idMap.set(name, { id, source });
43
		}
44
	}
45

46
	for (const { name } of installedExtensions) {
47
		if (!name.includes('/')) continue;
48

49
		const splittedName = name.split('/');
50

51
		const isScopedModuleBundleParent = name.startsWith('@') && splittedName.length == 2;
52

53
		if (isScopedModuleBundleParent) continue;
54

55
		const isScopedModuleBundleChild = name.startsWith('@') && splittedName.length > 2;
56

57
		const bundleParentName =
58
			isScopedModuleBundleParent || isScopedModuleBundleChild ? splittedName.slice(0, 2).join('/') : splittedName[0];
59

60
		const bundleParent = idMap.get(bundleParentName);
61

62
		if (!bundleParent) continue;
63

64
		await knex('directus_extensions')
65
			.update({
66
				bundle: bundleParent.id,
67
				folder: name.substring(bundleParentName.length + 1),
68
				source: bundleParent.source,
69
			})
70
			.where({ folder: name });
71
	}
72

73
	await knex.schema.alterTable('directus_extensions', (table) => {
74
		table.uuid('id').alter().notNullable();
75
	});
76

77
	await knex.transaction(async (trx) => {
78
		await trx.schema.alterTable('directus_extensions', (table) => {
79
			table.dropPrimary();
80
			table.primary(['id']);
81
		});
82
	});
83

84
	await knex.schema.alterTable('directus_extensions', (table) => {
85
		table.dropColumn('name');
86
		table.string('source').alter().notNullable();
87
		table.string('folder').alter().notNullable();
88
	});
89
}
90

91
/*
92
 * Note: For local extensions having a different package & folder name,
93
 * we aren't able to revert to the exact same state as before.
94
 * But we still need to do the name convertion, in order for the migration to succeed.
95
 */
96
export async function down(knex: Knex): Promise<void> {
97
	await knex.schema.alterTable('directus_extensions', (table) => {
98
		table.string('name');
99
	});
100

101
	const installedExtensions = await knex.select(['id', 'folder', 'bundle']).from('directus_extensions');
102

103
	const idMap = new Map<string, string>(installedExtensions.map((extension) => [extension.id, extension.folder]));
104

105
	for (const { id, folder, bundle, source } of installedExtensions) {
106
		if (source === 'registry') {
107
			await knex('directus_extensions').delete().where({ id });
108
			continue;
109
		}
110

111
		let name = folder;
112

113
		if (bundle) {
114
			const bundleParentName = idMap.get(bundle);
115

116
			name = `${bundleParentName}/${name}`;
117
		}
118

119
		await knex('directus_extensions').update({ name }).where({ id });
120
	}
121

122
	await knex.schema.alterTable('directus_extensions', (table) => {
123
		table.dropColumns('id', 'folder', 'source', 'bundle');
124
		table.string('name').alter().primary().notNullable();
125
	});
126
}
127

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.