From 8c2be0a8bda026d74c4065a422732784ea38a088 Mon Sep 17 00:00:00 2001
From: Swanand01 <75439077+Swanand01@users.noreply.github.com>
Date: Thu, 16 Jan 2025 18:44:28 +0530
Subject: [PATCH] fix: Update SnapWP environment variables (#57)
* refactor: update env var names
* refactor: replace `NEXT_URL` with `NEXT_PUBLIC_URL`
* feat: add commented property to variables
* fix: linting errors
* fix: remove trailing whitespace
* refactor: remove commented from variables, calculate it based on defaults
* fix: formatting errors in Admin.php
* fix : tests
* chore: cleanup
* feat: update docs
* fix : tests
---------
Co-authored-by: Ta5r
Co-authored-by: Dovid Levine
---
access-functions.php | 12 ++-
docs/rest-api.md | 14 +--
src/Modules/Admin.php | 10 +-
src/Modules/EnvGenerator/Generator.php | 26 +++--
src/Modules/EnvGenerator/VariableRegistry.php | 22 ++--
tests/Integration/GeneratorTest.php | 101 +++++++++++++-----
tests/Integration/RestControllerTest.php | 3 +-
7 files changed, 134 insertions(+), 54 deletions(-)
diff --git a/access-functions.php b/access-functions.php
index 0bb2a3e..5c16799 100644
--- a/access-functions.php
+++ b/access-functions.php
@@ -58,11 +58,15 @@ function snapwp_helper_get_env_variables() {
return new \WP_Error( 'graphql_not_found', 'WPGraphQL must be installed and activated.', [ 'status' => 500 ] );
}
+ $upload_dir = wp_get_upload_dir();
+
return [
- 'NODE_TLS_REJECT_UNAUTHORIZED' => '',
- 'NEXT_URL' => '',
- 'HOME_URL' => get_home_url(),
- 'GRAPHQL_ENDPOINT' => graphql_get_endpoint(),
+ 'NODE_TLS_REJECT_UNAUTHORIZED' => '',
+ 'NEXT_PUBLIC_URL' => '',
+ 'NEXT_PUBLIC_WORDPRESS_URL' => get_home_url(),
+ 'NEXT_PUBLIC_GRAPHQL_ENDPOINT' => graphql_get_endpoint(),
+ 'NEXT_PUBLIC_WORDPRESS_UPLOADS_PATH' => str_replace( ABSPATH, '', $upload_dir['basedir'] ),
+ 'NEXT_PUBLIC_WORDPRESS_REST_URL_PREFIX' => rest_get_url_prefix(),
];
}
}
diff --git a/docs/rest-api.md b/docs/rest-api.md
index 5bf9d81..a978476 100644
--- a/docs/rest-api.md
+++ b/docs/rest-api.md
@@ -21,12 +21,14 @@ curl -X GET \
### Parameters
-This endpoint does not require any parameters to be passed in the request body. The .env file content is generated based on WordPress settings.
-
- - `NEXT_URL` (Required): The headless frontend domain URL.
- - `HOME_URL` (Required): The WordPress "frontend" domain URL.
- - `GRAPHQL_ENDPOINT`: The WordPress GraphQL endpoint. (Default: `graphql`)
- - `NODE_TLS_REJECT_UNAUTHORIZED`: Enable if connecting to a self-signed cert. (Default: commented out)
+This endpoint does not require any parameters to be passed in the request body. The .env file content is generated based on WordPress settings. Unchanged variables will be commented out.
+
+ - `NODE_TLS_REJECT_UNAUTHORIZED`: Enable if connecting to a self-signed cert. (Default: `0`)
+ - `NEXT_PUBLIC_URL` (Required): The headless frontend domain URL. (Default: `http://localhost:3000`)
+ - `NEXT_PUBLIC_WORDPRESS_URL` (Required): The WordPress "frontend" domain URL.
+ - `NEXT_PUBLIC_GRAPHQL_ENDPOINT`: The WordPress GraphQL endpoint. (Default: `graphql`)
+ - `NEXT_PUBLIC_WORDPRESS_UPLOADS_PATH`: The WordPress Uploads directory path. (Default: `wp-content/uploads`)
+ - `NEXT_PUBLIC_WORDPRESS_REST_URL_PREFIX`: The WordPress REST URL Prefix. (Default: `wp-json`)
Note: This endpoint requires authentication with administrator privileges.
diff --git a/src/Modules/Admin.php b/src/Modules/Admin.php
index 11f3845..b4c8619 100644
--- a/src/Modules/Admin.php
+++ b/src/Modules/Admin.php
@@ -128,12 +128,12 @@ public function render_menu(): void {
$value ) : ?>
|
- |
+ %s', $value ) ); ?> |
@@ -164,8 +164,8 @@ public function render_menu(): void {
NEXT_URL'
+ esc_html__( 'Then update the %s variable with the URL for your headless frontend.', 'snapwp-helper' ),
+ 'NEXT_PUBLIC_URL
'
);
?>
@@ -180,7 +180,7 @@ public function render_menu(): void {
npm run dev',
'npm run build && npm run start
'
);
diff --git a/src/Modules/EnvGenerator/Generator.php b/src/Modules/EnvGenerator/Generator.php
index bee8082..9cec7f9 100644
--- a/src/Modules/EnvGenerator/Generator.php
+++ b/src/Modules/EnvGenerator/Generator.php
@@ -59,9 +59,16 @@ protected function prepare_variables( array $variables ): ?string {
foreach ( $variables as $name => $value ) {
$variable_output = $this->prepare_variable( $name, $value );
- if ( null !== $variable_output ) {
- $output .= $variable_output;
+ if ( empty( $variable_output ) ) {
+ continue;
}
+
+ // Add a newline if there's already content.
+ if ( ! empty( $output ) ) {
+ $output .= "\n";
+ }
+
+ $output .= $variable_output;
}
return $output ?: null;
@@ -94,13 +101,16 @@ protected function prepare_variable( string $name, ?string $value ): ?string {
// Determine the final value to output.
$resolved_value = ! empty( $value ) ? $value : $default;
- if ( empty( $resolved_value ) ) {
- $resolved_value = null;
- }
- $comment = ! empty( $description ) ? sprintf( "\n# %s\n", $description ) : '';
- $output = null !== $resolved_value ? sprintf( '%s=%s\n', $name, $resolved_value ) : sprintf( '# %s=\'0\'\n', $name );
+ // Prepare the output.
+ $comment = ! empty( $description ) ? sprintf( "\n# %s\n", $description ) : '';
+ $env_output = sprintf( '%s=%s', $name, $resolved_value );
+
+ // Comment out variables if they're not required and have the default value.
+ if ( ! $required && $resolved_value === $default ) {
+ $env_output = '# ' . $env_output;
+ }
- return $comment . $output;
+ return $comment . $env_output;
}
}
diff --git a/src/Modules/EnvGenerator/VariableRegistry.php b/src/Modules/EnvGenerator/VariableRegistry.php
index 5a2c876..1992853 100644
--- a/src/Modules/EnvGenerator/VariableRegistry.php
+++ b/src/Modules/EnvGenerator/VariableRegistry.php
@@ -19,26 +19,36 @@ class VariableRegistry {
* @var array
*/
private const VARIABLES = [
- 'NODE_TLS_REJECT_UNAUTHORIZED' => [
+ 'NODE_TLS_REJECT_UNAUTHORIZED' => [
'description' => 'Enable if connecting to a self-signed cert',
- 'default' => '',
+ 'default' => '0',
'required' => false,
],
- 'NEXT_URL' => [
+ 'NEXT_PUBLIC_URL' => [
'description' => 'The headless frontend domain URL',
- 'default' => '',
+ 'default' => 'http://localhost:3000',
'required' => false,
],
- 'HOME_URL' => [
+ 'NEXT_PUBLIC_WORDPRESS_URL' => [
'description' => 'The WordPress "frontend" domain URL',
'default' => '',
'required' => true,
],
- 'GRAPHQL_ENDPOINT' => [
+ 'NEXT_PUBLIC_GRAPHQL_ENDPOINT' => [
'description' => 'The WordPress GraphQL endpoint',
'default' => 'graphql',
'required' => false,
],
+ 'NEXT_PUBLIC_WORDPRESS_UPLOADS_PATH' => [
+ 'description' => 'The WordPress Uploads directory path',
+ 'default' => 'wp-content/uploads',
+ 'required' => false,
+ ],
+ 'NEXT_PUBLIC_WORDPRESS_REST_URL_PREFIX' => [
+ 'description' => 'The WordPress REST URL Prefix',
+ 'default' => 'wp-json',
+ 'required' => false,
+ ],
];
/**
diff --git a/tests/Integration/GeneratorTest.php b/tests/Integration/GeneratorTest.php
index f513889..259fdce 100644
--- a/tests/Integration/GeneratorTest.php
+++ b/tests/Integration/GeneratorTest.php
@@ -7,9 +7,9 @@
namespace SnapWP\Helper\Tests\Integration;
-use lucatume\WPBrowser\TestCase\WPTestCase;
use SnapWP\Helper\Modules\EnvGenerator\Generator;
use SnapWP\Helper\Modules\EnvGenerator\VariableRegistry;
+use lucatume\WPBrowser\TestCase\WPTestCase;
/**
* Class GeneratorTest
@@ -24,10 +24,12 @@ public function testGeneratorInitialization(): void {
$registry = new VariableRegistry();
$values = [
- 'NODE_TLS_REJECT_UNAUTHORIZED' => '',
- 'NEXT_URL' => 'http://localhost:3000',
- 'HOME_URL' => 'https://headless-demo.local',
- 'GRAPHQL_ENDPOINT' => '',
+ 'NODE_TLS_REJECT_UNAUTHORIZED' => '',
+ 'NEXT_PUBLIC_URL' => 'http://localhost:3000',
+ 'NEXT_PUBLIC_WORDPRESS_URL' => 'https://headless-demo.local',
+ 'NEXT_PUBLIC_GRAPHQL_ENDPOINT' => '',
+ 'NEXT_PUBLIC_WORDPRESS_UPLOADS_PATH' => '',
+ 'NEXT_PUBLIC_WORDPRESS_REST_URL_PREFIX' => '',
];
$generator = new Generator( $values, $registry );
@@ -41,11 +43,13 @@ public function testGeneratorInitialization(): void {
public function testGenerateEnvContent(): void {
$registry = new VariableRegistry();
$values = [
- 'NODE_TLS_REJECT_UNAUTHORIZED' => '5',
- 'NEXT_URL' => 'http://localhost:3000',
- 'HOME_URL' => 'https://headless-demo.local',
- 'GRAPHQL_ENDPOINT' => '/test_endpoint',
- 'INVALID_VARIABLE' => 'should-not-be-included', // This should not be included in the output.
+ 'NODE_TLS_REJECT_UNAUTHORIZED' => '5',
+ 'NEXT_PUBLIC_URL' => 'http://localhost:3000',
+ 'NEXT_PUBLIC_WORDPRESS_URL' => 'https://headless-demo.local',
+ 'NEXT_PUBLIC_GRAPHQL_ENDPOINT' => '/test_endpoint',
+ 'NEXT_PUBLIC_WORDPRESS_UPLOADS_PATH' => 'uploads',
+ 'NEXT_PUBLIC_WORDPRESS_REST_URL_PREFIX' => 'api',
+ 'INVALID_VARIABLE' => 'should-not-be-included', // This should not be included in the output.
];
$generator = new Generator( $values, $registry );
@@ -53,7 +57,24 @@ public function testGenerateEnvContent(): void {
// Generate the .env content.
$content = $generator->generate();
- $expectedContent = "\n# Enable if connecting to a self-signed cert\nNODE_TLS_REJECT_UNAUTHORIZED=5\\n\n# The headless frontend domain URL\nNEXT_URL=http://localhost:3000\\n\n# The WordPress \"frontend\" domain URL\nHOME_URL=https://headless-demo.local\\n\n# The WordPress GraphQL endpoint\nGRAPHQL_ENDPOINT=/test_endpoint\\n";
+ $expectedContent = '
+# Enable if connecting to a self-signed cert
+NODE_TLS_REJECT_UNAUTHORIZED=5
+
+# The headless frontend domain URL
+# NEXT_PUBLIC_URL=http://localhost:3000
+
+# The WordPress "frontend" domain URL
+NEXT_PUBLIC_WORDPRESS_URL=https://headless-demo.local
+
+# The WordPress GraphQL endpoint
+NEXT_PUBLIC_GRAPHQL_ENDPOINT=/test_endpoint
+
+# The WordPress Uploads directory path
+NEXT_PUBLIC_WORDPRESS_UPLOADS_PATH=uploads
+
+# The WordPress REST URL Prefix
+NEXT_PUBLIC_WORDPRESS_REST_URL_PREFIX=api';
$this->assertSame( $expectedContent, $content );
}
@@ -64,10 +85,12 @@ public function testGenerateEnvContent(): void {
public function testMissingRequiredValuesEnvContent(): void {
$registry = new VariableRegistry();
$values = [
- 'NODE_TLS_REJECT_UNAUTHORIZED' => '',
- 'NEXT_URL' => '',
- 'HOME_URL' => '',
- 'GRAPHQL_ENDPOINT' => '',
+ 'NODE_TLS_REJECT_UNAUTHORIZED' => '',
+ 'NEXT_PUBLIC_URL' => '',
+ 'NEXT_PUBLIC_WORDPRESS_URL' => '',
+ 'NEXT_PUBLIC_GRAPHQL_ENDPOINT' => '',
+ 'NEXT_PUBLIC_WORDPRESS_UPLOADS_PATH' => '',
+ 'NEXT_PUBLIC_WORDPRESS_REST_URL_PREFIX' => '',
];
$generator = new Generator( $values, $registry );
@@ -88,10 +111,12 @@ public function testDefaultValuesForEnvContent(): void {
// CASE : For NODE_TLS_REJECT_UNAUTHORIZED with no default value, Generator class should comment out the variable in .ENV content.
$values = [
- 'NODE_TLS_REJECT_UNAUTHORIZED' => '',
- 'NEXT_URL' => 'http://localhost:3000',
- 'HOME_URL' => 'https://headless-demo.local',
- 'GRAPHQL_ENDPOINT' => '/test_endpoint',
+ 'NODE_TLS_REJECT_UNAUTHORIZED' => '',
+ 'NEXT_PUBLIC_URL' => '',
+ 'NEXT_PUBLIC_WORDPRESS_URL' => 'https://headless-demo.local',
+ 'NEXT_PUBLIC_GRAPHQL_ENDPOINT' => '/test_endpoint',
+ 'NEXT_PUBLIC_WORDPRESS_UPLOADS_PATH' => '',
+ 'NEXT_PUBLIC_WORDPRESS_REST_URL_PREFIX' => '',
];
$generator = new Generator( $values, $registry );
@@ -100,16 +125,33 @@ public function testDefaultValuesForEnvContent(): void {
$content = $generator->generate();
// Define expected content.
- $expectedContent = "\n# Enable if connecting to a self-signed cert\n# NODE_TLS_REJECT_UNAUTHORIZED='0'\\n\n# The headless frontend domain URL\nNEXT_URL=http://localhost:3000\\n\n# The WordPress \"frontend\" domain URL\nHOME_URL=https://headless-demo.local\\n\n# The WordPress GraphQL endpoint\nGRAPHQL_ENDPOINT=/test_endpoint\\n";
+ $expectedContent = '
+# Enable if connecting to a self-signed cert
+# NODE_TLS_REJECT_UNAUTHORIZED=0
+
+# The headless frontend domain URL
+# NEXT_PUBLIC_URL=http://localhost:3000
+
+# The WordPress "frontend" domain URL
+NEXT_PUBLIC_WORDPRESS_URL=https://headless-demo.local
+
+# The WordPress GraphQL endpoint
+NEXT_PUBLIC_GRAPHQL_ENDPOINT=/test_endpoint
+
+# The WordPress Uploads directory path
+# NEXT_PUBLIC_WORDPRESS_UPLOADS_PATH=wp-content/uploads
+
+# The WordPress REST URL Prefix
+# NEXT_PUBLIC_WORDPRESS_REST_URL_PREFIX=wp-json';
$this->assertSame( $expectedContent, $content );
// CASE : For GRAPHQL_ENDPOINT, Generator should use the default value of the variable.
$values = [
'NODE_TLS_REJECT_UNAUTHORIZED' => '',
- 'NEXT_URL' => 'http://localhost:3000',
- 'HOME_URL' => 'https://headless-demo.local',
- 'GRAPHQL_ENDPOINT' => '',
+ 'NEXT_PUBLIC_URL' => 'http://localhost:3000',
+ 'NEXT_PUBLIC_WORDPRESS_URL' => 'https://headless-demo.local',
+ 'NEXT_PUBLIC_GRAPHQL_ENDPOINT' => '',
];
$generator = new Generator( $values, $registry );
@@ -117,7 +159,18 @@ public function testDefaultValuesForEnvContent(): void {
// Generate the .env content.
$content = $generator->generate();
- $expectedContent = "\n# Enable if connecting to a self-signed cert\n# NODE_TLS_REJECT_UNAUTHORIZED='0'\\n\n# The headless frontend domain URL\nNEXT_URL=http://localhost:3000\\n\n# The WordPress \"frontend\" domain URL\nHOME_URL=https://headless-demo.local\\n\n# The WordPress GraphQL endpoint\nGRAPHQL_ENDPOINT=graphql\\n";
+ $expectedContent = '
+# Enable if connecting to a self-signed cert
+# NODE_TLS_REJECT_UNAUTHORIZED=0
+
+# The headless frontend domain URL
+# NEXT_PUBLIC_URL=http://localhost:3000
+
+# The WordPress "frontend" domain URL
+NEXT_PUBLIC_WORDPRESS_URL=https://headless-demo.local
+
+# The WordPress GraphQL endpoint
+# NEXT_PUBLIC_GRAPHQL_ENDPOINT=graphql';
$this->assertSame( $expectedContent, $content );
}
diff --git a/tests/Integration/RestControllerTest.php b/tests/Integration/RestControllerTest.php
index 57b7093..1c73ed8 100644
--- a/tests/Integration/RestControllerTest.php
+++ b/tests/Integration/RestControllerTest.php
@@ -64,6 +64,7 @@ public function testRegisterRoutes(): void {
/**
* Tests if the endpoint is accessible, and the env content in response is correct.
+ * Assuming standard default values.
*/
public function testGenerateEnvEndpoint(): void {
@@ -86,7 +87,7 @@ public function testGenerateEnvEndpoint(): void {
$this->assertNotEmpty( $actual_data['content'] );
$search = '\n';
$replace = '';
- $expected = "\n# Enable if connecting to a self-signed cert\n# NODE_TLS_REJECT_UNAUTHORIZED='0'\n# The headless frontend domain URL\n# NEXT_URL='0'\n# The WordPress \"frontend\" domain URL\nHOME_URL=" . get_home_url() . "\n# The WordPress GraphQL endpoint\nGRAPHQL_ENDPOINT=" . graphql_get_endpoint();
+ $expected = "\n# Enable if connecting to a self-signed cert\n# NODE_TLS_REJECT_UNAUTHORIZED=0\n\n# The headless frontend domain URL\n# NEXT_PUBLIC_URL=http://localhost:3000\n\n# The WordPress \"frontend\" domain URL\nNEXT_PUBLIC_WORDPRESS_URL=" . get_home_url() . "\n\n# The WordPress GraphQL endpoint\n# NEXT_PUBLIC_GRAPHQL_ENDPOINT=" . graphql_get_endpoint() . "\n\n# The WordPress Uploads directory path\n# NEXT_PUBLIC_WORDPRESS_UPLOADS_PATH=" . str_replace( ABSPATH, '', wp_get_upload_dir()['basedir'] ) . "\n\n# The WordPress REST URL Prefix\n# NEXT_PUBLIC_WORDPRESS_REST_URL_PREFIX=" . rest_get_url_prefix();
$this->assertEquals( $expected, str_replace( $search, $replace, $actual_data['content'] ) );