-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Loading status checks…
feat: add oas-overlay command
This command implements v1.0.0 of the OpenAPI Overlay specification It allows you to apply an Overlay to an existing OAS.
Showing
22 changed files
with
6,237 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
// Copyright 2024 Google LLC | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
|
||
package oas_overlay | ||
|
||
import ( | ||
"github.com/apigee/apigee-go-gen/pkg/flags" | ||
"github.com/apigee/apigee-go-gen/pkg/utils" | ||
"github.com/spf13/cobra" | ||
) | ||
|
||
var spec flags.String | ||
var overlay flags.String | ||
var output flags.String | ||
|
||
var Cmd = &cobra.Command{ | ||
Use: "oas-overlay", | ||
Short: "Transforms Open API spec by applying overlay file", | ||
RunE: func(cmd *cobra.Command, args []string) error { | ||
return utils.OASOverlay(string(overlay), string(spec), string(output)) | ||
}, | ||
} | ||
|
||
func init() { | ||
|
||
Cmd.Flags().SortFlags = false | ||
Cmd.Flags().VarP(&spec, "spec", "s", "path to OpenAPI spec file (optional)") | ||
Cmd.Flags().VarP(&overlay, "overlay", "", "path to overlay file") | ||
Cmd.Flags().VarP(&output, "output", "o", "path to output file, or omit to use stdout") | ||
|
||
_ = Cmd.MarkFlagRequired("overlay") | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
# OAS Overlay | ||
<!-- | ||
Copyright 2024 Google LLC | ||
Licensed under the Apache License, Version 2.0 (the "License"); | ||
you may not use this file except in compliance with the License. | ||
You may obtain a copy of the License at | ||
http://www.apache.org/licenses/LICENSE-2.0 | ||
Unless required by applicable law or agreed to in writing, software | ||
distributed under the License is distributed on an "AS IS" BASIS, | ||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
See the License for the specific language governing permissions and | ||
limitations under the License. | ||
--> | ||
|
||
This command applies an OpenAPI Overlay to an OpenAPI spec. | ||
|
||
## Usage | ||
|
||
The `oas-overlay` command takes the following parameters: | ||
|
||
* `--overlay` is the path to the OpenAPI Overlay (either as JSON or YAML) | ||
|
||
* `--spec` (*optional*) is the path to the OpenAPI Spec to transform (either as JSON or YAML) | ||
|
||
> The `--spec` parameter is optional. If omitted, the OAS path is read form the `extends` property of the overlay. | ||
> In this case, the path is relative to the location of the overlay file itself. | ||
* `--output` is the document to be created (either as JSON or YAML) | ||
|
||
> Full path is created if it does not exist (like `mkdir -p`) | ||
|
||
> You may omit the `--output` flags to write to stdout | ||
|
||
|
||
### Examples | ||
|
||
Below are a few examples for using the `oas-overlay` command. | ||
|
||
#### Write to file | ||
Writing the output to a new file | ||
```shell | ||
apigee-go-gen transform oas-overlay \ | ||
--spec ./examples/specs/oas3/petstore.yaml \ | ||
--overlay ./examples/overlays/petstore.yaml \ | ||
--output ./out/specs/oas3/petstore-overlaid.yaml | ||
``` | ||
|
||
#### Write To stdout | ||
Writing the output to stdout | ||
```shell | ||
apigee-go-gen transform oas-overlay \ | ||
--spec ./examples/specs/oas3/petstore.yaml \ | ||
--overlay ./examples/overlays/petstore.yaml | ||
``` | ||
|
||
#### Using the `extends` property | ||
Instead of passing `--spec`, use the value of the `extends` property in the overlay | ||
```shell | ||
apigee-go-gen transform oas-overlay \ | ||
--overlay ./examples/overlays/petstore.yaml | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
overlay: 1.0.0 | ||
info: | ||
title: Targeted Overlay | ||
version: 1.0.0 | ||
extends: ../specs/oas3/petstore.yaml | ||
actions: | ||
- target: $.info.contact | ||
remove: true | ||
- target: $.info | ||
update: | ||
description: This is a new description | ||
- target: $.tags[?(@.name=='pet')] | ||
update: | ||
externalDocs: | ||
url: https://example.com/pet | ||
- target: $.paths['/pet/{petId}/uploadImage'].post | ||
update: | ||
description: This is the new description for uploadImage operation | ||
- target: $.paths['/pet/{petId}'] | ||
update: | ||
get: | ||
description: This is an updated description of a child object | ||
x-safe: false |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,397 @@ | ||
// Copyright 2024 Google LLC | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
|
||
package utils | ||
|
||
import ( | ||
"github.com/go-errors/errors" | ||
libopenapijson "github.com/pb33f/libopenapi/json" | ||
"github.com/vmware-labs/yaml-jsonpath/pkg/yamlpath" | ||
"gopkg.in/yaml.v3" | ||
"path" | ||
"path/filepath" | ||
"slices" | ||
) | ||
|
||
func OASOverlay(overlayFile string, specFile string, outputFile string) error { | ||
overlayText, err := ReadInputTextFile(overlayFile) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
var overlayNode *yaml.Node | ||
overlayNode = &yaml.Node{} | ||
err = yaml.Unmarshal(overlayText, overlayNode) | ||
if err != nil { | ||
return errors.New(err) | ||
} | ||
|
||
extendsField, err := getExtends(overlayNode, overlayFile) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
//if extends field is set, and there is no spec file specified, use the extends field | ||
if extendsField != nil && specFile == "" { | ||
if path.IsAbs(*extendsField) { | ||
specFile = *extendsField | ||
} else { | ||
//when using extends, if path is relative, then it's relative to the overlay itself | ||
dir := path.Dir(overlayFile) | ||
specFile = path.Join(dir, *extendsField) | ||
} | ||
} | ||
|
||
if specFile == "" { | ||
return errors.Errorf("neither --spec parameter nor Overlay 'extends' field was specified") | ||
} | ||
|
||
specText, err := ReadInputTextFile(specFile) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
var specNode *yaml.Node | ||
specNode = &yaml.Node{} | ||
err = yaml.Unmarshal(specText, specNode) | ||
if err != nil { | ||
return errors.New(err) | ||
} | ||
|
||
//verify we are actually working with OAS3 | ||
if slices.IndexFunc(specNode.Content[0].Content, func(n *yaml.Node) bool { | ||
return n.Value == "openapi" | ||
}) < 0 { | ||
return errors.Errorf("%s is not an OpenAPI 3.X spec file", specFile) | ||
} | ||
|
||
resultNode, err := ApplyOASOverlay(overlayNode, specNode, overlayFile, specFile) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
ext := filepath.Ext(outputFile) | ||
if ext == "" { | ||
ext = filepath.Ext(specFile) | ||
} | ||
|
||
//depending on the file extension write the outputFile as either JSON or YAML | ||
var outputText []byte | ||
if ext == ".json" { | ||
outputText, err = libopenapijson.YAMLNodeToJSON(resultNode, " ") | ||
if err != nil { | ||
return errors.New(err) | ||
} | ||
} else { | ||
outputText, err = YAML2Text(UnFlowYAMLNode(resultNode), 2) | ||
if err != nil { | ||
return err | ||
} | ||
} | ||
|
||
return WriteOutputText(outputFile, outputText) | ||
} | ||
|
||
func ApplyOASOverlay(overlayNode *yaml.Node, specNode *yaml.Node, overlayFile string, specFile string) (*yaml.Node, error) { | ||
actions, err := getActions(overlayNode, overlayFile) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
var newSpec *yaml.Node = specNode | ||
for _, action := range actions { | ||
newSpec, err = ApplyOASOverlayAction(action, newSpec, overlayFile, specFile) | ||
if err != nil { | ||
return nil, err | ||
} | ||
} | ||
|
||
return specNode, nil | ||
} | ||
|
||
func ApplyOASOverlayAction(action *yaml.Node, specNode *yaml.Node, overlayFile string, specFile string) (*yaml.Node, error) { | ||
|
||
targetNode, err := getActionTarget(action, overlayFile) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
updateNode, err := getActionUpdate(action, overlayFile) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
remove, err := getActionRemove(action, overlayFile) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
if targetNode == nil { | ||
return nil, errors.Errorf("'target' field is required for action") | ||
} | ||
|
||
if remove == nil && updateNode == nil { | ||
return nil, errors.Errorf("action does not contain neither 'remove' nor 'update' field at %s:%d", overlayFile, action.Line) | ||
} else if remove != nil && *remove == true { | ||
//handle remove action | ||
specNode, err = removeYAMLNode(specNode, targetNode, overlayFile, specFile) | ||
if err != nil { | ||
return nil, err | ||
} | ||
} else if updateNode != nil { | ||
//handle updateNode action | ||
specNode, err = updateYAMLNode(specNode, targetNode, updateNode, overlayFile, specFile) | ||
if err != nil { | ||
return nil, err | ||
} | ||
} else { | ||
//no-op action | ||
return specNode, nil | ||
} | ||
|
||
return specNode, nil | ||
} | ||
|
||
func getActionTarget(actionNode *yaml.Node, overlayFile string) (*yaml.Node, error) { | ||
targetPath, err := yamlpath.NewPath("$.target") | ||
if err != nil { | ||
return nil, errors.New(err) | ||
} | ||
|
||
results, err := targetPath.Find(actionNode) | ||
if err != nil { | ||
return nil, errors.New(err) | ||
} | ||
|
||
if len(results) == 0 { | ||
return nil, nil | ||
} | ||
|
||
targetNode := results[0] | ||
|
||
if targetNode.Kind != yaml.ScalarNode { | ||
return nil, errors.Errorf("'target' field within overlay action is not a string at %s:%d", overlayFile, targetNode.Line) | ||
} | ||
|
||
return targetNode, nil | ||
} | ||
|
||
func getActionUpdate(actionNode *yaml.Node, overlayFile string) (*yaml.Node, error) { | ||
updatePath, err := yamlpath.NewPath("$.update") | ||
if err != nil { | ||
return nil, errors.New(err) | ||
} | ||
|
||
results, err := updatePath.Find(actionNode) | ||
if err != nil { | ||
return nil, errors.New(err) | ||
} | ||
|
||
if len(results) == 0 { | ||
return nil, nil | ||
} | ||
|
||
return results[0], nil | ||
} | ||
|
||
func getActionRemove(actionNode *yaml.Node, overlayFile string) (*bool, error) { | ||
var remove bool | ||
removePath, err := yamlpath.NewPath("$.remove") | ||
if err != nil { | ||
return &remove, errors.New(err) | ||
} | ||
|
||
results, err := removePath.Find(actionNode) | ||
if err != nil { | ||
return nil, errors.New(err) | ||
} | ||
|
||
if len(results) == 0 { | ||
return nil, nil | ||
} | ||
|
||
removeNode := results[0] | ||
|
||
if removeNode.Kind != yaml.ScalarNode || | ||
!(removeNode.Value == "true" || removeNode.Value == "false") { | ||
return nil, errors.Errorf("'remove' field within overlay action is not boolean at %s:%d", overlayFile, removeNode.Line) | ||
} | ||
|
||
remove = results[0].Value == "true" | ||
return &remove, nil | ||
} | ||
|
||
func getActions(overlayNode *yaml.Node, overlayFile string) ([]*yaml.Node, error) { | ||
actionsPath, err := yamlpath.NewPath("$.actions") | ||
if err != nil { | ||
return nil, errors.New(err) | ||
} | ||
|
||
actionsNodes, err := actionsPath.Find(overlayNode) | ||
if err != nil { | ||
return nil, errors.New(err) | ||
} | ||
|
||
if len(actionsNodes) == 0 { | ||
return nil, nil | ||
} | ||
|
||
actionsNode := actionsNodes[0] | ||
|
||
if actionsNode.Kind != yaml.SequenceNode { | ||
return nil, errors.Errorf("'actions' field must be an array at %s:%d", overlayFile, actionsNode.Line) | ||
} | ||
|
||
return actionsNode.Content, nil | ||
} | ||
|
||
func getExtends(overlayNode *yaml.Node, overlayFile string) (*string, error) { | ||
var extends *string | ||
extendsPath, err := yamlpath.NewPath("$.extends") | ||
if err != nil { | ||
return extends, errors.New(err) | ||
} | ||
|
||
results, err := extendsPath.Find(overlayNode) | ||
if err != nil { | ||
return extends, errors.New(err) | ||
} | ||
|
||
if len(results) == 0 { | ||
return extends, nil | ||
} | ||
|
||
extendsNode := *results[0] | ||
if extendsNode.Kind != yaml.ScalarNode { | ||
return nil, errors.Errorf("extends field is not a string at %s:%d", overlayFile, extendsNode.Line) | ||
} | ||
|
||
return &extendsNode.Value, nil | ||
} | ||
|
||
func updateYAMLNode(root *yaml.Node, targetNode *yaml.Node, updateNode *yaml.Node, overlayFile string, specFile string) (*yaml.Node, error) { | ||
pathToUpdate, err := yamlpath.NewPath(targetNode.Value) | ||
if err != nil { | ||
return nil, errors.Errorf("%s at %s:%d", err.Error(), overlayFile, targetNode.Line) | ||
} | ||
|
||
nodesToUpdate, err := pathToUpdate.Find(root) | ||
if err != nil { | ||
return nil, errors.New(err) | ||
} | ||
|
||
if len(nodesToUpdate) == 0 { | ||
return root, nil | ||
} | ||
|
||
for _, nodeToUpdate := range nodesToUpdate { | ||
updateYAMLNodeRecursiveInPlace(nodeToUpdate, updateNode) | ||
} | ||
|
||
return root, nil | ||
|
||
} | ||
|
||
func removeYAMLNode(root *yaml.Node, targetNode *yaml.Node, overlayFile string, specFile string) (*yaml.Node, error) { | ||
pathToRemove, err := yamlpath.NewPath(targetNode.Value) | ||
if err != nil { | ||
return nil, errors.Errorf("%s at %s:%d", err.Error(), overlayFile, targetNode.Line) | ||
} | ||
|
||
nodesToRemove, err := pathToRemove.Find(root) | ||
if err != nil { | ||
return nil, errors.New(err) | ||
} | ||
|
||
if len(nodesToRemove) == 0 { | ||
return root, nil | ||
} | ||
|
||
for _, nodeToRemove := range nodesToRemove { | ||
removeYAMLNodeRecursiveInPlace(nodeToRemove, root) | ||
} | ||
|
||
return root, nil | ||
} | ||
|
||
func removeYAMLNodeRecursiveInPlace(needle *yaml.Node, haystack *yaml.Node) { | ||
if needle == nil { | ||
return | ||
} | ||
|
||
if haystack.Kind == yaml.MappingNode { | ||
for i := 0; i+1 < len(haystack.Content); i += 2 { | ||
value := haystack.Content[i+1] | ||
if value == needle { | ||
haystack.Content = slices.Delete(haystack.Content, i, i+2) | ||
return | ||
} else { | ||
removeYAMLNodeRecursiveInPlace(needle, value) | ||
} | ||
} | ||
} else if haystack.Kind == yaml.DocumentNode { | ||
removeYAMLNodeRecursiveInPlace(needle, haystack.Content[0]) | ||
} else if haystack.Kind == yaml.SequenceNode { | ||
for i := 0; i < len(haystack.Content); i += 1 { | ||
value := haystack.Content[i] | ||
if value == needle { | ||
haystack.Content = slices.Delete(haystack.Content, i, i+1) | ||
return | ||
} else { | ||
removeYAMLNodeRecursiveInPlace(needle, value) | ||
} | ||
} | ||
} | ||
|
||
return | ||
} | ||
|
||
func updateYAMLNodeRecursiveInPlace(target *yaml.Node, source *yaml.Node) { | ||
if target.Kind == yaml.MappingNode && source.Kind == yaml.MappingNode { | ||
//create a lookup map for the target | ||
lookupMap := map[string]*yaml.Node{} | ||
for i := 0; i+1 < len(target.Content); i += 2 { | ||
key := target.Content[i].Value | ||
value := target.Content[i+1] | ||
lookupMap[key] = value | ||
} | ||
|
||
//merge keys that match | ||
for i := 0; i+1 < len(source.Content); i += 2 { | ||
key := source.Content[i].Value | ||
if subTarget, found := lookupMap[key]; found { | ||
updateYAMLNodeRecursiveInPlace(subTarget, source.Content[i+1]) | ||
} else { | ||
target.Content = append(target.Content, source.Content[i], source.Content[i+1]) | ||
} | ||
} | ||
return | ||
} | ||
|
||
if target.Kind == yaml.SequenceNode && (source.Kind == yaml.MappingNode || | ||
source.Kind == yaml.ScalarNode) { | ||
target.Content = append(target.Content, source) | ||
} | ||
|
||
if target.Kind == yaml.ScalarNode && source.Kind == yaml.ScalarNode { | ||
target.Value = source.Value | ||
return | ||
} | ||
|
||
if target.Kind == yaml.SequenceNode && source.Kind == yaml.SequenceNode { | ||
target.Content = append(target.Content, source.Content...) | ||
return | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,110 @@ | ||
// Copyright 2024 Google LLC | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
|
||
package utils | ||
|
||
import ( | ||
"github.com/go-errors/errors" | ||
"github.com/stretchr/testify/require" | ||
"os" | ||
"path" | ||
"path/filepath" | ||
"testing" | ||
) | ||
|
||
func TestOASOverlay(t *testing.T) { | ||
type args struct { | ||
} | ||
|
||
tests := []struct { | ||
dir string | ||
specFile string | ||
wantErr error | ||
}{ | ||
{ | ||
"structured", | ||
"petstore/oas3.yaml", | ||
nil, | ||
}, | ||
{ | ||
"targeted", | ||
"petstore/oas3.yaml", | ||
nil, | ||
}, | ||
{ | ||
"wildcard", | ||
"petstore/oas3.yaml", | ||
nil, | ||
}, | ||
{ | ||
"array", | ||
"petstore/oas3.yaml", | ||
nil, | ||
}, | ||
{ | ||
"bad-update-target", | ||
"petstore/oas3.yaml", | ||
errors.New("invalid array index [?@.name=='status' && @.in=='query'] before position 58: non-integer array index at testdata/oas-overlay/bad-update-target/overlay.yaml:19"), | ||
}, | ||
{ | ||
"bad-remove-value", | ||
"petstore/oas3.yaml", | ||
errors.New("'remove' field within overlay action is not boolean at testdata/oas-overlay/bad-remove-value/overlay.yaml:20"), | ||
}, | ||
{ | ||
"bad-action-op", | ||
"petstore/oas3.yaml", | ||
errors.New("action does not contain neither 'remove' nor 'update' field at testdata/oas-overlay/bad-action-op/overlay.yaml:19"), | ||
}, | ||
{ | ||
"bad-actions-value", | ||
"petstore/oas3.yaml", | ||
errors.New("'actions' field must be an array at testdata/oas-overlay/bad-actions-value/overlay.yaml:18"), | ||
}, | ||
} | ||
for _, tt := range tests { | ||
t.Run(tt.dir, func(t *testing.T) { | ||
testDir := path.Join("testdata", "oas-overlay", tt.dir) | ||
specFile := path.Join("testdata", "specs", "oas3", tt.specFile) | ||
overlayFile := path.Join(testDir, "overlay.yaml") | ||
outputFile := path.Join(testDir, "out-oas3.yaml") | ||
expectedFile := path.Join(testDir, "exp-oas3.yaml") | ||
|
||
var err error | ||
err = os.RemoveAll(outputFile) | ||
require.NoError(t, err) | ||
|
||
err = OASOverlay(overlayFile, specFile, outputFile) | ||
|
||
if tt.wantErr != nil { | ||
require.EqualError(t, err, tt.wantErr.Error()) | ||
return | ||
} | ||
require.NoError(t, err) | ||
|
||
outputBytes := MustReadFileBytes(outputFile) | ||
expectedBytes := MustReadFileBytes(expectedFile) | ||
|
||
if filepath.Ext(expectedFile) == ".json" { | ||
require.JSONEq(t, string(expectedBytes), string(outputBytes)) | ||
} else if filepath.Ext(expectedFile) == ".yaml" { | ||
outputBytes = RemoveYAMLComments(outputBytes) | ||
expectedBytes = RemoveYAMLComments(expectedBytes) | ||
require.YAMLEq(t, string(expectedBytes), string(outputBytes)) | ||
} else { | ||
t.Error("unknown output format in testcase") | ||
} | ||
}) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
# Copyright 2024 Google LLC | ||
# | ||
# Licensed under the Apache License, Version 2.0 (the "License"); | ||
# you may not use this file except in compliance with the License. | ||
# You may obtain a copy of the License at | ||
# | ||
# http:#www.apache.org/licenses/LICENSE-2.0 | ||
# | ||
# Unless required by applicable law or agreed to in writing, software | ||
# distributed under the License is distributed on an "AS IS" BASIS, | ||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
# See the License for the specific language governing permissions and | ||
# limitations under the License. | ||
|
||
**/out-*.yaml | ||
**/out-*.json |
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
overlay: 1.0.0 | ||
info: | ||
title: Update many objects at once | ||
version: 1.0.0 | ||
actions: | ||
- target: $.paths.*.get.parameters | ||
update: | ||
name: newParam | ||
in: query | ||
description: New parameter | ||
schema: | ||
type: string | ||
- target: $.paths.*.*.parameters[?(@.name=='additionalMetadata')] | ||
remove: true |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
# Copyright 2024 Google LLC | ||
# | ||
# Licensed under the Apache License, Version 2.0 (the "License"); | ||
# you may not use this file except in compliance with the License. | ||
# You may obtain a copy of the License at | ||
# | ||
# http:#www.apache.org/licenses/LICENSE-2.0 | ||
# | ||
# Unless required by applicable law or agreed to in writing, software | ||
# distributed under the License is distributed on an "AS IS" BASIS, | ||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
# See the License for the specific language governing permissions and | ||
# limitations under the License. | ||
overlay: 1.0.0 | ||
info: | ||
title: Missing remove / update field | ||
version: 1.0.0 | ||
actions: | ||
- target: $.info.contact |
18 changes: 18 additions & 0 deletions
18
pkg/utils/testdata/oas-overlay/bad-actions-value/overlay.yaml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
# Copyright 2024 Google LLC | ||
# | ||
# Licensed under the Apache License, Version 2.0 (the "License"); | ||
# you may not use this file except in compliance with the License. | ||
# You may obtain a copy of the License at | ||
# | ||
# http:#www.apache.org/licenses/LICENSE-2.0 | ||
# | ||
# Unless required by applicable law or agreed to in writing, software | ||
# distributed under the License is distributed on an "AS IS" BASIS, | ||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
# See the License for the specific language governing permissions and | ||
# limitations under the License. | ||
overlay: 1.0.0 | ||
info: | ||
title: The actions value must be an array | ||
version: 1.0.0 | ||
actions: "Bad" |
20 changes: 20 additions & 0 deletions
20
pkg/utils/testdata/oas-overlay/bad-remove-value/overlay.yaml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
# Copyright 2024 Google LLC | ||
# | ||
# Licensed under the Apache License, Version 2.0 (the "License"); | ||
# you may not use this file except in compliance with the License. | ||
# You may obtain a copy of the License at | ||
# | ||
# http:#www.apache.org/licenses/LICENSE-2.0 | ||
# | ||
# Unless required by applicable law or agreed to in writing, software | ||
# distributed under the License is distributed on an "AS IS" BASIS, | ||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
# See the License for the specific language governing permissions and | ||
# limitations under the License. | ||
overlay: 1.0.0 | ||
info: | ||
title: The remove field only accepts booleans | ||
version: 1.0.0 | ||
actions: | ||
- target: $.info.contact | ||
remove: yes |
22 changes: 22 additions & 0 deletions
22
pkg/utils/testdata/oas-overlay/bad-update-target/overlay.yaml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
# Copyright 2024 Google LLC | ||
# | ||
# Licensed under the Apache License, Version 2.0 (the "License"); | ||
# you may not use this file except in compliance with the License. | ||
# You may obtain a copy of the License at | ||
# | ||
# http:#www.apache.org/licenses/LICENSE-2.0 | ||
# | ||
# Unless required by applicable law or agreed to in writing, software | ||
# distributed under the License is distributed on an "AS IS" BASIS, | ||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
# See the License for the specific language governing permissions and | ||
# limitations under the License. | ||
overlay: 1.0.0 | ||
info: | ||
title: Target JSONPath is not valid | ||
version: 1.0.0 | ||
actions: | ||
- target: $.paths.*.*.parameters[?@.name=='status' && @.in=='query'] | ||
update: | ||
schema: | ||
$ref: '#/components/schemas/filterSchema' |
833 changes: 833 additions & 0 deletions
833
pkg/utils/testdata/oas-overlay/structured/exp-oas3.yaml
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
# Copyright 2024 Google LLC | ||
# | ||
# Licensed under the Apache License, Version 2.0 (the "License"); | ||
# you may not use this file except in compliance with the License. | ||
# You may obtain a copy of the License at | ||
# | ||
# http:#www.apache.org/licenses/LICENSE-2.0 | ||
# | ||
# Unless required by applicable law or agreed to in writing, software | ||
# distributed under the License is distributed on an "AS IS" BASIS, | ||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
# See the License for the specific language governing permissions and | ||
# limitations under the License. | ||
overlay: 1.0.0 | ||
info: | ||
title: Structured Overlay | ||
version: 1.0.0 | ||
actions: | ||
- target: '$' # Root of document | ||
update: | ||
info: | ||
x-overlay-applied: structured-overlay | ||
paths: | ||
'/': | ||
summary: 'The root resource' | ||
get: | ||
summary: 'Retrieve the root resource' | ||
responses: | ||
200: | ||
description: OK | ||
x-rate-limit: 100 | ||
'/pet': | ||
get: | ||
summary: 'Retrieve a list of pets' | ||
responses: | ||
200: | ||
description: OK | ||
x-rate-limit: 100 | ||
|
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
# Copyright 2024 Google LLC | ||
# | ||
# Licensed under the Apache License, Version 2.0 (the "License"); | ||
# you may not use this file except in compliance with the License. | ||
# You may obtain a copy of the License at | ||
# | ||
# http:#www.apache.org/licenses/LICENSE-2.0 | ||
# | ||
# Unless required by applicable law or agreed to in writing, software | ||
# distributed under the License is distributed on an "AS IS" BASIS, | ||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
# See the License for the specific language governing permissions and | ||
# limitations under the License. | ||
overlay: 1.0.0 | ||
info: | ||
title: Targeted Overlay | ||
version: 1.0.0 | ||
actions: | ||
- target: $.info.contact | ||
remove: true | ||
- target: $.info | ||
update: | ||
description: This is a new description | ||
- target: $.tags[?(@.name=='pet')] | ||
update: | ||
externalDocs: | ||
url: https://example.com/pet | ||
- target: $.paths['/pet/{petId}/uploadImage'].post | ||
update: | ||
description: This is the new description for uploadImage operation | ||
- target: $.paths['/pet/{petId}'] | ||
update: | ||
get: | ||
description: This is an updated description of a child object | ||
x-safe: false |
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
# Copyright 2024 Google LLC | ||
# | ||
# Licensed under the Apache License, Version 2.0 (the "License"); | ||
# you may not use this file except in compliance with the License. | ||
# You may obtain a copy of the License at | ||
# | ||
# http:#www.apache.org/licenses/LICENSE-2.0 | ||
# | ||
# Unless required by applicable law or agreed to in writing, software | ||
# distributed under the License is distributed on an "AS IS" BASIS, | ||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
# See the License for the specific language governing permissions and | ||
# limitations under the License. | ||
overlay: 1.0.0 | ||
info: | ||
title: Update many objects at once | ||
version: 1.0.0 | ||
actions: | ||
- target: $.paths.*.get | ||
update: | ||
x-safe: true | ||
- target: $.components.schemas | ||
update: | ||
filterSchema: | ||
type: string | ||
default: available | ||
enum: | ||
- available | ||
- pending | ||
- sold | ||
- target: $.paths.*.*.parameters[?(@.name=='status' && @.in=='query')].schema | ||
remove: true | ||
- target: $.paths.*.*.parameters[?(@.name=='status' && @.in=='query')] | ||
update: | ||
schema: | ||
$ref: '#/components/schemas/filterSchema' |
Large diffs are not rendered by default.
Oops, something went wrong.
Large diffs are not rendered by default.
Oops, something went wrong.