@@ -31,6 +31,15 @@ class ApiDocBuilder
3131 /** @var array<string, array<string, mixed>> */
3232 private array $ securitySchemes = [];
3333
34+ /** @var array<string, array<string, mixed>> */
35+ private array $ links = [];
36+
37+ /** @var array<string, array<string, mixed>> */
38+ private array $ callbacks = [];
39+
40+ /** @var array<string, array<string, mixed>> */
41+ private array $ pathItems = [];
42+
3443 /**
3544 * Start building a new route/path definition.
3645 */
@@ -77,6 +86,36 @@ public function addTag(string $name): TagBuilder
7786 return new TagBuilder ($ this , $ name );
7887 }
7988
89+ /**
90+ * Start building a new link component.
91+ *
92+ * @param string $name The link name
93+ */
94+ public function addLink (string $ name ): LinkBuilder
95+ {
96+ return new LinkBuilder ($ this , $ name );
97+ }
98+
99+ /**
100+ * Start building a new callback component.
101+ *
102+ * @param string $name The callback name
103+ */
104+ public function addCallback (string $ name ): CallbackBuilder
105+ {
106+ return new CallbackBuilder ($ this , $ name );
107+ }
108+
109+ /**
110+ * Start building a new path item component.
111+ *
112+ * @param string $name The path item name
113+ */
114+ public function addPathItem (string $ name ): PathItemBuilder
115+ {
116+ return new PathItemBuilder ($ this , $ name );
117+ }
118+
80119 /**
81120 * Register a custom reference name for a schema.
82121 * This allows you to use short aliases instead of full schema names.
@@ -232,6 +271,45 @@ public function registerSecurityScheme(string $name, array $definition): void
232271 $ this ->securitySchemes [$ name ] = $ definition ;
233272 }
234273
274+ /**
275+ * Internal method to register a link definition.
276+ *
277+ * @param string $name The link name
278+ * @param array<string, mixed> $definition The link definition
279+ *
280+ * @internal
281+ */
282+ public function registerLink (string $ name , array $ definition ): void
283+ {
284+ $ this ->links [$ name ] = $ definition ;
285+ }
286+
287+ /**
288+ * Internal method to register a callback definition.
289+ *
290+ * @param string $name The callback name
291+ * @param array<string, mixed> $definition The callback definition
292+ *
293+ * @internal
294+ */
295+ public function registerCallback (string $ name , array $ definition ): void
296+ {
297+ $ this ->callbacks [$ name ] = $ definition ;
298+ }
299+
300+ /**
301+ * Internal method to register a path item definition.
302+ *
303+ * @param string $name The path item name
304+ * @param array<string, mixed> $definition The path item definition
305+ *
306+ * @internal
307+ */
308+ public function registerPathItem (string $ name , array $ definition ): void
309+ {
310+ $ this ->pathItems [$ name ] = $ definition ;
311+ }
312+
235313 /**
236314 * Get all paths (routes) as an array.
237315 *
@@ -292,14 +370,29 @@ public function build(): array
292370 $ spec ['paths ' ] = $ this ->paths ;
293371 }
294372
295- // Add components (schemas and securitySchemes)
296- if (!empty ($ this ->schemas ) || !empty ($ this ->securitySchemes )) {
373+ // Add components (schemas, securitySchemes, links, callbacks, pathItems)
374+ $ hasComponents = !empty ($ this ->schemas )
375+ || !empty ($ this ->securitySchemes )
376+ || !empty ($ this ->links )
377+ || !empty ($ this ->callbacks )
378+ || !empty ($ this ->pathItems );
379+
380+ if ($ hasComponents ) {
297381 if (!empty ($ this ->schemas )) {
298382 $ spec ['components ' ]['schemas ' ] = $ this ->schemas ;
299383 }
300384 if (!empty ($ this ->securitySchemes )) {
301385 $ spec ['components ' ]['securitySchemes ' ] = $ this ->securitySchemes ;
302386 }
387+ if (!empty ($ this ->links )) {
388+ $ spec ['components ' ]['links ' ] = $ this ->links ;
389+ }
390+ if (!empty ($ this ->callbacks )) {
391+ $ spec ['components ' ]['callbacks ' ] = $ this ->callbacks ;
392+ }
393+ if (!empty ($ this ->pathItems )) {
394+ $ spec ['components ' ]['pathItems ' ] = $ this ->pathItems ;
395+ }
303396 }
304397
305398 return $ spec ;
0 commit comments