🚀 Big News: Socket Acquires Coana to Bring Reachability Analysis to Every Appsec Team.Learn more
Socket
Book a DemoInstallSign in
Socket

@faustwp/cli

Package Overview
Dependencies
Maintainers
0
Versions
124
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@faustwp/cli - npm Package Compare versions

Comparing version

to
0.0.0-20250218203800

8

CHANGELOG.md
# @faustwp/cli
## 0.0.0-20241106203730
## 0.0.0-20250218203800
### Patch Changes
- 74e55bc: Updated code formatting config and switch to tabs. Configure your editor config settings for tab sizing preferences.
## 3.1.1
### Patch Changes
- e22b87d: **@faustwp/cli**: Migrates `glob-promise` dependency to Promise support.

@@ -8,0 +14,0 @@

7

dist/telemetry/marshallTelemetryData.js

@@ -9,3 +9,3 @@ import fs from 'fs';

export const marshallTelemetryData = (command) => {
var _a, _b, _c, _d, _e, _f, _g;
var _a, _b, _c, _d, _e, _f;
const packageJson = JSON.parse(fs.readFileSync('package.json', 'utf8'));

@@ -17,6 +17,5 @@ const telemetryData = {

node_faustwp_block_editor_utils_version: sanitizePackageJsonVersion((_d = packageJson === null || packageJson === void 0 ? void 0 : packageJson.devDependencies) === null || _d === void 0 ? void 0 : _d['@faustwp/block-editor-utils']),
node_faustwp_experimental_app_router_version: sanitizePackageJsonVersion((_e = packageJson === null || packageJson === void 0 ? void 0 : packageJson.dependencies) === null || _e === void 0 ? void 0 : _e['@faustwp/experimental-app-router']),
node_apollo_client_version: sanitizePackageJsonVersion((_f = packageJson === null || packageJson === void 0 ? void 0 : packageJson.dependencies) === null || _f === void 0 ? void 0 : _f['@apollo/client']),
node_apollo_client_version: sanitizePackageJsonVersion((_e = packageJson === null || packageJson === void 0 ? void 0 : packageJson.dependencies) === null || _e === void 0 ? void 0 : _e['@apollo/client']),
node_version: process.versions.node,
node_next_version: sanitizePackageJsonVersion((_g = packageJson === null || packageJson === void 0 ? void 0 : packageJson.dependencies) === null || _g === void 0 ? void 0 : _g.next),
node_next_version: sanitizePackageJsonVersion((_f = packageJson === null || packageJson === void 0 ? void 0 : packageJson.dependencies) === null || _f === void 0 ? void 0 : _f.next),
node_is_development: getCliArgs()[0] === 'dev',

@@ -23,0 +22,0 @@ command,

{
"name": "@faustwp/cli",
"version": "0.0.0-20241106203730",
"description": "This modules provides a CLI to develop, build, and serve your Faust apps",
"main": "dist/index.js",
"type": "module",
"types": "dist/index.d.ts",
"bin": {
"faust": "dist/index.js"
},
"devDependencies": {
"@types/archiver": "^5.3.2",
"@types/cookie": "0.5.1",
"@types/dotenv-flow": "^3.2.0",
"@types/fs-extra": "^11.0.2",
"@types/isomorphic-fetch": "^0.0.36",
"@types/jest": "^29.5.5",
"@types/node": "^18.15.11",
"@types/prompt": "1.1.2",
"fetch-mock-jest": "^1.5.1",
"jest-environment-jsdom": "29.6.4",
"rimraf": "5.0.5",
"ts-jest": "^29.1.1",
"typescript": "^4.9.5"
},
"dependencies": {
"archiver": "^6.0.1",
"chalk": "^4.1.2",
"dotenv-flow": "^3.2.0",
"form-data": "^4.0.0",
"fs-extra": "^11.1.1",
"glob": "^11.0.0",
"isomorphic-fetch": "^3.0.0",
"lodash": "^4.17.21",
"webpack-cli": "5.1.4"
},
"scripts": {
"build": "tsc -p tsconfig.json",
"clean": "rimraf dist",
"dev": "tsc -p tsconfig.json --watch",
"format": "prettier --write .",
"test": "jest",
"test:coverage:ci": "jest --ci --json --coverage --testLocationInResults --passWithNoTests --outputFile=report.json",
"test:coverage": "jest --coverage",
"test:watch": "jest --watch"
},
"repository": {
"type": "git",
"url": "git+https://github.com/wpengine/faustjs.git"
},
"author": "Faust Team",
"license": "MIT",
"bugs": {
"url": "https://github.com/wpengine/faustjs/issues"
},
"homepage": "https://github.com/wpengine/faustjs#readme",
"engines": {
"node": ">=18",
"npm": ">=8"
}
"name": "@faustwp/cli",
"version": "0.0.0-20250218203800",
"description": "This modules provides a CLI to develop, build, and serve your Faust apps",
"main": "dist/index.js",
"type": "module",
"types": "dist/index.d.ts",
"bin": {
"faust": "dist/index.js"
},
"devDependencies": {
"@types/archiver": "^5.3.2",
"@types/cookie": "0.5.1",
"@types/dotenv-flow": "^3.2.0",
"@types/fs-extra": "^11.0.2",
"@types/isomorphic-fetch": "^0.0.36",
"@types/jest": "^29.5.5",
"@types/node": "^18.15.11",
"@types/prompt": "1.1.2",
"fetch-mock-jest": "^1.5.1",
"jest-environment-jsdom": "29.6.4",
"rimraf": "5.0.5",
"ts-jest": "^29.1.1",
"typescript": "^4.9.5"
},
"dependencies": {
"archiver": "^6.0.1",
"chalk": "^4.1.2",
"dotenv-flow": "^3.2.0",
"form-data": "^4.0.0",
"fs-extra": "^11.1.1",
"glob": "^11.0.0",
"isomorphic-fetch": "^3.0.0",
"lodash": "^4.17.21",
"webpack-cli": "5.1.4"
},
"scripts": {
"build": "tsc -p tsconfig.json",
"clean": "rimraf dist",
"dev": "tsc -p tsconfig.json --watch",
"format": "prettier --write .",
"test": "jest",
"test:coverage:ci": "jest --ci --json --coverage --testLocationInResults --passWithNoTests --outputFile=report.json",
"test:coverage": "jest --coverage",
"test:watch": "jest --watch"
},
"repository": {
"type": "git",
"url": "git+https://github.com/wpengine/faustjs.git"
},
"author": "Faust Team",
"license": "MIT",
"bugs": {
"url": "https://github.com/wpengine/faustjs/issues"
},
"homepage": "https://github.com/wpengine/faustjs#readme",
"engines": {
"node": ">=18",
"npm": ">=8"
}
}

@@ -22,2 +22,2 @@ # @faustwp/cli

`@faustwp/cli` provides a CLI to develop, build, and serve your Faust apps.
`@faustwp/cli` provides a CLI to develop, build, and serve your Next.js apps built with Faust.js.

@@ -29,9 +29,9 @@ import fetch from 'isomorphic-fetch';

export type Manifest = {
blocks: any[];
timestamp: string;
blocks: any[];
timestamp: string;
};
const manifest: Manifest = {
blocks: [],
timestamp: new Date().toISOString(),
blocks: [],
timestamp: new Date().toISOString(),
};

@@ -43,4 +43,4 @@

export interface PhpAsset {
dependencies?: string[];
version?: string;
dependencies?: string[];
version?: string;
}

@@ -55,29 +55,29 @@

export function parsePhpAssetFile(phpContent: string): PhpAsset {
const jsonObject: PhpAsset = {};
const jsonObject: PhpAsset = {};
// Match the PHP array structure
const matches = /return\s+array\(([^;]+)\);/.exec(phpContent);
if (!matches || matches.length < 2) {
console.error('Error: Unable to parse PHP file.');
return {};
}
// Match the PHP array structure
const matches = /return\s+array\(([^;]+)\);/.exec(phpContent);
if (!matches || matches.length < 2) {
console.error('Error: Unable to parse PHP file.');
return {};
}
// Extract dependencies if present
const dependenciesMatch = matches[1].match(
/'dependencies'\s*=>\s*array\(([^)]+)\)/,
);
if (dependenciesMatch) {
jsonObject.dependencies = dependenciesMatch[1]
.split(',')
.map((dep) => dep.trim().replace(/'/g, ''));
}
// Extract dependencies if present
const dependenciesMatch = matches[1].match(
/'dependencies'\s*=>\s*array\(([^)]+)\)/,
);
if (dependenciesMatch) {
jsonObject.dependencies = dependenciesMatch[1]
.split(',')
.map((dep) => dep.trim().replace(/'/g, ''));
}
// Extract version if present
const versionMatch = matches[1].match(/'version'\s*=>\s*'([^']+)'/);
if (versionMatch) {
const [, version] = versionMatch; // destructures versionMatch and skips the first element (which is the full match of the regex), directly assigning the second element (the captured group) to the variable version.
jsonObject.version = version;
}
// Extract version if present
const versionMatch = matches[1].match(/'version'\s*=>\s*'([^']+)'/);
if (versionMatch) {
const [, version] = versionMatch; // destructures versionMatch and skips the first element (which is the full match of the regex), directly assigning the second element (the captured group) to the variable version.
jsonObject.version = version;
}
return jsonObject;
return jsonObject;
}

@@ -91,5 +91,5 @@

export async function fetchBlockFiles(): Promise<string[]> {
return glob(`${FAUST_BUILD_DIR}/**/block.json`, {
ignore: IGNORE_NODE_MODULES,
});
return glob(`${FAUST_BUILD_DIR}/**/block.json`, {
ignore: IGNORE_NODE_MODULES,
});
}

@@ -105,39 +105,39 @@

export async function processBlockFiles(files: string[]): Promise<void> {
await fs.emptyDir(BLOCKS_DIR);
await fs.emptyDir(BLOCKS_DIR);
const fileProcessingPromises = files.map(async (filePath) => {
const blockDir = path.dirname(filePath);
const blockName = path.basename(blockDir);
const destDir = path.join(BLOCKS_DIR, blockName);
const fileProcessingPromises = files.map(async (filePath) => {
const blockDir = path.dirname(filePath);
const blockName = path.basename(blockDir);
const destDir = path.join(BLOCKS_DIR, blockName);
await fs.copy(blockDir, destDir);
await fs.copy(blockDir, destDir);
if (path.extname(filePath) === '.json') {
try {
const blockJson = await fs.readJson(filePath);
manifest.blocks.push(blockJson);
} catch (error) {
console.error(`Error reading JSON file: ${filePath}`, error);
}
}
if (path.extname(filePath) === '.json') {
try {
const blockJson = await fs.readJson(filePath);
manifest.blocks.push(blockJson);
} catch (error) {
console.error(`Error reading JSON file: ${filePath}`, error);
}
}
// Handle PHP asset file
const phpAssetPath = path.join(blockDir, 'index.asset.php');
if (await fs.pathExists(phpAssetPath)) {
const phpContent = await fs.readFile(phpAssetPath, 'utf8');
const assetData = parsePhpAssetFile(phpContent);
await fs.writeJson(path.join(destDir, 'index.asset.json'), assetData, {
spaces: 2,
});
await fs.remove(phpAssetPath);
}
// Handle PHP asset file
const phpAssetPath = path.join(blockDir, 'index.asset.php');
if (await fs.pathExists(phpAssetPath)) {
const phpContent = await fs.readFile(phpAssetPath, 'utf8');
const assetData = parsePhpAssetFile(phpContent);
await fs.writeJson(path.join(destDir, 'index.asset.json'), assetData, {
spaces: 2,
});
await fs.remove(phpAssetPath);
}
// Remove any other PHP files
const phpFiles = await glob(`${destDir}/**/*.php`, {
ignore: IGNORE_NODE_MODULES,
});
await Promise.all(phpFiles.map((file) => fs.remove(file)));
});
// Remove any other PHP files
const phpFiles = await glob(`${destDir}/**/*.php`, {
ignore: IGNORE_NODE_MODULES,
});
await Promise.all(phpFiles.map((file) => fs.remove(file)));
});
await Promise.all(fileProcessingPromises);
await Promise.all(fileProcessingPromises);
}

@@ -151,11 +151,11 @@

export async function createZipArchive(): Promise<string> {
const zipPath = path.join(FAUST_DIR, 'blocks.zip');
const output = fs.createWriteStream(zipPath);
const archive = archiver('zip');
const zipPath = path.join(FAUST_DIR, 'blocks.zip');
const output = fs.createWriteStream(zipPath);
const archive = archiver('zip');
archive.pipe(output);
archive.directory(BLOCKS_DIR, false);
await archive.finalize();
archive.pipe(output);
archive.directory(BLOCKS_DIR, false);
await archive.finalize();
return zipPath;
return zipPath;
}

@@ -170,44 +170,44 @@

export async function uploadToWordPress(zipPath: string): Promise<void> {
if (!fs.existsSync(zipPath)) {
throw new Error('Provided zipPath does not exist.');
}
if (!fs.existsSync(zipPath)) {
throw new Error('Provided zipPath does not exist.');
}
const form = new FormData();
form.append('zipfile', fs.createReadStream(zipPath));
const form = new FormData();
form.append('zipfile', fs.createReadStream(zipPath));
const apiUrl = `${getWpUrl()}/wp-json/faustwp/v1/blockset`;
const headers = {
...form.getHeaders(),
'x-faustwp-secret': getWpSecret() || '',
};
const apiUrl = `${getWpUrl()}/wp-json/faustwp/v1/blockset`;
const headers = {
...form.getHeaders(),
'x-faustwp-secret': getWpSecret() || '',
};
try {
const response = await fetch(apiUrl, {
headers,
method: 'POST',
body: form,
timeout: 30000, // 30 seconds timeout
} as unknown as RequestInit);
try {
const response = await fetch(apiUrl, {
headers,
method: 'POST',
body: form,
timeout: 30000, // 30 seconds timeout
} as unknown as RequestInit);
if (!response.ok) {
throw new Error(`Error uploading to WordPress: ${await response.text()}`);
}
if (!response.ok) {
throw new Error(`Error uploading to WordPress: ${await response.text()}`);
}
try {
console.log(await response.json());
} catch (jsonError) {
if (jsonError instanceof Error) {
throw new Error('Error parsing response from WordPress.');
}
throw jsonError;
}
} catch (error) {
if (error instanceof Error) {
if (error.name === 'AbortError') {
throw new Error('Request timed out.');
}
throw new Error(`Network error: ${error.message}`);
}
throw error;
}
try {
console.log(await response.json());
} catch (jsonError) {
if (jsonError instanceof Error) {
throw new Error('Error parsing response from WordPress.');
}
throw jsonError;
}
} catch (error) {
if (error instanceof Error) {
if (error.name === 'AbortError') {
throw new Error('Request timed out.');
}
throw new Error(`Network error: ${error.message}`);
}
throw error;
}
}

@@ -221,23 +221,23 @@

export async function compileBlocks(): Promise<void> {
debugLog(`Faust: Compiling Blocks into ${FAUST_BUILD_DIR}`);
await fs.emptyDir(FAUST_BUILD_DIR);
const command = hasYarn() ? 'yarn' : 'npm';
let args = ['exec', 'wp-scripts', 'start', '--package=@wordpress/scripts'];
if (!hasYarn()) {
args.push('--verbose');
args.push('--');
}
args = args.concat([
'--no-watch',
`--webpack-src-dir=${FAUST_BLOCKS_SRC_DIR}`,
`--output-path="${FAUST_BUILD_DIR}"`,
]);
const res = spawnSync(command, args, {
shell: true,
stdio: 'inherit',
encoding: 'utf8',
});
if (res.status && res.status > 0) {
process.exit(res.status);
}
debugLog(`Faust: Compiling Blocks into ${FAUST_BUILD_DIR}`);
await fs.emptyDir(FAUST_BUILD_DIR);
const command = hasYarn() ? 'yarn' : 'npm';
let args = ['exec', 'wp-scripts', 'start', '--package=@wordpress/scripts'];
if (!hasYarn()) {
args.push('--verbose');
args.push('--');
}
args = args.concat([
'--no-watch',
`--webpack-src-dir=${FAUST_BLOCKS_SRC_DIR}`,
`--output-path="${FAUST_BUILD_DIR}"`,
]);
const res = spawnSync(command, args, {
shell: true,
stdio: 'inherit',
encoding: 'utf8',
});
if (res.status && res.status > 0) {
process.exit(res.status);
}
}

@@ -251,12 +251,12 @@

export async function blockset(): Promise<void> {
try {
await compileBlocks();
const files = await fetchBlockFiles();
await processBlockFiles(files);
await fs.writeJson(MANIFEST_PATH, manifest, { spaces: 2 });
const zipPath = await createZipArchive();
await uploadToWordPress(zipPath);
} catch (error) {
console.error(`"faust blockset" failed with the following error:`, error);
}
try {
await compileBlocks();
const files = await fetchBlockFiles();
await processBlockFiles(files);
await fs.writeJson(MANIFEST_PATH, manifest, { spaces: 2 });
const zipPath = await createZipArchive();
await uploadToWordPress(zipPath);
} catch (error) {
console.error(`"faust blockset" failed with the following error:`, error);
}
}

@@ -8,13 +8,13 @@ import 'isomorphic-fetch';

export async function generateGlobalStylesheet(): Promise<void> {
const graphqlEndpoint = getGraphqlEndpoint();
const graphqlEndpoint = getGraphqlEndpoint();
try {
const response: Response = await fetch(graphqlEndpoint, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
variables: {},
query: `
try {
const response: Response = await fetch(graphqlEndpoint, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
variables: {},
query: `
{

@@ -24,38 +24,38 @@ globalStylesheet

`,
}),
});
}),
});
const json: {
data: { globalStylesheet: string };
errors?: {
message: string;
}[];
} = await response.json();
const json: {
data: { globalStylesheet: string };
errors?: {
message: string;
}[];
} = await response.json();
if (json.errors) {
const errors = json.errors.map((error) => {
return error.message;
});
if (json.errors) {
const errors = json.errors.map((error) => {
return error.message;
});
throw new Error(
`There were errors in the GraphQL request: ${errors.join(', ')}`,
);
}
throw new Error(
`There were errors in the GraphQL request: ${errors.join(', ')}`,
);
}
fs.writeFileSync('./globalStylesheet.css', json.data.globalStylesheet);
fs.writeFileSync('./globalStylesheet.css', json.data.globalStylesheet);
infoLog("This project's globalStylesheet.css has been updated!");
} catch (err) {
debugLog(
`"faust generateGlobalStylesheet" failed with the following error: `,
err,
);
infoLog("This project's globalStylesheet.css has been updated!");
} catch (err) {
debugLog(
`"faust generateGlobalStylesheet" failed with the following error: `,
err,
);
errorLog("Unable to update this project's globalStylesheet.css");
errorLog(
`Make sure you have "Enable Public Introspection" checked in WPGraphQL: ${getWpUrl()}/wp-admin/admin.php?page=graphql-settings`,
);
errorLog("Unable to update this project's globalStylesheet.css");
errorLog(
`Make sure you have "Enable Public Introspection" checked in WPGraphQL: ${getWpUrl()}/wp-admin/admin.php?page=graphql-settings`,
);
process.exit(0);
}
process.exit(0);
}
}

@@ -8,27 +8,27 @@ import 'isomorphic-fetch';

type PossibleTypes = {
[key: string]: any;
[key: string]: any;
};
type Supertype = {
possibleTypes: any[];
name: string | number;
possibleTypes: any[];
name: string | number;
};
type Subtype = {
name: string | number;
name: string | number;
};
export async function generatePossibleTypes(): Promise<void> {
const graphqlEndpoint = getGraphqlEndpoint();
const graphqlEndpoint = getGraphqlEndpoint();
try {
const response: Response = await fetch(graphqlEndpoint, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'x-faust-secret': getWpSecret() || '',
},
body: JSON.stringify({
variables: {},
query: `
try {
const response: Response = await fetch(graphqlEndpoint, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'x-faust-secret': getWpSecret() || '',
},
body: JSON.stringify({
variables: {},
query: `
{

@@ -46,47 +46,47 @@ __schema {

`,
}),
});
}),
});
const json: {
data: { __schema: { types: [] } };
errors?: {
message: string;
}[];
} = await response.json();
const possibleTypes = <PossibleTypes>{};
const json: {
data: { __schema: { types: [] } };
errors?: {
message: string;
}[];
} = await response.json();
const possibleTypes = <PossibleTypes>{};
if (json.errors) {
const errors = json.errors.map((error) => {
return error.message;
});
if (json.errors) {
const errors = json.errors.map((error) => {
return error.message;
});
throw new Error(
`There were errors in the GraphQL request: ${errors.join(', ')}`,
);
}
throw new Error(
`There were errors in the GraphQL request: ${errors.join(', ')}`,
);
}
json.data.__schema.types.forEach((supertype: Supertype) => {
if (supertype.possibleTypes) {
possibleTypes[supertype.name] = supertype.possibleTypes.map(
(subtype: Subtype) => subtype.name,
);
}
});
json.data.__schema.types.forEach((supertype: Supertype) => {
if (supertype.possibleTypes) {
possibleTypes[supertype.name] = supertype.possibleTypes.map(
(subtype: Subtype) => subtype.name,
);
}
});
fs.writeFileSync('./possibleTypes.json', JSON.stringify(possibleTypes));
fs.writeFileSync('./possibleTypes.json', JSON.stringify(possibleTypes));
infoLog("This project's possibleTypes schema has been updated!");
} catch (err) {
debugLog(
`"faust generatePossibleTypes" failed with the following error: `,
err,
);
infoLog("This project's possibleTypes schema has been updated!");
} catch (err) {
debugLog(
`"faust generatePossibleTypes" failed with the following error: `,
err,
);
errorLog("Unable to update this project's possibleTypes schema");
errorLog(
`Make sure the FAUST_SECRET_KEY value in your environment matches the value in the Faust WordPress plugin settings, or that you have "Enable Public Introspection" checked in WPGraphQL if not using FAUST_SECRET_KEY: ${getWpUrl()}/wp-admin/admin.php?page=graphql-settings`,
);
errorLog("Unable to update this project's possibleTypes schema");
errorLog(
`Make sure the FAUST_SECRET_KEY value in your environment matches the value in the Faust WordPress plugin settings, or that you have "Enable Public Introspection" checked in WPGraphQL if not using FAUST_SECRET_KEY: ${getWpUrl()}/wp-admin/admin.php?page=graphql-settings`,
);
process.exit(0);
}
process.exit(0);
}
}

@@ -6,5 +6,5 @@ import { getWpSecret, getWpUrl } from '../utils/index.js';

export function isWPEngineComSubdomain(url: string) {
const regex = /\b\w+\.wpengine\.com\b/;
const regex = /\b\w+\.wpengine\.com\b/;
return regex.test(url);
return regex.test(url);
}

@@ -16,59 +16,59 @@

export const validateFaustEnvVars = async () => {
const secretWp = getWpSecret();
const secretWp = getWpSecret();
if (!process.env.NEXT_PUBLIC_WORDPRESS_URL) {
errorLog('Could not find NEXT_PUBLIC_WORDPRESS_URL environment variable.');
if (!process.env.NEXT_PUBLIC_WORDPRESS_URL) {
errorLog('Could not find NEXT_PUBLIC_WORDPRESS_URL environment variable.');
process.exit(1);
}
process.exit(1);
}
if (isWPEngineComSubdomain(process.env.NEXT_PUBLIC_WORDPRESS_URL)) {
infoLog(`Found NEXT_PUBLIC_WORDPRESS_URL using wpengine.com TLD.`);
infoLog(`It is recommended to use the wpenginepowered.com TLD instead.`);
infoLog(
`Ex: https://example.wpengine.com -> https://example.wpenginepowered.com`,
);
infoLog(
`This will leverage WP Engine's Advanced Network CDN. See: https://wpengine.com/support/network/`,
);
}
if (isWPEngineComSubdomain(process.env.NEXT_PUBLIC_WORDPRESS_URL)) {
infoLog(`Found NEXT_PUBLIC_WORDPRESS_URL using wpengine.com TLD.`);
infoLog(`It is recommended to use the wpenginepowered.com TLD instead.`);
infoLog(
`Ex: https://example.wpengine.com -> https://example.wpenginepowered.com`,
);
infoLog(
`This will leverage WP Engine's Advanced Network CDN. See: https://wpengine.com/support/network/`,
);
}
if (!secretWp) {
warnLog('Could not find FAUST_SECRET_KEY environment variable.');
warnLog('Some functionality may be limited.');
}
if (!secretWp) {
warnLog('Could not find FAUST_SECRET_KEY environment variable.');
warnLog('Some functionality may be limited.');
}
if (process.env.NEXT_PUBLIC_WORDPRESS_URL.startsWith('http://') && secretWp) {
warnLog('Your WordPress site is not running on https!');
warnLog(
'This is a security concern as all traffic with your secret key is in plain text.',
);
warnLog(
'Please make sure your production Faust app runs with a WordPress instance on https!',
);
}
if (process.env.NEXT_PUBLIC_WORDPRESS_URL.startsWith('http://') && secretWp) {
warnLog('Your WordPress site is not running on https!');
warnLog(
'This is a security concern as all traffic with your secret key is in plain text.',
);
warnLog(
'Please make sure your production Faust app runs with a WordPress instance on https!',
);
}
if (secretWp) {
// send secret key
const apiUrl = `${getWpUrl()}/?rest_route=/faustwp/v1/validate_secret_key`;
const headers = {
'x-faustwp-secret': secretWp,
};
try {
const response = await fetch(apiUrl, {
headers,
method: 'POST',
});
if (response.status === 401) {
// Unauthorized: User receives a 401 status code AND the message below
errorLog(
'Ensure your FAUST_SECRET_KEY environment variable matches your Secret Key in the Faust WordPress plugin settings',
);
process.exit(1);
}
await validateNextWordPressUrl();
} catch (error) {
console.log('error', error);
}
}
if (secretWp) {
// send secret key
const apiUrl = `${getWpUrl()}/?rest_route=/faustwp/v1/validate_secret_key`;
const headers = {
'x-faustwp-secret': secretWp,
};
try {
const response = await fetch(apiUrl, {
headers,
method: 'POST',
});
if (response.status === 401) {
// Unauthorized: User receives a 401 status code AND the message below
errorLog(
'Ensure your FAUST_SECRET_KEY environment variable matches your Secret Key in the Faust WordPress plugin settings',
);
process.exit(1);
}
await validateNextWordPressUrl();
} catch (error) {
console.log('error', error);
}
}
};

@@ -9,34 +9,34 @@ import { getWpSecret, getWpUrl } from '../utils/index.js';

export async function validateNextWordPressUrl(): Promise<void> {
const apiUrl = `${getWpUrl()}/wp-json/faustwp/v1/validate_public_wordpress_url`;
const headers = {
'Content-Type': 'application/json',
'x-faustwp-secret': getWpSecret() || '',
};
const apiUrl = `${getWpUrl()}/wp-json/faustwp/v1/validate_public_wordpress_url`;
const headers = {
'Content-Type': 'application/json',
'x-faustwp-secret': getWpSecret() || '',
};
const postData = {
public_wordpress_url: getWpUrl(),
};
try {
const response = await fetch(apiUrl, {
method: 'POST',
headers,
body: JSON.stringify(postData),
});
const postData = {
public_wordpress_url: getWpUrl(),
};
try {
const response = await fetch(apiUrl, {
method: 'POST',
headers,
body: JSON.stringify(postData),
});
if (!response.ok) {
if (response.status === 404) {
// Handle the case when the route does not exist
warnLog(
'Route not found: Please update your FaustWP plugin to the latest version.',
);
} else {
errorLog(
'Validation Failed: Your Faust front-end site URL value is misconfigured. It should NOT match the `NEXT_PUBLIC_WORDPRESS_URL.`',
);
process.exit(1);
}
}
} catch (error) {
console.log('error', error);
}
if (!response.ok) {
if (response.status === 404) {
// Handle the case when the route does not exist
warnLog(
'Route not found: Please update your FaustWP plugin to the latest version.',
);
} else {
errorLog(
'Validation Failed: Your Faust front-end site URL value is misconfigured. It should NOT match the `NEXT_PUBLIC_WORDPRESS_URL.`',
);
process.exit(1);
}
}
} catch (error) {
console.log('error', error);
}
}

@@ -10,37 +10,37 @@ import 'isomorphic-fetch';

export async function verifyGraphQLEndpoint() {
const graphqlEndpoint = getGraphqlEndpoint();
const graphqlEndpoint = getGraphqlEndpoint();
try {
// Perform GraphQL request.
const response: Response = await fetch(graphqlEndpoint, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ query: '{ __typename }' }),
});
try {
// Perform GraphQL request.
const response: Response = await fetch(graphqlEndpoint, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ query: '{ __typename }' }),
});
// Expect a valid GraphQL response.
const json: {
data: {
__typename: 'string';
};
} = await response.json();
// Expect a valid GraphQL response.
const json: {
data: {
__typename: 'string';
};
} = await response.json();
// eslint-disable-next-line no-underscore-dangle
if (!json.data.__typename) {
throw new Error(`GraphQL request didn't include "json.data.__typename"`);
}
// eslint-disable-next-line no-underscore-dangle
if (!json.data.__typename) {
throw new Error(`GraphQL request didn't include "json.data.__typename"`);
}
debugLog(`Discoverd GraphQL endpoint at ${graphqlEndpoint}`);
debugLog(`Discoverd GraphQL endpoint at ${graphqlEndpoint}`);
return true;
} catch (err) {
errorLog(`Unable to find a GraphQL endpoint at ${graphqlEndpoint}`);
errorLog(
'WPGraphQL may not be active, or your WordPress site is unavailable.',
);
return true;
} catch (err) {
errorLog(`Unable to find a GraphQL endpoint at ${graphqlEndpoint}`);
errorLog(
'WPGraphQL may not be active, or your WordPress site is unavailable.',
);
return process.exit(1);
}
return process.exit(1);
}
}

@@ -5,56 +5,56 @@ import { isDebug } from '../utils/index.js';

export const log = (
logLevel: 'info' | 'warn' | 'error' | 'debug',
message: string,
...args: any
logLevel: 'info' | 'warn' | 'error' | 'debug',
message: string,
...args: any
) => {
let styledLogLevel = '';
let styledLogLevel = '';
switch (logLevel) {
case 'info': {
styledLogLevel = styles.info('info');
break;
}
case 'warn': {
styledLogLevel = styles.warn('warn');
break;
}
case 'error': {
styledLogLevel = styles.error('error');
break;
}
case 'debug': {
styledLogLevel = styles.debug('debug');
break;
}
default: {
break;
}
}
switch (logLevel) {
case 'info': {
styledLogLevel = styles.info('info');
break;
}
case 'warn': {
styledLogLevel = styles.warn('warn');
break;
}
case 'error': {
styledLogLevel = styles.error('error');
break;
}
case 'debug': {
styledLogLevel = styles.debug('debug');
break;
}
default: {
break;
}
}
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
console.log(`${styledLogLevel} - ${message}`, ...args);
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
console.log(`${styledLogLevel} - ${message}`, ...args);
};
export const infoLog = (message: string, ...args: any) => {
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
log('info', message, ...args);
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
log('info', message, ...args);
};
export const warnLog = (message: string, ...args: any) => {
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
log('warn', message, ...args);
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
log('warn', message, ...args);
};
export const errorLog = (message: string, ...args: any) => {
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
log('error', message, ...args);
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
log('error', message, ...args);
};
export const debugLog = (message: string, ...args: any) => {
if (!isDebug()) {
return;
}
if (!isDebug()) {
return;
}
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
log('debug', message, ...args);
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
log('debug', message, ...args);
};
import chalk from 'chalk';
export const styles = {
brand: chalk.bold.whiteBright,
info: chalk.cyan,
warn: chalk.yellow,
error: chalk.red,
success: chalk.blueBright,
debug: chalk.magenta.italic,
brand: chalk.bold.whiteBright,
info: chalk.cyan,
warn: chalk.yellow,
error: chalk.red,
success: chalk.blueBright,
debug: chalk.magenta.italic,
};

@@ -6,12 +6,12 @@ import fs from 'fs';

export interface TelemetryData {
node_faustwp_core_version?: string;
node_faustwp_cli_version?: string;
node_faustwp_blocks_version?: string;
node_faustwp_block_editor_utils_version?: string;
node_faustwp_experimental_app_router_version?: string;
node_apollo_client_version?: string;
node_version?: string;
node_next_version?: string;
node_is_development?: boolean;
command?: string;
node_faustwp_core_version?: string;
node_faustwp_cli_version?: string;
node_faustwp_blocks_version?: string;
node_faustwp_block_editor_utils_version?: string;
node_faustwp_experimental_app_router_version?: string;
node_apollo_client_version?: string;
node_version?: string;
node_next_version?: string;
node_is_development?: boolean;
command?: string;
}

@@ -24,37 +24,31 @@

export const marshallTelemetryData = (command: string) => {
const packageJson = JSON.parse(fs.readFileSync('package.json', 'utf8'));
const packageJson = JSON.parse(fs.readFileSync('package.json', 'utf8'));
const telemetryData: TelemetryData = {
node_faustwp_core_version: sanitizePackageJsonVersion(
packageJson?.dependencies?.['@faustwp/core'] as string | undefined,
),
node_faustwp_cli_version: sanitizePackageJsonVersion(
packageJson?.dependencies?.['@faustwp/cli'] as string | undefined,
),
node_faustwp_blocks_version: sanitizePackageJsonVersion(
packageJson?.dependencies?.['@faustwp/blocks'] as string | undefined,
),
node_faustwp_block_editor_utils_version: sanitizePackageJsonVersion(
packageJson?.devDependencies?.['@faustwp/block-editor-utils'] as
| string
| undefined,
),
node_faustwp_experimental_app_router_version: sanitizePackageJsonVersion(
packageJson?.dependencies?.['@faustwp/experimental-app-router'] as
| string
| undefined,
),
const telemetryData: TelemetryData = {
node_faustwp_core_version: sanitizePackageJsonVersion(
packageJson?.dependencies?.['@faustwp/core'] as string | undefined,
),
node_faustwp_cli_version: sanitizePackageJsonVersion(
packageJson?.dependencies?.['@faustwp/cli'] as string | undefined,
),
node_faustwp_blocks_version: sanitizePackageJsonVersion(
packageJson?.dependencies?.['@faustwp/blocks'] as string | undefined,
),
node_faustwp_block_editor_utils_version: sanitizePackageJsonVersion(
packageJson?.devDependencies?.['@faustwp/block-editor-utils'] as
| string
| undefined,
),
node_apollo_client_version: sanitizePackageJsonVersion(
packageJson?.dependencies?.['@apollo/client'] as string | undefined,
),
node_version: process.versions.node,
node_next_version: sanitizePackageJsonVersion(
packageJson?.dependencies?.next as string | undefined,
),
node_is_development: getCliArgs()[0] === 'dev',
command,
};
node_apollo_client_version: sanitizePackageJsonVersion(
packageJson?.dependencies?.['@apollo/client'] as string | undefined,
),
node_version: process.versions.node,
node_next_version: sanitizePackageJsonVersion(
packageJson?.dependencies?.next as string | undefined,
),
node_is_development: getCliArgs()[0] === 'dev',
command,
};
return telemetryData;
return telemetryData;
};

@@ -6,17 +6,17 @@ import 'isomorphic-fetch';

export interface WPTelemetryResponseData {
faustwp: {
version: string;
has_frontend_uri: boolean;
redirects_enabled: boolean;
rewrites_enabled: boolean;
themes_disabled: boolean;
image_source_replacement_enabled: boolean;
};
wpgraphql_content_blocks: {
version: string;
};
is_wpe: boolean;
multisite: boolean;
php_version: string;
wp_version: string;
faustwp: {
version: string;
has_frontend_uri: boolean;
redirects_enabled: boolean;
rewrites_enabled: boolean;
themes_disabled: boolean;
image_source_replacement_enabled: boolean;
};
wpgraphql_content_blocks: {
version: string;
};
is_wpe: boolean;
multisite: boolean;
php_version: string;
wp_version: string;
}

@@ -32,20 +32,20 @@

export const requestWPTelemetryData = async (
headlessWpUrl: string,
headlessSecretKey: string,
headlessWpUrl: string,
headlessSecretKey: string,
): Promise<WPTelemetryResponseData | undefined> => {
const res = await fetch(`${headlessWpUrl}${WP_TELEMETRY_ENDPOINT}`, {
method: 'POST',
headers: {
'x-faustwp-secret': headlessSecretKey,
},
});
const res = await fetch(`${headlessWpUrl}${WP_TELEMETRY_ENDPOINT}`, {
method: 'POST',
headers: {
'x-faustwp-secret': headlessSecretKey,
},
});
// If the response is invalid, return undefined for appropriate error handling.
if (res.status !== 200) {
return undefined;
}
// If the response is invalid, return undefined for appropriate error handling.
if (res.status !== 200) {
return undefined;
}
const json = (await res.json()) as WPTelemetryResponseData;
const json = (await res.json()) as WPTelemetryResponseData;
return json;
return json;
};

@@ -13,19 +13,19 @@ import 'isomorphic-fetch';

export const sendTelemetryData = (payload: TelemetryData) => {
const secret = getWpSecret();
const secret = getWpSecret();
if (!secret) {
throw new Error('Faust secret key is required');
}
if (!secret) {
throw new Error('Faust secret key is required');
}
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const WP_TELEMETRY_ENDPOINT = `${getWpUrl()!}/wp-json/faustwp/v1/process_telemetry`;
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const WP_TELEMETRY_ENDPOINT = `${getWpUrl()!}/wp-json/faustwp/v1/process_telemetry`;
return fetch(WP_TELEMETRY_ENDPOINT, {
headers: {
'x-faustwp-secret': secret,
'Content-Type': 'application/json',
},
method: 'POST',
body: JSON.stringify(payload),
});
return fetch(WP_TELEMETRY_ENDPOINT, {
headers: {
'x-faustwp-secret': secret,
'Content-Type': 'application/json',
},
method: 'POST',
body: JSON.stringify(payload),
});
};

@@ -7,7 +7,7 @@ import { getWpUrl } from './getWpUrl.js';

export function getGraphqlEndpoint() {
const wpUrl = getWpUrl();
const wpUrl = getWpUrl();
// Use direct WordPress query to avoid relying on a filter.
// https://github.com/wpengine/faustjs/issues/1360
return `${wpUrl}/index.php?graphql`;
// Use direct WordPress query to avoid relying on a filter.
// https://github.com/wpengine/faustjs/issues/1360
return `${wpUrl}/index.php?graphql`;
}

@@ -12,3 +12,3 @@ import { getCliArgs } from './getCliArgs.js';

export const getNextCliArgs = () => {
return getCliArgs().filter((arg) => !FAUST_CLI_FLAGS.includes(arg));
return getCliArgs().filter((arg) => !FAUST_CLI_FLAGS.includes(arg));
};

@@ -5,3 +5,3 @@ /**

export function getWpSecret() {
return process.env.FAUST_SECRET_KEY || process.env.FAUSTWP_SECRET_KEY;
return process.env.FAUST_SECRET_KEY || process.env.FAUSTWP_SECRET_KEY;
}

@@ -7,9 +7,9 @@ import trim from 'lodash/trim.js';

export function getWpUrl(path = ''): string {
const wpUrl = trim(process.env.NEXT_PUBLIC_WORDPRESS_URL, '/');
const wpUrl = trim(process.env.NEXT_PUBLIC_WORDPRESS_URL, '/');
if (!path) {
return wpUrl;
}
if (!path) {
return wpUrl;
}
return `${wpUrl}/${trim(path, '/')}`;
return `${wpUrl}/${trim(path, '/')}`;
}

@@ -6,3 +6,3 @@ import process from 'process';

export function hasYarn(cwd = process.cwd()) {
return fs.existsSync(path.resolve(cwd, 'yarn.lock'));
return fs.existsSync(path.resolve(cwd, 'yarn.lock'));
}
export function isDebug(): boolean {
const isDebugEnvVar = process.env.FAUST_DEBUG;
const isDebugEnvVar = process.env.FAUST_DEBUG;
if (isDebugEnvVar === 'true' || isDebugEnvVar === '1') {
return true;
}
if (isDebugEnvVar === 'true' || isDebugEnvVar === '1') {
return true;
}
return false;
return false;
}

@@ -11,34 +11,34 @@ import fs from 'fs';

export function sanitizePackageJsonVersion(_version: string | undefined) {
let version = _version;
let version = _version;
if (!version) {
return undefined;
}
if (!version) {
return undefined;
}
if (version.charAt(0) === '^' || version.charAt(0) === '~') {
version = version.substring(1);
}
if (version.charAt(0) === '^' || version.charAt(0) === '~') {
version = version.substring(1);
}
/**
* If a dependency is a file path set the value to undefined as we
* don't want to collect file paths in telemetry
*/
if (version.startsWith('file:')) {
version = undefined;
}
/**
* If a dependency is a file path set the value to undefined as we
* don't want to collect file paths in telemetry
*/
if (version.startsWith('file:')) {
version = undefined;
}
return version;
return version;
}
export function printFaustVersion(): void {
const packageJson = JSON.parse(fs.readFileSync('package.json', 'utf8'));
const coreVersion = sanitizePackageJsonVersion(
packageJson?.dependencies?.['@faustwp/core'] as string | undefined,
);
const cliVersion = sanitizePackageJsonVersion(
packageJson?.dependencies?.['@faustwp/cli'] as string | undefined,
);
// eslint-disable-next-line
infoLog(`Faust.js v${coreVersion || 'unknown'}`);
infoLog(`Faust.js CLI v${cliVersion || 'unknown'}`);
const packageJson = JSON.parse(fs.readFileSync('package.json', 'utf8'));
const coreVersion = sanitizePackageJsonVersion(
packageJson?.dependencies?.['@faustwp/core'] as string | undefined,
);
const cliVersion = sanitizePackageJsonVersion(
packageJson?.dependencies?.['@faustwp/cli'] as string | undefined,
);
// eslint-disable-next-line
infoLog(`Faust.js v${coreVersion || 'unknown'}`);
infoLog(`Faust.js CLI v${cliVersion || 'unknown'}`);
}

Sorry, the diff of this file is not supported yet