techeduspace 0.2.3 → 0.2.4

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.
Files changed (2) hide show
  1. package/bin/techeduspace.js +81 -12
  2. package/package.json +1 -1
@@ -37,8 +37,14 @@ function findInstalledApp() {
37
37
  }
38
38
  } else if (platform === "darwin") {
39
39
  const candidates = [
40
- "/Applications/TechEduSpace.app/Contents/MacOS/TechEduSpace",
41
- path.join(os.homedir(), "Applications", "TechEduSpace.app", "Contents", "MacOS", "TechEduSpace"),
40
+ "/Applications/TechEduSpace Beta.app",
41
+ "/Applications/TechEduSpace.app",
42
+ path.join(os.homedir(), "Applications", "TechEduSpace Beta.app"),
43
+ path.join(os.homedir(), "Applications", "TechEduSpace.app"),
44
+ path.resolve(__dirname, "../../dist/mac-arm64/TechEduSpace Beta.app"),
45
+ path.resolve(__dirname, "../../dist/mac/TechEduSpace.app"),
46
+ path.resolve(process.cwd(), "agents/tes-exam-app/dist/mac-arm64/TechEduSpace Beta.app"),
47
+ path.resolve(process.cwd(), "dist/mac-arm64/TechEduSpace Beta.app"),
42
48
  ]
43
49
  for (const c of candidates) {
44
50
  if (fs.existsSync(c)) return c
@@ -48,15 +54,38 @@ function findInstalledApp() {
48
54
  const p = execSync("which techeduspace 2>/dev/null").toString().trim()
49
55
  if (p && fs.existsSync(p)) return p
50
56
  } catch {}
57
+ const defaultAppImage = path.join(os.homedir(), ".local", "bin", "TESExamApp.AppImage")
58
+ if (fs.existsSync(defaultAppImage)) return defaultAppImage
51
59
  }
52
60
  return null
53
61
  }
54
62
 
63
+ function launchApp(appPath) {
64
+ const platform = os.platform()
65
+ log(`Launching TechEduSpace workstation...`)
66
+
67
+ let executable = appPath
68
+ if (platform === "darwin" && appPath.endsWith(".app")) {
69
+ const binName = path.basename(appPath, ".app")
70
+ const innerBin = path.join(appPath, "Contents", "MacOS", binName)
71
+ if (fs.existsSync(innerBin)) {
72
+ executable = innerBin
73
+ }
74
+ }
75
+
76
+ const env = { ...process.env }
77
+ delete env.ELECTRON_RUN_AS_NODE
78
+
79
+ const child = spawn(executable, [], { detached: true, stdio: "ignore", env })
80
+ child.unref()
81
+ process.exit(0)
82
+ }
83
+
55
84
  function downloadFile(url, dest) {
56
85
  return new Promise((resolve, reject) => {
57
86
  log(`Downloading installer from ${url}...`)
58
87
  const file = fs.createWriteStream(dest)
59
-
88
+
60
89
  function get(currentUrl) {
61
90
  https.get(currentUrl, (response) => {
62
91
  if (response.statusCode >= 300 && response.statusCode < 400 && response.headers.location) {
@@ -86,10 +115,8 @@ async function main() {
86
115
  const installed = findInstalledApp()
87
116
  if (installed) {
88
117
  log(`Found installed workstation at: ${installed}`)
89
- log("Launching TechEduSpace...")
90
- const child = spawn(installed, [], { detached: true, stdio: "ignore" })
91
- child.unref()
92
- process.exit(0)
118
+ launchApp(installed)
119
+ return
93
120
  }
94
121
 
95
122
  const platform = os.platform()
@@ -107,8 +134,7 @@ async function main() {
107
134
  const newlyInstalled = findInstalledApp()
108
135
  if (newlyInstalled) {
109
136
  log("Installation complete! Launching TechEduSpace...")
110
- const child = spawn(newlyInstalled, [], { detached: true, stdio: "ignore" })
111
- child.unref()
137
+ launchApp(newlyInstalled)
112
138
  } else {
113
139
  log("Installation completed. Launch 'TechEduSpace' from Start Menu.")
114
140
  }
@@ -117,6 +143,51 @@ async function main() {
117
143
  log("You can download directly from: " + url)
118
144
  process.exit(1)
119
145
  }
146
+ } else if (platform === "darwin") {
147
+ log("TechEduSpace is not installed. Downloading macOS installer...")
148
+ const arch = process.arch === "arm64" ? "arm64" : "x64"
149
+ const dmgName = `TESExamApp-darwin-${arch}.dmg`
150
+ const tempDmg = path.join(os.tmpdir(), dmgName)
151
+ const url = `${BASE_DOWNLOAD_URL}/${dmgName}`
152
+
153
+ try {
154
+ await downloadFile(url, tempDmg)
155
+ log("Mounting installer image...")
156
+ const mountPoint = path.join(os.tmpdir(), "TechEduSpaceMount")
157
+ try {
158
+ try { execSync(`hdiutil detach "${mountPoint}" -quiet 2>/dev/null`) } catch {}
159
+ execSync(`hdiutil attach "${tempDmg}" -nobrowse -mountpoint "${mountPoint}" -quiet`)
160
+
161
+ let foundApp = null
162
+ for (const name of ["TechEduSpace Beta.app", "TechEduSpace.app"]) {
163
+ const p = path.join(mountPoint, name)
164
+ if (fs.existsSync(p)) {
165
+ foundApp = p
166
+ break
167
+ }
168
+ }
169
+
170
+ const targetDir = fs.existsSync("/Applications") ? "/Applications" : path.join(os.homedir(), "Applications")
171
+ const targetApp = path.join(targetDir, foundApp ? path.basename(foundApp) : "TechEduSpace Beta.app")
172
+
173
+ if (foundApp) {
174
+ log(`Installing TechEduSpace to ${targetApp}...`)
175
+ execSync(`rm -rf "${targetApp}" && cp -R "${foundApp}" "${targetApp}"`)
176
+ }
177
+ execSync(`hdiutil detach "${mountPoint}" -quiet`)
178
+ fs.unlinkSync(tempDmg)
179
+
180
+ log("Installation complete! Launching TechEduSpace...")
181
+ launchApp(targetApp)
182
+ } catch (mountErr) {
183
+ log("Opening DMG for manual install...")
184
+ execSync(`open "${tempDmg}"`)
185
+ }
186
+ } catch (e) {
187
+ err(`Automated download failed: ${e.message}`)
188
+ log("You can download directly from: https://techeduspace.com/downloads")
189
+ process.exit(1)
190
+ }
120
191
  } else if (platform === "linux") {
121
192
  const appImage = path.join(os.homedir(), ".local", "bin", "TESExamApp.AppImage")
122
193
  fs.mkdirSync(path.dirname(appImage), { recursive: true })
@@ -125,8 +196,7 @@ async function main() {
125
196
  await downloadFile(url, appImage)
126
197
  fs.chmodSync(appImage, 0o755)
127
198
  log("Launching TechEduSpace AppImage...")
128
- const child = spawn(appImage, [], { detached: true, stdio: "ignore" })
129
- child.unref()
199
+ launchApp(appImage)
130
200
  } catch (e) {
131
201
  err(`Download failed: ${e.message}`)
132
202
  process.exit(1)
@@ -140,4 +210,3 @@ main().catch((e) => {
140
210
  err(e.message)
141
211
  process.exit(1)
142
212
  })
143
-
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "techeduspace",
3
- "version": "0.2.3",
3
+ "version": "0.2.4",
4
4
  "description": "Cross-platform CLI installer and workstation launcher for TechEduSpace",
5
5
  "bin": {
6
6
  "techeduspace": "./bin/techeduspace.js"