feat: Initial clean release of CHM
一些检查失败了
automerge / automerge (push) Has been cancelled
react-native-android-build-apk / AssembleRelease (push) Has been cancelled
Build macOS M1 / Main (push) Has been cancelled
Joplin Continuous Integration / Main (macos-15-intel) (push) Has been cancelled
Joplin Continuous Integration / Main (ubuntu-22.04) (push) Has been cancelled
Joplin Continuous Integration / Main (ubuntu-22.04-arm) (push) Has been cancelled
Joplin Continuous Integration / Main (windows-11-vs2026-arm) (push) Has been cancelled
Joplin Continuous Integration / Main (windows-2025) (push) Has been cancelled
Joplin Continuous Integration / ServerDockerImage (ubuntu-22.04) (push) Has been cancelled
Joplin Continuous Integration / ServerDockerImage (ubuntu-22.04-arm) (push) Has been cancelled
Joplin UI tests / Main (ubuntu-22.04) (push) Has been cancelled
Joplin UI tests / Main (windows-2025) (push) Has been cancelled
Joplin UI tests / Mobile (push) Has been cancelled
Close stale issues / ProcessStaleIssues (push) Has been cancelled
一些检查失败了
automerge / automerge (push) Has been cancelled
react-native-android-build-apk / AssembleRelease (push) Has been cancelled
Build macOS M1 / Main (push) Has been cancelled
Joplin Continuous Integration / Main (macos-15-intel) (push) Has been cancelled
Joplin Continuous Integration / Main (ubuntu-22.04) (push) Has been cancelled
Joplin Continuous Integration / Main (ubuntu-22.04-arm) (push) Has been cancelled
Joplin Continuous Integration / Main (windows-11-vs2026-arm) (push) Has been cancelled
Joplin Continuous Integration / Main (windows-2025) (push) Has been cancelled
Joplin Continuous Integration / ServerDockerImage (ubuntu-22.04) (push) Has been cancelled
Joplin Continuous Integration / ServerDockerImage (ubuntu-22.04-arm) (push) Has been cancelled
Joplin UI tests / Main (ubuntu-22.04) (push) Has been cancelled
Joplin UI tests / Main (windows-2025) (push) Has been cancelled
Joplin UI tests / Mobile (push) Has been cancelled
Close stale issues / ProcessStaleIssues (push) Has been cancelled
这个提交包含在:
@@ -0,0 +1,130 @@
|
||||
import { execCommand } from '@joplin/utils';
|
||||
import { insertContentIntoFile, rootDir } from './tool-utils';
|
||||
import { remove } from 'fs-extra';
|
||||
import sqlts, { Table, Column } from '@rmp135/sql-ts';
|
||||
import * as fs from 'fs-extra';
|
||||
|
||||
function createRuntimeObject(table: Table) {
|
||||
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: Table[]) => {
|
||||
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`);
|
||||
const profileDir = `${__dirname}/__generateTypesProfile`;
|
||||
await execCommand(['yarn', 'start', '--profile', profileDir, 'version']);
|
||||
|
||||
try {
|
||||
const sqlTsConfig = {
|
||||
'client': 'sqlite3',
|
||||
'connection': {
|
||||
'filename': `${profileDir}/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: Table) => {
|
||||
// Adding the missing Column fields explicitly may change fromObject() output.
|
||||
t.columns.push({
|
||||
nullable: false,
|
||||
name: 'type_',
|
||||
type: 'int',
|
||||
optional: true,
|
||||
isEnum: false,
|
||||
propertyName: 'type_',
|
||||
propertyType: 'number',
|
||||
} as Column);
|
||||
|
||||
return t;
|
||||
});
|
||||
|
||||
definitions.tables = definitions.tables.map((table: Table) => {
|
||||
table.columns = table.columns.map((column: Column) => {
|
||||
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.trim()}\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,
|
||||
);
|
||||
} finally {
|
||||
await remove(profileDir);
|
||||
}
|
||||
}
|
||||
|
||||
main().catch((error) => {
|
||||
console.error(error);
|
||||
process.exit(1);
|
||||
});
|
||||
在新工单中引用
屏蔽一个用户