nivii 0.3.1 → 0.3.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.
Files changed (57) hide show
  1. package/README.md +142 -215
  2. package/dist/cli.js +48 -1
  3. package/dist/cli.js.map +1 -1
  4. package/dist/commands/fullstack.d.ts +12 -0
  5. package/dist/commands/fullstack.d.ts.map +1 -0
  6. package/dist/commands/fullstack.js +173 -0
  7. package/dist/commands/fullstack.js.map +1 -0
  8. package/dist/commands/pro.d.ts +2 -0
  9. package/dist/commands/pro.d.ts.map +1 -0
  10. package/dist/commands/pro.js +174 -0
  11. package/dist/commands/pro.js.map +1 -0
  12. package/dist/commands/share.d.ts.map +1 -1
  13. package/dist/commands/share.js +5 -4
  14. package/dist/commands/share.js.map +1 -1
  15. package/dist/core/backend.d.ts +26 -0
  16. package/dist/core/backend.d.ts.map +1 -0
  17. package/dist/core/backend.js +185 -0
  18. package/dist/core/backend.js.map +1 -0
  19. package/dist/core/env.d.ts +27 -0
  20. package/dist/core/env.d.ts.map +1 -0
  21. package/dist/core/env.js +164 -0
  22. package/dist/core/env.js.map +1 -0
  23. package/dist/core/fullstack.d.ts +29 -0
  24. package/dist/core/fullstack.d.ts.map +1 -0
  25. package/dist/core/fullstack.js +126 -0
  26. package/dist/core/fullstack.js.map +1 -0
  27. package/dist/core/upload.d.ts +2 -1
  28. package/dist/core/upload.d.ts.map +1 -1
  29. package/dist/core/upload.js +2 -0
  30. package/dist/core/upload.js.map +1 -1
  31. package/dist/ui/spinner.d.ts +1 -0
  32. package/dist/ui/spinner.d.ts.map +1 -1
  33. package/dist/ui/spinner.js +3 -0
  34. package/dist/ui/spinner.js.map +1 -1
  35. package/dist/ui/welcome.d.ts.map +1 -1
  36. package/dist/ui/welcome.js +6 -3
  37. package/dist/ui/welcome.js.map +1 -1
  38. package/dist/utils/config.d.ts +3 -0
  39. package/dist/utils/config.d.ts.map +1 -1
  40. package/dist/utils/config.js.map +1 -1
  41. package/package.json +9 -4
  42. package/src/cli.ts +0 -118
  43. package/src/commands/config.ts +0 -33
  44. package/src/commands/share.ts +0 -159
  45. package/src/commands/whoami.ts +0 -16
  46. package/src/core/analytics.ts +0 -64
  47. package/src/core/build.ts +0 -46
  48. package/src/core/detect.ts +0 -159
  49. package/src/core/qr.ts +0 -30
  50. package/src/core/tunnel.ts +0 -70
  51. package/src/core/upload.ts +0 -95
  52. package/src/ui/spinner.ts +0 -36
  53. package/src/ui/theme.ts +0 -35
  54. package/src/ui/welcome.ts +0 -104
  55. package/src/utils/config.ts +0 -47
  56. package/src/utils/hash.ts +0 -11
  57. package/src/utils/zip.ts +0 -22
@@ -0,0 +1,185 @@
1
+ import fs from 'fs';
2
+ import path from 'path';
3
+ import fetch from 'node-fetch';
4
+ import { createSpinner } from '../ui/spinner.js';
5
+ import chalk from 'chalk';
6
+ const FLY_API = 'https://api.machines.dev/v1';
7
+ const FLY_DEPLOY_API = 'https://fly.io/api/v1';
8
+ /** Generate a minimal Dockerfile for the backend */
9
+ export function generateDockerfile(framework, port) {
10
+ const portStr = String(port);
11
+ if (framework === 'hono') {
12
+ return `FROM node:20-alpine
13
+ WORKDIR /app
14
+ COPY package*.json ./
15
+ RUN npm ci --production
16
+ COPY . .
17
+ EXPOSE ${portStr}
18
+ CMD ["node", "src/index.js"]
19
+ `;
20
+ }
21
+ // Express / Fastify / generic Node
22
+ return `FROM node:20-alpine
23
+ WORKDIR /app
24
+ COPY package*.json ./
25
+ RUN npm ci --production
26
+ COPY . .
27
+ EXPOSE ${portStr}
28
+ CMD ["node", "index.js"]
29
+ `;
30
+ }
31
+ /** Generate fly.toml for the app */
32
+ export function generateFlyToml(appName, port) {
33
+ return `app = "${appName}"
34
+ primary_region = "sin"
35
+
36
+ [build]
37
+
38
+ [http_service]
39
+ internal_port = ${port}
40
+ force_https = true
41
+ auto_stop_machines = true
42
+ auto_start_machines = true
43
+ min_machines_running = 0
44
+
45
+ [env]
46
+ PORT = "${port}"
47
+ `;
48
+ }
49
+ /** Create a Fly.io app via API */
50
+ async function createFlyApp(name, token) {
51
+ const res = await fetch('https://api.fly.io/graphql', {
52
+ method: 'POST',
53
+ headers: {
54
+ 'Authorization': `Bearer ${token}`,
55
+ 'Content-Type': 'application/json',
56
+ },
57
+ body: JSON.stringify({
58
+ query: `
59
+ mutation CreateApp($input: CreateAppInput!) {
60
+ createApp(input: $input) {
61
+ app { name }
62
+ }
63
+ }
64
+ `,
65
+ variables: {
66
+ input: {
67
+ name,
68
+ organizationSlug: 'personal',
69
+ },
70
+ },
71
+ }),
72
+ });
73
+ const json = await res.json();
74
+ if (json.errors && json.errors.length > 0) {
75
+ // App might already exist — that's OK
76
+ if (!json.errors[0].message.includes('already exists')) {
77
+ throw new Error(`Fly app creation failed: ${json.errors[0].message}`);
78
+ }
79
+ }
80
+ }
81
+ /** Deploy backend to Fly.io using flyctl via CLI subprocess */
82
+ export async function deployBackend(opts) {
83
+ const spinner = createSpinner('Deploying backend to Fly.io…');
84
+ spinner.start();
85
+ const appName = `nivii-${opts.slug}-api`;
86
+ const port = opts.port || 3000;
87
+ const tmpDir = path.join('/tmp', `nivii-backend-${opts.slug}`);
88
+ try {
89
+ // Copy project to temp dir
90
+ if (fs.existsSync(tmpDir))
91
+ fs.rmSync(tmpDir, { recursive: true });
92
+ fs.mkdirSync(tmpDir, { recursive: true });
93
+ copyDir(opts.projectDir, tmpDir, ['node_modules', '.git', '.next', 'dist', 'build']);
94
+ // Generate Dockerfile if missing
95
+ const dockerfilePath = path.join(tmpDir, 'Dockerfile');
96
+ if (!fs.existsSync(dockerfilePath)) {
97
+ fs.writeFileSync(dockerfilePath, generateDockerfile(opts.framework, port));
98
+ }
99
+ // Generate fly.toml
100
+ fs.writeFileSync(path.join(tmpDir, 'fly.toml'), generateFlyToml(appName, port));
101
+ // Write .env file for the deployment
102
+ if (opts.envVars.length > 0) {
103
+ const envContent = opts.envVars
104
+ .map(v => `${v.key}=${v.value}`)
105
+ .join('\n');
106
+ fs.writeFileSync(path.join(tmpDir, '.env'), envContent);
107
+ }
108
+ // Use flyctl to deploy (must be installed)
109
+ const { execSync } = await import('child_process');
110
+ // Check flyctl available
111
+ try {
112
+ execSync('flyctl version', { stdio: 'ignore' });
113
+ }
114
+ catch {
115
+ throw new Error('flyctl not found. Install it: curl -L https://fly.io/install.sh | sh');
116
+ }
117
+ // Set env vars as args
118
+ const envArgs = opts.envVars
119
+ .map(v => `--env ${v.key}="${v.value}"`)
120
+ .join(' ');
121
+ // Deploy
122
+ execSync(`flyctl deploy --app ${appName} --remote-only --yes ${envArgs}`, {
123
+ cwd: tmpDir,
124
+ stdio: 'pipe',
125
+ env: { ...process.env, FLY_API_TOKEN: opts.flyToken },
126
+ });
127
+ const url = `https://${appName}.fly.dev`;
128
+ spinner.succeed(chalk.hex('#10B981')('Backend deployed ') + chalk.hex('#6B7280')(`(${appName})`));
129
+ return { url, appName, machineId: '' };
130
+ }
131
+ catch (err) {
132
+ spinner.fail(chalk.hex('#EF4444')('Backend deploy failed'));
133
+ throw err;
134
+ }
135
+ finally {
136
+ // Cleanup temp dir
137
+ try {
138
+ fs.rmSync(tmpDir, { recursive: true });
139
+ }
140
+ catch { }
141
+ }
142
+ }
143
+ /** Schedule auto-destruction of a Fly.io app after N hours */
144
+ export async function scheduleBackendDestroy(appName, flyToken, afterHours = 48) {
145
+ // We store this intent locally — a cron/timeout will handle it
146
+ // In production this would be a CF Worker scheduled task
147
+ const destroyAt = Date.now() + afterHours * 60 * 60 * 1000;
148
+ const record = { appName, flyToken: '[redacted]', destroyAt };
149
+ // Write to ~/.nivii/pending-destroys.json
150
+ const home = process.env.HOME || '/tmp';
151
+ const file = path.join(home, '.nivii', 'pending-destroys.json');
152
+ let existing = [];
153
+ try {
154
+ existing = JSON.parse(fs.readFileSync(file, 'utf-8'));
155
+ }
156
+ catch { }
157
+ existing.push(record);
158
+ fs.mkdirSync(path.dirname(file), { recursive: true });
159
+ fs.writeFileSync(file, JSON.stringify(existing, null, 2));
160
+ }
161
+ /** Destroy a Fly.io app */
162
+ export async function destroyBackend(appName, flyToken) {
163
+ const { execSync } = await import('child_process');
164
+ execSync(`flyctl apps destroy ${appName} --yes`, {
165
+ stdio: 'pipe',
166
+ env: { ...process.env, FLY_API_TOKEN: flyToken },
167
+ });
168
+ }
169
+ function copyDir(src, dest, skip = []) {
170
+ const entries = fs.readdirSync(src, { withFileTypes: true });
171
+ for (const entry of entries) {
172
+ if (skip.includes(entry.name))
173
+ continue;
174
+ const srcPath = path.join(src, entry.name);
175
+ const destPath = path.join(dest, entry.name);
176
+ if (entry.isDirectory()) {
177
+ fs.mkdirSync(destPath, { recursive: true });
178
+ copyDir(srcPath, destPath, skip);
179
+ }
180
+ else {
181
+ fs.copyFileSync(srcPath, destPath);
182
+ }
183
+ }
184
+ }
185
+ //# sourceMappingURL=backend.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"backend.js","sourceRoot":"","sources":["../../src/core/backend.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,27 @@
1
+ export interface EnvVar {
2
+ key: string;
3
+ value: string;
4
+ isFrontendSafe: boolean;
5
+ source: string;
6
+ }
7
+ export interface EnvScanResult {
8
+ vars: EnvVar[];
9
+ files: string[];
10
+ localhostRefs: LocalhostRef[];
11
+ }
12
+ export interface LocalhostRef {
13
+ file: string;
14
+ line: number;
15
+ original: string;
16
+ envKey: string;
17
+ }
18
+ export declare function scanEnvFiles(cwd: string): EnvScanResult;
19
+ /** Scan source files for hardcoded localhost references */
20
+ export declare function scanLocalhostRefs(cwd: string): LocalhostRef[];
21
+ /** Filter which env vars to send to backend deployment */
22
+ export declare function filterBackendVars(vars: EnvVar[]): EnvVar[];
23
+ /** Replace localhost URLs in source code with env var references */
24
+ export declare function injectEnvIntoSource(cwd: string, frontendDir: string, backendUrl: string, frontendUrl: string): void;
25
+ /** Print a formatted summary of found env vars */
26
+ export declare function formatEnvSummary(result: EnvScanResult): string;
27
+ //# sourceMappingURL=env.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"env.d.ts","sourceRoot":"","sources":["../../src/core/env.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,MAAM;IACrB,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,cAAc,EAAE,OAAO,CAAC;IACxB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,aAAa,EAAE,YAAY,EAAE,CAAC;CAC/B;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;CAChB;AA+CD,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,aAAa,CAiCvD;AAED,2DAA2D;AAC3D,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,YAAY,EAAE,CAiC7D;AAED,0DAA0D;AAC1D,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,CAQ1D;AAED,oEAAoE;AACpE,wBAAgB,mBAAmB,CACjC,GAAG,EAAE,MAAM,EACX,WAAW,EAAE,MAAM,EACnB,UAAU,EAAE,MAAM,EAClB,WAAW,EAAE,MAAM,GAClB,IAAI,CA2BN;AAED,kDAAkD;AAClD,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,aAAa,GAAG,MAAM,CAS9D"}
@@ -0,0 +1,164 @@
1
+ import fs from 'fs';
2
+ import path from 'path';
3
+ const ENV_FILES = [
4
+ '.env',
5
+ '.env.local',
6
+ '.env.development',
7
+ '.env.development.local',
8
+ '.env.production',
9
+ '.env.production.local',
10
+ ];
11
+ /** Prefixes that are safe to expose to the frontend */
12
+ const FRONTEND_SAFE_PREFIXES = [
13
+ 'NEXT_PUBLIC_',
14
+ 'VITE_',
15
+ 'REACT_APP_',
16
+ 'NUXT_PUBLIC_',
17
+ 'PUBLIC_',
18
+ 'EXPO_PUBLIC_',
19
+ ];
20
+ /** Keys that should NEVER be sent anywhere */
21
+ const SENSITIVE_PATTERNS = [
22
+ /secret/i,
23
+ /password/i,
24
+ /passwd/i,
25
+ /private_key/i,
26
+ /api_key/i,
27
+ /access_key/i,
28
+ /token/i,
29
+ /auth/i,
30
+ /credential/i,
31
+ /cert/i,
32
+ /database_url/i,
33
+ /db_url/i,
34
+ /mongo/i,
35
+ /postgres/i,
36
+ /mysql/i,
37
+ /redis/i,
38
+ /stripe/i,
39
+ /twilio/i,
40
+ /sendgrid/i,
41
+ /aws_/i,
42
+ /gcp_/i,
43
+ /azure_/i,
44
+ ];
45
+ export function scanEnvFiles(cwd) {
46
+ const vars = [];
47
+ const files = [];
48
+ for (const filename of ENV_FILES) {
49
+ const filePath = path.join(cwd, filename);
50
+ if (!fs.existsSync(filePath))
51
+ continue;
52
+ files.push(filename);
53
+ const content = fs.readFileSync(filePath, 'utf-8');
54
+ for (const line of content.split('\n')) {
55
+ const trimmed = line.trim();
56
+ if (!trimmed || trimmed.startsWith('#'))
57
+ continue;
58
+ const eqIdx = trimmed.indexOf('=');
59
+ if (eqIdx === -1)
60
+ continue;
61
+ const key = trimmed.slice(0, eqIdx).trim();
62
+ const value = trimmed.slice(eqIdx + 1).trim().replace(/^["']|["']$/g, '');
63
+ if (!key)
64
+ continue;
65
+ const isFrontendSafe = FRONTEND_SAFE_PREFIXES.some(p => key.startsWith(p));
66
+ // Don't override if already added (prefer more specific .env files)
67
+ if (!vars.find(v => v.key === key)) {
68
+ vars.push({ key, value, isFrontendSafe, source: filename });
69
+ }
70
+ }
71
+ }
72
+ return { vars, files, localhostRefs: [] };
73
+ }
74
+ /** Scan source files for hardcoded localhost references */
75
+ export function scanLocalhostRefs(cwd) {
76
+ const refs = [];
77
+ const extensions = ['.ts', '.tsx', '.js', '.jsx', '.vue', '.svelte'];
78
+ const skipDirs = ['node_modules', '.next', 'dist', 'build', 'out', '.git'];
79
+ function scan(dir) {
80
+ const entries = fs.readdirSync(dir, { withFileTypes: true });
81
+ for (const entry of entries) {
82
+ if (skipDirs.includes(entry.name))
83
+ continue;
84
+ const full = path.join(dir, entry.name);
85
+ if (entry.isDirectory()) {
86
+ scan(full);
87
+ }
88
+ else if (extensions.includes(path.extname(entry.name))) {
89
+ const content = fs.readFileSync(full, 'utf-8');
90
+ const lines = content.split('\n');
91
+ lines.forEach((line, idx) => {
92
+ const match = line.match(/['"`](https?:\/\/localhost:\d+[^'"`]*?)['"`]/);
93
+ if (match) {
94
+ const port = match[1].match(/:(\d+)/)?.[1] || '3000';
95
+ refs.push({
96
+ file: path.relative(cwd, full),
97
+ line: idx + 1,
98
+ original: match[1],
99
+ envKey: `NEXT_PUBLIC_API_URL`,
100
+ });
101
+ }
102
+ });
103
+ }
104
+ }
105
+ }
106
+ try {
107
+ scan(cwd);
108
+ }
109
+ catch { }
110
+ return refs;
111
+ }
112
+ /** Filter which env vars to send to backend deployment */
113
+ export function filterBackendVars(vars) {
114
+ return vars.filter(v => {
115
+ // Always include – these are meant to be public/config
116
+ if (v.isFrontendSafe)
117
+ return true;
118
+ // Exclude obviously sensitive values
119
+ const looksSecret = SENSITIVE_PATTERNS.some(p => p.test(v.key));
120
+ return !looksSecret;
121
+ });
122
+ }
123
+ /** Replace localhost URLs in source code with env var references */
124
+ export function injectEnvIntoSource(cwd, frontendDir, backendUrl, frontendUrl) {
125
+ const extensions = ['.ts', '.tsx', '.js', '.jsx', '.vue', '.svelte', '.env', '.env.local'];
126
+ const skipDirs = ['node_modules', '.next', 'dist', 'build', 'out', '.git'];
127
+ // Write/update .env.local with injected URLs
128
+ const envLocalPath = path.join(frontendDir, '.env.local');
129
+ let envContent = '';
130
+ if (fs.existsSync(envLocalPath)) {
131
+ envContent = fs.readFileSync(envLocalPath, 'utf-8');
132
+ }
133
+ // Inject or replace NEXT_PUBLIC_API_URL / VITE_API_URL
134
+ const apiUrlLine = `NEXT_PUBLIC_API_URL=${backendUrl}`;
135
+ const viteApiUrlLine = `VITE_API_URL=${backendUrl}`;
136
+ if (!envContent.includes('NEXT_PUBLIC_API_URL')) {
137
+ envContent += `\n${apiUrlLine}`;
138
+ }
139
+ else {
140
+ envContent = envContent.replace(/NEXT_PUBLIC_API_URL=.*/g, apiUrlLine);
141
+ }
142
+ if (!envContent.includes('VITE_API_URL')) {
143
+ envContent += `\n${viteApiUrlLine}`;
144
+ }
145
+ else {
146
+ envContent = envContent.replace(/VITE_API_URL=.*/g, viteApiUrlLine);
147
+ }
148
+ fs.writeFileSync(envLocalPath, envContent.trim() + '\n');
149
+ }
150
+ /** Print a formatted summary of found env vars */
151
+ export function formatEnvSummary(result) {
152
+ if (result.files.length === 0)
153
+ return ' No .env files found';
154
+ const lines = [];
155
+ lines.push(` Found ${result.vars.length} vars in: ${result.files.join(', ')}`);
156
+ const pub = result.vars.filter(v => v.isFrontendSafe);
157
+ const priv = result.vars.filter(v => !v.isFrontendSafe);
158
+ if (pub.length)
159
+ lines.push(` ✓ ${pub.length} frontend-safe (NEXT_PUBLIC_* / VITE_*)`);
160
+ if (priv.length)
161
+ lines.push(` 🔒 ${priv.length} server-only (secrets, DB URLs, etc.)`);
162
+ return lines.join('\n');
163
+ }
164
+ //# sourceMappingURL=env.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"env.js","sourceRoot":"","sources":["../../src/core/env.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,29 @@
1
+ import { DetectResult } from './detect.js';
2
+ import { scanEnvFiles, scanLocalhostRefs } from './env.js';
3
+ export interface FullStackProject {
4
+ frontend: {
5
+ dir: string;
6
+ detect: DetectResult;
7
+ } | null;
8
+ backend: {
9
+ dir: string;
10
+ detect: DetectResult;
11
+ } | null;
12
+ envResult: ReturnType<typeof scanEnvFiles>;
13
+ localhostRefs: ReturnType<typeof scanLocalhostRefs>;
14
+ }
15
+ /** Detect frontend + backend in a monorepo or single project */
16
+ export declare function detectFullStack(cwd: string): FullStackProject;
17
+ /** Auto-wire frontend + backend env vars after both are deployed */
18
+ export declare function wireEnvVars(opts: {
19
+ frontendDir: string;
20
+ backendUrl: string;
21
+ frontendUrl: string;
22
+ existingVars: ReturnType<typeof scanEnvFiles>['vars'];
23
+ }): {
24
+ injected: string[];
25
+ warning: string[];
26
+ };
27
+ /** Print full-stack detection summary */
28
+ export declare function printFullStackSummary(project: FullStackProject): void;
29
+ //# sourceMappingURL=fullstack.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fullstack.d.ts","sourceRoot":"","sources":["../../src/core/fullstack.ts"],"names":[],"mappings":"AAEA,OAAO,EAAmB,YAAY,EAAE,MAAM,aAAa,CAAC;AAC5D,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAA4D,MAAM,UAAU,CAAC;AAKrH,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE;QACR,GAAG,EAAE,MAAM,CAAC;QACZ,MAAM,EAAE,YAAY,CAAC;KACtB,GAAG,IAAI,CAAC;IACT,OAAO,EAAE;QACP,GAAG,EAAE,MAAM,CAAC;QACZ,MAAM,EAAE,YAAY,CAAC;KACtB,GAAG,IAAI,CAAC;IACT,SAAS,EAAE,UAAU,CAAC,OAAO,YAAY,CAAC,CAAC;IAC3C,aAAa,EAAE,UAAU,CAAC,OAAO,iBAAiB,CAAC,CAAC;CACrD;AAKD,gEAAgE;AAChE,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,gBAAgB,CAsD7D;AAED,oEAAoE;AACpE,wBAAgB,WAAW,CAAC,IAAI,EAAE;IAChC,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,UAAU,CAAC,OAAO,YAAY,CAAC,CAAC,MAAM,CAAC,CAAC;CACvD,GAAG;IAAE,QAAQ,EAAE,MAAM,EAAE,CAAC;IAAC,OAAO,EAAE,MAAM,EAAE,CAAA;CAAE,CAqC5C;AAED,yCAAyC;AACzC,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,gBAAgB,GAAG,IAAI,CAiCrE"}
@@ -0,0 +1,126 @@
1
+ import fs from 'fs';
2
+ import path from 'path';
3
+ import { detectFramework } from './detect.js';
4
+ import { scanEnvFiles, scanLocalhostRefs, formatEnvSummary } from './env.js';
5
+ import { theme } from '../ui/theme.js';
6
+ import chalk from 'chalk';
7
+ const SERVER_FRAMEWORKS = ['express', 'fastify', 'hono'];
8
+ const CLIENT_FRAMEWORKS = ['nextjs', 'vite', 'react-cra', 'vue', 'svelte', 'sveltekit', 'astro', 'remix', 'nuxt', 'solid', 'static'];
9
+ /** Detect frontend + backend in a monorepo or single project */
10
+ export function detectFullStack(cwd) {
11
+ // Check if it's a monorepo (has packages/ or apps/ subdirs)
12
+ const subdirs = fs.readdirSync(cwd, { withFileTypes: true })
13
+ .filter(e => e.isDirectory() && !e.name.startsWith('.') && e.name !== 'node_modules')
14
+ .map(e => e.name);
15
+ const monorepoFolders = ['frontend', 'client', 'web', 'app', 'apps/web', 'packages/web',
16
+ 'backend', 'server', 'api', 'apps/api', 'packages/api'];
17
+ let frontendDir = null;
18
+ let backendDir = null;
19
+ let frontendDetect = null;
20
+ let backendDetect = null;
21
+ // Try monorepo detection first
22
+ for (const sub of subdirs) {
23
+ const subPath = path.join(cwd, sub);
24
+ if (!fs.existsSync(path.join(subPath, 'package.json')))
25
+ continue;
26
+ const detected = detectFramework(subPath);
27
+ if (!frontendDir && CLIENT_FRAMEWORKS.includes(detected.framework)) {
28
+ frontendDir = subPath;
29
+ frontendDetect = detected;
30
+ }
31
+ if (!backendDir && (SERVER_FRAMEWORKS.includes(detected.framework) || detected.isServer)) {
32
+ backendDir = subPath;
33
+ backendDetect = detected;
34
+ }
35
+ }
36
+ // Fallback: root-level detection
37
+ if (!frontendDir && !backendDir) {
38
+ const rootDetect = detectFramework(cwd);
39
+ if (SERVER_FRAMEWORKS.includes(rootDetect.framework) || rootDetect.isServer) {
40
+ backendDir = cwd;
41
+ backendDetect = rootDetect;
42
+ }
43
+ else {
44
+ frontendDir = cwd;
45
+ frontendDetect = rootDetect;
46
+ }
47
+ }
48
+ // Env scanning (from both dirs)
49
+ const scanDir = frontendDir || backendDir || cwd;
50
+ const envResult = scanEnvFiles(scanDir);
51
+ const localhostRefs = scanLocalhostRefs(scanDir);
52
+ return {
53
+ frontend: frontendDir && frontendDetect ? { dir: frontendDir, detect: frontendDetect } : null,
54
+ backend: backendDir && backendDetect ? { dir: backendDir, detect: backendDetect } : null,
55
+ envResult,
56
+ localhostRefs,
57
+ };
58
+ }
59
+ /** Auto-wire frontend + backend env vars after both are deployed */
60
+ export function wireEnvVars(opts) {
61
+ const injected = [];
62
+ const warning = [];
63
+ const envLocalPath = path.join(opts.frontendDir, '.env.local');
64
+ let envContent = '';
65
+ if (fs.existsSync(envLocalPath)) {
66
+ envContent = fs.readFileSync(envLocalPath, 'utf-8');
67
+ }
68
+ const apiVars = [
69
+ { key: 'NEXT_PUBLIC_API_URL', value: opts.backendUrl },
70
+ { key: 'VITE_API_URL', value: opts.backendUrl },
71
+ { key: 'REACT_APP_API_URL', value: opts.backendUrl },
72
+ { key: 'PUBLIC_API_URL', value: opts.backendUrl },
73
+ ];
74
+ for (const v of apiVars) {
75
+ if (envContent.includes(v.key)) {
76
+ // Replace existing
77
+ envContent = envContent.replace(new RegExp(`${v.key}=.*`, 'g'), `${v.key}=${v.value}`);
78
+ injected.push(`Updated ${v.key}`);
79
+ }
80
+ else {
81
+ envContent += `\n${v.key}=${v.value}`;
82
+ injected.push(`Added ${v.key}`);
83
+ }
84
+ }
85
+ // Add CORS_ORIGIN for backend to allow frontend
86
+ // (this gets passed to backend deploy env vars)
87
+ if (opts.frontendUrl) {
88
+ envContent += `\nCORS_ORIGIN=${opts.frontendUrl}`;
89
+ injected.push('Added CORS_ORIGIN');
90
+ }
91
+ fs.writeFileSync(envLocalPath, envContent.trim() + '\n');
92
+ return { injected, warning };
93
+ }
94
+ /** Print full-stack detection summary */
95
+ export function printFullStackSummary(project) {
96
+ console.log('');
97
+ console.log(chalk.hex('#A78BFA')(' ⚡ Full-Stack Detection'));
98
+ console.log('');
99
+ if (project.frontend) {
100
+ const { detect, dir } = project.frontend;
101
+ console.log(` ${chalk.green('✓')} Frontend ${chalk.cyan(detect.framework)} ${theme.muted(`→ ${path.basename(dir)}`)}`);
102
+ }
103
+ else {
104
+ console.log(` ${chalk.yellow('⚠')} Frontend ${theme.muted('not detected')}`);
105
+ }
106
+ if (project.backend) {
107
+ const { detect, dir } = project.backend;
108
+ console.log(` ${chalk.green('✓')} Backend ${chalk.cyan(detect.framework)} ${theme.muted(`→ ${path.basename(dir)}`)}`);
109
+ }
110
+ else {
111
+ console.log(` ${chalk.yellow('⚠')} Backend ${theme.muted('not detected')}`);
112
+ }
113
+ if (project.envResult.files.length > 0) {
114
+ console.log('');
115
+ console.log(formatEnvSummary(project.envResult));
116
+ }
117
+ if (project.localhostRefs.length > 0) {
118
+ console.log('');
119
+ console.log(` ${chalk.yellow('⚠')} Found ${project.localhostRefs.length} hardcoded localhost URL(s) — will auto-replace`);
120
+ project.localhostRefs.slice(0, 3).forEach(r => {
121
+ console.log(` ${theme.muted(r.file + ':' + r.line)} → ${chalk.dim(r.original)}`);
122
+ });
123
+ }
124
+ console.log('');
125
+ }
126
+ //# sourceMappingURL=fullstack.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fullstack.js","sourceRoot":"","sources":["../../src/core/fullstack.ts"],"names":[],"mappings":"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"}
@@ -2,6 +2,7 @@ export interface UploadOptions {
2
2
  buildDir: string;
3
3
  slug: string;
4
4
  token?: string;
5
+ proEmail?: string;
5
6
  password?: string;
6
7
  otp?: boolean;
7
8
  expires?: string;
@@ -14,7 +15,7 @@ export interface DeployResult {
14
15
  url: string;
15
16
  slug: string;
16
17
  liveToken?: string;
17
- collabToken?: string;
18
+ collabId?: string;
18
19
  otpCode?: string;
19
20
  expiresAt?: string;
20
21
  }
@@ -1 +1 @@
1
- {"version":3,"file":"upload.d.ts","sourceRoot":"","sources":["../../src/core/upload.ts"],"names":[],"mappings":"AASA,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,YAAY;IAC3B,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAgBD,wBAAsB,YAAY,CAAC,IAAI,EAAE,aAAa,GAAG,OAAO,CAAC,YAAY,CAAC,CAiD7E"}
1
+ {"version":3,"file":"upload.d.ts","sourceRoot":"","sources":["../../src/core/upload.ts"],"names":[],"mappings":"AASA,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,YAAY;IAC3B,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAgBD,wBAAsB,YAAY,CAAC,IAAI,EAAE,aAAa,GAAG,OAAO,CAAC,YAAY,CAAC,CAkD7E"}
@@ -44,6 +44,8 @@ export async function uploadDeploy(opts) {
44
44
  form.append('maxViews', String(opts.maxViews));
45
45
  if (opts.selfDestruct)
46
46
  form.append('selfDestruct', 'true');
47
+ if (opts.proEmail)
48
+ form.append('proEmail', opts.proEmail);
47
49
  // Attach each file with its relative path as the field name
48
50
  for (const { abs, rel } of files) {
49
51
  form.append('file[]', fs.createReadStream(abs), { filename: rel });
@@ -1 +1 @@
1
- {"version":3,"file":"upload.js","sourceRoot":"","sources":["../../src/core/upload.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"upload.js","sourceRoot":"","sources":["../../src/core/upload.ts"],"names":[],"mappings":"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"}
@@ -4,4 +4,5 @@ export declare function step(emoji: string, text: string, detail?: string): void
4
4
  export declare function success(text: string): void;
5
5
  export declare function warn(text: string): void;
6
6
  export declare function error(text: string): void;
7
+ export declare function info(text: string): void;
7
8
  //# sourceMappingURL=spinner.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"spinner.d.ts","sourceRoot":"","sources":["../../src/ui/spinner.ts"],"names":[],"mappings":"AAAA,OAAY,EAAE,GAAG,EAAE,MAAM,KAAK,CAAC;AAK/B,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,GAAG,CAS/C;AAED,wBAAgB,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,QAOhE;AAED,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,QAEnC;AAED,wBAAgB,IAAI,CAAC,IAAI,EAAE,MAAM,QAEhC;AAED,wBAAgB,KAAK,CAAC,IAAI,EAAE,MAAM,QAEjC"}
1
+ {"version":3,"file":"spinner.d.ts","sourceRoot":"","sources":["../../src/ui/spinner.ts"],"names":[],"mappings":"AAAA,OAAY,EAAE,GAAG,EAAE,MAAM,KAAK,CAAC;AAK/B,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,GAAG,CAS/C;AAED,wBAAgB,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,QAOhE;AAED,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,QAEnC;AAED,wBAAgB,IAAI,CAAC,IAAI,EAAE,MAAM,QAEhC;AAED,wBAAgB,KAAK,CAAC,IAAI,EAAE,MAAM,QAEjC;AAED,wBAAgB,IAAI,CAAC,IAAI,EAAE,MAAM,QAEhC"}
@@ -29,4 +29,7 @@ export function warn(text) {
29
29
  export function error(text) {
30
30
  console.log(chalk.hex('#EF4444')(' ✗ ') + chalk.white(text));
31
31
  }
32
+ export function info(text) {
33
+ console.log(chalk.hex('#60A5FA')(' ℹ ') + chalk.white(text));
34
+ }
32
35
  //# sourceMappingURL=spinner.js.map