117 lines
3 KiB
Go
117 lines
3 KiB
Go
package sdk
|
|
|
|
import (
|
|
"context"
|
|
|
|
"dappco.re/go/core"
|
|
"dappco.re/go/core/build/internal/ax"
|
|
coreerr "dappco.re/go/core/log"
|
|
)
|
|
|
|
// commonSpecPaths are checked in order when no spec is configured.
|
|
var commonSpecPaths = []string{
|
|
"api/openapi.yaml",
|
|
"api/openapi.yml",
|
|
"api/openapi.json",
|
|
"openapi.yaml",
|
|
"openapi.yml",
|
|
"openapi.json",
|
|
"docs/api.yaml",
|
|
"docs/api.yml",
|
|
"docs/api.json",
|
|
"swagger.yaml",
|
|
"swagger.yml",
|
|
"swagger.json",
|
|
}
|
|
|
|
// DetectSpec finds the OpenAPI spec file.
|
|
// Priority: config path -> common paths -> Laravel Scramble.
|
|
//
|
|
// path, err := s.DetectSpec() // → "api/openapi.yaml", nil
|
|
func (s *SDK) DetectSpec() (string, error) {
|
|
// 1. Check configured path
|
|
if s.config.Spec != "" {
|
|
specPath := ax.Join(s.projectDir, s.config.Spec)
|
|
if ax.IsFile(specPath) {
|
|
return specPath, nil
|
|
}
|
|
return "", coreerr.E("sdk.DetectSpec", "configured spec not found: "+s.config.Spec, nil)
|
|
}
|
|
|
|
// 2. Check common paths
|
|
for _, p := range commonSpecPaths {
|
|
specPath := ax.Join(s.projectDir, p)
|
|
if ax.IsFile(specPath) {
|
|
return specPath, nil
|
|
}
|
|
}
|
|
|
|
// 3. Try Laravel Scramble detection
|
|
composerPath := ax.Join(s.projectDir, "composer.json")
|
|
if ax.IsFile(composerPath) {
|
|
data, err := ax.ReadFile(composerPath)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
if containsScramble(string(data)) {
|
|
specPath, err := s.detectScramble()
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
return specPath, nil
|
|
}
|
|
}
|
|
|
|
return "", coreerr.E("sdk.DetectSpec", "no OpenAPI spec found (checked config, common paths, Scramble)", nil)
|
|
}
|
|
|
|
// detectScramble checks for Laravel Scramble and exports the spec.
|
|
func (s *SDK) detectScramble() (string, error) {
|
|
composerPath := ax.Join(s.projectDir, "composer.json")
|
|
if !ax.IsFile(composerPath) {
|
|
return "", coreerr.E("sdk.detectScramble", "no composer.json", nil)
|
|
}
|
|
|
|
// Check for scramble in composer.json
|
|
data, err := ax.ReadFile(composerPath)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
// Simple check for scramble package
|
|
if !containsScramble(string(data)) {
|
|
return "", coreerr.E("sdk.detectScramble", "scramble not found in composer.json", nil)
|
|
}
|
|
|
|
scrambleSpecPath := ax.Join(s.projectDir, "api.json")
|
|
|
|
phpCommand, err := resolvePHPCli()
|
|
if err != nil {
|
|
return "", coreerr.E("sdk.detectScramble", "php CLI not found", err)
|
|
}
|
|
|
|
if err := ax.ExecDir(context.Background(), s.projectDir, phpCommand, "artisan", "scramble:export", "--path=api.json"); err != nil {
|
|
return "", coreerr.E("sdk.detectScramble", "scramble export failed", err)
|
|
}
|
|
|
|
if !ax.IsFile(scrambleSpecPath) {
|
|
return "", coreerr.E("sdk.detectScramble", "scramble export did not create api.json", nil)
|
|
}
|
|
|
|
return scrambleSpecPath, nil
|
|
}
|
|
|
|
// containsScramble checks if composer.json includes scramble.
|
|
func containsScramble(content string) bool {
|
|
return core.Contains(content, "dedoc/scramble") ||
|
|
core.Contains(content, "\"scramble\"")
|
|
}
|
|
|
|
func resolvePHPCli() (string, error) {
|
|
return ax.ResolveCommand("php",
|
|
"/usr/bin/php",
|
|
"/usr/local/bin/php",
|
|
"/opt/homebrew/bin/php",
|
|
)
|
|
}
|