latest update
This commit is contained in:
1 parent
7a7ed16830
commit
026a23ade1
17 files changed
+2739
No files matched your search
@@ -0,0 +1,383 @@
|
||||
<?php
|
||||
|
||||
|
||||
error_reporting(E_ERROR | E_PARSE);
|
||||
|
||||
define('LARAVEL_START', microtime(true));
|
||||
|
||||
require_once __DIR__ . '/../autoload.php';
|
||||
|
||||
class LaravelVsCode
|
||||
{
|
||||
public static function relativePath($path)
|
||||
{
|
||||
if (!str_contains($path, base_path())) {
|
||||
return (string) $path;
|
||||
}
|
||||
|
||||
return ltrim(str_replace(base_path(), '', realpath($path) ?: $path), DIRECTORY_SEPARATOR);
|
||||
}
|
||||
|
||||
public static function isVendor($path)
|
||||
{
|
||||
return str_contains($path, base_path("vendor"));
|
||||
}
|
||||
|
||||
public static function outputMarker($key)
|
||||
{
|
||||
return '__VSCODE_LARAVEL_' . $key . '__';
|
||||
}
|
||||
|
||||
public static function startupError(\Throwable $e)
|
||||
{
|
||||
throw new Error(self::outputMarker('STARTUP_ERROR') . ': ' . $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
$app = require_once __DIR__ . '/../../bootstrap/app.php';
|
||||
} catch (\Throwable $e) {
|
||||
LaravelVsCode::startupError($e);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
$app->register(new class($app) extends \Illuminate\Support\ServiceProvider
|
||||
{
|
||||
public function boot()
|
||||
{
|
||||
config([
|
||||
'logging.channels.null' => [
|
||||
'driver' => 'monolog',
|
||||
'handler' => \Monolog\Handler\NullHandler::class,
|
||||
],
|
||||
'logging.default' => 'null',
|
||||
]);
|
||||
}
|
||||
});
|
||||
|
||||
try {
|
||||
$kernel = $app->make(Illuminate\Contracts\Console\Kernel::class);
|
||||
$kernel->bootstrap();
|
||||
} catch (\Throwable $e) {
|
||||
LaravelVsCode::startupError($e);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
echo LaravelVsCode::outputMarker('START_OUTPUT');
|
||||
|
||||
$components = new class {
|
||||
protected $autoloaded = [];
|
||||
|
||||
protected $prefixes = [];
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->autoloaded = require base_path("vendor/composer/autoload_psr4.php");
|
||||
}
|
||||
|
||||
public function all()
|
||||
{
|
||||
$components = collect(array_merge(
|
||||
$this->getStandardClasses(),
|
||||
$this->getStandardViews(),
|
||||
$this->getNamespaced(),
|
||||
$this->getAnonymousNamespaced(),
|
||||
$this->getAnonymous(),
|
||||
$this->getAliases(),
|
||||
$this->getVendorComponents(),
|
||||
))->groupBy('key')->map(fn($items) => [
|
||||
'isVendor' => $items->first()['isVendor'],
|
||||
'paths' => $items->pluck('path')->values(),
|
||||
'props' => $items->pluck('props')->values()->filter()->flatMap(fn($i) => $i),
|
||||
]);
|
||||
|
||||
return [
|
||||
'components' => $components,
|
||||
'prefixes' => $this->prefixes,
|
||||
];
|
||||
}
|
||||
|
||||
protected function getStandardViews()
|
||||
{
|
||||
$path = resource_path('views/components');
|
||||
|
||||
return $this->findFiles($path, 'blade.php');
|
||||
}
|
||||
|
||||
protected function findFiles($path, $extension, $keyCallback = null)
|
||||
{
|
||||
if (!is_dir($path)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$files = \Symfony\Component\Finder\Finder::create()
|
||||
->files()
|
||||
->name("*." . $extension)
|
||||
->in($path);
|
||||
$components = [];
|
||||
$pathRealPath = realpath($path);
|
||||
|
||||
foreach ($files as $file) {
|
||||
$realPath = $file->getRealPath();
|
||||
|
||||
$key = str($realPath)
|
||||
->replace($pathRealPath, '')
|
||||
->ltrim('/\\')
|
||||
->replace('.' . $extension, '')
|
||||
->replace(['/', '\\'], '.')
|
||||
->pipe(fn($str) => $this->handleIndexComponents($str));
|
||||
|
||||
$components[] = [
|
||||
"path" => LaravelVsCode::relativePath($realPath),
|
||||
"isVendor" => LaravelVsCode::isVendor($realPath),
|
||||
"key" => $keyCallback ? $keyCallback($key) : $key,
|
||||
];
|
||||
}
|
||||
|
||||
return $components;
|
||||
}
|
||||
|
||||
protected function getStandardClasses()
|
||||
{
|
||||
$path = app_path('View/Components');
|
||||
|
||||
$appNamespace = collect($this->autoloaded)
|
||||
->filter(fn($paths) => in_array(app_path(), $paths))
|
||||
->keys()
|
||||
->first() ?? '';
|
||||
|
||||
return collect($this->findFiles(
|
||||
$path,
|
||||
'php',
|
||||
fn($key) => $key->explode('.')
|
||||
->map(fn($p) => \Illuminate\Support\Str::kebab($p))
|
||||
->implode('.'),
|
||||
))->map(function ($item) use ($appNamespace) {
|
||||
$class = str($item['path'])
|
||||
->after('View/Components/')
|
||||
->replace('.php', '')
|
||||
->replace('/', '\\')
|
||||
->prepend($appNamespace . 'View\\Components\\')
|
||||
->toString();
|
||||
|
||||
if (!class_exists($class)) {
|
||||
return $item;
|
||||
}
|
||||
|
||||
$reflection = new \ReflectionClass($class);
|
||||
$parameters = collect($reflection->getConstructor()?->getParameters() ?? [])
|
||||
->filter(fn($p) => $p->isPromoted())
|
||||
->flatMap(fn($p) => [$p->getName() => $p->isOptional() ? $p->getDefaultValue() : null])
|
||||
->all();
|
||||
|
||||
$props = collect($reflection->getProperties())
|
||||
->filter(fn($p) => $p->isPublic() && $p->getDeclaringClass()->getName() === $class)
|
||||
->map(fn($p) => [
|
||||
'name' => \Illuminate\Support\Str::kebab($p->getName()),
|
||||
'type' => (string) ($p->getType() ?? 'mixed'),
|
||||
'default' => $p->getDefaultValue() ?? $parameters[$p->getName()] ?? null,
|
||||
]);
|
||||
|
||||
[$except, $props] = $props->partition(fn($p) => $p['name'] === 'except');
|
||||
|
||||
if ($except->isNotEmpty()) {
|
||||
$except = $except->first()['default'];
|
||||
$props = $props->reject(fn($p) => in_array($p['name'], $except));
|
||||
}
|
||||
|
||||
return [
|
||||
...$item,
|
||||
'props' => $props,
|
||||
];
|
||||
})->all();
|
||||
}
|
||||
|
||||
protected function getAliases()
|
||||
{
|
||||
$components = [];
|
||||
|
||||
foreach (\Illuminate\Support\Facades\Blade::getClassComponentAliases() as $key => $class) {
|
||||
if (class_exists($class)) {
|
||||
$reflection = new ReflectionClass($class);
|
||||
|
||||
$components[] = [
|
||||
"path" => LaravelVsCode::relativePath($reflection->getFileName()),
|
||||
"isVendor" => LaravelVsCode::isVendor($reflection->getFileName()),
|
||||
"key" => $key,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
return $components;
|
||||
}
|
||||
|
||||
protected function getAnonymousNamespaced()
|
||||
{
|
||||
$components = [];
|
||||
|
||||
foreach (\Illuminate\Support\Facades\Blade::getAnonymousComponentNamespaces() as $key => $dir) {
|
||||
$path = collect([$dir, resource_path('views/' . $dir)])->first(fn($p) => is_dir($p));
|
||||
|
||||
if (!$path) {
|
||||
continue;
|
||||
}
|
||||
|
||||
array_push(
|
||||
$components,
|
||||
...$this->findFiles(
|
||||
$path,
|
||||
'blade.php',
|
||||
fn($k) => $k->kebab()->prepend($key . "::"),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
return $components;
|
||||
}
|
||||
|
||||
protected function getAnonymous()
|
||||
{
|
||||
$components = [];
|
||||
|
||||
foreach (\Illuminate\Support\Facades\Blade::getAnonymousComponentPaths() as $item) {
|
||||
array_push(
|
||||
$components,
|
||||
...$this->findFiles(
|
||||
$item['path'],
|
||||
'blade.php',
|
||||
function (\Illuminate\Support\Stringable $key) use ($item) {
|
||||
$prefix = $item['prefix'] ? $item['prefix'] . '::' : '';
|
||||
$key = $key->kebab();
|
||||
$keys = [];
|
||||
|
||||
$keys[] = $key->prepend($prefix);
|
||||
|
||||
if ($item['prefix'] === 'flux') {
|
||||
$keys[] = $key->prepend('flux:');
|
||||
}
|
||||
|
||||
return $keys;
|
||||
},
|
||||
)
|
||||
);
|
||||
|
||||
if (!in_array($item['prefix'], $this->prefixes)) {
|
||||
$this->prefixes[] = $item['prefix'];
|
||||
}
|
||||
}
|
||||
|
||||
return $components;
|
||||
}
|
||||
|
||||
protected function getVendorComponents(): array
|
||||
{
|
||||
$components = [];
|
||||
|
||||
/** @var \Illuminate\View\Factory $view */
|
||||
$view = \Illuminate\Support\Facades\App::make('view');
|
||||
|
||||
/** @var \Illuminate\View\FileViewFinder $finder */
|
||||
$finder = $view->getFinder();
|
||||
|
||||
/** @var array<string, array<int, string>> $views */
|
||||
$views = $finder->getHints();
|
||||
|
||||
foreach ($views as $key => $paths) {
|
||||
foreach ($paths as $path) {
|
||||
$path .= '/components';
|
||||
|
||||
if (!is_dir($path)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
array_push(
|
||||
$components,
|
||||
...$this->findFiles(
|
||||
$path,
|
||||
'blade.php',
|
||||
fn (\Illuminate\Support\Stringable $k) => $k->kebab()->prepend($key.'::'),
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return $components;
|
||||
}
|
||||
|
||||
protected function handleIndexComponents($str)
|
||||
{
|
||||
if ($str->endsWith('.index')) {
|
||||
return $str->replaceLast('.index', '');
|
||||
}
|
||||
|
||||
if (!$str->contains('.')) {
|
||||
return $str;
|
||||
}
|
||||
|
||||
$parts = $str->explode('.');
|
||||
|
||||
if ($parts->slice(-2)->unique()->count() === 1) {
|
||||
$parts->pop();
|
||||
|
||||
return str($parts->implode('.'));
|
||||
}
|
||||
|
||||
return $str;
|
||||
}
|
||||
|
||||
protected function getNamespaced()
|
||||
{
|
||||
$namespaced = \Illuminate\Support\Facades\Blade::getClassComponentNamespaces();
|
||||
$components = [];
|
||||
|
||||
foreach ($namespaced as $key => $classNamespace) {
|
||||
$path = $this->getNamespacePath($classNamespace);
|
||||
|
||||
if (!$path) {
|
||||
continue;
|
||||
}
|
||||
|
||||
array_push(
|
||||
$components,
|
||||
...$this->findFiles(
|
||||
$path,
|
||||
'php',
|
||||
fn($k) => $k->kebab()->prepend($key . "::"),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
return $components;
|
||||
}
|
||||
|
||||
protected function getNamespacePath($classNamespace)
|
||||
{
|
||||
foreach ($this->autoloaded as $ns => $paths) {
|
||||
if (!str_starts_with($classNamespace, $ns)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach ($paths as $p) {
|
||||
$dir = str($classNamespace)
|
||||
->replace($ns, '')
|
||||
->replace('\\', '/')
|
||||
->prepend($p . DIRECTORY_SEPARATOR)
|
||||
->toString();
|
||||
|
||||
if (is_dir($dir)) {
|
||||
return $dir;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
echo json_encode($components->all());
|
||||
|
||||
echo LaravelVsCode::outputMarker('END_OUTPUT');
|
||||
|
||||
exit(0);
|
||||
Reference in new issue
Block a user