@relesio/cli 0.2.6

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 (75) hide show
  1. package/README.md +224 -0
  2. package/bin/relesio.js +4 -0
  3. package/dist/commands/auth/index.d.ts +2 -0
  4. package/dist/commands/auth/index.js +9 -0
  5. package/dist/commands/auth/login.d.ts +2 -0
  6. package/dist/commands/auth/login.js +82 -0
  7. package/dist/commands/auth/logout.d.ts +2 -0
  8. package/dist/commands/auth/logout.js +25 -0
  9. package/dist/commands/auth/status.d.ts +2 -0
  10. package/dist/commands/auth/status.js +35 -0
  11. package/dist/commands/deploy.d.ts +2 -0
  12. package/dist/commands/deploy.js +293 -0
  13. package/dist/commands/organizations/index.d.ts +2 -0
  14. package/dist/commands/organizations/index.js +8 -0
  15. package/dist/commands/organizations/list.d.ts +2 -0
  16. package/dist/commands/organizations/list.js +54 -0
  17. package/dist/commands/organizations/set.d.ts +2 -0
  18. package/dist/commands/organizations/set.js +34 -0
  19. package/dist/commands/projects/index.d.ts +2 -0
  20. package/dist/commands/projects/index.js +6 -0
  21. package/dist/commands/projects/list.d.ts +2 -0
  22. package/dist/commands/projects/list.js +49 -0
  23. package/dist/commands/rollback.d.ts +2 -0
  24. package/dist/commands/rollback.js +119 -0
  25. package/dist/commands/status.d.ts +2 -0
  26. package/dist/commands/status.js +59 -0
  27. package/dist/commands/team/get.d.ts +2 -0
  28. package/dist/commands/team/get.js +34 -0
  29. package/dist/commands/team/index.d.ts +2 -0
  30. package/dist/commands/team/index.js +7 -0
  31. package/dist/commands/team/list.d.ts +2 -0
  32. package/dist/commands/team/list.js +46 -0
  33. package/dist/commands/upload.d.ts +2 -0
  34. package/dist/commands/upload.js +365 -0
  35. package/dist/commands/versions/index.d.ts +2 -0
  36. package/dist/commands/versions/index.js +6 -0
  37. package/dist/commands/versions/list.d.ts +2 -0
  38. package/dist/commands/versions/list.js +51 -0
  39. package/dist/commands/whoami.d.ts +2 -0
  40. package/dist/commands/whoami.js +52 -0
  41. package/dist/index.d.ts +2 -0
  42. package/dist/index.js +90 -0
  43. package/dist/lib/api/client.d.ts +32 -0
  44. package/dist/lib/api/client.js +187 -0
  45. package/dist/lib/api/deployments.d.ts +122 -0
  46. package/dist/lib/api/deployments.js +55 -0
  47. package/dist/lib/api/organizations.d.ts +27 -0
  48. package/dist/lib/api/organizations.js +37 -0
  49. package/dist/lib/api/projects.d.ts +38 -0
  50. package/dist/lib/api/projects.js +34 -0
  51. package/dist/lib/api/teams.d.ts +15 -0
  52. package/dist/lib/api/teams.js +44 -0
  53. package/dist/lib/api/types.d.ts +89 -0
  54. package/dist/lib/api/types.js +2 -0
  55. package/dist/lib/api/versions.d.ts +140 -0
  56. package/dist/lib/api/versions.js +53 -0
  57. package/dist/lib/config/manager.d.ts +35 -0
  58. package/dist/lib/config/manager.js +78 -0
  59. package/dist/lib/config/types.d.ts +15 -0
  60. package/dist/lib/config/types.js +15 -0
  61. package/dist/lib/errors/handler.d.ts +1 -0
  62. package/dist/lib/errors/handler.js +75 -0
  63. package/dist/lib/errors/types.d.ts +19 -0
  64. package/dist/lib/errors/types.js +34 -0
  65. package/dist/lib/files/scanner.d.ts +23 -0
  66. package/dist/lib/files/scanner.js +81 -0
  67. package/dist/lib/git/metadata.d.ts +31 -0
  68. package/dist/lib/git/metadata.js +90 -0
  69. package/dist/lib/output/colors.d.ts +14 -0
  70. package/dist/lib/output/colors.js +23 -0
  71. package/dist/lib/output/formatter.d.ts +2 -0
  72. package/dist/lib/output/formatter.js +7 -0
  73. package/dist/lib/output/table.d.ts +7 -0
  74. package/dist/lib/output/table.js +64 -0
  75. package/package.json +58 -0
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Git metadata collected from the repository
3
+ */
4
+ export interface GitMetadata {
5
+ sha?: string;
6
+ branch?: string;
7
+ commitMessage?: string;
8
+ author?: string;
9
+ tag?: string;
10
+ isDirty: boolean;
11
+ remoteUrl?: string;
12
+ }
13
+ /**
14
+ * Collect git metadata from the current repository
15
+ * Automatically called during upload to track version provenance
16
+ *
17
+ * @returns Git metadata or empty object if not in a git repository
18
+ */
19
+ export declare function collectGitMetadata(): Promise<GitMetadata>;
20
+ /**
21
+ * Validate git state before deployment
22
+ *
23
+ * @param metadata - Git metadata
24
+ * @param requireClean - Whether to require clean working directory
25
+ * @throws Error if validation fails
26
+ */
27
+ export declare function validateGitState(metadata: GitMetadata, requireClean?: boolean): void;
28
+ /**
29
+ * Format git metadata for display
30
+ */
31
+ export declare function formatGitMetadata(metadata: GitMetadata): string;
@@ -0,0 +1,90 @@
1
+ import { execSync } from "node:child_process";
2
+ /**
3
+ * Collect git metadata from the current repository
4
+ * Automatically called during upload to track version provenance
5
+ *
6
+ * @returns Git metadata or empty object if not in a git repository
7
+ */
8
+ export async function collectGitMetadata() {
9
+ try {
10
+ // Check if in git repository
11
+ execSync("git rev-parse --git-dir", { stdio: "pipe" });
12
+ const sha = execSync("git rev-parse HEAD", { encoding: "utf8" }).trim();
13
+ const branch = execSync("git rev-parse --abbrev-ref HEAD", {
14
+ encoding: "utf8"
15
+ }).trim();
16
+ const commitMessage = execSync("git log -1 --pretty=%B", {
17
+ encoding: "utf8"
18
+ }).trim();
19
+ const author = execSync('git log -1 --pretty=format:"%an <%ae>"', {
20
+ encoding: "utf8"
21
+ }).trim();
22
+ // Check for tag on current commit
23
+ let tag;
24
+ try {
25
+ tag = execSync("git describe --exact-match --tags HEAD", {
26
+ encoding: "utf8",
27
+ stdio: "pipe"
28
+ }).trim();
29
+ }
30
+ catch {
31
+ // No tag on current commit
32
+ }
33
+ // Check if working directory is dirty
34
+ const status = execSync("git status --porcelain", { encoding: "utf8" });
35
+ const isDirty = status.trim().length > 0;
36
+ let remoteUrl;
37
+ try {
38
+ remoteUrl = execSync("git config --get remote.origin.url", {
39
+ encoding: "utf8"
40
+ }).trim();
41
+ // Sanitize credentials from URL
42
+ remoteUrl = remoteUrl.replace(/\/\/[^@]+@/, "//");
43
+ }
44
+ catch {
45
+ // No remote configured
46
+ }
47
+ return { sha, branch, commitMessage, author, tag, isDirty, remoteUrl };
48
+ }
49
+ catch (_error) {
50
+ // Not a git repository or git not available
51
+ return { isDirty: false };
52
+ }
53
+ }
54
+ /**
55
+ * Validate git state before deployment
56
+ *
57
+ * @param metadata - Git metadata
58
+ * @param requireClean - Whether to require clean working directory
59
+ * @throws Error if validation fails
60
+ */
61
+ export function validateGitState(metadata, requireClean = false) {
62
+ if (requireClean && metadata.isDirty) {
63
+ throw new Error("Working directory has uncommitted changes. Commit or stash changes before deploying.");
64
+ }
65
+ if (!metadata.sha) {
66
+ console.warn("⚠️ Not in a git repository. Version tracking will be limited.");
67
+ }
68
+ }
69
+ /**
70
+ * Format git metadata for display
71
+ */
72
+ export function formatGitMetadata(metadata) {
73
+ const lines = [];
74
+ if (metadata.sha) {
75
+ lines.push(` Commit: ${metadata.sha.substring(0, 7)}`);
76
+ }
77
+ if (metadata.branch) {
78
+ lines.push(` Branch: ${metadata.branch}`);
79
+ }
80
+ if (metadata.tag) {
81
+ lines.push(` Tag: ${metadata.tag}`);
82
+ }
83
+ if (metadata.author) {
84
+ lines.push(` Author: ${metadata.author}`);
85
+ }
86
+ if (metadata.isDirty) {
87
+ lines.push(` Status: ⚠️ Uncommitted changes`);
88
+ }
89
+ return lines.join("\n");
90
+ }
@@ -0,0 +1,14 @@
1
+ export declare const colors: {
2
+ success: import("chalk").ChalkInstance;
3
+ error: import("chalk").ChalkInstance;
4
+ warning: import("chalk").ChalkInstance;
5
+ info: import("chalk").ChalkInstance;
6
+ dim: import("chalk").ChalkInstance;
7
+ bold: import("chalk").ChalkInstance;
8
+ highlight: import("chalk").ChalkInstance;
9
+ primary: import("chalk").ChalkInstance;
10
+ };
11
+ export declare function formatSuccess(message: string): string;
12
+ export declare function formatError(message: string): string;
13
+ export declare function formatWarning(message: string): string;
14
+ export declare function formatInfo(message: string): string;
@@ -0,0 +1,23 @@
1
+ import chalk from "chalk";
2
+ export const colors = {
3
+ success: chalk.green,
4
+ error: chalk.red,
5
+ warning: chalk.yellow,
6
+ info: chalk.blue,
7
+ dim: chalk.dim,
8
+ bold: chalk.bold,
9
+ highlight: chalk.cyan,
10
+ primary: chalk.magenta
11
+ };
12
+ export function formatSuccess(message) {
13
+ return colors.success(`✓ ${message}`);
14
+ }
15
+ export function formatError(message) {
16
+ return colors.error(`✗ ${message}`);
17
+ }
18
+ export function formatWarning(message) {
19
+ return colors.warning(`⚠ ${message}`);
20
+ }
21
+ export function formatInfo(message) {
22
+ return colors.info(`ℹ ${message}`);
23
+ }
@@ -0,0 +1,2 @@
1
+ export declare function outputJSON(data: unknown): void;
2
+ export declare function shouldOutputJSON(): boolean;
@@ -0,0 +1,7 @@
1
+ import { ConfigManager } from "../config/manager.js";
2
+ export function outputJSON(data) {
3
+ console.log(JSON.stringify(data, null, 2));
4
+ }
5
+ export function shouldOutputJSON() {
6
+ return ConfigManager.get("output") === "json";
7
+ }
@@ -0,0 +1,7 @@
1
+ import Table from "cli-table3";
2
+ import type { Team, Organization } from "../api/types.js";
3
+ export declare function createTable(head: string[], options?: Record<string, unknown>): Table.Table;
4
+ export declare function renderOrganizationsTable(orgs: Organization[]): void;
5
+ export declare function renderTeamsTable(teams: Team[]): void;
6
+ export declare function renderTeamDetails(team: Team): void;
7
+ export declare function formatTable(headers: string[], rows: string[][]): string;
@@ -0,0 +1,64 @@
1
+ import Table from "cli-table3";
2
+ import chalk from "chalk";
3
+ export function createTable(head, options) {
4
+ return new Table({
5
+ head: head.map((h) => chalk.cyan(h)),
6
+ style: {
7
+ head: [],
8
+ border: ["dim"]
9
+ },
10
+ ...options
11
+ });
12
+ }
13
+ export function renderOrganizationsTable(orgs) {
14
+ if (orgs.length === 0) {
15
+ console.log(chalk.dim("No organizations found"));
16
+ return;
17
+ }
18
+ const table = createTable(["ID", "Name", "Slug", "Members"]);
19
+ for (const org of orgs) {
20
+ table.push([
21
+ chalk.dim(org.id),
22
+ chalk.bold(org.name),
23
+ org.slug || chalk.dim("(none)"),
24
+ org.membersCount?.toString() || chalk.dim("0")
25
+ ]);
26
+ }
27
+ console.log(table.toString());
28
+ console.log(chalk.dim(`\nTotal: ${orgs.length} organization${orgs.length !== 1 ? "s" : ""}`));
29
+ }
30
+ export function renderTeamsTable(teams) {
31
+ if (teams.length === 0) {
32
+ console.log(chalk.dim("No teams found"));
33
+ return;
34
+ }
35
+ const table = createTable(["ID", "Name", "Description", "Members"]);
36
+ for (const team of teams) {
37
+ table.push([
38
+ chalk.dim(`${team.id.substring(0, 8)}...`),
39
+ chalk.bold(team.name),
40
+ team.description || chalk.dim("(no description)"),
41
+ team.memberCount?.toString() || chalk.dim("0")
42
+ ]);
43
+ }
44
+ console.log(table.toString());
45
+ console.log(chalk.dim(`\nTotal: ${teams.length} team${teams.length !== 1 ? "s" : ""}`));
46
+ }
47
+ export function renderTeamDetails(team) {
48
+ console.log(chalk.bold("\nTeam Details"));
49
+ console.log(chalk.dim("─".repeat(50)));
50
+ console.log(`${chalk.cyan("ID:")} ${chalk.dim(team.id)}`);
51
+ console.log(`${chalk.cyan("Name:")} ${chalk.bold(team.name)}`);
52
+ console.log(`${chalk.cyan("Description:")} ${team.description || chalk.dim("(no description)")}`);
53
+ console.log(`${chalk.cyan("Members:")} ${team.memberCount || 0}`);
54
+ console.log(`${chalk.cyan("Organization:")} ${chalk.dim(team.organizationId)}`);
55
+ console.log(`${chalk.cyan("Created:")} ${chalk.dim(new Date(team.createdAt).toLocaleString())}`);
56
+ console.log(`${chalk.cyan("Updated:")} ${chalk.dim(new Date(team.updatedAt).toLocaleString())}`);
57
+ }
58
+ export function formatTable(headers, rows) {
59
+ const table = createTable(headers);
60
+ for (const row of rows) {
61
+ table.push(row);
62
+ }
63
+ return table.toString();
64
+ }
package/package.json ADDED
@@ -0,0 +1,58 @@
1
+ {
2
+ "name": "@relesio/cli",
3
+ "version": "0.2.6",
4
+ "description": "CLI tool for Relesio - Modern Micro-Frontend Hosting",
5
+ "private": false,
6
+ "type": "module",
7
+ "bin": {
8
+ "relesio": "./bin/relesio.js"
9
+ },
10
+ "files": [
11
+ "dist",
12
+ "bin"
13
+ ],
14
+ "scripts": {
15
+ "dev": "bun src/index.ts",
16
+ "build": "tsc -p tsconfig.build.json",
17
+ "type-check": "tsc --noEmit",
18
+ "lint": "biome lint --write .",
19
+ "format": "biome format --write .",
20
+ "format:check": "biome format .",
21
+ "test": "echo 'No tests yet'",
22
+ "clean": "rm -rf dist"
23
+ },
24
+ "dependencies": {
25
+ "chalk": "^5.3.0",
26
+ "cli-table3": "^0.6.5",
27
+ "commander": "^12.1.0",
28
+ "conf": "^13.0.1",
29
+ "inquirer": "^10.2.2",
30
+ "mime-types": "^2.1.35",
31
+ "ora": "^8.1.2",
32
+ "undici": "^6.0.0",
33
+ "zod": "^3.23.8"
34
+ },
35
+ "devDependencies": {
36
+ "@biomejs/biome": "2.3.10",
37
+ "@types/inquirer": "^9.0.7",
38
+ "@types/mime-types": "^2.1.4",
39
+ "@types/node": "^22.10.6",
40
+ "typescript": "^5.7.3"
41
+ },
42
+ "engines": {
43
+ "node": ">=18.0.0"
44
+ },
45
+ "publishConfig": {
46
+ "access": "public"
47
+ },
48
+ "repository": {
49
+ "type": "git",
50
+ "url": "https://github.com/relesio/relesio.git",
51
+ "directory": "api/apps/cli"
52
+ },
53
+ "homepage": "https://relesio.io",
54
+ "bugs": {
55
+ "url": "https://github.com/relesio/relesio/issues"
56
+ },
57
+ "license": "MIT"
58
+ }