Line data Source code
1 : import type { SessionMigrationStep } from '../session_migration.js';
2 :
3 : /// The order of the scripts and the database of each script live in the session metadata.
4 : ///
5 : /// Version 4 ordered the scripts by a numeric prefix of their file names and listed the files in a
6 : /// separate index for sessions served over HTTP. The index was kept in natural order, its order is
7 : /// the order of the scripts. Every script runs on the main database. A folder without an index gets
8 : /// empty lists, the loader appends the script files in natural order.
9 1 : export const scriptsInSessionFile: SessionMigrationStep = {
10 1 : version: 5,
11 1 : description: 'List the scripts with their databases in the session metadata',
12 1 : async migrate(folder) {
13 1 : const text = await folder.readText('dashql-session.json');
14 1 : if (text == null) {
15 0 : return;
16 : }
17 1 : const data = JSON.parse(text) as Record<string, unknown>;
18 1 : if (!Array.isArray(data.scripts)) {
19 1 : const mainDatabase = data.mainDatabase as { databaseId?: unknown } | undefined;
20 1 : const index = parseIndex(await folder.readText('dashql-session-index.json'));
21 1 : const databaseId = typeof mainDatabase?.databaseId === 'string' ? mainDatabase.databaseId : null;
22 1 : data.scripts = databaseId == null ? [] : index.scripts.map(name => ({ name, databaseId }));
23 1 : data.attachments = index.data.map(name => ({ name }));
24 1 : await folder.writeText('dashql-session.json', JSON.stringify(data, null, 2));
25 1 : }
26 1 : await folder.remove('dashql-session-index.json');
27 1 : },
28 1 : };
29 :
30 : /// The file names of an index, an unreadable index lists nothing
31 1 : function parseIndex(text: string | null): { scripts: string[]; data: string[] } {
32 1 : const names = (entries: unknown): string[] => Array.isArray(entries)
33 1 : ? entries.map(entry => (entry as { name?: unknown } | null)?.name).filter((name): name is string => typeof name === 'string')
34 1 : : [];
35 1 : if (text == null) {
36 1 : return { scripts: [], data: [] };
37 : }
38 1 : try {
39 1 : const index = JSON.parse(text) as { scripts?: unknown; data?: unknown } | null;
40 1 : return { scripts: names(index?.scripts), data: names(index?.data) };
41 1 : } catch {
42 1 : return { scripts: [], data: [] };
43 1 : }
44 1 : }
|