paymongo-cli 1.0.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/.github/ISSUE_TEMPLATE/bug-report.md +33 -0
- package/.github/PULL_REQUEST_TEMPLATE.md +30 -0
- package/.github/workflows/ci-cd.yml +88 -0
- package/.github/workflows/ci.yml +46 -0
- package/.github/workflows/release.yml +54 -0
- package/LICENSE +21 -0
- package/README.md +113 -0
- package/bin/paymongo.js +3 -0
- package/dist/.tsbuildinfo +1 -0
- package/dist/commands/config.d.ts +4 -0
- package/dist/commands/config.d.ts.map +1 -0
- package/dist/commands/config.js +398 -0
- package/dist/commands/config.js.map +1 -0
- package/dist/commands/dev.d.ts +4 -0
- package/dist/commands/dev.d.ts.map +1 -0
- package/dist/commands/dev.js +353 -0
- package/dist/commands/dev.js.map +1 -0
- package/dist/commands/gui.d.ts +4 -0
- package/dist/commands/gui.d.ts.map +1 -0
- package/dist/commands/gui.js +74 -0
- package/dist/commands/gui.js.map +1 -0
- package/dist/commands/init.d.ts +4 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +268 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/login.d.ts +4 -0
- package/dist/commands/login.d.ts.map +1 -0
- package/dist/commands/login.js +287 -0
- package/dist/commands/login.js.map +1 -0
- package/dist/commands/payments.d.ts +4 -0
- package/dist/commands/payments.d.ts.map +1 -0
- package/dist/commands/payments.js +180 -0
- package/dist/commands/payments.js.map +1 -0
- package/dist/commands/team/index.d.ts +4 -0
- package/dist/commands/team/index.d.ts.map +1 -0
- package/dist/commands/team/index.js +155 -0
- package/dist/commands/team/index.js.map +1 -0
- package/dist/commands/trigger.d.ts +4 -0
- package/dist/commands/trigger.d.ts.map +1 -0
- package/dist/commands/trigger.js +312 -0
- package/dist/commands/trigger.js.map +1 -0
- package/dist/commands/webhooks.d.ts +4 -0
- package/dist/commands/webhooks.d.ts.map +1 -0
- package/dist/commands/webhooks.js +357 -0
- package/dist/commands/webhooks.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +61 -0
- package/dist/index.js.map +1 -0
- package/dist/services/analytics/service.d.ts +29 -0
- package/dist/services/analytics/service.d.ts.map +1 -0
- package/dist/services/analytics/service.js +97 -0
- package/dist/services/analytics/service.js.map +1 -0
- package/dist/services/api/client.d.ts +27 -0
- package/dist/services/api/client.d.ts.map +1 -0
- package/dist/services/api/client.js +151 -0
- package/dist/services/api/client.js.map +1 -0
- package/dist/services/config/manager.d.ts +16 -0
- package/dist/services/config/manager.d.ts.map +1 -0
- package/dist/services/config/manager.js +211 -0
- package/dist/services/config/manager.js.map +1 -0
- package/dist/services/github/auth.d.ts +15 -0
- package/dist/services/github/auth.d.ts.map +1 -0
- package/dist/services/github/auth.js +119 -0
- package/dist/services/github/auth.js.map +1 -0
- package/dist/services/github/client.d.ts +54 -0
- package/dist/services/github/client.d.ts.map +1 -0
- package/dist/services/github/client.js +107 -0
- package/dist/services/github/client.js.map +1 -0
- package/dist/services/github/sync.d.ts +26 -0
- package/dist/services/github/sync.d.ts.map +1 -0
- package/dist/services/github/sync.js +200 -0
- package/dist/services/github/sync.js.map +1 -0
- package/dist/services/web/server.d.ts +30 -0
- package/dist/services/web/server.d.ts.map +1 -0
- package/dist/services/web/server.js +159 -0
- package/dist/services/web/server.js.map +1 -0
- package/dist/types/paymongo.d.ts +118 -0
- package/dist/types/paymongo.d.ts.map +1 -0
- package/dist/types/paymongo.js +3 -0
- package/dist/types/paymongo.js.map +1 -0
- package/dist/utils/cache.d.ts +20 -0
- package/dist/utils/cache.d.ts.map +1 -0
- package/dist/utils/cache.js +164 -0
- package/dist/utils/cache.js.map +1 -0
- package/dist/utils/constants.d.ts +32 -0
- package/dist/utils/constants.d.ts.map +1 -0
- package/dist/utils/constants.js +52 -0
- package/dist/utils/constants.js.map +1 -0
- package/dist/utils/errors.d.ts +33 -0
- package/dist/utils/errors.d.ts.map +1 -0
- package/dist/utils/errors.js +79 -0
- package/dist/utils/errors.js.map +1 -0
- package/dist/utils/logger.d.ts +17 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +53 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/spinner.d.ts +17 -0
- package/dist/utils/spinner.d.ts.map +1 -0
- package/dist/utils/spinner.js +54 -0
- package/dist/utils/spinner.js.map +1 -0
- package/dist/utils/validator.d.ts +10 -0
- package/dist/utils/validator.d.ts.map +1 -0
- package/dist/utils/validator.js +79 -0
- package/dist/utils/validator.js.map +1 -0
- package/package.json +70 -0
- package/web/index.html +688 -0
|
@@ -0,0 +1,107 @@
|
|
|
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.GitHubClient = void 0;
|
|
7
|
+
const axios_1 = __importDefault(require("axios"));
|
|
8
|
+
const errors_1 = require("../../utils/errors");
|
|
9
|
+
class GitHubClient {
|
|
10
|
+
constructor(options = {}) {
|
|
11
|
+
this.token = options.token;
|
|
12
|
+
const timeout = options.timeout || 30000;
|
|
13
|
+
this.client = axios_1.default.create({
|
|
14
|
+
baseURL: 'https://api.github.com',
|
|
15
|
+
timeout,
|
|
16
|
+
headers: {
|
|
17
|
+
Accept: 'application/vnd.github.v3+json',
|
|
18
|
+
'User-Agent': 'paymongo-cli/1.0.0',
|
|
19
|
+
},
|
|
20
|
+
});
|
|
21
|
+
if (this.token) {
|
|
22
|
+
const authToken = this.token;
|
|
23
|
+
this.client.defaults.headers.common['Authorization'] = `token ${authToken}`;
|
|
24
|
+
}
|
|
25
|
+
this.setupInterceptors();
|
|
26
|
+
}
|
|
27
|
+
setupInterceptors() {
|
|
28
|
+
// Request interceptor for debugging
|
|
29
|
+
this.client.interceptors.request.use((config) => {
|
|
30
|
+
if (!this.token && config.url?.includes('/repos/')) {
|
|
31
|
+
// For public repo access, we can proceed without token
|
|
32
|
+
// But for private repos or write operations, token is required
|
|
33
|
+
}
|
|
34
|
+
return config;
|
|
35
|
+
});
|
|
36
|
+
// Response interceptor for error handling
|
|
37
|
+
this.client.interceptors.response.use((response) => response, (error) => {
|
|
38
|
+
if (error.response?.status === 401) {
|
|
39
|
+
throw new Error('GitHub authentication failed. Please check your token.');
|
|
40
|
+
}
|
|
41
|
+
if (error.response?.status === 403) {
|
|
42
|
+
throw new Error('GitHub API rate limit exceeded or insufficient permissions.');
|
|
43
|
+
}
|
|
44
|
+
if (error.response?.status === 404) {
|
|
45
|
+
throw new Error('GitHub repository or file not found.');
|
|
46
|
+
}
|
|
47
|
+
throw new errors_1.NetworkError(`GitHub API error: ${error.message}`);
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
async getRepo(owner, repo) {
|
|
51
|
+
const response = await (0, errors_1.withRetry)(() => this.client.get(`/repos/${owner}/${repo}`), {
|
|
52
|
+
maxRetries: 3,
|
|
53
|
+
delayMs: 1000,
|
|
54
|
+
});
|
|
55
|
+
return response.data;
|
|
56
|
+
}
|
|
57
|
+
async getFile(owner, repo, path, ref) {
|
|
58
|
+
const params = ref ? { ref } : {};
|
|
59
|
+
const response = await (0, errors_1.withRetry)(() => this.client.get(`/repos/${owner}/${repo}/contents/${path}`, { params }), { maxRetries: 3, delayMs: 1000 });
|
|
60
|
+
return response.data;
|
|
61
|
+
}
|
|
62
|
+
async createOrUpdateFile(owner, repo, path, content, message, branch = 'main', sha) {
|
|
63
|
+
const data = {
|
|
64
|
+
message,
|
|
65
|
+
content: Buffer.from(content).toString('base64'),
|
|
66
|
+
branch,
|
|
67
|
+
};
|
|
68
|
+
if (sha) {
|
|
69
|
+
data.sha = sha;
|
|
70
|
+
}
|
|
71
|
+
const response = await (0, errors_1.withRetry)(() => this.client.put(`/repos/${owner}/${repo}/contents/${path}`, data), { maxRetries: 3, delayMs: 1000 });
|
|
72
|
+
return response.data;
|
|
73
|
+
}
|
|
74
|
+
async getCommits(owner, repo, path, since) {
|
|
75
|
+
const params = { per_page: 10 };
|
|
76
|
+
if (path) {
|
|
77
|
+
params.path = path;
|
|
78
|
+
}
|
|
79
|
+
if (since) {
|
|
80
|
+
params.since = since;
|
|
81
|
+
}
|
|
82
|
+
const response = await (0, errors_1.withRetry)(() => this.client.get(`/repos/${owner}/${repo}/commits`, { params }), { maxRetries: 3, delayMs: 1000 });
|
|
83
|
+
return response.data;
|
|
84
|
+
}
|
|
85
|
+
async createRepo(name, description, isPrivate = false) {
|
|
86
|
+
const data = {
|
|
87
|
+
name,
|
|
88
|
+
description: description || 'PayMongo CLI team configuration',
|
|
89
|
+
private: isPrivate,
|
|
90
|
+
auto_init: true,
|
|
91
|
+
};
|
|
92
|
+
const response = await (0, errors_1.withRetry)(() => this.client.post('/user/repos', data), {
|
|
93
|
+
maxRetries: 3,
|
|
94
|
+
delayMs: 1000,
|
|
95
|
+
});
|
|
96
|
+
return response.data;
|
|
97
|
+
}
|
|
98
|
+
setToken(token) {
|
|
99
|
+
this.token = token;
|
|
100
|
+
this.client.defaults.headers.common['Authorization'] = `token ${token}`;
|
|
101
|
+
}
|
|
102
|
+
hasToken() {
|
|
103
|
+
return !!this.token;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
exports.GitHubClient = GitHubClient;
|
|
107
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../../src/services/github/client.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { ConfigManager } from '../config/manager';
|
|
2
|
+
import { GitHubAuthService } from './auth';
|
|
3
|
+
export interface TeamSyncOptions {
|
|
4
|
+
config: ConfigManager;
|
|
5
|
+
auth: GitHubAuthService;
|
|
6
|
+
}
|
|
7
|
+
export interface SyncOptions {
|
|
8
|
+
repo: string;
|
|
9
|
+
branch?: string;
|
|
10
|
+
force?: boolean;
|
|
11
|
+
direction?: 'push' | 'pull' | 'sync';
|
|
12
|
+
}
|
|
13
|
+
export declare class TeamSyncService {
|
|
14
|
+
private config;
|
|
15
|
+
private auth;
|
|
16
|
+
constructor(options: TeamSyncOptions);
|
|
17
|
+
sync(options: SyncOptions): Promise<void>;
|
|
18
|
+
private pushConfig;
|
|
19
|
+
private pullConfig;
|
|
20
|
+
private sanitizeConfig;
|
|
21
|
+
private validateRemoteConfig;
|
|
22
|
+
private checkConfigConflicts;
|
|
23
|
+
private mergeConfigs;
|
|
24
|
+
private updateTeamConfig;
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=sync.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sync.d.ts","sourceRoot":"","sources":["../../../src/services/github/sync.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAElD,OAAO,EAAE,iBAAiB,EAAE,MAAM,QAAQ,CAAC;AAE3C,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,aAAa,CAAC;IACtB,IAAI,EAAE,iBAAiB,CAAC;CACzB;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC;CACtC;AAED,qBAAa,eAAe;IAC1B,OAAO,CAAC,MAAM,CAAgB;IAC9B,OAAO,CAAC,IAAI,CAAoB;gBAEpB,OAAO,EAAE,eAAe;IAK9B,IAAI,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;YA+CjC,UAAU;YAoDV,UAAU;IA8DxB,OAAO,CAAC,cAAc;IAiBtB,OAAO,CAAC,oBAAoB;IAY5B,OAAO,CAAC,oBAAoB;IAuC5B,OAAO,CAAC,YAAY;YAsBN,gBAAgB;CAe/B"}
|
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.TeamSyncService = void 0;
|
|
4
|
+
class TeamSyncService {
|
|
5
|
+
constructor(options) {
|
|
6
|
+
this.config = options.config;
|
|
7
|
+
this.auth = options.auth;
|
|
8
|
+
}
|
|
9
|
+
async sync(options) {
|
|
10
|
+
const { repo, branch = 'main', force = false, direction = 'sync' } = options;
|
|
11
|
+
// Parse repo string (owner/repo)
|
|
12
|
+
const [owner, repoName] = repo.split('/');
|
|
13
|
+
if (!owner || !repoName) {
|
|
14
|
+
throw new Error('Invalid repository format. Use "owner/repo" format.');
|
|
15
|
+
}
|
|
16
|
+
// Get authenticated GitHub client
|
|
17
|
+
const client = await this.auth.authenticate();
|
|
18
|
+
// Ensure repo exists
|
|
19
|
+
let githubRepo;
|
|
20
|
+
try {
|
|
21
|
+
githubRepo = await client.getRepo(owner, repoName);
|
|
22
|
+
}
|
|
23
|
+
catch (error) {
|
|
24
|
+
if (error instanceof Error && error.message.includes('404')) {
|
|
25
|
+
throw new Error(`Repository "${repo}" not found. Please create it first or check permissions.`);
|
|
26
|
+
}
|
|
27
|
+
throw error;
|
|
28
|
+
}
|
|
29
|
+
// Check if repo is accessible
|
|
30
|
+
if (githubRepo.private && !client.hasToken()) {
|
|
31
|
+
throw new Error(`Repository "${repo}" is private. Please provide a GitHub token with repo permissions.`);
|
|
32
|
+
}
|
|
33
|
+
const configPath = '.paymongo';
|
|
34
|
+
const remotePath = 'paymongo-config.json';
|
|
35
|
+
if (direction === 'push' || direction === 'sync') {
|
|
36
|
+
await this.pushConfig(client, owner, repoName, branch, configPath, remotePath, force);
|
|
37
|
+
}
|
|
38
|
+
if (direction === 'pull' || direction === 'sync') {
|
|
39
|
+
await this.pullConfig(client, owner, repoName, branch, configPath, remotePath, force);
|
|
40
|
+
}
|
|
41
|
+
// Update local team config
|
|
42
|
+
await this.updateTeamConfig(repo, branch);
|
|
43
|
+
}
|
|
44
|
+
async pushConfig(client, owner, repo, branch, _localPath, remotePath, force) {
|
|
45
|
+
const localConfig = await this.config.load();
|
|
46
|
+
if (!localConfig) {
|
|
47
|
+
throw new Error('No local configuration found. Run "paymongo init" first.');
|
|
48
|
+
}
|
|
49
|
+
// Create sanitized config for sharing (remove sensitive data)
|
|
50
|
+
const shareableConfig = this.sanitizeConfig(localConfig);
|
|
51
|
+
let sha;
|
|
52
|
+
// Check if remote file exists
|
|
53
|
+
try {
|
|
54
|
+
const remoteFile = await client.getFile(owner, repo, remotePath, branch);
|
|
55
|
+
sha = remoteFile.sha;
|
|
56
|
+
if (!force) {
|
|
57
|
+
// Check if remote exists
|
|
58
|
+
const remoteCommits = await client.getCommits(owner, repo, remotePath);
|
|
59
|
+
if (remoteCommits.length > 0) {
|
|
60
|
+
// For now, just warn about potential conflicts
|
|
61
|
+
console.log(`⚠️ Remote config exists. Use --force to overwrite.`);
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
catch (error) {
|
|
67
|
+
// File doesn't exist, that's fine for push
|
|
68
|
+
if (!(error instanceof Error && error.message.includes('404'))) {
|
|
69
|
+
throw error;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
// Push config to GitHub
|
|
73
|
+
await client.createOrUpdateFile(owner, repo, remotePath, JSON.stringify(shareableConfig, null, 2), 'Update PayMongo CLI configuration', branch, sha);
|
|
74
|
+
}
|
|
75
|
+
async pullConfig(client, owner, repo, branch, _localPath, remotePath, force) {
|
|
76
|
+
let remoteFile;
|
|
77
|
+
try {
|
|
78
|
+
remoteFile = await client.getFile(owner, repo, remotePath, branch);
|
|
79
|
+
}
|
|
80
|
+
catch (error) {
|
|
81
|
+
if (error instanceof Error && error.message.includes('404')) {
|
|
82
|
+
console.log(`ℹ️ No remote configuration found in ${repo}. Skipping pull.`);
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
throw error;
|
|
86
|
+
}
|
|
87
|
+
if (!remoteFile.content) {
|
|
88
|
+
throw new Error('Remote configuration file is empty.');
|
|
89
|
+
}
|
|
90
|
+
// Decode base64 content
|
|
91
|
+
const remoteConfigContent = Buffer.from(remoteFile.content, 'base64').toString('utf-8');
|
|
92
|
+
let remoteConfig;
|
|
93
|
+
try {
|
|
94
|
+
remoteConfig = JSON.parse(remoteConfigContent);
|
|
95
|
+
}
|
|
96
|
+
catch (error) {
|
|
97
|
+
throw new Error('Invalid JSON in remote configuration file.');
|
|
98
|
+
}
|
|
99
|
+
// Validate remote config structure
|
|
100
|
+
this.validateRemoteConfig(remoteConfig);
|
|
101
|
+
// Merge with local config
|
|
102
|
+
const localConfig = await this.config.load();
|
|
103
|
+
if (!localConfig) {
|
|
104
|
+
// No local config, use remote as base
|
|
105
|
+
await this.config.save(remoteConfig);
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
if (!force) {
|
|
109
|
+
// Check for conflicts
|
|
110
|
+
const conflicts = this.checkConfigConflicts(localConfig, remoteConfig);
|
|
111
|
+
if (conflicts.length > 0) {
|
|
112
|
+
console.log('⚠️ Configuration conflicts detected:');
|
|
113
|
+
conflicts.forEach((conflict) => console.log(` - ${conflict}`));
|
|
114
|
+
console.log('Use --force to overwrite local config with remote.');
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
// Merge configurations (remote takes precedence for shared settings)
|
|
119
|
+
const mergedConfig = this.mergeConfigs(localConfig, remoteConfig);
|
|
120
|
+
await this.config.save(mergedConfig);
|
|
121
|
+
}
|
|
122
|
+
sanitizeConfig(config) {
|
|
123
|
+
// Create a copy without sensitive data
|
|
124
|
+
const sanitized = { ...config };
|
|
125
|
+
// Remove webhook secrets (they should be environment-specific)
|
|
126
|
+
if (sanitized.webhookSecrets) {
|
|
127
|
+
sanitized.webhookSecrets = {};
|
|
128
|
+
}
|
|
129
|
+
// Remove GitHub token (should be set per user)
|
|
130
|
+
if (sanitized.team?.githubToken) {
|
|
131
|
+
delete sanitized.team.githubToken;
|
|
132
|
+
}
|
|
133
|
+
return sanitized;
|
|
134
|
+
}
|
|
135
|
+
validateRemoteConfig(config) {
|
|
136
|
+
if (!config || typeof config !== 'object') {
|
|
137
|
+
throw new Error('Remote configuration is not a valid object.');
|
|
138
|
+
}
|
|
139
|
+
if (!config.version) {
|
|
140
|
+
throw new Error('Remote configuration is missing version field.');
|
|
141
|
+
}
|
|
142
|
+
// Add more validation as needed
|
|
143
|
+
}
|
|
144
|
+
checkConfigConflicts(local, remote) {
|
|
145
|
+
const conflicts = [];
|
|
146
|
+
// Check for API key conflicts
|
|
147
|
+
if (local.apiKeys?.test?.public &&
|
|
148
|
+
remote.apiKeys?.test?.public &&
|
|
149
|
+
local.apiKeys.test.public !== remote.apiKeys.test.public) {
|
|
150
|
+
conflicts.push('Test environment public API key');
|
|
151
|
+
}
|
|
152
|
+
if (local.apiKeys?.test?.secret &&
|
|
153
|
+
remote.apiKeys?.test?.secret &&
|
|
154
|
+
local.apiKeys.test.secret !== remote.apiKeys.test.secret) {
|
|
155
|
+
conflicts.push('Test environment secret API key');
|
|
156
|
+
}
|
|
157
|
+
if (local.apiKeys?.live?.public &&
|
|
158
|
+
remote.apiKeys?.live?.public &&
|
|
159
|
+
local.apiKeys.live.public !== remote.apiKeys.live.public) {
|
|
160
|
+
conflicts.push('Live environment public API key');
|
|
161
|
+
}
|
|
162
|
+
if (local.apiKeys?.live?.secret &&
|
|
163
|
+
remote.apiKeys?.live?.secret &&
|
|
164
|
+
local.apiKeys.live.secret !== remote.apiKeys.live.secret) {
|
|
165
|
+
conflicts.push('Live environment secret API key');
|
|
166
|
+
}
|
|
167
|
+
return conflicts;
|
|
168
|
+
}
|
|
169
|
+
mergeConfigs(local, remote) {
|
|
170
|
+
// Start with remote as base, then merge local specifics
|
|
171
|
+
const merged = { ...remote };
|
|
172
|
+
// Keep local API keys if they exist (user-specific)
|
|
173
|
+
if (local.apiKeys) {
|
|
174
|
+
merged.apiKeys = { ...merged.apiKeys, ...local.apiKeys };
|
|
175
|
+
}
|
|
176
|
+
// Keep local webhook secrets (environment-specific)
|
|
177
|
+
if (local.webhookSecrets) {
|
|
178
|
+
merged.webhookSecrets = { ...merged.webhookSecrets, ...local.webhookSecrets };
|
|
179
|
+
}
|
|
180
|
+
// Keep local team settings (user-specific)
|
|
181
|
+
if (local.team) {
|
|
182
|
+
merged.team = { ...merged.team, ...local.team };
|
|
183
|
+
}
|
|
184
|
+
return merged;
|
|
185
|
+
}
|
|
186
|
+
async updateTeamConfig(repo, branch) {
|
|
187
|
+
let config = await this.config.load();
|
|
188
|
+
if (!config) {
|
|
189
|
+
config = this.config.getDefaultConfig();
|
|
190
|
+
}
|
|
191
|
+
if (!config.team) {
|
|
192
|
+
config.team = {};
|
|
193
|
+
}
|
|
194
|
+
config.team.repo = repo;
|
|
195
|
+
config.team.branch = branch;
|
|
196
|
+
await this.config.save(config);
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
exports.TeamSyncService = TeamSyncService;
|
|
200
|
+
//# sourceMappingURL=sync.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sync.js","sourceRoot":"","sources":["../../../src/services/github/sync.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { ConfigManager } from '../config/manager';
|
|
2
|
+
import { ApiClient } from '../api/client';
|
|
3
|
+
import { AnalyticsService } from '../analytics/service';
|
|
4
|
+
export interface WebServerOptions {
|
|
5
|
+
port: number;
|
|
6
|
+
host?: string;
|
|
7
|
+
configManager: ConfigManager;
|
|
8
|
+
apiClient: ApiClient;
|
|
9
|
+
analyticsService: AnalyticsService;
|
|
10
|
+
}
|
|
11
|
+
export declare class WebServer {
|
|
12
|
+
private app;
|
|
13
|
+
private server;
|
|
14
|
+
private io;
|
|
15
|
+
private configManager;
|
|
16
|
+
private apiClient;
|
|
17
|
+
private analyticsService;
|
|
18
|
+
private logger;
|
|
19
|
+
private port;
|
|
20
|
+
private host;
|
|
21
|
+
constructor(options: WebServerOptions);
|
|
22
|
+
private setupMiddleware;
|
|
23
|
+
private setupRoutes;
|
|
24
|
+
private setupSocketHandlers;
|
|
25
|
+
start(): Promise<void>;
|
|
26
|
+
stop(): Promise<void>;
|
|
27
|
+
getPort(): number;
|
|
28
|
+
emitWebhookEvent(event: any): void;
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=server.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../../src/services/web/server.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAClD,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAC1C,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAGxD,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,aAAa,EAAE,aAAa,CAAC;IAC7B,SAAS,EAAE,SAAS,CAAC;IACrB,gBAAgB,EAAE,gBAAgB,CAAC;CACpC;AAED,qBAAa,SAAS;IACpB,OAAO,CAAC,GAAG,CAAsB;IACjC,OAAO,CAAC,MAAM,CAAa;IAC3B,OAAO,CAAC,EAAE,CAAe;IACzB,OAAO,CAAC,aAAa,CAAgB;IACrC,OAAO,CAAC,SAAS,CAAY;IAC7B,OAAO,CAAC,gBAAgB,CAAmB;IAC3C,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,IAAI,CAAS;IACrB,OAAO,CAAC,IAAI,CAAS;gBAET,OAAO,EAAE,gBAAgB;IAiBrC,OAAO,CAAC,eAAe;IAuBvB,OAAO,CAAC,WAAW;IA2EnB,OAAO,CAAC,mBAAmB;IAiBd,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IActB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAU3B,OAAO,IAAI,MAAM;IAIjB,gBAAgB,CAAC,KAAK,EAAE,GAAG,GAAG,IAAI;CAG1C"}
|
|
@@ -0,0 +1,159 @@
|
|
|
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.WebServer = void 0;
|
|
7
|
+
const express_1 = __importDefault(require("express"));
|
|
8
|
+
const http_1 = require("http");
|
|
9
|
+
const socket_io_1 = require("socket.io");
|
|
10
|
+
const path_1 = __importDefault(require("path"));
|
|
11
|
+
const logger_1 = __importDefault(require("../../utils/logger"));
|
|
12
|
+
class WebServer {
|
|
13
|
+
constructor(options) {
|
|
14
|
+
this.port = options.port;
|
|
15
|
+
this.host = options.host || 'localhost';
|
|
16
|
+
this.configManager = options.configManager;
|
|
17
|
+
this.apiClient = options.apiClient;
|
|
18
|
+
this.analyticsService = options.analyticsService;
|
|
19
|
+
this.logger = new logger_1.default();
|
|
20
|
+
this.app = (0, express_1.default)();
|
|
21
|
+
this.server = new http_1.Server(this.app);
|
|
22
|
+
this.io = new socket_io_1.Server(this.server);
|
|
23
|
+
this.setupMiddleware();
|
|
24
|
+
this.setupRoutes();
|
|
25
|
+
this.setupSocketHandlers();
|
|
26
|
+
}
|
|
27
|
+
setupMiddleware() {
|
|
28
|
+
// Serve static files from web directory
|
|
29
|
+
this.app.use(express_1.default.static(path_1.default.join(__dirname, '../../../web')));
|
|
30
|
+
// Parse JSON bodies
|
|
31
|
+
this.app.use(express_1.default.json());
|
|
32
|
+
// CORS for local development
|
|
33
|
+
this.app.use((req, res, next) => {
|
|
34
|
+
res.header('Access-Control-Allow-Origin', '*');
|
|
35
|
+
res.header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');
|
|
36
|
+
res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept, Authorization');
|
|
37
|
+
if (req.method === 'OPTIONS') {
|
|
38
|
+
res.sendStatus(200);
|
|
39
|
+
}
|
|
40
|
+
else {
|
|
41
|
+
next();
|
|
42
|
+
}
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
setupRoutes() {
|
|
46
|
+
// API routes for frontend
|
|
47
|
+
this.app.get('/api/config', async (_req, res) => {
|
|
48
|
+
try {
|
|
49
|
+
const config = await this.configManager.load();
|
|
50
|
+
res.json({ success: true, data: config });
|
|
51
|
+
}
|
|
52
|
+
catch (error) {
|
|
53
|
+
this.logger.error('Failed to load config for web API', error);
|
|
54
|
+
res.status(500).json({ success: false, error: 'Failed to load configuration' });
|
|
55
|
+
}
|
|
56
|
+
});
|
|
57
|
+
this.app.put('/api/config', async (req, res) => {
|
|
58
|
+
try {
|
|
59
|
+
const { key, value } = req.body;
|
|
60
|
+
if (!key || value === undefined) {
|
|
61
|
+
return res.status(400).json({ success: false, error: 'Key and value are required' });
|
|
62
|
+
}
|
|
63
|
+
const config = await this.configManager.load();
|
|
64
|
+
if (!config) {
|
|
65
|
+
return res.status(404).json({ success: false, error: 'Configuration not found' });
|
|
66
|
+
}
|
|
67
|
+
// Set the configuration value
|
|
68
|
+
const keys = key.split('.');
|
|
69
|
+
let current = config;
|
|
70
|
+
for (let i = 0; i < keys.length - 1; i++) {
|
|
71
|
+
if (!current[keys[i]]) {
|
|
72
|
+
current[keys[i]] = {};
|
|
73
|
+
}
|
|
74
|
+
current = current[keys[i]];
|
|
75
|
+
}
|
|
76
|
+
current[keys[keys.length - 1]] = value;
|
|
77
|
+
await this.configManager.save(config);
|
|
78
|
+
// Notify connected clients
|
|
79
|
+
this.io.emit('config:updated', { key, value });
|
|
80
|
+
res.json({ success: true });
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
catch (error) {
|
|
84
|
+
this.logger.error('Failed to update config via web API', error);
|
|
85
|
+
res.status(500).json({ success: false, error: 'Failed to update configuration' });
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
});
|
|
89
|
+
this.app.get('/api/webhooks', async (_req, res) => {
|
|
90
|
+
try {
|
|
91
|
+
const webhooks = await this.apiClient.listWebhooks();
|
|
92
|
+
res.json({ success: true, data: webhooks });
|
|
93
|
+
}
|
|
94
|
+
catch (error) {
|
|
95
|
+
this.logger.error('Failed to fetch webhooks for web API', error);
|
|
96
|
+
res.status(500).json({ success: false, error: 'Failed to fetch webhooks' });
|
|
97
|
+
}
|
|
98
|
+
});
|
|
99
|
+
this.app.get('/api/analytics', (_req, res) => {
|
|
100
|
+
try {
|
|
101
|
+
const analytics = this.analyticsService.getAnalytics();
|
|
102
|
+
res.json({ success: true, data: analytics });
|
|
103
|
+
}
|
|
104
|
+
catch (error) {
|
|
105
|
+
this.logger.error('Failed to fetch analytics for web API', error);
|
|
106
|
+
res.status(500).json({ success: false, error: 'Failed to fetch analytics' });
|
|
107
|
+
}
|
|
108
|
+
});
|
|
109
|
+
// Serve the main dashboard
|
|
110
|
+
this.app.get('/', (_req, res) => {
|
|
111
|
+
res.sendFile(path_1.default.join(__dirname, '../../../web/index.html'));
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
setupSocketHandlers() {
|
|
115
|
+
this.io.on('connection', (socket) => {
|
|
116
|
+
this.logger.info(`Web client connected: ${socket.id}`);
|
|
117
|
+
socket.on('disconnect', () => {
|
|
118
|
+
this.logger.info(`Web client disconnected: ${socket.id}`);
|
|
119
|
+
});
|
|
120
|
+
// Handle real-time webhook events (to be integrated with dev server)
|
|
121
|
+
socket.on('webhook:event', (event) => {
|
|
122
|
+
this.logger.info('Webhook event received via socket', event);
|
|
123
|
+
// Forward to all connected clients
|
|
124
|
+
socket.broadcast.emit('webhook:event', event);
|
|
125
|
+
});
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
async start() {
|
|
129
|
+
return new Promise((resolve, reject) => {
|
|
130
|
+
this.server.listen(this.port, this.host, (error) => {
|
|
131
|
+
if (error) {
|
|
132
|
+
this.logger.error('Failed to start web server', error);
|
|
133
|
+
reject(error);
|
|
134
|
+
}
|
|
135
|
+
else {
|
|
136
|
+
this.logger.info(`PayMongo GUI Dashboard running at http://${this.host}:${this.port}`);
|
|
137
|
+
resolve();
|
|
138
|
+
}
|
|
139
|
+
});
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
async stop() {
|
|
143
|
+
return new Promise((resolve) => {
|
|
144
|
+
this.io.close();
|
|
145
|
+
this.server.close(() => {
|
|
146
|
+
this.logger.info('Web server stopped');
|
|
147
|
+
resolve();
|
|
148
|
+
});
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
getPort() {
|
|
152
|
+
return this.port;
|
|
153
|
+
}
|
|
154
|
+
emitWebhookEvent(event) {
|
|
155
|
+
this.io.emit('webhook:event', event);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
exports.WebServer = WebServer;
|
|
159
|
+
//# sourceMappingURL=server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../../src/services/web/server.ts"],"names":[],"mappings":"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"}
|