@tothalex/nulljs 0.0.47 → 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/commands/profile.ts
DELETED
|
@@ -1,189 +0,0 @@
|
|
|
1
|
-
import chalk from 'chalk'
|
|
2
|
-
import {
|
|
3
|
-
listProfiles,
|
|
4
|
-
getActiveProfile,
|
|
5
|
-
setActiveProfile,
|
|
6
|
-
loadProfile,
|
|
7
|
-
saveProfile,
|
|
8
|
-
deleteProfile,
|
|
9
|
-
profileExists,
|
|
10
|
-
loadConfigWithProfile
|
|
11
|
-
} from '../lib/config'
|
|
12
|
-
|
|
13
|
-
export const listProfilesCommand = () => {
|
|
14
|
-
const profiles = listProfiles()
|
|
15
|
-
const activeProfile = getActiveProfile()
|
|
16
|
-
|
|
17
|
-
if (profiles.length === 0) {
|
|
18
|
-
console.log(chalk.yellow('No profiles found.'))
|
|
19
|
-
console.log(chalk.gray('Create your first profile with: nulljs profile create <name>'))
|
|
20
|
-
return
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
console.log(chalk.bold('\nProfiles:'))
|
|
24
|
-
profiles.forEach((profile) => {
|
|
25
|
-
const isActive = profile === activeProfile
|
|
26
|
-
const marker = isActive ? chalk.green('●') : chalk.gray('○')
|
|
27
|
-
const name = isActive ? chalk.green(profile) : profile
|
|
28
|
-
const suffix = isActive ? chalk.green(' (active)') : ''
|
|
29
|
-
console.log(` ${marker} ${name}${suffix}`)
|
|
30
|
-
})
|
|
31
|
-
|
|
32
|
-
if (!activeProfile) {
|
|
33
|
-
console.log(
|
|
34
|
-
chalk.gray('\nNo active profile set. Switch to a profile with: nulljs profile use <name>')
|
|
35
|
-
)
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
export const createProfile = (name: string) => {
|
|
40
|
-
if (!name) {
|
|
41
|
-
console.error(chalk.red('✗'), 'Profile name is required')
|
|
42
|
-
process.exit(1)
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
if (profileExists(name)) {
|
|
46
|
-
console.error(chalk.red('✗'), `Profile '${name}' already exists`)
|
|
47
|
-
process.exit(1)
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
try {
|
|
51
|
-
const currentConfig = loadConfigWithProfile()
|
|
52
|
-
saveProfile(name, currentConfig)
|
|
53
|
-
console.log(chalk.green('✓'), `Profile '${chalk.blue(name)}' created`)
|
|
54
|
-
} catch (error) {
|
|
55
|
-
console.error(chalk.red('✗'), 'Failed to create profile:', error)
|
|
56
|
-
process.exit(1)
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
export const useProfile = (name: string) => {
|
|
61
|
-
if (!name) {
|
|
62
|
-
console.error(chalk.red('✗'), 'Profile name is required')
|
|
63
|
-
process.exit(1)
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
if (!profileExists(name)) {
|
|
67
|
-
console.error(chalk.red('✗'), `Profile '${name}' does not exist`)
|
|
68
|
-
process.exit(1)
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
try {
|
|
72
|
-
setActiveProfile(name)
|
|
73
|
-
console.log(chalk.green('✓'), `Switched to profile '${chalk.blue(name)}'`)
|
|
74
|
-
} catch (error) {
|
|
75
|
-
console.error(chalk.red('✗'), 'Failed to switch profile:', error)
|
|
76
|
-
process.exit(1)
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
export const showProfile = (name?: string) => {
|
|
81
|
-
const profileName = name || getActiveProfile()
|
|
82
|
-
|
|
83
|
-
if (!profileName) {
|
|
84
|
-
console.error(chalk.red('✗'), 'No active profile and no profile name provided')
|
|
85
|
-
process.exit(1)
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
if (!profileExists(profileName)) {
|
|
89
|
-
console.error(chalk.red('✗'), `Profile '${profileName}' does not exist`)
|
|
90
|
-
process.exit(1)
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
try {
|
|
94
|
-
const config = loadProfile(profileName)
|
|
95
|
-
const isActive = profileName === getActiveProfile()
|
|
96
|
-
|
|
97
|
-
console.log(chalk.bold(`\nProfile: ${profileName}`), isActive ? chalk.green('(active)') : '')
|
|
98
|
-
console.log(chalk.gray('─'.repeat(40)))
|
|
99
|
-
|
|
100
|
-
if (config.api) {
|
|
101
|
-
console.log(`${chalk.blue('API URL:')} ${config.api}`)
|
|
102
|
-
} else {
|
|
103
|
-
console.log(`${chalk.blue('API URL:')} ${chalk.gray('(not set)')}`)
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
if (config.key?.public) {
|
|
107
|
-
console.log(`${chalk.blue('Public Key:')} ${config.key.public.substring(0, 20)}...`)
|
|
108
|
-
} else {
|
|
109
|
-
console.log(`${chalk.blue('Public Key:')} ${chalk.gray('(not set)')}`)
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
if (config.key?.private) {
|
|
113
|
-
console.log(`${chalk.blue('Private Key:')} ${chalk.gray('(set)')}`)
|
|
114
|
-
} else {
|
|
115
|
-
console.log(`${chalk.blue('Private Key:')} ${chalk.gray('(not set)')}`)
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
if (config.dev) {
|
|
119
|
-
console.log(`${chalk.blue('Dev API Port:')} ${config.dev.apiPort || 3000}`)
|
|
120
|
-
console.log(`${chalk.blue('Dev Gateway Port:')} ${config.dev.gatewayPort || 3001}`)
|
|
121
|
-
}
|
|
122
|
-
} catch (error) {
|
|
123
|
-
console.error(chalk.red('✗'), 'Failed to load profile:', error)
|
|
124
|
-
process.exit(1)
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
export const removeProfile = (name: string) => {
|
|
129
|
-
if (!name) {
|
|
130
|
-
console.error(chalk.red('✗'), 'Profile name is required')
|
|
131
|
-
process.exit(1)
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
if (!profileExists(name)) {
|
|
135
|
-
console.error(chalk.red('✗'), `Profile '${name}' does not exist`)
|
|
136
|
-
process.exit(1)
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
const activeProfile = getActiveProfile()
|
|
140
|
-
if (activeProfile === name) {
|
|
141
|
-
console.log(chalk.yellow('⚠'), `Profile '${name}' is currently active`)
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
try {
|
|
145
|
-
const deleted = deleteProfile(name)
|
|
146
|
-
if (deleted) {
|
|
147
|
-
console.log(chalk.green('✓'), `Profile '${chalk.blue(name)}' removed`)
|
|
148
|
-
if (activeProfile === name) {
|
|
149
|
-
console.log(chalk.gray('Active profile cleared'))
|
|
150
|
-
}
|
|
151
|
-
} else {
|
|
152
|
-
console.error(chalk.red('✗'), `Failed to remove profile '${name}'`)
|
|
153
|
-
process.exit(1)
|
|
154
|
-
}
|
|
155
|
-
} catch (error) {
|
|
156
|
-
console.error(chalk.red('✗'), 'Failed to remove profile:', error)
|
|
157
|
-
process.exit(1)
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
export const copyProfile = (fromName: string, toName: string) => {
|
|
162
|
-
if (!fromName || !toName) {
|
|
163
|
-
console.error(chalk.red('✗'), 'Both source and destination profile names are required')
|
|
164
|
-
process.exit(1)
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
if (!profileExists(fromName)) {
|
|
168
|
-
console.error(chalk.red('✗'), `Source profile '${fromName}' does not exist`)
|
|
169
|
-
process.exit(1)
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
if (profileExists(toName)) {
|
|
173
|
-
console.error(chalk.red('✗'), `Destination profile '${toName}' already exists`)
|
|
174
|
-
process.exit(1)
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
try {
|
|
178
|
-
const sourceConfig = loadProfile(fromName)
|
|
179
|
-
saveProfile(toName, sourceConfig)
|
|
180
|
-
console.log(
|
|
181
|
-
chalk.green('✓'),
|
|
182
|
-
`Profile '${chalk.blue(fromName)}' copied to '${chalk.blue(toName)}'`
|
|
183
|
-
)
|
|
184
|
-
} catch (error) {
|
|
185
|
-
console.error(chalk.red('✗'), 'Failed to copy profile:', error)
|
|
186
|
-
process.exit(1)
|
|
187
|
-
}
|
|
188
|
-
}
|
|
189
|
-
|
package/src/index.ts
DELETED
|
@@ -1,346 +0,0 @@
|
|
|
1
|
-
#! /usr/bin/env bun
|
|
2
|
-
|
|
3
|
-
import yargs from 'yargs'
|
|
4
|
-
import { hideBin } from 'yargs/helpers'
|
|
5
|
-
|
|
6
|
-
import {
|
|
7
|
-
deploy,
|
|
8
|
-
auth,
|
|
9
|
-
createSecret,
|
|
10
|
-
listSecretKeys,
|
|
11
|
-
setApiUrl,
|
|
12
|
-
create,
|
|
13
|
-
createSecretsFromFile,
|
|
14
|
-
dev,
|
|
15
|
-
host,
|
|
16
|
-
unhost,
|
|
17
|
-
listProfilesCommand,
|
|
18
|
-
createProfile,
|
|
19
|
-
useProfile,
|
|
20
|
-
showProfile,
|
|
21
|
-
removeProfile,
|
|
22
|
-
copyProfile
|
|
23
|
-
} from './commands'
|
|
24
|
-
import chalk from 'chalk'
|
|
25
|
-
import { getActiveProfile, listProfiles, profileExists, loadProfile } from './lib/config'
|
|
26
|
-
|
|
27
|
-
const showWelcome = () => {
|
|
28
|
-
console.log(chalk.bold.blue('\n🚀 NullJS CLI'))
|
|
29
|
-
console.log(chalk.gray('─'.repeat(40)))
|
|
30
|
-
|
|
31
|
-
// Show current profile
|
|
32
|
-
const activeProfile = getActiveProfile()
|
|
33
|
-
if (activeProfile && profileExists(activeProfile)) {
|
|
34
|
-
const config = loadProfile(activeProfile)
|
|
35
|
-
console.log(chalk.bold(`\n📋 Current Profile: ${chalk.green(activeProfile)}`))
|
|
36
|
-
|
|
37
|
-
if (config.api) {
|
|
38
|
-
console.log(` ${chalk.blue('API URL:')} ${config.api}`)
|
|
39
|
-
} else {
|
|
40
|
-
console.log(` ${chalk.blue('API URL:')} ${chalk.red('(not configured)')}`)
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
if (config.key?.public && config.key?.private) {
|
|
44
|
-
console.log(` ${chalk.blue('Authentication:')} ${chalk.green('✓ configured')}`)
|
|
45
|
-
} else {
|
|
46
|
-
console.log(` ${chalk.blue('Authentication:')} ${chalk.red('✗ not configured')}`)
|
|
47
|
-
}
|
|
48
|
-
} else {
|
|
49
|
-
console.log(chalk.yellow('\n⚠️ No active profile selected'))
|
|
50
|
-
const profiles = listProfiles()
|
|
51
|
-
if (profiles.length > 0) {
|
|
52
|
-
console.log(chalk.gray(' Available profiles:'))
|
|
53
|
-
profiles.forEach((profile) => console.log(chalk.gray(` - ${profile}`)))
|
|
54
|
-
console.log(chalk.gray(' Switch to a profile: nulljs profile use <name>'))
|
|
55
|
-
} else {
|
|
56
|
-
console.log(chalk.gray(' Create your first profile: nulljs profile create <name>'))
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
// Show available commands
|
|
61
|
-
console.log(chalk.bold('\n📚 Available Commands:'))
|
|
62
|
-
console.log(chalk.blue(' nulljs create <name>') + chalk.gray(' Create a new project'))
|
|
63
|
-
console.log(chalk.blue(' nulljs deploy [path]') + chalk.gray(' Deploy your project'))
|
|
64
|
-
console.log(chalk.blue(' nulljs dev [path]') + chalk.gray(' Start development mode'))
|
|
65
|
-
console.log(
|
|
66
|
-
chalk.blue(' nulljs auth') + chalk.gray(' Generate authentication keys')
|
|
67
|
-
)
|
|
68
|
-
console.log(chalk.blue(' nulljs config set-api <url>') + chalk.gray(' Set API URL'))
|
|
69
|
-
console.log(chalk.blue(' nulljs secret <action>') + chalk.gray(' Manage secrets'))
|
|
70
|
-
console.log(chalk.blue(' nulljs profile <action>') + chalk.gray(' Manage profiles'))
|
|
71
|
-
console.log(
|
|
72
|
-
chalk.blue(' nulljs host [cloud-path]') + chalk.gray(' Set up production hosting')
|
|
73
|
-
)
|
|
74
|
-
console.log(
|
|
75
|
-
chalk.blue(' nulljs host --update') + chalk.gray(' Update server binary and restart service')
|
|
76
|
-
)
|
|
77
|
-
console.log(chalk.blue(' nulljs unhost') + chalk.gray(' Remove production hosting'))
|
|
78
|
-
|
|
79
|
-
console.log(chalk.gray('\n💡 Quick Start:'))
|
|
80
|
-
if (!activeProfile) {
|
|
81
|
-
console.log(chalk.gray(' 1. nulljs profile create my-profile'))
|
|
82
|
-
console.log(chalk.gray(' 2. nulljs auth'))
|
|
83
|
-
console.log(chalk.gray(' 3. nulljs config set-api <your-api-url>'))
|
|
84
|
-
console.log(chalk.gray(' 4. nulljs create my-project'))
|
|
85
|
-
} else {
|
|
86
|
-
console.log(chalk.gray(' • nulljs create my-project (create a new project)'))
|
|
87
|
-
console.log(chalk.gray(' • nulljs dev (start development)'))
|
|
88
|
-
console.log(chalk.gray(' • nulljs deploy (deploy to production)'))
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
console.log(chalk.gray('\n Run "nulljs --help" for detailed usage\n'))
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
const parser = yargs(hideBin(process.argv))
|
|
95
|
-
.scriptName('nulljs')
|
|
96
|
-
.usage('Usage: $0 <command> [options]')
|
|
97
|
-
.command(
|
|
98
|
-
'create <name>',
|
|
99
|
-
'Create a nulljs project with <name>',
|
|
100
|
-
(yargs) =>
|
|
101
|
-
yargs.positional('name', {
|
|
102
|
-
description: 'Project name',
|
|
103
|
-
type: 'string',
|
|
104
|
-
demandOption: true
|
|
105
|
-
}),
|
|
106
|
-
(argv) => create(argv.name)
|
|
107
|
-
)
|
|
108
|
-
.command(
|
|
109
|
-
'deploy [path]',
|
|
110
|
-
'Deploy a project to the platform',
|
|
111
|
-
(yargs) =>
|
|
112
|
-
yargs.positional('path', {
|
|
113
|
-
description:
|
|
114
|
-
'Path to the project directory or file (optional, defaults to current directory)',
|
|
115
|
-
type: 'string',
|
|
116
|
-
demandOption: false
|
|
117
|
-
}),
|
|
118
|
-
(argv) => deploy(argv.path)
|
|
119
|
-
)
|
|
120
|
-
.command(
|
|
121
|
-
'dev [path]',
|
|
122
|
-
'Start dev mode with Vite server and function watching',
|
|
123
|
-
(yargs) =>
|
|
124
|
-
yargs.positional('path', {
|
|
125
|
-
description: 'Path to the src directory (defaults to ./src)',
|
|
126
|
-
type: 'string',
|
|
127
|
-
default: './src'
|
|
128
|
-
}),
|
|
129
|
-
(argv) => dev(argv.path)
|
|
130
|
-
)
|
|
131
|
-
.command(
|
|
132
|
-
'host [cloud-path]',
|
|
133
|
-
'Set up production hosting with systemd service (Linux only)',
|
|
134
|
-
(yargs) =>
|
|
135
|
-
yargs
|
|
136
|
-
.positional('cloud-path', {
|
|
137
|
-
description: 'Path to cloud data directory (defaults to ~/.nulljs)',
|
|
138
|
-
type: 'string',
|
|
139
|
-
demandOption: false
|
|
140
|
-
})
|
|
141
|
-
.option('update', {
|
|
142
|
-
description: 'Update the server binary to the latest version and restart the service',
|
|
143
|
-
type: 'boolean',
|
|
144
|
-
default: false
|
|
145
|
-
}),
|
|
146
|
-
(argv) => host(argv['cloud-path'], { update: argv.update })
|
|
147
|
-
)
|
|
148
|
-
.command(
|
|
149
|
-
'unhost',
|
|
150
|
-
'Remove production hosting setup (Linux only)',
|
|
151
|
-
(yargs) =>
|
|
152
|
-
yargs.option('keep-data', {
|
|
153
|
-
description: 'Keep the cloud data directory',
|
|
154
|
-
type: 'boolean',
|
|
155
|
-
default: false
|
|
156
|
-
}),
|
|
157
|
-
(argv) => unhost({ keepData: argv['keep-data'] })
|
|
158
|
-
)
|
|
159
|
-
.command(
|
|
160
|
-
'auth',
|
|
161
|
-
'Generate or regenerate authentication keys',
|
|
162
|
-
(yargs) =>
|
|
163
|
-
yargs.option('profile', {
|
|
164
|
-
description: 'Save keys to a specific profile',
|
|
165
|
-
type: 'string',
|
|
166
|
-
demandOption: false
|
|
167
|
-
}),
|
|
168
|
-
(argv) => auth(argv.profile)
|
|
169
|
-
)
|
|
170
|
-
.command(
|
|
171
|
-
'config',
|
|
172
|
-
'Configuration management',
|
|
173
|
-
(yargs) =>
|
|
174
|
-
yargs
|
|
175
|
-
.command(
|
|
176
|
-
'set-api <url>',
|
|
177
|
-
'Set the API URL for the platform',
|
|
178
|
-
(yargs) =>
|
|
179
|
-
yargs
|
|
180
|
-
.positional('url', {
|
|
181
|
-
description: 'API URL to save in configuration',
|
|
182
|
-
type: 'string',
|
|
183
|
-
demandOption: true
|
|
184
|
-
})
|
|
185
|
-
.option('profile', {
|
|
186
|
-
description: 'Save to a specific profile',
|
|
187
|
-
type: 'string',
|
|
188
|
-
demandOption: false
|
|
189
|
-
}),
|
|
190
|
-
(argv) => setApiUrl(argv.url, argv.profile)
|
|
191
|
-
)
|
|
192
|
-
.demandCommand(1, 'You need to specify a config action'),
|
|
193
|
-
() => {}
|
|
194
|
-
)
|
|
195
|
-
.command(
|
|
196
|
-
'secret <action>',
|
|
197
|
-
'Secret management operations',
|
|
198
|
-
(yargs) =>
|
|
199
|
-
yargs
|
|
200
|
-
.command(
|
|
201
|
-
'create',
|
|
202
|
-
'Create a new secret',
|
|
203
|
-
(yargs) =>
|
|
204
|
-
yargs
|
|
205
|
-
.option('key', {
|
|
206
|
-
description: 'Key name for the secret',
|
|
207
|
-
type: 'string',
|
|
208
|
-
demandOption: false
|
|
209
|
-
})
|
|
210
|
-
.option('value', {
|
|
211
|
-
description: 'Value for the secret',
|
|
212
|
-
type: 'string',
|
|
213
|
-
demandOption: false
|
|
214
|
-
})
|
|
215
|
-
.option('file', {
|
|
216
|
-
description: 'Path to file containing the secret value',
|
|
217
|
-
type: 'string',
|
|
218
|
-
demandOption: false
|
|
219
|
-
})
|
|
220
|
-
.check((argv) => {
|
|
221
|
-
// Either file is provided OR both key and value are provided
|
|
222
|
-
if (argv.file && (argv.key || argv.value)) {
|
|
223
|
-
throw new Error('Cannot use --file with --key or --value options')
|
|
224
|
-
}
|
|
225
|
-
if (!argv.file && (!argv.key || !argv.value)) {
|
|
226
|
-
throw new Error('Must provide either --file OR both --key and --value')
|
|
227
|
-
}
|
|
228
|
-
return true
|
|
229
|
-
}),
|
|
230
|
-
(argv) => {
|
|
231
|
-
if (argv.file) {
|
|
232
|
-
createSecretsFromFile({
|
|
233
|
-
filePath: argv.file
|
|
234
|
-
})
|
|
235
|
-
} else {
|
|
236
|
-
createSecret({ key: argv.key!, value: argv.value! })
|
|
237
|
-
}
|
|
238
|
-
}
|
|
239
|
-
)
|
|
240
|
-
.command('list', 'List all available secret keys', {}, () => listSecretKeys())
|
|
241
|
-
.demandCommand(1, 'You need to specify a secret action'),
|
|
242
|
-
() => {}
|
|
243
|
-
)
|
|
244
|
-
.command(
|
|
245
|
-
'profile <action>',
|
|
246
|
-
'Profile management operations',
|
|
247
|
-
(yargs) =>
|
|
248
|
-
yargs
|
|
249
|
-
.command('list', 'List all available profiles', {}, () => listProfilesCommand())
|
|
250
|
-
.command(
|
|
251
|
-
'create <name>',
|
|
252
|
-
'Create a new profile',
|
|
253
|
-
(yargs) =>
|
|
254
|
-
yargs.positional('name', {
|
|
255
|
-
description: 'Profile name',
|
|
256
|
-
type: 'string',
|
|
257
|
-
demandOption: true
|
|
258
|
-
}),
|
|
259
|
-
(argv) => createProfile(argv.name)
|
|
260
|
-
)
|
|
261
|
-
.command(
|
|
262
|
-
'use <name>',
|
|
263
|
-
'Switch to a profile',
|
|
264
|
-
(yargs) =>
|
|
265
|
-
yargs.positional('name', {
|
|
266
|
-
description: 'Profile name to switch to',
|
|
267
|
-
type: 'string',
|
|
268
|
-
demandOption: true
|
|
269
|
-
}),
|
|
270
|
-
(argv) => useProfile(argv.name)
|
|
271
|
-
)
|
|
272
|
-
.command(
|
|
273
|
-
'show [name]',
|
|
274
|
-
'Show profile configuration',
|
|
275
|
-
(yargs) =>
|
|
276
|
-
yargs.positional('name', {
|
|
277
|
-
description: 'Profile name (defaults to active profile)',
|
|
278
|
-
type: 'string',
|
|
279
|
-
demandOption: false
|
|
280
|
-
}),
|
|
281
|
-
(argv) => showProfile(argv.name)
|
|
282
|
-
)
|
|
283
|
-
.command(
|
|
284
|
-
'remove <name>',
|
|
285
|
-
'Remove a profile',
|
|
286
|
-
(yargs) =>
|
|
287
|
-
yargs.positional('name', {
|
|
288
|
-
description: 'Profile name to remove',
|
|
289
|
-
type: 'string',
|
|
290
|
-
demandOption: true
|
|
291
|
-
}),
|
|
292
|
-
(argv) => removeProfile(argv.name)
|
|
293
|
-
)
|
|
294
|
-
.command(
|
|
295
|
-
'copy <from> <to>',
|
|
296
|
-
'Copy a profile to a new profile',
|
|
297
|
-
(yargs) =>
|
|
298
|
-
yargs
|
|
299
|
-
.positional('from', {
|
|
300
|
-
description: 'Source profile name',
|
|
301
|
-
type: 'string',
|
|
302
|
-
demandOption: true
|
|
303
|
-
})
|
|
304
|
-
.positional('to', {
|
|
305
|
-
description: 'Destination profile name',
|
|
306
|
-
type: 'string',
|
|
307
|
-
demandOption: true
|
|
308
|
-
}),
|
|
309
|
-
(argv) => copyProfile(argv.from, argv.to)
|
|
310
|
-
)
|
|
311
|
-
.demandCommand(1, 'You need to specify a profile action'),
|
|
312
|
-
() => {}
|
|
313
|
-
)
|
|
314
|
-
.help('h')
|
|
315
|
-
.alias('h', 'help')
|
|
316
|
-
.version('0.0.3')
|
|
317
|
-
.alias('v', 'version')
|
|
318
|
-
.example('$0 create my-project', 'Create project called my-project')
|
|
319
|
-
.example('$0 deploy ./my-project', 'Deploy a project from the current directory')
|
|
320
|
-
.example('$0 dev', 'Start dev mode for current project (./src)')
|
|
321
|
-
.example('$0 dev ./src', 'Start dev mode for specific src directory')
|
|
322
|
-
.example('$0 host', 'Set up production hosting with default cloud path (~/.nulljs)')
|
|
323
|
-
.example('$0 host /var/nulljs', 'Set up production hosting with custom cloud path')
|
|
324
|
-
.example('$0 host --update', 'Update server binary to latest version and restart service')
|
|
325
|
-
.example('$0 unhost', 'Remove production hosting (removes service and data)')
|
|
326
|
-
.example('$0 unhost --keep-data', 'Remove hosting but keep cloud data')
|
|
327
|
-
.example('$0 auth', 'Generate authentication keys')
|
|
328
|
-
.example('$0 config set-api https://api.example.com', 'Set the API URL')
|
|
329
|
-
.example('$0 secret create --key MY_KEY --value "secret value"', 'Create a new secret')
|
|
330
|
-
.example('$0 secret create --file secrets.json', 'Create secrets from a file')
|
|
331
|
-
.example('$0 profile list', 'List all available profiles')
|
|
332
|
-
.example('$0 profile create development', 'Create a new profile called development')
|
|
333
|
-
.example('$0 profile use production', 'Switch to the production profile')
|
|
334
|
-
.example('$0 profile show', 'Show the current active profile configuration')
|
|
335
|
-
.example('$0 profile copy development staging', 'Copy development profile to staging')
|
|
336
|
-
.epilogue('For more information, visit: https://your-docs-url.com')
|
|
337
|
-
|
|
338
|
-
// Parse arguments and show welcome screen if no command is provided
|
|
339
|
-
async function main() {
|
|
340
|
-
const argv = await parser.parse()
|
|
341
|
-
if (argv._.length === 0) {
|
|
342
|
-
showWelcome()
|
|
343
|
-
}
|
|
344
|
-
}
|
|
345
|
-
|
|
346
|
-
main().catch(console.error)
|