-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #25 from wp-blocks/v0.0.4
V0.0.4
- Loading branch information
Showing
34 changed files
with
3,043 additions
and
880 deletions.
There are no files selected for viewing
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 }] | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; |
Oops, something went wrong.