@lvce-editor/shared-process 0.14.7 → 0.14.8
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.
- package/package.json +4 -4
- package/src/parts/AutoUpdater/AutoUpdater.ipc.js +9 -0
- package/src/parts/AutoUpdater/AutoUpdater.js +29 -0
- package/src/parts/AutoUpdaterAppImage/AutoUpdaterAppImage.js +85 -0
- package/src/parts/CompareVersion/CompareVersion.js +3 -0
- package/src/parts/GetLatestReleaseVersion/GetLatestReleaseVersion.js +60 -0
- package/src/parts/IsAutoUpdateSupported/IsAutoUpdateSupported.ipc.js +7 -0
- package/src/parts/IsAutoUpdateSupported/IsAutoUpdateSupported.js +10 -0
- package/src/parts/Module/Module.js +4 -0
- package/src/parts/ModuleId/ModuleId.js +2 -0
- package/src/parts/ModuleMap/ModuleMap.js +6 -0
- package/src/parts/Platform/Platform.js +10 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lvce-editor/shared-process",
|
|
3
|
-
"version": "0.14.
|
|
3
|
+
"version": "0.14.8",
|
|
4
4
|
"description": "Utility package for @lvce-editor/server",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -17,9 +17,9 @@
|
|
|
17
17
|
},
|
|
18
18
|
"dependencies": {
|
|
19
19
|
"@babel/code-frame": "^7.21.4",
|
|
20
|
-
"@lvce-editor/extension-host": "0.14.
|
|
21
|
-
"@lvce-editor/extension-host-helper-process": "0.14.
|
|
22
|
-
"@lvce-editor/pty-host": "0.14.
|
|
20
|
+
"@lvce-editor/extension-host": "0.14.8",
|
|
21
|
+
"@lvce-editor/extension-host-helper-process": "0.14.8",
|
|
22
|
+
"@lvce-editor/pty-host": "0.14.8",
|
|
23
23
|
"debug": "^4.3.4",
|
|
24
24
|
"execa": "^7.1.1",
|
|
25
25
|
"exit-hook": "^3.2.0",
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import * as AutoUpdater from './AutoUpdater.js'
|
|
2
|
+
|
|
3
|
+
export const name = 'AutoUpdater'
|
|
4
|
+
|
|
5
|
+
export const Commands = {
|
|
6
|
+
checkForUpdatesAndNotify: AutoUpdater.checkForUpdatesAndNotify,
|
|
7
|
+
downloadUpdate: AutoUpdater.downloadUpdate,
|
|
8
|
+
installAndRestart: AutoUpdater.installAndRestart,
|
|
9
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import * as AutoUpdaterAppImage from '../AutoUpdaterAppImage/AutoUpdaterAppImage.js'
|
|
2
|
+
import { VError } from '../VError/VError.js'
|
|
3
|
+
|
|
4
|
+
export const checkForUpdatesAndNotify = async () => {
|
|
5
|
+
try {
|
|
6
|
+
return await AutoUpdaterAppImage.checkForUpdatesAndNotify()
|
|
7
|
+
} catch (error) {
|
|
8
|
+
// @ts-ignore
|
|
9
|
+
throw new VError(error, `Failed to check for updates`)
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export const downloadUpdate = async (version) => {
|
|
14
|
+
try {
|
|
15
|
+
return await AutoUpdaterAppImage.downloadUpdate(version)
|
|
16
|
+
} catch (error) {
|
|
17
|
+
// @ts-ignore
|
|
18
|
+
throw new VError(error, `Failed to download update`)
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export const installAndRestart = async (downloadPath) => {
|
|
23
|
+
try {
|
|
24
|
+
return await AutoUpdaterAppImage.installAndRestart(downloadPath)
|
|
25
|
+
} catch (error) {
|
|
26
|
+
// @ts-ignore
|
|
27
|
+
throw new VError(error, `Failed to install and restart`)
|
|
28
|
+
}
|
|
29
|
+
}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { spawn } from 'node:child_process'
|
|
2
|
+
import { chmod, rename } from 'node:fs/promises'
|
|
3
|
+
import { tmpdir } from 'node:os'
|
|
4
|
+
import { join } from 'node:path'
|
|
5
|
+
import * as Assert from '../Assert/Assert.js'
|
|
6
|
+
import * as CompareVersion from '../CompareVersion/CompareVersion.js'
|
|
7
|
+
import * as Download from '../Download/Download.js'
|
|
8
|
+
import * as GetLatestReleaseVersion from '../GetLatestReleaseVersion/GetLatestReleaseVersion.js'
|
|
9
|
+
import * as Platform from '../Platform/Platform.js'
|
|
10
|
+
import { VError } from '../VError/VError.js'
|
|
11
|
+
|
|
12
|
+
const getDownloadUrl = (repository, version, appImageName) => {
|
|
13
|
+
Assert.string(version)
|
|
14
|
+
return `https://github.com/${repository}/releases/download/v${version}/${appImageName}-v${version}.AppImage`
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const getOutfilePath = (version) => {
|
|
18
|
+
Assert.string(version)
|
|
19
|
+
const outFile = join(tmpdir(), `appimage-${version}`)
|
|
20
|
+
return outFile
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export const downloadUpdate = async (version) => {
|
|
24
|
+
try {
|
|
25
|
+
Assert.string(version)
|
|
26
|
+
const repository = Platform.getRepository()
|
|
27
|
+
const appImageName = Platform.getAppImageName()
|
|
28
|
+
const downLoadUrl = getDownloadUrl(repository, version, appImageName)
|
|
29
|
+
const outFile = getOutfilePath(version)
|
|
30
|
+
await Download.download(downLoadUrl, outFile)
|
|
31
|
+
} catch (error) {
|
|
32
|
+
// @ts-ignore
|
|
33
|
+
throw new VError(error, `Failed to download new version ${version}`)
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export const checkForUpdatesAndNotify = async () => {
|
|
38
|
+
const repository = Platform.getRepository()
|
|
39
|
+
const version = await GetLatestReleaseVersion.getLatestReleaseVersion(repository)
|
|
40
|
+
const currentVersion = Platform.version
|
|
41
|
+
if (CompareVersion.isGreater(version, currentVersion)) {
|
|
42
|
+
return {
|
|
43
|
+
version,
|
|
44
|
+
}
|
|
45
|
+
} else {
|
|
46
|
+
console.log('not update is available')
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const getAppImagePath = () => {
|
|
51
|
+
return process.env.APPIMAGE
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const installNewAppImage = async (appImageFile, downloadPath) => {
|
|
55
|
+
try {
|
|
56
|
+
await rename(downloadPath, appImageFile)
|
|
57
|
+
} catch (error) {
|
|
58
|
+
// @ts-ignore
|
|
59
|
+
throw new VError(error, `Failed to rename AppImage file`)
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
const restart = (downloadPath) => {
|
|
64
|
+
// TODO handle errors
|
|
65
|
+
spawn(downloadPath, { stdio: 'inherit' })
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
const makeExecutable = async (file) => {
|
|
69
|
+
await chmod(file, 0o755)
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export const installAndRestart = async (downloadPath) => {
|
|
73
|
+
try {
|
|
74
|
+
const appImageFile = getAppImagePath()
|
|
75
|
+
if (!appImageFile) {
|
|
76
|
+
throw new Error(`AppImage path not found`)
|
|
77
|
+
}
|
|
78
|
+
await makeExecutable(downloadPath)
|
|
79
|
+
await installNewAppImage(appImageFile, downloadPath)
|
|
80
|
+
await restart(downloadPath)
|
|
81
|
+
} catch (error) {
|
|
82
|
+
// @ts-ignore
|
|
83
|
+
throw new VError(error, `Failed to install AppImage update`)
|
|
84
|
+
}
|
|
85
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import got, { HTTPError } from 'got'
|
|
2
|
+
import { VError } from '../VError/VError.js'
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
*
|
|
6
|
+
* @param {HTTPError} error
|
|
7
|
+
*/
|
|
8
|
+
const getHttpErrorMessage = (error) => {
|
|
9
|
+
try {
|
|
10
|
+
const body = error.response.body
|
|
11
|
+
if (error.response.url.includes('api.github.com') && typeof body === 'string') {
|
|
12
|
+
const json = JSON.parse(body)
|
|
13
|
+
if (json.message) {
|
|
14
|
+
const message = json.message
|
|
15
|
+
if (message.includes('rate limit exceeded')) {
|
|
16
|
+
const reset = error.response.headers['x-ratelimit-reset']
|
|
17
|
+
const limit = error.response.headers['x-ratelimit-limit']
|
|
18
|
+
if (reset && typeof reset === 'string' && typeof limit === 'string') {
|
|
19
|
+
const resetDate = new Date(parseInt(reset) * 1000)
|
|
20
|
+
const limitAmount = parseInt(limit)
|
|
21
|
+
return `GitHub rate limit of ${limitAmount} requests per hour execeeded, resets at ${resetDate}`
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
return json.message
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
} catch {}
|
|
28
|
+
return `${error.message}`
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const parseVersionFromUrl = (url, repository) => {
|
|
32
|
+
if (!url.includes('releases/tag')) {
|
|
33
|
+
if (url.endsWith('/releases')) {
|
|
34
|
+
throw new Error(`no releases found for ${repository}`)
|
|
35
|
+
}
|
|
36
|
+
throw new Error(`cannot parse release version from url ${url}`)
|
|
37
|
+
}
|
|
38
|
+
const slashIndex = url.lastIndexOf('/')
|
|
39
|
+
const version = url.slice(slashIndex + 1)
|
|
40
|
+
if (version.startsWith('v')) {
|
|
41
|
+
return version.slice(1)
|
|
42
|
+
}
|
|
43
|
+
return version
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export const getLatestReleaseVersion = async (repository) => {
|
|
47
|
+
try {
|
|
48
|
+
const json = await got.head(`https://github.com/${repository}/releases/latest`)
|
|
49
|
+
const finalUrl = json.url
|
|
50
|
+
const version = parseVersionFromUrl(finalUrl, repository)
|
|
51
|
+
return version
|
|
52
|
+
} catch (error) {
|
|
53
|
+
if (error instanceof HTTPError) {
|
|
54
|
+
const httpErrorMessage = getHttpErrorMessage(error)
|
|
55
|
+
throw new VError(`Failed to get latest release for ${repository}: ${httpErrorMessage}`)
|
|
56
|
+
}
|
|
57
|
+
// @ts-ignore
|
|
58
|
+
throw new VError(error, `Failed to get latest release for ${repository}`)
|
|
59
|
+
}
|
|
60
|
+
}
|
|
@@ -44,6 +44,10 @@ export const load = (moduleId) => {
|
|
|
44
44
|
return import('../Workspace/Workspace.ipc.js')
|
|
45
45
|
case ModuleId.InstallExtension:
|
|
46
46
|
return import('../InstallExtension/InstallExtension.ipc.js')
|
|
47
|
+
case ModuleId.AutoUpdater:
|
|
48
|
+
return import('../AutoUpdater/AutoUpdater.ipc.js')
|
|
49
|
+
case ModuleId.IsAutoUpdateSupported:
|
|
50
|
+
return import('../IsAutoUpdateSupported/IsAutoUpdateSupported.ipc.js')
|
|
47
51
|
default:
|
|
48
52
|
throw new Error(`module ${moduleId} not found`)
|
|
49
53
|
}
|
|
@@ -3,6 +3,10 @@ import * as ModuleId from '../ModuleId/ModuleId.js'
|
|
|
3
3
|
|
|
4
4
|
export const getModuleId = (commandId) => {
|
|
5
5
|
switch (commandId) {
|
|
6
|
+
case 'AutoUpdater.checkForUpdatesAndNotify':
|
|
7
|
+
case 'AutoUpdater.downloadUpdate':
|
|
8
|
+
case 'AutoUpdater.installAndRestart':
|
|
9
|
+
return ModuleId.AutoUpdater
|
|
6
10
|
case 'BulkReplacement.applyBulkReplacement':
|
|
7
11
|
return ModuleId.BulkReplacement
|
|
8
12
|
case 'ChromeExtension.install':
|
|
@@ -99,6 +103,8 @@ export const getModuleId = (commandId) => {
|
|
|
99
103
|
case 'GitLsFiles.gitLsFilesHash':
|
|
100
104
|
case 'GitLsFiles.resolveGit':
|
|
101
105
|
return ModuleId.GitLsFiles
|
|
106
|
+
case 'IsAutoUpdateSupported.isAutoUpdateSupported':
|
|
107
|
+
return ModuleId.IsAutoUpdateSupported
|
|
102
108
|
case 'Native.openFolder':
|
|
103
109
|
return ModuleId.Native
|
|
104
110
|
case 'OutputChannel.close':
|
|
@@ -147,3 +147,13 @@ export const getDownloadDir = () => {
|
|
|
147
147
|
const { XDG_DOWNLOAD_DIR } = env
|
|
148
148
|
return XDG_DOWNLOAD_DIR || join(homeDir, 'Downloads')
|
|
149
149
|
}
|
|
150
|
+
|
|
151
|
+
export const getRepository = () => {
|
|
152
|
+
return `lvce-editor/lvce-editor`
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
export const getAppImageName = () => {
|
|
156
|
+
return 'Lvce'
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
export const version = '0.0.0-dev'
|