@typed-assistant/builder 0.0.34 → 0.0.36
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 +5 -5
- package/src/appProcess.tsx +16 -3
- package/src/getAddonInfo.tsx +74 -0
- package/src/restartAddon.tsx +12 -0
- package/src/setupWebhook.tsx +1 -13
- package/src/setupWebserver.tsx +9 -12
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@typed-assistant/builder",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.36",
|
|
4
4
|
"exports": {
|
|
5
5
|
"./appProcess": "./src/appProcess.tsx",
|
|
6
6
|
"./bunInstall": "./src/bunInstall.tsx",
|
|
@@ -24,10 +24,10 @@
|
|
|
24
24
|
"home-assistant-js-websocket": "^8.2.0",
|
|
25
25
|
"ts-toolbelt": "^9.6.0",
|
|
26
26
|
"typescript": "^5.3.3",
|
|
27
|
-
"@typed-assistant/
|
|
28
|
-
"@typed-assistant/
|
|
29
|
-
"@typed-assistant/
|
|
30
|
-
"@typed-assistant/utils": "0.0.
|
|
27
|
+
"@typed-assistant/eslint-config": "0.0.8",
|
|
28
|
+
"@typed-assistant/logger": "0.0.12",
|
|
29
|
+
"@typed-assistant/typescript-config": "0.0.8",
|
|
30
|
+
"@typed-assistant/utils": "0.0.13"
|
|
31
31
|
},
|
|
32
32
|
"peerDependencies": {
|
|
33
33
|
"home-assistant-js-websocket": "^8.2.0"
|
package/src/appProcess.tsx
CHANGED
|
@@ -15,7 +15,8 @@ import { setupGitPoller } from "./setupGitPoller"
|
|
|
15
15
|
import { setupWebhook } from "./setupWebhook"
|
|
16
16
|
import { startWebappServer } from "./setupWebserver"
|
|
17
17
|
import { restartAddon } from "./restartAddon"
|
|
18
|
-
import { getAddonInfo } from "./getAddonInfo"
|
|
18
|
+
import { getAddonInfo as getAddonInfoAPI } from "./getAddonInfo"
|
|
19
|
+
import debounce from "debounce"
|
|
19
20
|
|
|
20
21
|
type Processes = Awaited<ReturnType<typeof buildAndStartAppProcess>>
|
|
21
22
|
|
|
@@ -71,6 +72,7 @@ const checkProcesses = async (
|
|
|
71
72
|
) => {
|
|
72
73
|
const ps = await $`ps -f`.text()
|
|
73
74
|
const matches = ps.match(new RegExp(`bun .+${entryFile}`, "gmi")) ?? []
|
|
75
|
+
onProcessError?.("message", addonUrl, restartAddonUrl)
|
|
74
76
|
|
|
75
77
|
if (matches.length > 1) {
|
|
76
78
|
multipleProcessesErrorCount++
|
|
@@ -145,6 +147,16 @@ export async function setup({
|
|
|
145
147
|
return subprocesses
|
|
146
148
|
}
|
|
147
149
|
|
|
150
|
+
const getAddonInfo = async () => {
|
|
151
|
+
log("🔍 Getting addon info...")
|
|
152
|
+
|
|
153
|
+
const { data, error } = await getAddonInfoAPI()
|
|
154
|
+
|
|
155
|
+
if (error) log(`🚨 Failed to get addon info: ${error}`)
|
|
156
|
+
|
|
157
|
+
return data
|
|
158
|
+
}
|
|
159
|
+
|
|
148
160
|
const setupGitSync = async () => {
|
|
149
161
|
if (
|
|
150
162
|
!process.env.GITHUB_TOKEN ||
|
|
@@ -191,7 +203,8 @@ function setupWatcher({
|
|
|
191
203
|
const watcher = watch(
|
|
192
204
|
directoryToWatch,
|
|
193
205
|
{ recursive: true },
|
|
194
|
-
async function onFileChange(event, filename) {
|
|
206
|
+
debounce(async function onFileChange(event, filename) {
|
|
207
|
+
console.log("😅😅😅 ~ event:", event)
|
|
195
208
|
if (!filename) return
|
|
196
209
|
if (shouldIgnoreFileOrFolder(filename)) return
|
|
197
210
|
log(`⚠️ Change to ${filename} detected.`)
|
|
@@ -203,7 +216,7 @@ function setupWatcher({
|
|
|
203
216
|
await killAndRestartApp(entryFile, { mdiPaths }, getSubprocesses()),
|
|
204
217
|
)
|
|
205
218
|
}
|
|
206
|
-
},
|
|
219
|
+
}, 200),
|
|
207
220
|
)
|
|
208
221
|
|
|
209
222
|
addKillListener(() => {
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { log } from "@typed-assistant/logger"
|
|
2
|
+
import { getSupervisorAPI } from "@typed-assistant/utils/getHassAPI"
|
|
3
|
+
import { withErrorHandling } from "@typed-assistant/utils/withErrorHandling"
|
|
4
|
+
|
|
5
|
+
type AddonInfoResponse = {
|
|
6
|
+
result: string
|
|
7
|
+
data: {
|
|
8
|
+
name: string
|
|
9
|
+
slug: string
|
|
10
|
+
hostname: string
|
|
11
|
+
description: string
|
|
12
|
+
long_description: string
|
|
13
|
+
advanced: boolean
|
|
14
|
+
stage: string
|
|
15
|
+
repository: string
|
|
16
|
+
version_latest: string
|
|
17
|
+
protected: boolean
|
|
18
|
+
rating: number
|
|
19
|
+
boot: string
|
|
20
|
+
arch: string[]
|
|
21
|
+
machine: any[]
|
|
22
|
+
homeassistant: null
|
|
23
|
+
url: string
|
|
24
|
+
detached: boolean
|
|
25
|
+
available: boolean
|
|
26
|
+
build: boolean
|
|
27
|
+
network: null
|
|
28
|
+
network_description: null
|
|
29
|
+
host_network: boolean
|
|
30
|
+
host_pid: boolean
|
|
31
|
+
host_ipc: boolean
|
|
32
|
+
host_uts: boolean
|
|
33
|
+
host_dbus: boolean
|
|
34
|
+
full_access: boolean
|
|
35
|
+
apparmor: string
|
|
36
|
+
icon: boolean
|
|
37
|
+
logo: boolean
|
|
38
|
+
changelog: boolean
|
|
39
|
+
documentation: boolean
|
|
40
|
+
stdin: boolean
|
|
41
|
+
hassio_api: boolean
|
|
42
|
+
hassio_role: string
|
|
43
|
+
auth_api: boolean
|
|
44
|
+
homeassistant_api: boolean
|
|
45
|
+
gpio: boolean
|
|
46
|
+
usb: boolean
|
|
47
|
+
uart: boolean
|
|
48
|
+
kernel_modules: boolean
|
|
49
|
+
devicetree: boolean
|
|
50
|
+
udev: boolean
|
|
51
|
+
docker_api: boolean
|
|
52
|
+
video: boolean
|
|
53
|
+
audio: boolean
|
|
54
|
+
startup: string
|
|
55
|
+
ingress: boolean
|
|
56
|
+
signed: boolean
|
|
57
|
+
state: string
|
|
58
|
+
webui: null
|
|
59
|
+
ingress_entry: string
|
|
60
|
+
ingress_url: string
|
|
61
|
+
ingress_port: number
|
|
62
|
+
ingress_panel: boolean
|
|
63
|
+
audio_input: null
|
|
64
|
+
audio_output: null
|
|
65
|
+
auto_update: boolean
|
|
66
|
+
ip_address: string
|
|
67
|
+
version: string
|
|
68
|
+
update_available: boolean
|
|
69
|
+
watchdog: boolean
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
export const getAddonInfo = () =>
|
|
74
|
+
withErrorHandling(getSupervisorAPI)<AddonInfoResponse>("/addons/self/info")
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { log } from "@typed-assistant/logger"
|
|
2
|
+
import { getSupervisorAPI } from "@typed-assistant/utils/getHassAPI"
|
|
3
|
+
|
|
4
|
+
export const restartAddon = async () => {
|
|
5
|
+
if (!process.env.SUPERVISOR_TOKEN) {
|
|
6
|
+
log("♻️ Can't restart addon. Exiting...")
|
|
7
|
+
process.exit(1)
|
|
8
|
+
return
|
|
9
|
+
}
|
|
10
|
+
log("♻️ Restarting addon...")
|
|
11
|
+
await getSupervisorAPI(`/addons/self/restart`, { method: "POST" })
|
|
12
|
+
}
|
package/src/setupWebhook.tsx
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { log } from "@typed-assistant/logger"
|
|
2
|
+
import { handleFetchError } from "@typed-assistant/utils/getHassAPI"
|
|
2
3
|
import { withErrorHandling } from "@typed-assistant/utils/withErrorHandling"
|
|
3
4
|
import { z } from "zod"
|
|
4
5
|
|
|
@@ -97,19 +98,6 @@ const Webhook = z.object({
|
|
|
97
98
|
|
|
98
99
|
type Webhook = z.infer<typeof Webhook>
|
|
99
100
|
|
|
100
|
-
const handleFetchError = async (d: Response): Promise<Response> => {
|
|
101
|
-
if (!d.ok)
|
|
102
|
-
throw new Error(
|
|
103
|
-
d.status +
|
|
104
|
-
" " +
|
|
105
|
-
d.statusText +
|
|
106
|
-
(d.headers.get("Content-Type")?.includes("application/json")
|
|
107
|
-
? `:\n${JSON.stringify(await d.json(), null, 2)}`
|
|
108
|
-
: ""),
|
|
109
|
-
)
|
|
110
|
-
return d
|
|
111
|
-
}
|
|
112
|
-
|
|
113
101
|
const retryTimeout = 2000
|
|
114
102
|
let retries = 0
|
|
115
103
|
export const setupWebhook = async (): Promise<void> => {
|
package/src/setupWebserver.tsx
CHANGED
|
@@ -6,15 +6,9 @@ import { Elysia, t } from "elysia"
|
|
|
6
6
|
import { watch } from "fs"
|
|
7
7
|
import { basename, join } from "path"
|
|
8
8
|
import type { List, String } from "ts-toolbelt"
|
|
9
|
-
import {
|
|
10
|
-
addKillListener,
|
|
11
|
-
addSoftKillListener,
|
|
12
|
-
killSubprocess,
|
|
13
|
-
} from "./killProcess"
|
|
14
|
-
import { restartAddon } from "./restartAddon"
|
|
15
9
|
import { getAddonInfo } from "./getAddonInfo"
|
|
16
|
-
import {
|
|
17
|
-
import {
|
|
10
|
+
import { addKillListener, killSubprocess } from "./killProcess"
|
|
11
|
+
import { restartAddon } from "./restartAddon"
|
|
18
12
|
|
|
19
13
|
const indexHtmlFilePath = `${import.meta.dir}/webserver/index.html` as const
|
|
20
14
|
const cssFile = `${import.meta.dir}/webserver/input.css` as const
|
|
@@ -116,12 +110,15 @@ export const startWebappServer = async ({
|
|
|
116
110
|
restartAddon()
|
|
117
111
|
})
|
|
118
112
|
.get("/addon-info", async () => {
|
|
119
|
-
const { data, error } = await
|
|
120
|
-
data: { ingress_entry: string }
|
|
121
|
-
}>("/addons/self/info")
|
|
113
|
+
const { data, error } = await getAddonInfo()
|
|
122
114
|
|
|
123
115
|
if (error) return error
|
|
124
|
-
return
|
|
116
|
+
return {
|
|
117
|
+
...data.data,
|
|
118
|
+
options: "HIDDEN",
|
|
119
|
+
schema: "HIDDEN",
|
|
120
|
+
translations: "HIDDEN",
|
|
121
|
+
}
|
|
125
122
|
})
|
|
126
123
|
.get(
|
|
127
124
|
"/log.txt",
|