techeduspace 0.0.0-stage → 0.2.3

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,143 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * TechEduSpace CLI Workstation Launcher
5
+ * Supports: npx techeduspace or npm i -g techeduspace
6
+ * Author: Acadure Private Limited
7
+ */
8
+
9
+ const { spawn, execSync } = require("child_process")
10
+ const fs = require("fs")
11
+ const os = require("os")
12
+ const path = require("path")
13
+ const https = require("https")
14
+
15
+ const REPO = "acadure/acadure"
16
+ const RELEASE_TAG = "tes-exam-app-stable"
17
+ const BASE_DOWNLOAD_URL = `https://github.com/${REPO}/releases/download/${RELEASE_TAG}`
18
+
19
+ function log(msg) {
20
+ console.log(`\x1b[36m[TechEduSpace]\x1b[0m ${msg}`)
21
+ }
22
+
23
+ function err(msg) {
24
+ console.error(`\x1b[31m[TechEduSpace Error]\x1b[0m ${msg}`)
25
+ }
26
+
27
+ function findInstalledApp() {
28
+ const platform = os.platform()
29
+ if (platform === "win32") {
30
+ const candidates = [
31
+ path.join(process.env.LOCALAPPDATA || "", "Programs", "TechEduSpace", "TechEduSpace.exe"),
32
+ path.join(process.env.ProgramFiles || "", "TechEduSpace", "TechEduSpace.exe"),
33
+ path.join(process.env["ProgramFiles(x86)"] || "", "TechEduSpace", "TechEduSpace.exe"),
34
+ ]
35
+ for (const c of candidates) {
36
+ if (fs.existsSync(c)) return c
37
+ }
38
+ } else if (platform === "darwin") {
39
+ const candidates = [
40
+ "/Applications/TechEduSpace.app/Contents/MacOS/TechEduSpace",
41
+ path.join(os.homedir(), "Applications", "TechEduSpace.app", "Contents", "MacOS", "TechEduSpace"),
42
+ ]
43
+ for (const c of candidates) {
44
+ if (fs.existsSync(c)) return c
45
+ }
46
+ } else if (platform === "linux") {
47
+ try {
48
+ const p = execSync("which techeduspace 2>/dev/null").toString().trim()
49
+ if (p && fs.existsSync(p)) return p
50
+ } catch {}
51
+ }
52
+ return null
53
+ }
54
+
55
+ function downloadFile(url, dest) {
56
+ return new Promise((resolve, reject) => {
57
+ log(`Downloading installer from ${url}...`)
58
+ const file = fs.createWriteStream(dest)
59
+
60
+ function get(currentUrl) {
61
+ https.get(currentUrl, (response) => {
62
+ if (response.statusCode >= 300 && response.statusCode < 400 && response.headers.location) {
63
+ get(response.headers.location)
64
+ return
65
+ }
66
+ if (response.statusCode !== 200) {
67
+ reject(new Error(`Failed to download: HTTP ${response.statusCode}`))
68
+ return
69
+ }
70
+ response.pipe(file)
71
+ file.on("finish", () => {
72
+ file.close(() => resolve(dest))
73
+ })
74
+ }).on("error", (err) => {
75
+ fs.unlink(dest, () => {})
76
+ reject(err)
77
+ })
78
+ }
79
+ get(url)
80
+ })
81
+ }
82
+
83
+ async function main() {
84
+ log("Initializing TechEduSpace Examination Workstation...")
85
+
86
+ const installed = findInstalledApp()
87
+ if (installed) {
88
+ 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)
93
+ }
94
+
95
+ const platform = os.platform()
96
+ if (platform === "win32") {
97
+ log("TechEduSpace is not installed. Initiating automated Windows install...")
98
+ const tempInstaller = path.join(os.tmpdir(), "TESExamApp-windows-x64.exe")
99
+ const url = `${BASE_DOWNLOAD_URL}/TESExamApp-windows-x64.exe`
100
+
101
+ try {
102
+ await downloadFile(url, tempInstaller)
103
+ log("Running silent installer (/S)...")
104
+ execSync(`"${tempInstaller}" /S`, { stdio: "inherit" })
105
+ fs.unlinkSync(tempInstaller)
106
+
107
+ const newlyInstalled = findInstalledApp()
108
+ if (newlyInstalled) {
109
+ log("Installation complete! Launching TechEduSpace...")
110
+ const child = spawn(newlyInstalled, [], { detached: true, stdio: "ignore" })
111
+ child.unref()
112
+ } else {
113
+ log("Installation completed. Launch 'TechEduSpace' from Start Menu.")
114
+ }
115
+ } catch (e) {
116
+ err(`Automated install failed: ${e.message}`)
117
+ log("You can download directly from: " + url)
118
+ process.exit(1)
119
+ }
120
+ } else if (platform === "linux") {
121
+ const appImage = path.join(os.homedir(), ".local", "bin", "TESExamApp.AppImage")
122
+ fs.mkdirSync(path.dirname(appImage), { recursive: true })
123
+ const url = `${BASE_DOWNLOAD_URL}/TESExamApp-linux-x64.AppImage`
124
+ try {
125
+ await downloadFile(url, appImage)
126
+ fs.chmodSync(appImage, 0o755)
127
+ log("Launching TechEduSpace AppImage...")
128
+ const child = spawn(appImage, [], { detached: true, stdio: "ignore" })
129
+ child.unref()
130
+ } catch (e) {
131
+ err(`Download failed: ${e.message}`)
132
+ process.exit(1)
133
+ }
134
+ } else {
135
+ log(`Please download TechEduSpace for ${platform} from https://techeduspace.com/downloads`)
136
+ }
137
+ }
138
+
139
+ main().catch((e) => {
140
+ err(e.message)
141
+ process.exit(1)
142
+ })
143
+
package/package.json CHANGED
@@ -1,6 +1,26 @@
1
1
  {
2
2
  "name": "techeduspace",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
6
- }
3
+ "version": "0.2.3",
4
+ "description": "Cross-platform CLI installer and workstation launcher for TechEduSpace",
5
+ "bin": {
6
+ "techeduspace": "./bin/techeduspace.js"
7
+ },
8
+ "keywords": [
9
+ "techeduspace",
10
+ "exam",
11
+ "proctoring",
12
+ "acadure",
13
+ "assessment",
14
+ "coding-test"
15
+ ],
16
+ "author": "Acadure Private Limited <contact@acadure.com>",
17
+ "repository": {
18
+ "type": "git",
19
+ "url": "git+https://github.com/acadure/acadure.git",
20
+ "directory": "agents/tes-exam-app/cli"
21
+ },
22
+ "engines": {
23
+ "node": ">=18"
24
+ }
25
+ }
26
+
package/README.md DELETED
@@ -1,3 +0,0 @@
1
- # Temporary Holding Version
2
-
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.