farm-orchestrator 1.0.1
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/README.md +276 -0
- package/dist/src/bundle.js +1 -0
- package/dist/src/scripts/db-utils.d.ts +2 -0
- package/dist/src/scripts/db-utils.js +191 -0
- package/dist/src/scripts/prepare-wda.d.ts +16 -0
- package/dist/src/scripts/prepare-wda.js +609 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/package.json +115 -0
|
@@ -0,0 +1,191 @@
|
|
|
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.createDatabase = createDatabase;
|
|
7
|
+
exports.runMigrations = runMigrations;
|
|
8
|
+
const child_process_1 = require("child_process");
|
|
9
|
+
const fs_1 = __importDefault(require("fs"));
|
|
10
|
+
const path_1 = __importDefault(require("path"));
|
|
11
|
+
const pg_1 = require("pg");
|
|
12
|
+
const dbConfig = {
|
|
13
|
+
host: process.env.DB_HOST || 'localhost',
|
|
14
|
+
port: parseInt(process.env.DB_PORT || '5432', 10),
|
|
15
|
+
user: process.env.DB_USER || 'postgres',
|
|
16
|
+
password: process.env.DB_PASSWORD || '',
|
|
17
|
+
};
|
|
18
|
+
const dbName = process.env.DB_NAME || 'device_farm';
|
|
19
|
+
async function createDatabase() {
|
|
20
|
+
// Try connecting to different default databases to create the target database
|
|
21
|
+
const defaultDatabases = ['postgres', 'template1'];
|
|
22
|
+
let client = null;
|
|
23
|
+
let connected = false;
|
|
24
|
+
console.log(`Attempting to connect to PostgreSQL at ${dbConfig.host}:${dbConfig.port}...`);
|
|
25
|
+
for (const defaultDb of defaultDatabases) {
|
|
26
|
+
try {
|
|
27
|
+
client = new pg_1.Client({
|
|
28
|
+
...dbConfig,
|
|
29
|
+
database: defaultDb,
|
|
30
|
+
});
|
|
31
|
+
await client.connect();
|
|
32
|
+
console.log(`Connected to PostgreSQL as ${dbConfig.user} (via ${defaultDb})`);
|
|
33
|
+
connected = true;
|
|
34
|
+
break;
|
|
35
|
+
}
|
|
36
|
+
catch (error) {
|
|
37
|
+
if (client) {
|
|
38
|
+
try {
|
|
39
|
+
await client.end();
|
|
40
|
+
}
|
|
41
|
+
catch (e) {
|
|
42
|
+
// Ignore cleanup errors
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
// Try next database
|
|
46
|
+
continue;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
if (!connected) {
|
|
50
|
+
console.error('Error: Could not connect to PostgreSQL. Make sure PostgreSQL is running.');
|
|
51
|
+
throw new Error('Could not connect to PostgreSQL');
|
|
52
|
+
}
|
|
53
|
+
if (!client) {
|
|
54
|
+
throw new Error('Client is null despite connected being true');
|
|
55
|
+
}
|
|
56
|
+
try {
|
|
57
|
+
// Check if database exists
|
|
58
|
+
const result = await client.query(`SELECT 1 FROM pg_database WHERE datname = $1`, [dbName]);
|
|
59
|
+
if (result.rows.length > 0) {
|
|
60
|
+
console.log(`Database "${dbName}" already exists.`);
|
|
61
|
+
await client.end();
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
// Create the database
|
|
65
|
+
// Note: Parameterized queries cannot be used for database names in CREATE DATABASE
|
|
66
|
+
// We sanitize by using double quotes, assuming dbName comes from trusted env or config
|
|
67
|
+
await client.query(`CREATE DATABASE "${dbName}"`);
|
|
68
|
+
console.log(`Database "${dbName}" created successfully.`);
|
|
69
|
+
await client.end();
|
|
70
|
+
}
|
|
71
|
+
catch (error) {
|
|
72
|
+
if (error.code === '42P04') {
|
|
73
|
+
// Database already exists (race condition)
|
|
74
|
+
console.log(`Database "${dbName}" already exists.`);
|
|
75
|
+
}
|
|
76
|
+
else {
|
|
77
|
+
console.error('Error creating database:', error.message);
|
|
78
|
+
if (client) {
|
|
79
|
+
await client.end();
|
|
80
|
+
}
|
|
81
|
+
throw error;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
async function runMigrations() {
|
|
86
|
+
console.log('Running database migrations...');
|
|
87
|
+
// Find sequelize-cli executable
|
|
88
|
+
let sequelizeBin;
|
|
89
|
+
let useNode = true;
|
|
90
|
+
try {
|
|
91
|
+
// Try to resolve from node_modules
|
|
92
|
+
const sequelizePkg = require.resolve('sequelize-cli/package.json');
|
|
93
|
+
const pkgRoot = path_1.default.dirname(sequelizePkg);
|
|
94
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
95
|
+
const pkgJson = require(sequelizePkg);
|
|
96
|
+
const binPath = typeof pkgJson.bin === 'string' ? pkgJson.bin : pkgJson.bin['sequelize'];
|
|
97
|
+
sequelizeBin = path_1.default.join(pkgRoot, binPath);
|
|
98
|
+
useNode = true;
|
|
99
|
+
}
|
|
100
|
+
catch (error) {
|
|
101
|
+
console.warn('Could not resolve sequelize-cli from dependencies, trying global or relative path...');
|
|
102
|
+
// Try to find in node_modules/.bin (in current dir and up the tree)
|
|
103
|
+
const possiblePaths = [
|
|
104
|
+
path_1.default.resolve(process.cwd(), 'node_modules', '.bin', 'sequelize-cli'),
|
|
105
|
+
path_1.default.resolve(process.cwd(), '..', 'node_modules', '.bin', 'sequelize-cli'), // parent dir
|
|
106
|
+
path_1.default.resolve(process.cwd(), '..', '..', 'node_modules', '.bin', 'sequelize-cli'), // repo root (if packages/hub)
|
|
107
|
+
];
|
|
108
|
+
const foundBin = possiblePaths.find(p => fs_1.default.existsSync(p));
|
|
109
|
+
if (foundBin) {
|
|
110
|
+
console.log(`Found sequelize-cli at: ${foundBin}`);
|
|
111
|
+
sequelizeBin = foundBin;
|
|
112
|
+
useNode = false; // Executable script/symlink
|
|
113
|
+
}
|
|
114
|
+
else {
|
|
115
|
+
console.warn('Could not find sequelize-cli in common locations, falling back to PATH');
|
|
116
|
+
sequelizeBin = 'sequelize-cli'; // Fallback to PATH
|
|
117
|
+
useNode = false;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
// Find config file
|
|
121
|
+
// In development: src/config/sequelize-cli.js
|
|
122
|
+
// In production (bundled): might be tricky.
|
|
123
|
+
// But we know where the source is relative to CWD usually.
|
|
124
|
+
// If running from node_modules/@device-farm/hub/dist/src/bundle.js
|
|
125
|
+
// process.cwd() is user's project root.
|
|
126
|
+
// We need to point to the config file inside the package.
|
|
127
|
+
// Assuming bundle structure:
|
|
128
|
+
// dist/src/bundle.js
|
|
129
|
+
// src/config/sequelize-cli.js (if copied)
|
|
130
|
+
// OR we can generate a temporary config file.
|
|
131
|
+
// Let's rely on .sequelizerc if it exists in the package root.
|
|
132
|
+
// But package root relative to bundle.js is ../..
|
|
133
|
+
const currentDir = __dirname; // dist/src (if bundled) or src/scripts (if ts-node)
|
|
134
|
+
// Helper to find file recursively up or in common locations
|
|
135
|
+
const findFile = (searchPaths) => {
|
|
136
|
+
for (const p of searchPaths) {
|
|
137
|
+
if (fs_1.default.existsSync(p))
|
|
138
|
+
return p;
|
|
139
|
+
}
|
|
140
|
+
return null;
|
|
141
|
+
};
|
|
142
|
+
// Possible locations for sequelize config
|
|
143
|
+
// 1. Inside built output: dist/src/config/sequelize-cli.js
|
|
144
|
+
// 2. Inside source: src/config/sequelize-cli.js
|
|
145
|
+
const configPath = findFile([
|
|
146
|
+
path_1.default.resolve(currentDir, '../config/sequelize-cli.js'), // dist/src/config/sequelize-cli.js
|
|
147
|
+
path_1.default.resolve(currentDir, '../../src/config/sequelize-cli.js'), // src/config/sequelize-cli.js (from scripts)
|
|
148
|
+
path_1.default.resolve(process.cwd(), 'node_modules/@device-farm/hub/src/config/sequelize-cli.js'),
|
|
149
|
+
]);
|
|
150
|
+
// Possible locations for migrations
|
|
151
|
+
const migrationsPath = findFile([
|
|
152
|
+
path_1.default.resolve(currentDir, '../../migrations'), // dist/src/../../migrations -> dist/migrations ?? No.
|
|
153
|
+
// If we are in dist/src, ../.. is dist. ../../../ is root.
|
|
154
|
+
// If migrations are in root/migrations.
|
|
155
|
+
path_1.default.resolve(currentDir, '../../../migrations'), // from dist/src
|
|
156
|
+
path_1.default.resolve(currentDir, '../../migrations'), // from src/scripts
|
|
157
|
+
path_1.default.resolve(process.cwd(), 'node_modules/@device-farm/hub/migrations'),
|
|
158
|
+
]);
|
|
159
|
+
if (!configPath) {
|
|
160
|
+
throw new Error('Could not find sequelize-cli.js config file');
|
|
161
|
+
}
|
|
162
|
+
if (!migrationsPath) {
|
|
163
|
+
throw new Error('Could not find migrations directory');
|
|
164
|
+
}
|
|
165
|
+
console.log(`Using config: ${configPath}`);
|
|
166
|
+
console.log(`Using migrations: ${migrationsPath}`);
|
|
167
|
+
return new Promise((resolve, reject) => {
|
|
168
|
+
const args = ['db:migrate', `--config=${configPath}`, `--migrations-path=${migrationsPath}`];
|
|
169
|
+
const command = useNode ? process.execPath : sequelizeBin;
|
|
170
|
+
const commandArgs = useNode ? [sequelizeBin, ...args] : args;
|
|
171
|
+
console.log(`Executing: ${command} ${commandArgs.join(' ')}`);
|
|
172
|
+
const child = (0, child_process_1.spawn)(command, commandArgs, {
|
|
173
|
+
stdio: 'inherit',
|
|
174
|
+
env: process.env,
|
|
175
|
+
});
|
|
176
|
+
child.on('close', code => {
|
|
177
|
+
if (code === 0) {
|
|
178
|
+
console.log('Migrations completed successfully.');
|
|
179
|
+
resolve();
|
|
180
|
+
}
|
|
181
|
+
else {
|
|
182
|
+
console.error(`Migrations failed with code ${code}`);
|
|
183
|
+
reject(new Error(`Migrations failed with code ${code}`));
|
|
184
|
+
}
|
|
185
|
+
});
|
|
186
|
+
child.on('error', err => {
|
|
187
|
+
console.error('Failed to start sequelize-cli:', err);
|
|
188
|
+
reject(err);
|
|
189
|
+
});
|
|
190
|
+
});
|
|
191
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WebDriverAgent (WDA) Preparation Script
|
|
3
|
+
*
|
|
4
|
+
* This script builds, signs, and packages WebDriverAgent for iOS devices.
|
|
5
|
+
* It can be run as a CLI command: `hub prepare-wda`
|
|
6
|
+
*
|
|
7
|
+
* Options:
|
|
8
|
+
* --mobile-provisioning-file, -m Path to the mobile provisioning file
|
|
9
|
+
* --wda-project-path, -p Path to WebDriverAgent xcode project
|
|
10
|
+
* --platform Platform type: ios, tvos, or both (default: ios)
|
|
11
|
+
*/
|
|
12
|
+
import { PrepareWdaOptions } from '../config/hub.config';
|
|
13
|
+
/**
|
|
14
|
+
* Main function to prepare WDA
|
|
15
|
+
*/
|
|
16
|
+
export declare function prepareWda(options: PrepareWdaOptions): Promise<void>;
|