Skip to content

Commit

Permalink
Completed npm commands (npm:install, npm:update, npm:run) (#1202)
Browse files Browse the repository at this point in the history
Documented by wintercms/docs#213
  • Loading branch information
jaxwilko authored Oct 25, 2024
1 parent 76b9331 commit 7d67661
Show file tree
Hide file tree
Showing 34 changed files with 1,501 additions and 311 deletions.
4 changes: 3 additions & 1 deletion .eslintignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,6 @@ assets/vendor
# Ignore test fixtures
tests/js
tests/fixtures/themes/test/assets/js
tests/fixtures/themes/vitetest/assets/javascript
tests/fixtures/themes/npmtest
tests/fixtures/themes/assettest
tests/fixtures/plugins/mix
5 changes: 3 additions & 2 deletions ServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -338,8 +338,9 @@ protected function registerConsole()
$this->registerConsoleCommand('vite.list', Console\Asset\Vite\ViteList::class);
$this->registerConsoleCommand('vite.watch', Console\Asset\Vite\ViteWatch::class);

$this->registerConsoleCommand('npm.run', Console\Asset\NpmRun::class);
$this->registerConsoleCommand('npm.update', Console\Asset\NpmUpdate::class);
$this->registerConsoleCommand('npm.run', Console\Asset\Npm\NpmRun::class);
$this->registerConsoleCommand('npm.install', Console\Asset\Npm\NpmInstall::class);
$this->registerConsoleCommand('npm.update', Console\Asset\Npm\NpmUpdate::class);
}

/*
Expand Down
15 changes: 11 additions & 4 deletions classes/asset/PackageJson.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,17 +19,24 @@ class PackageJson
/**
* The contents of the package.json being modified
*/
protected array $data;
protected array $data = [];

/**
* Create a new instance with optional path, loads file if file already exists
* @throws \JsonException
*/
public function __construct(
protected ?string $path = null
) {
$this->data = File::exists($this->path)
? json_decode(File::get($this->path), JSON_OBJECT_AS_ARRAY)
: [];
if (File::exists($this->path)) {
// Test the json to insure it's valid
$json = json_decode(File::get($this->path), JSON_OBJECT_AS_ARRAY);
if (json_last_error() !== JSON_ERROR_NONE) {
throw new \JsonException('The contents of the file "' . $this->path . '" is not valid json.');
}

$this->data = $json;
}
}

/**
Expand Down
93 changes: 76 additions & 17 deletions classes/asset/PackageManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,14 @@ class PackageManager
{
use \Winter\Storm\Support\Traits\Singleton;

public const TYPE_THEME = 'theme';
public const TYPE_MODULE = 'module';
public const TYPE_PLUGIN = 'plugin';

/**
* The filename that stores the package definition.
*/
protected string $packageJson = 'package.json';
protected PackageJson $packageJson;

/**
* @var array<string, array<string, string>> List of package types and registration methods
Expand Down Expand Up @@ -56,6 +60,8 @@ class PackageManager
*/
public function init(): void
{
$this->setPackageJsonPath(base_path('package.json'));

$packagePaths = [];

/*
Expand Down Expand Up @@ -183,12 +189,14 @@ public static function registerCallback(callable $callback): void
/**
* Calls the deferred callbacks.
*/
public function fireCallbacks(): void
public function fireCallbacks(): static
{
// Call callbacks
foreach (static::$callbacks as $callback) {
$callback($this);
}

return $this;
}

/**
Expand All @@ -206,6 +214,10 @@ public function getPackages(string $type, bool $includeIgnored = false): array
{
$packages = $this->packages[$type] ?? [];

foreach ($packages as $index => $package) {
$packages[$index]['ignored'] = $this->isPackageIgnored($package['path']);
}

ksort($packages);

if (!$includeIgnored) {
Expand All @@ -223,9 +235,13 @@ public function getPackages(string $type, bool $includeIgnored = false): array
public function hasPackage(string $name, bool $includeIgnored = false): bool
{
foreach ($this->packages ?? [] as $packages) {
foreach ($packages as $packageName => $config) {
if (($name === $packageName) && (!$config['ignored'] || $includeIgnored)) {
return true;
foreach ($packages as $packageName => $package) {
if ($name === $packageName) {
if ((!$this->isPackageIgnored($package['path']) || $includeIgnored)) {
return true;
}

return false;
}
}
}
Expand All @@ -239,10 +255,12 @@ public function hasPackage(string $name, bool $includeIgnored = false): bool
public function getPackage(string $name, bool $includeIgnored = false): array
{
$results = [];
foreach ($this->packages ?? [] as $packages) {
foreach ($packages as $packageName => $config) {
if (($name === $packageName) && (!$config['ignored'] || $includeIgnored)) {
$results[] = $config;
foreach ($this->packages ?? [] as $type => $packages) {
foreach ($packages as $packageName => $package) {
if (($name === $packageName)) {
if (!$this->isPackageIgnored($package['path']) || $includeIgnored) {
$results[] = $package + ['type' => $type];
}
}
}
}
Expand Down Expand Up @@ -297,6 +315,17 @@ public function registerPackage(string $name, string $path, string $type = 'mix'
));
}

$package = $path . '/package.json';
$config = $path . DIRECTORY_SEPARATOR . $configFile;

if (!File::exists($config)) {
throw new SystemException(sprintf(
'Cannot register "%s" as a compilable package; the config file "%s" does not exist.',
$name,
$config
));
}

// Check for any existing packages already registered under the provided name
if (isset($this->packages[$name])) {
throw new SystemException(sprintf(
Expand All @@ -306,9 +335,6 @@ public function registerPackage(string $name, string $path, string $type = 'mix'
));
}

$package = "$path/{$this->packageJson}";
$config = $path . DIRECTORY_SEPARATOR . $configFile;

// Check for any existing package that already registers the given compilable config path
foreach ($this->packages[$type] ?? [] as $packageName => $settings) {
if ($settings['config'] === $config) {
Expand All @@ -325,11 +351,46 @@ public function registerPackage(string $name, string $path, string $type = 'mix'
$this->packages[$type][$name] = [
'path' => $path,
'package' => $package,
'config' => $config,
'ignored' => $this->isPackageIgnored($path),
'config' => $config
];
}

/**
* Returns an expected package type from its name
*/
public function getPackageTypeFromName(string $package): ?string
{
// Check if package could be a module
if (Str::startsWith($package, 'module-') && !in_array($package, ['system', 'backend', 'cms'])) {
return static::TYPE_MODULE;
}

// Check if package could be a theme
if (
in_array('Cms', Config::get('cms.loadModules'))
&& Str::startsWith($package, 'theme-')
&& Theme::exists(Str::after($package, 'theme-'))
) {
return static::TYPE_THEME;
}

// Check if a package could be a plugin
if (PluginManager::instance()->exists($package)) {
return static::TYPE_PLUGIN;
}

return null;
}

/**
* Set the package.json file path used for checking if packages are in workspaces or ignored
*/
public function setPackageJsonPath(string $packageJsonPath): static
{
$this->packageJson = new PackageJson($packageJsonPath);
return $this;
}

/**
* Returns the registration method for a compiler type
*/
Expand All @@ -343,8 +404,6 @@ protected function getRegistrationMethod(string $type): string
*/
protected function isPackageIgnored(string $packagePath): bool
{
// Load the main package.json for the project
$packageJson = new PackageJson(base_path($this->packageJson));
return $packageJson->hasIgnoredPackage($packagePath);
return $this->packageJson->hasIgnoredPackage($packagePath);
}
}
Loading

0 comments on commit 7d67661

Please sign in to comment.