Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

V0.0.4 #25

Merged
merged 70 commits into from
Dec 11, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
70 commits
Select commit Hold shift + click to select a range
3791575
Rename class and file 'install' to 'Installer'
erikyo Dec 8, 2023
45ec2e0
Add Database.js file with upload and dump methods
erikyo Dec 8, 2023
daa727a
Refactor package installation classes into separate files
erikyo Dec 8, 2023
ac8af1d
Add Updater.js with update methods for plugins, themes and WordPress
erikyo Dec 8, 2023
ec94d27
Refactor utils.js, moving functions into newly created utils/index.js
erikyo Dec 8, 2023
0aeb047
Refactor code and enhance database functionality
erikyo Dec 8, 2023
41fd51d
Update package version and add new dependencies
erikyo Dec 8, 2023
0426834
Add typings for WPMMconfig object properties
erikyo Dec 8, 2023
9b2d987
Refactor getConfig function for better typing
erikyo Dec 8, 2023
29655bf
Improve code documentation and implement proper naming
erikyo Dec 8, 2023
ccca816
Add comprehensive JSDoc comments and refactor variable names
erikyo Dec 8, 2023
33fba9c
Refactor codebase for clarity and add JSDoc comments
erikyo Dec 8, 2023
e68283e
Add user locale function and improve code readability
erikyo Dec 9, 2023
fa8c1ec
Create WordPress configuration utility functions
erikyo Dec 9, 2023
d3b28f6
Refactor Dump class for WordPress configuration
erikyo Dec 9, 2023
d75d1e9
Correct typo in Initialize.js comments
erikyo Dec 9, 2023
96386a7
Refactor WordPress installer in Installer.js
erikyo Dec 9, 2023
c34e7e2
Refactor Package class and remove Plugin/Theme specific classes
erikyo Dec 9, 2023
15e6a95
Refactor WpPackage setup and configuration
erikyo Dec 9, 2023
bc80770
Refactor WordPress paths utility and action functions
erikyo Dec 9, 2023
0282cdc
Update package version and dependencies in package-lock.json
erikyo Dec 9, 2023
25421ce
: Simplify wp-package.json and reorganize tests
erikyo Dec 9, 2023
ebfb655
Refactor and simplify utility test file imports
erikyo Dec 9, 2023
6e54259
Provides an example for the new database related functions
erikyo Dec 9, 2023
b19665a
Add post-install command runner function
erikyo Dec 9, 2023
263a661
chore
erikyo Dec 9, 2023
6ee55c1
: Implement remote config loading
erikyo Dec 9, 2023
d1484b4
Update baseFolder for WordPress installation
erikyo Dec 9, 2023
86c4c55
Add lib/constants.js file for WordPress install
erikyo Dec 9, 2023
1036322
Refactor WordPress config generation in Initialize.js
erikyo Dec 9, 2023
99afe09
Implement WordPress package update functionality
erikyo Dec 9, 2023
9b2bf81
Refactor Dump.js and improve WordPress version handling
erikyo Dec 9, 2023
44cd7f6
Add husky for git hooks and update scripts
erikyo Dec 9, 2023
b08953c
Implement Updater class and adjust update functionality
erikyo Dec 9, 2023
b854a04
Refactor update method with Updater class and 'updateObject'
erikyo Dec 9, 2023
7b46e00
Refactor updater logic by moving it to Updater class
erikyo Dec 9, 2023
adee258
Update and organize Initialize class methods
erikyo Dec 9, 2023
b02291d
Refactor dependency paths and constructor in Installer class
erikyo Dec 9, 2023
3d64e4e
Refactor lib/utils module and update Installer class
erikyo Dec 9, 2023
255e610
Refactor utility functions and update Installer constructor
erikyo Dec 9, 2023
caa1dee
Remove `wp-package.json` and refactor utility imports
erikyo Dec 9, 2023
f82e789
Refactor code to consolidate utility imports
erikyo Dec 9, 2023
a6ae21a
Update base folder definition and refactor file imports
erikyo Dec 9, 2023
2a795b4
Refactor function name and add new tests to utils.test.js
erikyo Dec 9, 2023
c78c061
Add WordPress configuration parsing functionality and related tests
erikyo Dec 9, 2023
33fa39f
Add initConfig function to data.js
erikyo Dec 10, 2023
06758fe
Refactor getConfig function and connection settings in data.js
erikyo Dec 10, 2023
f71f110
Add axiosFetch function to wordpress.js
erikyo Dec 10, 2023
0841b18
Replace axios.get with axiosFetch in getLastWp function
erikyo Dec 10, 2023
5af2e3c
Add getWpConfigContent function in wordpress.js
erikyo Dec 10, 2023
575bc94
Fix constant names and improve function parsers in wordpress.js
erikyo Dec 10, 2023
9d79a14
Refactor database dump method and improve error handling
erikyo Dec 10, 2023
1b4993f
Update Dump class in lib/Dump.js
erikyo Dec 10, 2023
130c25c
Update casing of constant declarations in lib/constants.js
erikyo Dec 10, 2023
120d1ad
Adapt lib/index.js to handle asynchronous configuration loading
erikyo Dec 10, 2023
c3bfc09
Refactor code to use async functions and rename constants
erikyo Dec 10, 2023
719d2c0
Update parseWpConfig tests and move test assets to fixtures
erikyo Dec 10, 2023
c63a8d1
Add directory existence validation to scanDirectory method
erikyo Dec 10, 2023
3b633b7
Refactor WordPress configuration definitions and simplify action invo…
erikyo Dec 10, 2023
57cbbb7
Add actions.js file with WordPress management functionalities
erikyo Dec 10, 2023
98f741d
Refactor actions in actions.js and index.js
erikyo Dec 10, 2023
c982e82
Refactor code for clarity and error handling in data.js
erikyo Dec 10, 2023
aabc72d
Refactor code and update documentation
erikyo Dec 10, 2023
6a29c76
Update project dependencies and introduce TypeScript
erikyo Dec 10, 2023
9973f23
Refactor and optimize WordPress installation configuration
erikyo Dec 11, 2023
bb8be61
Add utility functions for WordPress configuration parsing and modific…
erikyo Dec 11, 2023
3f8eb28
Add utility prompts for WordPress configuration and dump options
erikyo Dec 11, 2023
c635334
Refactor utility imports and update test configurations
erikyo Dec 11, 2023
da2a62d
Modify typescript target, update eslint script and add dependencies
erikyo Dec 11, 2023
0999c8a
Update configuration handling and refactor prompts
erikyo Dec 11, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 0 additions & 17 deletions .eslintrc.js

This file was deleted.

19 changes: 19 additions & 0 deletions .eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"env": {
"browser": true,
"node": true,
"es2021": true,
"jest": true
},
"extends": "eslint:recommended",
"overrides": [
],
"parserOptions": {
"ecmaVersion": "latest",
"sourceType": "module"
},
"rules": {
"semi": ["error", "always"],
"max-len": ["error", { "code": 200 }]
}
}
5 changes: 5 additions & 0 deletions .husky/pre-commit
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"

npm run lint
npm test
127 changes: 127 additions & 0 deletions lib/Database.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
const mysql = require('mysql2/promise');
const mysqldump = require('mysqldump').default;
const {getConnectionSettings} = require("./utils/data");
const path = require("path");
const fs = require('fs');

/**
* Constructor for the Database class.
*
* @class Database
*/
class Database {
/**
* A description of the entire function.
*
* @param {import('./constants').WPMMconfig} config - The configuration object.
*/
constructor (config) {
// Load configuration from wp-package.json
this.config = config;
}

/**
* Generates a unique filename for the database dump.
*
* @returns {string} - The generated filename.
*/
dbDumpFilename = () => {
const date = new Date().toDateString().replace(" ", "-");
return `${this.config.wordpress.WP_config.DB_NAME}-${date}.sql.gz`;
};

/**
* Uploads a database by executing SQL queries from a specified file.
*
* @async
* @param {string} sqlFilePath - The path to the SQL file.
* @return {Promise<void | Error>} - A Promise that resolves to a MySQL Connection object or throws an Error.
*/
async uploadDatabase (sqlFilePath) {
try {
console.log('Uploading database...');

if (!fs.existsSync(sqlFilePath)) {
return new Error('SQL file not found');
}

if (!this.config) {
return new Error('Database configuration not found');
}

/**
* the connection settings for the database
* @type {mysql.ConnectionOptions} databaseConnectionConfig - The connection settings for the database.
*/
const databaseConnectionConfig = getConnectionSettings(this.config.wordpress.WP_config);

/**
* @type {import('mysql2/promise').Connection} connection - The MySQL connection object.
*/
const connection = await mysql.createConnection(databaseConnectionConfig);

const sqlFileContent = fs.readFileSync(sqlFilePath, 'utf8');
const queries = sqlFileContent.split(';');

for (const query of queries) {
if (query.trim() !== '') {
await connection.query(query);
}
}

console.log('Database uploaded successfully');
connection.end().then(() => {
console.log('👍 Database connection closed');
}).catch(error => {
console.error('🫠 Error closing database connection:', error.message);
});
} catch (/** @type {any} */ error) {
console.error('🔴 Error uploading database:', error.message);
}
}

/**
* Asynchronously dumps the database to the specified output file.
*
* @param {string} basePath - The base path of the WordPress installation.
* @async
* @return {Promise<void | Error>} - A promise that resolves if the database is dumped successfully, or rejects with an error message if an error occurs.
*/
async dumpDatabase (basePath) {
const dumpPath = path.join( basePath, 'backups', 'db');
const dumpFile = path.join( dumpPath, this.dbDumpFilename());

// Check if the directory exists and create it if it doesn't
if (!fs.existsSync(dumpPath)) {
fs.mkdirSync( dumpPath, { recursive: true });
console.log(`ℹ️ Directory created: ${dumpPath}`);
}

console.log(`✳️ Dumping database to ${dumpFile}...`);

if (!this.config.wordpress.WP_config) {
return new Error('🔴 Database configuration not found');
}

/**
* the connection settings for the database
*
* @type {mysqldump.ConnectionOptions} databaseConnectionConfig - The connection settings for the database.
*/
const databaseConnectionConfig = getConnectionSettings(this.config.wordpress.WP_config);

if (databaseConnectionConfig.host === 'localhost') {
console.log('⚠️ Warning: You are using localhost as your database host. This may not work correctly.');
}

mysqldump({
connection: databaseConnectionConfig,
dumpToFile: dumpFile,
compressFile: true
}).catch(error => {
console.error('🔴 Error dumping database:', error.message);
});
}
}

module.exports = Database;
153 changes: 153 additions & 0 deletions lib/Dump.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
const fs = require('fs');
const path = require('path');
const {getCurrentWpInfo} = require("./utils/wordpress.js");
const {getWpConfigContent} = require("./utils/wordpress.js");
const {parseWpConfig} = require("./utils/parsers.js");

/**
* Represents a Dump class for WordPress configuration.
*
* @class Dump
*/
class Dump {
/**
* Constructor for the class.
*
* Initializes the class with the necessary folders for WordPress.
* @param {import("./constants").WPMMpaths} paths - The object containing the paths for the WordPress installation.
*/
constructor (paths) {
this.baseFolder = paths.baseFolder;
this.themeFolder = paths.themeFolder;
this.pluginsFolder = paths.pluginsFolder;
}

/**
* Initializes the function by logging the `baseFolder` and `themeFolder` properties,
* scanning the theme and plugins directories, retrieving the website name from the
* `baseFolder` path, getting the WordPress version from `wp-includes/version.php`,
* determining the language using `Intl.DateTimeFormat().resolvedOptions().locale`,
* and saving the result to a JSON file.
*
* @return {Promise<import('./constants').WPMMconfig|{}>} - The configuration object.
*/
async init() {
const themes = this.scanDirectory(this.themeFolder);
const plugins = this.scanDirectory(this.pluginsFolder);

// the website name
const name = path.basename(this.baseFolder);

console.log(`🔍️ Scanning ${this.baseFolder}`);
/**
* @type {{locale: string|null, version: string|null}}
*/
const wpInfo = getCurrentWpInfo(this.baseFolder);

const wpConfigData = parseWpConfig(
getWpConfigContent(this.baseFolder)
);

const version = wpInfo.version || 'latest';
const language = wpInfo.locale || 'en_US';

const result = {
wordpress: {
name,
version,
language,
WP_config: {
...wpConfigData?.constants,
...wpConfigData?.variables
}
},
themes,
plugins
};

const outputPath = path.join(process.cwd(), 'wp-package.json');

fs.writeFileSync(outputPath, JSON.stringify(result, null, 2));
console.log(`🆗 Wordpress configuration Dump completed. Configuration saved to ${outputPath}`);

return result;
}

/**
* Scans a directory and returns an array of objects containing the name and version of each item found.
*
* @param {string} directory - The path of the directory to scan.
* @return {import('./constants').WPMMconfigPkg[]|null} - An array of objects with the name and version of each item found.
*/
scanDirectory (directory) {
// Check if the directory exists
if (! fs.existsSync(directory)) {
console.log(`⚠️ The directory ${directory} does not exist.`);
return [];
}

const items = fs.readdirSync(directory);
/**
* The array of parsed items
*
* @type {import('./constants').WPMMconfigPkg[]} result
*/
let result= [];

for (const item of items) {
const fullPath = path.join(directory, item);
console.log(`🔍️ Scanning ${fullPath}`);
const isDirectory = fs.statSync(fullPath).isDirectory();

if (isDirectory) {
const stylePath = path.join(fullPath, 'style.css');
const themeFile = path.join(fullPath, `${item}.php`);
const pluginFile = `${item}.php`; // ie: 'hello-dolly.php'

if (fs.existsSync(stylePath)) {
const version = this.extractVersionFromStyleFile(stylePath);
if (version) {
console.log(`ℹ️ Found ${item} version ${version}`);
result.push({ name: item, version });
}
}

if (fs.existsSync(themeFile) || fs.existsSync(pluginFile)) {
const version = this.extractVersionFromPHPFile(themeFile) || this.extractVersionFromPHPFile(pluginFile);
if (version) {
console.log(`ℹ️ Found ${item} version ${version}`);
result.push({ name: item, version });
}
}
}
}

return result.length ? result : null;
}

/**
* Extracts the version number from a style file.
*
* @param {string} filePath - The path to the style file.
* @return {string|null} The version number extracted from the style file, or null if no match was found.
*/
extractVersionFromStyleFile (filePath) {
const content = fs.readFileSync(filePath, 'utf8');
const match = /Version:\s*([\d.]+)/i.exec(content);
return match ? match[1] : null;
}

/**
* Extracts the version number from a PHP file.
*
* @param {string} filePath - The path to the PHP file.
* @return {string|null} The version number extracted from the file, or null if no version is found.
*/
extractVersionFromPHPFile (filePath) {
const content = fs.readFileSync(filePath, 'utf8');
const match = /Version:\s*([\d.]+)/i.exec(content);
return match ? match[1] : null;
}
}

module.exports = Dump;
Loading