mirror of
https://github.com/laurent22/joplin.git
synced 2024-12-15 09:04:04 +02:00
125 lines
3.5 KiB
TypeScript
125 lines
3.5 KiB
TypeScript
import { execCommand } from '@joplin/utils';
|
|
import { insertContentIntoFile, rootDir } from './tool-utils';
|
|
|
|
const sqlts = require('@rmp135/sql-ts').default;
|
|
const fs = require('fs-extra');
|
|
|
|
function createRuntimeObject(table: any) {
|
|
const colStrings = [];
|
|
for (const col of table.columns) {
|
|
const name = col.propertyName;
|
|
const type = col.propertyType;
|
|
colStrings.push(`\t\t${name}: { type: '${type}' },`);
|
|
}
|
|
|
|
return `\t${table.name}: {\n${colStrings.join('\n')}\n\t},`;
|
|
}
|
|
|
|
const stringToSingular = (word: string) => {
|
|
if (word.endsWith('s')) return word.substring(0, word.length - 1);
|
|
return word;
|
|
};
|
|
|
|
const generateListRenderDependencyType = (tables: any[]) => {
|
|
const output: string[] = [];
|
|
|
|
for (const table of tables) {
|
|
if (!['notes', 'folders'].includes(table.name)) continue;
|
|
|
|
for (const col of table.columns) {
|
|
const name = col.propertyName;
|
|
output.push(`'${stringToSingular(table.name)}.${name}'`);
|
|
}
|
|
}
|
|
|
|
return output.join(' | ');
|
|
};
|
|
|
|
async function main() {
|
|
// Run the CLI app once so as to generate the database file
|
|
process.chdir(`${rootDir}/packages/app-cli`);
|
|
await execCommand('yarn start version');
|
|
|
|
const sqlTsConfig = {
|
|
'client': 'sqlite3',
|
|
'connection': {
|
|
'filename': `${require('os').homedir()}/.config/joplindev/database.sqlite`,
|
|
},
|
|
'tableNameCasing': 'pascal',
|
|
'singularTableNames': true,
|
|
'useNullAsDefault': true, // To disable warning "sqlite does not support inserting default values"
|
|
'excludedTables': [
|
|
'main.notes_fts',
|
|
'main.notes_fts_segments',
|
|
'main.notes_fts_segdir',
|
|
'main.notes_fts_docsize',
|
|
'main.notes_fts_stat',
|
|
'main.master_keys',
|
|
],
|
|
};
|
|
|
|
const definitions = await sqlts.toObject(sqlTsConfig);
|
|
|
|
definitions.tables = definitions.tables.map((t: any) => {
|
|
t.columns.push({
|
|
nullable: false,
|
|
name: 'type_',
|
|
type: 'int',
|
|
optional: true,
|
|
isEnum: false,
|
|
propertyName: 'type_',
|
|
propertyType: 'number',
|
|
});
|
|
|
|
return t;
|
|
});
|
|
|
|
definitions.tables = definitions.tables.map((table: any) => {
|
|
table.columns = table.columns.map((column: any) => {
|
|
return {
|
|
...column,
|
|
optional: true,
|
|
};
|
|
});
|
|
|
|
return table;
|
|
});
|
|
|
|
const tableStrings = [];
|
|
for (const table of definitions.tables) {
|
|
tableStrings.push(createRuntimeObject(table));
|
|
}
|
|
|
|
const tsString = sqlts.fromObject(definitions, sqlTsConfig)
|
|
.replace(/": /g, '"?: ');
|
|
const header = `// AUTO-GENERATED BY ${__filename.substr(rootDir.length + 1)}`;
|
|
|
|
const targetFile = `${rootDir}/packages/lib/services/database/types.ts`;
|
|
console.info(`Writing type definitions to ${targetFile}...`);
|
|
|
|
const existingContent = (await fs.pathExists(targetFile)) ? await fs.readFile(targetFile, 'utf8') : '';
|
|
const splitted = existingContent.split('// AUTO-GENERATED BY');
|
|
const staticContent = splitted[0];
|
|
|
|
const runtimeContent = `export const databaseSchema: DatabaseTables = {\n${tableStrings.join('\n')}\n};`;
|
|
|
|
const listRendererDependency = `type ListRendererDatabaseDependency = ${generateListRenderDependencyType(definitions.tables)};`;
|
|
const noteListTypeFilePath = `${rootDir}/packages/lib/services/plugins/api/noteListType.ts`;
|
|
|
|
await fs.writeFile(targetFile, `${staticContent}\n\n${header}\n\n${tsString}\n\n${runtimeContent}`, 'utf8');
|
|
|
|
console.info(`Writing ListRendererDatabaseDependency type to ${noteListTypeFilePath}...`);
|
|
|
|
await insertContentIntoFile(
|
|
noteListTypeFilePath,
|
|
'// AUTO-GENERATED by generate-database-type\n',
|
|
'\n// AUTO-GENERATED by generate-database-type',
|
|
listRendererDependency,
|
|
);
|
|
}
|
|
|
|
main().catch((error) => {
|
|
console.error(error);
|
|
process.exit(1);
|
|
});
|