electerm-data-tool 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,85 @@
1
+ /**
2
+ * common data upgrade process
3
+ * It will check current version in db and check version in package.json,
4
+ * run every upgrade script one by one
5
+ */
6
+
7
+ const { packInfo } = require('../common/app-props')
8
+ const { version: packVersion } = packInfo
9
+ const { resolve } = require('path')
10
+ const fs = require('fs')
11
+ const log = require('../common/log')
12
+ const compare = require('../common/version-compare')
13
+ const { dbAction } = require('../nedb')
14
+ const _ = require('lodash')
15
+ const { updateDBVersion } = require('./version-upgrade')
16
+ const emptyVersion = '0.0.0'
17
+ const versionQuery = {
18
+ _id: 'version'
19
+ }
20
+
21
+ async function getDBVersion () {
22
+ const version = await dbAction('data', 'findOne', versionQuery)
23
+ .then(doc => {
24
+ return doc ? doc.value : emptyVersion
25
+ })
26
+ .catch(e => {
27
+ log.error(e)
28
+ return emptyVersion
29
+ })
30
+ return version
31
+ }
32
+
33
+ /**
34
+ * get upgrade versions should be run as version upgrade
35
+ */
36
+ async function getUpgradeVersionList () {
37
+ const version = await getDBVersion()
38
+ const list = fs.readdirSync(__dirname)
39
+ return list.filter(f => {
40
+ const vv = f.replace('.js', '').replace('v', '')
41
+ return /^v\d/.test(f) && compare(vv, version) > 0 && compare(vv, packVersion) <= 0
42
+ }).sort((a, b) => {
43
+ return compare(a, b)
44
+ })
45
+ }
46
+ async function versionShouldUpgrade () {
47
+ const dbVersion = await getDBVersion()
48
+ log.info('database version:', dbVersion)
49
+ return compare(dbVersion, packVersion) < 0
50
+ }
51
+
52
+ async function shouldUpgrade () {
53
+ const shouldUpgradeVersion = await versionShouldUpgrade()
54
+ if (!shouldUpgradeVersion) {
55
+ return false
56
+ }
57
+ const dbVersion = await getDBVersion()
58
+ log.info('dbVersion', dbVersion)
59
+ if (dbVersion === emptyVersion) {
60
+ return false
61
+ }
62
+ const list = await getUpgradeVersionList()
63
+ if (_.isEmpty(list)) {
64
+ await updateDBVersion(packVersion)
65
+ return false
66
+ }
67
+ return {
68
+ dbVersion,
69
+ packVersion
70
+ }
71
+ }
72
+
73
+ async function doUpgrade () {
74
+ const list = await getUpgradeVersionList()
75
+ log.info('Upgrading...')
76
+ for (const v of list) {
77
+ const p = resolve(__dirname, v)
78
+ const run = require(p)
79
+ await run()
80
+ }
81
+ log.info('Upgrade end')
82
+ }
83
+
84
+ exports.checkDbUpgrade = shouldUpgrade
85
+ exports.doUpgrade = doUpgrade
@@ -0,0 +1,117 @@
1
+ /**
2
+ * migrate from NeDB (v1) to SQLite (v2)
3
+ */
4
+
5
+ const { resolve } = require('path')
6
+ const { existsSync, renameSync } = require('fs')
7
+ const { appPath, defaultUserName } = require('../common/app-props')
8
+ const log = require('../common/log')
9
+
10
+ const reso = (name) => {
11
+ return resolve(appPath, 'electerm', 'users', defaultUserName, `electerm.${name}.nedb`)
12
+ }
13
+
14
+ const tables = [
15
+ 'bookmarks',
16
+ 'bookmarkGroups',
17
+ 'addressBookmarks',
18
+ 'terminalThemes',
19
+ 'lastStates',
20
+ 'data',
21
+ 'quickCommands',
22
+ 'log',
23
+ 'dbUpgradeLog',
24
+ 'profiles'
25
+ ]
26
+
27
+ /**
28
+ * Check if migration from v1 (NeDB) to v2 (SQLite) is needed
29
+ * @returns {boolean} true if migration is needed
30
+ */
31
+ function checkMigrate () {
32
+ if (process.versions.node < '22.0.0') {
33
+ return false
34
+ }
35
+ // Check if any NeDB files exist
36
+ for (const table of tables) {
37
+ const nedbPath = reso(table)
38
+ if (existsSync(nedbPath)) {
39
+ return true
40
+ }
41
+ }
42
+ return false
43
+ }
44
+
45
+ /**
46
+ * Migrate all data from NeDB to SQLite and backup NeDB files
47
+ */
48
+ async function migrate () {
49
+ log.info('Starting migration from NeDB (v1) to SQLite (v2)...')
50
+ // Import both database modules
51
+ const nedbModule = require('../nedb')
52
+ const sqliteModule = require('../sqlite')
53
+ const {
54
+ checkDbUpgrade,
55
+ doUpgrade
56
+ } = require('./index')
57
+ if (await checkDbUpgrade()) {
58
+ await doUpgrade()
59
+ }
60
+
61
+ const timeStamp = Date.now()
62
+
63
+ // Migrate data from each table
64
+ for (const table of tables) {
65
+ const nedbPath = reso(table)
66
+
67
+ if (existsSync(nedbPath)) {
68
+ log.info(`Migrating table: ${table}`)
69
+
70
+ // Read all data from NeDB
71
+ const nedbData = await nedbModule.dbAction(table, 'find', {})
72
+
73
+ if (nedbData && nedbData.length > 0) {
74
+ log.info(`Found ${nedbData.length} records in ${table}`)
75
+
76
+ // Insert/update data into SQLite using upsert to avoid conflicts
77
+ for (const record of nedbData) {
78
+ // Ensure record has an _id field
79
+ const recordId = record._id || record.id
80
+ if (!recordId) {
81
+ log.warn(`Record in ${table} has no _id or id field, skipping:`, record)
82
+ continue
83
+ }
84
+ // Use update with upsert option to handle existing records gracefully
85
+ await sqliteModule.dbAction(table, 'update',
86
+ { _id: recordId },
87
+ { $set: record },
88
+ { upsert: true }
89
+ )
90
+ }
91
+
92
+ log.info(`Successfully migrated ${nedbData.length} records from ${table}`)
93
+ } else {
94
+ log.info(`Table ${table} is empty, nothing to migrate`)
95
+ }
96
+
97
+ // Rename NeDB file to .bak
98
+ const backupPath = `${nedbPath}-${timeStamp}.bak`
99
+ try {
100
+ renameSync(nedbPath, backupPath)
101
+ log.info(`Backed up ${nedbPath} to ${backupPath}`)
102
+ } catch (renameError) {
103
+ log.error(`Error backing up ${nedbPath}:`, renameError)
104
+ }
105
+ } else {
106
+ log.info(`NeDB file for ${table} does not exist, skipping`)
107
+ }
108
+ }
109
+
110
+ log.info('Migration from NeDB to SQLite completed successfully')
111
+ return true
112
+ }
113
+
114
+ module.exports = {
115
+ checkMigrate,
116
+ migrate
117
+ }
@@ -0,0 +1,48 @@
1
+ /**
2
+ * upgrade database to v1.7.0
3
+ */
4
+
5
+ const { userConfigId } = require('../common/constants')
6
+ const { dbAction } = require('../lib/nedb')
7
+ const { updateDBVersion } = require('./version-upgrade')
8
+ const log = require('../common/log')
9
+
10
+ async function fixAll () {
11
+ const q = {
12
+ _id: userConfigId
13
+ }
14
+ const conf = await dbAction('data', 'findOne', q)
15
+ if (!conf) {
16
+ return
17
+ }
18
+ if (!conf.syncSetting) {
19
+ conf.syncSetting = {}
20
+ }
21
+ const {
22
+ syncEncrypt,
23
+ githubAccessToken,
24
+ giteeAccessToken
25
+ } = conf.syncSetting
26
+ if (!syncEncrypt) {
27
+ return
28
+ }
29
+ if (githubAccessToken) {
30
+ conf.syncSetting.githubSyncPassword = githubAccessToken
31
+ }
32
+ if (giteeAccessToken) {
33
+ conf.syncSetting.giteeSyncPassword = giteeAccessToken
34
+ }
35
+ delete conf.syncSetting.syncEncrypt
36
+ await dbAction('data', 'update', q, {
37
+ ...q,
38
+ ...conf
39
+ })
40
+ }
41
+
42
+ module.exports = async () => {
43
+ const versionTo = '1.25.0'
44
+ log.info(`Start: upgrading to v${versionTo}`)
45
+ await fixAll()
46
+ await updateDBVersion(versionTo)
47
+ log.info(`Done: upgrading to v${versionTo}`)
48
+ }
@@ -0,0 +1,66 @@
1
+ /**
2
+ * upgrade database to v1.27.7
3
+ */
4
+
5
+ const { userConfigId } = require('../common/constants')
6
+ const { dbAction } = require('../lib/nedb')
7
+ const { updateDBVersion } = require('./version-upgrade')
8
+ const log = require('../common/log')
9
+ const { buildProxyString } = require('../lib/build-proxy')
10
+
11
+ async function fixConf () {
12
+ log.info('Start update global proxy config')
13
+ const q = {
14
+ _id: userConfigId
15
+ }
16
+ const conf = await dbAction('data', 'findOne', q)
17
+ if (!conf) {
18
+ return
19
+ }
20
+ const proxy = buildProxyString(conf)
21
+ if (proxy) {
22
+ conf.proxy = proxy
23
+ }
24
+ const props = [
25
+ 'proxyPort', 'proxyType', 'proxyIp', 'proxyUsername', 'proxyPassword'
26
+ ]
27
+ for (const p of props) {
28
+ delete conf[p]
29
+ }
30
+ await dbAction('data', 'update', q, {
31
+ ...q,
32
+ ...conf
33
+ })
34
+ }
35
+
36
+ async function fixBookmarks () {
37
+ log.info('Start update bookmark proxy config')
38
+ const arr = await dbAction('bookmarks', 'find', {})
39
+ const len = arr.length
40
+ let i = 0
41
+ log.info('bookmarks count:', len)
42
+ for (const b of arr) {
43
+ const proxy = buildProxyString(b.proxy || {})
44
+ console.log(i + 1, b._id, proxy)
45
+ await dbAction('bookmarks', 'update', {
46
+ _id: b._id
47
+ }, {
48
+ ...b,
49
+ proxy
50
+ })
51
+ i = i + 1
52
+ }
53
+ }
54
+
55
+ async function fixAll () {
56
+ await fixConf()
57
+ await fixBookmarks()
58
+ }
59
+
60
+ module.exports = async () => {
61
+ const versionTo = '1.27.17'
62
+ log.info(`Start: upgrading to v${versionTo}`)
63
+ await fixAll()
64
+ await updateDBVersion(versionTo)
65
+ log.info(`Done: upgrading to v${versionTo}`)
66
+ }
@@ -0,0 +1,44 @@
1
+ /**
2
+ * upgrade database to v1.3.9
3
+ * migrate old file based db to nedb
4
+ */
5
+
6
+ const { dbAction, tables } = require('../lib/nedb')
7
+ const { updateDBVersion } = require('./version-upgrade')
8
+ const log = require('../common/log')
9
+
10
+ function wait (time) {
11
+ return new Promise(resolve => {
12
+ setTimeout(resolve, time)
13
+ })
14
+ }
15
+
16
+ async function fixAll () {
17
+ for (const name of tables) {
18
+ const all = await dbAction(name, 'find', {})
19
+ for (const inst of all) {
20
+ const { id, _id, ...rest } = inst
21
+ if (id) {
22
+ await dbAction(name, 'remove', {
23
+ id
24
+ })
25
+ await dbAction(name, 'remove', {
26
+ _id: id
27
+ }, { multi: true })
28
+ await wait(100)
29
+ await dbAction(name, 'insert', {
30
+ _id: id,
31
+ ...rest
32
+ })
33
+ }
34
+ }
35
+ }
36
+ }
37
+
38
+ module.exports = async () => {
39
+ const versionTo = '1.3.9'
40
+ log.info(`Start: upgrading to v${versionTo}`)
41
+ await fixAll()
42
+ await updateDBVersion(versionTo)
43
+ log.info(`Done: upgrading to v${versionTo}`)
44
+ }
@@ -0,0 +1,44 @@
1
+ /**
2
+ * upgrade database to v1.32.36
3
+ */
4
+
5
+ const { dbAction } = require('../lib/nedb')
6
+ const { updateDBVersion } = require('./version-upgrade')
7
+ const log = require('../common/log')
8
+ const { buildSshTunnels } = require('../common/build-ssh-tunnel')
9
+
10
+ async function fixBookmarks () {
11
+ log.info('Start update bookmark Ssh Tunnels config')
12
+ const arr = await dbAction('bookmarks', 'find', {})
13
+ const len = arr.length
14
+ let i = 0
15
+ log.info('bookmarks count:', len)
16
+ for (const b of arr) {
17
+ console.log(i + 1, b._id, b.sshTunnel ? 'has sshTunnel' : 'no sshTunnel')
18
+ if (b.sshTunnel) {
19
+ const sshTunnels = buildSshTunnels(b)
20
+ delete b.sshTunnel
21
+ delete b.sshTunnelRemotePort
22
+ delete b.sshTunnelLocalPort
23
+ await dbAction('bookmarks', 'update', {
24
+ _id: b._id
25
+ }, {
26
+ ...b,
27
+ sshTunnels
28
+ })
29
+ }
30
+ i = i + 1
31
+ }
32
+ }
33
+
34
+ async function fixAll () {
35
+ await fixBookmarks()
36
+ }
37
+
38
+ module.exports = async () => {
39
+ const versionTo = '1.32.36'
40
+ log.info(`Start: upgrading to v${versionTo}`)
41
+ await fixAll()
42
+ await updateDBVersion(versionTo)
43
+ log.info(`Done: upgrading to v${versionTo}`)
44
+ }
@@ -0,0 +1,43 @@
1
+ /**
2
+ * upgrade database to v1.34.20
3
+ */
4
+
5
+ const { dbAction } = require('../lib/nedb')
6
+ const { updateDBVersion } = require('./version-upgrade')
7
+ const log = require('../common/log')
8
+ const { buildRunScripts } = require('../common/build-run-scripts')
9
+
10
+ async function fixBookmarks () {
11
+ log.info('Start update bookmark loginScript config')
12
+ const arr = await dbAction('bookmarks', 'find', {})
13
+ const len = arr.length
14
+ let i = 0
15
+ log.info('bookmarks count:', len)
16
+ for (const b of arr) {
17
+ console.log(i + 1, b._id, b.loginScript ? 'has loginScript' : 'no loginScript')
18
+ if (b.loginScript) {
19
+ const runScripts = buildRunScripts(b)
20
+ delete b.loginScript
21
+ delete b.loginScriptDelay
22
+ await dbAction('bookmarks', 'update', {
23
+ _id: b._id
24
+ }, {
25
+ ...b,
26
+ runScripts
27
+ })
28
+ }
29
+ i = i + 1
30
+ }
31
+ }
32
+
33
+ async function fixAll () {
34
+ await fixBookmarks()
35
+ }
36
+
37
+ module.exports = async () => {
38
+ const versionTo = '1.34.20'
39
+ log.info(`Start: upgrading to v${versionTo}`)
40
+ await fixAll()
41
+ await updateDBVersion(versionTo)
42
+ log.info(`Done: upgrading to v${versionTo}`)
43
+ }
@@ -0,0 +1,32 @@
1
+ /**
2
+ * upgrade database to v1.34.20
3
+ */
4
+
5
+ const { dbAction } = require('../lib/nedb')
6
+ const { userConfigId } = require('../common/constants')
7
+ const { updateDBVersion } = require('./version-upgrade')
8
+ const log = require('../common/log')
9
+
10
+ async function fixAll () {
11
+ log.info('Start update default terminal word separator config')
12
+ const q = {
13
+ _id: userConfigId
14
+ }
15
+ const conf = await dbAction('data', 'findOne', q)
16
+ if (conf && conf.terminalWordSeparator && !conf.terminalWordSeparator.includes(' ')) {
17
+ conf.terminalWordSeparator = conf.terminalWordSeparator.slice(0, 1) + ' ' +
18
+ conf.terminalWordSeparator.slice(1)
19
+ await dbAction('data', 'update', q, {
20
+ ...q,
21
+ ...conf
22
+ })
23
+ }
24
+ }
25
+
26
+ module.exports = async () => {
27
+ const versionTo = '1.34.59'
28
+ log.info(`Start: upgrading to v${versionTo}`)
29
+ await fixAll()
30
+ await updateDBVersion(versionTo)
31
+ log.info(`Done: upgrading to v${versionTo}`)
32
+ }
@@ -0,0 +1,57 @@
1
+ /**
2
+ * upgrade database to v1.5.13
3
+ */
4
+
5
+ const { userConfigId } = require('../common/constants')
6
+ const { dbAction } = require('../lib/nedb')
7
+ const { updateDBVersion } = require('./version-upgrade')
8
+ const log = require('../common/log')
9
+ const { decrypt } = require('../lib/enc')
10
+
11
+ async function fixAll () {
12
+ const q = {
13
+ _id: userConfigId
14
+ }
15
+ const conf = await dbAction('data', 'findOne', q)
16
+ if (!conf.syncSetting) {
17
+ conf.syncSetting = {}
18
+ }
19
+ const {
20
+ encrypted,
21
+ gistId,
22
+ githubAccessToken,
23
+ lastSyncTime
24
+ } = conf.syncSetting
25
+ if (lastSyncTime) {
26
+ conf.syncSetting.githubLastSyncTime = lastSyncTime
27
+ }
28
+ if (gistId) {
29
+ conf.syncSetting.githubGistId = gistId
30
+ }
31
+ if (
32
+ encrypted &&
33
+ gistId &&
34
+ githubAccessToken
35
+ ) {
36
+ const nt = decrypt(
37
+ conf.syncSetting.githubAccessToken,
38
+ conf.syncSetting.gistId
39
+ )
40
+ conf.syncSetting.githubAccessToken = nt
41
+ }
42
+ delete conf.syncSetting.encrypted
43
+ delete conf.syncSetting.lastSyncTime
44
+ delete conf.syncSetting.gistId
45
+ await dbAction('data', 'update', q, {
46
+ ...q,
47
+ ...conf
48
+ })
49
+ }
50
+
51
+ module.exports = async () => {
52
+ const versionTo = '1.5.13'
53
+ log.info(`Start: upgrading to v${versionTo}`)
54
+ await fixAll()
55
+ await updateDBVersion(versionTo)
56
+ log.info(`Done: upgrading to v${versionTo}`)
57
+ }
@@ -0,0 +1,36 @@
1
+ /**
2
+ * upgrade database to v1.7.0
3
+ */
4
+
5
+ const { dbAction } = require('../lib/nedb')
6
+ const { updateDBVersion } = require('./version-upgrade')
7
+ const log = require('../common/log')
8
+ const defaults = require('./db-defaults')
9
+
10
+ async function fixAll () {
11
+ const defaultThemeConfig = defaults[0].data[0]
12
+ const defaultLightThemeConfig = defaults[0].data[1]
13
+ const all = await dbAction('terminalThemes', 'find', {}).catch(log.error) || []
14
+ for (const item of all) {
15
+ const q = {
16
+ _id: item.id || item._id
17
+ }
18
+ const updates = q._id === 'default'
19
+ ? defaultThemeConfig
20
+ : {
21
+ ...item,
22
+ uiThemeConfig: defaultThemeConfig.uiThemeConfig
23
+ }
24
+ await dbAction('terminalThemes', 'update', q, updates).catch(log.error)
25
+ }
26
+ await dbAction('terminalThemes', 'insert', defaultLightThemeConfig).catch(log.error)
27
+ log.info('end: update db')
28
+ }
29
+
30
+ module.exports = async () => {
31
+ const versionTo = '1.7.0'
32
+ log.info(`Start: upgrading to v${versionTo}`)
33
+ await fixAll()
34
+ await updateDBVersion(versionTo)
35
+ log.info(`Done: upgrading to v${versionTo}`)
36
+ }
@@ -0,0 +1,39 @@
1
+ /**
2
+ * upgrade db version
3
+ */
4
+
5
+ /**
6
+ * common data upgrade process
7
+ * It will check current version in db and check version in package.json,
8
+ * run every upgrade script one by one
9
+ */
10
+
11
+ const log = require('../common/log')
12
+ const { dbAction } = require('../nedb')
13
+
14
+ async function updateDBVersion (toVersion) {
15
+ const versionQuery = {
16
+ _id: 'version'
17
+ }
18
+ log.info('upgrade db version to', toVersion)
19
+ await dbAction('data', 'update', versionQuery, {
20
+ ...versionQuery,
21
+ value: toVersion
22
+ }, {
23
+ upsert: true
24
+ })
25
+ .catch(e => {
26
+ log.error(e)
27
+ log.error('upgrade db version error', toVersion)
28
+ })
29
+ await dbAction('dbUpgradeLog', 'insert', {
30
+ time: Date.now(),
31
+ toVersion
32
+ })
33
+ .catch(e => {
34
+ log.error(e)
35
+ log.error('insert dbUpgradeLog error', toVersion)
36
+ })
37
+ }
38
+
39
+ exports.updateDBVersion = updateDBVersion
package/src/nedb.js ADDED
@@ -0,0 +1,52 @@
1
+ /**
2
+ * nedb api wrapper
3
+ */
4
+
5
+ const { appPath, defaultUserName } = require('./common/app-props')
6
+ const { resolve } = require('path')
7
+ const Datastore = require('@yetzt/nedb')
8
+ const db = {}
9
+
10
+ const reso = (name) => {
11
+ return resolve(appPath, 'electerm', 'users', defaultUserName, `electerm.${name}.nedb`)
12
+ }
13
+ const tables = [
14
+ 'bookmarks',
15
+ 'bookmarkGroups',
16
+ 'addressBookmarks',
17
+ 'terminalThemes',
18
+ 'lastStates',
19
+ 'data',
20
+ 'quickCommands',
21
+ 'log',
22
+ 'dbUpgradeLog',
23
+ 'profiles'
24
+ ]
25
+
26
+ tables.forEach(table => {
27
+ const conf = {
28
+ filename: reso(table),
29
+ autoload: true
30
+ }
31
+ db[table] = new Datastore(conf)
32
+ })
33
+
34
+ const dbAction = (dbName, op, ...args) => {
35
+ if (op === 'compactDatafile') {
36
+ db[dbName].persistence.compactDatafile()
37
+ return
38
+ }
39
+ return new Promise((resolve, reject) => {
40
+ db[dbName][op](...args, (err, result) => {
41
+ if (err) {
42
+ return reject(err)
43
+ }
44
+ resolve(result)
45
+ })
46
+ })
47
+ }
48
+
49
+ module.exports = {
50
+ dbAction,
51
+ tables
52
+ }