Laravel AT Protocol Client (alpha & unstable)
1<?php
2
3namespace SocialDept\AtpClient\Console;
4
5use Illuminate\Console\Command;
6use Illuminate\Filesystem\Filesystem;
7use Illuminate\Support\Str;
8
9class MakeAtpRequestCommand extends Command
10{
11 protected $signature = 'make:atp-request
12 {name : The name of the request client class}
13 {--domain=bsky : The domain to extend (bsky, atproto, chat, ozone)}
14 {--force : Overwrite existing file}';
15
16 protected $description = 'Create a new ATP request client extension for an existing domain';
17
18 protected array $validDomains = ['bsky', 'atproto', 'chat', 'ozone'];
19
20 public function __construct(protected Filesystem $files)
21 {
22 parent::__construct();
23 }
24
25 public function handle(): int
26 {
27 $name = $this->argument('name');
28 $domain = $this->option('domain');
29
30 if (! in_array($domain, $this->validDomains)) {
31 $this->components->error("Invalid domain [{$domain}]. Valid domains: ".implode(', ', $this->validDomains));
32
33 return self::FAILURE;
34 }
35
36 if (! Str::endsWith($name, 'Client')) {
37 $name .= 'Client';
38 }
39
40 $path = $this->getPath($name);
41
42 if ($this->files->exists($path) && ! $this->option('force')) {
43 $this->components->error("Request client [{$name}] already exists!");
44
45 return self::FAILURE;
46 }
47
48 $this->makeDirectory($path);
49
50 $content = $this->populateStub($this->getStub(), $name);
51
52 $this->files->put($path, $content);
53
54 $this->components->info("Request client [{$path}] created successfully.");
55
56 $this->outputRegistrationHint($name, $domain);
57
58 return self::SUCCESS;
59 }
60
61 protected function getPath(string $name): string
62 {
63 $basePath = config('client.generators.request_path', 'app/Services/Clients/Requests');
64
65 return base_path($basePath.'/'.$name.'.php');
66 }
67
68 protected function makeDirectory(string $path): void
69 {
70 if (! $this->files->isDirectory(dirname($path))) {
71 $this->files->makeDirectory(dirname($path), 0755, true);
72 }
73 }
74
75 protected function getNamespace(): string
76 {
77 $basePath = config('client.generators.request_path', 'app/Services/Clients/Requests');
78
79 return Str::of($basePath)
80 ->replace('/', '\\')
81 ->ucfirst()
82 ->replace('App', 'App')
83 ->toString();
84 }
85
86 protected function populateStub(string $stub, string $name): string
87 {
88 return str_replace(
89 ['{{ namespace }}', '{{ class }}'],
90 [$this->getNamespace(), $name],
91 $stub
92 );
93 }
94
95 protected function outputRegistrationHint(string $name, string $domain): void
96 {
97 $this->newLine();
98 $this->components->info('Register the extension in your AppServiceProvider:');
99 $this->newLine();
100
101 $namespace = $this->getNamespace();
102 $extensionName = Str::of($name)->before('Client')->camel()->toString();
103
104 $this->line("use {$namespace}\\{$name};");
105 $this->line("use SocialDept\\AtpClient\\AtpClient;");
106 $this->newLine();
107 $this->line("// In boot() method:");
108 $this->line("AtpClient::extendDomain('{$domain}', '{$extensionName}', fn(\$domain) => new {$name}(\$domain));");
109 }
110
111 protected function getStub(): string
112 {
113 return <<<'STUB'
114<?php
115
116namespace {{ namespace }};
117
118use SocialDept\AtpClient\Client\Requests\Request;
119
120class {{ class }} extends Request
121{
122 //
123}
124STUB;
125 }
126}