Frontend CLI + Templates
This commit is contained in:
parent
a54ab8620e
commit
716d623db4
@ -10,7 +10,7 @@ if (is_file($autoLoad)) {
|
|||||||
require_once $autoLoad;
|
require_once $autoLoad;
|
||||||
}
|
}
|
||||||
|
|
||||||
const WEBBASE_VERSION = "2.3.0";
|
const WEBBASE_VERSION = "2.3.1";
|
||||||
|
|
||||||
spl_autoload_extensions(".php");
|
spl_autoload_extensions(".php");
|
||||||
spl_autoload_register(function ($class) {
|
spl_autoload_register(function ($class) {
|
||||||
|
12
README.md
12
README.md
@ -305,7 +305,17 @@ php cli.php routes remove 1
|
|||||||
php cli.php routes enable 1
|
php cli.php routes enable 1
|
||||||
php cli.php routes disable 1
|
php cli.php routes disable 1
|
||||||
php cli.php routes add /some/path static /static/test.html
|
php cli.php routes add /some/path static /static/test.html
|
||||||
php.cli.php routes modify 1 '/regex(/.*)?' dynamic '\\Documents\\Test'
|
php cli.php routes modify 1 '/regex(/.*)?' dynamic '\\Documents\\Test'
|
||||||
|
```
|
||||||
|
|
||||||
|
### Frontend commands
|
||||||
|
```bash
|
||||||
|
# Frontend commands
|
||||||
|
php cli.php frontend build
|
||||||
|
php cli.php frontend ls
|
||||||
|
php cli.php frontend add <module-name>
|
||||||
|
php cli.php frontend rm <module-name>
|
||||||
|
php cli.php frontend dev <module-name>
|
||||||
```
|
```
|
||||||
|
|
||||||
## Anything more?
|
## Anything more?
|
||||||
|
210
cli.php
210
cli.php
@ -50,16 +50,6 @@ if ($database->getProperty("isDocker", false) && !is_file("/.dockerenv")) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($database->getProperty("isDocker", false) && !is_file("/.dockerenv")) {
|
|
||||||
printLine("Detected docker environment in config, running docker exec...");
|
|
||||||
if (count($argv) < 3 || $argv[1] !== "db" || !in_array($argv[2], ["shell", "import", "export"])) {
|
|
||||||
$containerName = $dockerYaml["services"]["php"]["container_name"];
|
|
||||||
$command = array_merge(["docker", "exec", "-it", $containerName, "php"], $argv);
|
|
||||||
$proc = proc_open($command, [1 => STDOUT, 2 => STDERR], $pipes);
|
|
||||||
exit(proc_close($proc));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function connectSQL(): ?SQL {
|
function connectSQL(): ?SQL {
|
||||||
global $context;
|
global $context;
|
||||||
$sql = $context->initSQL();
|
$sql = $context->initSQL();
|
||||||
@ -662,40 +652,180 @@ function onImpersonate($argv): void {
|
|||||||
echo "session=" . $session->getUUID() . PHP_EOL;
|
echo "session=" . $session->getUUID() . PHP_EOL;
|
||||||
}
|
}
|
||||||
|
|
||||||
$argv = $_SERVER['argv'];
|
function onFrontend(array $argv): void {
|
||||||
if (count($argv) < 2) {
|
if (count($argv) < 3) {
|
||||||
_exit("Usage: cli.php <db|routes|settings|maintenance|impersonate> [options...]");
|
_exit("Usage: cli.php frontend <build|add|ls> [options...]");
|
||||||
|
}
|
||||||
|
|
||||||
|
$reactRoot = realpath(WEBROOT . "/react/");
|
||||||
|
if (!$reactRoot) {
|
||||||
|
_exit("React root directory not found!");
|
||||||
|
}
|
||||||
|
|
||||||
|
$action = $argv[2] ?? null;
|
||||||
|
if ($action === "build") {
|
||||||
|
$proc = proc_open(["yarn", "run", "build"], [1 => STDOUT, 2 => STDERR], $pipes, $reactRoot);
|
||||||
|
exit(proc_close($proc));
|
||||||
|
} else if ($action === "add") {
|
||||||
|
if (count($argv) < 4) {
|
||||||
|
_exit("Usage: cli.php frontend add <module-name>");
|
||||||
|
}
|
||||||
|
|
||||||
|
$moduleName = strtolower($argv[3]);
|
||||||
|
if (!preg_match("/[a-z0-9_-]/", $moduleName)) {
|
||||||
|
_exit("Module name should only be [a-zA-Z0-9_-]");
|
||||||
|
}
|
||||||
|
|
||||||
|
$templatePath = implode(DIRECTORY_SEPARATOR, [$reactRoot, "_tmpl"]);
|
||||||
|
$modulePath = implode(DIRECTORY_SEPARATOR, [$reactRoot, $moduleName]);
|
||||||
|
if (file_exists($modulePath)) {
|
||||||
|
_exit("File or module does already exist: " . $modulePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
$rootPackageJsonPath = implode(DIRECTORY_SEPARATOR, [$reactRoot, "package.json"]);
|
||||||
|
$rootPackageJson = @json_decode(@file_get_contents($rootPackageJsonPath), true);
|
||||||
|
if (!$rootPackageJson) {
|
||||||
|
_exit("Unable to read root package.json");
|
||||||
|
}
|
||||||
|
|
||||||
|
$reactVersion = $rootPackageJson["dependencies"]["react"];
|
||||||
|
if (!array_key_exists($moduleName, $rootPackageJson["targets"])) {
|
||||||
|
$rootPackageJson["targets"][$moduleName] = [
|
||||||
|
"source" => "./$moduleName/src/index.js",
|
||||||
|
"distDir" => "./dist/$moduleName"
|
||||||
|
];
|
||||||
|
file_put_contents($rootPackageJsonPath, json_encode($rootPackageJson, JSON_PRETTY_PRINT|JSON_UNESCAPED_SLASHES));
|
||||||
|
}
|
||||||
|
|
||||||
|
mkdir($modulePath, 0775, true);
|
||||||
|
$placeHolders = [
|
||||||
|
"MODULE_NAME" => $moduleName,
|
||||||
|
"REACT_VERSION" => $reactVersion
|
||||||
|
];
|
||||||
|
|
||||||
|
$it = new RecursiveDirectoryIterator($templatePath);
|
||||||
|
foreach (new RecursiveIteratorIterator($it) as $file) {
|
||||||
|
$fileName = $file->getFilename();
|
||||||
|
$relDir = substr($file->getPath(), strlen($templatePath) + 1);
|
||||||
|
$targetFile = implode(DIRECTORY_SEPARATOR, [$modulePath, $relDir, $fileName]);
|
||||||
|
if ($file->isFile()) {
|
||||||
|
$contents = file_get_contents($file);
|
||||||
|
foreach ($placeHolders as $key => $value) {
|
||||||
|
$contents = str_replace("{{{$key}}}", $value, $contents);
|
||||||
|
}
|
||||||
|
$directory = dirname($targetFile);
|
||||||
|
if (!is_dir($directory)) {
|
||||||
|
mkdir($directory, 0775, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
file_put_contents($targetFile, $contents);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
printLine("Successfully added react module: $moduleName");
|
||||||
|
printLine("Run `php cli.php frontend build` to create a production build or");
|
||||||
|
printLine("run `php cli.php frontend dev $moduleName` to start a dev-server with your module");
|
||||||
|
} else if ($action === "dev") {
|
||||||
|
if (count($argv) < 4) {
|
||||||
|
_exit("Usage: cli.php frontend add <module-name>");
|
||||||
|
}
|
||||||
|
|
||||||
|
$moduleName = strtolower($argv[3]);
|
||||||
|
$proc = proc_open(["yarn", "workspace", $moduleName, "run", "dev"], [1 => STDOUT, 2 => STDERR], $pipes, $reactRoot);
|
||||||
|
exit(proc_close($proc));
|
||||||
|
} else if ($action === "rm") {
|
||||||
|
if (count($argv) < 4) {
|
||||||
|
_exit("Usage: cli.php frontend add <module-name>");
|
||||||
|
}
|
||||||
|
|
||||||
|
$moduleName = strtolower($argv[3]);
|
||||||
|
if (!preg_match("/[a-z0-9_-]/", $moduleName)) {
|
||||||
|
_exit("Module name should only be [a-zA-Z0-9_-]");
|
||||||
|
}
|
||||||
|
|
||||||
|
$modulePath = implode(DIRECTORY_SEPARATOR, [$reactRoot, $moduleName]);
|
||||||
|
if (!is_dir($modulePath)) {
|
||||||
|
_exit("Module not found: $modulePath");
|
||||||
|
}
|
||||||
|
|
||||||
|
$rootPackageJsonPath = implode(DIRECTORY_SEPARATOR, [$reactRoot, "package.json"]);
|
||||||
|
$rootPackageJson = @json_decode(@file_get_contents($rootPackageJsonPath), true);
|
||||||
|
if (!$rootPackageJson) {
|
||||||
|
_exit("Unable to read root package.json");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (array_key_exists($moduleName, $rootPackageJson["targets"])) {
|
||||||
|
unset($rootPackageJson["targets"][$moduleName]);
|
||||||
|
file_put_contents($rootPackageJsonPath, json_encode($rootPackageJson, JSON_PRETTY_PRINT|JSON_UNESCAPED_SLASHES));
|
||||||
|
}
|
||||||
|
|
||||||
|
$input = strtolower(trim(readline("Do you want to disable the module only and keep the files? [Y|n]: ")));
|
||||||
|
if ($input === "n") {
|
||||||
|
rrmdir($modulePath);
|
||||||
|
printLine("Disabled and deleted module: $moduleName");
|
||||||
|
} else {
|
||||||
|
printLine("Disabled module: $moduleName");
|
||||||
|
}
|
||||||
|
} else if ($action === "ls") {
|
||||||
|
printLine("Current available modules:");
|
||||||
|
foreach (glob(implode(DIRECTORY_SEPARATOR, [$reactRoot, "*"]), GLOB_ONLYDIR) as $directory) {
|
||||||
|
if (basename($directory) === "_tmpl") {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$packageJson = realpath(implode(DIRECTORY_SEPARATOR, [$directory, "package.json"]));
|
||||||
|
if ($packageJson) {
|
||||||
|
$packageJsonContents = @json_decode(@file_get_contents($packageJson), true);
|
||||||
|
if (!$packageJsonContents) {
|
||||||
|
printLine("$directory: Unable to read package.json");
|
||||||
|
} else {
|
||||||
|
$packageName = $packageJsonContents["name"];
|
||||||
|
$packageVersion = $packageJsonContents["version"];
|
||||||
|
printLine("- $packageName version: $packageVersion");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
_exit("Usage: cli.php frontend <build|ls|add|rm|dev> [options...]");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$command = $argv[1];
|
$argv = $_SERVER['argv'];
|
||||||
switch ($command) {
|
$registeredCommands = [
|
||||||
case 'help':
|
"help" => ["handler" => "printHelp"],
|
||||||
printHelp($argv);
|
"db" => ["handler" => "handleDatabase", "requiresDocker" => ["shell", "import", "export"]],
|
||||||
exit;
|
"routes" => ["handler" => "onRoutes"],
|
||||||
case 'db':
|
"maintenance" => ["handler" => "onMaintenance"],
|
||||||
handleDatabase($argv);
|
"test" => ["handler" => "onTest"],
|
||||||
break;
|
"mail" => ["handler" => "onMail"],
|
||||||
case 'routes':
|
"settings" => ["handler" => "onSettings"],
|
||||||
onRoutes($argv);
|
"impersonate" => ["handler" => "onImpersonate"],
|
||||||
break;
|
"frontend" => ["handler" => "onFrontend"],
|
||||||
case 'maintenance':
|
];
|
||||||
onMaintenance($argv);
|
|
||||||
break;
|
|
||||||
case 'test':
|
if (count($argv) < 2) {
|
||||||
onTest($argv);
|
_exit("Usage: cli.php <" . implode("|", array_keys($registeredCommands)) . "> [options...]");
|
||||||
break;
|
} else {
|
||||||
case 'mail':
|
$command = $argv[1];
|
||||||
onMail($argv);
|
if (array_key_exists($command, $registeredCommands)) {
|
||||||
break;
|
|
||||||
case 'settings':
|
if ($database->getProperty("isDocker", false) && !is_file("/.dockerenv")) {
|
||||||
onSettings($argv);
|
$requiresDocker = in_array($argv[2] ?? null, $registeredCommands[$command]["requiresDocker"] ?? []);
|
||||||
break;
|
if ($requiresDocker) {
|
||||||
case 'impersonate':
|
printLine("Detected docker environment in config, running docker exec...");
|
||||||
onImpersonate($argv);
|
$containerName = $dockerYaml["services"]["php"]["container_name"];
|
||||||
break;
|
$command = array_merge(["docker", "exec", "-it", $containerName, "php"], $argv);
|
||||||
default:
|
$proc = proc_open($command, [1 => STDOUT, 2 => STDERR], $pipes);
|
||||||
|
exit(proc_close($proc));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
call_user_func($registeredCommands[$command]["handler"], $argv);
|
||||||
|
} else {
|
||||||
printLine("Unknown command '$command'");
|
printLine("Unknown command '$command'");
|
||||||
printLine();
|
printLine();
|
||||||
printHelp($argv);
|
printHelp($argv);
|
||||||
exit;
|
exit;
|
||||||
|
}
|
||||||
}
|
}
|
@ -5,7 +5,7 @@ WORKDIR "/application"
|
|||||||
ARG ADDITIONAL_PACKAGES
|
ARG ADDITIONAL_PACKAGES
|
||||||
ARG ADDITIONAL_SCRIPT
|
ARG ADDITIONAL_SCRIPT
|
||||||
|
|
||||||
RUN mkdir -p /application/core/Configuration /var/www/.gnupg && \
|
RUN mkdir -p /application/Core/Configuration /var/www/.gnupg && \
|
||||||
chown -R www-data:www-data /application /var/www/ && \
|
chown -R www-data:www-data /application /var/www/ && \
|
||||||
chmod 700 /var/www/.gnupg
|
chmod 700 /var/www/.gnupg
|
||||||
|
|
||||||
|
27
react/_tmpl/config-overrides.js
Normal file
27
react/_tmpl/config-overrides.js
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
const fs = require('fs');
|
||||||
|
const path = require('path');
|
||||||
|
const {
|
||||||
|
override,
|
||||||
|
removeModuleScopePlugin,
|
||||||
|
babelInclude,
|
||||||
|
addWebpackModuleRule,
|
||||||
|
} = require('customize-cra');
|
||||||
|
|
||||||
|
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
|
||||||
|
const addMiniCssExtractPlugin = config => {
|
||||||
|
config.plugins.push(new MiniCssExtractPlugin());
|
||||||
|
return config;
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = override(
|
||||||
|
removeModuleScopePlugin(),
|
||||||
|
addMiniCssExtractPlugin,
|
||||||
|
addWebpackModuleRule({
|
||||||
|
test: /\.css$/,
|
||||||
|
use: [ MiniCssExtractPlugin.loader, 'css-loader' ]
|
||||||
|
}),
|
||||||
|
babelInclude([
|
||||||
|
path.resolve(path.join(__dirname, 'src')),
|
||||||
|
fs.realpathSync(path.join(__dirname, '../shared')),
|
||||||
|
]),
|
||||||
|
);
|
28
react/_tmpl/package.json
Normal file
28
react/_tmpl/package.json
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
{
|
||||||
|
"name": "{{MODULE_NAME}}",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"dependencies": {
|
||||||
|
"shared": "link:../shared",
|
||||||
|
"react": "{{REACT_VERSION}}"
|
||||||
|
},
|
||||||
|
"scripts": {
|
||||||
|
"dev": "react-app-rewired start"
|
||||||
|
},
|
||||||
|
"author": "",
|
||||||
|
"license": "ISC",
|
||||||
|
"description": "",
|
||||||
|
"devDependencies": {},
|
||||||
|
"browserslist": {
|
||||||
|
"production": [
|
||||||
|
">0.2%",
|
||||||
|
"not dead",
|
||||||
|
"not op_mini all"
|
||||||
|
],
|
||||||
|
"development": [
|
||||||
|
"last 1 chrome version",
|
||||||
|
"last 1 firefox version",
|
||||||
|
"last 1 safari version"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"proxy": "http://localhost"
|
||||||
|
}
|
9
react/_tmpl/src/App.jsx
Normal file
9
react/_tmpl/src/App.jsx
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
import {useMemo} from "react";
|
||||||
|
import API from "shared/api";
|
||||||
|
|
||||||
|
export default function App() {
|
||||||
|
|
||||||
|
const api = useMemo(() => new API(), []);
|
||||||
|
|
||||||
|
return <></>
|
||||||
|
}
|
9
react/_tmpl/src/index.js
Normal file
9
react/_tmpl/src/index.js
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
import React from "react";
|
||||||
|
import {createRoot} from "react-dom/client";
|
||||||
|
import App from "./App";
|
||||||
|
import {LocaleProvider} from "shared/locale";
|
||||||
|
|
||||||
|
const root = createRoot(document.getElementById('{{MODULE_NAME}}'));
|
||||||
|
root.render(<LocaleProvider>
|
||||||
|
<App />
|
||||||
|
</LocaleProvider>);
|
@ -2487,10 +2487,10 @@
|
|||||||
resolved "https://registry.yarnpkg.com/@popperjs/core/-/core-2.11.6.tgz#cee20bd55e68a1720bdab363ecf0c821ded4cd45"
|
resolved "https://registry.yarnpkg.com/@popperjs/core/-/core-2.11.6.tgz#cee20bd55e68a1720bdab363ecf0c821ded4cd45"
|
||||||
integrity sha512-50/17A98tWUfQ176raKiOGXuYpLyyVMkxxG6oylzL3BPOlA6ADGdK7EYunSa4I064xerltq9TGXs8HmOk5E+vw==
|
integrity sha512-50/17A98tWUfQ176raKiOGXuYpLyyVMkxxG6oylzL3BPOlA6ADGdK7EYunSa4I064xerltq9TGXs8HmOk5E+vw==
|
||||||
|
|
||||||
"@remix-run/router@1.0.3":
|
"@remix-run/router@1.15.3":
|
||||||
version "1.0.3"
|
version "1.15.3"
|
||||||
resolved "https://registry.yarnpkg.com/@remix-run/router/-/router-1.0.3.tgz#953b88c20ea00d0eddaffdc1b115c08474aa295d"
|
resolved "https://registry.yarnpkg.com/@remix-run/router/-/router-1.15.3.tgz#d2509048d69dbb72d5389a14945339f1430b2d3c"
|
||||||
integrity sha512-ceuyTSs7PZ/tQqi19YZNBc5X7kj1f8p+4DIyrcIYFY9h+hd1OKm4RqtiWldR9eGEvIiJfsqwM4BsuCtRIuEw6Q==
|
integrity sha512-Oy8rmScVrVxWZVOpEF57ovlnhpZ8CCPlnIIumVcV9nFdiSIrus99+Lw78ekXyGvVDlIsFJbSfmSovJUhCWYV3w==
|
||||||
|
|
||||||
"@rollup/plugin-babel@^5.2.0":
|
"@rollup/plugin-babel@^5.2.0":
|
||||||
version "5.3.1"
|
version "5.3.1"
|
||||||
@ -3838,9 +3838,9 @@ caniuse-api@^3.0.0:
|
|||||||
lodash.uniq "^4.5.0"
|
lodash.uniq "^4.5.0"
|
||||||
|
|
||||||
caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001400, caniuse-lite@^1.0.30001426:
|
caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001400, caniuse-lite@^1.0.30001426:
|
||||||
version "1.0.30001435"
|
version "1.0.30001600"
|
||||||
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001435.tgz#502c93dbd2f493bee73a408fe98e98fb1dad10b2"
|
resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001600.tgz"
|
||||||
integrity sha512-kdCkUTjR+v4YAJelyiDTqiu82BDr4W4CP5sgTA0ZBmqn30XfS2ZghPLMowik9TPhS+psWJiUNxsqLyurDbmutA==
|
integrity sha512-+2S9/2JFhYmYaDpZvo0lKkfvuKIglrx68MwOBqMGHhQsNkLjB5xtc/TGoEPs+MxjSyN/72qer2g97nzR641mOQ==
|
||||||
|
|
||||||
case-sensitive-paths-webpack-plugin@^2.4.0:
|
case-sensitive-paths-webpack-plugin@^2.4.0:
|
||||||
version "2.4.0"
|
version "2.4.0"
|
||||||
@ -8584,20 +8584,20 @@ react-refresh@^0.9.0:
|
|||||||
resolved "https://registry.yarnpkg.com/react-refresh/-/react-refresh-0.9.0.tgz#71863337adc3e5c2f8a6bfddd12ae3bfe32aafbf"
|
resolved "https://registry.yarnpkg.com/react-refresh/-/react-refresh-0.9.0.tgz#71863337adc3e5c2f8a6bfddd12ae3bfe32aafbf"
|
||||||
integrity sha512-Gvzk7OZpiqKSkxsQvO/mbTN1poglhmAV7gR/DdIrRrSMXraRQQlfikRJOr3Nb9GTMPC5kof948Zy6jJZIFtDvQ==
|
integrity sha512-Gvzk7OZpiqKSkxsQvO/mbTN1poglhmAV7gR/DdIrRrSMXraRQQlfikRJOr3Nb9GTMPC5kof948Zy6jJZIFtDvQ==
|
||||||
|
|
||||||
react-router-dom@^6.4.3:
|
react-router-dom@^6.6.2:
|
||||||
version "6.4.3"
|
version "6.22.3"
|
||||||
resolved "https://registry.yarnpkg.com/react-router-dom/-/react-router-dom-6.4.3.tgz#70093b5f65f85f1df9e5d4182eb7ff3a08299275"
|
resolved "https://registry.yarnpkg.com/react-router-dom/-/react-router-dom-6.22.3.tgz#9781415667fd1361a475146c5826d9f16752a691"
|
||||||
integrity sha512-MiaYQU8CwVCaOfJdYvt84KQNjT78VF0TJrA17SIQgNHRvLnXDJO6qsFqq8F/zzB1BWZjCFIrQpu4QxcshitziQ==
|
integrity sha512-7ZILI7HjcE+p31oQvwbokjk6OA/bnFxrhJ19n82Ex9Ph8fNAq+Hm/7KchpMGlTgWhUxRHMMCut+vEtNpWpowKw==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@remix-run/router" "1.0.3"
|
"@remix-run/router" "1.15.3"
|
||||||
react-router "6.4.3"
|
react-router "6.22.3"
|
||||||
|
|
||||||
react-router@6.4.3:
|
react-router@6.22.3:
|
||||||
version "6.4.3"
|
version "6.22.3"
|
||||||
resolved "https://registry.yarnpkg.com/react-router/-/react-router-6.4.3.tgz#9ed3ee4d6e95889e9b075a5d63e29acc7def0d49"
|
resolved "https://registry.yarnpkg.com/react-router/-/react-router-6.22.3.tgz#9d9142f35e08be08c736a2082db5f0c9540a885e"
|
||||||
integrity sha512-BT6DoGn6aV1FVP5yfODMOiieakp3z46P1Fk0RNzJMACzE7C339sFuHebfvWtnB4pzBvXXkHP2vscJzWRuUjTtA==
|
integrity sha512-dr2eb3Mj5zK2YISHK++foM9w4eBnO23eKnZEDs7c880P6oKbrjz/Svg9+nxqtHQK+oMW4OtjZca0RqPglXxguQ==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@remix-run/router" "1.0.3"
|
"@remix-run/router" "1.15.3"
|
||||||
|
|
||||||
react-scripts@^5.0.1:
|
react-scripts@^5.0.1:
|
||||||
version "5.0.1"
|
version "5.0.1"
|
||||||
|
Loading…
Reference in New Issue
Block a user