Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions anysdk/address_space.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package anysdk

type AddressSpaceExpansionConfig interface {
IsLegacy() bool
IsAllowNilResponse() bool
}

type AddressSpace interface {
GetGlobalSelectSchemas() map[string]Schema
DereferenceAddress(address string) (any, bool)
WriteToAddress(address string, val any) error
ReadFromAddress(address string) (any, bool)
ResolveSignature(map[string]any) (bool, map[string]any)
Invoke(...any) error
ToMap(AddressSpaceExpansionConfig) (map[string]any, error)
ToRelation(AddressSpaceExpansionConfig) (Relation, error)
}
12 changes: 10 additions & 2 deletions anysdk/addressable.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,13 @@ func (ns *namedSchema) GetName() string {
return ns.name
}

func (ns *namedSchema) GetAlias() string {
if ns.s != nil {
return ns.s.GetAlias()
}
return ""
}

func (ns *namedSchema) GetSchema() (Schema, bool) {
return ns.s, true
}
Expand Down Expand Up @@ -47,7 +54,7 @@ func newAddressableRequestBodyProperty(name string, s Schema, isRequired bool) A
return &namedSchema{
s: s,
name: name,
location: "requestBody",
location: LocationRequestBody,
isRequired: isRequired,
}
}
Expand All @@ -56,7 +63,7 @@ func newAddressableServerVariable(name string, s Schema, isRequired bool) Addres
return &namedSchema{
s: s,
name: name,
location: "server",
location: LocationServer,
isRequired: isRequired,
}
}
Expand All @@ -65,6 +72,7 @@ type Addressable interface {
ConditionIsValid(lhs string, rhs interface{}) bool
GetLocation() string
GetName() string
GetAlias() string
GetSchema() (Schema, bool)
GetType() string
IsRequired() bool
Expand Down
23 changes: 0 additions & 23 deletions anysdk/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -347,29 +347,6 @@ func inferMaxResultsElement(OperationStore) internaldto.HTTPElement {
)
}

func HTTPApiCallFromRequest(
cc client.AnySdkClientConfigurator,
runtimeCtx dto.RuntimeCtx,
authCtx *dto.AuthCtx,
authTypeRequested string,
enforceRevokeFirst bool,
outErrFile io.Writer,
prov Provider,
method OperationStore,
request *http.Request,
) (*http.Response, error) {
return httpApiCallFromRequest(
cc,
runtimeCtx,
authCtx,
authTypeRequested,
enforceRevokeFirst,
outErrFile,
method,
request,
)
}

func GetMonitorRequest(urlStr string) (client.AnySdkArgList, error) {
urlObj, err := url.Parse(urlStr)
if err != nil {
Expand Down
9 changes: 9 additions & 0 deletions anysdk/concerted_action.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ type MethodAnalysisOutput interface {
GetItemSchema() (Schema, bool)
GetResponseSchema() (Schema, bool)
IsNilResponseAllowed() bool
IsAwait() bool
}

type analysisOutput struct {
Expand All @@ -79,6 +80,7 @@ type analysisOutput struct {
responseSchema Schema
itemSchema Schema
isNilResponseAllowed bool
isAwait bool
}

func (ao *analysisOutput) GetMethod() OperationStore {
Expand All @@ -93,6 +95,10 @@ func (ao *analysisOutput) GetSelectItemsKey() string {
return ao.selectItemsKey
}

func (ao *analysisOutput) IsAwait() bool {
return ao.isAwait
}

func (ao *analysisOutput) GetItemSchema() (Schema, bool) {
return ao.itemSchema, ao.itemSchema != nil
}
Expand Down Expand Up @@ -149,6 +155,7 @@ func newMethodAnalysisOutput(
responseSchema Schema,
itemSchema Schema,
isNilResponseAllowed bool,
isAwait bool,
) MethodAnalysisOutput {
return &analysisOutput{
method: method,
Expand All @@ -159,6 +166,7 @@ func newMethodAnalysisOutput(
responseSchema: responseSchema,
itemSchema: itemSchema,
isNilResponseAllowed: isNilResponseAllowed,
isAwait: isAwait,
}
}

Expand Down Expand Up @@ -239,5 +247,6 @@ func (ma *standardMethodAnalyzer) AnalyzeUnaryAction(
schema,
itemSchema,
isNilResponseAllowed,
isAwait,
), nil
}
10 changes: 10 additions & 0 deletions anysdk/const.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,23 @@ const (
SQLVerb string = "SQLVerb"
)

const (
LocationRequestBody string = "requestBody"
LocationPath string = "path"
LocationQuery string = "query"
LocationHeader string = "header"
LocationCookie string = "cookie"
LocationServer string = "server"
)

const (
ExtensionKeyAlwaysRequired string = "x-alwaysRequired"
ExtensionKeyGraphQL string = "x-stackQL-graphQL"
ExtensionKeyConfig string = "x-stackQL-config"
ExtensionKeyProvider string = "x-stackql-provider"
ExtensionKeyResources string = "x-stackQL-resources"
ExtensionKeyStringOnly string = "x-stackQL-stringOnly"
ExtensionKeyAlias string = "x-stackQL-alias"
)

const (
Expand Down
13 changes: 7 additions & 6 deletions anysdk/expectedRequest.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,13 @@ type ExpectedRequest interface {
type standardExpectedRequest struct {
BodyMediaType string `json:"mediaType,omitempty" yaml:"mediaType,omitempty"`
Schema Schema
Default string `json:"default,omitempty" yaml:"default,omitempty"`
Base string `json:"base,omitempty" yaml:"base,omitempty"`
Required []string `json:"required,omitempty" yaml:"required,omitempty"`
XMLDeclaration string `json:"xmlDeclaration,omitempty" yaml:"xmlDeclaration,omitempty"`
XMLTransform string `json:"xmlTransform,omitempty" yaml:"xmlTransform,omitempty"`
XMLRootAnnotation string `json:"xmlRootAnnotation,omitempty" yaml:"xmlRootAnnotation,omitempty"`
Default string `json:"default,omitempty" yaml:"default,omitempty"`
Base string `json:"base,omitempty" yaml:"base,omitempty"`
ProjectionMap map[string]string `json:"projection_map,omitempty" yaml:"projection_map,omitempty"`
Required []string `json:"required,omitempty" yaml:"required,omitempty"`
XMLDeclaration string `json:"xmlDeclaration,omitempty" yaml:"xmlDeclaration,omitempty"`
XMLTransform string `json:"xmlTransform,omitempty" yaml:"xmlTransform,omitempty"`
XMLRootAnnotation string `json:"xmlRootAnnotation,omitempty" yaml:"xmlRootAnnotation,omitempty"`
}

func (er *standardExpectedRequest) setBodyMediaType(s string) {
Expand Down
28 changes: 23 additions & 5 deletions anysdk/expectedResponse.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ type ExpectedResponse interface {
GetOpenAPIDocKey() string
GetObjectKey() string
GetSchema() Schema
GetProjectionMap() map[string]string
GetProjection(string) (string, bool)
getOverrideSchema() (*LocalSchemaRef, bool)
getAsyncOverrideSchema() (*LocalSchemaRef, bool)
setOverrideSchemaValue(Schema)
Expand All @@ -21,17 +23,33 @@ type ExpectedResponse interface {
}

type standardExpectedResponse struct {
OverrideBodyMediaType string `json:"overrideMediaType,omitempty" yaml:"overrideMediaType,omitempty"`
AsyncOverrideBodyMediaType string `json:"asyncOverrideMediaType,omitempty" yaml:"asyncOverrideMediaType,omitempty"`
BodyMediaType string `json:"mediaType,omitempty" yaml:"mediaType,omitempty"`
OpenAPIDocKey string `json:"openAPIDocKey,omitempty" yaml:"openAPIDocKey,omitempty"`
ObjectKey string `json:"objectKey,omitempty" yaml:"objectKey,omitempty"`
OverrideBodyMediaType string `json:"overrideMediaType,omitempty" yaml:"overrideMediaType,omitempty"`
AsyncOverrideBodyMediaType string `json:"asyncOverrideMediaType,omitempty" yaml:"asyncOverrideMediaType,omitempty"`
BodyMediaType string `json:"mediaType,omitempty" yaml:"mediaType,omitempty"`
OpenAPIDocKey string `json:"openAPIDocKey,omitempty" yaml:"openAPIDocKey,omitempty"`
ObjectKey string `json:"objectKey,omitempty" yaml:"objectKey,omitempty"`
ProjectionMap map[string]string `json:"projection_map,omitempty" yaml:"projection_map,omitempty"`
Schema Schema
OverrideSchema *LocalSchemaRef `json:"schema_override,omitempty" yaml:"schema_override,omitempty"`
AsyncOverrideSchema *LocalSchemaRef `json:"async_schema_override,omitempty" yaml:"async_schema_override,omitempty"`
Transform *standardTransform `json:"transform,omitempty" yaml:"transform,omitempty"`
}

func (er *standardExpectedResponse) GetProjectionMap() map[string]string {
if er.ProjectionMap == nil {
return make(map[string]string)
}
return er.ProjectionMap
}

func (er *standardExpectedResponse) GetProjection(key string) (string, bool) {
if er.ProjectionMap == nil {
return "", false
}
v, ok := er.ProjectionMap[key]
return v, ok
}

func (er *standardExpectedResponse) setBodyMediaType(s string) {
er.BodyMediaType = s
}
Expand Down
63 changes: 45 additions & 18 deletions anysdk/loader.go
Original file line number Diff line number Diff line change
Expand Up @@ -317,7 +317,7 @@ func (l *standardLoader) mergeResources(svc OpenAPIService, rscMap map[string]Re
if rsc.GetServiceDocPath() != nil {
sr = rsc.GetServiceDocPath()
}
err := l.mergeResource(svc, rsc, sr)
err := l.mergeResource(k, svc, rsc, sr)
if err != nil {
return err
}
Expand All @@ -330,7 +330,7 @@ func (l *standardLoader) mergeResourcesScoped(svc OpenAPIService, svcUrl string,
scopedMap := make(map[string]Resource)
for k, rsc := range rr.GetResources() {
if rr.ObtainServiceDocUrl(k) == svcUrl {
err := l.mergeResource(svc, rsc, &ServiceRef{Ref: svcUrl})
err := l.mergeResource(k, svc, rsc, &ServiceRef{Ref: svcUrl})
if err != nil {
return err
}
Expand All @@ -349,14 +349,28 @@ func (l *standardLoader) mergeResourcesScoped(svc OpenAPIService, svcUrl string,
return nil
}

func (l *standardLoader) mergeResource(svc OpenAPIService,
func (l *standardLoader) mergeResource(
rscKey string,
svc OpenAPIService,
rsc Resource,
sr *ServiceRef,
) error {
rsc.setService(svc) // must happen before resolving inverses
existingMethods := make(Methods)
existingResource, existingResourceErr := svc.GetResource(rscKey)
if existingResourceErr == nil && existingResource != nil {
existingMethods = existingResource.GetMethods()
}
for k, vOp := range rsc.GetMethods() {
v := vOp
v.setMethodKey(k)
existingMethod, existingMethodExists := existingMethods[k]
if existingMethodExists {
v = existingMethod
v.setMethodKey(k)
v.setResource(rsc)
continue
}
// TODO: replicate this for the damned inverse
err := l.resolveOperationRef(svc, rsc, &v, v.GetPathRef(), sr)
if err != nil {
Expand Down Expand Up @@ -579,20 +593,23 @@ func LoadProviderDocFromFile(fileName string) (Provider, error) {
return loadProviderDocFromBytes(bytes)
}

func GetProviderDocBytes(prov string) ([]byte, error) {
fn, err := getProviderDoc(prov)
func GetProviderDocBytes(prov string, fileRoot string) ([]byte, error) {
fn, err := getProviderDoc(prov, fileRoot)
if err != nil {
return nil, err
}
return os.ReadFile(fn)
}

func getServiceDoc(url string) (io.ReadCloser, error) {
return os.Open(path.Join(OpenapiFileRoot, url))
func getServiceDoc(url string, fileRoot string) (io.ReadCloser, error) {
if fileRoot == "" {
fileRoot = OpenapiFileRoot
}
return os.Open(path.Join(fileRoot, url))
}

func getServiceDocBytes(url string) ([]byte, error) {
f, err := getServiceDoc(url)
func getServiceDocBytes(url string, fileRoot string) ([]byte, error) {
f, err := getServiceDoc(url, fileRoot)
if err != nil {
return nil, err
}
Expand All @@ -606,16 +623,16 @@ func ReadService(b []byte) (Service, error) {
return svc, err
}

func GetResourcesRegisterDocBytes(url string) ([]byte, error) {
return getServiceDocBytes(url)
func GetResourcesRegisterDocBytes(url string, fileRoot string) ([]byte, error) {
return getServiceDocBytes(url, fileRoot)
}

func GetServiceDocBytes(url string) ([]byte, error) {
return getServiceDocBytes(url)
func GetServiceDocBytes(url string, fileRoot string) ([]byte, error) {
return getServiceDocBytes(url, fileRoot)
}

func LoadProviderByName(prov, version string) (Provider, error) {
b, err := GetProviderDocBytes(path.Join(prov, version))
func LoadProviderByName(prov, version string, fileRoot string) (Provider, error) {
b, err := GetProviderDocBytes(path.Join(prov, version), fileRoot)
if err != nil {
return nil, err
}
Expand All @@ -641,12 +658,15 @@ func findLatestDoc(serviceDir string) (string, error) {
return path.Join(serviceDir, fileNames[fileCount-1]), nil
}

func getProviderDoc(provider string) (string, error) {
func getProviderDoc(provider string, fileRoot string) (string, error) {
if fileRoot == "" {
fileRoot = OpenapiFileRoot
}
switch provider {
case "google":
return findLatestDoc(path.Join(OpenapiFileRoot, "googleapis.com"))
return findLatestDoc(path.Join(fileRoot, "googleapis.com"))
}
return findLatestDoc(path.Join(OpenapiFileRoot, provider))
return findLatestDoc(path.Join(fileRoot, provider))
}

func loadOpenapiServiceDocFromBytes(ps ProviderService, bytes []byte) (OpenAPIService, error) {
Expand Down Expand Up @@ -763,6 +783,13 @@ func (loader *standardLoader) resolveOperationRef(doc OpenAPIService, rsc Resour
}

component.setOperationRef(&OperationRef{Value: op, Ref: component.GetOperationRef().Ref})
response, responseExists := component.GetResponse()
if responseExists {
err = loader.resolveExpectedResponse(doc, component.GetOperationRef().Value, response)
if err != nil {
return err
}
}
component.setPathItem(pi)
err = loader.extractAndMergeQueryTransposeOpLevel(component)
if err != nil {
Expand Down
Loading
Loading