@vue-skuilder/common 0.1.6 → 0.1.8-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/docker/CouchDBManager.d.ts +84 -0
- package/dist/docker/CouchDBManager.d.ts.map +1 -0
- package/dist/docker/CouchDBManager.js +347 -0
- package/dist/docker/CouchDBManager.js.map +1 -0
- package/dist/docker/CouchDBManager.mjs +343 -0
- package/dist/docker/index.d.ts +3 -0
- package/dist/docker/index.d.ts.map +1 -0
- package/dist/docker/index.js +6 -0
- package/dist/docker/index.js.map +1 -0
- package/dist/docker/index.mjs +2 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +2 -0
- package/dist/wire-format.d.ts +17 -2
- package/dist/wire-format.d.ts.map +1 -1
- package/dist/wire-format.js +1 -0
- package/dist/wire-format.js.map +1 -1
- package/dist/wire-format.mjs +1 -0
- package/package.json +8 -2
- package/src/docker/CouchDBManager.ts +395 -0
- package/src/docker/index.ts +2 -0
- package/src/index.ts +3 -0
- package/src/wire-format.ts +18 -1
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { EventEmitter } from 'events';
|
|
2
|
+
export interface CouchDBConfig {
|
|
3
|
+
mode: 'blank' | 'test-data' | 'custom';
|
|
4
|
+
port: number;
|
|
5
|
+
containerName?: string;
|
|
6
|
+
image?: string;
|
|
7
|
+
username?: string;
|
|
8
|
+
password?: string;
|
|
9
|
+
dataVolume?: string;
|
|
10
|
+
configFile?: string;
|
|
11
|
+
maxStartupWaitMs?: number;
|
|
12
|
+
}
|
|
13
|
+
export interface CouchDBManagerOptions {
|
|
14
|
+
onLog?: (message: string) => void;
|
|
15
|
+
onError?: (error: string) => void;
|
|
16
|
+
}
|
|
17
|
+
export declare class CouchDBManager extends EventEmitter {
|
|
18
|
+
private config;
|
|
19
|
+
private options;
|
|
20
|
+
private isStarting;
|
|
21
|
+
constructor(config: CouchDBConfig, options?: CouchDBManagerOptions);
|
|
22
|
+
private log;
|
|
23
|
+
private error;
|
|
24
|
+
/**
|
|
25
|
+
* Check if Docker is available
|
|
26
|
+
*/
|
|
27
|
+
checkDockerAvailable(): Promise<boolean>;
|
|
28
|
+
/**
|
|
29
|
+
* Check if container exists
|
|
30
|
+
*/
|
|
31
|
+
private containerExists;
|
|
32
|
+
/**
|
|
33
|
+
* Check if container is running
|
|
34
|
+
*/
|
|
35
|
+
private isContainerRunning;
|
|
36
|
+
/**
|
|
37
|
+
* Stop and remove existing container
|
|
38
|
+
*/
|
|
39
|
+
private cleanupExistingContainer;
|
|
40
|
+
/**
|
|
41
|
+
* Build Docker run command based on configuration
|
|
42
|
+
*/
|
|
43
|
+
private buildDockerCommand;
|
|
44
|
+
/**
|
|
45
|
+
* Wait for CouchDB to be ready with admin credentials working
|
|
46
|
+
*/
|
|
47
|
+
private waitForReady;
|
|
48
|
+
/**
|
|
49
|
+
* Start CouchDB container
|
|
50
|
+
*/
|
|
51
|
+
start(): Promise<void>;
|
|
52
|
+
/**
|
|
53
|
+
* Stop CouchDB container
|
|
54
|
+
*/
|
|
55
|
+
stop(): Promise<void>;
|
|
56
|
+
/**
|
|
57
|
+
* Remove CouchDB container and volumes
|
|
58
|
+
*/
|
|
59
|
+
remove(): Promise<void>;
|
|
60
|
+
/**
|
|
61
|
+
* Get container status
|
|
62
|
+
*/
|
|
63
|
+
getStatus(): Promise<'running' | 'stopped' | 'missing'>;
|
|
64
|
+
/**
|
|
65
|
+
* Get connection URL for this CouchDB instance
|
|
66
|
+
*/
|
|
67
|
+
getConnectionUrl(): string;
|
|
68
|
+
/**
|
|
69
|
+
* Get connection details for applications
|
|
70
|
+
*/
|
|
71
|
+
getConnectionDetails(): {
|
|
72
|
+
protocol: string;
|
|
73
|
+
host: string;
|
|
74
|
+
port: number;
|
|
75
|
+
username: string;
|
|
76
|
+
password: string;
|
|
77
|
+
url: string;
|
|
78
|
+
};
|
|
79
|
+
/**
|
|
80
|
+
* Configure CORS settings for browser access with retry logic
|
|
81
|
+
*/
|
|
82
|
+
private configureCORS;
|
|
83
|
+
}
|
|
84
|
+
//# sourceMappingURL=CouchDBManager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CouchDBManager.d.ts","sourceRoot":"","sources":["../../src/docker/CouchDBManager.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AAEtC,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,OAAO,GAAG,WAAW,GAAG,QAAQ,CAAC;IACvC,IAAI,EAAE,MAAM,CAAC;IACb,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,qBAAqB;IACpC,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;CACnC;AAED,qBAAa,cAAe,SAAQ,YAAY;IAC9C,OAAO,CAAC,MAAM,CAA0B;IACxC,OAAO,CAAC,OAAO,CAAwB;IACvC,OAAO,CAAC,UAAU,CAAS;gBAEf,MAAM,EAAE,aAAa,EAAE,OAAO,GAAE,qBAA0B;IAsBtE,OAAO,CAAC,GAAG;IAIX,OAAO,CAAC,KAAK;IAIb;;OAEG;IACG,oBAAoB,IAAI,OAAO,CAAC,OAAO,CAAC;IAS9C;;OAEG;YACW,eAAe;IAY7B;;OAEG;YACW,kBAAkB;IAYhC;;OAEG;YACW,wBAAwB;IAqBtC;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAoC1B;;OAEG;YACW,YAAY;IAsC1B;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAwC5B;;OAEG;IACG,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAgB3B;;OAEG;IACG,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;IAgB7B;;OAEG;IACG,SAAS,IAAI,OAAO,CAAC,SAAS,GAAG,SAAS,GAAG,SAAS,CAAC;IAY7D;;OAEG;IACH,gBAAgB,IAAI,MAAM;IAI1B;;OAEG;IACH,oBAAoB;;;;;;;;IAWpB;;OAEG;YACW,aAAa;CAyE5B"}
|
|
@@ -0,0 +1,347 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.CouchDBManager = void 0;
|
|
4
|
+
const child_process_1 = require("child_process");
|
|
5
|
+
const events_1 = require("events");
|
|
6
|
+
class CouchDBManager extends events_1.EventEmitter {
|
|
7
|
+
config;
|
|
8
|
+
options;
|
|
9
|
+
isStarting = false;
|
|
10
|
+
constructor(config, options = {}) {
|
|
11
|
+
super();
|
|
12
|
+
// Set defaults
|
|
13
|
+
this.config = {
|
|
14
|
+
mode: config.mode,
|
|
15
|
+
port: config.port,
|
|
16
|
+
containerName: config.containerName || `skuilder-couch-${config.port}`,
|
|
17
|
+
image: config.image || 'couchdb:3.4.3',
|
|
18
|
+
username: config.username || 'admin',
|
|
19
|
+
password: config.password || 'password',
|
|
20
|
+
dataVolume: config.dataVolume || '',
|
|
21
|
+
configFile: config.configFile || '',
|
|
22
|
+
maxStartupWaitMs: config.maxStartupWaitMs || 30000,
|
|
23
|
+
};
|
|
24
|
+
this.options = {
|
|
25
|
+
onLog: options.onLog || (() => { }),
|
|
26
|
+
onError: options.onError || (() => { }),
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
log(message) {
|
|
30
|
+
this.options.onLog(message);
|
|
31
|
+
}
|
|
32
|
+
error(message) {
|
|
33
|
+
this.options.onError(message);
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Check if Docker is available
|
|
37
|
+
*/
|
|
38
|
+
async checkDockerAvailable() {
|
|
39
|
+
try {
|
|
40
|
+
(0, child_process_1.execSync)('docker --version', { stdio: 'pipe' });
|
|
41
|
+
return true;
|
|
42
|
+
}
|
|
43
|
+
catch {
|
|
44
|
+
return false;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Check if container exists
|
|
49
|
+
*/
|
|
50
|
+
async containerExists() {
|
|
51
|
+
try {
|
|
52
|
+
const result = (0, child_process_1.execSync)(`docker ps -a -q -f name=^${this.config.containerName}$`, { stdio: 'pipe' }).toString().trim();
|
|
53
|
+
return result.length > 0;
|
|
54
|
+
}
|
|
55
|
+
catch {
|
|
56
|
+
return false;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Check if container is running
|
|
61
|
+
*/
|
|
62
|
+
async isContainerRunning() {
|
|
63
|
+
try {
|
|
64
|
+
const result = (0, child_process_1.execSync)(`docker ps -q -f name=^${this.config.containerName}$`, { stdio: 'pipe' }).toString().trim();
|
|
65
|
+
return result.length > 0;
|
|
66
|
+
}
|
|
67
|
+
catch {
|
|
68
|
+
return false;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Stop and remove existing container
|
|
73
|
+
*/
|
|
74
|
+
async cleanupExistingContainer() {
|
|
75
|
+
if (await this.containerExists()) {
|
|
76
|
+
this.log(`Found existing container '${this.config.containerName}'. Cleaning up...`);
|
|
77
|
+
try {
|
|
78
|
+
if (await this.isContainerRunning()) {
|
|
79
|
+
this.log('Stopping container...');
|
|
80
|
+
(0, child_process_1.execSync)(`docker stop ${this.config.containerName}`, { stdio: 'pipe' });
|
|
81
|
+
this.log('Container stopped.');
|
|
82
|
+
}
|
|
83
|
+
this.log('Removing container...');
|
|
84
|
+
(0, child_process_1.execSync)(`docker rm ${this.config.containerName}`, { stdio: 'pipe' });
|
|
85
|
+
this.log('Container removed.');
|
|
86
|
+
}
|
|
87
|
+
catch (error) {
|
|
88
|
+
this.error(`Error during cleanup: ${error instanceof Error ? error.message : String(error)}`);
|
|
89
|
+
throw error;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Build Docker run command based on configuration
|
|
95
|
+
*/
|
|
96
|
+
buildDockerCommand() {
|
|
97
|
+
const cmd = [
|
|
98
|
+
'run', '-d',
|
|
99
|
+
'--name', this.config.containerName,
|
|
100
|
+
'-p', `${this.config.port}:5984`,
|
|
101
|
+
'-e', `COUCHDB_USER=${this.config.username}`,
|
|
102
|
+
'-e', `COUCHDB_PASSWORD=${this.config.password}`,
|
|
103
|
+
];
|
|
104
|
+
// Add volume mounts based on mode
|
|
105
|
+
switch (this.config.mode) {
|
|
106
|
+
case 'test-data':
|
|
107
|
+
if (this.config.dataVolume) {
|
|
108
|
+
cmd.push('-v', `${this.config.dataVolume}:/opt/couchdb/data`);
|
|
109
|
+
}
|
|
110
|
+
if (this.config.configFile) {
|
|
111
|
+
cmd.push('-v', `${this.config.configFile}:/opt/couchdb/etc/local.ini`);
|
|
112
|
+
}
|
|
113
|
+
break;
|
|
114
|
+
case 'custom':
|
|
115
|
+
if (this.config.dataVolume) {
|
|
116
|
+
cmd.push('-v', `${this.config.dataVolume}:/opt/couchdb/data`);
|
|
117
|
+
}
|
|
118
|
+
if (this.config.configFile) {
|
|
119
|
+
cmd.push('-v', `${this.config.configFile}:/opt/couchdb/etc/local.ini`);
|
|
120
|
+
}
|
|
121
|
+
break;
|
|
122
|
+
case 'blank':
|
|
123
|
+
// No volume mounts for blank mode - clean slate
|
|
124
|
+
break;
|
|
125
|
+
}
|
|
126
|
+
cmd.push(this.config.image);
|
|
127
|
+
return cmd;
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Wait for CouchDB to be ready with admin credentials working
|
|
131
|
+
*/
|
|
132
|
+
async waitForReady() {
|
|
133
|
+
const maxAttempts = Math.floor(this.config.maxStartupWaitMs / 1000);
|
|
134
|
+
let attempts = 0;
|
|
135
|
+
return new Promise((resolve, reject) => {
|
|
136
|
+
const checkInterval = setInterval(() => {
|
|
137
|
+
attempts++;
|
|
138
|
+
try {
|
|
139
|
+
// First check basic connectivity
|
|
140
|
+
(0, child_process_1.execSync)(`curl -s http://localhost:${this.config.port}/`, { stdio: 'pipe' });
|
|
141
|
+
// Then verify admin credentials work by checking _up endpoint
|
|
142
|
+
const auth = `${this.config.username}:${this.config.password}`;
|
|
143
|
+
const result = (0, child_process_1.execSync)(`curl -s http://${auth}@localhost:${this.config.port}/_up`, { stdio: 'pipe' }).toString();
|
|
144
|
+
// _up endpoint should return {"status":"ok"} when admin is ready
|
|
145
|
+
if (result.includes('"status":"ok"')) {
|
|
146
|
+
clearInterval(checkInterval);
|
|
147
|
+
this.log('CouchDB is ready with admin credentials!');
|
|
148
|
+
resolve();
|
|
149
|
+
}
|
|
150
|
+
else {
|
|
151
|
+
// CouchDB responds but admin not ready yet
|
|
152
|
+
this.log(`CouchDB responding but admin not ready (attempt ${attempts}/${maxAttempts})`);
|
|
153
|
+
if (attempts >= maxAttempts) {
|
|
154
|
+
clearInterval(checkInterval);
|
|
155
|
+
reject(new Error('CouchDB admin credentials failed to become ready within timeout period'));
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
catch {
|
|
160
|
+
if (attempts >= maxAttempts) {
|
|
161
|
+
clearInterval(checkInterval);
|
|
162
|
+
reject(new Error('CouchDB failed to start within timeout period'));
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
}, 1000);
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Start CouchDB container
|
|
170
|
+
*/
|
|
171
|
+
async start() {
|
|
172
|
+
if (this.isStarting) {
|
|
173
|
+
throw new Error('CouchDB is already starting');
|
|
174
|
+
}
|
|
175
|
+
this.isStarting = true;
|
|
176
|
+
try {
|
|
177
|
+
// Check Docker availability
|
|
178
|
+
if (!(await this.checkDockerAvailable())) {
|
|
179
|
+
throw new Error('Docker is not available or not running');
|
|
180
|
+
}
|
|
181
|
+
// Clean up any existing container
|
|
182
|
+
await this.cleanupExistingContainer();
|
|
183
|
+
// Build and execute Docker command
|
|
184
|
+
const dockerCmd = this.buildDockerCommand();
|
|
185
|
+
this.log(`Starting CouchDB container: docker ${dockerCmd.join(' ')}`);
|
|
186
|
+
(0, child_process_1.execSync)(`docker ${dockerCmd.join(' ')}`, { stdio: 'pipe' });
|
|
187
|
+
this.log('Container started successfully');
|
|
188
|
+
// Wait for CouchDB to be ready
|
|
189
|
+
this.log('Waiting for CouchDB to be ready...');
|
|
190
|
+
await this.waitForReady();
|
|
191
|
+
// Configure CORS for browser access
|
|
192
|
+
await this.configureCORS();
|
|
193
|
+
this.emit('ready');
|
|
194
|
+
}
|
|
195
|
+
catch (error) {
|
|
196
|
+
this.error(`Failed to start CouchDB: ${error instanceof Error ? error.message : String(error)}`);
|
|
197
|
+
this.emit('error', error);
|
|
198
|
+
throw error;
|
|
199
|
+
}
|
|
200
|
+
finally {
|
|
201
|
+
this.isStarting = false;
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* Stop CouchDB container
|
|
206
|
+
*/
|
|
207
|
+
async stop() {
|
|
208
|
+
try {
|
|
209
|
+
if (await this.isContainerRunning()) {
|
|
210
|
+
this.log('Stopping CouchDB container...');
|
|
211
|
+
(0, child_process_1.execSync)(`docker stop ${this.config.containerName}`, { stdio: 'pipe' });
|
|
212
|
+
this.log('CouchDB stopped');
|
|
213
|
+
this.emit('stopped');
|
|
214
|
+
}
|
|
215
|
+
else {
|
|
216
|
+
this.log('CouchDB container is not running');
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
catch (error) {
|
|
220
|
+
this.error(`Failed to stop CouchDB: ${error instanceof Error ? error.message : String(error)}`);
|
|
221
|
+
throw error;
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
/**
|
|
225
|
+
* Remove CouchDB container and volumes
|
|
226
|
+
*/
|
|
227
|
+
async remove() {
|
|
228
|
+
try {
|
|
229
|
+
await this.stop();
|
|
230
|
+
if (await this.containerExists()) {
|
|
231
|
+
this.log('Removing CouchDB container...');
|
|
232
|
+
(0, child_process_1.execSync)(`docker rm ${this.config.containerName}`, { stdio: 'pipe' });
|
|
233
|
+
this.log('CouchDB container removed');
|
|
234
|
+
this.emit('removed');
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
catch (error) {
|
|
238
|
+
this.error(`Failed to remove CouchDB: ${error instanceof Error ? error.message : String(error)}`);
|
|
239
|
+
throw error;
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
/**
|
|
243
|
+
* Get container status
|
|
244
|
+
*/
|
|
245
|
+
async getStatus() {
|
|
246
|
+
if (!(await this.containerExists())) {
|
|
247
|
+
return 'missing';
|
|
248
|
+
}
|
|
249
|
+
if (await this.isContainerRunning()) {
|
|
250
|
+
return 'running';
|
|
251
|
+
}
|
|
252
|
+
return 'stopped';
|
|
253
|
+
}
|
|
254
|
+
/**
|
|
255
|
+
* Get connection URL for this CouchDB instance
|
|
256
|
+
*/
|
|
257
|
+
getConnectionUrl() {
|
|
258
|
+
return `http://localhost:${this.config.port}`;
|
|
259
|
+
}
|
|
260
|
+
/**
|
|
261
|
+
* Get connection details for applications
|
|
262
|
+
*/
|
|
263
|
+
getConnectionDetails() {
|
|
264
|
+
return {
|
|
265
|
+
protocol: 'http',
|
|
266
|
+
host: 'localhost',
|
|
267
|
+
port: this.config.port,
|
|
268
|
+
username: this.config.username,
|
|
269
|
+
password: this.config.password,
|
|
270
|
+
url: this.getConnectionUrl(),
|
|
271
|
+
};
|
|
272
|
+
}
|
|
273
|
+
/**
|
|
274
|
+
* Configure CORS settings for browser access with retry logic
|
|
275
|
+
*/
|
|
276
|
+
async configureCORS() {
|
|
277
|
+
const maxRetries = 3;
|
|
278
|
+
let attempt = 0;
|
|
279
|
+
while (attempt < maxRetries) {
|
|
280
|
+
try {
|
|
281
|
+
attempt++;
|
|
282
|
+
this.log(`Configuring CORS for browser access (attempt ${attempt}/${maxRetries})...`);
|
|
283
|
+
const baseUrl = `http://localhost:${this.config.port}`;
|
|
284
|
+
const auth = `${this.config.username}:${this.config.password}`;
|
|
285
|
+
// Enable CORS with comprehensive PouchDB-compatible headers
|
|
286
|
+
// Note: CouchDB requires BOTH chttpd/enable_cors AND cors section settings
|
|
287
|
+
const corsCommands = [
|
|
288
|
+
// First: Enable CORS globally in chttpd section (CRITICAL!)
|
|
289
|
+
`curl -X PUT "${baseUrl}/_node/_local/_config/chttpd/enable_cors" -d '"true"' -H "Content-Type: application/json" -u "${auth}"`,
|
|
290
|
+
// Then: Configure CORS settings in cors section
|
|
291
|
+
`curl -X PUT "${baseUrl}/_node/_local/_config/cors/enable" -d '"true"' -H "Content-Type: application/json" -u "${auth}"`,
|
|
292
|
+
`curl -X PUT "${baseUrl}/_node/_local/_config/cors/origins" -d '"*"' -H "Content-Type: application/json" -u "${auth}"`,
|
|
293
|
+
`curl -X PUT "${baseUrl}/_node/_local/_config/cors/methods" -d '"GET,POST,PUT,DELETE,OPTIONS,HEAD"' -H "Content-Type: application/json" -u "${auth}"`,
|
|
294
|
+
`curl -X PUT "${baseUrl}/_node/_local/_config/cors/headers" -d '"accept,authorization,content-type,origin,referer,x-csrf-token,cache-control,if-none-match,x-requested-with,pragma,expires,x-couch-request-id,x-couch-update-newrev"' -H "Content-Type: application/json" -u "${auth}"`,
|
|
295
|
+
`curl -X PUT "${baseUrl}/_node/_local/_config/cors/credentials" -d '"true"' -H "Content-Type: application/json" -u "${auth}"`,
|
|
296
|
+
];
|
|
297
|
+
for (const cmd of corsCommands) {
|
|
298
|
+
const result = (0, child_process_1.execSync)(cmd, { stdio: 'pipe' }).toString().trim();
|
|
299
|
+
// Check for CouchDB error responses
|
|
300
|
+
if (result.includes('"error":"unauthorized"')) {
|
|
301
|
+
this.error(`CORS command failed with unauthorized: ${cmd}`);
|
|
302
|
+
this.error(`Response: ${result}`);
|
|
303
|
+
throw new Error(`CORS configuration failed: unauthorized access. Admin credentials may not be ready.`);
|
|
304
|
+
}
|
|
305
|
+
else if (result.includes('"error":')) {
|
|
306
|
+
this.error(`CORS command failed with error: ${cmd}`);
|
|
307
|
+
this.error(`Response: ${result}`);
|
|
308
|
+
throw new Error(`CORS configuration failed: ${result}`);
|
|
309
|
+
}
|
|
310
|
+
else {
|
|
311
|
+
this.log(`CORS command success: ${result || 'OK'}`);
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
// Verify CORS configuration took effect
|
|
315
|
+
try {
|
|
316
|
+
this.log('Verifying CORS configuration...');
|
|
317
|
+
const verifyCmd = `curl -s "${baseUrl}/_node/_local/_config/cors" -u "${auth}"`;
|
|
318
|
+
const corsSettings = (0, child_process_1.execSync)(verifyCmd, { stdio: 'pipe' }).toString();
|
|
319
|
+
this.log(`CORS verification result: ${corsSettings.trim()}`);
|
|
320
|
+
}
|
|
321
|
+
catch (error) {
|
|
322
|
+
this.log(`Warning: CORS verification failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
323
|
+
}
|
|
324
|
+
this.log('CORS configuration completed successfully');
|
|
325
|
+
return; // Success - exit retry loop
|
|
326
|
+
}
|
|
327
|
+
catch (error) {
|
|
328
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
329
|
+
if (attempt < maxRetries && errorMessage.includes('unauthorized')) {
|
|
330
|
+
// Retry with exponential backoff for auth issues
|
|
331
|
+
const delay = Math.pow(2, attempt - 1) * 1000; // 1s, 2s, 4s
|
|
332
|
+
this.log(`CORS configuration failed (attempt ${attempt}/${maxRetries}), retrying in ${delay}ms...`);
|
|
333
|
+
await new Promise(resolve => setTimeout(resolve, delay));
|
|
334
|
+
continue;
|
|
335
|
+
}
|
|
336
|
+
else {
|
|
337
|
+
// Final attempt failed or non-auth error
|
|
338
|
+
this.error(`CORS configuration failed after ${attempt} attempts: ${errorMessage}`);
|
|
339
|
+
// Don't throw - CORS failure shouldn't prevent container startup
|
|
340
|
+
return;
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
exports.CouchDBManager = CouchDBManager;
|
|
347
|
+
//# sourceMappingURL=CouchDBManager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CouchDBManager.js","sourceRoot":"","sources":["../../src/docker/CouchDBManager.ts"],"names":[],"mappings":"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"}
|