@daileyos/cli 0.3.0 → 0.4.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/auth.js +10 -3
- package/dist/commands/auth.js.map +1 -1
- package/dist/commands/deploy.js +26 -10
- package/dist/commands/deploy.js.map +1 -1
- package/dist/commands/images.d.ts +2 -0
- package/dist/commands/images.js +166 -0
- package/dist/commands/images.js.map +1 -0
- package/dist/commands/links.d.ts +2 -0
- package/dist/commands/links.js +72 -0
- package/dist/commands/links.js.map +1 -0
- package/dist/commands/open.js +3 -1
- package/dist/commands/open.js.map +1 -1
- package/dist/commands/resources.d.ts +2 -0
- package/dist/commands/resources.js +122 -0
- package/dist/commands/resources.js.map +1 -0
- package/dist/commands/scale.js +40 -0
- package/dist/commands/scale.js.map +1 -1
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/commands/auth.ts +11 -3
- package/src/commands/deploy.ts +26 -10
- package/src/commands/images.ts +204 -0
- package/src/commands/links.ts +96 -0
- package/src/commands/open.ts +3 -1
- package/src/commands/resources.ts +147 -0
- package/src/commands/scale.ts +49 -0
- package/src/index.ts +6 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scale.js","sourceRoot":"","sources":["../../src/commands/scale.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,GAAG,MAAM,KAAK,CAAC;AACtB,OAAO,EAAE,GAAG,EAAE,MAAM,WAAW,CAAC;AAChC,OAAO,EAAE,cAAc,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAE1E,MAAM,UAAU,qBAAqB,CAAC,OAAgB;IACpD,OAAO;SACJ,OAAO,CAAC,6BAA6B,CAAC;SACtC,WAAW,CAAC,8BAA8B,CAAC;SAC3C,MAAM,CACL,gBAAgB,CAAC,KAAK,EAAE,QAAiB,EAAE,QAAiB,EAAE,EAAE;QAC9D,MAAM,OAAO,GAAG,MAAM,cAAc,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC;QACvD,MAAM,KAAK,GAAG,QAAQ,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC,CAAC;QAC7C,IAAI,KAAK,CAAC,KAAK,CAAC,IAAI,KAAK,GAAG,CAAC,EAAE,CAAC;YAC9B,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,0CAA0C,CAAC,CAAC,CAAC;YACrE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QAED,MAAM,OAAO,GAAG,GAAG,CAAC,YAAY,OAAO,CAAC,IAAI,QAAQ,KAAK,cAAc,CAAC,CAAC,KAAK,EAAE,CAAC;QACjF,MAAM,GAAG,CAAC,aAAa,OAAO,CAAC,EAAE,QAAQ,EAAE;YACzC,MAAM,EAAE,MAAM;YACd,IAAI,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE;SAC1B,CAAC,CAAC;QACH,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,WAAW,OAAO,CAAC,IAAI,QAAQ,KAAK,YAAY,CAAC,CAAC,CAAC;IACjF,CAAC,CAAC,CACH,CAAC;IAEJ,OAAO;SACJ,OAAO,CAAC,mBAAmB,CAAC;SAC5B,WAAW,CAAC,0CAA0C,CAAC;SACvD,MAAM,CAAC,QAAQ,EAAE,gBAAgB,CAAC;SAClC,MAAM,CACL,gBAAgB,CAAC,KAAK,EAAE,QAAiB,EAAE,IAAwB,EAAE,EAAE;QACrE,MAAM,OAAO,GAAG,MAAM,cAAc,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC;QAEvD,UAAU,CAAC,IAAI,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;QAE/B,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,WAAW,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;QACnD,OAAO,CAAC,GAAG,CAAC,KAAK,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,OAAO,CAAC,MAAM,IAAI,SAAS,EAAE,CAAC,CAAC;QAC5E,OAAO,CAAC,GAAG,CAAC,KAAK,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,KAAK,OAAO,CAAC,QAAQ,IAAI,KAAK,EAAE,CAAC,CAAC;QAC1E,OAAO,CAAC,GAAG,CAAC,KAAK,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,UAAU,OAAO,CAAC,GAAG,IAAI,KAAK,EAAE,CAAC,CAAC;QACrE,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;YACnB,OAAO,CAAC,GAAG,CAAC,KAAK,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;QACjE,CAAC;IACH,CAAC,CAAC,CACH,CAAC;AACN,CAAC"}
|
|
1
|
+
{"version":3,"file":"scale.js","sourceRoot":"","sources":["../../src/commands/scale.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -13,6 +13,9 @@ import { registerOpenCommand } from './commands/open.js';
|
|
|
13
13
|
import { registerPlatformCommands } from './commands/platform.js';
|
|
14
14
|
import { registerStorageCommands } from './commands/storage.js';
|
|
15
15
|
import { registerJobCommands } from './commands/jobs.js';
|
|
16
|
+
import { registerImageCommands } from './commands/images.js';
|
|
17
|
+
import { registerLinkCommands } from './commands/links.js';
|
|
18
|
+
import { registerResourceCommands } from './commands/resources.js';
|
|
16
19
|
const program = new Command();
|
|
17
20
|
program
|
|
18
21
|
.name('dailey')
|
|
@@ -31,5 +34,8 @@ registerOpenCommand(program);
|
|
|
31
34
|
registerPlatformCommands(program);
|
|
32
35
|
registerStorageCommands(program);
|
|
33
36
|
registerJobCommands(program);
|
|
37
|
+
registerImageCommands(program);
|
|
38
|
+
registerLinkCommands(program);
|
|
39
|
+
registerResourceCommands(program);
|
|
34
40
|
program.parse();
|
|
35
41
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAC1D,OAAO,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AACjE,OAAO,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AAC9D,OAAO,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AAC/D,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAC;AAChE,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,EAAE,wBAAwB,EAAE,MAAM,wBAAwB,CAAC;AAClE,OAAO,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAC;AAChE,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAC1D,OAAO,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AACjE,OAAO,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AAC9D,OAAO,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AAC/D,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAC;AAChE,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,EAAE,wBAAwB,EAAE,MAAM,wBAAwB,CAAC;AAClE,OAAO,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAC;AAChE,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAC7D,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAC3D,OAAO,EAAE,wBAAwB,EAAE,MAAM,yBAAyB,CAAC;AAEnE,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,QAAQ,CAAC;KACd,WAAW,CAAC,gEAAgE,CAAC;KAC7E,OAAO,CAAC,OAAO,CAAC,CAAC;AAEpB,oBAAoB,CAAC,OAAO,CAAC,CAAC;AAC9B,uBAAuB,CAAC,OAAO,CAAC,CAAC;AACjC,sBAAsB,CAAC,OAAO,CAAC,CAAC;AAChC,qBAAqB,CAAC,OAAO,CAAC,CAAC;AAC/B,mBAAmB,CAAC,OAAO,CAAC,CAAC;AAC7B,sBAAsB,CAAC,OAAO,CAAC,CAAC;AAChC,kBAAkB,CAAC,OAAO,CAAC,CAAC;AAC5B,qBAAqB,CAAC,OAAO,CAAC,CAAC;AAC/B,uBAAuB,CAAC,OAAO,CAAC,CAAC;AACjC,mBAAmB,CAAC,OAAO,CAAC,CAAC;AAC7B,wBAAwB,CAAC,OAAO,CAAC,CAAC;AAClC,uBAAuB,CAAC,OAAO,CAAC,CAAC;AACjC,mBAAmB,CAAC,OAAO,CAAC,CAAC;AAC7B,qBAAqB,CAAC,OAAO,CAAC,CAAC;AAC/B,oBAAoB,CAAC,OAAO,CAAC,CAAC;AAC9B,wBAAwB,CAAC,OAAO,CAAC,CAAC;AAElC,OAAO,CAAC,KAAK,EAAE,CAAC"}
|
package/package.json
CHANGED
package/src/commands/auth.ts
CHANGED
|
@@ -14,9 +14,12 @@ function prompt(question: string, hidden = false): Promise<string> {
|
|
|
14
14
|
});
|
|
15
15
|
|
|
16
16
|
if (hidden) {
|
|
17
|
-
// For password input,
|
|
17
|
+
// For password input, use raw mode to suppress echo
|
|
18
18
|
process.stdout.write(question);
|
|
19
|
+
rl.close(); // close readline so it doesn't interfere
|
|
20
|
+
|
|
19
21
|
const stdin = process.stdin;
|
|
22
|
+
stdin.resume();
|
|
20
23
|
const wasRaw = stdin.isRaw;
|
|
21
24
|
if (stdin.isTTY) {
|
|
22
25
|
stdin.setRawMode(true);
|
|
@@ -29,18 +32,23 @@ function prompt(question: string, hidden = false): Promise<string> {
|
|
|
29
32
|
if (stdin.isTTY && wasRaw !== undefined) {
|
|
30
33
|
stdin.setRawMode(wasRaw);
|
|
31
34
|
}
|
|
35
|
+
stdin.pause();
|
|
32
36
|
process.stdout.write('\n');
|
|
33
|
-
rl.close();
|
|
34
37
|
resolve(input);
|
|
35
38
|
} else if (c === '\u0003') {
|
|
36
39
|
process.exit(0);
|
|
37
40
|
} else if (c === '\u007f' || c === '\b') {
|
|
38
|
-
input
|
|
41
|
+
if (input.length > 0) {
|
|
42
|
+
input = input.slice(0, -1);
|
|
43
|
+
process.stdout.write('\b \b'); // erase the * character
|
|
44
|
+
}
|
|
39
45
|
} else {
|
|
40
46
|
input += c;
|
|
47
|
+
process.stdout.write('*'); // show asterisks instead of characters
|
|
41
48
|
}
|
|
42
49
|
};
|
|
43
50
|
stdin.on('data', onData);
|
|
51
|
+
return; // don't fall through to readline
|
|
44
52
|
} else {
|
|
45
53
|
rl.question(question, (answer) => {
|
|
46
54
|
rl.close();
|
package/src/commands/deploy.ts
CHANGED
|
@@ -7,18 +7,34 @@ import { resolveProject, formatTable, handleJson, withErrorHandler } from '../ut
|
|
|
7
7
|
export function registerDeployCommands(program: Command): void {
|
|
8
8
|
program
|
|
9
9
|
.command('deploy <idOrName>')
|
|
10
|
-
.description('Trigger a deploy (
|
|
10
|
+
.description('Trigger a new deploy (works for both git repos and Docker images)')
|
|
11
|
+
.option('--force', 'Force redeploy even if up to date')
|
|
11
12
|
.action(
|
|
12
|
-
withErrorHandler(async (idOrName: unknown) => {
|
|
13
|
+
withErrorHandler(async (idOrName: unknown, opts: { force?: boolean }) => {
|
|
13
14
|
const project = await resolveProject(String(idOrName));
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
15
|
+
const spinner = ora(`Deploying "${project.name}"...`).start();
|
|
16
|
+
|
|
17
|
+
try {
|
|
18
|
+
const result = await api<any>('/deploys', {
|
|
19
|
+
method: 'POST',
|
|
20
|
+
body: { project_id: project.id, commit_sha: 'HEAD' },
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
spinner.succeed(chalk.green(`Deploy triggered for "${project.name}"`));
|
|
24
|
+
console.log();
|
|
25
|
+
console.log(chalk.gray(' Build ID: ') + chalk.white(result.build_id));
|
|
26
|
+
if (result.mode === 'image') {
|
|
27
|
+
console.log(chalk.gray(' Mode: ') + chalk.cyan('Docker image (no build step)'));
|
|
28
|
+
} else {
|
|
29
|
+
console.log(chalk.gray(' Mode: ') + chalk.cyan('Git repo (clone → build → deploy)'));
|
|
30
|
+
}
|
|
31
|
+
console.log(chalk.gray(' Status: ') + chalk.yellow(result.status));
|
|
32
|
+
console.log();
|
|
33
|
+
console.log(chalk.gray(`View logs: ${chalk.white(`dailey logs ${String(idOrName)}`)}`));
|
|
34
|
+
console.log(chalk.gray(`View deploys: ${chalk.white(`dailey deploys ${String(idOrName)}`)}`));
|
|
35
|
+
} catch (err: any) {
|
|
36
|
+
spinner.fail(chalk.red(`Deploy failed: ${err.message}`));
|
|
37
|
+
}
|
|
22
38
|
}),
|
|
23
39
|
);
|
|
24
40
|
|
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
import chalk from 'chalk';
|
|
3
|
+
import ora from 'ora';
|
|
4
|
+
import { api } from '../api.js';
|
|
5
|
+
import { resolveProject, formatTable, handleJson, withErrorHandler } from '../util.js';
|
|
6
|
+
|
|
7
|
+
export function registerImageCommands(program: Command): void {
|
|
8
|
+
// Deploy a Docker image to a project
|
|
9
|
+
program
|
|
10
|
+
.command('run <image>')
|
|
11
|
+
.description('Deploy a Docker image (e.g., wordpress:6-apache, nginx:alpine)')
|
|
12
|
+
.option('-n, --name <name>', 'Project name (auto-generated if not provided)')
|
|
13
|
+
.option('--db', 'Provision a managed MySQL database')
|
|
14
|
+
.option('--json', 'Output as JSON')
|
|
15
|
+
.action(
|
|
16
|
+
withErrorHandler(async (image: unknown, opts: { name?: string; db?: boolean; json?: boolean }) => {
|
|
17
|
+
const imageStr = String(image);
|
|
18
|
+
const projectName = opts.name || imageStr.split('/').pop()?.split(':')[0] || 'app';
|
|
19
|
+
|
|
20
|
+
const spinner = ora(`Deploying ${chalk.cyan(imageStr)}...`).start();
|
|
21
|
+
|
|
22
|
+
// Create the project (this also triggers the deploy automatically)
|
|
23
|
+
const project = await api<any>('/projects', {
|
|
24
|
+
method: 'POST',
|
|
25
|
+
body: {
|
|
26
|
+
name: projectName,
|
|
27
|
+
repo_url: imageStr,
|
|
28
|
+
branch: 'main',
|
|
29
|
+
needs_database: opts.db || false,
|
|
30
|
+
},
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
spinner.text = `Project created: ${chalk.green(project.slug)}. Triggering deploy...`;
|
|
34
|
+
|
|
35
|
+
if (project.slug_auto_generated && project.slug_note) {
|
|
36
|
+
spinner.info(chalk.yellow(project.slug_note));
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// Trigger the deploy
|
|
40
|
+
let deploy: any = {};
|
|
41
|
+
try {
|
|
42
|
+
deploy = await api<any>('/deploys', {
|
|
43
|
+
method: 'POST',
|
|
44
|
+
body: { project_id: project.id, commit_sha: 'HEAD' },
|
|
45
|
+
});
|
|
46
|
+
} catch (err: any) {
|
|
47
|
+
// Deploy trigger might fail but project is created
|
|
48
|
+
deploy = { build_id: 'pending' };
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
spinner.succeed(chalk.green(`Deployed ${chalk.bold(imageStr)} → https://${project.slug}.dailey.cloud`));
|
|
52
|
+
|
|
53
|
+
console.log();
|
|
54
|
+
console.log(chalk.gray(' Project: ') + chalk.white(project.name));
|
|
55
|
+
console.log(chalk.gray(' URL: ') + chalk.cyan(`https://${project.slug}.dailey.cloud`));
|
|
56
|
+
console.log(chalk.gray(' Build ID: ') + chalk.white(deploy.build_id || 'pending'));
|
|
57
|
+
|
|
58
|
+
if (project.database) {
|
|
59
|
+
console.log(chalk.gray(' Database: ') + chalk.green(project.database.database));
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
if (deploy.credentials) {
|
|
63
|
+
console.log();
|
|
64
|
+
console.log(chalk.bold(' Credentials:'));
|
|
65
|
+
for (const [key, val] of Object.entries(deploy.credentials)) {
|
|
66
|
+
if (key !== 'note' && key !== 'label') {
|
|
67
|
+
console.log(chalk.gray(` ${key}: `) + chalk.yellow(String(val)));
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
console.log();
|
|
73
|
+
console.log(chalk.gray(`View logs: ${chalk.white(`dailey logs ${project.slug}`)}`));
|
|
74
|
+
console.log(chalk.gray(`View info: ${chalk.white(`dailey projects info ${project.slug}`)}`));
|
|
75
|
+
|
|
76
|
+
handleJson(opts.json, { project, deploy });
|
|
77
|
+
}),
|
|
78
|
+
);
|
|
79
|
+
|
|
80
|
+
// List marketplace catalog
|
|
81
|
+
program
|
|
82
|
+
.command('catalog')
|
|
83
|
+
.description('List available marketplace apps')
|
|
84
|
+
.option('--json', 'Output as JSON')
|
|
85
|
+
.action(
|
|
86
|
+
withErrorHandler(async (opts: { json?: boolean }) => {
|
|
87
|
+
const spinner = ora('Fetching catalog...').start();
|
|
88
|
+
const data = await api<{ apps: any[] }>('/projects/catalog');
|
|
89
|
+
spinner.stop();
|
|
90
|
+
|
|
91
|
+
handleJson(opts.json, data.apps);
|
|
92
|
+
|
|
93
|
+
console.log(chalk.bold('Marketplace Apps'));
|
|
94
|
+
console.log(chalk.gray('Deploy any of these with: dailey run <image>'));
|
|
95
|
+
console.log();
|
|
96
|
+
|
|
97
|
+
console.log(
|
|
98
|
+
formatTable(data.apps, [
|
|
99
|
+
{ key: 'name', label: 'App' },
|
|
100
|
+
{ key: 'image', label: 'Image' },
|
|
101
|
+
{ key: 'needs_database', label: 'DB' },
|
|
102
|
+
{ key: 'memory_mb', label: 'Memory' },
|
|
103
|
+
{ key: 'description', label: 'Description' },
|
|
104
|
+
]),
|
|
105
|
+
);
|
|
106
|
+
}),
|
|
107
|
+
);
|
|
108
|
+
|
|
109
|
+
// Analyze a Docker image before deploying
|
|
110
|
+
program
|
|
111
|
+
.command('inspect <image>')
|
|
112
|
+
.description('Analyze a Docker image before deploying')
|
|
113
|
+
.option('--json', 'Output as JSON')
|
|
114
|
+
.action(
|
|
115
|
+
withErrorHandler(async (image: unknown, opts: { json?: boolean }) => {
|
|
116
|
+
const imageStr = String(image);
|
|
117
|
+
const spinner = ora(`Analyzing ${chalk.cyan(imageStr)}...`).start();
|
|
118
|
+
|
|
119
|
+
const data = await api<any>('/projects/analyze', {
|
|
120
|
+
method: 'POST',
|
|
121
|
+
body: { repo_url: imageStr },
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
spinner.stop();
|
|
125
|
+
handleJson(opts.json, data);
|
|
126
|
+
|
|
127
|
+
if (data._isDockerImage) {
|
|
128
|
+
console.log(chalk.bold('Docker Image Analysis'));
|
|
129
|
+
console.log();
|
|
130
|
+
console.log(chalk.gray(' Image: ') + chalk.cyan(data.image?.name || imageStr));
|
|
131
|
+
console.log(chalk.gray(' Registry: ') + chalk.white(data.image?.registry || 'Docker Hub'));
|
|
132
|
+
console.log(chalk.gray(' Size: ') + chalk.white(`${data.image?.size_mb || '?'} MB`));
|
|
133
|
+
console.log(chalk.gray(' Port: ') + chalk.white(data.image?.port || 3000));
|
|
134
|
+
|
|
135
|
+
if (data.image?.description) {
|
|
136
|
+
console.log(chalk.gray(' About: ') + chalk.white(data.image.description));
|
|
137
|
+
}
|
|
138
|
+
if (data.image?.catalog_match) {
|
|
139
|
+
console.log(chalk.gray(' Catalog: ') + chalk.green(`✓ ${data.image.catalog_match} (pre-configured)`));
|
|
140
|
+
}
|
|
141
|
+
if (data.database?.needed) {
|
|
142
|
+
console.log(chalk.gray(' Database: ') + chalk.yellow('Recommended'));
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
if (data.estimates) {
|
|
146
|
+
console.log();
|
|
147
|
+
console.log(chalk.gray(` Pull time: ~${data.estimates.pull_time_seconds || '?'}s`));
|
|
148
|
+
console.log(chalk.gray(` Deploy time: ~${data.estimates.deploy_time_seconds || '?'}s`));
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
if (data.warnings?.length) {
|
|
152
|
+
console.log();
|
|
153
|
+
for (const w of data.warnings) {
|
|
154
|
+
console.log(chalk.yellow(` ⚠ ${w}`));
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
if (data.issues?.length) {
|
|
159
|
+
console.log();
|
|
160
|
+
for (const issue of data.issues) {
|
|
161
|
+
console.log(chalk.red(` ✗ ${issue}`));
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
if (!data.issues?.length) {
|
|
166
|
+
console.log();
|
|
167
|
+
console.log(chalk.green(` ✓ Ready to deploy: ${chalk.white(`dailey run ${imageStr}`)}`));
|
|
168
|
+
}
|
|
169
|
+
} else {
|
|
170
|
+
console.log(chalk.bold('Git Repository Analysis'));
|
|
171
|
+
console.log(chalk.gray(` Stack: ${data.stack?.name || 'unknown'}`));
|
|
172
|
+
}
|
|
173
|
+
}),
|
|
174
|
+
);
|
|
175
|
+
|
|
176
|
+
// List project credentials
|
|
177
|
+
program
|
|
178
|
+
.command('credentials <idOrName>')
|
|
179
|
+
.alias('creds')
|
|
180
|
+
.description('Show auto-generated credentials for a project')
|
|
181
|
+
.option('--json', 'Output as JSON')
|
|
182
|
+
.action(
|
|
183
|
+
withErrorHandler(async (idOrName: unknown, opts: { json?: boolean }) => {
|
|
184
|
+
const project = await resolveProject(String(idOrName));
|
|
185
|
+
const data = await api<{ credentials: any[] }>(`/projects/${project.id}/credentials`);
|
|
186
|
+
|
|
187
|
+
handleJson(opts.json, data.credentials);
|
|
188
|
+
|
|
189
|
+
if (!data.credentials?.length) {
|
|
190
|
+
console.log(chalk.gray('No auto-generated credentials for this project.'));
|
|
191
|
+
return;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
console.log(chalk.bold(`Credentials for ${project.name}`));
|
|
195
|
+
console.log();
|
|
196
|
+
for (const cred of data.credentials) {
|
|
197
|
+
console.log(chalk.gray(` ${cred.label}:`));
|
|
198
|
+
console.log(chalk.yellow(` ${cred.value}`));
|
|
199
|
+
}
|
|
200
|
+
}),
|
|
201
|
+
);
|
|
202
|
+
|
|
203
|
+
// Show project resources — moved to resources.ts to avoid duplicate 'resources' command registration
|
|
204
|
+
}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
import chalk from 'chalk';
|
|
3
|
+
import ora from 'ora';
|
|
4
|
+
import { api } from '../api.js';
|
|
5
|
+
import { resolveProject, formatTable, withErrorHandler } from '../util.js';
|
|
6
|
+
|
|
7
|
+
export function registerLinkCommands(program: Command): void {
|
|
8
|
+
// List service links
|
|
9
|
+
program
|
|
10
|
+
.command('links <idOrName>')
|
|
11
|
+
.description('List linked services for a project')
|
|
12
|
+
.option('--json', 'Output as JSON')
|
|
13
|
+
.action(
|
|
14
|
+
withErrorHandler(async (idOrName: unknown, opts: { json?: boolean }) => {
|
|
15
|
+
const project = await resolveProject(String(idOrName));
|
|
16
|
+
const spinner = ora('Fetching links...').start();
|
|
17
|
+
const data = await api<{ links: any[] }>(`/projects/${project.id}/links`);
|
|
18
|
+
spinner.stop();
|
|
19
|
+
|
|
20
|
+
if (opts.json) {
|
|
21
|
+
console.log(JSON.stringify(data.links, null, 2));
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
if (!data.links?.length) {
|
|
26
|
+
console.log(chalk.gray('No linked services.'));
|
|
27
|
+
console.log(chalk.gray(`Link a service: ${chalk.white(`dailey link ${String(idOrName)} <target>`)}`));
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
console.log(chalk.bold(`Linked services for ${project.name}:`));
|
|
32
|
+
console.log(
|
|
33
|
+
formatTable(data.links, [
|
|
34
|
+
{ key: 'target_name', label: 'Target' },
|
|
35
|
+
{ key: 'env_key', label: 'Env Variable' },
|
|
36
|
+
{ key: 'url', label: 'Internal URL' },
|
|
37
|
+
{ key: 'target_status', label: 'Status' },
|
|
38
|
+
]),
|
|
39
|
+
);
|
|
40
|
+
}),
|
|
41
|
+
);
|
|
42
|
+
|
|
43
|
+
// Create a service link
|
|
44
|
+
program
|
|
45
|
+
.command('link <project> <target>')
|
|
46
|
+
.description('Link a project to another service (injects internal URL as env var)')
|
|
47
|
+
.option('--env-key <key>', 'Custom env variable name (default: auto-generated)')
|
|
48
|
+
.action(
|
|
49
|
+
withErrorHandler(async (projectName: unknown, targetName: unknown, opts: { envKey?: string }) => {
|
|
50
|
+
const source = await resolveProject(String(projectName));
|
|
51
|
+
const target = await resolveProject(String(targetName));
|
|
52
|
+
|
|
53
|
+
const spinner = ora(`Linking ${chalk.cyan(target.name)} to ${chalk.cyan(source.name)}...`).start();
|
|
54
|
+
|
|
55
|
+
const result = await api<{ link: any; hint: string }>(`/projects/${source.id}/links`, {
|
|
56
|
+
method: 'POST',
|
|
57
|
+
body: { target_project_id: target.id, env_key: opts.envKey || undefined },
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
spinner.succeed(
|
|
61
|
+
chalk.green(`Linked ${chalk.bold(target.name)} → ${chalk.bold(source.name)}`),
|
|
62
|
+
);
|
|
63
|
+
|
|
64
|
+
console.log();
|
|
65
|
+
console.log(chalk.gray(' Env var: ') + chalk.white(result.link.env_key));
|
|
66
|
+
console.log(chalk.gray(' URL: ') + chalk.cyan(result.link.url));
|
|
67
|
+
console.log();
|
|
68
|
+
console.log(chalk.yellow(` Redeploy ${source.name} to pick up the new env var.`));
|
|
69
|
+
}),
|
|
70
|
+
);
|
|
71
|
+
|
|
72
|
+
// Remove a service link
|
|
73
|
+
program
|
|
74
|
+
.command('unlink <project> <target>')
|
|
75
|
+
.description('Remove a service link between two projects')
|
|
76
|
+
.action(
|
|
77
|
+
withErrorHandler(async (projectName: unknown, targetName: unknown) => {
|
|
78
|
+
const source = await resolveProject(String(projectName));
|
|
79
|
+
const target = await resolveProject(String(targetName));
|
|
80
|
+
|
|
81
|
+
const spinner = ora('Removing link...').start();
|
|
82
|
+
|
|
83
|
+
// Find the link
|
|
84
|
+
const data = await api<{ links: any[] }>(`/projects/${source.id}/links`);
|
|
85
|
+
const link = data.links?.find((l: any) => l.target_project_id === target.id);
|
|
86
|
+
|
|
87
|
+
if (!link) {
|
|
88
|
+
spinner.fail(chalk.red(`No link found from ${source.name} to ${target.name}`));
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
await api(`/projects/${source.id}/links/${link.id}`, { method: 'DELETE' });
|
|
93
|
+
spinner.succeed(chalk.green(`Unlinked ${chalk.bold(target.name)} from ${chalk.bold(source.name)}`));
|
|
94
|
+
}),
|
|
95
|
+
);
|
|
96
|
+
}
|
package/src/commands/open.ts
CHANGED
|
@@ -10,7 +10,9 @@ export function registerOpenCommand(program: Command): void {
|
|
|
10
10
|
.action(
|
|
11
11
|
withErrorHandler(async (idOrName: unknown) => {
|
|
12
12
|
const project = await resolveProject(String(idOrName));
|
|
13
|
-
const url = project.url as string | undefined
|
|
13
|
+
const url = (project.url as string | undefined)
|
|
14
|
+
|| (project.domain ? `https://${project.domain}` : null)
|
|
15
|
+
|| (project.slug ? `https://${project.slug}.dailey.cloud` : null);
|
|
14
16
|
if (!url) {
|
|
15
17
|
console.error(chalk.red(`No URL found for project "${project.name}".`));
|
|
16
18
|
process.exit(1);
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
import chalk from 'chalk';
|
|
3
|
+
import ora from 'ora';
|
|
4
|
+
import { api } from '../api.js';
|
|
5
|
+
import { resolveProject, formatTable, handleJson, withErrorHandler } from '../util.js';
|
|
6
|
+
|
|
7
|
+
export function registerResourceCommands(program: Command): void {
|
|
8
|
+
const resources = program
|
|
9
|
+
.command('resources')
|
|
10
|
+
.description('Manage per-project resource allocation (CPU, memory, storage)');
|
|
11
|
+
|
|
12
|
+
resources
|
|
13
|
+
.command('get <idOrName>')
|
|
14
|
+
.description('Show current resource allocation for a project')
|
|
15
|
+
.option('--json', 'Output as JSON')
|
|
16
|
+
.action(
|
|
17
|
+
withErrorHandler(async (idOrName: unknown, opts: { json?: boolean }) => {
|
|
18
|
+
const project = await resolveProject(String(idOrName));
|
|
19
|
+
const spinner = ora('Loading resource config...').start();
|
|
20
|
+
const data = await api<any>(`/projects/${project.id}/resource-config`);
|
|
21
|
+
spinner.stop();
|
|
22
|
+
|
|
23
|
+
handleJson(opts.json, data);
|
|
24
|
+
|
|
25
|
+
console.log(chalk.bold(`\nResource Config: ${project.name}`));
|
|
26
|
+
console.log(chalk.blue('\n Project allocation:'));
|
|
27
|
+
console.log(` CPU request: ${data.project.cpu_request || chalk.gray('(default)')}`);
|
|
28
|
+
console.log(` CPU limit: ${data.project.cpu_limit || chalk.gray('(default)')}`);
|
|
29
|
+
console.log(` Memory request: ${data.project.memory_request || chalk.gray('(default)')}`);
|
|
30
|
+
console.log(` Memory limit: ${data.project.memory_limit || chalk.gray('(default)')}`);
|
|
31
|
+
console.log(` Storage limit: ${data.project.storage_limit || chalk.gray('(default)')}`);
|
|
32
|
+
console.log(` Replicas: ${data.project.replicas}`);
|
|
33
|
+
|
|
34
|
+
console.log(chalk.blue(`\n Pool (${data.pool.plan} plan):`));
|
|
35
|
+
console.log(` Total CPU: ${data.pool.total.cpu}`);
|
|
36
|
+
console.log(` Total Memory: ${data.pool.total.memory}`);
|
|
37
|
+
console.log(` Used CPU: ${data.pool.used.cpu}`);
|
|
38
|
+
console.log(` Used Memory: ${data.pool.used.memory}`);
|
|
39
|
+
console.log(` Available CPU: ${chalk.green(data.pool.available.cpu)}`);
|
|
40
|
+
console.log(` Available Mem: ${chalk.green(data.pool.available.memory)}`);
|
|
41
|
+
console.log(` This project: ${data.pool.used_by_this_project.cpu} CPU, ${data.pool.used_by_this_project.memory} memory`);
|
|
42
|
+
console.log();
|
|
43
|
+
}),
|
|
44
|
+
);
|
|
45
|
+
|
|
46
|
+
resources
|
|
47
|
+
.command('set <idOrName>')
|
|
48
|
+
.description('Set resource allocation for a project')
|
|
49
|
+
.option('--cpu <value>', 'CPU limit (e.g., 2000m, 4000m)')
|
|
50
|
+
.option('--memory <value>', 'Memory limit (e.g., 2Gi, 8Gi)')
|
|
51
|
+
.option('--storage <value>', 'Storage limit (e.g., 5Gi, 10Gi)')
|
|
52
|
+
.option('--json', 'Output as JSON')
|
|
53
|
+
.action(
|
|
54
|
+
withErrorHandler(async (idOrName: unknown, opts: { cpu?: string; memory?: string; storage?: string; json?: boolean }) => {
|
|
55
|
+
if (!opts.cpu && !opts.memory && !opts.storage) {
|
|
56
|
+
console.error(chalk.red('Provide at least one of: --cpu, --memory, --storage'));
|
|
57
|
+
process.exit(1);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
const project = await resolveProject(String(idOrName));
|
|
61
|
+
const body: Record<string, string> = {};
|
|
62
|
+
if (opts.cpu) body.cpu_limit = opts.cpu;
|
|
63
|
+
if (opts.memory) body.memory_limit = opts.memory;
|
|
64
|
+
if (opts.storage) body.storage_limit = opts.storage;
|
|
65
|
+
|
|
66
|
+
const spinner = ora(`Updating resources for "${project.name}"...`).start();
|
|
67
|
+
const data = await api<any>(`/projects/${project.id}/resource-config`, {
|
|
68
|
+
method: 'PUT',
|
|
69
|
+
body,
|
|
70
|
+
});
|
|
71
|
+
spinner.succeed(chalk.green(`Resources updated for "${project.name}".`));
|
|
72
|
+
|
|
73
|
+
handleJson(opts.json, data);
|
|
74
|
+
|
|
75
|
+
if (data.warning) {
|
|
76
|
+
console.log(chalk.yellow(` Warning: ${data.warning}`));
|
|
77
|
+
}
|
|
78
|
+
if (data.k8s_applied) {
|
|
79
|
+
console.log(chalk.gray(' Applied to running deployment.'));
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
console.log(` CPU: ${data.project.cpu_request || '-'} / ${data.project.cpu_limit || '-'}`);
|
|
83
|
+
console.log(` Memory: ${data.project.memory_request || '-'} / ${data.project.memory_limit || '-'}`);
|
|
84
|
+
console.log(` Storage: ${data.project.storage_limit || '-'}`);
|
|
85
|
+
}),
|
|
86
|
+
);
|
|
87
|
+
|
|
88
|
+
resources
|
|
89
|
+
.command('pool')
|
|
90
|
+
.description('Show total resource pool and usage across all projects')
|
|
91
|
+
.option('--json', 'Output as JSON')
|
|
92
|
+
.action(
|
|
93
|
+
withErrorHandler(async (opts: { json?: boolean }) => {
|
|
94
|
+
const spinner = ora('Loading projects...').start();
|
|
95
|
+
const { projects } = await api<{ projects: any[] }>('/projects');
|
|
96
|
+
|
|
97
|
+
if (projects.length === 0) {
|
|
98
|
+
spinner.stop();
|
|
99
|
+
console.log(chalk.gray('No projects found.'));
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// Fetch resource config for each project
|
|
104
|
+
const configs = await Promise.all(
|
|
105
|
+
projects.map(async (p: any) => {
|
|
106
|
+
try {
|
|
107
|
+
const cfg = await api<any>(`/projects/${p.id}/resource-config`);
|
|
108
|
+
return { name: p.name, slug: p.slug, ...cfg };
|
|
109
|
+
} catch {
|
|
110
|
+
return { name: p.name, slug: p.slug, project: {}, pool: null };
|
|
111
|
+
}
|
|
112
|
+
}),
|
|
113
|
+
);
|
|
114
|
+
spinner.stop();
|
|
115
|
+
|
|
116
|
+
// Use the pool info from the first successful response
|
|
117
|
+
const poolInfo = configs.find((c: any) => c.pool)?.pool;
|
|
118
|
+
|
|
119
|
+
handleJson(opts.json, { pool: poolInfo, projects: configs });
|
|
120
|
+
|
|
121
|
+
if (poolInfo) {
|
|
122
|
+
console.log(chalk.bold(`\nResource Pool (${poolInfo.plan} plan)`));
|
|
123
|
+
console.log(` Total: ${poolInfo.total.cpu} CPU | ${poolInfo.total.memory} memory | ${poolInfo.total.storage} storage`);
|
|
124
|
+
console.log(` Used: ${poolInfo.used.cpu} CPU | ${poolInfo.used.memory} memory`);
|
|
125
|
+
console.log(` Available: ${chalk.green(poolInfo.available.cpu)} CPU | ${chalk.green(poolInfo.available.memory)} memory`);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
console.log(chalk.bold('\nPer-project allocation:'));
|
|
129
|
+
const rows = configs.map((c: any) => ({
|
|
130
|
+
name: c.name || c.slug,
|
|
131
|
+
cpu_limit: c.project?.cpu_limit || '(default)',
|
|
132
|
+
memory_limit: c.project?.memory_limit || '(default)',
|
|
133
|
+
storage_limit: c.project?.storage_limit || '(default)',
|
|
134
|
+
}));
|
|
135
|
+
|
|
136
|
+
console.log(
|
|
137
|
+
formatTable(rows, [
|
|
138
|
+
{ key: 'name', label: 'PROJECT' },
|
|
139
|
+
{ key: 'cpu_limit', label: 'CPU LIMIT' },
|
|
140
|
+
{ key: 'memory_limit', label: 'MEM LIMIT' },
|
|
141
|
+
{ key: 'storage_limit', label: 'STORAGE' },
|
|
142
|
+
]),
|
|
143
|
+
);
|
|
144
|
+
console.log();
|
|
145
|
+
}),
|
|
146
|
+
);
|
|
147
|
+
}
|
package/src/commands/scale.ts
CHANGED
|
@@ -26,6 +26,55 @@ export function registerScaleCommands(program: Command): void {
|
|
|
26
26
|
}),
|
|
27
27
|
);
|
|
28
28
|
|
|
29
|
+
program
|
|
30
|
+
.command('stop <idOrName>')
|
|
31
|
+
.description('Stop an app (scale to 0 replicas)')
|
|
32
|
+
.action(
|
|
33
|
+
withErrorHandler(async (idOrName: unknown) => {
|
|
34
|
+
const project = await resolveProject(String(idOrName));
|
|
35
|
+
const spinner = ora(`Stopping "${project.name}"...`).start();
|
|
36
|
+
await api(`/projects/${project.id}/scale`, {
|
|
37
|
+
method: 'POST',
|
|
38
|
+
body: { replicas: 0 },
|
|
39
|
+
});
|
|
40
|
+
spinner.succeed(chalk.green(`Stopped "${project.name}" — scaled to 0 replicas.`));
|
|
41
|
+
console.log(chalk.gray(` Start again: ${chalk.white(`dailey start ${String(idOrName)}`)}`));
|
|
42
|
+
}),
|
|
43
|
+
);
|
|
44
|
+
|
|
45
|
+
program
|
|
46
|
+
.command('start <idOrName>')
|
|
47
|
+
.description('Start an app (scale to 1 replica)')
|
|
48
|
+
.option('-r, --replicas <n>', 'Number of replicas to start with', '1')
|
|
49
|
+
.action(
|
|
50
|
+
withErrorHandler(async (idOrName: unknown, opts: { replicas: string }) => {
|
|
51
|
+
const project = await resolveProject(String(idOrName));
|
|
52
|
+
const count = parseInt(opts.replicas, 10) || 1;
|
|
53
|
+
const spinner = ora(`Starting "${project.name}" with ${count} replica${count > 1 ? 's' : ''}...`).start();
|
|
54
|
+
await api(`/projects/${project.id}/scale`, {
|
|
55
|
+
method: 'POST',
|
|
56
|
+
body: { replicas: count },
|
|
57
|
+
});
|
|
58
|
+
spinner.succeed(chalk.green(`Started "${project.name}" with ${count} replica${count > 1 ? 's' : ''}.`));
|
|
59
|
+
console.log(chalk.gray(` View: ${chalk.white(`https://${project.slug}.dailey.cloud`)}`));
|
|
60
|
+
}),
|
|
61
|
+
);
|
|
62
|
+
|
|
63
|
+
program
|
|
64
|
+
.command('restart <idOrName>')
|
|
65
|
+
.description('Restart an app (rolling restart, no downtime)')
|
|
66
|
+
.action(
|
|
67
|
+
withErrorHandler(async (idOrName: unknown) => {
|
|
68
|
+
const project = await resolveProject(String(idOrName));
|
|
69
|
+
const spinner = ora(`Restarting "${project.name}"...`).start();
|
|
70
|
+
// Scale to 0 then back to current replicas
|
|
71
|
+
const replicas = Number(project.replicas) || 1;
|
|
72
|
+
await api(`/projects/${project.id}/scale`, { method: 'POST', body: { replicas: 0 } });
|
|
73
|
+
await api(`/projects/${project.id}/scale`, { method: 'POST', body: { replicas } });
|
|
74
|
+
spinner.succeed(chalk.green(`Restarted "${project.name}" with ${replicas} replica${replicas > 1 ? 's' : ''}.`));
|
|
75
|
+
}),
|
|
76
|
+
);
|
|
77
|
+
|
|
29
78
|
program
|
|
30
79
|
.command('status <idOrName>')
|
|
31
80
|
.description('Show app status (pods, replicas, health)')
|