replicas-cli 0.1.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.
Files changed (66) hide show
  1. package/README.md +93 -0
  2. package/dist/commands/connect.d.ts +4 -0
  3. package/dist/commands/connect.d.ts.map +1 -0
  4. package/dist/commands/connect.js +145 -0
  5. package/dist/commands/connect.js.map +1 -0
  6. package/dist/commands/login.d.ts +2 -0
  7. package/dist/commands/login.d.ts.map +1 -0
  8. package/dist/commands/login.js +149 -0
  9. package/dist/commands/login.js.map +1 -0
  10. package/dist/commands/logout.d.ts +2 -0
  11. package/dist/commands/logout.d.ts.map +1 -0
  12. package/dist/commands/logout.js +17 -0
  13. package/dist/commands/logout.js.map +1 -0
  14. package/dist/commands/org.d.ts +3 -0
  15. package/dist/commands/org.d.ts.map +1 -0
  16. package/dist/commands/org.js +83 -0
  17. package/dist/commands/org.js.map +1 -0
  18. package/dist/commands/whoami.d.ts +2 -0
  19. package/dist/commands/whoami.d.ts.map +1 -0
  20. package/dist/commands/whoami.js +31 -0
  21. package/dist/commands/whoami.js.map +1 -0
  22. package/dist/index.d.ts +3 -0
  23. package/dist/index.d.ts.map +1 -0
  24. package/dist/index.js +109 -0
  25. package/dist/index.js.map +1 -0
  26. package/dist/lib/api.d.ts +7 -0
  27. package/dist/lib/api.d.ts.map +1 -0
  28. package/dist/lib/api.js +52 -0
  29. package/dist/lib/api.js.map +1 -0
  30. package/dist/lib/auth.d.ts +4 -0
  31. package/dist/lib/auth.d.ts.map +1 -0
  32. package/dist/lib/auth.js +61 -0
  33. package/dist/lib/auth.js.map +1 -0
  34. package/dist/lib/config.d.ts +10 -0
  35. package/dist/lib/config.d.ts.map +1 -0
  36. package/dist/lib/config.js +70 -0
  37. package/dist/lib/config.js.map +1 -0
  38. package/dist/lib/git.d.ts +4 -0
  39. package/dist/lib/git.d.ts.map +1 -0
  40. package/dist/lib/git.js +39 -0
  41. package/dist/lib/git.js.map +1 -0
  42. package/dist/lib/organization.d.ts +5 -0
  43. package/dist/lib/organization.d.ts.map +1 -0
  44. package/dist/lib/organization.js +29 -0
  45. package/dist/lib/organization.js.map +1 -0
  46. package/dist/lib/ports.d.ts +3 -0
  47. package/dist/lib/ports.d.ts.map +1 -0
  48. package/dist/lib/ports.js +44 -0
  49. package/dist/lib/ports.js.map +1 -0
  50. package/dist/lib/replicas-config.d.ts +8 -0
  51. package/dist/lib/replicas-config.d.ts.map +1 -0
  52. package/dist/lib/replicas-config.js +58 -0
  53. package/dist/lib/replicas-config.js.map +1 -0
  54. package/dist/lib/ssh.d.ts +5 -0
  55. package/dist/lib/ssh.d.ts.map +1 -0
  56. package/dist/lib/ssh.js +82 -0
  57. package/dist/lib/ssh.js.map +1 -0
  58. package/dist/lib/supabase.d.ts +5 -0
  59. package/dist/lib/supabase.d.ts.map +1 -0
  60. package/dist/lib/supabase.js +15 -0
  61. package/dist/lib/supabase.js.map +1 -0
  62. package/dist/types/index.d.ts +44 -0
  63. package/dist/types/index.d.ts.map +1 -0
  64. package/dist/types/index.js +3 -0
  65. package/dist/types/index.js.map +1 -0
  66. package/package.json +50 -0
package/dist/index.js ADDED
@@ -0,0 +1,109 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ var __importDefault = (this && this.__importDefault) || function (mod) {
4
+ return (mod && mod.__esModule) ? mod : { "default": mod };
5
+ };
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ require("dotenv/config");
8
+ const commander_1 = require("commander");
9
+ const chalk_1 = __importDefault(require("chalk"));
10
+ const login_1 = require("./commands/login");
11
+ const logout_1 = require("./commands/logout");
12
+ const whoami_1 = require("./commands/whoami");
13
+ const connect_1 = require("./commands/connect");
14
+ const org_1 = require("./commands/org");
15
+ const program = new commander_1.Command();
16
+ program
17
+ .name('replicas')
18
+ .description('CLI for managing Replicas workspaces')
19
+ .version('0.1.0');
20
+ program
21
+ .command('login')
22
+ .description('Authenticate with your Replicas account')
23
+ .action(async () => {
24
+ try {
25
+ await (0, login_1.loginCommand)();
26
+ }
27
+ catch (error) {
28
+ if (error instanceof Error) {
29
+ console.error(chalk_1.default.red(`\n✗ ${error.message}\n`));
30
+ }
31
+ process.exit(1);
32
+ }
33
+ });
34
+ program
35
+ .command('logout')
36
+ .description('Clear stored credentials')
37
+ .action(() => {
38
+ try {
39
+ (0, logout_1.logoutCommand)();
40
+ }
41
+ catch (error) {
42
+ if (error instanceof Error) {
43
+ console.error(chalk_1.default.red(`\n✗ ${error.message}\n`));
44
+ }
45
+ process.exit(1);
46
+ }
47
+ });
48
+ program
49
+ .command('whoami')
50
+ .description('Display current authenticated user')
51
+ .action(async () => {
52
+ try {
53
+ await (0, whoami_1.whoamiCommand)();
54
+ }
55
+ catch (error) {
56
+ if (error instanceof Error) {
57
+ console.error(chalk_1.default.red(`\n✗ ${error.message}\n`));
58
+ }
59
+ process.exit(1);
60
+ }
61
+ });
62
+ // Organization commands
63
+ const org = program
64
+ .command('org')
65
+ .description('Manage organizations');
66
+ org
67
+ .command('switch')
68
+ .description('Switch to a different organization')
69
+ .action(async () => {
70
+ try {
71
+ await (0, org_1.orgSwitchCommand)();
72
+ }
73
+ catch (error) {
74
+ if (error instanceof Error) {
75
+ console.error(chalk_1.default.red(`\n✗ ${error.message}\n`));
76
+ }
77
+ process.exit(1);
78
+ }
79
+ });
80
+ // Default action for 'org' command (show current org)
81
+ org.action(async () => {
82
+ try {
83
+ await (0, org_1.orgCommand)();
84
+ }
85
+ catch (error) {
86
+ if (error instanceof Error) {
87
+ console.error(chalk_1.default.red(`\n✗ ${error.message}\n`));
88
+ }
89
+ process.exit(1);
90
+ }
91
+ });
92
+ // Connect command
93
+ program
94
+ .command('connect <workspace-name>')
95
+ .description('Connect to a workspace via SSH')
96
+ .option('-c, --copy', 'Copy files from replicas.json to the workspace')
97
+ .action(async (workspaceName, options) => {
98
+ try {
99
+ await (0, connect_1.connectCommand)(workspaceName, options);
100
+ }
101
+ catch (error) {
102
+ if (error instanceof Error) {
103
+ console.error(chalk_1.default.red(`\n✗ ${error.message}\n`));
104
+ }
105
+ process.exit(1);
106
+ }
107
+ });
108
+ program.parse();
109
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ interface FetchOptions extends Omit<RequestInit, 'body'> {
2
+ body?: unknown;
3
+ }
4
+ export declare function authenticatedFetch<T = unknown>(url: string, options?: FetchOptions): Promise<T>;
5
+ export declare function orgAuthenticatedFetch<T = unknown>(url: string, options?: FetchOptions): Promise<T>;
6
+ export {};
7
+ //# sourceMappingURL=api.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../src/lib/api.ts"],"names":[],"mappings":"AAKA,UAAU,YAAa,SAAQ,IAAI,CAAC,WAAW,EAAE,MAAM,CAAC;IACtD,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED,wBAAsB,kBAAkB,CAAC,CAAC,GAAG,OAAO,EAClD,GAAG,EAAE,MAAM,EACX,OAAO,CAAC,EAAE,YAAY,GACrB,OAAO,CAAC,CAAC,CAAC,CAyBZ;AAED,wBAAsB,qBAAqB,CAAC,CAAC,GAAG,OAAO,EACrD,GAAG,EAAE,MAAM,EACX,OAAO,CAAC,EAAE,YAAY,GACrB,OAAO,CAAC,CAAC,CAAC,CA6BZ"}
@@ -0,0 +1,52 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.authenticatedFetch = authenticatedFetch;
4
+ exports.orgAuthenticatedFetch = orgAuthenticatedFetch;
5
+ const auth_1 = require("./auth");
6
+ const config_1 = require("./config");
7
+ const WEB_APP_URL = process.env.REPLICAS_WEB_URL || 'https://replicas.dev';
8
+ async function authenticatedFetch(url, options) {
9
+ const token = await (0, auth_1.getValidToken)();
10
+ if (!token) {
11
+ throw new Error('No access token available');
12
+ }
13
+ const headers = {
14
+ 'Authorization': `Bearer ${token}`,
15
+ 'Content-Type': 'application/json',
16
+ ...(options?.headers || {}),
17
+ };
18
+ const response = await fetch(`${WEB_APP_URL}${url}`, {
19
+ ...options,
20
+ headers,
21
+ body: options?.body ? JSON.stringify(options.body) : undefined,
22
+ });
23
+ if (!response.ok) {
24
+ const error = await response.json().catch(() => ({ error: 'Request failed' }));
25
+ throw new Error(error.error || `Request failed with status ${response.status}`);
26
+ }
27
+ return response.json();
28
+ }
29
+ async function orgAuthenticatedFetch(url, options) {
30
+ const token = await (0, auth_1.getValidToken)();
31
+ const organizationId = (0, config_1.getOrganizationId)();
32
+ if (!organizationId) {
33
+ throw new Error('No organization selected. Please run "replicas org switch" to select an organization.');
34
+ }
35
+ const headers = {
36
+ 'Authorization': `Bearer ${token}`,
37
+ 'Replicas-Org-Id': organizationId,
38
+ 'Content-Type': 'application/json',
39
+ ...(options?.headers || {}),
40
+ };
41
+ const response = await fetch(`${WEB_APP_URL}${url}`, {
42
+ ...options,
43
+ headers,
44
+ body: options?.body ? JSON.stringify(options.body) : undefined,
45
+ });
46
+ if (!response.ok) {
47
+ const error = await response.json().catch(() => ({ error: 'Request failed' }));
48
+ throw new Error(error.error || `Request failed with status ${response.status}`);
49
+ }
50
+ return response.json();
51
+ }
52
+ //# sourceMappingURL=api.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api.js","sourceRoot":"","sources":["../../src/lib/api.ts"],"names":[],"mappings":";;AASA,gDA4BC;AAED,sDAgCC;AAvED,iCAAuC;AACvC,qCAA6C;AAE7C,MAAM,WAAW,GAAG,OAAO,CAAC,GAAG,CAAC,gBAAgB,IAAI,sBAAsB,CAAC;AAMpE,KAAK,UAAU,kBAAkB,CACtC,GAAW,EACX,OAAsB;IAEtB,MAAM,KAAK,GAAG,MAAM,IAAA,oBAAa,GAAE,CAAC;IAEpC,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,MAAM,IAAI,KAAK,CAAC,2BAA2B,CAAC,CAAC;IAC/C,CAAC;IAED,MAAM,OAAO,GAA2B;QACtC,eAAe,EAAE,UAAU,KAAK,EAAE;QAClC,cAAc,EAAE,kBAAkB;QAClC,GAAG,CAAC,OAAO,EAAE,OAAiC,IAAI,EAAE,CAAC;KACtD,CAAC;IAEF,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,WAAW,GAAG,GAAG,EAAE,EAAE;QACnD,GAAG,OAAO;QACV,OAAO;QACP,IAAI,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS;KAC/D,CAAC,CAAC;IAEH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;QACjB,MAAM,KAAK,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,gBAAgB,EAAE,CAAC,CAAuB,CAAC;QACrG,MAAM,IAAI,KAAK,CAAC,KAAK,CAAC,KAAK,IAAI,8BAA8B,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;IAClF,CAAC;IAED,OAAO,QAAQ,CAAC,IAAI,EAAgB,CAAC;AACvC,CAAC;AAEM,KAAK,UAAU,qBAAqB,CACzC,GAAW,EACX,OAAsB;IAEtB,MAAM,KAAK,GAAG,MAAM,IAAA,oBAAa,GAAE,CAAC;IACpC,MAAM,cAAc,GAAG,IAAA,0BAAiB,GAAE,CAAC;IAE3C,IAAI,CAAC,cAAc,EAAE,CAAC;QACpB,MAAM,IAAI,KAAK,CACb,uFAAuF,CACxF,CAAC;IACJ,CAAC;IAED,MAAM,OAAO,GAA2B;QACtC,eAAe,EAAE,UAAU,KAAK,EAAE;QAClC,iBAAiB,EAAE,cAAc;QACjC,cAAc,EAAE,kBAAkB;QAClC,GAAG,CAAC,OAAO,EAAE,OAAiC,IAAI,EAAE,CAAC;KACtD,CAAC;IAEF,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,WAAW,GAAG,GAAG,EAAE,EAAE;QACnD,GAAG,OAAO;QACV,OAAO;QACP,IAAI,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS;KAC/D,CAAC,CAAC;IAEH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;QACjB,MAAM,KAAK,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,gBAAgB,EAAE,CAAC,CAAuB,CAAC;QACrG,MAAM,IAAI,KAAK,CAAC,KAAK,CAAC,KAAK,IAAI,8BAA8B,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;IAClF,CAAC;IAED,OAAO,QAAQ,CAAC,IAAI,EAAgB,CAAC;AACvC,CAAC"}
@@ -0,0 +1,4 @@
1
+ import { User } from '../types';
2
+ export declare function getValidToken(): Promise<string>;
3
+ export declare function getCurrentUser(): Promise<User>;
4
+ //# sourceMappingURL=auth.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/lib/auth.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,IAAI,EAAE,MAAM,UAAU,CAAC;AA+BhC,wBAAsB,aAAa,IAAI,OAAO,CAAC,MAAM,CAAC,CAgBrD;AAED,wBAAsB,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC,CAYpD"}
@@ -0,0 +1,61 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getValidToken = getValidToken;
4
+ exports.getCurrentUser = getCurrentUser;
5
+ const supabase_1 = require("./supabase");
6
+ const config_1 = require("./config");
7
+ function isTokenExpired(expiresAt) {
8
+ const now = Math.floor(Date.now() / 1000);
9
+ return expiresAt - now < 60;
10
+ }
11
+ async function refreshToken() {
12
+ const config = (0, config_1.readConfig)();
13
+ if (!config) {
14
+ throw new Error('Not authenticated. Please run "replicas login"');
15
+ }
16
+ try {
17
+ const { data, error } = await supabase_1.supabase.auth.refreshSession({
18
+ refresh_token: config.refresh_token,
19
+ });
20
+ if (error)
21
+ throw error;
22
+ if (!data.session)
23
+ throw new Error('Failed to refresh session');
24
+ (0, config_1.writeConfig)({
25
+ access_token: data.session.access_token,
26
+ refresh_token: data.session.refresh_token,
27
+ expires_at: data.session.expires_at || 0,
28
+ });
29
+ }
30
+ catch (error) {
31
+ throw new Error('Failed to refresh token. Please run "replicas login" again.');
32
+ }
33
+ }
34
+ async function getValidToken() {
35
+ const config = (0, config_1.readConfig)();
36
+ if (!config) {
37
+ throw new Error('Not authenticated. Please run "replicas login"');
38
+ }
39
+ if (isTokenExpired(config.expires_at)) {
40
+ await refreshToken();
41
+ const newConfig = (0, config_1.readConfig)();
42
+ if (!newConfig) {
43
+ throw new Error('Failed to get valid token');
44
+ }
45
+ return newConfig.access_token;
46
+ }
47
+ return config.access_token;
48
+ }
49
+ async function getCurrentUser() {
50
+ const token = await getValidToken();
51
+ const { data: { user }, error } = await supabase_1.supabase.auth.getUser(token);
52
+ if (error)
53
+ throw error;
54
+ if (!user)
55
+ throw new Error('User not found');
56
+ return {
57
+ id: user.id,
58
+ email: user.email || 'Unknown',
59
+ };
60
+ }
61
+ //# sourceMappingURL=auth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/lib/auth.ts"],"names":[],"mappings":";;AAiCA,sCAgBC;AAED,wCAYC;AA/DD,yCAAsC;AACtC,qCAAmD;AAGnD,SAAS,cAAc,CAAC,SAAiB;IACvC,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC;IAC1C,OAAO,SAAS,GAAG,GAAG,GAAG,EAAE,CAAC;AAC9B,CAAC;AAED,KAAK,UAAU,YAAY;IACzB,MAAM,MAAM,GAAG,IAAA,mBAAU,GAAE,CAAC;IAC5B,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,IAAI,KAAK,CAAC,gDAAgD,CAAC,CAAC;IACpE,CAAC;IAED,IAAI,CAAC;QACH,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,MAAM,mBAAQ,CAAC,IAAI,CAAC,cAAc,CAAC;YACzD,aAAa,EAAE,MAAM,CAAC,aAAa;SACpC,CAAC,CAAC;QAEH,IAAI,KAAK;YAAE,MAAM,KAAK,CAAC;QACvB,IAAI,CAAC,IAAI,CAAC,OAAO;YAAE,MAAM,IAAI,KAAK,CAAC,2BAA2B,CAAC,CAAC;QAEhE,IAAA,oBAAW,EAAC;YACV,YAAY,EAAE,IAAI,CAAC,OAAO,CAAC,YAAY;YACvC,aAAa,EAAE,IAAI,CAAC,OAAO,CAAC,aAAa;YACzC,UAAU,EAAE,IAAI,CAAC,OAAO,CAAC,UAAU,IAAI,CAAC;SACzC,CAAC,CAAC;IACL,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,IAAI,KAAK,CAAC,6DAA6D,CAAC,CAAC;IACjF,CAAC;AACH,CAAC;AAEM,KAAK,UAAU,aAAa;IACjC,MAAM,MAAM,GAAG,IAAA,mBAAU,GAAE,CAAC;IAC5B,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,IAAI,KAAK,CAAC,gDAAgD,CAAC,CAAC;IACpE,CAAC;IAED,IAAI,cAAc,CAAC,MAAM,CAAC,UAAU,CAAC,EAAE,CAAC;QACtC,MAAM,YAAY,EAAE,CAAC;QACrB,MAAM,SAAS,GAAG,IAAA,mBAAU,GAAE,CAAC;QAC/B,IAAI,CAAC,SAAS,EAAE,CAAC;YACf,MAAM,IAAI,KAAK,CAAC,2BAA2B,CAAC,CAAC;QAC/C,CAAC;QACD,OAAO,SAAS,CAAC,YAAY,CAAC;IAChC,CAAC;IAED,OAAO,MAAM,CAAC,YAAY,CAAC;AAC7B,CAAC;AAEM,KAAK,UAAU,cAAc;IAClC,MAAM,KAAK,GAAG,MAAM,aAAa,EAAE,CAAC;IAEpC,MAAM,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,GAAG,MAAM,mBAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;IAErE,IAAI,KAAK;QAAE,MAAM,KAAK,CAAC;IACvB,IAAI,CAAC,IAAI;QAAE,MAAM,IAAI,KAAK,CAAC,gBAAgB,CAAC,CAAC;IAE7C,OAAO;QACL,EAAE,EAAE,IAAI,CAAC,EAAE;QACX,KAAK,EAAE,IAAI,CAAC,KAAK,IAAI,SAAS;KAC/B,CAAC;AACJ,CAAC"}
@@ -0,0 +1,10 @@
1
+ import { Config } from '../types';
2
+ declare const CONFIG_DIR: string;
3
+ export declare function readConfig(): Config | null;
4
+ export declare function writeConfig(config: Config): void;
5
+ export declare function deleteConfig(): void;
6
+ export declare function isAuthenticated(): boolean;
7
+ export declare function setOrganizationId(organizationId: string): void;
8
+ export declare function getOrganizationId(): string | null;
9
+ export { CONFIG_DIR };
10
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/lib/config.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAElC,QAAA,MAAM,UAAU,QAAuC,CAAC;AASxD,wBAAgB,UAAU,IAAI,MAAM,GAAG,IAAI,CAY1C;AAED,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAWhD;AAED,wBAAgB,YAAY,IAAI,IAAI,CAInC;AAED,wBAAgB,eAAe,IAAI,OAAO,CAGzC;AAED,wBAAgB,iBAAiB,CAAC,cAAc,EAAE,MAAM,GAAG,IAAI,CAQ9D;AAED,wBAAgB,iBAAiB,IAAI,MAAM,GAAG,IAAI,CAGjD;AAED,OAAO,EAAE,UAAU,EAAE,CAAC"}
@@ -0,0 +1,70 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.CONFIG_DIR = void 0;
7
+ exports.readConfig = readConfig;
8
+ exports.writeConfig = writeConfig;
9
+ exports.deleteConfig = deleteConfig;
10
+ exports.isAuthenticated = isAuthenticated;
11
+ exports.setOrganizationId = setOrganizationId;
12
+ exports.getOrganizationId = getOrganizationId;
13
+ const fs_1 = __importDefault(require("fs"));
14
+ const path_1 = __importDefault(require("path"));
15
+ const os_1 = __importDefault(require("os"));
16
+ const CONFIG_DIR = path_1.default.join(os_1.default.homedir(), '.replicas');
17
+ exports.CONFIG_DIR = CONFIG_DIR;
18
+ const CONFIG_FILE = path_1.default.join(CONFIG_DIR, 'config.json');
19
+ function ensureConfigDir() {
20
+ if (!fs_1.default.existsSync(CONFIG_DIR)) {
21
+ fs_1.default.mkdirSync(CONFIG_DIR, { recursive: true, mode: 0o700 });
22
+ }
23
+ }
24
+ function readConfig() {
25
+ if (!fs_1.default.existsSync(CONFIG_FILE)) {
26
+ return null;
27
+ }
28
+ try {
29
+ const data = fs_1.default.readFileSync(CONFIG_FILE, 'utf-8');
30
+ return JSON.parse(data);
31
+ }
32
+ catch (error) {
33
+ console.error('Error reading config file:', error);
34
+ return null;
35
+ }
36
+ }
37
+ function writeConfig(config) {
38
+ ensureConfigDir();
39
+ try {
40
+ fs_1.default.writeFileSync(CONFIG_FILE, JSON.stringify(config, null, 2), {
41
+ mode: 0o600, // Only owner can read/write
42
+ });
43
+ }
44
+ catch (error) {
45
+ console.error('Error writing config file:', error);
46
+ throw error;
47
+ }
48
+ }
49
+ function deleteConfig() {
50
+ if (fs_1.default.existsSync(CONFIG_FILE)) {
51
+ fs_1.default.unlinkSync(CONFIG_FILE);
52
+ }
53
+ }
54
+ function isAuthenticated() {
55
+ const config = readConfig();
56
+ return config !== null && !!config.access_token;
57
+ }
58
+ function setOrganizationId(organizationId) {
59
+ const config = readConfig();
60
+ if (!config) {
61
+ throw new Error('No config file found. Please login first.');
62
+ }
63
+ config.organization_id = organizationId;
64
+ writeConfig(config);
65
+ }
66
+ function getOrganizationId() {
67
+ const config = readConfig();
68
+ return config?.organization_id || null;
69
+ }
70
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/lib/config.ts"],"names":[],"mappings":";;;;;;AAcA,gCAYC;AAED,kCAWC;AAED,oCAIC;AAED,0CAGC;AAED,8CAQC;AAED,8CAGC;AAjED,4CAAoB;AACpB,gDAAwB;AACxB,4CAAoB;AAGpB,MAAM,UAAU,GAAG,cAAI,CAAC,IAAI,CAAC,YAAE,CAAC,OAAO,EAAE,EAAE,WAAW,CAAC,CAAC;AA8D/C,gCAAU;AA7DnB,MAAM,WAAW,GAAG,cAAI,CAAC,IAAI,CAAC,UAAU,EAAE,aAAa,CAAC,CAAC;AAEzD,SAAS,eAAe;IACtB,IAAI,CAAC,YAAE,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC/B,YAAE,CAAC,SAAS,CAAC,UAAU,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IAC7D,CAAC;AACH,CAAC;AAED,SAAgB,UAAU;IACxB,IAAI,CAAC,YAAE,CAAC,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC;QAChC,OAAO,IAAI,CAAC;IACd,CAAC;IAED,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,YAAE,CAAC,YAAY,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;QACnD,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAW,CAAC;IACpC,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CAAC,4BAA4B,EAAE,KAAK,CAAC,CAAC;QACnD,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,SAAgB,WAAW,CAAC,MAAc;IACxC,eAAe,EAAE,CAAC;IAElB,IAAI,CAAC;QACH,YAAE,CAAC,aAAa,CAAC,WAAW,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE;YAC7D,IAAI,EAAE,KAAK,EAAE,4BAA4B;SAC1C,CAAC,CAAC;IACL,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CAAC,4BAA4B,EAAE,KAAK,CAAC,CAAC;QACnD,MAAM,KAAK,CAAC;IACd,CAAC;AACH,CAAC;AAED,SAAgB,YAAY;IAC1B,IAAI,YAAE,CAAC,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC;QAC/B,YAAE,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC;IAC7B,CAAC;AACH,CAAC;AAED,SAAgB,eAAe;IAC7B,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC;IAC5B,OAAO,MAAM,KAAK,IAAI,IAAI,CAAC,CAAC,MAAM,CAAC,YAAY,CAAC;AAClD,CAAC;AAED,SAAgB,iBAAiB,CAAC,cAAsB;IACtD,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC;IAC5B,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,IAAI,KAAK,CAAC,2CAA2C,CAAC,CAAC;IAC/D,CAAC;IAED,MAAM,CAAC,eAAe,GAAG,cAAc,CAAC;IACxC,WAAW,CAAC,MAAM,CAAC,CAAC;AACtB,CAAC;AAED,SAAgB,iBAAiB;IAC/B,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC;IAC5B,OAAO,MAAM,EAAE,eAAe,IAAI,IAAI,CAAC;AACzC,CAAC"}
@@ -0,0 +1,4 @@
1
+ export declare function getGitRoot(): string;
2
+ export declare function getGitRepoName(): string;
3
+ export declare function isInsideGitRepo(): boolean;
4
+ //# sourceMappingURL=git.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"git.d.ts","sourceRoot":"","sources":["../../src/lib/git.ts"],"names":[],"mappings":"AAGA,wBAAgB,UAAU,IAAI,MAAM,CAUnC;AAED,wBAAgB,cAAc,IAAI,MAAM,CAGvC;AAED,wBAAgB,eAAe,IAAI,OAAO,CAUzC"}
@@ -0,0 +1,39 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.getGitRoot = getGitRoot;
7
+ exports.getGitRepoName = getGitRepoName;
8
+ exports.isInsideGitRepo = isInsideGitRepo;
9
+ const child_process_1 = require("child_process");
10
+ const path_1 = __importDefault(require("path"));
11
+ function getGitRoot() {
12
+ try {
13
+ const root = (0, child_process_1.execSync)('git rev-parse --show-toplevel', {
14
+ encoding: 'utf-8',
15
+ stdio: ['pipe', 'pipe', 'pipe'],
16
+ }).trim();
17
+ return root;
18
+ }
19
+ catch (error) {
20
+ throw new Error('Not inside a git repository');
21
+ }
22
+ }
23
+ function getGitRepoName() {
24
+ const root = getGitRoot();
25
+ return path_1.default.basename(root);
26
+ }
27
+ function isInsideGitRepo() {
28
+ try {
29
+ (0, child_process_1.execSync)('git rev-parse --is-inside-work-tree', {
30
+ encoding: 'utf-8',
31
+ stdio: ['pipe', 'pipe', 'pipe'],
32
+ });
33
+ return true;
34
+ }
35
+ catch {
36
+ return false;
37
+ }
38
+ }
39
+ //# sourceMappingURL=git.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"git.js","sourceRoot":"","sources":["../../src/lib/git.ts"],"names":[],"mappings":";;;;;AAGA,gCAUC;AAED,wCAGC;AAED,0CAUC;AA9BD,iDAAyC;AACzC,gDAAwB;AAExB,SAAgB,UAAU;IACxB,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,IAAA,wBAAQ,EAAC,+BAA+B,EAAE;YACrD,QAAQ,EAAE,OAAO;YACjB,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC;SAChC,CAAC,CAAC,IAAI,EAAE,CAAC;QACV,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,IAAI,KAAK,CAAC,6BAA6B,CAAC,CAAC;IACjD,CAAC;AACH,CAAC;AAED,SAAgB,cAAc;IAC5B,MAAM,IAAI,GAAG,UAAU,EAAE,CAAC;IAC1B,OAAO,cAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;AAC7B,CAAC;AAED,SAAgB,eAAe;IAC7B,IAAI,CAAC;QACH,IAAA,wBAAQ,EAAC,qCAAqC,EAAE;YAC9C,QAAQ,EAAE,OAAO;YACjB,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC;SAChC,CAAC,CAAC;QACH,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC"}
@@ -0,0 +1,5 @@
1
+ import { Organization } from '../types';
2
+ export declare function fetchOrganizations(): Promise<Organization[]>;
3
+ export declare function setActiveOrganization(organizationId: string): Promise<void>;
4
+ export declare function ensureOrganization(): Promise<string>;
5
+ //# sourceMappingURL=organization.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"organization.d.ts","sourceRoot":"","sources":["../../src/lib/organization.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAQxC,wBAAsB,kBAAkB,IAAI,OAAO,CAAC,YAAY,EAAE,CAAC,CAKlE;AAED,wBAAsB,qBAAqB,CAAC,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CASjF;AAED,wBAAsB,kBAAkB,IAAI,OAAO,CAAC,MAAM,CAAC,CAW1D"}
@@ -0,0 +1,29 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.fetchOrganizations = fetchOrganizations;
4
+ exports.setActiveOrganization = setActiveOrganization;
5
+ exports.ensureOrganization = ensureOrganization;
6
+ const api_1 = require("./api");
7
+ const config_1 = require("./config");
8
+ async function fetchOrganizations() {
9
+ const response = await (0, api_1.authenticatedFetch)('/api/user/organizations');
10
+ return response.organizations;
11
+ }
12
+ async function setActiveOrganization(organizationId) {
13
+ const organizations = await fetchOrganizations();
14
+ const organization = organizations.find(org => org.id === organizationId);
15
+ if (!organization) {
16
+ throw new Error(`Organization with ID ${organizationId} not found or you don't have access to it.`);
17
+ }
18
+ (0, config_1.setOrganizationId)(organizationId);
19
+ }
20
+ async function ensureOrganization() {
21
+ const organizations = await fetchOrganizations();
22
+ if (organizations.length === 0) {
23
+ throw new Error('You are not a member of any organization. Please contact support.');
24
+ }
25
+ const defaultOrg = organizations[0];
26
+ (0, config_1.setOrganizationId)(defaultOrg.id);
27
+ return defaultOrg.id;
28
+ }
29
+ //# sourceMappingURL=organization.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"organization.js","sourceRoot":"","sources":["../../src/lib/organization.ts"],"names":[],"mappings":";;AAQA,gDAKC;AAED,sDASC;AAED,gDAWC;AApCD,+BAA2C;AAC3C,qCAAwE;AAMjE,KAAK,UAAU,kBAAkB;IACtC,MAAM,QAAQ,GAAG,MAAM,IAAA,wBAAkB,EACvC,yBAAyB,CAC1B,CAAC;IACF,OAAO,QAAQ,CAAC,aAAa,CAAC;AAChC,CAAC;AAEM,KAAK,UAAU,qBAAqB,CAAC,cAAsB;IAChE,MAAM,aAAa,GAAG,MAAM,kBAAkB,EAAE,CAAC;IACjD,MAAM,YAAY,GAAG,aAAa,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,KAAK,cAAc,CAAC,CAAC;IAE1E,IAAI,CAAC,YAAY,EAAE,CAAC;QAClB,MAAM,IAAI,KAAK,CAAC,wBAAwB,cAAc,4CAA4C,CAAC,CAAC;IACtG,CAAC;IAED,IAAA,0BAAuB,EAAC,cAAc,CAAC,CAAC;AAC1C,CAAC;AAEM,KAAK,UAAU,kBAAkB;IACtC,MAAM,aAAa,GAAG,MAAM,kBAAkB,EAAE,CAAC;IAEjD,IAAI,aAAa,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC/B,MAAM,IAAI,KAAK,CAAC,mEAAmE,CAAC,CAAC;IACvF,CAAC;IAED,MAAM,UAAU,GAAG,aAAa,CAAC,CAAC,CAAC,CAAC;IACpC,IAAA,0BAAuB,EAAC,UAAU,CAAC,EAAE,CAAC,CAAC;IAEvC,OAAO,UAAU,CAAC,EAAE,CAAC;AACvB,CAAC"}
@@ -0,0 +1,3 @@
1
+ export declare function findAvailablePort(desiredPort: number): Promise<number>;
2
+ export declare function mapPortsToLocal(remotePorts: number[]): Promise<Map<number, number>>;
3
+ //# sourceMappingURL=ports.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ports.d.ts","sourceRoot":"","sources":["../../src/lib/ports.ts"],"names":[],"mappings":"AAqBA,wBAAsB,iBAAiB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAe5E;AAED,wBAAsB,eAAe,CAAC,WAAW,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CASzF"}
@@ -0,0 +1,44 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.findAvailablePort = findAvailablePort;
4
+ exports.mapPortsToLocal = mapPortsToLocal;
5
+ const child_process_1 = require("child_process");
6
+ async function isPortAvailable(port) {
7
+ try {
8
+ // Use lsof to check if anything is listening on this port
9
+ // -i :PORT - show network files on this port
10
+ // -P - show port numbers (not service names)
11
+ // -n - don't resolve hostnames
12
+ (0, child_process_1.execSync)(`lsof -i :${port} -P -n | grep LISTEN`, {
13
+ encoding: 'utf-8',
14
+ stdio: ['pipe', 'pipe', 'pipe'],
15
+ });
16
+ return false;
17
+ }
18
+ catch (error) {
19
+ // lsof returns exit code 1 if nothing found, which throws an error
20
+ // This means the port is available
21
+ return true;
22
+ }
23
+ }
24
+ async function findAvailablePort(desiredPort) {
25
+ const baseHundred = Math.floor(desiredPort / 100) * 100;
26
+ const maxPort = desiredPort >= baseHundred && desiredPort < baseHundred + 100
27
+ ? baseHundred + 99
28
+ : desiredPort + 100;
29
+ for (let port = desiredPort; port <= maxPort; port++) {
30
+ if (await isPortAvailable(port)) {
31
+ return port;
32
+ }
33
+ }
34
+ throw new Error(`Could not find available port in range ${desiredPort}-${maxPort}`);
35
+ }
36
+ async function mapPortsToLocal(remotePorts) {
37
+ const portMap = new Map();
38
+ for (const remotePort of remotePorts) {
39
+ const localPort = await findAvailablePort(remotePort);
40
+ portMap.set(remotePort, localPort);
41
+ }
42
+ return portMap;
43
+ }
44
+ //# sourceMappingURL=ports.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ports.js","sourceRoot":"","sources":["../../src/lib/ports.ts"],"names":[],"mappings":";;AAqBA,8CAeC;AAED,0CASC;AA/CD,iDAAyC;AAEzC,KAAK,UAAU,eAAe,CAAC,IAAY;IACzC,IAAI,CAAC;QACH,0DAA0D;QAC1D,6CAA6C;QAC7C,6CAA6C;QAC7C,+BAA+B;QAC/B,IAAA,wBAAQ,EAAC,YAAY,IAAI,sBAAsB,EAAE;YAC/C,QAAQ,EAAE,OAAO;YACjB,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC;SAChC,CAAC,CAAC;QAEH,OAAO,KAAK,CAAC;IACf,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,mEAAmE;QACnE,mCAAmC;QACnC,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAEM,KAAK,UAAU,iBAAiB,CAAC,WAAmB;IACzD,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,WAAW,GAAG,GAAG,CAAC,GAAG,GAAG,CAAC;IACxD,MAAM,OAAO,GAAG,WAAW,IAAI,WAAW,IAAI,WAAW,GAAG,WAAW,GAAG,GAAG;QAC3E,CAAC,CAAC,WAAW,GAAG,EAAE;QAClB,CAAC,CAAC,WAAW,GAAG,GAAG,CAAC;IAEtB,KAAK,IAAI,IAAI,GAAG,WAAW,EAAE,IAAI,IAAI,OAAO,EAAE,IAAI,EAAE,EAAE,CAAC;QACrD,IAAI,MAAM,eAAe,CAAC,IAAI,CAAC,EAAE,CAAC;YAChC,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;IAED,MAAM,IAAI,KAAK,CACb,0CAA0C,WAAW,IAAI,OAAO,EAAE,CACnE,CAAC;AACJ,CAAC;AAEM,KAAK,UAAU,eAAe,CAAC,WAAqB;IACzD,MAAM,OAAO,GAAG,IAAI,GAAG,EAAkB,CAAC;IAE1C,KAAK,MAAM,UAAU,IAAI,WAAW,EAAE,CAAC;QACrC,MAAM,SAAS,GAAG,MAAM,iBAAiB,CAAC,UAAU,CAAC,CAAC;QACtD,OAAO,CAAC,GAAG,CAAC,UAAU,EAAE,SAAS,CAAC,CAAC;IACrC,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC"}
@@ -0,0 +1,8 @@
1
+ import { ReplicasConfig } from '../types';
2
+ export declare function readReplicasConfig(): ReplicasConfig | null;
3
+ export declare function validateCopyFiles(copyFiles: string[]): {
4
+ valid: string[];
5
+ invalid: string[];
6
+ };
7
+ export declare function getAbsoluteCopyPath(relativePath: string): string;
8
+ //# sourceMappingURL=replicas-config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"replicas-config.d.ts","sourceRoot":"","sources":["../../src/lib/replicas-config.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAG1C,wBAAgB,kBAAkB,IAAI,cAAc,GAAG,IAAI,CA+B1D;AAED,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG;IAAE,KAAK,EAAE,MAAM,EAAE,CAAC;IAAC,OAAO,EAAE,MAAM,EAAE,CAAA;CAAE,CAe7F;AAED,wBAAgB,mBAAmB,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,CAGhE"}
@@ -0,0 +1,58 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.readReplicasConfig = readReplicasConfig;
7
+ exports.validateCopyFiles = validateCopyFiles;
8
+ exports.getAbsoluteCopyPath = getAbsoluteCopyPath;
9
+ const fs_1 = __importDefault(require("fs"));
10
+ const path_1 = __importDefault(require("path"));
11
+ const git_1 = require("./git");
12
+ function readReplicasConfig() {
13
+ try {
14
+ const gitRoot = (0, git_1.getGitRoot)();
15
+ const configPath = path_1.default.join(gitRoot, 'replicas.json');
16
+ if (!fs_1.default.existsSync(configPath)) {
17
+ return null;
18
+ }
19
+ const data = fs_1.default.readFileSync(configPath, 'utf-8');
20
+ const config = JSON.parse(data);
21
+ if (config.copy && !Array.isArray(config.copy)) {
22
+ throw new Error('Invalid replicas.json: "copy" must be an array of file paths');
23
+ }
24
+ if (config.ports && !Array.isArray(config.ports)) {
25
+ throw new Error('Invalid replicas.json: "ports" must be an array of port numbers');
26
+ }
27
+ if (config.ports && !config.ports.every(p => typeof p === 'number')) {
28
+ throw new Error('Invalid replicas.json: all ports must be numbers');
29
+ }
30
+ return config;
31
+ }
32
+ catch (error) {
33
+ if (error instanceof Error) {
34
+ throw error;
35
+ }
36
+ throw new Error('Failed to read replicas.json');
37
+ }
38
+ }
39
+ function validateCopyFiles(copyFiles) {
40
+ const gitRoot = (0, git_1.getGitRoot)();
41
+ const valid = [];
42
+ const invalid = [];
43
+ for (const file of copyFiles) {
44
+ const fullPath = path_1.default.join(gitRoot, file);
45
+ if (fs_1.default.existsSync(fullPath)) {
46
+ valid.push(file);
47
+ }
48
+ else {
49
+ invalid.push(file);
50
+ }
51
+ }
52
+ return { valid, invalid };
53
+ }
54
+ function getAbsoluteCopyPath(relativePath) {
55
+ const gitRoot = (0, git_1.getGitRoot)();
56
+ return path_1.default.join(gitRoot, relativePath);
57
+ }
58
+ //# sourceMappingURL=replicas-config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"replicas-config.js","sourceRoot":"","sources":["../../src/lib/replicas-config.ts"],"names":[],"mappings":";;;;;AAKA,gDA+BC;AAED,8CAeC;AAED,kDAGC;AA1DD,4CAAoB;AACpB,gDAAwB;AAExB,+BAAmC;AAEnC,SAAgB,kBAAkB;IAChC,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,IAAA,gBAAU,GAAE,CAAC;QAC7B,MAAM,UAAU,GAAG,cAAI,CAAC,IAAI,CAAC,OAAO,EAAE,eAAe,CAAC,CAAC;QAEvD,IAAI,CAAC,YAAE,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;YAC/B,OAAO,IAAI,CAAC;QACd,CAAC;QAED,MAAM,IAAI,GAAG,YAAE,CAAC,YAAY,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;QAClD,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAmB,CAAC;QAElD,IAAI,MAAM,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC;YAC/C,MAAM,IAAI,KAAK,CAAC,8DAA8D,CAAC,CAAC;QAClF,CAAC;QAED,IAAI,MAAM,CAAC,KAAK,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;YACjD,MAAM,IAAI,KAAK,CAAC,iEAAiE,CAAC,CAAC;QACrF,CAAC;QAED,IAAI,MAAM,CAAC,KAAK,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ,CAAC,EAAE,CAAC;YACpE,MAAM,IAAI,KAAK,CAAC,kDAAkD,CAAC,CAAC;QACtE,CAAC;QAED,OAAO,MAAM,CAAC;IAChB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,KAAK,YAAY,KAAK,EAAE,CAAC;YAC3B,MAAM,KAAK,CAAC;QACd,CAAC;QACD,MAAM,IAAI,KAAK,CAAC,8BAA8B,CAAC,CAAC;IAClD,CAAC;AACH,CAAC;AAED,SAAgB,iBAAiB,CAAC,SAAmB;IACnD,MAAM,OAAO,GAAG,IAAA,gBAAU,GAAE,CAAC;IAC7B,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,MAAM,OAAO,GAAa,EAAE,CAAC;IAE7B,KAAK,MAAM,IAAI,IAAI,SAAS,EAAE,CAAC;QAC7B,MAAM,QAAQ,GAAG,cAAI,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;QAC1C,IAAI,YAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC5B,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACnB,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACrB,CAAC;IACH,CAAC;IAED,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC;AAC5B,CAAC;AAED,SAAgB,mBAAmB,CAAC,YAAoB;IACtD,MAAM,OAAO,GAAG,IAAA,gBAAU,GAAE,CAAC;IAC7B,OAAO,cAAI,CAAC,IAAI,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;AAC1C,CAAC"}
@@ -0,0 +1,5 @@
1
+ export declare function hasSSHKeyLocally(sshKeyId: string): boolean;
2
+ export declare function getSSHKey(sshKeyId: string): Promise<string>;
3
+ export declare function scpCopyFile(privateKeyPath: string, localPath: string, remotePath: string, remoteHost: string): Promise<void>;
4
+ export declare function connectSSH(privateKeyPath: string, remoteHost: string, portMappings: Map<number, number>): Promise<void>;
5
+ //# sourceMappingURL=ssh.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ssh.d.ts","sourceRoot":"","sources":["../../src/lib/ssh.ts"],"names":[],"mappings":"AAwBA,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAE1D;AAED,wBAAsB,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAmBjE;AAED,wBAAsB,WAAW,CAC/B,cAAc,EAAE,MAAM,EACtB,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,IAAI,CAAC,CAsBf;AAED,wBAAsB,UAAU,CAC9B,cAAc,EAAE,MAAM,EACtB,UAAU,EAAE,MAAM,EAClB,YAAY,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,GAChC,OAAO,CAAC,IAAI,CAAC,CAwBf"}