@fold-run/cli 0.1.3 → 0.2.0
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/dist/commands/completions.d.ts +1 -0
- package/dist/commands/completions.js +195 -0
- package/dist/commands/completions.js.map +1 -0
- package/dist/commands/config.d.ts +4 -0
- package/dist/commands/config.js +75 -0
- package/dist/commands/config.js.map +1 -0
- package/dist/commands/deploy.d.ts +1 -0
- package/dist/commands/deploy.js +35 -2
- package/dist/commands/deploy.js.map +1 -1
- package/dist/commands/dev.d.ts +1 -0
- package/dist/commands/dev.js +41 -21
- package/dist/commands/dev.js.map +1 -1
- package/dist/commands/doctor.d.ts +1 -0
- package/dist/commands/doctor.js +138 -0
- package/dist/commands/doctor.js.map +1 -0
- package/dist/commands/domains.d.ts +11 -0
- package/dist/commands/domains.js +111 -0
- package/dist/commands/domains.js.map +1 -0
- package/dist/commands/init.d.ts +1 -0
- package/dist/commands/init.js +104 -6
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/invoke.d.ts +9 -0
- package/dist/commands/invoke.js +89 -0
- package/dist/commands/invoke.js.map +1 -0
- package/dist/commands/link.d.ts +4 -0
- package/dist/commands/link.js +77 -0
- package/dist/commands/link.js.map +1 -0
- package/dist/commands/logs.js +31 -1
- package/dist/commands/logs.js.map +1 -1
- package/dist/commands/whoami.d.ts +1 -0
- package/dist/commands/whoami.js +39 -0
- package/dist/commands/whoami.js.map +1 -0
- package/dist/index.js +72 -29
- package/dist/index.js.map +1 -1
- package/dist/lib/api.d.ts +1 -0
- package/dist/lib/api.js +30 -0
- package/dist/lib/api.js.map +1 -1
- package/dist/lib/bundler.js +124 -18
- package/dist/lib/bundler.js.map +1 -1
- package/dist/lib/colorize.d.ts +5 -0
- package/dist/lib/colorize.js +28 -0
- package/dist/lib/colorize.js.map +1 -0
- package/dist/lib/prompt.d.ts +22 -0
- package/dist/lib/prompt.js +146 -0
- package/dist/lib/prompt.js.map +1 -1
- package/package.json +10 -11
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function completionsCommand(shell: string): void;
|
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
const BASH_COMPLETIONS = `# fold CLI bash completions
|
|
2
|
+
# Add to ~/.bashrc: eval "$(fold completions bash)"
|
|
3
|
+
|
|
4
|
+
_fold_completions() {
|
|
5
|
+
local cur prev commands subcommands
|
|
6
|
+
cur="\${COMP_WORDS[COMP_CWORD]}"
|
|
7
|
+
prev="\${COMP_WORDS[COMP_CWORD-1]}"
|
|
8
|
+
|
|
9
|
+
commands="init login logout whoami status doctor deploy invoke dev functions delete rollback open tail logs secrets env webhooks schedules create-tool tools templates tenant config completions"
|
|
10
|
+
|
|
11
|
+
case "\${prev}" in
|
|
12
|
+
fold)
|
|
13
|
+
COMPREPLY=( $(compgen -W "\${commands}" -- "\${cur}") )
|
|
14
|
+
return 0
|
|
15
|
+
;;
|
|
16
|
+
secrets)
|
|
17
|
+
COMPREPLY=( $(compgen -W "set list delete" -- "\${cur}") )
|
|
18
|
+
return 0
|
|
19
|
+
;;
|
|
20
|
+
env)
|
|
21
|
+
COMPREPLY=( $(compgen -W "set list delete" -- "\${cur}") )
|
|
22
|
+
return 0
|
|
23
|
+
;;
|
|
24
|
+
webhooks)
|
|
25
|
+
COMPREPLY=( $(compgen -W "list create delete" -- "\${cur}") )
|
|
26
|
+
return 0
|
|
27
|
+
;;
|
|
28
|
+
schedules)
|
|
29
|
+
COMPREPLY=( $(compgen -W "list create toggle delete" -- "\${cur}") )
|
|
30
|
+
return 0
|
|
31
|
+
;;
|
|
32
|
+
tools)
|
|
33
|
+
COMPREPLY=( $(compgen -W "list" -- "\${cur}") )
|
|
34
|
+
return 0
|
|
35
|
+
;;
|
|
36
|
+
templates)
|
|
37
|
+
COMPREPLY=( $(compgen -W "list get deploy" -- "\${cur}") )
|
|
38
|
+
return 0
|
|
39
|
+
;;
|
|
40
|
+
tenant)
|
|
41
|
+
COMPREPLY=( $(compgen -W "set get list clear" -- "\${cur}") )
|
|
42
|
+
return 0
|
|
43
|
+
;;
|
|
44
|
+
config)
|
|
45
|
+
COMPREPLY=( $(compgen -W "get set list path" -- "\${cur}") )
|
|
46
|
+
return 0
|
|
47
|
+
;;
|
|
48
|
+
completions)
|
|
49
|
+
COMPREPLY=( $(compgen -W "bash zsh fish" -- "\${cur}") )
|
|
50
|
+
return 0
|
|
51
|
+
;;
|
|
52
|
+
deploy)
|
|
53
|
+
COMPREPLY=( $(compgen -f -X '!*.@(ts|tsx|js|mjs)' -- "\${cur}") )
|
|
54
|
+
return 0
|
|
55
|
+
;;
|
|
56
|
+
dev)
|
|
57
|
+
COMPREPLY=( $(compgen -f -X '!*.@(ts|tsx|js|mjs)' -- "\${cur}") )
|
|
58
|
+
return 0
|
|
59
|
+
;;
|
|
60
|
+
esac
|
|
61
|
+
|
|
62
|
+
# Default: show flags
|
|
63
|
+
if [[ "\${cur}" == -* ]]; then
|
|
64
|
+
COMPREPLY=( $(compgen -W "--json --help --version" -- "\${cur}") )
|
|
65
|
+
fi
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
complete -F _fold_completions fold`;
|
|
69
|
+
const ZSH_COMPLETIONS = `#compdef fold
|
|
70
|
+
# fold CLI zsh completions
|
|
71
|
+
# Add to ~/.zshrc: eval "$(fold completions zsh)"
|
|
72
|
+
|
|
73
|
+
_fold() {
|
|
74
|
+
local -a commands subcommands
|
|
75
|
+
|
|
76
|
+
commands=(
|
|
77
|
+
'init:Scaffold a new fold project'
|
|
78
|
+
'login:Authenticate with the fold.run API'
|
|
79
|
+
'logout:Remove saved credentials'
|
|
80
|
+
'whoami:Show current login info'
|
|
81
|
+
'status:Show current config and deployed functions'
|
|
82
|
+
'doctor:Diagnose common issues'
|
|
83
|
+
'deploy:Deploy a function'
|
|
84
|
+
'invoke:Invoke a deployed function directly'
|
|
85
|
+
'dev:Start a local dev server with auto-reload'
|
|
86
|
+
'functions:List deployed functions'
|
|
87
|
+
'delete:Delete a deployed function'
|
|
88
|
+
'rollback:Rollback a function to a previous version'
|
|
89
|
+
'open:Open a function URL in the browser'
|
|
90
|
+
'tail:Stream activations in real-time via SSE'
|
|
91
|
+
'logs:View activation logs'
|
|
92
|
+
'secrets:Manage tenant secrets'
|
|
93
|
+
'env:Manage function environment variables'
|
|
94
|
+
'webhooks:Manage webhook ingress endpoints'
|
|
95
|
+
'schedules:Manage scheduled triggers'
|
|
96
|
+
'create-tool:Generate and deploy an MCP tool'
|
|
97
|
+
'tools:Manage deployed MCP tools'
|
|
98
|
+
'templates:Browse and deploy from template marketplace'
|
|
99
|
+
'tenant:Manage default tenant'
|
|
100
|
+
'config:View and update CLI configuration'
|
|
101
|
+
'completions:Generate shell completions'
|
|
102
|
+
)
|
|
103
|
+
|
|
104
|
+
_arguments -C \\
|
|
105
|
+
'--json[Output results as JSON]' \\
|
|
106
|
+
'--help[Show help]' \\
|
|
107
|
+
'--version[Show version]' \\
|
|
108
|
+
'1:command:->command' \\
|
|
109
|
+
'*::args:->args'
|
|
110
|
+
|
|
111
|
+
case $state in
|
|
112
|
+
command)
|
|
113
|
+
_describe 'command' commands
|
|
114
|
+
;;
|
|
115
|
+
args)
|
|
116
|
+
case $words[1] in
|
|
117
|
+
secrets) _describe 'subcommand' '(set list delete)' ;;
|
|
118
|
+
env) _describe 'subcommand' '(set list delete)' ;;
|
|
119
|
+
webhooks) _describe 'subcommand' '(list create delete)' ;;
|
|
120
|
+
schedules) _describe 'subcommand' '(list create toggle delete)' ;;
|
|
121
|
+
tools) _describe 'subcommand' '(list)' ;;
|
|
122
|
+
templates) _describe 'subcommand' '(list get deploy)' ;;
|
|
123
|
+
tenant) _describe 'subcommand' '(set get list clear)' ;;
|
|
124
|
+
config) _describe 'subcommand' '(get set list path)' ;;
|
|
125
|
+
completions) _describe 'shell' '(bash zsh fish)' ;;
|
|
126
|
+
deploy|dev) _files -g '*.{ts,tsx,js,mjs}' ;;
|
|
127
|
+
esac
|
|
128
|
+
;;
|
|
129
|
+
esac
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
_fold`;
|
|
133
|
+
const FISH_COMPLETIONS = `# fold CLI fish completions
|
|
134
|
+
# Add to ~/.config/fish/completions/fold.fish or run:
|
|
135
|
+
# fold completions fish > ~/.config/fish/completions/fold.fish
|
|
136
|
+
|
|
137
|
+
# Disable file completions by default
|
|
138
|
+
complete -c fold -f
|
|
139
|
+
|
|
140
|
+
# Top-level commands
|
|
141
|
+
complete -c fold -n '__fish_use_subcommand' -a init -d 'Scaffold a new fold project'
|
|
142
|
+
complete -c fold -n '__fish_use_subcommand' -a login -d 'Authenticate with the fold.run API'
|
|
143
|
+
complete -c fold -n '__fish_use_subcommand' -a logout -d 'Remove saved credentials'
|
|
144
|
+
complete -c fold -n '__fish_use_subcommand' -a whoami -d 'Show current login info'
|
|
145
|
+
complete -c fold -n '__fish_use_subcommand' -a status -d 'Show current config and deployed functions'
|
|
146
|
+
complete -c fold -n '__fish_use_subcommand' -a doctor -d 'Diagnose common issues'
|
|
147
|
+
complete -c fold -n '__fish_use_subcommand' -a deploy -d 'Deploy a function'
|
|
148
|
+
complete -c fold -n '__fish_use_subcommand' -a invoke -d 'Invoke a deployed function directly'
|
|
149
|
+
complete -c fold -n '__fish_use_subcommand' -a dev -d 'Start a local dev server'
|
|
150
|
+
complete -c fold -n '__fish_use_subcommand' -a functions -d 'List deployed functions'
|
|
151
|
+
complete -c fold -n '__fish_use_subcommand' -a delete -d 'Delete a deployed function'
|
|
152
|
+
complete -c fold -n '__fish_use_subcommand' -a rollback -d 'Rollback to a previous version'
|
|
153
|
+
complete -c fold -n '__fish_use_subcommand' -a open -d 'Open function URL in browser'
|
|
154
|
+
complete -c fold -n '__fish_use_subcommand' -a tail -d 'Stream activations via SSE'
|
|
155
|
+
complete -c fold -n '__fish_use_subcommand' -a logs -d 'View activation logs'
|
|
156
|
+
complete -c fold -n '__fish_use_subcommand' -a secrets -d 'Manage tenant secrets'
|
|
157
|
+
complete -c fold -n '__fish_use_subcommand' -a env -d 'Manage function env vars'
|
|
158
|
+
complete -c fold -n '__fish_use_subcommand' -a webhooks -d 'Manage webhook endpoints'
|
|
159
|
+
complete -c fold -n '__fish_use_subcommand' -a schedules -d 'Manage scheduled triggers'
|
|
160
|
+
complete -c fold -n '__fish_use_subcommand' -a create-tool -d 'Generate and deploy an MCP tool'
|
|
161
|
+
complete -c fold -n '__fish_use_subcommand' -a tools -d 'Manage deployed MCP tools'
|
|
162
|
+
complete -c fold -n '__fish_use_subcommand' -a templates -d 'Browse templates'
|
|
163
|
+
complete -c fold -n '__fish_use_subcommand' -a tenant -d 'Manage default tenant'
|
|
164
|
+
complete -c fold -n '__fish_use_subcommand' -a config -d 'View and update CLI configuration'
|
|
165
|
+
complete -c fold -n '__fish_use_subcommand' -a completions -d 'Generate shell completions'
|
|
166
|
+
|
|
167
|
+
# Subcommands
|
|
168
|
+
complete -c fold -n '__fish_seen_subcommand_from secrets' -a 'set list delete'
|
|
169
|
+
complete -c fold -n '__fish_seen_subcommand_from env' -a 'set list delete'
|
|
170
|
+
complete -c fold -n '__fish_seen_subcommand_from webhooks' -a 'list create delete'
|
|
171
|
+
complete -c fold -n '__fish_seen_subcommand_from schedules' -a 'list create toggle delete'
|
|
172
|
+
complete -c fold -n '__fish_seen_subcommand_from tools' -a list
|
|
173
|
+
complete -c fold -n '__fish_seen_subcommand_from templates' -a 'list get deploy'
|
|
174
|
+
complete -c fold -n '__fish_seen_subcommand_from tenant' -a 'set get list clear'
|
|
175
|
+
complete -c fold -n '__fish_seen_subcommand_from config' -a 'get set list path'
|
|
176
|
+
complete -c fold -n '__fish_seen_subcommand_from completions' -a 'bash zsh fish'
|
|
177
|
+
|
|
178
|
+
# Global flags
|
|
179
|
+
complete -c fold -l json -d 'Output results as JSON'
|
|
180
|
+
complete -c fold -l help -d 'Show help'
|
|
181
|
+
complete -c fold -l version -d 'Show version'`;
|
|
182
|
+
const SHELLS = {
|
|
183
|
+
bash: BASH_COMPLETIONS,
|
|
184
|
+
zsh: ZSH_COMPLETIONS,
|
|
185
|
+
fish: FISH_COMPLETIONS,
|
|
186
|
+
};
|
|
187
|
+
export function completionsCommand(shell) {
|
|
188
|
+
const script = SHELLS[shell];
|
|
189
|
+
if (!script) {
|
|
190
|
+
console.error(`Unknown shell: "${shell}". Supported: bash, zsh, fish`);
|
|
191
|
+
process.exit(1);
|
|
192
|
+
}
|
|
193
|
+
console.log(script);
|
|
194
|
+
}
|
|
195
|
+
//# sourceMappingURL=completions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"completions.js","sourceRoot":"","sources":["../../src/commands/completions.ts"],"names":[],"mappings":"AAAA,MAAM,gBAAgB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;mCAmEU,CAAC;AAEpC,MAAM,eAAe,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;MA+DlB,CAAC;AAEP,MAAM,gBAAgB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8CAgDqB,CAAC;AAE/C,MAAM,MAAM,GAA2B;IACrC,IAAI,EAAE,gBAAgB;IACtB,GAAG,EAAE,eAAe;IACpB,IAAI,EAAE,gBAAgB;CACvB,CAAC;AAEF,MAAM,UAAU,kBAAkB,CAAC,KAAa;IAC9C,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;IAC7B,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,OAAO,CAAC,KAAK,CAAC,mBAAmB,KAAK,+BAA+B,CAAC,CAAC;QACvE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IACD,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;AACtB,CAAC"}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { loadConfig, saveConfig } from '../lib/config.js';
|
|
2
|
+
import { output } from '../lib/output.js';
|
|
3
|
+
/** Keys that are safe to get/set via CLI. Token is excluded from `list` for security. */
|
|
4
|
+
const ALLOWED_KEYS = ['apiUrl', 'tenantId'];
|
|
5
|
+
const KEY_DESCRIPTIONS = {
|
|
6
|
+
apiUrl: 'API base URL (e.g. https://api.fold.run)',
|
|
7
|
+
tenantId: 'Default tenant ID',
|
|
8
|
+
};
|
|
9
|
+
function isAllowedKey(key) {
|
|
10
|
+
return ALLOWED_KEYS.includes(key);
|
|
11
|
+
}
|
|
12
|
+
export function configGetCommand(key) {
|
|
13
|
+
const config = loadConfig();
|
|
14
|
+
if (!config) {
|
|
15
|
+
console.error('Not logged in. Run `fold login` first.');
|
|
16
|
+
process.exit(1);
|
|
17
|
+
}
|
|
18
|
+
if (!isAllowedKey(key)) {
|
|
19
|
+
console.error(`Unknown config key: "${key}". Valid keys: ${ALLOWED_KEYS.join(', ')}`);
|
|
20
|
+
process.exit(1);
|
|
21
|
+
}
|
|
22
|
+
const value = config[key];
|
|
23
|
+
output(value ?? null, () => {
|
|
24
|
+
if (value !== undefined && value !== null) {
|
|
25
|
+
console.log(value);
|
|
26
|
+
}
|
|
27
|
+
else {
|
|
28
|
+
console.log(`(not set)`);
|
|
29
|
+
}
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
export function configSetCommand(key, value) {
|
|
33
|
+
const config = loadConfig();
|
|
34
|
+
if (!config) {
|
|
35
|
+
console.error('Not logged in. Run `fold login` first.');
|
|
36
|
+
process.exit(1);
|
|
37
|
+
}
|
|
38
|
+
if (!isAllowedKey(key)) {
|
|
39
|
+
console.error(`Unknown config key: "${key}". Valid keys: ${ALLOWED_KEYS.join(', ')}`);
|
|
40
|
+
process.exit(1);
|
|
41
|
+
}
|
|
42
|
+
config[key] = value;
|
|
43
|
+
saveConfig(config);
|
|
44
|
+
console.log(`Set ${key} = ${value}`);
|
|
45
|
+
}
|
|
46
|
+
export function configListCommand() {
|
|
47
|
+
const config = loadConfig();
|
|
48
|
+
if (!config) {
|
|
49
|
+
console.error('Not logged in. Run `fold login` first.');
|
|
50
|
+
process.exit(1);
|
|
51
|
+
}
|
|
52
|
+
const data = {};
|
|
53
|
+
for (const key of ALLOWED_KEYS) {
|
|
54
|
+
data[key] = config[key] ?? undefined;
|
|
55
|
+
}
|
|
56
|
+
output(data, () => {
|
|
57
|
+
for (const key of ALLOWED_KEYS) {
|
|
58
|
+
const val = config[key];
|
|
59
|
+
const desc = KEY_DESCRIPTIONS[key];
|
|
60
|
+
if (val) {
|
|
61
|
+
console.log(` ${key}: ${val}`);
|
|
62
|
+
}
|
|
63
|
+
else {
|
|
64
|
+
console.log(` ${key}: \x1b[90m(not set)\x1b[0m — ${desc}`);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
export function configPathCommand() {
|
|
70
|
+
const { homedir } = require('node:os');
|
|
71
|
+
const { join } = require('node:path');
|
|
72
|
+
const configFile = join(homedir(), '.config', 'fold', 'config.json');
|
|
73
|
+
console.log(configFile);
|
|
74
|
+
}
|
|
75
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/commands/config.ts"],"names":[],"mappings":"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"}
|
package/dist/commands/deploy.js
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
import { readFileSync } from 'node:fs';
|
|
1
|
+
import { existsSync, readFileSync, writeFileSync } from 'node:fs';
|
|
2
2
|
import { basename, resolve } from 'node:path';
|
|
3
3
|
import { apiFetch } from '../lib/api.js';
|
|
4
4
|
import { bundleFile } from '../lib/bundler.js';
|
|
5
5
|
import { requireConfig } from '../lib/config.js';
|
|
6
6
|
import { formatManifestErrors, formatManifestWarnings, loadManifest } from '../lib/manifest.js';
|
|
7
7
|
import { output } from '../lib/output.js';
|
|
8
|
+
import { confirm } from '../lib/prompt.js';
|
|
8
9
|
import { createSpinner } from '../lib/spinner.js';
|
|
9
10
|
export async function deployCommand(file, opts) {
|
|
10
11
|
const config = requireConfig();
|
|
@@ -52,13 +53,36 @@ export async function deployCommand(file, opts) {
|
|
|
52
53
|
}
|
|
53
54
|
}
|
|
54
55
|
const name = opts.name ?? manifest?.name ?? basename(resolvedFile).replace(/\.(tsx?|js|mjs)$/, '');
|
|
56
|
+
// Dry-run: show what would be deployed without sending to the API
|
|
57
|
+
if (opts.dryRun) {
|
|
58
|
+
const sizeKb = (Buffer.byteLength(code, 'utf-8') / 1024).toFixed(1);
|
|
59
|
+
const dryRunResult = {
|
|
60
|
+
name,
|
|
61
|
+
tenant_id: tenantId,
|
|
62
|
+
file: resolvedFile,
|
|
63
|
+
bundle_size_kb: sizeKb,
|
|
64
|
+
intent: manifest?.intent,
|
|
65
|
+
};
|
|
66
|
+
output(dryRunResult, () => {
|
|
67
|
+
console.log('Dry run — no deploy will be made.\n');
|
|
68
|
+
console.log(` Name: ${name}`);
|
|
69
|
+
console.log(` Tenant: ${tenantId}`);
|
|
70
|
+
console.log(` File: ${resolvedFile}`);
|
|
71
|
+
console.log(` Bundle: ${sizeKb} KB`);
|
|
72
|
+
if (manifest?.intent?.trigger)
|
|
73
|
+
console.log(` Trigger: ${manifest.intent.trigger}`);
|
|
74
|
+
if (manifest?.intent?.bindings?.length)
|
|
75
|
+
console.log(` Bindings: ${manifest.intent.bindings.join(', ')}`);
|
|
76
|
+
});
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
55
79
|
const deploySpinner = createSpinner(`Deploying ${name}...`);
|
|
56
80
|
const body = { tenant_id: tenantId, name, code };
|
|
57
81
|
if (manifest?.intent)
|
|
58
82
|
body.intent = manifest.intent;
|
|
59
83
|
let result;
|
|
60
84
|
try {
|
|
61
|
-
result = (await apiFetch(config, '/deploy', { body }));
|
|
85
|
+
result = (await apiFetch(config, '/deploy', { body, retries: 2 }));
|
|
62
86
|
deploySpinner.success(`Deployed ${name} v${result.version}`);
|
|
63
87
|
}
|
|
64
88
|
catch (err) {
|
|
@@ -82,5 +106,14 @@ export async function deployCommand(file, opts) {
|
|
|
82
106
|
console.log(`\n Consider using secrets or env vars instead of hardcoding sensitive values.`);
|
|
83
107
|
}
|
|
84
108
|
});
|
|
109
|
+
// Offer to create fold.json if deploying from CLI args without a manifest
|
|
110
|
+
if (!manifest && file && !existsSync(resolve('fold.json')) && process.stdout.isTTY) {
|
|
111
|
+
const shouldCreate = await confirm('\nNo fold.json found. Create one for future deploys?');
|
|
112
|
+
if (shouldCreate) {
|
|
113
|
+
const manifestData = { name, entrypoint: resolvedFile, intent: { bindings: [] } };
|
|
114
|
+
writeFileSync(resolve('fold.json'), `${JSON.stringify(manifestData, null, 2)}\n`);
|
|
115
|
+
console.log('Created fold.json — next time just run `fold deploy`.');
|
|
116
|
+
}
|
|
117
|
+
}
|
|
85
118
|
}
|
|
86
119
|
//# sourceMappingURL=deploy.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"deploy.js","sourceRoot":"","sources":["../../src/commands/deploy.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"deploy.js","sourceRoot":"","sources":["../../src/commands/deploy.ts"],"names":[],"mappings":"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"}
|
package/dist/commands/dev.d.ts
CHANGED
package/dist/commands/dev.js
CHANGED
|
@@ -3,27 +3,44 @@ import { existsSync, readFileSync, watch } from 'node:fs';
|
|
|
3
3
|
import { dirname, resolve } from 'node:path';
|
|
4
4
|
import { bundleFile } from '../lib/bundler.js';
|
|
5
5
|
import { formatManifestErrors, formatManifestWarnings, loadManifest } from '../lib/manifest.js';
|
|
6
|
-
/** Parse
|
|
7
|
-
function
|
|
6
|
+
/** Parse a single .env file into a key-value record. */
|
|
7
|
+
function parseDotenv(filePath) {
|
|
8
8
|
const vars = {};
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
9
|
+
if (!existsSync(filePath))
|
|
10
|
+
return vars;
|
|
11
|
+
const lines = readFileSync(filePath, 'utf-8').split('\n');
|
|
12
|
+
for (const line of lines) {
|
|
13
|
+
const trimmed = line.trim();
|
|
14
|
+
if (!trimmed || trimmed.startsWith('#'))
|
|
15
|
+
continue;
|
|
16
|
+
const eq = trimmed.indexOf('=');
|
|
17
|
+
if (eq === -1)
|
|
18
|
+
continue;
|
|
19
|
+
const key = trimmed.slice(0, eq).trim();
|
|
20
|
+
const raw = trimmed.slice(eq + 1).trim();
|
|
21
|
+
// Strip surrounding quotes
|
|
22
|
+
vars[key] = raw.replace(/^(['"])(.*)\1$/, '$2');
|
|
23
|
+
}
|
|
24
|
+
return vars;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Load env vars following Vite's convention (lowest → highest priority):
|
|
28
|
+
* .env → .env.local → .env.{mode} → .env.{mode}.local → --env flags
|
|
29
|
+
*
|
|
30
|
+
* Default mode is "development". Override with --mode flag.
|
|
31
|
+
*/
|
|
32
|
+
function loadEnvVars(envFlags, mode = 'development') {
|
|
33
|
+
const envFiles = ['.env', '.env.local', `.env.${mode}`, `.env.${mode}.local`];
|
|
34
|
+
const loadedFiles = [];
|
|
35
|
+
const vars = {};
|
|
36
|
+
for (const name of envFiles) {
|
|
37
|
+
const filePath = resolve(name);
|
|
38
|
+
if (existsSync(filePath)) {
|
|
39
|
+
Object.assign(vars, parseDotenv(filePath));
|
|
40
|
+
loadedFiles.push(name);
|
|
24
41
|
}
|
|
25
42
|
}
|
|
26
|
-
// --env flags override
|
|
43
|
+
// --env flags override all files
|
|
27
44
|
for (const flag of envFlags) {
|
|
28
45
|
const eq = flag.indexOf('=');
|
|
29
46
|
if (eq === -1) {
|
|
@@ -33,7 +50,7 @@ function loadEnvVars(envFlags) {
|
|
|
33
50
|
vars[flag.slice(0, eq).trim()] = flag.slice(eq + 1);
|
|
34
51
|
}
|
|
35
52
|
}
|
|
36
|
-
return vars;
|
|
53
|
+
return { vars, files: loadedFiles };
|
|
37
54
|
}
|
|
38
55
|
async function buildCode(filePath, resolvedFile, noBundle) {
|
|
39
56
|
if (!noBundle && /\.tsx?$/.test(resolvedFile)) {
|
|
@@ -116,9 +133,12 @@ export async function devCommand(file, opts) {
|
|
|
116
133
|
const port = parseInt(opts.port ?? '8000', 10);
|
|
117
134
|
const noBundle = opts.noBundle ?? false;
|
|
118
135
|
const watchMode = opts.watch !== false; // default true
|
|
119
|
-
const env = loadEnvVars(opts.env ?? []);
|
|
136
|
+
const { vars: env, files: envFiles } = loadEnvVars(opts.env ?? [], opts.mode);
|
|
137
|
+
if (envFiles.length > 0) {
|
|
138
|
+
console.log(`Loaded env from: ${envFiles.join(', ')}`);
|
|
139
|
+
}
|
|
120
140
|
if (Object.keys(env).length > 0) {
|
|
121
|
-
console.log(`
|
|
141
|
+
console.log(`Env vars: ${Object.keys(env).join(', ')}`);
|
|
122
142
|
}
|
|
123
143
|
let code;
|
|
124
144
|
try {
|
package/dist/commands/dev.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dev.js","sourceRoot":"","sources":["../../src/commands/dev.ts"],"names":[],"mappings":"AAAA,OAAO,EAAqB,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAC9D,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAC1D,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,oBAAoB,EAAE,sBAAsB,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAEhG,
|
|
1
|
+
{"version":3,"file":"dev.js","sourceRoot":"","sources":["../../src/commands/dev.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function doctorCommand(): Promise<void>;
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
import { existsSync } from 'node:fs';
|
|
2
|
+
import { resolve } from 'node:path';
|
|
3
|
+
import { loadConfig } from '../lib/config.js';
|
|
4
|
+
import { loadManifest } from '../lib/manifest.js';
|
|
5
|
+
import { output } from '../lib/output.js';
|
|
6
|
+
export async function doctorCommand() {
|
|
7
|
+
const checks = [];
|
|
8
|
+
// 1. Node.js version
|
|
9
|
+
const nodeVersion = process.versions.node;
|
|
10
|
+
const major = Number.parseInt(nodeVersion.split('.')[0], 10);
|
|
11
|
+
if (major >= 20) {
|
|
12
|
+
checks.push({ name: 'Node.js', status: 'ok', message: `v${nodeVersion}` });
|
|
13
|
+
}
|
|
14
|
+
else {
|
|
15
|
+
checks.push({ name: 'Node.js', status: 'fail', message: `v${nodeVersion} (requires >=20)` });
|
|
16
|
+
}
|
|
17
|
+
// 2. Authentication
|
|
18
|
+
const config = loadConfig();
|
|
19
|
+
if (!config) {
|
|
20
|
+
checks.push({ name: 'Auth', status: 'fail', message: 'Not logged in. Run `fold login`.' });
|
|
21
|
+
}
|
|
22
|
+
else {
|
|
23
|
+
// Check JWT expiry
|
|
24
|
+
let expired = false;
|
|
25
|
+
let daysLeft = null;
|
|
26
|
+
try {
|
|
27
|
+
const payload = JSON.parse(Buffer.from(config.token.split('.')[1], 'base64url').toString());
|
|
28
|
+
if (payload.exp) {
|
|
29
|
+
const msLeft = payload.exp * 1000 - Date.now();
|
|
30
|
+
if (msLeft < 0) {
|
|
31
|
+
expired = true;
|
|
32
|
+
}
|
|
33
|
+
else {
|
|
34
|
+
daysLeft = Math.ceil(msLeft / (1000 * 60 * 60 * 24));
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
catch {
|
|
39
|
+
// Not a JWT — that's fine
|
|
40
|
+
}
|
|
41
|
+
if (expired) {
|
|
42
|
+
checks.push({ name: 'Auth', status: 'fail', message: 'Token expired. Run `fold login`.' });
|
|
43
|
+
}
|
|
44
|
+
else if (daysLeft !== null && daysLeft <= 7) {
|
|
45
|
+
checks.push({
|
|
46
|
+
name: 'Auth',
|
|
47
|
+
status: 'warn',
|
|
48
|
+
message: `Token expires in ${daysLeft} day${daysLeft === 1 ? '' : 's'}`,
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
checks.push({ name: 'Auth', status: 'ok', message: `Authenticated (${config.apiUrl})` });
|
|
53
|
+
}
|
|
54
|
+
// Check tenant
|
|
55
|
+
if (config.tenantId) {
|
|
56
|
+
checks.push({ name: 'Tenant', status: 'ok', message: config.tenantId });
|
|
57
|
+
}
|
|
58
|
+
else {
|
|
59
|
+
checks.push({ name: 'Tenant', status: 'warn', message: 'No default tenant set. Use `fold tenant set <id>`.' });
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
// 3. API connectivity
|
|
63
|
+
if (config) {
|
|
64
|
+
try {
|
|
65
|
+
const res = await fetch(`${config.apiUrl}/health`, {
|
|
66
|
+
signal: AbortSignal.timeout(5_000),
|
|
67
|
+
});
|
|
68
|
+
if (res.ok) {
|
|
69
|
+
checks.push({ name: 'API', status: 'ok', message: `${config.apiUrl} reachable` });
|
|
70
|
+
}
|
|
71
|
+
else {
|
|
72
|
+
checks.push({ name: 'API', status: 'fail', message: `${config.apiUrl} returned ${res.status}` });
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
catch (err) {
|
|
76
|
+
checks.push({ name: 'API', status: 'fail', message: `Cannot reach ${config.apiUrl}: ${err}` });
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
// 4. esbuild availability
|
|
80
|
+
try {
|
|
81
|
+
await import('esbuild');
|
|
82
|
+
checks.push({ name: 'esbuild', status: 'ok', message: 'Available' });
|
|
83
|
+
}
|
|
84
|
+
catch {
|
|
85
|
+
checks.push({ name: 'esbuild', status: 'warn', message: 'Not installed. TypeScript bundling will fail.' });
|
|
86
|
+
}
|
|
87
|
+
// 5. fold.json validation
|
|
88
|
+
const manifestPath = resolve('fold.json');
|
|
89
|
+
if (existsSync(manifestPath)) {
|
|
90
|
+
const { manifest, errors, warnings } = loadManifest();
|
|
91
|
+
if (errors.length > 0) {
|
|
92
|
+
checks.push({
|
|
93
|
+
name: 'fold.json',
|
|
94
|
+
status: 'fail',
|
|
95
|
+
message: errors.map((e) => e.message).join('; '),
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
else if (warnings.length > 0) {
|
|
99
|
+
checks.push({
|
|
100
|
+
name: 'fold.json',
|
|
101
|
+
status: 'warn',
|
|
102
|
+
message: warnings.join('; '),
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
else if (manifest) {
|
|
106
|
+
const parts = [manifest.name, manifest.entrypoint].filter(Boolean);
|
|
107
|
+
checks.push({ name: 'fold.json', status: 'ok', message: parts.join(' → ') || 'Valid' });
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
else {
|
|
111
|
+
checks.push({ name: 'fold.json', status: 'warn', message: 'Not found in current directory' });
|
|
112
|
+
}
|
|
113
|
+
// Output
|
|
114
|
+
const hasFailures = checks.some((c) => c.status === 'fail');
|
|
115
|
+
output(checks, () => {
|
|
116
|
+
console.log('fold doctor\n');
|
|
117
|
+
for (const check of checks) {
|
|
118
|
+
const icon = check.status === 'ok' ? '\x1b[32m✓\x1b[0m' : check.status === 'warn' ? '\x1b[33m!\x1b[0m' : '\x1b[31m✗\x1b[0m';
|
|
119
|
+
console.log(` ${icon} ${check.name}: ${check.message}`);
|
|
120
|
+
}
|
|
121
|
+
const okCount = checks.filter((c) => c.status === 'ok').length;
|
|
122
|
+
const warnCount = checks.filter((c) => c.status === 'warn').length;
|
|
123
|
+
const failCount = checks.filter((c) => c.status === 'fail').length;
|
|
124
|
+
console.log('');
|
|
125
|
+
if (failCount > 0) {
|
|
126
|
+
console.log(`\x1b[31m${failCount} issue${failCount > 1 ? 's' : ''} found.\x1b[0m`);
|
|
127
|
+
}
|
|
128
|
+
else if (warnCount > 0) {
|
|
129
|
+
console.log(`All clear with ${warnCount} warning${warnCount > 1 ? 's' : ''}.`);
|
|
130
|
+
}
|
|
131
|
+
else {
|
|
132
|
+
console.log(`\x1b[32mAll ${okCount} checks passed.\x1b[0m`);
|
|
133
|
+
}
|
|
134
|
+
});
|
|
135
|
+
if (hasFailures)
|
|
136
|
+
process.exit(1);
|
|
137
|
+
}
|
|
138
|
+
//# sourceMappingURL=doctor.js.map
|