@tothalex/nulljs 0.0.48 → 0.0.53
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 +22 -32
- package/src/cli.ts +24 -0
- package/src/commands/config.ts +130 -0
- package/src/commands/deploy.ts +182 -123
- package/src/commands/dev.ts +10 -0
- package/src/commands/host.ts +130 -139
- package/src/commands/index.ts +6 -8
- package/src/commands/secret.ts +364 -56
- package/src/commands/status.ts +41 -0
- package/src/components/DeployAnimation.tsx +92 -0
- package/src/components/DeploymentLogsPane.tsx +79 -0
- package/src/components/Header.tsx +57 -0
- package/src/components/HelpModal.tsx +64 -0
- package/src/components/SystemLogsPane.tsx +78 -0
- package/src/config/index.ts +181 -0
- package/src/lib/bundle/function.ts +125 -0
- package/src/lib/bundle/index.ts +3 -0
- package/src/lib/bundle/react.ts +149 -0
- package/src/lib/deploy.ts +103 -0
- package/src/lib/server.ts +160 -0
- package/src/lib/vite.ts +120 -0
- package/src/lib/watcher.ts +274 -0
- package/src/ui.tsx +363 -0
- package/tsconfig.json +30 -0
- package/scripts/install-server.js +0 -199
- package/src/commands/api.ts +0 -16
- package/src/commands/auth.ts +0 -54
- package/src/commands/create.ts +0 -43
- package/src/commands/dev/function/index.ts +0 -221
- package/src/commands/dev/function/utils.ts +0 -99
- package/src/commands/dev/index.tsx +0 -126
- package/src/commands/dev/logging-manager.ts +0 -87
- package/src/commands/dev/server/index.ts +0 -48
- package/src/commands/dev/server/utils.ts +0 -37
- package/src/commands/dev/ui/components/scroll-area.tsx +0 -141
- package/src/commands/dev/ui/components/tab-bar.tsx +0 -67
- package/src/commands/dev/ui/index.tsx +0 -71
- package/src/commands/dev/ui/logging-context.tsx +0 -76
- package/src/commands/dev/ui/tabs/functions-tab.tsx +0 -35
- package/src/commands/dev/ui/tabs/server-tab.tsx +0 -36
- package/src/commands/dev/ui/tabs/vite-tab.tsx +0 -35
- package/src/commands/dev/ui/use-logging.tsx +0 -34
- package/src/commands/dev/vite/index.ts +0 -54
- package/src/commands/dev/vite/utils.ts +0 -71
- package/src/commands/profile.ts +0 -189
- package/src/index.ts +0 -346
- package/src/lib/api.ts +0 -189
- package/src/lib/bundle/function/index.ts +0 -46
- package/src/lib/bundle/react/index.ts +0 -2
- package/src/lib/bundle/react/spa.ts +0 -77
- package/src/lib/bundle/react/ssr/client.ts +0 -93
- package/src/lib/bundle/react/ssr/config.ts +0 -77
- package/src/lib/bundle/react/ssr/index.ts +0 -4
- package/src/lib/bundle/react/ssr/props.ts +0 -71
- package/src/lib/bundle/react/ssr/server.ts +0 -83
- package/src/lib/config.ts +0 -347
- package/src/lib/deployment.ts +0 -244
- package/src/lib/update-server.ts +0 -262
package/src/lib/update-server.ts
DELETED
|
@@ -1,262 +0,0 @@
|
|
|
1
|
-
import { existsSync, createWriteStream, chmodSync, unlinkSync, mkdirSync } from 'node:fs'
|
|
2
|
-
import { join, dirname } from 'node:path'
|
|
3
|
-
import { fileURLToPath } from 'node:url'
|
|
4
|
-
import https from 'node:https'
|
|
5
|
-
import * as tar from 'tar'
|
|
6
|
-
import chalk from 'chalk'
|
|
7
|
-
|
|
8
|
-
// --- Configuration ---
|
|
9
|
-
const S3_BASE_URL = 'https://nulljs.s3.eu-north-1.amazonaws.com'
|
|
10
|
-
const S3_PREFIX = 'releases/'
|
|
11
|
-
const DOWNLOAD_BASE_URL = `${S3_BASE_URL}/${S3_PREFIX}`
|
|
12
|
-
// ---------------------
|
|
13
|
-
|
|
14
|
-
interface PlatformInfo {
|
|
15
|
-
target: string
|
|
16
|
-
extension: string
|
|
17
|
-
binaryName: string
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
interface S3DownloadInfo {
|
|
21
|
-
downloadUrl: string
|
|
22
|
-
version: string
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
// --- Core Helper Functions (Unchanged) ---
|
|
26
|
-
|
|
27
|
-
function getPlatformInfo(): PlatformInfo {
|
|
28
|
-
const platform = process.platform
|
|
29
|
-
const arch = process.arch
|
|
30
|
-
|
|
31
|
-
const platformMap: Record<string, Record<string, string>> = {
|
|
32
|
-
linux: {
|
|
33
|
-
x64: 'x86_64-unknown-linux-gnu',
|
|
34
|
-
arm64: 'aarch64-unknown-linux-gnu'
|
|
35
|
-
},
|
|
36
|
-
darwin: {
|
|
37
|
-
x64: 'x86_64-apple-darwin',
|
|
38
|
-
arm64: 'aarch64-apple-darwin'
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
const target = platformMap[platform]?.[arch]
|
|
43
|
-
if (!target) {
|
|
44
|
-
throw new Error(`Unsupported platform: ${platform}-${arch}`)
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
const extension = '.tar.gz'
|
|
48
|
-
const binaryName = 'server'
|
|
49
|
-
|
|
50
|
-
return { target, extension, binaryName }
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
async function downloadFile(url: string, destination: string): Promise<void> {
|
|
54
|
-
return new Promise((resolve, reject) => {
|
|
55
|
-
const file = createWriteStream(destination)
|
|
56
|
-
|
|
57
|
-
https
|
|
58
|
-
.get(url, (response) => {
|
|
59
|
-
if (response.statusCode === 302 || response.statusCode === 301) {
|
|
60
|
-
// Handle redirect
|
|
61
|
-
return downloadFile(response.headers.location!, destination).then(resolve).catch(reject)
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
if (response.statusCode !== 200) {
|
|
65
|
-
reject(new Error(`Failed to download: ${response.statusCode}`))
|
|
66
|
-
return
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
response.pipe(file)
|
|
70
|
-
|
|
71
|
-
file.on('finish', () => {
|
|
72
|
-
file.close()
|
|
73
|
-
resolve()
|
|
74
|
-
})
|
|
75
|
-
|
|
76
|
-
file.on('error', reject)
|
|
77
|
-
})
|
|
78
|
-
.on('error', reject)
|
|
79
|
-
})
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
async function extractArchive(
|
|
83
|
-
archivePath: string,
|
|
84
|
-
extractPath: string,
|
|
85
|
-
binaryName: string
|
|
86
|
-
): Promise<void> {
|
|
87
|
-
// Extract tar.gz
|
|
88
|
-
await tar.x({
|
|
89
|
-
file: archivePath,
|
|
90
|
-
cwd: extractPath
|
|
91
|
-
})
|
|
92
|
-
|
|
93
|
-
// Make binary executable
|
|
94
|
-
const binaryPath = join(extractPath, binaryName)
|
|
95
|
-
chmodSync(binaryPath, '755')
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
function getServerBinPath(): string {
|
|
99
|
-
// Try to find the server binary relative to this module
|
|
100
|
-
const currentFile = fileURLToPath(import.meta.url)
|
|
101
|
-
const moduleRoot = join(dirname(currentFile), '../..')
|
|
102
|
-
return join(moduleRoot, 'bin', 'server')
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
// --- S3 LISTING Functions (New) ---
|
|
106
|
-
|
|
107
|
-
/**
|
|
108
|
-
* Fetches the raw XML listing from S3.
|
|
109
|
-
*/
|
|
110
|
-
async function fetchXml(url: string): Promise<string> {
|
|
111
|
-
return new Promise((resolve, reject) => {
|
|
112
|
-
https
|
|
113
|
-
.get(url, (res) => {
|
|
114
|
-
if (res.statusCode !== 200) {
|
|
115
|
-
// This likely indicates a 403 Access Denied error
|
|
116
|
-
reject(
|
|
117
|
-
new Error(`S3 Request Failed (${res.statusCode}): Check public 's3:ListBucket' policy.`)
|
|
118
|
-
)
|
|
119
|
-
return
|
|
120
|
-
}
|
|
121
|
-
let data = ''
|
|
122
|
-
res.on('data', (chunk) => (data += chunk))
|
|
123
|
-
res.on('end', () => resolve(data))
|
|
124
|
-
})
|
|
125
|
-
.on('error', reject)
|
|
126
|
-
})
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
/**
|
|
130
|
-
* Lists the S3 prefix, parses the XML, and determines the latest version tag.
|
|
131
|
-
*/
|
|
132
|
-
async function getLatestVersionFromS3(target: string, extension: string): Promise<S3DownloadInfo> {
|
|
133
|
-
// Query S3 for folders using delimiter and prefix
|
|
134
|
-
const listUrl = `${S3_BASE_URL}/?delimiter=/&prefix=${S3_PREFIX}`
|
|
135
|
-
const xmlData = await fetchXml(listUrl)
|
|
136
|
-
|
|
137
|
-
// Regex to find all CommonPrefixes entries (the version folders)
|
|
138
|
-
// Example: <Prefix>releases/v1.0.0/</Prefix>
|
|
139
|
-
const prefixRegex = /<Prefix>(releases\/v[^<]+)\/<\/Prefix>/g
|
|
140
|
-
const versionFolders: string[] = []
|
|
141
|
-
let match: RegExpExecArray | null
|
|
142
|
-
|
|
143
|
-
while ((match = prefixRegex.exec(xmlData)) !== null) {
|
|
144
|
-
// Extract version part: "releases/v1.0.0/" -> "v1.0.0"
|
|
145
|
-
const fullPrefix = match[1]
|
|
146
|
-
const version = fullPrefix.substring(S3_PREFIX.length)
|
|
147
|
-
versionFolders.push(version)
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
if (versionFolders.length === 0) {
|
|
151
|
-
throw new Error('No version folders found in S3 bucket. Has the CI/CD run?')
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
// Sort versions to find the latest (using semantic versioning logic)
|
|
155
|
-
const sortedVersions = versionFolders.sort((a, b) => {
|
|
156
|
-
// Strips 'v', splits by '.', and converts to number arrays for comparison
|
|
157
|
-
const aParts = a.replace('v', '').split('.').map(Number)
|
|
158
|
-
const bParts = b.replace('v', '').split('.').map(Number)
|
|
159
|
-
|
|
160
|
-
// Compare major, minor, and patch numbers (assuming vX.Y.Z)
|
|
161
|
-
for (let i = 0; i < 3; i++) {
|
|
162
|
-
if (aParts[i] > bParts[i]) return 1
|
|
163
|
-
if (aParts[i] < bParts[i]) return -1
|
|
164
|
-
}
|
|
165
|
-
return 0
|
|
166
|
-
})
|
|
167
|
-
|
|
168
|
-
// The latest version is the last one after sorting
|
|
169
|
-
const latestVersion = sortedVersions[sortedVersions.length - 1]
|
|
170
|
-
|
|
171
|
-
// Construct the full download URL
|
|
172
|
-
const downloadUrl = `${DOWNLOAD_BASE_URL}${latestVersion}/nulljs-server-${target}${extension}`
|
|
173
|
-
|
|
174
|
-
return { downloadUrl, version: latestVersion }
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
// --- Main Update Function (Modified) ---
|
|
178
|
-
|
|
179
|
-
export async function updateServer(): Promise<void> {
|
|
180
|
-
try {
|
|
181
|
-
console.log(chalk.blue('🔄 Updating nulljs server binary...'))
|
|
182
|
-
|
|
183
|
-
const { target, extension, binaryName } = getPlatformInfo()
|
|
184
|
-
|
|
185
|
-
const serverBinPath = getServerBinPath()
|
|
186
|
-
const binDir = dirname(serverBinPath)
|
|
187
|
-
const archivePath = join(binDir, `server${extension}`)
|
|
188
|
-
const backupPath = join(binDir, 'server.backup')
|
|
189
|
-
|
|
190
|
-
// Create bin directory if it doesn't exist
|
|
191
|
-
if (!existsSync(binDir)) {
|
|
192
|
-
mkdirSync(binDir, { recursive: true })
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
// Backup existing binary if it exists
|
|
196
|
-
if (existsSync(serverBinPath)) {
|
|
197
|
-
console.log(chalk.blue('💾 Backing up existing binary...'))
|
|
198
|
-
|
|
199
|
-
if (existsSync(backupPath)) {
|
|
200
|
-
unlinkSync(backupPath)
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
const fs = await import('node:fs/promises')
|
|
204
|
-
await fs.copyFile(serverBinPath, backupPath)
|
|
205
|
-
console.log(chalk.green('✅ Backup created'))
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
console.log(chalk.blue(`🔍 Searching for latest server version...`))
|
|
209
|
-
|
|
210
|
-
// 1. Get download URL and version from S3 listing (NEW LOGIC)
|
|
211
|
-
const { downloadUrl, version } = await getLatestVersionFromS3(target, extension)
|
|
212
|
-
console.log(chalk.blue(` Found latest version: ${version} for ${target}`))
|
|
213
|
-
console.log(chalk.blue(` Downloading from: ${downloadUrl}`))
|
|
214
|
-
|
|
215
|
-
try {
|
|
216
|
-
// Download the archive
|
|
217
|
-
await downloadFile(downloadUrl, archivePath)
|
|
218
|
-
console.log(chalk.green('✅ Download completed'))
|
|
219
|
-
|
|
220
|
-
// Remove existing binary before extracting new one
|
|
221
|
-
if (existsSync(serverBinPath)) {
|
|
222
|
-
unlinkSync(serverBinPath)
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
// Extract the binary
|
|
226
|
-
console.log(chalk.blue('📂 Extracting binary...'))
|
|
227
|
-
await extractArchive(archivePath, binDir, binaryName)
|
|
228
|
-
|
|
229
|
-
// Clean up archive
|
|
230
|
-
unlinkSync(archivePath)
|
|
231
|
-
|
|
232
|
-
// Remove backup since update was successful
|
|
233
|
-
if (existsSync(backupPath)) {
|
|
234
|
-
unlinkSync(backupPath)
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
console.log(chalk.green('✅ nulljs server updated successfully'))
|
|
238
|
-
} catch (error) {
|
|
239
|
-
// If update failed and we have a backup, restore it
|
|
240
|
-
if (existsSync(backupPath)) {
|
|
241
|
-
console.log(chalk.yellow('⚠️ Update failed, restoring backup...'))
|
|
242
|
-
|
|
243
|
-
if (existsSync(serverBinPath)) {
|
|
244
|
-
unlinkSync(serverBinPath)
|
|
245
|
-
}
|
|
246
|
-
|
|
247
|
-
const fs = await import('node:fs/promises')
|
|
248
|
-
await fs.copyFile(backupPath, serverBinPath)
|
|
249
|
-
unlinkSync(backupPath)
|
|
250
|
-
|
|
251
|
-
console.log(chalk.green('✅ Backup restored'))
|
|
252
|
-
}
|
|
253
|
-
|
|
254
|
-
throw error
|
|
255
|
-
}
|
|
256
|
-
} catch (error) {
|
|
257
|
-
// Ensure the error message is available if it's not a standard Error object
|
|
258
|
-
const errorMessage = error instanceof Error ? error.message : String(error)
|
|
259
|
-
console.error(chalk.red('❌ Failed to update server binary:'), errorMessage)
|
|
260
|
-
throw error
|
|
261
|
-
}
|
|
262
|
-
}
|